1/*! 2FullCalendar v5.3.0 3Docs & License: https://fullcalendar.io/ 4(c) 2020 Adam Shaw 5*/ 6var FullCalendar = (function (exports) { 7 "use strict"; 8 9 /*! ***************************************************************************** 10 Copyright (c) Microsoft Corporation. 11 12 Permission to use, copy, modify, and/or distribute this software for any 13 purpose with or without fee is hereby granted. 14 15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 16 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 17 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 18 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 19 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 20 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 PERFORMANCE OF THIS SOFTWARE. 22 ***************************************************************************** */ 23 /* global Reflect, Promise */ 24 25 var extendStatics = function (d, b) { 26 extendStatics = 27 Object.setPrototypeOf || 28 ({ __proto__: [] } instanceof Array && 29 function (d, b) { 30 d.__proto__ = b; 31 }) || 32 function (d, b) { 33 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; 34 }; 35 return extendStatics(d, b); 36 }; 37 38 function __extends(d, b) { 39 extendStatics(d, b); 40 function __() { 41 this.constructor = d; 42 } 43 d.prototype = 44 b === null ? Object.create(b) : ((__.prototype = b.prototype), new __()); 45 } 46 47 var __assign = function () { 48 __assign = 49 Object.assign || 50 function __assign(t) { 51 for (var s, i = 1, n = arguments.length; i < n; i++) { 52 s = arguments[i]; 53 for (var p in s) 54 if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 55 } 56 return t; 57 }; 58 return __assign.apply(this, arguments); 59 }; 60 61 function __spreadArrays() { 62 for (var s = 0, i = 0, il = arguments.length; i < il; i++) 63 s += arguments[i].length; 64 for (var r = Array(s), k = 0, i = 0; i < il; i++) 65 for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) 66 r[k] = a[j]; 67 return r; 68 } 69 70 var n, 71 u, 72 i, 73 t, 74 r, 75 o, 76 f, 77 e = {}, 78 c = [], 79 s = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord/i; 80 function a(n, l) { 81 for (var u in l) n[u] = l[u]; 82 return n; 83 } 84 function v(n) { 85 var l = n.parentNode; 86 l && l.removeChild(n); 87 } 88 function h(n, l, u) { 89 var i, 90 t = arguments, 91 r = {}; 92 for (i in l) "key" !== i && "ref" !== i && (r[i] = l[i]); 93 if (arguments.length > 3) 94 for (u = [u], i = 3; i < arguments.length; i++) u.push(t[i]); 95 if ( 96 (null != u && (r.children = u), 97 "function" == typeof n && null != n.defaultProps) 98 ) 99 for (i in n.defaultProps) void 0 === r[i] && (r[i] = n.defaultProps[i]); 100 return p(n, r, l && l.key, l && l.ref, null); 101 } 102 function p(l, u, i, t, r) { 103 var o = { 104 type: l, 105 props: u, 106 key: i, 107 ref: t, 108 __k: null, 109 __: null, 110 __b: 0, 111 __e: null, 112 __d: void 0, 113 __c: null, 114 constructor: void 0, 115 __v: r, 116 }; 117 return null == r && (o.__v = o), n.vnode && n.vnode(o), o; 118 } 119 function y() { 120 return {}; 121 } 122 function d(n) { 123 return n.children; 124 } 125 function m(n, l) { 126 (this.props = n), (this.context = l); 127 } 128 function w(n, l) { 129 if (null == l) return n.__ ? w(n.__, n.__.__k.indexOf(n) + 1) : null; 130 for (var u; l < n.__k.length; l++) 131 if (null != (u = n.__k[l]) && null != u.__e) return u.__e; 132 return "function" == typeof n.type ? w(n) : null; 133 } 134 function k(n) { 135 var l, u; 136 if (null != (n = n.__) && null != n.__c) { 137 for (n.__e = n.__c.base = null, l = 0; l < n.__k.length; l++) 138 if (null != (u = n.__k[l]) && null != u.__e) { 139 n.__e = n.__c.base = u.__e; 140 break; 141 } 142 return k(n); 143 } 144 } 145 function g(l) { 146 ((!l.__d && (l.__d = !0) && u.push(l) && !i++) || 147 r !== n.debounceRendering) && 148 ((r = n.debounceRendering) || t)(_); 149 } 150 function _() { 151 for (var n; (i = u.length); )
152 (n = u.sort(function (n, l) { 153 return n.__v.__b - l.__v.__b; 154 })), 155 (u = []), 156 n.some(function (n) { 157 var l, u, i, t, r, o, f; 158 n.__d && 159 ((o = (r = (l = n).__v).__e), 160 (f = l.__P) && 161 ((u = []), 162 ((i = a({}, r)).__v = i), 163 (t = A( 164 f, 165 r, 166 i, 167 l.__n, 168 void 0 !== f.ownerSVGElement, 169 null, 170 u, 171 null == o ? w(r) : o 172 )), 173 T(u, r), 174 t != o && k(r))); 175 }); 176 } 177 function b(n, l, u, i, t, r, o, f, s) { 178 var a, 179 h, 180 p, 181 y, 182 d, 183 m, 184 k, 185 g = (u && u.__k) || c, 186 _ = g.length; 187 if ( 188 (f == e && (f = null != r ? r[0] : _ ? w(u, 0) : null), 189 (a = 0), 190 (l.__k = x(l.__k, function (u) { 191 if (null != u) { 192 if ( 193 ((u.__ = l), 194 (u.__b = l.__b + 1), 195 null === (p = g[a]) || (p && u.key == p.key && u.type === p.type)) 196 ) 197 g[a] = void 0; 198 else 199 for (h = 0; h < _; h++) { 200 if ((p = g[h]) && u.key == p.key && u.type === p.type) { 201 g[h] = void 0; 202 break; 203 } 204 p = null; 205 } 206 if ( 207 ((y = A(n, u, (p = p || e), i, t, r, o, f, s)), 208 (h = u.ref) && 209 p.ref != h && 210 (k || (k = []), 211 p.ref && k.push(p.ref, null, u), 212 k.push(h, u.__c || y, u)), 213 null != y) 214 ) { 215 var c; 216 if ((null == m && (m = y), void 0 !== u.__d)) 217 (c = u.__d), (u.__d = void 0); 218 else if (r == p || y != f || null == y.parentNode) { 219 n: if (null == f || f.parentNode !== n) 220 n.appendChild(y), (c = null); 221 else { 222 for (d = f, h = 0; (d = d.nextSibling) && h < _; h += 2) 223 if (d == y) break n; 224 n.insertBefore(y, f), (c = f); 225 } 226 "option" == l.type && (n.value = ""); 227 } 228 (f = void 0 !== c ? c : y.nextSibling), 229 "function" == typeof l.type && (l.__d = f); 230 } else f && p.__e == f && f.parentNode != n && (f = w(p)); 231 } 232 return a++, u; 233 })), 234 (l.__e = m), 235 null != r && "function" != typeof l.type) 236 ) 237 for (a = r.length; a--; ) null != r[a] && v(r[a]); 238 for (a = _; a--; ) null != g[a] && D(g[a], g[a]); 239 if (k) for (a = 0; a < k.length; a++) j(k[a], k[++a], k[++a]); 240 } 241 function x(n, l, u) { 242 if ((null == u && (u = []), null == n || "boolean" == typeof n)) 243 l && u.push(l(null)); 244 else if (Array.isArray(n)) for (var i = 0; i < n.length; i++) x(n[i], l, u); 245 else 246 u.push( 247 l 248 ? l( 249 "string" == typeof n || "number" == typeof n 250 ? p(null, n, null, null, n) 251 : null != n.__e || null != n.__c 252 ? p(n.type, n.props, n.key, null, n.__v) 253 : n 254 ) 255 : n 256 ); 257 return u; 258 } 259 function P(n, l, u, i, t) { 260 var r; 261 for (r in u) 262 "children" === r || "key" === r || r in l || N(n, r, null, u[r], i); 263 for (r in l) 264 (t && "function" != typeof l[r]) || 265 "children" === r || 266 "key" === r || 267 "value" === r || 268 "checked" === r || 269 u[r] === l[r] || 270 N(n, r, l[r], u[r], i); 271 } 272 function C(n, l, u) { 273 "-" === l[0] 274 ? n.setProperty(l, u) 275 : (n[l] = 276 "number" == typeof u && !1 === s.test(l) 277 ? u + "px" 278 : null == u 279 ? "" 280 : u); 281 } 282 function N(n, l, u, i, t) { 283 var r, o, f, e, c; 284 if ( 285 (t 286 ? "className" === l && (l = "class") 287 : "class" === l && (l = "className"), 288 "style" === l) 289 ) 290 if (((r = n.style), "string" == typeof u)) r.cssText = u; 291 else { 292 if (("string" == typeof i && ((r.cssText = ""), (i = null)), i))
293 for (e in i) (u && e in u) || C(r, e, ""); 294 if (u) for (c in u) (i && u[c] === i[c]) || C(r, c, u[c]); 295 } 296 else 297 "o" === l[0] && "n" === l[1] 298 ? ((o = l !== (l = l.replace(/Capture$/, ""))), 299 (f = l.toLowerCase()), 300 (l = (f in n ? f : l).slice(2)), 301 u 302 ? (i || n.addEventListener(l, z, o), ((n.l || (n.l = {}))[l] = u)) 303 : n.removeEventListener(l, z, o)) 304 : "list" !== l && 305 "tagName" !== l && 306 "form" !== l && 307 "type" !== l && 308 "size" !== l && 309 !t && 310 l in n 311 ? (n[l] = null == u ? "" : u) 312 : "function" != typeof u && 313 "dangerouslySetInnerHTML" !== l && 314 (l !== (l = l.replace(/^xlink:?/, "")) 315 ? null == u || !1 === u 316 ? n.removeAttributeNS( 317 "http://www.w3.org/1999/xlink", 318 l.toLowerCase() 319 ) 320 : n.setAttributeNS( 321 "http://www.w3.org/1999/xlink", 322 l.toLowerCase(), 323 u 324 ) 325 : null == u || (!1 === u && !/^ar/.test(l)) 326 ? n.removeAttribute(l) 327 : n.setAttribute(l, u)); 328 } 329 function z(l) { 330 this.l[l.type](n.event ? n.event(l) : l); 331 } 332 function A(l, u, i, t, r, o, f, e, c) { 333 var s, 334 v, 335 h, 336 p, 337 y, 338 w, 339 k, 340 g, 341 _, 342 x, 343 P = u.type; 344 if (void 0 !== u.constructor) return null; 345 (s = n.__b) && s(u); 346 try { 347 n: if ("function" == typeof P) { 348 if ( 349 ((g = u.props), 350 (_ = (s = P.contextType) && t[s.__c]), 351 (x = s ? (_ ? _.props.value : s.__) : t), 352 i.__c 353 ? (k = (v = u.__c = i.__c).__ = v.__E) 354 : ("prototype" in P && P.prototype.render 355 ? (u.__c = v = new P(g, x)) 356 : ((u.__c = v = new m(g, x)), 357 (v.constructor = P), 358 (v.render = E)), 359 _ && _.sub(v), 360 (v.props = g), 361 v.state || (v.state = {}), 362 (v.context = x), 363 (v.__n = t), 364 (h = v.__d = !0), 365 (v.__h = [])), 366 null == v.__s && (v.__s = v.state), 367 null != P.getDerivedStateFromProps && 368 (v.__s == v.state && (v.__s = a({}, v.__s)), 369 a(v.__s, P.getDerivedStateFromProps(g, v.__s))), 370 (p = v.props), 371 (y = v.state), 372 h) 373 ) 374 null == P.getDerivedStateFromProps && 375 null != v.componentWillMount && 376 v.componentWillMount(), 377 null != v.componentDidMount && v.__h.push(v.componentDidMount); 378 else { 379 if ( 380 (null == P.getDerivedStateFromProps && 381 g !== p && 382 null != v.componentWillReceiveProps && 383 v.componentWillReceiveProps(g, x), 384 (!v.__e && 385 null != v.shouldComponentUpdate && 386 !1 === v.shouldComponentUpdate(g, v.__s, x)) || 387 (u.__v === i.__v && !v.__)) 388 ) { 389 for ( 390 v.props = g, 391 v.state = v.__s, 392 u.__v !== i.__v && (v.__d = !1), 393 v.__v = u, 394 u.__e = i.__e, 395 u.__k = i.__k, 396 v.__h.length && f.push(v), 397 s = 0; 398 s < u.__k.length; 399 s++ 400 ) 401 u.__k[s] && (u.__k[s].__ = u); 402 break n; 403 } 404 null != v.componentWillUpdate && v.componentWillUpdate(g, v.__s, x), 405 null != v.componentDidUpdate && 406 v.__h.push(function () { 407 v.componentDidUpdate(p, y, w); 408 }); 409 } 410 (v.context = x), 411 (v.props = g), 412 (v.state = v.__s), 413 (s = n.__r) && s(u), 414 (v.__d = !1), 415 (v.__v = u), 416 (v.__P = l), 417 (s = v.render(v.props, v.state, v.context)), 418 (u.__k = 419 null != s && s.type == d && null == s.key 420 ? s.props.children 421 : Array.isArray(s) 422 ? s 423 : [s]), 424 null != v.getChildContext && (t = a(a({}, t), v.getChildContext())), 425 h || 426 null == v.getSnapshotBeforeUpdate || 427 (w = v.getSnapshotBeforeUpdate(p, y)), 428 b(l, u, i, t, r, o, f, e, c), 429 (v.base = u.__e), 430 v.__h.length && f.push(v), 431 k && (v.__E = v.__ = null),
432 (v.__e = !1); 433 } else 434 null == o && u.__v === i.__v 435 ? ((u.__k = i.__k), (u.__e = i.__e)) 436 : (u.__e = $(i.__e, u, i, t, r, o, f, c)); 437 (s = n.diffed) && s(u); 438 } catch (l) { 439 (u.__v = null), n.__e(l, u, i); 440 } 441 return u.__e; 442 } 443 function T(l, u) { 444 n.__c && n.__c(u, l), 445 l.some(function (u) { 446 try { 447 (l = u.__h), 448 (u.__h = []), 449 l.some(function (n) { 450 n.call(u); 451 }); 452 } catch (l) { 453 n.__e(l, u.__v); 454 } 455 }); 456 } 457 function $(n, l, u, i, t, r, o, f) { 458 var s, 459 a, 460 v, 461 h, 462 p, 463 y = u.props, 464 d = l.props; 465 if (((t = "svg" === l.type || t), null != r)) 466 for (s = 0; s < r.length; s++) 467 if ( 468 null != (a = r[s]) && 469 ((null === l.type ? 3 === a.nodeType : a.localName === l.type) || 470 n == a) 471 ) { 472 (n = a), (r[s] = null); 473 break; 474 } 475 if (null == n) { 476 if (null === l.type) return document.createTextNode(d); 477 (n = t 478 ? document.createElementNS("http://www.w3.org/2000/svg", l.type) 479 : document.createElement(l.type, d.is && { is: d.is })), 480 (r = null), 481 (f = !1); 482 } 483 if (null === l.type) y !== d && n.data != d && (n.data = d); 484 else { 485 if ( 486 (null != r && (r = c.slice.call(n.childNodes)), 487 (v = (y = u.props || e).dangerouslySetInnerHTML), 488 (h = d.dangerouslySetInnerHTML), 489 !f) 490 ) { 491 if (y === e) 492 for (y = {}, p = 0; p < n.attributes.length; p++) 493 y[n.attributes[p].name] = n.attributes[p].value; 494 (h || v) && 495 ((h && v && h.__html == v.__html) || 496 (n.innerHTML = (h && h.__html) || "")); 497 } 498 P(n, d, y, t, f), 499 h 500 ? (l.__k = []) 501 : ((l.__k = l.props.children), 502 b(n, l, u, i, "foreignObject" !== l.type && t, r, o, e, f)), 503 f || 504 ("value" in d && 505 void 0 !== (s = d.value) && 506 s !== n.value && 507 N(n, "value", s, y.value, !1), 508 "checked" in d && 509 void 0 !== (s = d.checked) && 510 s !== n.checked && 511 N(n, "checked", s, y.checked, !1)); 512 } 513 return n; 514 } 515 function j(l, u, i) { 516 try { 517 "function" == typeof l ? l(u) : (l.current = u); 518 } catch (l) { 519 n.__e(l, i); 520 } 521 } 522 function D(l, u, i) { 523 var t, r, o; 524 if ( 525 (n.unmount && n.unmount(l), 526 (t = l.ref) && ((t.current && t.current !== l.__e) || j(t, null, u)), 527 i || "function" == typeof l.type || (i = null != (r = l.__e)), 528 (l.__e = l.__d = void 0), 529 null != (t = l.__c)) 530 ) { 531 if (t.componentWillUnmount) 532 try { 533 t.componentWillUnmount(); 534 } catch (l) { 535 n.__e(l, u); 536 } 537 t.base = t.__P = null; 538 } 539 if ((t = l.__k)) for (o = 0; o < t.length; o++) t[o] && D(t[o], u, i); 540 null != r && v(r); 541 } 542 function E(n, l, u) { 543 return this.constructor(n, u); 544 } 545 function H(l, u, i) { 546 var t, r, f; 547 n.__ && n.__(l, u), 548 (r = (t = i === o) ? null : (i && i.__k) || u.__k), 549 (l = h(d, null, [l])), 550 (f = []), 551 A( 552 u, 553 ((t ? u : i || u).__k = l), 554 r || e, 555 e, 556 void 0 !== u.ownerSVGElement, 557 i && !t ? [i] : r ? null : c.slice.call(u.childNodes), 558 f, 559 i || e, 560 t 561 ), 562 T(f, l); 563 } 564 function M(n) { 565 var l = {}, 566 u = { 567 __c: "__cC" + f++, 568 __: n, 569 Consumer: function (n, l) { 570 return n.children(l); 571 }, 572 Provider: function (n) { 573 var i, 574 t = this; 575 return ( 576 this.getChildContext || 577 ((i = []), 578 (this.getChildContext = function () { 579 return (l[u.__c] = t), l; 580 }), 581 (this.shouldComponentUpdate = function (n) { 582 t.props.value !== n.value && 583 i.some(function (l) { 584 (l.context = n.value), g(l); 585 }); 586 }), 587 (this.sub = function (n) { 588 i.push(n); 589 var l = n.componentWillUnmount; 590 n.componentWillUnmount = function () { 591 i.splice(i.indexOf(n), 1), l && l.call(n); 592 }; 593 })), 594 n.children 595 ); 596 }, 597 }; 598 return (u.Consumer.contextType = u), (u.Provider.__ = u), u; 599 } 600 (n = { 601 __e: function (n, l) { 602 for (var u, i; (l = l.__); ) 603 if ((u = l.__c) && !u.__) 604 try { 605 if ( 606 (u.constructor && 607 null != u.constructor.getDerivedStateFromError && 608 ((i = !0), 609 u.setState(u.constructor.getDerivedStateFromError(n))), 610 null != u.componentDidCatch && ((i = !0), u.componentDidCatch(n)), 611 i) 612 ) 613 return g((u.__E = u)); 614 } catch (l) { 615 n = l; 616 } 617 throw n; 618 }, 619 }), 620 (m.prototype.setState = function (n, l) { 621 var u; 622 (u = this.__s !== this.state ? this.__s : (this.__s = a({}, this.state))), 623 "function" == typeof n && (n = n(u, this.props)), 624 n && a(u, n), 625 null != n && this.__v && (l && this.__h.push(l), g(this)); 626 }), 627 (m.prototype.forceUpdate = function (n) { 628 this.__v && ((this.__e = !0), n && this.__h.push(n), g(this)); 629 }), 630 (m.prototype.render = d), 631 (u = []), 632 (i = 0), 633 (t = 634 "function" == typeof Promise
635 ? Promise.prototype.then.bind(Promise.resolve()) 636 : setTimeout), 637 (o = e), 638 (f = 0); 639 640 (typeof globalThis !== "undefined" ? globalThis : window).FullCalendarVDom = { 641 Component: m, 642 createElement: h, 643 render: H, 644 createRef: y, 645 Fragment: d, 646 createContext: createContext, 647 flushToDom: flushToDom, 648 }; 649 // HACKS... 650 // TODO: lock version 651 // TODO: link gh issues 652 function flushToDom() { 653 var oldDebounceRendering = n.debounceRendering; // orig 654 var callbackQ = []; 655 function execCallbackSync(callback) { 656 callbackQ.push(callback); 657 } 658 n.debounceRendering = execCallbackSync; 659 H(h(FakeComponent, {}), document.createElement("div")); 660 while (callbackQ.length) { 661 callbackQ.shift()(); 662 } 663 n.debounceRendering = oldDebounceRendering; 664 } 665 var FakeComponent = /** @class */ (function (_super) { 666 __extends(FakeComponent, _super); 667 function FakeComponent() { 668 return (_super !== null && _super.apply(this, arguments)) || this; 669 } 670 FakeComponent.prototype.render = function () { 671 return h("div", {}); 672 }; 673 FakeComponent.prototype.componentDidMount = function () { 674 this.setState({}); 675 }; 676 return FakeComponent; 677 })(m); 678 function createContext(defaultValue) { 679 var ContextType = M(defaultValue); 680 var origProvider = ContextType.Provider; 681 ContextType.Provider = function () { 682 var _this = this; 683 var isNew = !this.getChildContext; 684 var children = origProvider.apply(this, arguments); 685 if (isNew) { 686 var subs_1 = []; 687 this.shouldComponentUpdate = function (_props) { 688 if (_this.props.value !== _props.value) { 689 subs_1.some(function (c) { 690 c.context = _props.value; 691 c.forceUpdate(); 692 }); 693 } 694 }; 695 this.sub = function (c) { 696 subs_1.push(c); 697 var old = c.componentWillUnmount; 698 c.componentWillUnmount = function () { 699 subs_1.splice(subs_1.indexOf(c), 1); 700 old && old.call(c); 701 }; 702 }; 703 } 704 return children; 705 }; 706 return ContextType; 707 } 708 709 // no public types yet. when there are, export from: 710 // import {} from './api-type-deps' 711 var EventSourceApi = /** @class */ (function () { 712 function EventSourceApi( 713 context, 714 internalEventSource // rename? 715 ) { 716 this.context = context; 717 this.internalEventSource = internalEventSource; 718 } 719 EventSourceApi.prototype.remove = function () { 720 this.context.dispatch({ 721 type: "REMOVE_EVENT_SOURCE", 722 sourceId: this.internalEventSource.sourceId, 723 }); 724 }; 725 EventSourceApi.prototype.refetch = function () { 726 this.context.dispatch({ 727 type: "FETCH_EVENT_SOURCES", 728 sourceIds: [this.internalEventSource.sourceId], 729 }); 730 }; 731 Object.defineProperty(EventSourceApi.prototype, "id", { 732 get: function () { 733 return this.internalEventSource.publicId; 734 }, 735 enumerable: false, 736 configurable: true, 737 }); 738 Object.defineProperty(EventSourceApi.prototype, "url", { 739 // only relevant to json-feed event sources 740 get: function () { 741 return this.internalEventSource.meta.url; 742 }, 743 enumerable: false, 744 configurable: true, 745 }); 746 return EventSourceApi; 747 })(); 748 749 function removeElement(el) { 750 if (el.parentNode) { 751 el.parentNode.removeChild(el); 752 } 753 } 754 // Querying 755 // ---------------------------------------------------------------------------------------------------------------- 756 function elementClosest(el, selector) { 757 if (el.closest) { 758 return el.closest(selector); 759 // really bad fallback for IE 760 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 761 } else { 762 if (!document.documentElement.contains(el)) { 763 return null; 764 } 765 do { 766 if (elementMatches(el, selector)) { 767 return el; 768 } 769 el = el.parentElement || el.parentNode; 770 } while (el !== null && el.nodeType === 1); 771 return null; 772 } 773 } 774 function elementMatches(el, selector) { 775 var method = el.matches || el.matchesSelector || el.msMatchesSelector; 776 return method.call(el, selector); 777 } 778 // accepts multiple subject els 779 // returns a real array. good for methods like forEach 780 // TODO: accept the document 781 function findElements(container, selector) { 782 var containers = container instanceof HTMLElement ? [container] : container; 783 var allMatches = []; 784 for (var i = 0; i < containers.length; i++) { 785 var matches = containers[i].querySelectorAll(selector); 786 for (var j = 0; j < matches.length; j++) { 787 allMatches.push(matches[j]); 788 } 789 } 790 return allMatches; 791 } 792 // accepts multiple subject els 793 // only queries direct child elements // TODO: rename to findDirectChildren! 794 function findDirectChildren(parent, selector) { 795 var parents = parent instanceof HTMLElement ? [parent] : parent; 796 var allMatches = []; 797 for (var i = 0; i < parents.length; i++) { 798 var childNodes = parents[i].children; // only ever elements 799 for (var j = 0; j < childNodes.length; j++) { 800 var childNode = childNodes[j]; 801 if (!selector || elementMatches(childNode, selector)) { 802 allMatches.push(childNode); 803 } 804 } 805 } 806 return allMatches; 807 } 808 // Style 809 // ---------------------------------------------------------------------------------------------------------------- 810 var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 811 function applyStyle(el, props) { 812 for (var propName in props) { 813 applyStyleProp(el, propName, props[propName]); 814 } 815 } 816 function applyStyleProp(el, name, val) { 817 if (val == null) { 818 el.style[name] = ""; 819 } else if (typeof val === "number" && PIXEL_PROP_RE.test(name)) { 820 el.style[name] = val + "px"; 821 } else { 822 el.style[name] = val; 823 } 824 } 825 826 // Stops a mouse/touch event from doing it's native browser action 827 function preventDefault(ev) { 828 ev.preventDefault(); 829 } 830 // Event Delegation 831 // ---------------------------------------------------------------------------------------------------------------- 832 function buildDelegationHandler(selector, handler) { 833 return function (ev) {
834 var matchedChild = elementClosest(ev.target, selector); 835 if (matchedChild) { 836 handler.call(matchedChild, ev, matchedChild); 837 } 838 }; 839 } 840 function listenBySelector(container, eventType, selector, handler) { 841 var attachedHandler = buildDelegationHandler(selector, handler); 842 container.addEventListener(eventType, attachedHandler); 843 return function () { 844 container.removeEventListener(eventType, attachedHandler); 845 }; 846 } 847 function listenToHoverBySelector( 848 container, 849 selector, 850 onMouseEnter, 851 onMouseLeave 852 ) { 853 var currentMatchedChild; 854 return listenBySelector( 855 container, 856 "mouseover", 857 selector, 858 function (ev, matchedChild) { 859 if (matchedChild !== currentMatchedChild) { 860 currentMatchedChild = matchedChild; 861 onMouseEnter(ev, matchedChild); 862 var realOnMouseLeave_1 = function (ev) { 863 currentMatchedChild = null; 864 onMouseLeave(ev, matchedChild); 865 matchedChild.removeEventListener("mouseleave", realOnMouseLeave_1); 866 }; 867 // listen to the next mouseleave, and then unattach 868 matchedChild.addEventListener("mouseleave", realOnMouseLeave_1); 869 } 870 } 871 ); 872 } 873 // Animation 874 // ---------------------------------------------------------------------------------------------------------------- 875 var transitionEventNames = [ 876 "webkitTransitionEnd", 877 "otransitionend", 878 "oTransitionEnd", 879 "msTransitionEnd", 880 "transitionend", 881 ]; 882 // triggered only when the next single subsequent transition finishes 883 function whenTransitionDone(el, callback) { 884 var realCallback = function (ev) { 885 callback(ev); 886 transitionEventNames.forEach(function (eventName) { 887 el.removeEventListener(eventName, realCallback); 888 }); 889 }; 890 transitionEventNames.forEach(function (eventName) { 891 el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes 892 }); 893 } 894 895 var guidNumber = 0; 896 function guid() { 897 return String(guidNumber++); 898 } 899 /* FullCalendar-specific DOM Utilities 900 ----------------------------------------------------------------------------------------------------------------------*/ 901 // Make the mouse cursor express that an event is not allowed in the current area 902 function disableCursor() { 903 document.body.classList.add("fc-not-allowed"); 904 } 905 // Returns the mouse cursor to its original look 906 function enableCursor() { 907 document.body.classList.remove("fc-not-allowed"); 908 } 909 /* Selection 910 ----------------------------------------------------------------------------------------------------------------------*/ 911 function preventSelection(el) { 912 el.classList.add("fc-unselectable"); 913 el.addEventListener("selectstart", preventDefault); 914 } 915 function allowSelection(el) { 916 el.classList.remove("fc-unselectable"); 917 el.removeEventListener("selectstart", preventDefault); 918 } 919 /* Context Menu 920 ----------------------------------------------------------------------------------------------------------------------*/ 921 function preventContextMenu(el) { 922 el.addEventListener("contextmenu", preventDefault); 923 } 924 function allowContextMenu(el) { 925 el.removeEventListener("contextmenu", preventDefault); 926 } 927 function parseFieldSpecs(input) { 928 var specs = []; 929 var tokens = []; 930 var i; 931 var token; 932 if (typeof input === "string") { 933 tokens = input.split(/\s*,\s*/); 934 } else if (typeof input === "function") { 935 tokens = [input]; 936 } else if (Array.isArray(input)) { 937 tokens = input; 938 } 939 for (i = 0; i < tokens.length; i++) { 940 token = tokens[i]; 941 if (typeof token === "string") { 942 specs.push( 943 token.charAt(0) === "-" 944 ? { field: token.substring(1), order: -1 } 945 : { field: token, order: 1 } 946 ); 947 } else if (typeof token === "function") { 948 specs.push({ func: token }); 949 } 950 } 951 return specs; 952 } 953 function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 954 var i; 955 var cmp; 956 for (i = 0; i < fieldSpecs.length; i++) { 957 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]); 958 if (cmp) { 959 return cmp; 960 } 961 } 962 return 0; 963 } 964 function compareByFieldSpec(obj0, obj1, fieldSpec) { 965 if (fieldSpec.func) { 966 return fieldSpec.func(obj0, obj1); 967 } 968 return ( 969 flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) * 970 (fieldSpec.order || 1) 971 ); 972 } 973 function flexibleCompare(a, b) { 974 if (!a && !b) { 975 return 0; 976 } 977 if (b == null) { 978 return -1; 979 } 980 if (a == null) { 981 return 1; 982 } 983 if (typeof a === "string" || typeof b === "string") { 984 return String(a).localeCompare(String(b)); 985 } 986 return a - b; 987 } 988 /* String Utilities 989 ----------------------------------------------------------------------------------------------------------------------*/ 990 function padStart(val, len) { 991 var s = String(val); 992 return "000".substr(0, len - s.length) + s; 993 } 994 /* Number Utilities 995 ----------------------------------------------------------------------------------------------------------------------*/ 996 function compareNumbers(a, b) { 997 return a - b; 998 } 999 function isInt(n) { 1000 return n % 1 === 0; 1001 } 1002 /* FC-specific DOM dimension stuff 1003 ----------------------------------------------------------------------------------------------------------------------*/ 1004 function computeSmallestCellWidth(cellEl) { 1005 var allWidthEl = cellEl.querySelector(".fc-scrollgrid-shrink-frame"); 1006 var contentWidthEl = cellEl.querySelector(".fc-scrollgrid-shrink-cushion"); 1007 if (!allWidthEl) { 1008 throw new Error("needs fc-scrollgrid-shrink-frame className"); // TODO: use const 1009 } 1010 if (!contentWidthEl) { 1011 throw new Error("needs fc-scrollgrid-shrink-cushion className"); 1012 } 1013 return ( 1014 cellEl.getBoundingClientRect().width - 1015 allWidthEl.getBoundingClientRect().width + // the cell padding+border 1016 contentWidthEl.getBoundingClientRect().width 1017 ); 1018 } 1019 1020 var DAY_IDS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; 1021 // Adding 1022 function addWeeks(m, n) { 1023 var a = dateToUtcArray(m); 1024 a[2] += n * 7; 1025 return arrayToUtcDate(a); 1026 } 1027 function addDays(m, n) { 1028 var a = dateToUtcArray(m); 1029 a[2] += n; 1030 return arrayToUtcDate(a); 1031 } 1032 function addMs(m, n) { 1033 var a = dateToUtcArray(m); 1034 a[6] += n; 1035 return arrayToUtcDate(a); 1036 } 1037 // Diffing (all return floats) 1038 // TODO: why not use ranges? 1039 function diffWeeks(m0, m1) { 1040 return diffDays(m0, m1) / 7; 1041 } 1042 function diffDays(m0, m1) { 1043 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24); 1044 } 1045 function diffHours(m0, m1) { 1046 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60); 1047 } 1048 function diffMinutes(m0, m1) { 1049 return (m1.valueOf() - m0.valueOf()) / (1000 * 60); 1050 } 1051 function diffSeconds(m0, m1) { 1052 return (m1.valueOf() - m0.valueOf()) / 1000; 1053 } 1054 function diffDayAndTime(m0, m1) { 1055 var m0day = startOfDay(m0); 1056 var m1day = startOfDay(m1); 1057 return { 1058 years: 0, 1059 months: 0, 1060 days: Math.round(diffDays(m0day, m1day)), 1061 milliseconds: 1062 m1.valueOf() - m1day.valueOf() - (m0.valueOf() - m0day.valueOf()), 1063 }; 1064 } 1065 // Diffing Whole Units 1066 function diffWholeWeeks(m0, m1) { 1067 var d = diffWholeDays(m0, m1); 1068 if (d !== null && d % 7 === 0) { 1069 return d / 7; 1070 } 1071 return null; 1072 } 1073 function diffWholeDays(m0, m1) { 1074 if (timeAsMs(m0) === timeAsMs(m1)) { 1075 return Math.round(diffDays(m0, m1)); 1076 } 1077 return null; 1078 } 1079 // Start-Of 1080 function startOfDay(m) { 1081 return arrayToUtcDate([ 1082 m.getUTCFullYear(), 1083 m.getUTCMonth(), 1084 m.getUTCDate(), 1085 ]); 1086 } 1087 function startOfHour(m) { 1088 return arrayToUtcDate([ 1089 m.getUTCFullYear(), 1090 m.getUTCMonth(), 1091 m.getUTCDate(), 1092 m.getUTCHours(), 1093 ]); 1094 } 1095 function startOfMinute(m) { 1096 return arrayToUtcDate([ 1097 m.getUTCFullYear(), 1098 m.getUTCMonth(), 1099 m.getUTCDate(), 1100 m.getUTCHours(), 1101 m.getUTCMinutes(), 1102 ]); 1103 } 1104 function startOfSecond(m) { 1105 return arrayToUtcDate([ 1106 m.getUTCFullYear(), 1107 m.getUTCMonth(), 1108 m.getUTCDate(), 1109 m.getUTCHours(), 1110 m.getUTCMinutes(), 1111 m.getUTCSeconds(), 1112 ]); 1113 } 1114 // Week Computation 1115 function weekOfYear(marker, dow, doy) { 1116 var y = marker.getUTCFullYear(); 1117 var w = weekOfGivenYear(marker, y, dow, doy); 1118 if (w < 1) { 1119 return weekOfGivenYear(marker, y - 1, dow, doy); 1120 } 1121 var nextW = weekOfGivenYear(marker, y + 1, dow, doy); 1122 if (nextW >= 1) { 1123 return Math.min(w, nextW); 1124 } 1125 return w; 1126 } 1127 function weekOfGivenYear(marker, year, dow, doy) { 1128 var firstWeekStart = arrayToUtcDate([ 1129 year, 1130 0, 1131 1 + firstWeekOffset(year, dow, doy), 1132 ]); 1133 var dayStart = startOfDay(marker); 1134 var days = Math.round(diffDays(firstWeekStart, dayStart)); 1135 return Math.floor(days / 7) + 1; // zero-indexed 1136 } 1137 // start-of-first-week - start-of-year 1138 function firstWeekOffset(year, dow, doy) { 1139 // first-week day -- which january is always in the first week (4 for iso, 1 for other) 1140 var fwd = 7 + dow - doy; 1141 // first-week day local weekday -- which local weekday is fwd 1142 var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 1143 return -fwdlw + fwd - 1; 1144 } 1145 // Array Conversion 1146 function dateToLocalArray(date) { 1147 return [ 1148 date.getFullYear(), 1149 date.getMonth(), 1150 date.getDate(), 1151 date.getHours(), 1152 date.getMinutes(), 1153 date.getSeconds(), 1154 date.getMilliseconds(), 1155 ]; 1156 } 1157 function arrayToLocalDate(a) { 1158 return new Date( 1159 a[0], 1160 a[1] || 0, 1161 a[2] == null ? 1 : a[2], // day of month 1162 a[3] || 0, 1163 a[4] || 0, 1164 a[5] || 0 1165 ); 1166 } 1167 function dateToUtcArray(date) { 1168 return [ 1169 date.getUTCFullYear(), 1170 date.getUTCMonth(), 1171 date.getUTCDate(), 1172 date.getUTCHours(), 1173 date.getUTCMinutes(), 1174 date.getUTCSeconds(), 1175 date.getUTCMilliseconds(), 1176 ]; 1177 } 1178 function arrayToUtcDate(a) { 1179 // according to web standards (and Safari), a month index is required. 1180 // massage if only given a year. 1181 if (a.length === 1) { 1182 a = a.concat([0]); 1183 } 1184 return new Date(Date.UTC.apply(Date, a)); 1185 } 1186 // Other Utils 1187 function isValidDate(m) { 1188 return !isNaN(m.valueOf()); 1189 } 1190 function timeAsMs(m) { 1191 return ( 1192 m.getUTCHours() * 1000 * 60 * 60 + 1193 m.getUTCMinutes() * 1000 * 60 + 1194 m.getUTCSeconds() * 1000 + 1195 m.getUTCMilliseconds() 1196 ); 1197 } 1198 1199 function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 1200 return { 1201 instanceId: guid(), 1202 defId: defId, 1203 range: range, 1204 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 1205 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo, 1206 }; 1207 } 1208 1209 var hasOwnProperty = Object.prototype.hasOwnProperty; 1210 // Merges an array of objects into a single object. 1211 // The second argument allows for an array of property names who's object values will be merged together. 1212 function mergeProps(propObjs, complexPropsMap) { 1213 var dest = {}; 1214 if (complexPropsMap) { 1215 for (var name_1 in complexPropsMap) { 1216 var complexObjs = []; 1217 // collect the trailing object values, stopping when a non-object is discovered 1218 for (var i = propObjs.length - 1; i >= 0; i--) { 1219 var val = propObjs[i][name_1]; 1220 if (typeof val === "object" && val) { 1221 // non-null object 1222 complexObjs.unshift(val); 1223 } else if (val !== undefined) { 1224 dest[name_1] = val; // if there were no objects, this value will be used 1225 break; 1226 } 1227 } 1228 // if the trailing values were objects, use the merged value 1229 if (complexObjs.length) { 1230 dest[name_1] = mergeProps(complexObjs); 1231 } 1232 } 1233 } 1234 // copy values into the destination, going from last to first 1235 for (var i = propObjs.length - 1; i >= 0; i--) { 1236 var props = propObjs[i]; 1237 for (var name_2 in props) { 1238 if (!(name_2 in dest)) { 1239 // if already assigned by previous props or complex props, don't reassign 1240 dest[name_2] = props[name_2]; 1241 } 1242 } 1243 } 1244 return dest; 1245 } 1246 function filterHash(hash, func) { 1247 var filtered = {}; 1248 for (var key in hash) { 1249 if (func(hash[key], key)) { 1250 filtered[key] = hash[key]; 1251 } 1252 } 1253 return filtered; 1254 } 1255 function mapHash(hash, func) { 1256 var newHash = {}; 1257 for (var key in hash) { 1258 newHash[key] = func(hash[key], key); 1259 } 1260 return newHash; 1261 } 1262 function arrayToHash(a) { 1263 var hash = {}; 1264 for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { 1265 var item = a_1[_i]; 1266 hash[item] = true; 1267 } 1268 return hash; 1269 } 1270 function buildHashFromArray(a, func) { 1271 var hash = {}; 1272 for (var i = 0; i < a.length; i++) { 1273 var tuple = func(a[i], i); 1274 hash[tuple[0]] = tuple[1]; 1275 } 1276 return hash; 1277 } 1278 function hashValuesToArray(obj) { 1279 var a = []; 1280 for (var key in obj) { 1281 a.push(obj[key]); 1282 } 1283 return a; 1284 } 1285 function isPropsEqual(obj0, obj1) { 1286 if (obj0 === obj1) { 1287 return true; 1288 } 1289 for (var key in obj0) { 1290 if (hasOwnProperty.call(obj0, key)) { 1291 if (!(key in obj1)) { 1292 return false;
1293 } 1294 } 1295 } 1296 for (var key in obj1) { 1297 if (hasOwnProperty.call(obj1, key)) { 1298 if (obj0[key] !== obj1[key]) { 1299 return false; 1300 } 1301 } 1302 } 1303 return true; 1304 } 1305 function getUnequalProps(obj0, obj1) { 1306 var keys = []; 1307 for (var key in obj0) { 1308 if (hasOwnProperty.call(obj0, key)) { 1309 if (!(key in obj1)) { 1310 keys.push(key); 1311 } 1312 } 1313 } 1314 for (var key in obj1) { 1315 if (hasOwnProperty.call(obj1, key)) { 1316 if (obj0[key] !== obj1[key]) { 1317 keys.push(key); 1318 } 1319 } 1320 } 1321 return keys; 1322 } 1323 function compareObjs(oldProps, newProps, equalityFuncs) { 1324 if (equalityFuncs === void 0) { 1325 equalityFuncs = {}; 1326 } 1327 if (oldProps === newProps) { 1328 return true; 1329 } 1330 for (var key in newProps) { 1331 if ( 1332 key in oldProps && 1333 isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key]) 1334 ); 1335 else { 1336 return false; 1337 } 1338 } 1339 // check for props that were omitted in the new 1340 for (var key in oldProps) { 1341 if (!(key in newProps)) { 1342 return false; 1343 } 1344 } 1345 return true; 1346 } 1347 /* 1348 assumed "true" equality for handler names like "onReceiveSomething" 1349 */ 1350 function isObjValsEqual(val0, val1, comparator) { 1351 if (val0 === val1 || comparator === true) { 1352 return true; 1353 } 1354 if (comparator) { 1355 return comparator(val0, val1); 1356 } 1357 return false; 1358 } 1359 function collectFromHash(hash, startIndex, endIndex, step) { 1360 if (startIndex === void 0) { 1361 startIndex = 0; 1362 } 1363 if (step === void 0) { 1364 step = 1; 1365 } 1366 var res = []; 1367 if (endIndex == null) { 1368 endIndex = Object.keys(hash).length; 1369 } 1370 for (var i = startIndex; i < endIndex; i += step) { 1371 var val = hash[i]; 1372 if (val !== undefined) { 1373 // will disregard undefined for sparse arrays 1374 res.push(val); 1375 } 1376 } 1377 return res; 1378 } 1379 1380 function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) { 1381 for (var i = 0; i < recurringTypes.length; i++) { 1382 var parsed = recurringTypes[i].parse(refined, dateEnv); 1383 if (parsed) { 1384 var allDay = refined.allDay; 1385 if (allDay == null) { 1386 allDay = defaultAllDay; 1387 if (allDay == null) { 1388 allDay = parsed.allDayGuess; 1389 if (allDay == null) { 1390 allDay = false; 1391 } 1392 } 1393 } 1394 return { 1395 allDay: allDay, 1396 duration: parsed.duration, 1397 typeData: parsed.typeData, 1398 typeId: i, 1399 }; 1400 } 1401 } 1402 return null; 1403 } 1404 function expandRecurring(eventStore, framingRange, context) { 1405 var dateEnv = context.dateEnv, 1406 pluginHooks = context.pluginHooks, 1407 options = context.options; 1408 var defs = eventStore.defs, 1409 instances = eventStore.instances; 1410 // remove existing recurring instances 1411 // TODO: bad. always expand events as a second step 1412 instances = filterHash(instances, function (instance) { 1413 return !defs[instance.defId].recurringDef; 1414 }); 1415 for (var defId in defs) { 1416 var def = defs[defId]; 1417 if (def.recurringDef) { 1418 var duration = def.recurringDef.duration; 1419 if (!duration) { 1420 duration = def.allDay 1421 ? options.defaultAllDayEventDuration 1422 : options.defaultTimedEventDuration; 1423 } 1424 var starts = expandRecurringRanges( 1425 def, 1426 duration, 1427 framingRange, 1428 dateEnv, 1429 pluginHooks.recurringTypes 1430 ); 1431 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) { 1432 var start = starts_1[_i]; 1433 var instance = createEventInstance(defId, { 1434 start: start, 1435 end: dateEnv.add(start, duration), 1436 }); 1437 instances[instance.instanceId] = instance; 1438 } 1439 } 1440 } 1441 return { defs: defs, instances: instances }; 1442 } 1443 /* 1444 Event MUST have a recurringDef 1445 */ 1446 function expandRecurringRanges( 1447 eventDef, 1448 duration, 1449 framingRange, 1450 dateEnv, 1451 recurringTypes 1452 ) { 1453 var typeDef = recurringTypes[eventDef.recurringDef.typeId]; 1454 var markers = typeDef.expand( 1455 eventDef.recurringDef.typeData, 1456 { 1457 start: dateEnv.subtract(framingRange.start, duration), 1458 end: framingRange.end, 1459 }, 1460 dateEnv 1461 ); 1462 // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to 1463 if (eventDef.allDay) { 1464 markers = markers.map(startOfDay); 1465 } 1466 return markers; 1467 } 1468 1469 var INTERNAL_UNITS = ["years", "months", "days", "milliseconds"];
1470 var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 1471 // Parsing and Creation 1472 function createDuration(input, unit) { 1473 var _a; 1474 if (typeof input === "string") { 1475 return parseString(input); 1476 } else if (typeof input === "object" && input) { 1477 // non-null object 1478 return parseObject(input); 1479 } else if (typeof input === "number") { 1480 return parseObject(((_a = {}), (_a[unit || "milliseconds"] = input), _a)); 1481 } else { 1482 return null; 1483 } 1484 } 1485 function parseString(s) { 1486 var m = PARSE_RE.exec(s); 1487 if (m) { 1488 var sign = m[1] ? -1 : 1; 1489 return { 1490 years: 0, 1491 months: 0, 1492 days: sign * (m[2] ? parseInt(m[2], 10) : 0), 1493 milliseconds: 1494 sign * 1495 ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours 1496 (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes 1497 (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds 1498 (m[6] ? parseInt(m[6], 10) : 0)), // ms 1499 }; 1500 } 1501 return null; 1502 } 1503 function parseObject(obj) { 1504 var duration = { 1505 years: obj.years || obj.year || 0, 1506 months: obj.months || obj.month || 0, 1507 days: obj.days || obj.day || 0, 1508 milliseconds: 1509 (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours 1510 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes 1511 (obj.seconds || obj.second || 0) * 1000 + // seconds 1512 (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms 1513 }; 1514 var weeks = obj.weeks || obj.week; 1515 if (weeks) { 1516 duration.days += weeks * 7; 1517 duration.specifiedWeeks = true; 1518 } 1519 return duration; 1520 } 1521 // Equality 1522 function durationsEqual(d0, d1) { 1523 return ( 1524 d0.years === d1.years && 1525 d0.months === d1.months && 1526 d0.days === d1.days && 1527 d0.milliseconds === d1.milliseconds 1528 ); 1529 } 1530 function asCleanDays(dur) { 1531 if (!dur.years && !dur.months && !dur.milliseconds) { 1532 return dur.days; 1533 } 1534 return 0; 1535 } 1536 // Simple Math 1537 function addDurations(d0, d1) { 1538 return { 1539 years: d0.years + d1.years, 1540 months: d0.months + d1.months, 1541 days: d0.days + d1.days, 1542 milliseconds: d0.milliseconds + d1.milliseconds, 1543 }; 1544 } 1545 function subtractDurations(d1, d0) { 1546 return { 1547 years: d1.years - d0.years, 1548 months: d1.months - d0.months, 1549 days: d1.days - d0.days, 1550 milliseconds: d1.milliseconds - d0.milliseconds, 1551 }; 1552 } 1553 function multiplyDuration(d, n) { 1554 return { 1555 years: d.years * n, 1556 months: d.months * n, 1557 days: d.days * n, 1558 milliseconds: d.milliseconds * n, 1559 }; 1560 } 1561 // Conversions 1562 // "Rough" because they are based on average-case Gregorian months/years 1563 function asRoughYears(dur) { 1564 return asRoughDays(dur) / 365; 1565 } 1566 function asRoughMonths(dur) { 1567 return asRoughDays(dur) / 30; 1568 } 1569 function asRoughDays(dur) { 1570 return asRoughMs(dur) / 864e5; 1571 } 1572 function asRoughMinutes(dur) { 1573 return asRoughMs(dur) / (1000 * 60); 1574 } 1575 function asRoughSeconds(dur) { 1576 return asRoughMs(dur) / 1000; 1577 } 1578 function asRoughMs(dur) { 1579 return ( 1580 dur.years * (365 * 864e5) + 1581 dur.months * (30 * 864e5) + 1582 dur.days * 864e5 + 1583 dur.milliseconds 1584 ); 1585 } 1586 // Advanced Math 1587 function wholeDivideDurations(numerator, denominator) { 1588 var res = null; 1589 for (var i = 0; i < INTERNAL_UNITS.length; i++) { 1590 var unit = INTERNAL_UNITS[i]; 1591 if (denominator[unit]) { 1592 var localRes = numerator[unit] / denominator[unit]; 1593 if (!isInt(localRes) || (res !== null && res !== localRes)) { 1594 return null; 1595 } 1596 res = localRes; 1597 } else if (numerator[unit]) { 1598 // needs to divide by something but can't! 1599 return null; 1600 } 1601 } 1602 return res; 1603 } 1604 function greatestDurationDenominator(dur) { 1605 var ms = dur.milliseconds; 1606 if (ms) { 1607 if (ms % 1000 !== 0) { 1608 return { unit: "millisecond", value: ms }; 1609 } 1610 if (ms % (1000 * 60) !== 0) { 1611 return { unit: "second", value: ms / 1000 }; 1612 } 1613 if (ms % (1000 * 60 * 60) !== 0) { 1614 return { unit: "minute", value: ms / (1000 * 60) }; 1615 } 1616 if (ms) { 1617 return { unit: "hour", value: ms / (1000 * 60 * 60) }; 1618 } 1619 } 1620 if (dur.days) { 1621 if (dur.specifiedWeeks && dur.days % 7 === 0) { 1622 return { unit: "week", value: dur.days / 7 }; 1623 } 1624 return { unit: "day", value: dur.days }; 1625 } 1626 if (dur.months) { 1627 return { unit: "month", value: dur.months }; 1628 } 1629 if (dur.years) { 1630 return { unit: "year", value: dur.years }; 1631 } 1632 return { unit: "millisecond", value: 0 }; 1633 } 1634 1635 // timeZoneOffset is in minutes 1636 function buildIsoString(marker, timeZoneOffset, stripZeroTime) { 1637 if (stripZeroTime === void 0) {
1638 stripZeroTime = false; 1639 } 1640 var s = marker.toISOString(); 1641 s = s.replace(".000", ""); 1642 if (stripZeroTime) { 1643 s = s.replace("T00:00:00Z", ""); 1644 } 1645 if (s.length > 10) { 1646 // time part wasn't stripped, can add timezone info 1647 if (timeZoneOffset == null) { 1648 s = s.replace("Z", ""); 1649 } else if (timeZoneOffset !== 0) { 1650 s = s.replace("Z", formatTimeZoneOffset(timeZoneOffset, true)); 1651 } 1652 // otherwise, its UTC-0 and we want to keep the Z 1653 } 1654 return s; 1655 } 1656 // formats the date, but with no time part 1657 // TODO: somehow merge with buildIsoString and stripZeroTime 1658 // TODO: rename. omit "string" 1659 function formatDayString(marker) { 1660 return marker.toISOString().replace(/T.*$/, ""); 1661 } 1662 // TODO: use Date::toISOString and use everything after the T? 1663 function formatIsoTimeString(marker) { 1664 return ( 1665 padStart(marker.getUTCHours(), 2) + 1666 ":" + 1667 padStart(marker.getUTCMinutes(), 2) + 1668 ":" + 1669 padStart(marker.getUTCSeconds(), 2) 1670 ); 1671 } 1672 function formatTimeZoneOffset(minutes, doIso) { 1673 if (doIso === void 0) { 1674 doIso = false; 1675 } 1676 var sign = minutes < 0 ? "-" : "+"; 1677 var abs = Math.abs(minutes); 1678 var hours = Math.floor(abs / 60); 1679 var mins = Math.round(abs % 60); 1680 if (doIso) { 1681 return sign + padStart(hours, 2) + ":" + padStart(mins, 2); 1682 } else { 1683 return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : ""); 1684 } 1685 } 1686 1687 // TODO: new util arrayify? 1688 function removeExact(array, exactVal) { 1689 var removeCnt = 0; 1690 var i = 0; 1691 while (i < array.length) { 1692 if (array[i] === exactVal) { 1693 array.splice(i, 1); 1694 removeCnt++; 1695 } else { 1696 i++; 1697 } 1698 } 1699 return removeCnt; 1700 } 1701 function isArraysEqual(a0, a1, equalityFunc) { 1702 if (a0 === a1) { 1703 return true; 1704 } 1705 var len = a0.length; 1706 var i; 1707 if (len !== a1.length) { 1708 // not array? or not same length? 1709 return false; 1710 } 1711 for (i = 0; i < len; i++) { 1712 if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) { 1713 return false; 1714 } 1715 } 1716 return true; 1717 } 1718 1719 function memoize(workerFunc, resEquality, teardownFunc) { 1720 var currentArgs; 1721 var currentRes; 1722 return function () { 1723 var newArgs = []; 1724 for (var _i = 0; _i < arguments.length; _i++) { 1725 newArgs[_i] = arguments[_i]; 1726 } 1727 if (!currentArgs) { 1728 currentRes = workerFunc.apply(this, newArgs); 1729 } else if (!isArraysEqual(currentArgs, newArgs)) { 1730 if (teardownFunc) { 1731 teardownFunc(currentRes); 1732 } 1733 var res = workerFunc.apply(this, newArgs); 1734 if (!resEquality || !resEquality(res, currentRes)) { 1735 currentRes = res; 1736 } 1737 } 1738 currentArgs = newArgs; 1739 return currentRes; 1740 }; 1741 } 1742 function memoizeObjArg(workerFunc, resEquality, teardownFunc) { 1743 var currentArg; 1744 var currentRes; 1745 return function (newArg) { 1746 if (!currentArg) { 1747 currentRes = workerFunc.call(this, newArg); 1748 } else if (!isPropsEqual(currentArg, newArg)) { 1749 if (teardownFunc) { 1750 teardownFunc(currentRes); 1751 } 1752 var res = workerFunc.call(this, newArg); 1753 if (!resEquality || !resEquality(res, currentRes)) { 1754 currentRes = res; 1755 } 1756 } 1757 currentArg = newArg; 1758 return currentRes; 1759 }; 1760 } 1761 function memoizeArraylike(workerFunc, resEquality, teardownFunc) { 1762 // used at all? 1763 var currentArgSets = []; 1764 var currentResults = []; 1765 return function (newArgSets) { 1766 var currentLen = currentArgSets.length; 1767 var newLen = newArgSets.length; 1768 var i = 0; 1769 for (; i < currentLen; i++) { 1770 if (!newArgSets[i]) { 1771 // one of the old sets no longer exists 1772 if (teardownFunc) { 1773 teardownFunc(currentResults[i]); 1774 } 1775 } else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) { 1776 if (teardownFunc) { 1777 teardownFunc(currentResults[i]); 1778 } 1779 var res = workerFunc.apply(this, newArgSets[i]); 1780 if (!resEquality || !resEquality(res, currentResults[i])) { 1781 currentResults[i] = res; 1782 } 1783 } 1784 } 1785 for (; i < newLen; i++) { 1786 currentResults[i] = workerFunc.apply(this, newArgSets[i]); 1787 } 1788 currentArgSets = newArgSets; 1789 currentResults.splice(newLen); // remove excess 1790 return currentResults; 1791 }; 1792 } 1793 function memoizeHashlike( // used? 1794 workerFunc, 1795 resEquality, 1796 teardownFunc // TODO: change arg order 1797 ) { 1798 var currentArgHash = {}; 1799 var currentResHash = {}; 1800 return function (newArgHash) { 1801 var newResHash = {}; 1802 for (var key in newArgHash) { 1803 if (!currentResHash[key]) { 1804 newResHash[key] = workerFunc.apply(this, newArgHash[key]); 1805 } else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) { 1806 if (teardownFunc) { 1807 teardownFunc(currentResHash[key]); 1808 } 1809 var res = workerFunc.apply(this, newArgHash[key]); 1810 newResHash[key] = 1811 resEquality && resEquality(res, currentResHash[key]) 1812 ? currentResHash[key] 1813 : res; 1814 } else { 1815 newResHash[key] = currentResHash[key]; 1816 } 1817 } 1818 currentArgHash = newArgHash; 1819 currentResHash = newResHash; 1820 return newResHash; 1821 }; 1822 } 1823 1824 var EXTENDED_SETTINGS_AND_SEVERITIES = { 1825 week: 3, 1826 separator: 0, 1827 omitZeroMinute: 0, 1828 meridiem: 0, 1829 omitCommas: 0, 1830 }; 1831 var STANDARD_DATE_PROP_SEVERITIES = { 1832 timeZoneName: 7, 1833 era: 6, 1834 year: 5, 1835 month: 4, 1836 day: 2, 1837 weekday: 2, 1838 hour: 1, 1839 minute: 1, 1840 second: 1, 1841 }; 1842 var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1842 // eats up leading spaces too 1843 var COMMA_RE = /,/g; // we need re for globalness 1844 var MULTI_SPACE_RE = /\s+/g; 1845 var LTR_RE = /\u200e/g; // control character 1846 var UTC_RE = /UTC|GMT/; 1847 var NativeFormatter = /** @class */ (function () { 1848 function NativeFormatter(formatSettings) { 1849 var standardDateProps = {}; 1850 var extendedSettings = {}; 1851 var severity = 0; 1852 for (var name_1 in formatSettings) { 1853 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) { 1854 extendedSettings[name_1] = formatSettings[name_1]; 1855 severity = Math.max( 1856 EXTENDED_SETTINGS_AND_SEVERITIES[name_1], 1857 severity 1858 ); 1859 } else { 1860 standardDateProps[name_1] = formatSettings[name_1]; 1861 if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { 1862 // TODO: what about hour12? no severity 1863 severity = Math.max( 1864 STANDARD_DATE_PROP_SEVERITIES[name_1], 1865 severity 1866 ); 1867 } 1868 } 1869 } 1870 this.standardDateProps = standardDateProps; 1871 this.extendedSettings = extendedSettings; 1872 this.severity = severity; 1873 this.buildFormattingFunc = memoize(buildFormattingFunc); 1874 } 1875 NativeFormatter.prototype.format = function (date, context) { 1876 return this.buildFormattingFunc( 1877 this.standardDateProps, 1878 this.extendedSettings, 1879 context 1880 )(date); 1881 }; 1882 NativeFormatter.prototype.formatRange = function ( 1883 start, 1884 end, 1885 context, 1886 betterDefaultSeparator 1887 ) { 1888 var _a = this, 1889 standardDateProps = _a.standardDateProps, 1890 extendedSettings = _a.extendedSettings; 1891 var diffSeverity = computeMarkerDiffSeverity( 1892 start.marker, 1893 end.marker, 1894 context.calendarSystem 1895 ); 1896 if (!diffSeverity) { 1897 return this.format(start, context); 1898 } 1899 var biggestUnitForPartial = diffSeverity; 1900 if ( 1901 biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1902 (standardDateProps.year === "numeric" || 1903 standardDateProps.year === "2-digit") && 1904 (standardDateProps.month === "numeric" || 1905 standardDateProps.month === "2-digit") && 1906 (standardDateProps.day === "numeric" || 1907 standardDateProps.day === "2-digit") 1908 ) { 1909 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time 1910 } 1911 var full0 = this.format(start, context); 1912 var full1 = this.format(end, context); 1913 if (full0 === full1) { 1914 return full0; 1915 } 1916 var partialDateProps = computePartialFormattingOptions( 1917 standardDateProps, 1918 biggestUnitForPartial 1919 ); 1920 var partialFormattingFunc = buildFormattingFunc( 1921 partialDateProps, 1922 extendedSettings, 1923 context 1924 ); 1925 var partial0 = partialFormattingFunc(start); 1926 var partial1 = partialFormattingFunc(end); 1927 var insertion = findCommonInsertion(full0, partial0, full1, partial1); 1928 var separator = 1929 extendedSettings.separator || 1930 betterDefaultSeparator || 1931 context.defaultSeparator || 1932 ""; 1933 if (insertion) { 1934 return ( 1935 insertion.before + partial0 + separator + partial1 + insertion.after 1936 ); 1937 } 1938 return full0 + separator + full1; 1939 }; 1940 NativeFormatter.prototype.getLargestUnit = function () { 1941 switch (this.severity) { 1942 case 7: 1943 case 6: 1944 case 5: 1945 return "year"; 1946 case 4: 1947 return "month"; 1948 case 3: 1949 return "week"; 1950 case 2: 1951 return "day"; 1952 default: 1953 return "time"; // really? 1954 } 1955 }; 1956 return NativeFormatter; 1957 })(); 1958 function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1959 var standardDatePropCnt = Object.keys(standardDateProps).length; 1960 if ( 1961 standardDatePropCnt === 1 && 1962 standardDateProps.timeZoneName === "short" 1963 ) { 1964 return function (date) { 1965 return formatTimeZoneOffset(date.timeZoneOffset); 1966 }; 1967 } 1968 if (standardDatePropCnt === 0 && extendedSettings.week) { 1969 return function (date) { 1970 return formatWeekNumber( 1971 context.computeWeekNumber(date.marker), 1972 context.weekText, 1973 context.locale, 1974 extendedSettings.week 1975 ); 1976 }; 1977 } 1978 return buildNativeFormattingFunc( 1979 standardDateProps, 1980 extendedSettings, 1981 context 1982 ); 1983 } 1984 function buildNativeFormattingFunc( 1985 standardDateProps, 1986 extendedSettings, 1987 context 1988 ) { 1989 standardDateProps = __assign({}, standardDateProps); // copy 1990 extendedSettings = __assign({}, extendedSettings); // copy 1991 sanitizeSettings(standardDateProps, extendedSettings); 1992 standardDateProps.timeZone = "UTC";
1992 // we leverage the only guaranteed timeZone for our UTC markers 1993 var normalFormat = new Intl.DateTimeFormat( 1994 context.locale.codes, 1995 standardDateProps 1996 ); 1997 var zeroFormat; // needed? 1998 if (extendedSettings.omitZeroMinute) { 1999 var zeroProps = __assign({}, standardDateProps); 2000 delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings 2001 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 2002 } 2003 return function (date) { 2004 var marker = date.marker; 2005 var format; 2006 if (zeroFormat && !marker.getUTCMinutes()) { 2007 format = zeroFormat; 2008 } else { 2009 format = normalFormat; 2010 } 2011 var s = format.format(marker); 2012 return postProcess(s, date, standardDateProps, extendedSettings, context); 2013 }; 2014 } 2015 function sanitizeSettings(standardDateProps, extendedSettings) { 2016 // deal with a browser inconsistency where formatting the timezone 2017 // requires that the hour/minute be present. 2018 if (standardDateProps.timeZoneName) { 2019 if (!standardDateProps.hour) { 2020 standardDateProps.hour = "2-digit"; 2021 } 2022 if (!standardDateProps.minute) { 2023 standardDateProps.minute = "2-digit"; 2024 } 2025 } 2026 // only support short timezone names 2027 if (standardDateProps.timeZoneName === "long") { 2028 standardDateProps.timeZoneName = "short"; 2029 } 2030 // if requesting to display seconds, MUST display minutes 2031 if ( 2032 extendedSettings.omitZeroMinute && 2033 (standardDateProps.second || standardDateProps.millisecond) 2034 ) { 2035 delete extendedSettings.omitZeroMinute; 2036 } 2037 } 2038 function postProcess(s, date, standardDateProps, extendedSettings, context) { 2039 s = s.replace(LTR_RE, ""); // remove left-to-right control chars. do first. good for other regexes 2040 if (standardDateProps.timeZoneName === "short") { 2041 s = injectTzoStr( 2042 s, 2043 context.timeZone === "UTC" || date.timeZoneOffset == null 2044 ? "UTC" // important to normalize for IE, which does "GMT" 2045 : formatTimeZoneOffset(date.timeZoneOffset) 2046 ); 2047 } 2048 if (extendedSettings.omitCommas) { 2049 s = s.replace(COMMA_RE, "").trim(); 2050 } 2051 if (extendedSettings.omitZeroMinute) { 2052 s = s.replace(":00", ""); // zeroFormat doesn't always achieve this 2053 } 2054 // ^ do anything that might create adjacent spaces before this point, 2055 // because MERIDIEM_RE likes to eat up loading spaces 2056 if (extendedSettings.meridiem === false) { 2057 s = s.replace(MERIDIEM_RE, "").trim(); 2058 } else if (extendedSettings.meridiem === "narrow") { 2059 // a/p 2060 s = s.replace(MERIDIEM_RE, function (m0, m1) { 2061 return m1.toLocaleLowerCase(); 2062 }); 2063 } else if (extendedSettings.meridiem === "short") { 2064 // am/pm 2065 s = s.replace(MERIDIEM_RE, function (m0, m1) { 2066 return m1.toLocaleLowerCase() + "m"; 2067 }); 2068 } else if (extendedSettings.meridiem === "lowercase") { 2069 // other meridiem transformers already converted to lowercase 2070 s = s.replace(MERIDIEM_RE, function (m0) { 2071 return m0.toLocaleLowerCase(); 2072 }); 2073 } 2074 s = s.replace(MULTI_SPACE_RE, " "); 2075 s = s.trim(); 2076 return s; 2077 } 2078 function injectTzoStr(s, tzoStr) { 2079 var replaced = false; 2080 s = s.replace(UTC_RE, function () { 2081 replaced = true; 2082 return tzoStr; 2083 }); 2084 // IE11 doesn't include UTC/GMT in the original string, so append to end 2085 if (!replaced) { 2086 s += " " + tzoStr; 2087 } 2088 return s; 2089 } 2090 function formatWeekNumber(num, weekText, locale, display) { 2091 var parts = []; 2092 if (display === "narrow") { 2093 parts.push(weekText); 2094 } else if (display === "short") { 2095 parts.push(weekText, " "); 2096 } 2097 // otherwise, considered 'numeric' 2098 parts.push(locale.simpleNumberFormat.format(num)); 2099 if (locale.options.direction === "rtl") { 2100 // TODO: use control characters instead? 2101 parts.reverse(); 2102 } 2103 return parts.join(""); 2104 } 2105 // Range Formatting Utils 2106 // 0 = exactly the same 2107 // 1 = different by time 2108 // and bigger 2109 function computeMarkerDiffSeverity(d0, d1, ca) { 2110 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 2111 return 5; 2112 } 2113 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 2114 return 4; 2115 } 2116 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 2117 return 2; 2118 } 2119 if (timeAsMs(d0) !== timeAsMs(d1)) { 2120 return 1; 2121 } 2122 return 0; 2123 } 2124 function computePartialFormattingOptions(options, biggestUnit) { 2125 var partialOptions = {}; 2126 for (var name_2 in options) { 2127 if ( 2128 !(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 2129 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit 2130 ) { 2131 partialOptions[name_2] = options[name_2]; 2132 } 2133 } 2134 return partialOptions; 2135 } 2136 function findCommonInsertion(full0, partial0, full1, partial1) { 2137 var i0 = 0; 2138 while (i0 < full0.length) { 2139 var found0 = full0.indexOf(partial0, i0); 2140 if (found0 === -1) { 2141 break; 2142 } 2143 var before0 = full0.substr(0, found0); 2144 i0 = found0 + partial0.length; 2145 var after0 = full0.substr(i0); 2146 var i1 = 0; 2147 while (i1 < full1.length) { 2148 var found1 = full1.indexOf(partial1, i1);
2149 if (found1 === -1) { 2150 break; 2151 } 2152 var before1 = full1.substr(0, found1); 2153 i1 = found1 + partial1.length; 2154 var after1 = full1.substr(i1); 2155 if (before0 === before1 && after0 === after1) { 2156 return { 2157 before: before0, 2158 after: after0, 2159 }; 2160 } 2161 } 2162 } 2163 return null; 2164 } 2165 2166 function expandZonedMarker(dateInfo, calendarSystem) { 2167 var a = calendarSystem.markerToArray(dateInfo.marker); 2168 return { 2169 marker: dateInfo.marker, 2170 timeZoneOffset: dateInfo.timeZoneOffset, 2171 array: a, 2172 year: a[0], 2173 month: a[1], 2174 day: a[2], 2175 hour: a[3], 2176 minute: a[4], 2177 second: a[5], 2178 millisecond: a[6], 2179 }; 2180 } 2181 2182 function createVerboseFormattingArg( 2183 start, 2184 end, 2185 context, 2186 betterDefaultSeparator 2187 ) { 2188 var startInfo = expandZonedMarker(start, context.calendarSystem); 2189 var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 2190 return { 2191 date: startInfo, 2192 start: startInfo, 2193 end: endInfo, 2194 timeZone: context.timeZone, 2195 localeCodes: context.locale.codes, 2196 defaultSeparator: betterDefaultSeparator || context.defaultSeparator, 2197 }; 2198 } 2199 2200 /* 2201 TODO: fix the terminology of "formatter" vs "formatting func" 2202 */ 2203 /* 2204 At the time of instantiation, this object does not know which cmd-formatting system it will use. 2205 It receives this at the time of formatting, as a setting. 2206 */ 2207 var CmdFormatter = /** @class */ (function () { 2208 function CmdFormatter(cmdStr) { 2209 this.cmdStr = cmdStr; 2210 } 2211 CmdFormatter.prototype.format = function ( 2212 date, 2213 context, 2214 betterDefaultSeparator 2215 ) { 2216 return context.cmdFormatter( 2217 this.cmdStr, 2218 createVerboseFormattingArg(date, null, context, betterDefaultSeparator) 2219 ); 2220 }; 2221 CmdFormatter.prototype.formatRange = function ( 2222 start, 2223 end, 2224 context, 2225 betterDefaultSeparator 2226 ) { 2227 return context.cmdFormatter( 2228 this.cmdStr, 2229 createVerboseFormattingArg(start, end, context, betterDefaultSeparator) 2230 ); 2231 }; 2232 return CmdFormatter; 2233 })(); 2234 2235 var FuncFormatter = /** @class */ (function () { 2236 function FuncFormatter(func) { 2237 this.func = func; 2238 } 2239 FuncFormatter.prototype.format = function ( 2240 date, 2241 context, 2242 betterDefaultSeparator 2243 ) { 2244 return this.func( 2245 createVerboseFormattingArg(date, null, context, betterDefaultSeparator) 2246 ); 2247 }; 2248 FuncFormatter.prototype.formatRange = function ( 2249 start, 2250 end, 2251 context, 2252 betterDefaultSeparator 2253 ) { 2254 return this.func( 2255 createVerboseFormattingArg(start, end, context, betterDefaultSeparator) 2256 ); 2257 }; 2258 return FuncFormatter; 2259 })(); 2260 2261 function createFormatter(input) { 2262 if (typeof input === "object" && input) { 2263 // non-null object 2264 return new NativeFormatter(input); 2265 } else if (typeof input === "string") { 2266 return new CmdFormatter(input); 2267 } else if (typeof input === "function") { 2268 return new FuncFormatter(input); 2269 } 2270 } 2271 2272 // base options 2273 // ------------ 2274 var BASE_OPTION_REFINERS = { 2275 navLinkDayClick: identity, 2276 navLinkWeekClick: identity, 2277 duration: createDuration, 2278 bootstrapFontAwesome: identity, 2279 buttonIcons: identity, 2280 customButtons: identity, 2281 defaultAllDayEventDuration: createDuration, 2282 defaultTimedEventDuration: createDuration, 2283 nextDayThreshold: createDuration, 2284 scrollTime: createDuration, 2285 slotMinTime: createDuration, 2286 slotMaxTime: createDuration, 2287 dayPopoverFormat: createFormatter, 2288 slotDuration: createDuration, 2289 snapDuration: createDuration, 2290 headerToolbar: identity, 2291 footerToolbar: identity, 2292 defaultRangeSeparator: String, 2293 titleRangeSeparator: String, 2294 forceEventDuration: Boolean, 2295 dayHeaders: Boolean, 2296 dayHeaderFormat: createFormatter, 2297 dayHeaderClassNames: identity, 2298 dayHeaderContent: identity, 2299 dayHeaderDidMount: identity, 2300 dayHeaderWillUnmount: identity, 2301 dayCellClassNames: identity, 2302 dayCellContent: identity, 2303 dayCellDidMount: identity, 2304 dayCellWillUnmount: identity, 2305 initialView: String, 2306 aspectRatio: Number, 2307 weekends: Boolean, 2308 weekNumberCalculation: identity, 2309 weekNumbers: Boolean, 2310 weekNumberClassNames: identity, 2311 weekNumberContent: identity, 2312 weekNumberDidMount: identity, 2313 weekNumberWillUnmount: identity, 2314 editable: Boolean, 2315 viewClassNames: identity, 2316 viewDidMount: identity, 2317 viewWillUnmount: identity, 2318 nowIndicator: Boolean, 2319 nowIndicatorClassNames: identity, 2320 nowIndicatorContent: identity, 2321 nowIndicatorDidMount: identity, 2322 nowIndicatorWillUnmount: identity, 2323 showNonCurrentDates: Boolean, 2324 lazyFetching: Boolean, 2325 startParam: String, 2326 endParam: String, 2327 timeZoneParam: String, 2328 timeZone: String, 2329 locales: identity, 2330 locale: identity, 2331 themeSystem: String, 2332 dragRevertDuration: Number, 2333 dragScroll: Boolean, 2334 allDayMaintainDuration: Boolean, 2335 unselectAuto: Boolean, 2336 dropAccept: identity, 2337 eventOrder: parseFieldSpecs, 2338 handleWindowResize: Boolean, 2339 windowResizeDelay: Number, 2340 longPressDelay: Number, 2341 eventDragMinDistance: Number, 2342 expandRows: Boolean, 2343 height: identity, 2344 contentHeight: identity, 2345 direction: String, 2346 weekNumberFormat: createFormatter, 2347 eventResizableFromStart: Boolean, 2348 displayEventTime: Boolean, 2349 displayEventEnd: Boolean, 2350 weekText: String, 2351 progressiveEventRendering: Boolean, 2352 businessHours: identity, 2353 initialDate: identity, 2354 now: identity, 2355 eventDataTransform: identity, 2356 stickyHeaderDates: identity, 2357 stickyFooterScrollbar: identity, 2358 viewHeight: identity, 2359 defaultAllDay: Boolean, 2360 eventSourceFailure: identity, 2361 eventSourceSuccess: identity, 2362 eventDisplay: String, 2363 eventStartEditable: Boolean, 2364 eventDurationEditable: Boolean, 2365 eventOverlap: identity, 2366 eventConstraint: identity, 2367 eventAllow: identity,
2368 eventBackgroundColor: String, 2369 eventBorderColor: String, 2370 eventTextColor: String, 2371 eventColor: String, 2372 eventClassNames: identity, 2373 eventContent: identity, 2374 eventDidMount: identity, 2375 eventWillUnmount: identity, 2376 selectConstraint: identity, 2377 selectOverlap: identity, 2378 selectAllow: identity, 2379 droppable: Boolean, 2380 unselectCancel: String, 2381 slotLabelFormat: identity, 2382 slotLaneClassNames: identity, 2383 slotLaneContent: identity, 2384 slotLaneDidMount: identity, 2385 slotLaneWillUnmount: identity, 2386 slotLabelClassNames: identity, 2387 slotLabelContent: identity, 2388 slotLabelDidMount: identity, 2389 slotLabelWillUnmount: identity, 2390 dayMaxEvents: identity, 2391 dayMaxEventRows: identity, 2392 dayMinWidth: Number, 2393 slotLabelInterval: createDuration, 2394 allDayText: String, 2395 allDayClassNames: identity, 2396 allDayContent: identity, 2397 allDayDidMount: identity, 2398 allDayWillUnmount: identity, 2399 slotMinWidth: Number, 2400 navLinks: Boolean, 2401 eventTimeFormat: createFormatter, 2402 rerenderDelay: Number, 2403 moreLinkText: identity, 2404 selectMinDistance: Number, 2405 selectable: Boolean, 2406 selectLongPressDelay: Number, 2407 eventLongPressDelay: Number, 2408 selectMirror: Boolean, 2409 eventMinHeight: Number, 2410 slotEventOverlap: Boolean, 2411 plugins: identity, 2412 firstDay: Number, 2413 dayCount: Number, 2414 dateAlignment: String, 2415 dateIncrement: createDuration, 2416 hiddenDays: identity, 2417 monthMode: Boolean, 2418 fixedWeekCount: Boolean, 2419 validRange: identity, 2420 visibleRange: identity, 2421 titleFormat: identity, 2422 // only used by list-view, but languages define the value, so we need it in base options 2423 noEventsText: String, 2424 }; 2425 // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results. 2426 // raw values. 2427 var BASE_OPTION_DEFAULTS = { 2428 eventDisplay: "auto", 2429 defaultRangeSeparator: " - ", 2430 titleRangeSeparator: " \u2013 ", 2431 defaultTimedEventDuration: "01:00:00", 2432 defaultAllDayEventDuration: { day: 1 }, 2433 forceEventDuration: false, 2434 nextDayThreshold: "00:00:00", 2435 dayHeaders: true, 2436 initialView: "", 2437 aspectRatio: 1.35, 2438 headerToolbar: { 2439 start: "title", 2440 center: "", 2441 end: "today prev,next", 2442 }, 2443 weekends: true, 2444 weekNumbers: false, 2445 weekNumberCalculation: "local", 2446 editable: false, 2447 nowIndicator: false, 2448 scrollTime: "06:00:00", 2449 slotMinTime: "00:00:00", 2450 slotMaxTime: "24:00:00", 2451 showNonCurrentDates: true, 2452 lazyFetching: true, 2453 startParam: "start", 2454 endParam: "end", 2455 timeZoneParam: "timeZone", 2456 timeZone: "local", 2457 locales: [], 2458 locale: "", 2459 themeSystem: "standard", 2460 dragRevertDuration: 500, 2461 dragScroll: true, 2462 allDayMaintainDuration: false, 2463 unselectAuto: true, 2464 dropAccept: "*", 2465 eventOrder: "start,-duration,allDay,title", 2466 dayPopoverFormat: { month: "long", day: "numeric", year: "numeric" }, 2467 handleWindowResize: true, 2468 windowResizeDelay: 100, 2469 longPressDelay: 1000, 2470 eventDragMinDistance: 5, 2471 expandRows: false, 2472 navLinks: false, 2473 selectable: false, 2474 }; 2475 // calendar listeners 2476 // ------------------ 2477 var CALENDAR_LISTENER_REFINERS = { 2478 datesSet: identity, 2479 eventsSet: identity, 2480 eventAdd: identity, 2481 eventChange: identity, 2482 eventRemove: identity, 2483 windowResize: identity, 2484 eventClick: identity, 2485 eventMouseEnter: identity, 2486 eventMouseLeave: identity, 2487 select: identity, 2488 unselect: identity, 2489 loading: identity, 2490 // internal 2491 _unmount: identity, 2492 _beforeprint: identity, 2493 _afterprint: identity, 2494 _noEventDrop: identity, 2495 _noEventResize: identity, 2496 _resize: identity, 2497 _scrollRequest: identity, 2498 }; 2499 // calendar-specific options 2500 // ------------------------- 2501 var CALENDAR_OPTION_REFINERS = { 2502 buttonText: identity, 2503 views: identity, 2504 plugins: identity, 2505 initialEvents: identity, 2506 events: identity, 2507 eventSources: identity, 2508 }; 2509 var COMPLEX_OPTION_COMPARATORS = { 2510 headerToolbar: isBoolComplexEqual, 2511 footerToolbar: isBoolComplexEqual, 2512 buttonText: isBoolComplexEqual, 2513 buttonIcons: isBoolComplexEqual, 2514 }; 2515 function isBoolComplexEqual(a, b) { 2516 if (typeof a === "object" && typeof b === "object" && a && b) { 2517 // both non-null objects 2518 return isPropsEqual(a, b); 2519 } else { 2520 return a === b; 2521 } 2522 } 2523 // view-specific options 2524 // --------------------- 2525 var VIEW_OPTION_REFINERS = { 2526 type: String, 2527 component: identity, 2528 buttonText: String, 2529 buttonTextKey: String,
2530 dateProfileGeneratorClass: identity, 2531 usesMinMaxTime: Boolean, 2532 classNames: identity, 2533 content: identity, 2534 didMount: identity, 2535 willUnmount: identity, 2536 }; 2537 // util funcs 2538 // ---------------------------------------------------------------------------------------------------- 2539 function mergeRawOptions(optionSets) { 2540 return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS); 2541 } 2542 function refineProps(input, refiners) { 2543 var refined = {}; 2544 var extra = {}; 2545 for (var propName in refiners) { 2546 if (propName in input) { 2547 refined[propName] = refiners[propName](input[propName]); 2548 } 2549 } 2550 for (var propName in input) { 2551 if (!(propName in refiners)) { 2552 extra[propName] = input[propName]; 2553 } 2554 } 2555 return { refined: refined, extra: extra }; 2556 } 2557 function identity(raw) { 2558 return raw; 2559 } 2560 2561 function parseEvents(rawEvents, eventSource, context, allowOpenRange) { 2562 var eventStore = createEmptyEventStore(); 2563 var eventRefiners = buildEventRefiners(context); 2564 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 2565 var rawEvent = rawEvents_1[_i]; 2566 var tuple = parseEvent( 2567 rawEvent, 2568 eventSource, 2569 context, 2570 allowOpenRange, 2571 eventRefiners 2572 ); 2573 if (tuple) { 2574 eventTupleToStore(tuple, eventStore); 2575 } 2576 } 2577 return eventStore; 2578 } 2579 function eventTupleToStore(tuple, eventStore) { 2580 if (eventStore === void 0) { 2581 eventStore = createEmptyEventStore(); 2582 } 2583 eventStore.defs[tuple.def.defId] = tuple.def; 2584 if (tuple.instance) { 2585 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 2586 } 2587 return eventStore; 2588 } 2589 // retrieves events that have the same groupId as the instance specified by `instanceId` 2590 // or they are the same as the instance. 2591 // why might instanceId not be in the store? an event from another calendar? 2592 function getRelevantEvents(eventStore, instanceId) { 2593 var instance = eventStore.instances[instanceId]; 2594 if (instance) { 2595 var def_1 = eventStore.defs[instance.defId]; 2596 // get events/instances with same group 2597 var newStore = filterEventStoreDefs(eventStore, function (lookDef) { 2598 return isEventDefsGrouped(def_1, lookDef); 2599 }); 2600 // add the original 2601 // TODO: wish we could use eventTupleToStore or something like it 2602 newStore.defs[def_1.defId] = def_1; 2603 newStore.instances[instance.instanceId] = instance; 2604 return newStore; 2605 } 2606 return createEmptyEventStore(); 2607 } 2608 function isEventDefsGrouped(def0, def1) { 2609 return Boolean(def0.groupId && def0.groupId === def1.groupId); 2610 } 2611 function createEmptyEventStore() { 2612 return { defs: {}, instances: {} }; 2613 } 2614 function mergeEventStores(store0, store1) { 2615 return { 2616 defs: __assign(__assign({}, store0.defs), store1.defs), 2617 instances: __assign(__assign({}, store0.instances), store1.instances), 2618 }; 2619 } 2620 function filterEventStoreDefs(eventStore, filterFunc) { 2621 var defs = filterHash(eventStore.defs, filterFunc); 2622 var instances = filterHash(eventStore.instances, function (instance) { 2623 return defs[instance.defId]; // still exists? 2624 }); 2625 return { defs: defs, instances: instances }; 2626 } 2627 function excludeSubEventStore(master, sub) { 2628 var defs = master.defs, 2629 instances = master.instances; 2630 var filteredDefs = {}; 2631 var filteredInstances = {}; 2632 for (var defId in defs) { 2633 if (!sub.defs[defId]) { 2634 // not explicitly excluded 2635 filteredDefs[defId] = defs[defId]; 2636 } 2637 } 2638 for (var instanceId in instances) { 2639 if ( 2640 !sub.instances[instanceId] && // not explicitly excluded 2641 filteredDefs[instances[instanceId].defId] // def wasn't filtered away 2642 ) { 2643 filteredInstances[instanceId] = instances[instanceId]; 2644 } 2645 } 2646 return { 2647 defs: filteredDefs, 2648 instances: filteredInstances, 2649 }; 2650 } 2651 2652 function normalizeConstraint(input, context) { 2653 if (Array.isArray(input)) { 2654 return parseEvents(input, null, context, true); // allowOpenRange=true 2655 } else if (typeof input === "object" && input) { 2656 // non-null object 2657 return parseEvents([input], null, context, true); // allowOpenRange=true 2658 } else if (input != null) { 2659 return String(input); 2660 } else { 2661 return null; 2662 } 2663 } 2664 2665 function parseClassNames(raw) { 2666 if (Array.isArray(raw)) { 2667 return raw; 2668 } else if (typeof raw === "string") { 2669 return raw.split(/\s+/); 2670 } else { 2671 return []; 2672 } 2673 } 2674
2675 // TODO: better called "EventSettings" or "EventConfig" 2676 // TODO: move this file into structs 2677 // TODO: separate constraint/overlap/allow, because selection uses only that, not other props 2678 var EVENT_UI_REFINERS = { 2679 display: String, 2680 editable: Boolean, 2681 startEditable: Boolean, 2682 durationEditable: Boolean, 2683 constraint: identity, 2684 overlap: identity, 2685 allow: identity, 2686 className: parseClassNames, 2687 classNames: parseClassNames, 2688 color: String, 2689 backgroundColor: String, 2690 borderColor: String, 2691 textColor: String, 2692 }; 2693 function createEventUi(refined, context) { 2694 var constraint = normalizeConstraint(refined.constraint, context); 2695 return { 2696 display: refined.display || null, 2697 startEditable: 2698 refined.startEditable != null 2699 ? refined.startEditable 2700 : refined.editable, 2701 durationEditable: 2702 refined.durationEditable != null 2703 ? refined.durationEditable 2704 : refined.editable, 2705 constraints: constraint != null ? [constraint] : [], 2706 overlap: refined.overlap != null ? refined.overlap : null, 2707 allows: refined.allow != null ? [refined.allow] : [], 2708 backgroundColor: refined.backgroundColor || refined.color || "", 2709 borderColor: refined.borderColor || refined.color || "", 2710 textColor: refined.textColor || "", 2711 classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural 2712 }; 2713 } 2714 // TODO: prevent against problems with <2 args! 2715 function combineEventUis(uis) { 2716 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 2717 } 2718 function combineTwoEventUis(item0, item1) { 2719 return { 2720 display: item1.display != null ? item1.display : item0.display, 2721 startEditable: 2722 item1.startEditable != null ? item1.startEditable : item0.startEditable, 2723 durationEditable: 2724 item1.durationEditable != null 2725 ? item1.durationEditable 2726 : item0.durationEditable, 2727 constraints: item0.constraints.concat(item1.constraints), 2728 overlap: 2729 typeof item1.overlap === "boolean" ? item1.overlap : item0.overlap, 2730 allows: item0.allows.concat(item1.allows), 2731 backgroundColor: item1.backgroundColor || item0.backgroundColor, 2732 borderColor: item1.borderColor || item0.borderColor, 2733 textColor: item1.textColor || item0.textColor, 2734 classNames: item0.classNames.concat(item1.classNames), 2735 }; 2736 } 2737 var EMPTY_EVENT_UI = { 2738 display: null, 2739 startEditable: null, 2740 durationEditable: null, 2741 constraints: [], 2742 overlap: null, 2743 allows: [], 2744 backgroundColor: "", 2745 borderColor: "", 2746 textColor: "", 2747 classNames: [], 2748 }; 2749 2750 var EVENT_NON_DATE_REFINERS = { 2751 id: String, 2752 groupId: String, 2753 title: String, 2754 url: String, 2755 }; 2756 var EVENT_DATE_REFINERS = { 2757 start: identity, 2758 end: identity, 2759 date: identity, 2760 allDay: Boolean, 2761 }; 2762 var EVENT_REFINERS = __assign( 2763 __assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), 2764 { extendedProps: identity } 2765 ); 2766 function parseEvent(raw, eventSource, context, allowOpenRange, refiners) { 2767 if (refiners === void 0) { 2768 refiners = buildEventRefiners(context); 2769 } 2770 var _a = refineEventDef(raw, context, refiners), 2771 refined = _a.refined, 2772 extra = _a.extra; 2773 var defaultAllDay = computeIsDefaultAllDay(eventSource, context); 2774 var recurringRes = parseRecurring( 2775 refined, 2776 defaultAllDay, 2777 context.dateEnv, 2778 context.pluginHooks.recurringTypes 2779 ); 2780 if (recurringRes) { 2781 var def = parseEventDef( 2782 refined, 2783 extra, 2784 eventSource ? eventSource.sourceId : "", 2785 recurringRes.allDay, 2786 Boolean(recurringRes.duration), 2787 context 2788 ); 2789 def.recurringDef = { 2790 typeId: recurringRes.typeId, 2791 typeData: recurringRes.typeData, 2792 duration: recurringRes.duration, 2793 }; 2794 return { def: def, instance: null }; 2795 } else { 2796 var singleRes = parseSingle( 2797 refined, 2798 defaultAllDay, 2799 context, 2800 allowOpenRange 2801 ); 2802 if (singleRes) { 2803 var def = parseEventDef( 2804 refined, 2805 extra, 2806 eventSource ? eventSource.sourceId : "", 2807 singleRes.allDay, 2808 singleRes.hasEnd, 2809 context 2810 ); 2811 var instance = createEventInstance( 2812 def.defId, 2813 singleRes.range, 2814 singleRes.forcedStartTzo, 2815 singleRes.forcedEndTzo 2816 ); 2817 return { def: def, instance: instance }; 2818 } 2819 } 2820 return null; 2821 } 2822 function refineEventDef(raw, context, refiners) { 2823 if (refiners === void 0) { 2824 refiners = buildEventRefiners(context); 2825 } 2826 return refineProps(raw, refiners); 2827 } 2828 function buildEventRefiners(context) { 2829 return __assign( 2830 __assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), 2831 context.pluginHooks.eventRefiners 2832 ); 2833 } 2834 /* 2835 Will NOT populate extendedProps with the leftover properties. 2836 Will NOT populate date-related props. 2837 */ 2838 function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) { 2839 var def = { 2840 title: refined.title || "", 2841 groupId: refined.groupId || "", 2842 publicId: refined.id || "", 2843 url: refined.url || "", 2844 recurringDef: null, 2845 defId: guid(), 2846 sourceId: sourceId, 2847 allDay: allDay, 2848 hasEnd: hasEnd,
2849 ui: createEventUi(refined, context), 2850 extendedProps: __assign(__assign({}, refined.extendedProps || {}), extra), 2851 }; 2852 for ( 2853 var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; 2854 _i < _a.length; 2855 _i++ 2856 ) { 2857 var memberAdder = _a[_i]; 2858 __assign(def, memberAdder(refined)); 2859 } 2860 // help out EventApi from having user modify props 2861 Object.freeze(def.ui.classNames); 2862 Object.freeze(def.extendedProps); 2863 return def; 2864 } 2865 function parseSingle(refined, defaultAllDay, context, allowOpenRange) { 2866 var allDay = refined.allDay; 2867 var startMeta; 2868 var startMarker = null; 2869 var hasEnd = false; 2870 var endMeta; 2871 var endMarker = null; 2872 var startInput = refined.start != null ? refined.start : refined.date; 2873 startMeta = context.dateEnv.createMarkerMeta(startInput); 2874 if (startMeta) { 2875 startMarker = startMeta.marker; 2876 } else if (!allowOpenRange) { 2877 return null; 2878 } 2879 if (refined.end != null) { 2880 endMeta = context.dateEnv.createMarkerMeta(refined.end); 2881 } 2882 if (allDay == null) { 2883 if (defaultAllDay != null) { 2884 allDay = defaultAllDay; 2885 } else { 2886 // fall back to the date props LAST 2887 allDay = 2888 (!startMeta || startMeta.isTimeUnspecified) && 2889 (!endMeta || endMeta.isTimeUnspecified); 2890 } 2891 } 2892 if (allDay && startMarker) { 2893 startMarker = startOfDay(startMarker); 2894 } 2895 if (endMeta) { 2896 endMarker = endMeta.marker; 2897 if (allDay) { 2898 endMarker = startOfDay(endMarker); 2899 } 2900 if (startMarker && endMarker <= startMarker) { 2901 endMarker = null; 2902 } 2903 } 2904 if (endMarker) { 2905 hasEnd = true; 2906 } else if (!allowOpenRange) { 2907 hasEnd = context.options.forceEventDuration || false; 2908 endMarker = context.dateEnv.add( 2909 startMarker, 2910 allDay 2911 ? context.options.defaultAllDayEventDuration 2912 : context.options.defaultTimedEventDuration 2913 ); 2914 } 2915 return { 2916 allDay: allDay, 2917 hasEnd: hasEnd, 2918 range: { start: startMarker, end: endMarker }, 2919 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 2920 forcedEndTzo: endMeta ? endMeta.forcedTzo : null, 2921 }; 2922 } 2923 function computeIsDefaultAllDay(eventSource, context) { 2924 var res = null; 2925 if (eventSource) { 2926 res = eventSource.defaultAllDay; 2927 } 2928 if (res == null) { 2929 res = context.options.defaultAllDay; 2930 } 2931 return res; 2932 } 2933 2934 /* Date stuff that doesn't belong in datelib core 2935 ----------------------------------------------------------------------------------------------------------------------*/ 2936 // given a timed range, computes an all-day range that has the same exact duration, 2937 // but whose start time is aligned with the start of the day. 2938 function computeAlignedDayRange(timedRange) { 2939 var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 2940 var start = startOfDay(timedRange.start); 2941 var end = addDays(start, dayCnt); 2942 return { start: start, end: end }; 2943 } 2944 // given a timed range, computes an all-day range based on how for the end date bleeds into the next day 2945 // TODO: give nextDayThreshold a default arg 2946 function computeVisibleDayRange(timedRange, nextDayThreshold) { 2947 if (nextDayThreshold === void 0) { 2948 nextDayThreshold = createDuration(0); 2949 } 2950 var startDay = null; 2951 var endDay = null; 2952 if (timedRange.end) { 2953 endDay = startOfDay(timedRange.end); 2954 var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay` 2955 // If the end time is actually inclusively part of the next day and is equal to or 2956 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 2957 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 2958 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 2959 endDay = addDays(endDay, 1); 2960 } 2961 } 2962 if (timedRange.start) { 2963 startDay = startOfDay(timedRange.start); // the beginning of the day the range starts 2964 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 2965 if (endDay && endDay <= startDay) { 2966 endDay = addDays(startDay, 1); 2967 } 2968 } 2969 return { start: startDay, end: endDay }; 2970 } 2971 // spans from one day into another? 2972 function isMultiDayRange(range) { 2973 var visibleRange = computeVisibleDayRange(range); 2974 return diffDays(visibleRange.start, visibleRange.end) > 1; 2975 } 2976 function diffDates(date0, date1, dateEnv, largeUnit) { 2977 if (largeUnit === "year") { 2978 return createDuration(dateEnv.diffWholeYears(date0, date1), "year"); 2979 } else if (largeUnit === "month") { 2980 return createDuration(dateEnv.diffWholeMonths(date0, date1), "month"); 2981 } else { 2982 return diffDayAndTime(date0, date1); // returns a duration 2983 } 2984 } 2985 2986 function parseRange(input, dateEnv) { 2987 var start = null; 2988 var end = null; 2989 if (input.start) { 2990 start = dateEnv.createMarker(input.start); 2991 } 2992 if (input.end) { 2993 end = dateEnv.createMarker(input.end); 2994 } 2995 if (!start && !end) { 2996 return null; 2997 } 2998 if (start && end && end < start) { 2999 return null; 3000 } 3001 return { start: start, end: end }; 3002 } 3003 // SIDE-EFFECT: will mutate ranges. 3004 // Will return a new array result. 3005 function invertRanges(ranges, constraintRange) { 3006 var invertedRanges = []; 3007 var start = constraintRange.start; // the end of the previous range. the start of the new range 3008 var i; 3009 var dateRange; 3010 // ranges need to be in order. required for our date-walking algorithm 3011 ranges.sort(compareRanges); 3012 for (i = 0; i < ranges.length; i++) { 3013 dateRange = ranges[i]; 3014 // add the span of time before the event (if there is any) 3015 if (dateRange.start > start) { 3016 // compare millisecond time (skip any ambig logic) 3017 invertedRanges.push({ start: start, end: dateRange.start }); 3018 } 3019 if (dateRange.end > start) { 3020 start = dateRange.end; 3021 } 3022 } 3023 // add the span of time after the last event (if there is any) 3024 if (start < constraintRange.end) { 3025 // compare millisecond time (skip any ambig logic) 3026 invertedRanges.push({ start: start, end: constraintRange.end }); 3027 } 3028 return invertedRanges; 3029 } 3030 function compareRanges(range0, range1) { 3031 return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first 3032 } 3033 function intersectRanges(range0, range1) { 3034 var start = range0.start; 3035 var end = range0.end; 3036 var newRange = null; 3037 if (range1.start !== null) { 3038 if (start === null) { 3039 start = range1.start; 3040 } else { 3041 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 3042 } 3043 } 3044 if (range1.end != null) { 3045 if (end === null) { 3046 end = range1.end; 3047 } else { 3048 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 3049 } 3050 } 3051 if (start === null || end === null || start < end) { 3052 newRange = { start: start, end: end }; 3053 } 3054 return newRange; 3055 } 3056 function rangesEqual(range0, range1) { 3057 return ( 3058 (range0.start === null ? null : range0.start.valueOf()) === 3059 (range1.start === null ? null : range1.start.valueOf()) && 3060 (range0.end === null ? null : range0.end.valueOf()) === 3061 (range1.end === null ? null : range1.end.valueOf()) 3062 ); 3063 } 3064 function rangesIntersect(range0, range1) { 3065 return ( 3066 (range0.end === null || 3067 range1.start === null || 3068 range0.end > range1.start) && 3069 (range0.start === null || 3070 range1.end === null || 3071 range0.start < range1.end) 3072 ); 3073 } 3074 function rangeContainsRange(outerRange, innerRange) { 3075 return ( 3076 (outerRange.start === null || 3077 (innerRange.start !== null && innerRange.start >= outerRange.start)) && 3078 (outerRange.end === null || 3079 (innerRange.end !== null && innerRange.end <= outerRange.end)) 3080 ); 3081 } 3082 function rangeContainsMarker(range, date) { 3083 return ( 3084 (range.start === null || date >= range.start) && 3085 (range.end === null || date < range.end) 3086 ); 3087 } 3088 // If the given date is not within the given range, move it inside. 3089 // (If it's past the end, make it one millisecond before the end). 3090 function constrainMarkerToRange(date, range) { 3091 if (range.start != null && date < range.start) { 3092 return range.start; 3093 } 3094 if (range.end != null && date >= range.end) { 3095 return new Date(range.end.valueOf() - 1); 3096 } 3097 return date; 3098 } 3099 3100 /* 3101 Specifying nextDayThreshold signals that all-day ranges should be sliced. 3102 */ 3103 function sliceEventStore( 3104 eventStore, 3105 eventUiBases, 3106 framingRange, 3107 nextDayThreshold 3108 ) { 3109 var inverseBgByGroupId = {}; 3110 var inverseBgByDefId = {}; 3111 var defByGroupId = {}; 3112 var bgRanges = []; 3113 var fgRanges = []; 3114 var eventUis = compileEventUis(eventStore.defs, eventUiBases); 3115 for (var defId in eventStore.defs) { 3116 var def = eventStore.defs[defId]; 3117 var ui = eventUis[def.defId]; 3118 if (ui.display === "inverse-background") { 3119 if (def.groupId) { 3120 inverseBgByGroupId[def.groupId] = []; 3121 if (!defByGroupId[def.groupId]) { 3122 defByGroupId[def.groupId] = def; 3123 } 3124 } else { 3125 inverseBgByDefId[defId] = []; 3126 } 3127 } 3128 } 3129 for (var instanceId in eventStore.instances) { 3130 var instance = eventStore.instances[instanceId]; 3131 var def = eventStore.defs[instance.defId]; 3132 var ui = eventUis[def.defId]; 3133 var origRange = instance.range; 3134 var normalRange = 3135 !def.allDay && nextDayThreshold 3136 ? computeVisibleDayRange(origRange, nextDayThreshold) 3137 : origRange; 3138 var slicedRange = intersectRanges(normalRange, framingRange); 3139 if (slicedRange) { 3140 if (ui.display === "inverse-background") { 3141 if (def.groupId) { 3142 inverseBgByGroupId[def.groupId].push(slicedRange); 3143 } else { 3144 inverseBgByDefId[instance.defId].push(slicedRange); 3145 } 3146 } else if (ui.display !== "none") { 3147 (ui.display === "background" ? bgRanges : fgRanges).push({ 3148 def: def, 3149 ui: ui, 3150 instance: instance, 3151 range: slicedRange, 3152 isStart: 3153 normalRange.start && 3154 normalRange.start.valueOf() === slicedRange.start.valueOf(), 3155 isEnd: 3156 normalRange.end && 3157 normalRange.end.valueOf() === slicedRange.end.valueOf(), 3158 }); 3159 } 3160 } 3161 } 3162 for (var groupId in inverseBgByGroupId) { 3163 // BY GROUP 3164 var ranges = inverseBgByGroupId[groupId]; 3165 var invertedRanges = invertRanges(ranges, framingRange); 3166 for ( 3167 var _i = 0, invertedRanges_1 = invertedRanges; 3168 _i < invertedRanges_1.length; 3169 _i++ 3170 ) { 3171 var invertedRange = invertedRanges_1[_i]; 3172 var def = defByGroupId[groupId]; 3173 var ui = eventUis[def.defId]; 3174 bgRanges.push({ 3175 def: def, 3176 ui: ui, 3177 instance: null, 3178 range: invertedRange, 3179 isStart: false, 3180 isEnd: false, 3181 }); 3182 } 3183 } 3184 for (var defId in inverseBgByDefId) { 3185 var ranges = inverseBgByDefId[defId]; 3186 var invertedRanges = invertRanges(ranges, framingRange); 3187 for ( 3188 var _a = 0, invertedRanges_2 = invertedRanges; 3189 _a < invertedRanges_2.length; 3190 _a++ 3191 ) { 3192 var invertedRange = invertedRanges_2[_a]; 3193 bgRanges.push({ 3194 def: eventStore.defs[defId], 3195 ui: eventUis[defId], 3196 instance: null, 3197 range: invertedRange, 3198 isStart: false, 3199 isEnd: false, 3200 }); 3201 } 3202 } 3203 return { bg: bgRanges, fg: fgRanges }; 3204 } 3205 function hasBgRendering(def) { 3206 return ( 3207 def.ui.display === "background" || def.ui.display === "inverse-background" 3208 ); 3209 } 3210 function setElSeg(el, seg) { 3211 el.fcSeg = seg; 3212 } 3213 function getElSeg(el) { 3214 return ( 3215 el.fcSeg || 3216 el.parentNode.fcSeg || // for the harness 3217 null 3218 ); 3219 } 3220 // event ui computation 3221 function compileEventUis(eventDefs, eventUiBases) { 3222 return mapHash(eventDefs, function (eventDef) { 3223 return compileEventUi(eventDef, eventUiBases); 3224 }); 3225 } 3226 function compileEventUi(eventDef, eventUiBases) { 3227 var uis = []; 3228 if (eventUiBases[""]) { 3229 uis.push(eventUiBases[""]); 3230 } 3231 if (eventUiBases[eventDef.defId]) { 3232 uis.push(eventUiBases[eventDef.defId]); 3233 } 3234 uis.push(eventDef.ui); 3235 return combineEventUis(uis); 3236 } 3237 function sortEventSegs(segs, eventOrderSpecs) { 3238 var objs = segs.map(buildSegCompareObj); 3239 objs.sort(function (obj0, obj1) { 3240 return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); 3241 }); 3242 return objs.map(function (c) { 3243 return c._seg; 3244 }); 3245 } 3246 // returns a object with all primitive props that can be compared 3247 function buildSegCompareObj(seg) { 3248 var eventRange = seg.eventRange; 3249 var eventDef = eventRange.def; 3250 var range = eventRange.instance 3251 ? eventRange.instance.range 3252 : eventRange.range; 3253 var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events 3254 var end = range.end ? range.end.valueOf() : 0; // " 3255 return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { 3256 id: eventDef.publicId, 3257 start: start, 3258 end: end, 3259 duration: end - start, 3260 allDay: Number(eventDef.allDay), 3261 _seg: seg, // for later retrieval 3262 }); 3263 } 3264 function computeSegDraggable(seg, context) { 3265 var pluginHooks = context.pluginHooks; 3266 var transformers = pluginHooks.isDraggableTransformers; 3267 var _a = seg.eventRange, 3268 def = _a.def, 3269 ui = _a.ui; 3270 var val = ui.startEditable; 3271 for ( 3272 var _i = 0, transformers_1 = transformers; 3273 _i < transformers_1.length; 3274 _i++ 3275 ) { 3276 var transformer = transformers_1[_i]; 3277 val = transformer(val, def, ui, context); 3278 } 3279 return val; 3280 } 3281 function computeSegStartResizable(seg, context) { 3282 return ( 3283 seg.isStart && 3284 seg.eventRange.ui.durationEditable && 3285 context.options.eventResizableFromStart 3286 ); 3287 } 3288 function computeSegEndResizable(seg, context) { 3289 return seg.isEnd && seg.eventRange.ui.durationEditable; 3290 } 3291 function buildSegTimeText( 3292 seg, 3293 timeFormat, 3294 context, 3295 defaultDisplayEventTime, // defaults to true 3296 defaultDisplayEventEnd, // defaults to true 3297 startOverride, 3298 endOverride 3299 ) { 3300 var dateEnv = context.dateEnv, 3301 options = context.options; 3302 var displayEventTime = options.displayEventTime, 3303 displayEventEnd = options.displayEventEnd; 3304 var eventDef = seg.eventRange.def; 3305 var eventInstance = seg.eventRange.instance; 3306 if (displayEventTime == null) { 3307 displayEventTime = defaultDisplayEventTime !== false; 3308 } 3309 if (displayEventEnd == null) { 3310 displayEventEnd = defaultDisplayEventEnd !== false; 3311 } 3312 if (displayEventTime && !eventDef.allDay && (seg.isStart || seg.isEnd)) { 3313 var segStart = 3314 startOverride || 3315 (seg.isStart 3316 ? eventInstance.range.start 3317 : seg.start || seg.eventRange.range.start); 3318 var segEnd = 3319 endOverride || 3320 (seg.isEnd 3321 ? eventInstance.range.end 3322 : seg.end || seg.eventRange.range.end); 3323 if (displayEventEnd && eventDef.hasEnd) { 3324 return dateEnv.formatRange(segStart, segEnd, timeFormat, { 3325 forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo, 3326 forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo, 3327 }); 3328 } else { 3329 return dateEnv.format(segStart, timeFormat, { 3330 forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same 3331 }); 3332 } 3333 } 3334 return ""; 3335 } 3336 function getSegMeta(seg, todayRange, nowDate) { 3337 var segRange = seg.eventRange.range; 3338 return { 3339 isPast: segRange.end < (nowDate || todayRange.start), 3340 isFuture: segRange.start >= (nowDate || todayRange.end), 3341 isToday: todayRange && rangeContainsMarker(todayRange, segRange.start), 3342 }; 3343 } 3344 function getEventClassNames(props) { 3345 var classNames = ["fc-event"]; 3346 if (props.isMirror) { 3347 classNames.push("fc-event-mirror"); 3348
3348 } 3349 if (props.isDraggable) { 3350 classNames.push("fc-event-draggable"); 3351 } 3352 if (props.isStartResizable || props.isEndResizable) { 3353 classNames.push("fc-event-resizable"); 3354 } 3355 if (props.isDragging) { 3356 classNames.push("fc-event-dragging"); 3357 } 3358 if (props.isResizing) { 3359 classNames.push("fc-event-resizing"); 3360 } 3361 if (props.isSelected) { 3362 classNames.push("fc-event-selected"); 3363 } 3364 if (props.isStart) { 3365 classNames.push("fc-event-start"); 3366 } 3367 if (props.isEnd) { 3368 classNames.push("fc-event-end"); 3369 } 3370 if (props.isPast) { 3371 classNames.push("fc-event-past"); 3372 } 3373 if (props.isToday) { 3374 classNames.push("fc-event-today"); 3375 } 3376 if (props.isFuture) { 3377 classNames.push("fc-event-future"); 3378 } 3379 return classNames; 3380 } 3381 function buildEventRangeKey(eventRange) { 3382 return eventRange.instance 3383 ? eventRange.instance.instanceId 3384 : eventRange.def.defId + ":" + eventRange.range.start.toISOString(); 3385 // inverse-background events don't have specific instances. TODO: better solution 3386 } 3387 3388 var STANDARD_PROPS = { 3389 start: identity, 3390 end: identity, 3391 allDay: Boolean, 3392 }; 3393 function parseDateSpan(raw, dateEnv, defaultDuration) { 3394 var span = parseOpenDateSpan(raw, dateEnv); 3395 var range = span.range; 3396 if (!range.start) { 3397 return null; 3398 } 3399 if (!range.end) { 3400 if (defaultDuration == null) { 3401 return null; 3402 } else { 3403 range.end = dateEnv.add(range.start, defaultDuration); 3404 } 3405 } 3406 return span; 3407 } 3408 /* 3409 TODO: somehow combine with parseRange? 3410 Will return null if the start/end props were present but parsed invalidly. 3411 */ 3412 function parseOpenDateSpan(raw, dateEnv) { 3413 var _a = refineProps(raw, STANDARD_PROPS), 3414 standardProps = _a.refined, 3415 extra = _a.extra; 3416 var startMeta = standardProps.start 3417 ? dateEnv.createMarkerMeta(standardProps.start) 3418 : null; 3419 var endMeta = standardProps.end 3420 ? dateEnv.createMarkerMeta(standardProps.end) 3421 : null; 3422 var allDay = standardProps.allDay; 3423 if (allDay == null) { 3424 allDay = 3425 startMeta && 3426 startMeta.isTimeUnspecified && 3427 (!endMeta || endMeta.isTimeUnspecified); 3428 } 3429 return __assign( 3430 { 3431 range: { 3432 start: startMeta ? startMeta.marker : null, 3433 end: endMeta ? endMeta.marker : null, 3434 }, 3435 allDay: allDay, 3436 }, 3437 extra 3438 ); 3439 } 3440 function isDateSpansEqual(span0, span1) { 3441 return ( 3442 rangesEqual(span0.range, span1.range) && 3443 span0.allDay === span1.allDay && 3444 isSpanPropsEqual(span0, span1) 3445 ); 3446 } 3447 // the NON-DATE-RELATED props 3448 function isSpanPropsEqual(span0, span1) { 3449 for (var propName in span1) { 3450 if (propName !== "range" && propName !== "allDay") { 3451 if (span0[propName] !== span1[propName]) { 3452 return false; 3453 } 3454 } 3455 } 3456 // are there any props that span0 has that span1 DOESN'T have? 3457 // both have range/allDay, so no need to special-case. 3458 for (var propName in span0) { 3459 if (!(propName in span1)) { 3460 return false; 3461 } 3462 } 3463 return true; 3464 } 3465 function buildDateSpanApi(span, dateEnv) { 3466 return __assign( 3467 __assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), 3468 { allDay: span.allDay } 3469 ); 3470 } 3471 function buildRangeApiWithTimeZone(range, dateEnv, omitTime) { 3472 return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { 3473 timeZone: dateEnv.timeZone, 3474 }); 3475 } 3476 function buildRangeApi(range, dateEnv, omitTime) { 3477 return { 3478 start: dateEnv.toDate(range.start), 3479 end: dateEnv.toDate(range.end), 3480 startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }), 3481 endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }), 3482 }; 3483 } 3484 function fabricateEventRange(dateSpan, eventUiBases, context) { 3485 var res = refineEventDef({ editable: false }, context); 3486 var def = parseEventDef( 3487 res.refined, 3488 res.extra, 3489 "", // sourceId 3490 dateSpan.allDay, 3491 true, // hasEnd 3492 context 3493 ); 3494 return { 3495 def: def, 3496 ui: compileEventUi(def, eventUiBases), 3497 instance: createEventInstance(def.defId, dateSpan.range), 3498 range: dateSpan.range, 3499 isStart: true, 3500 isEnd: true, 3501 }; 3502 } 3503 3504 function triggerDateSelect(selection, pev, context) { 3505 context.emitter.trigger( 3506 "select", 3507 __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { 3508 jsEvent: pev ? pev.origEvent : null, 3509 view: context.viewApi || context.calendarApi.view, 3510 }) 3511 ); 3512 } 3513 function triggerDateUnselect(pev, context) { 3514 context.emitter.trigger("unselect", { 3515 jsEvent: pev ? pev.origEvent : null, 3516 view: context.viewApi || context.calendarApi.view, 3517 }); 3518 } 3519 function buildDateSpanApiWithContext(dateSpan, context) { 3520 var props = {}; 3521 for ( 3522 var _i = 0, _a = context.pluginHooks.dateSpanTransforms; 3523 _i < _a.length; 3524 _i++ 3525 ) { 3526 var transform = _a[_i]; 3527 __assign(props, transform(dateSpan, context)); 3528 } 3529 __assign(props, buildDateSpanApi(dateSpan, context.dateEnv)); 3530 return props; 3531 } 3532 // Given an event's allDay status and start date, return what its fallback end date should be. 3533 // TODO: rename to computeDefaultEventEnd 3534 function getDefaultEventEnd(allDay, marker, context) { 3535 var dateEnv = context.dateEnv, 3536 options = context.options; 3537 var end = marker; 3538 if (allDay) { 3539 end = startOfDay(end); 3540 end = dateEnv.add(end, options.defaultAllDayEventDuration); 3541 } else { 3542 end = dateEnv.add(end, options.defaultTimedEventDuration); 3543 } 3544 return end; 3545 } 3546 3547 // applies the mutation to ALL defs/instances within the event store 3548 function applyMutationToEventStore( 3549 eventStore, 3550 eventConfigBase, 3551 mutation, 3552 context 3553 ) { 3554 var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 3555 var dest = createEmptyEventStore(); 3556 for (var defId in eventStore.defs) { 3557 var def = eventStore.defs[defId]; 3558 dest.defs[defId] = applyMutationToEventDef( 3559 def, 3560 eventConfigs[defId], 3561 mutation, 3562 context 3563 ); 3564 } 3565 for (var instanceId in eventStore.instances) { 3566 var instance = eventStore.instances[instanceId]; 3567 var def = dest.defs[instance.defId]; // important to grab the newly modified def 3568 dest.instances[instanceId] = applyMutationToEventInstance( 3569 instance, 3570 def, 3571 eventConfigs[instance.defId], 3572 mutation, 3573 context 3574 ); 3575 } 3576 return dest; 3577 } 3578 function applyMutationToEventDef(eventDef, eventConfig, mutation, context) { 3579 var standardProps = mutation.standardProps || {}; 3580 // if hasEnd has not been specified, guess a good value based on deltas. 3581 // if duration will change, there's no way the default duration will persist, 3582 // and thus, we need to mark the event as having a real end 3583 if ( 3584 standardProps.hasEnd == null && 3585 eventConfig.durationEditable && 3586 (mutation.startDelta || mutation.endDelta) 3587 ) { 3588 standardProps.hasEnd = true; // TODO: is this mutation okay? 3589 } 3590 var copy = __assign(__assign(__assign({}, eventDef), standardProps), { 3591 ui: __assign(__assign({}, eventDef.ui), standardProps.ui), 3592 }); 3593 if (mutation.extendedProps) { 3594 copy.extendedProps = __assign( 3595 __assign({}, copy.extendedProps), 3596 mutation.extendedProps 3597 ); 3598 } 3599 for ( 3600 var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; 3601 _i < _a.length; 3602 _i++ 3603 ) { 3604 var applier = _a[_i]; 3605 applier(copy, mutation, context); 3606 } 3607 if (!copy.hasEnd && context.options.forceEventDuration) { 3608 copy.hasEnd = true; 3609 } 3610 return copy; 3611 } 3612 function applyMutationToEventInstance( 3613 eventInstance, 3614 eventDef, // must first be modified by applyMutationToEventDef 3615 eventConfig, 3616 mutation, 3617 context 3618 ) { 3619 var dateEnv = context.dateEnv; 3620 var forceAllDay = 3621 mutation.standardProps && mutation.standardProps.allDay === true; 3622 var clearEnd = 3623 mutation.standardProps && mutation.standardProps.hasEnd === false; 3624 var copy = __assign({}, eventInstance); 3625 if (forceAllDay) { 3626 copy.range = computeAlignedDayRange(copy.range); 3627 } 3628 if (mutation.datesDelta && eventConfig.startEditable) { 3629 copy.range = { 3630 start: dateEnv.add(copy.range.start, mutation.datesDelta), 3631 end: dateEnv.add(copy.range.end, mutation.datesDelta), 3632 }; 3633 } 3634 if (mutation.startDelta && eventConfig.durationEditable) { 3635 copy.range = { 3636 start: dateEnv.add(copy.range.start, mutation.startDelta), 3637 end: copy.range.end, 3638 }; 3639 } 3640 if (mutation.endDelta && eventConfig.durationEditable) { 3641 copy.range = { 3642 start: copy.range.start, 3643 end: dateEnv.add(copy.range.end, mutation.endDelta), 3644 }; 3645 } 3646 if (clearEnd) { 3647 copy.range = { 3648 start: copy.range.start, 3649 end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context), 3650 }; 3651 } 3652 // in case event was all-day but the supplied deltas were not 3653 // better util for this? 3654 if (eventDef.allDay) { 3655 copy.range = { 3656 start: startOfDay(copy.range.start), 3657 end: startOfDay(copy.range.end), 3658 }; 3659 } 3660 // handle invalid durations 3661 if (copy.range.end < copy.range.start) { 3662 copy.range.end = getDefaultEventEnd( 3663 eventDef.allDay, 3664 copy.range.start, 3665 context 3666 ); 3667 } 3668 return copy; 3669 } 3670 3671 // no public types yet. when there are, export from: 3672 // import {} from './api-type-deps' 3673 var ViewApi = /** @class */ (function () { 3674 function ViewApi(type, getCurrentData, dateEnv) { 3675 this.type = type; 3676 this.getCurrentData = getCurrentData; 3677 this.dateEnv = dateEnv; 3678 } 3679 Object.defineProperty(ViewApi.prototype, "calendar", { 3680 get: function () { 3681 return this.getCurrentData().calendarApi; 3682 }, 3683 enumerable: false, 3684 configurable: true, 3685 });
3686 Object.defineProperty(ViewApi.prototype, "title", { 3687 get: function () { 3688 return this.getCurrentData().viewTitle; 3689 }, 3690 enumerable: false, 3691 configurable: true, 3692 }); 3693 Object.defineProperty(ViewApi.prototype, "activeStart", { 3694 get: function () { 3695 return this.dateEnv.toDate( 3696 this.getCurrentData().dateProfile.activeRange.start 3697 ); 3698 }, 3699 enumerable: false, 3700 configurable: true, 3701 }); 3702 Object.defineProperty(ViewApi.prototype, "activeEnd", { 3703 get: function () { 3704 return this.dateEnv.toDate( 3705 this.getCurrentData().dateProfile.activeRange.end 3706 ); 3707 }, 3708 enumerable: false, 3709 configurable: true, 3710 }); 3711 Object.defineProperty(ViewApi.prototype, "currentStart", { 3712 get: function () { 3713 return this.dateEnv.toDate( 3714 this.getCurrentData().dateProfile.currentRange.start 3715 ); 3716 }, 3717 enumerable: false, 3718 configurable: true, 3719 }); 3720 Object.defineProperty(ViewApi.prototype, "currentEnd", { 3721 get: function () { 3722 return this.dateEnv.toDate( 3723 this.getCurrentData().dateProfile.currentRange.end 3724 ); 3725 }, 3726 enumerable: false, 3727 configurable: true, 3728 }); 3729 ViewApi.prototype.getOption = function (name) { 3730 return this.getCurrentData().options[name]; // are the view-specific options 3731 }; 3732 return ViewApi; 3733 })(); 3734 3735 var EVENT_SOURCE_REFINERS = { 3736 id: String, 3737 defaultAllDay: Boolean, 3738 url: String, 3739 events: identity, 3740 eventDataTransform: identity, 3741 // for any network-related sources 3742 success: identity, 3743 failure: identity, 3744 }; 3745 function parseEventSource(raw, context, refiners) { 3746 if (refiners === void 0) { 3747 refiners = buildEventSourceRefiners(context); 3748 } 3749 var rawObj; 3750 if (typeof raw === "string") { 3751 rawObj = { url: raw }; 3752 } else if (typeof raw === "function" || Array.isArray(raw)) { 3753 rawObj = { events: raw }; 3754 } else if (typeof raw === "object" && raw) { 3755 // not null 3756 rawObj = raw; 3757 } 3758 if (rawObj) { 3759 var _a = refineProps(rawObj, refiners), 3760 refined = _a.refined, 3761 extra = _a.extra; 3762 var metaRes = buildEventSourceMeta(refined, context); 3763 if (metaRes) { 3764 return { 3765 _raw: raw, 3766 isFetching: false, 3767 latestFetchId: "", 3768 fetchRange: null, 3769 defaultAllDay: refined.defaultAllDay, 3770 eventDataTransform: refined.eventDataTransform, 3771 success: refined.success, 3772 failure: refined.failure, 3773 publicId: refined.id || "", 3774 sourceId: guid(), 3775 sourceDefId: metaRes.sourceDefId, 3776 meta: metaRes.meta, 3777 ui: createEventUi(refined, context), 3778 extendedProps: extra, 3779 }; 3780 } 3781 } 3782 return null; 3783 } 3784 function buildEventSourceRefiners(context) { 3785 return __assign( 3786 __assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), 3787 context.pluginHooks.eventSourceRefiners 3788 ); 3789 } 3790 function buildEventSourceMeta(raw, context) { 3791 var defs = context.pluginHooks.eventSourceDefs; 3792 for (var i = defs.length - 1; i >= 0; i--) { 3793 // later-added plugins take precedence 3794 var def = defs[i]; 3795 var meta = def.parseMeta(raw); 3796 if (meta) { 3797 return { sourceDefId: i, meta: meta }; 3798 } 3799 } 3800 return null; 3801 } 3802 3803 function reduceCurrentDate(currentDate, action) { 3804 switch (action.type) { 3805 case "CHANGE_DATE": 3806 return action.dateMarker; 3807 default: 3808 return currentDate; 3809 } 3810 } 3811 function getInitialDate(options, dateEnv) { 3812 var initialDateInput = options.initialDate; 3813 // compute the initial ambig-timezone date 3814 if (initialDateInput != null) { 3815 return dateEnv.createMarker(initialDateInput); 3816 } else { 3817 return getNow(options.now, dateEnv); // getNow already returns unzoned 3818 } 3819 } 3820 function getNow(nowInput, dateEnv) { 3821 if (typeof nowInput === "function") { 3822 nowInput = nowInput(); 3823 } 3824 if (nowInput == null) { 3825 return dateEnv.createNowMarker(); 3826 } 3827 return dateEnv.createMarker(nowInput); 3828 } 3829 3830 var CalendarApi = /** @class */ (function () { 3831 function CalendarApi() {} 3832 CalendarApi.prototype.getCurrentData = function () { 3833 return this.currentDataManager.getCurrentData(); 3834 }; 3835 CalendarApi.prototype.dispatch = function (action) { 3836 return this.currentDataManager.dispatch(action); 3837 };
3838 Object.defineProperty(CalendarApi.prototype, "view", { 3839 get: function () { 3840 return this.getCurrentData().viewApi; 3841 }, // for public API 3842 enumerable: false, 3843 configurable: true, 3844 }); 3845 CalendarApi.prototype.batchRendering = function (callback) { 3846 callback(); 3847 }; 3848 CalendarApi.prototype.updateSize = function () { 3849 this.trigger("_resize", true); 3850 }; 3851 // Options 3852 // ----------------------------------------------------------------------------------------------------------------- 3853 CalendarApi.prototype.setOption = function (name, val) { 3854 this.dispatch({ 3855 type: "SET_OPTION", 3856 optionName: name, 3857 rawOptionValue: val, 3858 }); 3859 }; 3860 CalendarApi.prototype.getOption = function (name) { 3861 return this.currentDataManager.currentCalendarOptionsInput[name]; 3862 }; 3863 CalendarApi.prototype.getAvailableLocaleCodes = function () { 3864 return Object.keys(this.getCurrentData().availableRawLocales); 3865 }; 3866 // Trigger 3867 // ----------------------------------------------------------------------------------------------------------------- 3868 CalendarApi.prototype.on = function (handlerName, handler) { 3869 var currentDataManager = this.currentDataManager; 3870 if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) { 3871 currentDataManager.emitter.on(handlerName, handler); 3872 } else { 3873 console.warn("Unknown listener name '" + handlerName + "'"); 3874 } 3875 }; 3876 CalendarApi.prototype.off = function (handlerName, handler) { 3877 this.currentDataManager.emitter.off(handlerName, handler); 3878 }; 3879 // not meant for public use 3880 CalendarApi.prototype.trigger = function (handlerName) { 3881 var _a; 3882 var args = []; 3883 for (var _i = 1; _i < arguments.length; _i++) { 3884 args[_i - 1] = arguments[_i]; 3885 } 3886 (_a = this.currentDataManager.emitter).trigger.apply( 3887 _a, 3888 __spreadArrays([handlerName], args) 3889 ); 3890 }; 3891 // View 3892 // ----------------------------------------------------------------------------------------------------------------- 3893 CalendarApi.prototype.changeView = function (viewType, dateOrRange) { 3894 var _this = this; 3895 this.batchRendering(function () { 3896 _this.unselect(); 3897 if (dateOrRange) { 3898 if (dateOrRange.start && dateOrRange.end) { 3899 // a range 3900 _this.dispatch({ 3901 type: "CHANGE_VIEW_TYPE", 3902 viewType: viewType, 3903 }); 3904 _this.dispatch({ 3905 type: "SET_OPTION", 3906 optionName: "visibleRange", 3907 rawOptionValue: dateOrRange, 3908 }); 3909 } else { 3910 var dateEnv = _this.getCurrentData().dateEnv; 3911 _this.dispatch({ 3912 type: "CHANGE_VIEW_TYPE", 3913 viewType: viewType, 3914 dateMarker: dateEnv.createMarker(dateOrRange), 3915 }); 3916 } 3917 } else { 3918 _this.dispatch({ 3919 type: "CHANGE_VIEW_TYPE", 3920 viewType: viewType, 3921 }); 3922 } 3923 }); 3924 }; 3925 // Forces navigation to a view for the given date. 3926 // `viewType` can be a specific view name or a generic one like "week" or "day". 3927 // needs to change 3928 CalendarApi.prototype.zoomTo = function (dateMarker, viewType) { 3929 var state = this.getCurrentData(); 3930 var spec; 3931 viewType = viewType || "day"; // day is default zoom 3932 spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType); 3933 this.unselect(); 3934 if (spec) { 3935 this.dispatch({ 3936 type: "CHANGE_VIEW_TYPE", 3937 viewType: spec.type, 3938 dateMarker: dateMarker, 3939 }); 3940 } else { 3941 this.dispatch({ 3942 type: "CHANGE_DATE", 3943 dateMarker: dateMarker, 3944 }); 3945 } 3946 }; 3947 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 3948 // Preference is given to views that have corresponding buttons. 3949 CalendarApi.prototype.getUnitViewSpec = function (unit) { 3950 var _a = this.getCurrentData(), 3951 viewSpecs = _a.viewSpecs, 3952 toolbarConfig = _a.toolbarConfig; 3953 var viewTypes = [].concat(toolbarConfig.viewsWithButtons); 3954 var i; 3955 var spec; 3956 for (var viewType in viewSpecs) { 3957 viewTypes.push(viewType); 3958 } 3959 for (i = 0; i < viewTypes.length; i++) { 3960 spec = viewSpecs[viewTypes[i]]; 3961 if (spec) { 3962 if (spec.singleUnit === unit) { 3963 return spec; 3964 } 3965 } 3966 } 3967 }; 3968 // Current Date 3969 // ----------------------------------------------------------------------------------------------------------------- 3970 CalendarApi.prototype.prev = function () { 3971 this.unselect(); 3972 this.dispatch({ type: "PREV" }); 3973 }; 3974 CalendarApi.prototype.next = function () { 3975 this.unselect(); 3976 this.dispatch({ type: "NEXT" }); 3977 }; 3978 CalendarApi.prototype.prevYear = function () { 3979 var state = this.getCurrentData(); 3980 this.unselect(); 3981 this.dispatch({ 3982 type: "CHANGE_DATE", 3983 dateMarker: state.dateEnv.addYears(state.currentDate, -1), 3984 }); 3985 }; 3986 CalendarApi.prototype.nextYear = function () { 3987 var state = this.getCurrentData(); 3988 this.unselect(); 3989 this.dispatch({ 3990 type: "CHANGE_DATE", 3991 dateMarker: state.dateEnv.addYears(state.currentDate, 1), 3992 }); 3993 }; 3994 CalendarApi.prototype.today = function () { 3995 var state = this.getCurrentData(); 3996 this.unselect(); 3997 this.dispatch({ 3998 type: "CHANGE_DATE", 3999 dateMarker: getNow(state.calendarOptions.now, state.dateEnv), 4000 }); 4001 }; 4002 CalendarApi.prototype.gotoDate = function (zonedDateInput) { 4003 var state = this.getCurrentData(); 4004 this.unselect(); 4005 this.dispatch({ 4006 type: "CHANGE_DATE", 4007 dateMarker: state.dateEnv.createMarker(zonedDateInput), 4008 }); 4009 }; 4010 CalendarApi.prototype.incrementDate = function (deltaInput) { 4011 var state = this.getCurrentData(); 4012 var delta = createDuration(deltaInput); 4013 if (delta) { 4014 // else, warn about invalid input? 4015 this.unselect(); 4016 this.dispatch({ 4017 type: "CHANGE_DATE", 4018 dateMarker: state.dateEnv.add(state.currentDate, delta), 4019 }); 4020 } 4021 }; 4022 // for external API 4023 CalendarApi.prototype.getDate = function () { 4024 var state = this.getCurrentData(); 4025 return state.dateEnv.toDate(state.currentDate); 4026 }; 4027 // Date Formatting Utils 4028 // ----------------------------------------------------------------------------------------------------------------- 4029 CalendarApi.prototype.formatDate = function (d, formatter) { 4030 var dateEnv = this.getCurrentData().dateEnv; 4031 return dateEnv.format( 4032 dateEnv.createMarker(d), 4033 createFormatter(formatter) 4034 ); 4035 }; 4036 // `settings` is for formatter AND isEndExclusive 4037 CalendarApi.prototype.formatRange = function (d0, d1, settings) { 4038 var dateEnv = this.getCurrentData().dateEnv; 4039 return dateEnv.formatRange( 4040 dateEnv.createMarker(d0), 4041 dateEnv.createMarker(d1), 4042 createFormatter(settings), 4043 settings 4044 ); 4045 }; 4046 CalendarApi.prototype.formatIso = function (d, omitTime) { 4047 var dateEnv = this.getCurrentData().dateEnv; 4048 return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime }); 4049 }; 4050 // Date Selection / Event Selection / DayClick 4051 // ----------------------------------------------------------------------------------------------------------------- 4052 // this public method receives start/end dates in any format, with any timezone 4053 // NOTE: args were changed from v3 4054 CalendarApi.prototype.select = function (dateOrObj, endDate) { 4055 var selectionInput; 4056 if (endDate == null) { 4057 if (dateOrObj.start != null) { 4058 selectionInput = dateOrObj; 4059 } else { 4060 selectionInput = { 4061 start: dateOrObj, 4062 end: null, 4063 }; 4064 } 4065 } else { 4066 selectionInput = { 4067 start: dateOrObj, 4068 end: endDate, 4069 }; 4070 } 4071 var state = this.getCurrentData(); 4072 var selection = parseDateSpan( 4073 selectionInput, 4074 state.dateEnv, 4075 createDuration({ days: 1 }) // TODO: cache this? 4076 ); 4077 if (selection) { 4078 // throw parse error otherwise? 4079 this.dispatch({ type: "SELECT_DATES", selection: selection }); 4080 triggerDateSelect(selection, null, state); 4081 } 4082 }; 4083 // public method 4084 CalendarApi.prototype.unselect = function (pev) { 4085 var state = this.getCurrentData(); 4086 if (state.dateSelection) { 4087 this.dispatch({ type: "UNSELECT_DATES" }); 4088 triggerDateUnselect(pev, state); 4089 } 4090 }; 4091 // Public Events API 4092 // ----------------------------------------------------------------------------------------------------------------- 4093 CalendarApi.prototype.addEvent = function (eventInput, sourceIn
4093put) { 4094 if (eventInput instanceof EventApi) { 4095 var def = eventInput._def; 4096 var instance = eventInput._instance; 4097 var currentData = this.getCurrentData(); 4098 // not already present? don't want to add an old snapshot 4099 if (!currentData.eventStore.defs[def.defId]) { 4100 this.dispatch({ 4101 type: "ADD_EVENTS", 4102 eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args? 4103 }); 4104 this.triggerEventAdd(eventInput); 4105 } 4106 return eventInput; 4107 } 4108 var state = this.getCurrentData(); 4109 var eventSource; 4110 if (sourceInput instanceof EventSourceApi) { 4111 eventSource = sourceInput.internalEventSource; 4112 } else if (typeof sourceInput === "boolean") { 4113 if (sourceInput) { 4114 // true. part of the first event source 4115 eventSource = hashValuesToArray(state.eventSources)[0]; 4116 } 4117 } else if (sourceInput != null) { 4118 // an ID. accepts a number too 4119 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function 4120 if (!sourceApi) { 4121 console.warn( 4122 'Could not find an event source with ID "' + sourceInput + '"' 4123 ); // TODO: test 4124 return null; 4125 } else { 4126 eventSource = sourceApi.internalEventSource; 4127 } 4128 } 4129 var tuple = parseEvent(eventInput, eventSource, state, false); 4130 if (tuple) { 4131 var newEventApi = new EventApi( 4132 state, 4133 tuple.def, 4134 tuple.def.recurringDef ? null : tuple.instance 4135 ); 4136 this.dispatch({ 4137 type: "ADD_EVENTS", 4138 eventStore: eventTupleToStore(tuple), 4139 }); 4140 this.triggerEventAdd(newEventApi); 4141 return newEventApi; 4142 } 4143 return null; 4144 }; 4145 CalendarApi.prototype.triggerEventAdd = function (eventApi) { 4146 var _this = this; 4147 var emitter = this.getCurrentData().emitter; 4148 emitter.trigger("eventAdd", { 4149 event: eventApi, 4150 relatedEvents: [], 4151 revert: function () { 4152 _this.dispatch({ 4153 type: "REMOVE_EVENTS", 4154 eventStore: eventApiToStore(eventApi), 4155 }); 4156 }, 4157 }); 4158 }; 4159 // TODO: optimize 4160 CalendarApi.prototype.getEventById = function (id) { 4161 var state = this.getCurrentData(); 4162 var _a = state.eventStore, 4163 defs = _a.defs, 4164 instances = _a.instances; 4165 id = String(id); 4166 for (var defId in defs) { 4167 var def = defs[defId]; 4168 if (def.publicId === id) { 4169 if (def.recurringDef) { 4170 return new EventApi(state, def, null); 4171 } else { 4172 for (var instanceId in instances) { 4173 var instance = instances[instanceId]; 4174 if (instance.defId === def.defId) { 4175 return new EventApi(state, def, instance); 4176 } 4177 } 4178 } 4179 } 4180 } 4181 return null; 4182 }; 4183 CalendarApi.prototype.getEvents = function () { 4184 var currentData = this.getCurrentData(); 4185 return buildEventApis(currentData.eventStore, currentData); 4186 }; 4187 CalendarApi.prototype.removeAllEvents = function () { 4188 this.dispatch({ type: "REMOVE_ALL_EVENTS" }); 4189 }; 4190 // Public Event Sources API 4191 // ----------------------------------------------------------------------------------------------------------------- 4192 CalendarApi.prototype.getEventSources = function () { 4193 var state = this.getCurrentData(); 4194 var sourceHash = state.eventSources; 4195 var sourceApis = []; 4196 for (var internalId in sourceHash) { 4197 sourceApis.push(new EventSourceApi(state, sourceHash[internalId])); 4198 } 4199 return sourceApis; 4200 }; 4201 CalendarApi.prototype.getEventSourceById = function (id) { 4202 var state = this.getCurrentData(); 4203 var sourceHash = state.eventSources; 4204 id = String(id); 4205 for (var sourceId in sourceHash) { 4206 if (sourceHash[sourceId].publicId === id) { 4207 return new EventSourceApi(state, sourceHash[sourceId]); 4208 } 4209 } 4210 return null; 4211 }; 4212 CalendarApi.prototype.addEventSource = function (sourceInput) { 4213 var state = this.getCurrentData(); 4214 if (sourceInput instanceof EventSourceApi) { 4215 // not already present? don't want to add an old snapshot
4216 if (!state.eventSources[sourceInput.internalEventSource.sourceId]) { 4217 this.dispatch({ 4218 type: "ADD_EVENT_SOURCES", 4219 sources: [sourceInput.internalEventSource], 4220 }); 4221 } 4222 return sourceInput; 4223 } 4224 var eventSource = parseEventSource(sourceInput, state); 4225 if (eventSource) { 4226 // TODO: error otherwise? 4227 this.dispatch({ type: "ADD_EVENT_SOURCES", sources: [eventSource] }); 4228 return new EventSourceApi(state, eventSource); 4229 } 4230 return null; 4231 }; 4232 CalendarApi.prototype.removeAllEventSources = function () { 4233 this.dispatch({ type: "REMOVE_ALL_EVENT_SOURCES" }); 4234 }; 4235 CalendarApi.prototype.refetchEvents = function () { 4236 this.dispatch({ type: "FETCH_EVENT_SOURCES" }); 4237 }; 4238 // Scroll 4239 // ----------------------------------------------------------------------------------------------------------------- 4240 CalendarApi.prototype.scrollToTime = function (timeInput) { 4241 var time = createDuration(timeInput); 4242 if (time) { 4243 this.trigger("_scrollRequest", { time: time }); 4244 } 4245 }; 4246 return CalendarApi; 4247 })(); 4248 4249 var EventApi = /** @class */ (function () { 4250 // instance will be null if expressing a recurring event that has no current instances, 4251 // OR if trying to validate an incoming external event that has no dates assigned 4252 function EventApi(context, def, instance) { 4253 this._context = context; 4254 this._def = def; 4255 this._instance = instance || null; 4256 } 4257 /* 4258 TODO: make event struct more responsible for this 4259 */ 4260 EventApi.prototype.setProp = function (name, val) { 4261 var _a, _b; 4262 if (name in EVENT_DATE_REFINERS) { 4263 console.warn( 4264 "Could not set date-related prop 'name'. Use one of the date-related methods instead." 4265 ); 4266 } else if (name in EVENT_NON_DATE_REFINERS) { 4267 val = EVENT_NON_DATE_REFINERS[name](val); 4268 this.mutate({ 4269 standardProps: ((_a = {}), (_a[name] = val), _a), 4270 }); 4271 } else if (name in EVENT_UI_REFINERS) { 4272 var ui = EVENT_UI_REFINERS[name](val); 4273 if (name === "color") { 4274 ui = { backgroundColor: val, borderColor: val }; 4275 } else if (name === "editable") { 4276 ui = { startEditable: val, durationEditable: val }; 4277 } else { 4278 ui = ((_b = {}), (_b[name] = val), _b); 4279 } 4280 this.mutate({ 4281 standardProps: { ui: ui }, 4282 }); 4283 } else { 4284 console.warn( 4285 "Could not set prop '" + name + "'. Use setExtendedProp instead." 4286 ); 4287 } 4288 }; 4289 EventApi.prototype.setExtendedProp = function (name, val) { 4290 var _a; 4291 this.mutate({ 4292 extendedProps: ((_a = {}), (_a[name] = val), _a), 4293 }); 4294 }; 4295 EventApi.prototype.setStart = function (startInput, options) { 4296 if (options === void 0) { 4297 options = {}; 4298 } 4299 var dateEnv = this._context.dateEnv; 4300 var start = dateEnv.createMarker(startInput); 4301 if (start && this._instance) { 4302 // TODO: warning if parsed bad 4303 var instanceRange = this._instance.range; 4304 var startDelta = diffDates( 4305 instanceRange.start, 4306 start, 4307 dateEnv, 4308 options.granularity 4309 ); // what if parsed bad!? 4310 if (options.maintainDuration) { 4311 this.mutate({ datesDelta: startDelta }); 4312 } else { 4313 this.mutate({ startDelta: startDelta }); 4314 } 4315 } 4316 }; 4317 EventApi.prototype.setEnd = function (endInput, options) { 4318 if (options === void 0) { 4319 options = {}; 4320 } 4321 var dateEnv = this._context.dateEnv; 4322 var end; 4323 if (endInput != null) { 4324 end = dateEnv.createMarker(endInput); 4325 if (!end) { 4326 return; // TODO: warning if parsed bad 4327 } 4328 } 4329 if (this._instance) { 4330 if (end) { 4331 var endDelta = diffDates( 4332 this._instance.range.end, 4333 end, 4334 dateEnv, 4335 options.granularity 4336 ); 4337 this.mutate({ endDelta: endDelta }); 4338 } else { 4339 this.mutate({ standardProps: { hasEnd: false } }); 4340 } 4341 } 4342 }; 4343 EventApi.prototype.setDates = function (startInput, endInput, options) { 4344 if (options === void 0) { 4345 options = {}; 4346 } 4347 var dateEnv = this._context.dateEnv; 4348 var standardProps = { allDay: options.allDay }; 4349 var start = dateEnv.createMarker(startInput); 4350 var end; 4351 if (!start) { 4352 return; // TODO: warning if parsed bad 4353 } 4354 if (endInput != null) { 4355 end = dateEnv.createMarker(endInput); 4356 if (!end) { 4357 // TODO: warning if parsed bad 4358 return; 4359 } 4360 } 4361 if (this._instance) { 4362 var instanceRange = this._instance.range; 4363 // when computing the diff for an event being converted to all-day, 4364 // compute diff off of the all-day values the way event-mutation does. 4365 if (options.allDay === true) { 4366 instanceRange = computeAlignedDayRange(instanceRange); 4367 } 4368 var startDelta = diffDates( 4369 instanceRange.start, 4370 start, 4371 dateEnv, 4372 options.granularity 4373 ); 4374 if (end) { 4375 var endDelta = diffDates( 4376 instanceRange.end, 4377 end, 4378 dateEnv, 4379 options.granularity 4380 ); 4381 if (durationsEqual(startDelta, endDelta)) { 4382 this.mutate({ 4383 datesDelta: startDelta, 4384 standardProps: standardProps, 4385 }); 4386 } else { 4387 this.mutate({ 4388 startDelta: startDelta, 4389 endDelta: endDelta, 4390 standardProps: standardProps, 4391 }); 4392 } 4393 } else { 4394 // means "clear the end" 4395 standardProps.hasEnd = false;
4396 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 4397 } 4398 } 4399 }; 4400 EventApi.prototype.moveStart = function (deltaInput) { 4401 var delta = createDuration(deltaInput); 4402 if (delta) { 4403 // TODO: warning if parsed bad 4404 this.mutate({ startDelta: delta }); 4405 } 4406 }; 4407 EventApi.prototype.moveEnd = function (deltaInput) { 4408 var delta = createDuration(deltaInput); 4409 if (delta) { 4410 // TODO: warning if parsed bad 4411 this.mutate({ endDelta: delta }); 4412 } 4413 }; 4414 EventApi.prototype.moveDates = function (deltaInput) { 4415 var delta = createDuration(deltaInput); 4416 if (delta) { 4417 // TODO: warning if parsed bad 4418 this.mutate({ datesDelta: delta }); 4419 } 4420 }; 4421 EventApi.prototype.setAllDay = function (allDay, options) { 4422 if (options === void 0) { 4423 options = {}; 4424 } 4425 var standardProps = { allDay: allDay }; 4426 var maintainDuration = options.maintainDuration; 4427 if (maintainDuration == null) { 4428 maintainDuration = this._context.options.allDayMaintainDuration; 4429 } 4430 if (this._def.allDay !== allDay) { 4431 standardProps.hasEnd = maintainDuration; 4432 } 4433 this.mutate({ standardProps: standardProps }); 4434 }; 4435 EventApi.prototype.formatRange = function (formatInput) { 4436 var dateEnv = this._context.dateEnv; 4437 var instance = this._instance; 4438 var formatter = createFormatter(formatInput); 4439 if (this._def.hasEnd) { 4440 return dateEnv.formatRange( 4441 instance.range.start, 4442 instance.range.end, 4443 formatter, 4444 { 4445 forcedStartTzo: instance.forcedStartTzo, 4446 forcedEndTzo: instance.forcedEndTzo, 4447 } 4448 ); 4449 } else { 4450 return dateEnv.format(instance.range.start, formatter, { 4451 forcedTzo: instance.forcedStartTzo, 4452 }); 4453 } 4454 }; 4455 EventApi.prototype.mutate = function (mutation) { 4456 var instance = this._instance; 4457 if (instance) { 4458 var def = this._def; 4459 var context_1 = this._context; 4460 var eventStore = context_1.getCurrentData().eventStore; 4461 var relevantEvents_1 = getRelevantEvents( 4462 eventStore, 4463 instance.instanceId 4464 ); 4465 var eventConfigBase = { 4466 "": { 4467 display: "", 4468 startEditable: true, 4469 durationEditable: true, 4470 constraints: [], 4471 overlap: null, 4472 allows: [], 4473 backgroundColor: "", 4474 borderColor: "", 4475 textColor: "", 4476 classNames: [], 4477 }, 4478 }; 4479 relevantEvents_1 = applyMutationToEventStore( 4480 relevantEvents_1, 4481 eventConfigBase, 4482 mutation, 4483 context_1 4484 ); 4485 var oldEvent = new EventApi(context_1, def, instance); // snapshot 4486 this._def = relevantEvents_1.defs[def.defId]; 4487 this._instance = relevantEvents_1.instances[instance.instanceId]; 4488 context_1.dispatch({ 4489 type: "MERGE_EVENTS", 4490 eventStore: relevantEvents_1, 4491 }); 4492 context_1.emitter.trigger("eventChange", { 4493 oldEvent: oldEvent, 4494 event: this, 4495 relatedEvents: buildEventApis(relevantEvents_1, context_1, instance), 4496 revert: function () { 4497 context_1.dispatch({ 4498 type: "REMOVE_EVENTS", 4499 eventStore: relevantEvents_1, 4500 }); 4501 }, 4502 }); 4503 } 4504 }; 4505 EventApi.prototype.remove = function () { 4506 var context = this._context; 4507 var asStore = eventApiToStore(this); 4508 context.dispatch({ 4509 type: "REMOVE_EVENTS", 4510 eventStore: asStore, 4511 }); 4512 context.emitter.trigger("eventRemove", { 4513 event: this, 4514 relatedEvents: [], 4515 revert: function () { 4516 context.dispatch({ 4517 type: "MERGE_EVENTS", 4518 eventStore: asStore, 4519 }); 4520 }, 4521 }); 4522 }; 4523 Object.defineProperty(EventApi.prototype, "source", { 4524 get: function () { 4525 var sourceId = this._def.sourceId; 4526 if (sourceId) { 4527 return new EventSourceApi( 4528 this._context, 4529 this._context.getCurrentData().eventSources[sourceId] 4530 ); 4531 } 4532 return null; 4533 }, 4534 enumerable: false, 4535 configurable: true, 4536 });
4537 Object.defineProperty(EventApi.prototype, "start", { 4538 get: function () { 4539 return this._instance 4540 ? this._context.dateEnv.toDate(this._instance.range.start) 4541 : null; 4542 }, 4543 enumerable: false, 4544 configurable: true, 4545 }); 4546 Object.defineProperty(EventApi.prototype, "end", { 4547 get: function () { 4548 return this._instance && this._def.hasEnd 4549 ? this._context.dateEnv.toDate(this._instance.range.end) 4550 : null; 4551 }, 4552 enumerable: false, 4553 configurable: true, 4554 }); 4555 Object.defineProperty(EventApi.prototype, "startStr", { 4556 get: function () { 4557 var instance = this._instance; 4558 if (instance) { 4559 return this._context.dateEnv.formatIso(instance.range.start, { 4560 omitTime: this._def.allDay, 4561 forcedTzo: instance.forcedStartTzo, 4562 }); 4563 } 4564 return ""; 4565 }, 4566 enumerable: false, 4567 configurable: true, 4568 }); 4569 Object.defineProperty(EventApi.prototype, "endStr", { 4570 get: function () { 4571 var instance = this._instance; 4572 if (instance && this._def.hasEnd) { 4573 return this._context.dateEnv.formatIso(instance.range.end, { 4574 omitTime: this._def.allDay, 4575 forcedTzo: instance.forcedEndTzo, 4576 }); 4577 } 4578 return ""; 4579 }, 4580 enumerable: false, 4581 configurable: true, 4582 }); 4583 Object.defineProperty(EventApi.prototype, "id", { 4584 // computable props that all access the def
4585 // TODO: find a TypeScript-compatible way to do this at scale 4586 get: function () { 4587 return this._def.publicId; 4588 }, 4589 enumerable: false, 4590 configurable: true, 4591 }); 4592 Object.defineProperty(EventApi.prototype, "groupId", { 4593 get: function () { 4594 return this._def.groupId; 4595 }, 4596 enumerable: false, 4597 configurable: true, 4598 }); 4599 Object.defineProperty(EventApi.prototype, "allDay", { 4600 get: function () { 4601 return this._def.allDay; 4602 }, 4603 enumerable: false, 4604 configurable: true, 4605 }); 4606 Object.defineProperty(EventApi.prototype, "title", { 4607 get: function () { 4608 return this._def.title; 4609 }, 4610 enumerable: false, 4611 configurable: true, 4612 }); 4613 Object.defineProperty(EventApi.prototype, "url", { 4614 get: function () { 4615 return this._def.url; 4616 }, 4617 enumerable: false, 4618 configurable: true, 4619 }); 4620 Object.defineProperty(EventApi.prototype, "display", { 4621 get: function () { 4622 return this._def.ui.display || "auto"; 4623 }, // bad. just normalize the type earlier 4624 enumerable: false, 4625 configurable: true, 4626 }); 4627 Object.defineProperty(EventApi.prototype, "startEditable", { 4628 get: function () { 4629 return this._def.ui.startEditable; 4630 }, 4631 enumerable: false, 4632 configurable: true, 4633 }); 4634 Object.defineProperty(EventApi.prototype, "durationEditable", { 4635 get: function () { 4636 return this._def.ui.durationEditable; 4637 }, 4638 enumerable: false, 4639 configurable: true, 4640 }); 4641 Object.defineProperty(EventApi.prototype, "constraint", { 4642 get: function () { 4643 return this._def.ui.constraints[0] || null; 4644 }, 4645 enumerable: false, 4646 configurable: true, 4647 }); 4648 Object.defineProperty(EventApi.prototype, "overlap", { 4649 get: function () { 4650 return this._def.ui.overlap; 4651 }, 4652 enumerable: false, 4653 configurable: true, 4654 }); 4655 Object.defineProperty(EventApi.prototype, "allow", { 4656 get: function () { 4657 return this._def.ui.allows[0] || null; 4658 }, 4659 enumerable: false, 4660 configurable: true, 4661 }); 4662 Object.defineProperty(EventApi.prototype, "backgroundColor", { 4663 get: function () { 4664 return this._def.ui.backgroundColor; 4665 }, 4666 enumerable: false, 4667 configurable: true, 4668 }); 4669 Object.defineProperty(EventApi.prototype, "borderColor", { 4670 get: function () { 4671 return this._def.ui.borderColor; 4672 }, 4673 enumerable: false, 4674 configurable: true, 4675 }); 4676 Object.defineProperty(EventApi.prototype, "textColor", { 4677 get: function () { 4678 return this._def.ui.textColor; 4679 }, 4680 enumerable: false, 4681 configurable: true, 4682 }); 4683 Object.defineProperty(EventApi.prototype, "classNames", { 4684 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 4685 get: function () { 4686 return this._def.ui.classNames; 4687 }, 4688 enumerable: false, 4689 configurable: true, 4690 }); 4691 Object.defineProperty(EventApi.prototype, "extendedProps", { 4692 get: function () { 4693 return this._def.extendedProps; 4694 }, 4695 enumerable: false, 4696 configurable: true, 4697 }); 4698 EventApi.prototype.toPlainObject = function (settings) { 4699 if (settings === void 0) { 4700 settings = {}; 4701 } 4702 var def = this._def; 4703 var ui = def.ui; 4704 var _a = this, 4705 startStr = _a.startStr, 4706 endStr = _a.endStr; 4707 var res = {}; 4708 if (def.title) { 4709 res.title = def.title; 4710 } 4711 if (startStr) { 4712 res.start = startStr; 4713 } 4714 if (endStr) { 4715 res.end = endStr; 4716 } 4717 if (def.publicId) { 4718 res.id = def.publicId; 4719 } 4720 if (def.groupId) { 4721 res.groupId = def.groupId; 4722 } 4723 if (def.url) { 4724 res.url = def.url; 4725 } 4726 if (ui.display && ui.display !== "auto") { 4727 res.display = ui.display; 4728 } 4729 // TODO: what about recurring-event properties??? 4730 // TODO: include startEditable/durationEditable/constraint/overlap/allow 4731 if ( 4732 settings.collapseColor && 4733 ui.backgroundColor && 4734 ui.backgroundColor === ui.borderColor 4735 ) { 4736 res.color = ui.backgroundColor; 4737 } else { 4738 if (ui.backgroundColor) { 4739 res.backgroundColor = ui.backgroundColor; 4740 } 4741 if (ui.borderColor) { 4742 res.borderColor = ui.borderColor; 4743 } 4744 } 4745 if (ui.textColor) { 4746 res.textColor = ui.textColor; 4747 } 4748 if (ui.classNames.length) { 4749 res.classNames = ui.classNames; 4750 } 4751 if (Object.keys(def.extendedProps).length) { 4752 if (settings.collapseExtendedProps) { 4753 __assign(res, def.extendedProps); 4754 } else { 4755 res.extendedProps = def.extendedProps; 4756 } 4757 } 4758 return res; 4759 }; 4760 EventApi.prototype.toJSON = function () { 4761 return this.toPlainObject(); 4762 }; 4763 return EventApi; 4764 })(); 4765 function eventApiToStore(eventApi) { 4766 var _a, _b; 4767 var def = eventApi._def; 4768 var instance = eventApi._instance; 4769 return { 4770 defs: ((_a = {}), (_a[def.defId] = def), _a), 4771 instances: instance 4772 ? ((_b = {}), (_b[instance.instanceId] = instance), _b) 4773 : {}, 4774 }; 4775 } 4776 function buildEventApis(eventStore, context, excludeInstance) { 4777 var defs = eventStore.defs, 4778 instances = eventStore.instances; 4779 var eventApis = []; 4780 var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : ""; 4781 for (var id in instances) { 4782 var instance = instances[id]; 4783 var def = defs[instance.defId]; 4784 if (instance.instanceId !== excludeInstanceId) { 4785 eventApis.push(new EventApi(context, def, instance)); 4786 } 4787 } 4788 return eventApis; 4789 } 4790 4791 var calendarSystemClassMap = {}; 4792 function registerCalendarSystem(name, theClass) { 4793 calendarSystemClassMap[name] = theClass; 4794 } 4795 function createCalendarSystem(name) { 4796 return new calendarSystemClassMap[name](); 4797 } 4798 var GregorianCalendarSystem = /** @class */ (function () { 4799 function GregorianCalendarSystem() {} 4800 GregorianCalendarSystem.prototype.getMarkerYear = function (d) { 4801 return d.getUTCFullYear(); 4802 }; 4803 GregorianCalendarSystem.prototype.getMarkerMonth = function (d) { 4804 return d.getUTCMonth(); 4805 }; 4806 GregorianCalendarSystem.prototype.getMarkerDay = function (d) { 4807 return d.getUTCDate(); 4808 }; 4809 GregorianCalendarSystem.prototype.arrayToMarker = function (arr) { 4810 return arrayToUtcDate(arr); 4811 }; 4812 GregorianCalendarSystem.prototype.markerToArray = function (marker) { 4813 return dateToUtcArray(marker); 4814 }; 4815 return GregorianCalendarSystem; 4816 })(); 4817 registerCalendarSystem("gregory", GregorianCalendarSystem); 4818 4819 var ISO_RE = 4820 /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 4821 function parse(str) { 4822 var m = ISO_RE.exec(str); 4823 if (m) { 4824 var marker = new Date( 4825 Date.UTC( 4826 Number(m[1]), 4827 m[3] ? Number(m[3]) - 1 : 0, 4828 Number(m[5] || 1), 4829 Number(m[7] || 0), 4830 Number(m[8] || 0), 4831 Number(m[10] || 0), 4832 m[12] ? Number("0." + m[12]) * 1000 : 0 4833 ) 4834 ); 4835 if (isValidDate(marker)) { 4836 var timeZoneOffset = null; 4837 if (m[13]) { 4838 timeZoneOffset = 4839 (m[15] === "-" ? -1 : 1) * 4840 (Number(m[16] || 0) * 60 + Number(m[18] || 0)); 4841 } 4842 return { 4843 marker: marker, 4844 isTimeUnspecified: !m[6], 4845 timeZoneOffset: timeZoneOffset, 4846 }; 4847 } 4848 } 4849 return null; 4850 } 4851 4852 var DateEnv = /** @class */ (function () { 4853 function DateEnv(settings) { 4854 var timeZone = (this.timeZone = settings.timeZone); 4855 var isNamedTimeZone = timeZone !== "local" && timeZone !== "UTC"; 4856 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 4857 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 4858 } 4859 this.canComputeOffset = Boolean( 4860 !isNamedTimeZone || this.namedTimeZoneImpl 4861 ); 4862 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 4863 this.locale = settings.locale; 4864 this.weekDow = settings.locale.week.dow; 4865 this.weekDoy = settings.locale.week.doy; 4866 if (settings.weekNumberCalculation === "ISO") { 4867 this.weekDow = 1; 4868 this.weekDoy = 4; 4869 } 4870 if (typeof settings.firstDay === "number") { 4871 this.weekDow = settings.firstDay; 4872 } 4873 if (typeof settings.weekNumberCalculation === "function") {
4874 this.weekNumberFunc = settings.weekNumberCalculation; 4875 } 4876 this.weekText = 4877 settings.weekText != null 4878 ? settings.weekText 4879 : settings.locale.options.weekText; 4880 this.cmdFormatter = settings.cmdFormatter; 4881 this.defaultSeparator = settings.defaultSeparator; 4882 } 4883 // Creating / Parsing 4884 DateEnv.prototype.createMarker = function (input) { 4885 var meta = this.createMarkerMeta(input); 4886 if (meta === null) { 4887 return null; 4888 } 4889 return meta.marker; 4890 }; 4891 DateEnv.prototype.createNowMarker = function () { 4892 if (this.canComputeOffset) { 4893 return this.timestampToMarker(new Date().valueOf()); 4894 } else { 4895 // if we can't compute the current date val for a timezone, 4896 // better to give the current local date vals than UTC 4897 return arrayToUtcDate(dateToLocalArray(new Date())); 4898 } 4899 }; 4900 DateEnv.prototype.createMarkerMeta = function (input) { 4901 if (typeof input === "string") { 4902 return this.parse(input); 4903 } 4904 var marker = null; 4905 if (typeof input === "number") { 4906 marker = this.timestampToMarker(input); 4907 } else if (input instanceof Date) { 4908 input = input.valueOf(); 4909 if (!isNaN(input)) { 4910 marker = this.timestampToMarker(input); 4911 } 4912 } else if (Array.isArray(input)) { 4913 marker = arrayToUtcDate(input); 4914 } 4915 if (marker === null || !isValidDate(marker)) { 4916 return null; 4917 } 4918 return { marker: marker, isTimeUnspecified: false, forcedTzo: null }; 4919 }; 4920 DateEnv.prototype.parse = function (s) { 4921 var parts = parse(s); 4922 if (parts === null) { 4923 return null; 4924 } 4925 var marker = parts.marker; 4926 var forcedTzo = null; 4927 if (parts.timeZoneOffset !== null) { 4928 if (this.canComputeOffset) { 4929 marker = this.timestampToMarker( 4930 marker.valueOf() - parts.timeZoneOffset * 60 * 1000 4931 ); 4932 } else { 4933 forcedTzo = parts.timeZoneOffset; 4934 } 4935 } 4936 return { 4937 marker: marker, 4938 isTimeUnspecified: parts.isTimeUnspecified, 4939 forcedTzo: forcedTzo, 4940 }; 4941 }; 4942 // Accessors 4943 DateEnv.prototype.getYear = function (marker) { 4944 return this.calendarSystem.getMarkerYear(marker); 4945 }; 4946 DateEnv.prototype.getMonth = function (marker) { 4947 return this.calendarSystem.getMarkerMonth(marker); 4948 }; 4949 // Adding / Subtracting 4950 DateEnv.prototype.add = function (marker, dur) { 4951 var a = this.calendarSystem.markerToArray(marker); 4952 a[0] += dur.years; 4953 a[1] += dur.months; 4954 a[2] += dur.days; 4955 a[6] += dur.milliseconds; 4956 return this.calendarSystem.arrayToMarker(a); 4957 }; 4958 DateEnv.prototype.subtract = function (marker, dur) { 4959 var a = this.calendarSystem.markerToArray(marker); 4960 a[0] -= dur.years; 4961 a[1] -= dur.months; 4962 a[2] -= dur.days; 4963 a[6] -= dur.milliseconds; 4964 return this.calendarSystem.arrayToMarker(a); 4965 }; 4966 DateEnv.prototype.addYears = function (marker, n) { 4967 var a = this.calendarSystem.markerToArray(marker); 4968 a[0] += n; 4969 return this.calendarSystem.arrayToMarker(a); 4970 }; 4971 DateEnv.prototype.addMonths = function (marker, n) { 4972 var a = this.calendarSystem.markerToArray(marker); 4973 a[1] += n; 4974 return this.calendarSystem.arrayToMarker(a); 4975 }; 4976 // Diffing Whole Units 4977 DateEnv.prototype.diffWholeYears = function (m0, m1) { 4978 var calendarSystem = this.calendarSystem; 4979 if ( 4980 timeAsMs(m0) === timeAsMs(m1) && 4981 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && 4982 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1) 4983 ) { 4984 return ( 4985 calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0) 4986 ); 4987 } 4988 return null; 4989 }; 4990 DateEnv.prototype.diffWholeMonths = function (m0, m1) { 4991 var calendarSystem = this.calendarSystem; 4992 if ( 4993 timeAsMs(m0) === timeAsMs(m1) && 4994 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) 4995 ) { 4996 return ( 4997 calendarSystem.getMarkerMonth(m1) - 4998 calendarSystem.getMarkerMonth(m0) + 4999 (calendarSystem.getMarkerYear(m1) - 5000 calendarSystem.getMarkerYear(m0)) * 5001 12 5002 ); 5003 } 5004 return null; 5005 }; 5006 // Range / Duration 5007 DateEnv.prototype.greatestWholeUnit = function (m0, m1) { 5008 var n = this.diffWholeYears(m0, m1); 5009 if (n !== null) { 5010 return { unit: "year", value: n }; 5011 } 5012 n = this.diffWholeMonths(m0, m1); 5013 if (n !== null) { 5014 return { unit: "month", value: n }; 5015 } 5016 n = diffWholeWeeks(m0, m1); 5017 if (n !== null) { 5018 return { unit: "week", value: n }; 5019 } 5020 n = diffWholeDays(m0, m1); 5021 if (n !== null) { 5022 return { unit: "day", value: n }; 5023 } 5024 n = diffHours(m0, m1); 5025 if (isInt(n)) { 5026 return { unit: "hour", value: n }; 5027 } 5028 n = diffMinutes(m0, m1); 5029 if (isInt(n)) { 5030 return { unit: "minute", value: n }; 5031 } 5032 n = diffSeconds(m0, m1); 5033 if (isInt(n)) { 5034 return { unit: "second", value: n }; 5035 } 5036 return { unit: "millisecond", value: m1.valueOf() - m0.valueOf() }; 5037 }; 5038 DateEnv.prototype.countDurationsBetween = function (m0, m1, d) { 5039 // TODO: can use greatestWholeUnit 5040 var diff; 5041 if (d.years) { 5042 diff = this.diffWholeYears(m0, m1); 5043 if (diff !== null) { 5044 return diff / asRoughYears(d); 5045 } 5046 } 5047 if (d.months) { 5048 diff = this.diffWholeMonths(m0, m1); 5049 if (diff !== null) { 5050 return diff / asRoughMonths(d); 5051 } 5052 } 5053 if (d.days) { 5054 diff = diffWholeDays(m0, m1); 5055 if (diff !== null) { 5056 return diff / asRoughDays(d); 5057 } 5058 } 5059 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d); 5060 }; 5061 // Start-Of 5062 // these DON'T return zoned-dates. only UTC start-of dates 5063 DateEnv.prototype.startOf = function (m, unit) { 5064 if (unit === "year") { 5065 return this.startOfYear(m); 5066 } else if (unit === "month") { 5067 return this.startOfMonth(m); 5068 } else if (unit === "week") { 5069 return this.startOfWeek(m); 5070 } else if (unit === "day") { 5071 return startOfDay(m); 5072 } else if (unit === "hour") { 5073 return startOfHour(m); 5074 } else if (unit === "minute") { 5075 return startOfMinute(m); 5076 } else if (unit === "second") { 5077 return startOfSecond(m); 5078 } 5079 }; 5080 DateEnv.prototype.startOfYear = function (m) { 5081 return this.calendarSystem.arrayToMarker([ 5082 this.calendarSystem.getMarkerYear(m), 5083 ]); 5084 }; 5085 DateEnv.prototype.startOfMonth = function (m) { 5086 return this.calendarSystem.arrayToMarker([ 5087 this.calendarSystem.getMarkerYear(m), 5088 this.calendarSystem.getMarkerMonth(m), 5089 ]); 5090 }; 5091 DateEnv.prototype.startOfWeek = function (m) { 5092 return this.calendarSystem.arrayToMarker([ 5093 this.calendarSystem.getMarkerYear(m), 5094 this.calendarSystem.getMarkerMonth(m), 5095 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7), 5096 ]); 5097 }; 5098 // Week Number 5099 DateEnv.prototype.computeWeekNumber = function (marker) { 5100 if (this.weekNumberFunc) { 5101 return this.weekNumberFunc(this.toDate(marker)); 5102 } else { 5103 return weekOfYear(marker, this.weekDow, this.weekDoy); 5104 } 5105 }; 5106 // TODO: choke on timeZoneName: long 5107 DateEnv.prototype.format = function (marker, formatter, dateOptions) { 5108 if (dateOptions === void 0) { 5109 dateOptions = {}; 5110 } 5111 return formatter.format( 5112 { 5113 marker: marker, 5114 timeZoneOffset: 5115 dateOptions.forcedTzo != null 5116 ? dateOptions.forcedTzo 5117 : this.offsetForMarker(marker), 5118 }, 5119 this 5120 ); 5121 }; 5122 DateEnv.prototype.formatRange = function ( 5123 start, 5124 end, 5125 formatter, 5126 dateOptions 5127 ) { 5128 if (dateOptions === void 0) { 5129 dateOptions = {}; 5130 } 5131 if (dateOptions.isEndExclusive) { 5132 end = addMs(end, -1); 5133 } 5134 return formatter.formatRange( 5135 { 5136 marker: start, 5137 timeZoneOffset: 5138 dateOptions.forcedStartTzo != null 5139 ? dateOptions.forcedStartTzo 5140 : this.offsetForMarker(start), 5141 }, 5142 { 5143 marker: end, 5144 timeZoneOffset: 5145 dateOptions.forcedEndTzo != null 5146 ? dateOptions.forcedEndTzo 5147 : this.offsetForMarker(end), 5148 }, 5149 this, 5150 dateOptions.defaultSeparator 5151 ); 5152 }; 5153 /* 5154 DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that, 5155 might as well use buildIsoString or some other util directly 5156 */ 5157 DateEnv.prototype.formatIso = function (marker, extraOptions) { 5158 if (extraOptions === void 0) { 5159 extraOptions = {}; 5160 } 5161 var timeZoneOffset = null; 5162 if (!extraOptions.omitTimeZoneOffset) { 5163 if (extraOptions.forcedTzo != null) { 5164 timeZoneOffset = extraOptions.forcedTzo; 5165 } else { 5166 timeZoneOffset = this.offsetForMarker(marker); 5167 } 5168 } 5169 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 5170 }; 5171 // TimeZone 5172 DateEnv.prototype.timestampToMarker = function (ms) { 5173 if (this.timeZone === "local") { 5174 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 5175 } else if (this.timeZone === "UTC" || !this.namedTimeZoneImpl) { 5176 return new Date(ms); 5177 } else { 5178 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 5179 } 5180 }; 5181 DateEnv.prototype.offsetForMarker = function (m) { 5182 if (this.timeZone === "local") { 5183 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset 5184 } else if (this.timeZone === "UTC") { 5185 return 0; 5186 } else if (this.namedTimeZoneImpl) { 5187 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)); 5188 } 5189 return null; 5190 }; 5191 // Conversion 5192 DateEnv.prototype.toDate = function (m, forcedTzo) { 5193 if (this.timeZone === "local") { 5194 return arrayToLocalDate(dateToUtcArray(m)); 5195 } else if (this.timeZone === "UTC") { 5196 return new Date(m.valueOf()); // make sure it's a copy 5197 } else if (!this.namedTimeZoneImpl) { 5198 return new Date(m.valueOf() - (forcedTzo || 0)); 5199 } else { 5200 return new Date( 5201 m.valueOf() - 5202 this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60 // convert minutes -> ms 5203 ); 5204 } 5205 }; 5206 return DateEnv; 5207 })(); 5208 5209 var globalLocales = []; 5210 5211 var RAW_EN_LOCALE = { 5212 code: "en", 5213 week: { 5214 dow: 0, 5215 doy: 4, // 4 days need to be within the year to be considered the first week 5216 }, 5217 direction: "ltr", 5218 buttonText: { 5219 prev: "prev", 5220 next: "next", 5221 prevYear: "prev year", 5222 nextYear: "next year", 5223 year: "year", 5224 today: "today", 5225 month: "month", 5226 week: "week", 5227 day: "day", 5228 list: "list", 5229 }, 5230 weekText: "W", 5231 allDayText: "all-day", 5232 moreLinkText: "daha fazla", 5233 noEventsText: "No events to display", 5234 }; 5235 function organizeRawLocales(explicitRawLocales) { 5236 var defaultCode = 5237 explicitRawLocales.length > 0 ? explicitRawLocales[0].code : "en"; 5238 var allRawLocales = globalLocales.concat(explicitRawLocales); 5239 var rawLocaleMap = { 5240 en: RAW_EN_LOCALE, // necessary? 5241 }; 5242 for ( 5243 var _i = 0, allRawLocales_1 = allRawLocales; 5244 _i < allRawLocales_1.length; 5245 _i++ 5246 ) { 5247 var rawLocale = allRawLocales_1[_i]; 5248 rawLocaleMap[rawLocale.code] = rawLocale; 5249 } 5250 return { 5251 map: rawLocaleMap, 5252 defaultCode: defaultCode, 5253 }; 5254 } 5255 function buildLocale(inputSingular, available) { 5256 if (typeof inputSingular === "object" && !Array.isArray(inputSingular)) { 5257 return parseLocale( 5258 inputSingular.code, 5259 [inputSingular.code], 5260 inputSingular 5261 ); 5262 } else { 5263 return queryLocale(inputSingular, available); 5264 } 5265 } 5266 function queryLocale(codeArg, available) { 5267 var codes = [].concat(codeArg || []); // will convert to array 5268 var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 5269 return parseLocale(codeArg, codes, raw); 5270 } 5271 function queryRawLocale(codes, available) { 5272 for (var i = 0; i < codes.length; i++) { 5273 var parts = codes[i].toLocaleLowerCase().split("-"); 5274 for (var j = parts.length; j > 0; j--) { 5275 var simpleId = parts.slice(0, j).join("-"); 5276 if (available[simpleId]) { 5277 return available[simpleId]; 5278 } 5279 } 5280 } 5281 return null; 5282 } 5283 function parseLocale(codeArg, codes, raw) { 5284 var merged = mergeProps([RAW_EN_LOCALE, raw], ["buttonText"]); 5285 delete merged.code; // don't want this part of the options 5286 var week = merged.week; 5287 delete merged.week; 5288 return { 5289 codeArg: codeArg, 5290 codes: codes, 5291 week: week, 5292 simpleNumberFormat: new Intl.NumberFormat(codeArg), 5293 options: merged, 5294 }; 5295 } 5296 5297 function formatDate(dateInput, options) { 5298 if (options === void 0) { 5299 options = {}; 5300 } 5301 var dateEnv = buildDateEnv(options); 5302 var formatter = createFormatter(options); 5303 var dateMeta = dateEnv.createMarkerMeta(dateInput); 5304 if (!dateMeta) { 5305 // TODO: warning? 5306 return ""; 5307 } 5308 return dateEnv.format(dateMeta.marker, formatter, { 5309 forcedTzo: dateMeta.forcedTzo, 5310 }); 5311 } 5312 function formatRange( 5313 startInput, 5314 endInput, 5315 options // mixture of env and formatter settings 5316 ) { 5317 var dateEnv = buildDateEnv( 5318 typeof options === "object" && options ? options : {} 5319 ); // pass in if non-null object 5320 var formatter = createFormatter(options); 5321 var startMeta = dateEnv.createMarkerMeta(startInput); 5322 var endMeta = dateEnv.createMarkerMeta(endInput); 5323 if (!startMeta || !endMeta) { 5324 // TODO: warning? 5325 return ""; 5326 } 5327 return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, { 5328 forcedStartTzo: startMeta.forcedTzo, 5329 forcedEndTzo: endMeta.forcedTzo, 5330 isEndExclusive: options.isEndExclusive, 5331 defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator, 5332 }); 5333 } 5334 // TODO: more DRY and optimized 5335 function buildDateEnv(settings) { 5336 var locale = buildLocale( 5337 settings.locale || "en", 5338 organizeRawLocales([]).map 5339 ); // TODO: don't hardcode 'en' everywhere 5340 return new DateEnv( 5341 __assign( 5342 __assign( 5343 { 5344 timeZone: BASE_OPTION_DEFAULTS.timeZone, 5345 calendarSystem: "gregory", 5346 }, 5347 settings 5348 ), 5349 { locale: locale } 5350 ) 5351 ); 5352 } 5353 5354 var DEF_DEFAULTS = {
5355 startTime: "09:00", 5356 endTime: "17:00", 5357 daysOfWeek: [1, 2, 3, 4, 5], 5358 display: "inverse-background", 5359 classNames: "fc-non-business", 5360 groupId: "_businessHours", // so multiple defs get grouped 5361 }; 5362 /* 5363 TODO: pass around as EventDefHash!!! 5364 */ 5365 function parseBusinessHours(input, context) { 5366 return parseEvents(refineInputs(input), null, context); 5367 } 5368 function refineInputs(input) { 5369 var rawDefs; 5370 if (input === true) { 5371 rawDefs = [{}]; // will get DEF_DEFAULTS verbatim 5372 } else if (Array.isArray(input)) { 5373 // if specifying an array, every sub-definition NEEDS a day-of-week 5374 rawDefs = input.filter(function (rawDef) { 5375 return rawDef.daysOfWeek; 5376 }); 5377 } else if (typeof input === "object" && input) { 5378 // non-null object 5379 rawDefs = [input]; 5380 } else { 5381 // is probably false 5382 rawDefs = []; 5383 } 5384 rawDefs = rawDefs.map(function (rawDef) { 5385 return __assign(__assign({}, DEF_DEFAULTS), rawDef); 5386 }); 5387 return rawDefs; 5388 } 5389 5390 function pointInsideRect(point, rect) { 5391 return ( 5392 point.left >= rect.left && 5393 point.left < rect.right && 5394 point.top >= rect.top && 5395 point.top < rect.bottom 5396 ); 5397 } 5398 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 5399 function intersectRects(rect1, rect2) { 5400 var res = { 5401 left: Math.max(rect1.left, rect2.left), 5402 right: Math.min(rect1.right, rect2.right), 5403 top: Math.max(rect1.top, rect2.top), 5404 bottom: Math.min(rect1.bottom, rect2.bottom), 5405 }; 5406 if (res.left < res.right && res.top < res.bottom) { 5407 return res; 5408 } 5409 return false; 5410 } 5411 function translateRect(rect, deltaX, deltaY) { 5412 return { 5413 left: rect.left + deltaX, 5414 right: rect.right + deltaX, 5415 top: rect.top + deltaY, 5416 bottom: rect.bottom + deltaY, 5417 }; 5418 } 5419 // Returns a new point that will have been moved to reside within the given rectangle 5420 function constrainPoint(point, rect) { 5421 return { 5422 left: Math.min(Math.max(point.left, rect.left), rect.right), 5423 top: Math.min(Math.max(point.top, rect.top), rect.bottom), 5424 }; 5425 } 5426 // Returns a point that is the center of the given rectangle 5427 function getRectCenter(rect) { 5428 return { 5429 left: (rect.left + rect.right) / 2, 5430 top: (rect.top + rect.bottom) / 2, 5431 }; 5432 } 5433 // Subtracts point2's coordinates from point1's coordinates, returning a delta 5434 function diffPoints(point1, point2) { 5435 return { 5436 left: point1.left - point2.left, 5437 top: point1.top - point2.top, 5438 }; 5439 } 5440 5441 var canVGrowWithinCell; 5442 function getCanVGrowWithinCell() { 5443 if (canVGrowWithinCell == null) { 5444 canVGrowWithinCell = computeCanVGrowWithinCell(); 5445 } 5446 return canVGrowWithinCell; 5447 } 5448 function computeCanVGrowWithinCell() { 5449 // for SSR, because this function is call immediately at top-level 5450 // TODO: just make this logic execute top-level, immediately, instead of doing lazily 5451 if (typeof document === "undefined") { 5452 return true; 5453 } 5454 var el = document.createElement("div"); 5455 el.style.position = "absolute"; 5456 el.style.top = "0px"; 5457 el.style.left = "0px"; 5458 el.innerHTML = "<table><tr><td><div></div></td></tr></table>"; 5459 el.querySelector("table").style.height = "100px"; 5460 el.querySelector("div").style.height = "100%"; 5461 document.body.appendChild(el); 5462 var div = el.querySelector("div"); 5463 var possible = div.offsetHeight > 0; 5464 document.body.removeChild(el); 5465 return possible; 5466 } 5467 5468 var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere 5469 var Splitter = /** @class */ (function () { 5470 function Splitter() { 5471 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 5472 this.splitDateSelection = memoize(this._splitDateSpan); 5473 this.splitEventStore = memoize(this._splitEventStore); 5474 this.splitIndividualUi = memoize(this._splitIndividualUi); 5475 this.splitEventDrag = memoize(this._splitInteraction); 5476 this.splitEventResize = memoize(this._splitInteraction); 5477 this.eventUiBuilders = {}; // TODO: typescript protection 5478 } 5479 Splitter.prototype.splitProps = function (props) { 5480 var _this = this; 5481 var keyInfos = this.getKeyInfo(props);
5482 var defKeys = this.getKeysForEventDefs(props.eventStore); 5483 var dateSelections = this.splitDateSelection(props.dateSelection); 5484 var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases* 5485 var eventStores = this.splitEventStore(props.eventStore, defKeys); 5486 var eventDrags = this.splitEventDrag(props.eventDrag); 5487 var eventResizes = this.splitEventResize(props.eventResize); 5488 var splitProps = {}; 5489 this.eventUiBuilders = mapHash(keyInfos, function (info, key) { 5490 return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); 5491 }); 5492 for (var key in keyInfos) { 5493 var keyInfo = keyInfos[key]; 5494 var eventStore = eventStores[key] || EMPTY_EVENT_STORE; 5495 var buildEventUi = this.eventUiBuilders[key]; 5496 splitProps[key] = { 5497 businessHours: keyInfo.businessHours || props.businessHours, 5498 dateSelection: dateSelections[key] || null, 5499 eventStore: eventStore, 5500 eventUiBases: buildEventUi( 5501 props.eventUiBases[""], 5502 keyInfo.ui, 5503 individualUi[key] 5504 ), 5505 eventSelection: eventStore.instances[props.eventSelection] 5506 ? props.eventSelection 5507 : "", 5508 eventDrag: eventDrags[key] || null, 5509 eventResize: eventResizes[key] || null, 5510 }; 5511 } 5512 return splitProps; 5513 }; 5514 Splitter.prototype._splitDateSpan = function (dateSpan) { 5515 var dateSpans = {}; 5516 if (dateSpan) { 5517 var keys = this.getKeysForDateSpan(dateSpan); 5518 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 5519 var key = keys_1[_i]; 5520 dateSpans[key] = dateSpan; 5521 } 5522 } 5523 return dateSpans; 5524 }; 5525 Splitter.prototype._getKeysForEventDefs = function (eventStore) { 5526 var _this = this; 5527 return mapHash(eventStore.defs, function (eventDef) { 5528 return _this.getKeysForEventDef(eventDef); 5529 }); 5530 }; 5531 Splitter.prototype._splitEventStore = function (eventStore, defKeys) { 5532 var defs = eventStore.defs, 5533 instances = eventStore.instances; 5534 var splitStores = {}; 5535 for (var defId in defs) { 5536 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 5537 var key = _a[_i]; 5538 if (!splitStores[key]) { 5539 splitStores[key] = createEmptyEventStore(); 5540 } 5541 splitStores[key].defs[defId] = defs[defId]; 5542 } 5543 } 5544 for (var instanceId in instances) { 5545 var instance = instances[instanceId]; 5546 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) { 5547 var key = _c[_b]; 5548 if (splitStores[key]) { 5549 // must have already been created 5550 splitStores[key].instances[instanceId] = instance; 5551 } 5552 } 5553 } 5554 return splitStores; 5555 }; 5556 Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) { 5557 var splitHashes = {}; 5558 for (var defId in eventUiBases) { 5559 if (defId) { 5560 // not the '' key 5561 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 5562 var key = _a[_i]; 5563 if (!splitHashes[key]) { 5564 splitHashes[key] = {}; 5565 } 5566 splitHashes[key][defId] = eventUiBases[defId]; 5567 } 5568 } 5569 } 5570 return splitHashes; 5571 }; 5572 Splitter.prototype._splitInteraction = function (interaction) { 5573 var splitStates = {}; 5574 if (interaction) { 5575 var affectedStores_1 = this._splitEventStore( 5576 interaction.affectedEvents, 5577 this._getKeysForEventDefs(interaction.affectedEvents) // can't use cached. might be events from other calendar 5578 ); 5579 // can't rely on defKeys because event data is mutated 5580 var mutatedKeysByDefId = this._getKeysForEventDefs( 5581 interaction.mutatedEvents 5582 ); 5583 var mutatedStores_1 = this._splitEventStore( 5584 interaction.mutatedEvents, 5585 mutatedKeysByDefId 5586 ); 5587 var populate = function (key) { 5588 if (!splitStates[key]) { 5589 splitStates[key] = { 5590 affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE, 5591 mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE, 5592 isEvent: interaction.isEvent, 5593 }; 5594 } 5595 }; 5596 for (var key in affectedStores_1) { 5597 populate(key); 5598 } 5599 for (var key in mutatedStores_1) { 5600 populate(key); 5601 } 5602 } 5603 return splitStates; 5604 }; 5605 return Splitter; 5606 })(); 5607 function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 5608 var baseParts = []; 5609 if (allUi) { 5610 baseParts.push(allUi); 5611 } 5612 if (eventUiForKey) { 5613 baseParts.push(eventUiForKey); 5614 } 5615 var stuff = { 5616 "": combineEventUis(baseParts), 5617 }; 5618 if (individualUi) { 5619 __assign(stuff, individualUi); 5620 } 5621 return stuff; 5622 } 5623 5624 function getDateMeta(date, todayRange, nowDate, dateProfile) { 5625 return { 5626 dow: date.getUTCDay(), 5627 isDisabled: Boolean( 5628 dateProfile && !rangeContainsMarker(dateProfile.activeRange, date) 5629 ), 5630 isOther: Boolean( 5631 dateProfile && !rangeContainsMarker(dateProfile.currentRange, date) 5632 ), 5633 isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)), 5634 isPast: Boolean( 5635 nowDate ? date < nowDate : todayRange ? date < todayRange.start : false 5636 ), 5637 isFuture: Boolean( 5638 nowDate ? date > nowDate : todayRange ? date >= todayRange.end : false 5639 ), 5640 }; 5641 } 5642 function getDayClassNames(meta, theme) {
5643 var classNames = ["fc-day", "fc-day-" + DAY_IDS[meta.dow]]; 5644 if (meta.isDisabled) { 5645 classNames.push("fc-day-disabled"); 5646 } else { 5647 if (meta.isToday) { 5648 classNames.push("fc-day-today"); 5649 classNames.push(theme.getClass("today")); 5650 } 5651 if (meta.isPast) { 5652 classNames.push("fc-day-past"); 5653 } 5654 if (meta.isFuture) { 5655 classNames.push("fc-day-future"); 5656 } 5657 if (meta.isOther) { 5658 classNames.push("fc-day-other"); 5659 } 5660 } 5661 return classNames; 5662 } 5663 function getSlotClassNames(meta, theme) { 5664 var classNames = ["fc-slot", "fc-slot-" + DAY_IDS[meta.dow]]; 5665 if (meta.isDisabled) { 5666 classNames.push("fc-slot-disabled"); 5667 } else { 5668 if (meta.isToday) { 5669 classNames.push("fc-slot-today"); 5670 classNames.push(theme.getClass("today")); 5671 } 5672 if (meta.isPast) { 5673 classNames.push("fc-slot-past"); 5674 } 5675 if (meta.isFuture) { 5676 classNames.push("fc-slot-future"); 5677 } 5678 } 5679 return classNames; 5680 } 5681 5682 function buildNavLinkData(date, type) { 5683 if (type === void 0) { 5684 type = "day"; 5685 } 5686 return JSON.stringify({ 5687 date: formatDayString(date), 5688 type: type, 5689 }); 5690 } 5691 5692 var _isRtlScrollbarOnLeft = null; 5693 function getIsRtlScrollbarOnLeft() { 5694 if (_isRtlScrollbarOnLeft === null) { 5695 _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 5696 } 5697 return _isRtlScrollbarOnLeft; 5698 } 5699 function computeIsRtlScrollbarOnLeft() { 5700 var outerEl = document.createElement("div"); 5701 applyStyle(outerEl, { 5702 position: "absolute", 5703 top: -1000, 5704 left: 0, 5705 border: 0, 5706 padding: 0, 5707 overflow: "scroll", 5708 direction: "rtl", 5709 }); 5710 outerEl.innerHTML = "<div></div>"; 5711 document.body.appendChild(outerEl); 5712 var innerEl = outerEl.firstChild; 5713 var res = 5714 innerEl.getBoundingClientRect().left > 5715 outerEl.getBoundingClientRect().left; 5716 removeElement(outerEl); 5717 return res; 5718 } 5719 5720 var _scrollbarWidths; 5721 function getScrollbarWidths() { 5722 if (!_scrollbarWidths) { 5723 _scrollbarWidths = computeScrollbarWidths(); 5724 } 5725 return _scrollbarWidths; 5726 } 5727 function computeScrollbarWidths() { 5728 var el = document.createElement("div"); 5729 el.style.overflow = "scroll"; 5730 document.body.appendChild(el); 5731 var res = computeScrollbarWidthsForEl(el); 5732 document.body.removeChild(el); 5733 return res; 5734 } 5735 // WARNING: will include border 5736 function computeScrollbarWidthsForEl(el) { 5737 return { 5738 x: el.offsetHeight - el.clientHeight, 5739 y: el.offsetWidth - el.clientWidth, 5740 }; 5741 } 5742 5743 function computeEdges(el, getPadding) { 5744 if (getPadding === void 0) { 5745 getPadding = false; 5746 } 5747 var computedStyle = window.getComputedStyle(el); 5748 var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 5749 var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 5750 var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 5751 var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 5752 var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border! 5753 var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight; 5754 var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom; 5755 var res = { 5756 borderLeft: borderLeft, 5757 borderRight: borderRight, 5758 borderTop: borderTop, 5759 borderBottom: borderBottom, 5760 scrollbarBottom: scrollbarBottom, 5761 scrollbarLeft: 0, 5762 scrollbarRight: 0, 5763 }; 5764 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === "rtl") { 5765 // is the scrollbar on the left side? 5766 res.scrollbarLeft = scrollbarLeftRight; 5767 } else { 5768 res.scrollbarRight = scrollbarLeftRight; 5769 } 5770 if (getPadding) { 5771 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 5772 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 5773 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 5774 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 5775 } 5776 return res; 5777 } 5778 function computeInnerRect(el, goWithinPadding, doFromWindowViewport) { 5779 if (goWithinPadding === void 0) { 5780 goWithinPadding = false;
5781 } 5782 var outerRect = doFromWindowViewport 5783 ? el.getBoundingClientRect() 5784 : computeRect(el); 5785 var edges = computeEdges(el, goWithinPadding); 5786 var res = { 5787 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 5788 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 5789 top: outerRect.top + edges.borderTop, 5790 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom, 5791 }; 5792 if (goWithinPadding) { 5793 res.left += edges.paddingLeft; 5794 res.right -= edges.paddingRight; 5795 res.top += edges.paddingTop; 5796 res.bottom -= edges.paddingBottom; 5797 } 5798 return res; 5799 } 5800 function computeRect(el) { 5801 var rect = el.getBoundingClientRect(); 5802 return { 5803 left: rect.left + window.pageXOffset, 5804 top: rect.top + window.pageYOffset, 5805 right: rect.right + window.pageXOffset, 5806 bottom: rect.bottom + window.pageYOffset, 5807 }; 5808 } 5809 function computeHeightAndMargins(el) { 5810 return el.getBoundingClientRect().height + computeVMargins(el); 5811 } 5812 function computeVMargins(el) { 5813 var computed = window.getComputedStyle(el); 5814 return ( 5815 parseInt(computed.marginTop, 10) + parseInt(computed.marginBottom, 10) 5816 ); 5817 } 5818 // does not return window 5819 function getClippingParents(el) { 5820 var parents = []; 5821 while (el instanceof HTMLElement) { 5822 // will stop when gets to document or null 5823 var computedStyle = window.getComputedStyle(el); 5824 if (computedStyle.position === "fixed") { 5825 break; 5826 } 5827 if ( 5828 /(auto|scroll)/.test( 5829 computedStyle.overflow + 5830 computedStyle.overflowY + 5831 computedStyle.overflowX 5832 ) 5833 ) { 5834 parents.push(el); 5835 } 5836 el = el.parentNode; 5837 } 5838 return parents; 5839 } 5840 5841 // given a function that resolves a result asynchronously. 5842 // the function can either call passed-in success and failure callbacks, 5843 // or it can return a promise. 5844 // if you need to pass additional params to func, bind them first. 5845 function unpromisify(func, success, failure) { 5846 // guard against success/failure callbacks being called more than once 5847 // and guard against a promise AND callback being used together. 5848 var isResolved = false; 5849 var wrappedSuccess = function () { 5850 if (!isResolved) { 5851 isResolved = true; 5852 success.apply(this, arguments); 5853 } 5854 }; 5855 var wrappedFailure = function () { 5856 if (!isResolved) { 5857 isResolved = true; 5858 if (failure) { 5859 failure.apply(this, arguments); 5860 } 5861 } 5862 }; 5863 var res = func(wrappedSuccess, wrappedFailure); 5864 if (res && typeof res.then === "function") { 5865 res.then(wrappedSuccess, wrappedFailure); 5866 } 5867 } 5868 5869 var Emitter = /** @class */ (function () { 5870 function Emitter() { 5871 this.handlers = {}; 5872 this.thisContext = null; 5873 } 5874 Emitter.prototype.setThisContext = function (thisContext) { 5875 this.thisContext = thisContext; 5876 }; 5877 Emitter.prototype.setOptions = function (options) { 5878 this.options = options; 5879 }; 5880 Emitter.prototype.on = function (type, handler) { 5881 addToHash(this.handlers, type, handler); 5882 }; 5883 Emitter.prototype.off = function (type, handler) { 5884 removeFromHash(this.handlers, type, handler); 5885 }; 5886 Emitter.prototype.trigger = function (type) { 5887 var args = []; 5888 for (var _i = 1; _i < arguments.length; _i++) { 5889 args[_i - 1] = arguments[_i]; 5890 } 5891 var attachedHandlers = this.handlers[type] || []; 5892 var optionHandler = this.options && this.options[type]; 5893 var handlers = [].concat(optionHandler || [], attachedHandlers); 5894 for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { 5895 var handler = handlers_1[_a]; 5896 handler.apply(this.thisContext, args); 5897 } 5898 }; 5899 Emitter.prototype.hasHandlers = function (type) { 5900 return ( 5901 (this.handlers[type] && this.handlers[type].length) || 5902 (this.options && this.options[type]) 5903 ); 5904 }; 5905 return Emitter; 5906 })(); 5907 function addToHash(hash, type, handler) { 5908 (hash[type] || (hash[type] = [])).push(handler); 5909 } 5910 function removeFromHash(hash, type, handler) { 5911 if (handler) { 5912 if (hash[type]) { 5913 hash[type] = hash[type].filter(function (func) { 5914 return func !== handler; 5915 }); 5916 } 5917 } else { 5918 delete hash[type]; // remove all handler funcs for this type 5919 } 5920 } 5921 5922 /* 5923 Records offset information for a set of elements, relative to an origin element. 5924 Can record the left/right OR the top/bottom OR both. 5925 Provides methods for querying the cache by position. 5926 */ 5927 var PositionCache = /** @class */ (function () { 5928 function PositionCache(originEl, els, isHorizontal, isVertical) { 5929 this.els = els; 5930 var originClientRect = (this.originClientRect = 5931 originEl.getBoundingClientRect()); // relative to viewport top-left 5932 if (isHorizontal) { 5933 this.buildElHorizontals(originClientRect.left); 5934 } 5935 if (isVertical) { 5936 this.buildElVerticals(originClientRect.top); 5937 } 5938 }
5939 // Populates the left/right internal coordinate arrays 5940 PositionCache.prototype.buildElHorizontals = function (originClientLeft) { 5941 var lefts = []; 5942 var rights = []; 5943 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 5944 var el = _a[_i]; 5945 var rect = el.getBoundingClientRect(); 5946 lefts.push(rect.left - originClientLeft); 5947 rights.push(rect.right - originClientLeft); 5948 } 5949 this.lefts = lefts; 5950 this.rights = rights; 5951 }; 5952 // Populates the top/bottom internal coordinate arrays 5953 PositionCache.prototype.buildElVerticals = function (originClientTop) { 5954 var tops = []; 5955 var bottoms = []; 5956 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 5957 var el = _a[_i]; 5958 var rect = el.getBoundingClientRect(); 5959 tops.push(rect.top - originClientTop); 5960 bottoms.push(rect.bottom - originClientTop); 5961 } 5962 this.tops = tops; 5963 this.bottoms = bottoms; 5964 }; 5965 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 5966 // If no intersection is made, returns undefined. 5967 PositionCache.prototype.leftToIndex = function (leftPosition) { 5968 var lefts = this.lefts; 5969 var rights = this.rights; 5970 var len = lefts.length; 5971 var i; 5972 for (i = 0; i < len; i++) { 5973 if (leftPosition >= lefts[i] && leftPosition < rights[i]) { 5974 return i; 5975 } 5976 } 5977 }; 5978 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 5979 // If no intersection is made, returns undefined. 5980 PositionCache.prototype.topToIndex = function (topPosition) { 5981 var tops = this.tops; 5982 var bottoms = this.bottoms; 5983 var len = tops.length; 5984 var i; 5985 for (i = 0; i < len; i++) { 5986 if (topPosition >= tops[i] && topPosition < bottoms[i]) { 5987 return i; 5988 } 5989 } 5990 }; 5991 // Gets the width of the element at the given index 5992 PositionCache.prototype.getWidth = function (leftIndex) { 5993 return this.rights[leftIndex] - this.lefts[leftIndex]; 5994 }; 5995 // Gets the height of the element at the given index 5996 PositionCache.prototype.getHeight = function (topIndex) { 5997 return this.bottoms[topIndex] - this.tops[topIndex]; 5998 }; 5999 return PositionCache; 6000 })(); 6001 6002 /* 6003 An object for getting/setting scroll-related information for an element. 6004 Internally, this is done very differently for window versus DOM element, 6005 so this object serves as a common interface. 6006 */ 6007 var ScrollController = /** @class */ (function () { 6008 function ScrollController() {} 6009 ScrollController.prototype.getMaxScrollTop = function () { 6010 return this.getScrollHeight() - this.getClientHeight(); 6011 }; 6012 ScrollController.prototype.getMaxScrollLeft = function () { 6013 return this.getScrollWidth() - this.getClientWidth(); 6014 }; 6015 ScrollController.prototype.canScrollVertically = function () { 6016 return this.getMaxScrollTop() > 0; 6017 }; 6018 ScrollController.prototype.canScrollHorizontally = function () { 6019 return this.getMaxScrollLeft() > 0; 6020 }; 6021 ScrollController.prototype.canScrollUp = function () { 6022 return this.getScrollTop() > 0; 6023 }; 6024 ScrollController.prototype.canScrollDown = function () { 6025 return this.getScrollTop() < this.getMaxScrollTop(); 6026 }; 6027 ScrollController.prototype.canScrollLeft = function () { 6028 return this.getScrollLeft() > 0; 6029 }; 6030 ScrollController.prototype.canScrollRight = function () { 6031 return this.getScrollLeft() < this.getMaxScrollLeft(); 6032 }; 6033 return ScrollController; 6034 })(); 6035 var ElementScrollController = /** @class */ (function (_super) { 6036 __extends(ElementScrollController, _super); 6037 function ElementScrollController(el) { 6038 var _this = _super.call(this) || this; 6039 _this.el = el; 6040 return _this; 6041 } 6042 ElementScrollController.prototype.getScrollTop = function () { 6043 return this.el.scrollTop; 6044 }; 6045 ElementScrollController.prototype.getScrollLeft = function () { 6046 return this.el.scrollLeft; 6047 }; 6048 ElementScrollController.prototype.setScrollTop = function (top) { 6049 this.el.scrollTop = top; 6050 }; 6051 ElementScrollController.prototype.setScrollLeft = function (left) { 6052 this.el.scrollLeft = left; 6053 }; 6054 ElementScrollController.prototype.getScrollWidth = function () { 6055 return this.el.scrollWidth; 6056 }; 6057 ElementScrollController.prototype.getScrollHeight = function () { 6058 return this.el.scrollHeight; 6059 }; 6060 ElementScrollController.prototype.getClientHeight = function () { 6061 return this.el.clientHeight; 6062 }; 6063 ElementScrollController.prototype.getClientWidth = function () { 6064 return this.el.clientWidth; 6065 }; 6066 return ElementScrollController; 6067 })(ScrollController); 6068 var WindowScrollController = /** @class */ (function (_super) { 6069 __extends(WindowScrollController, _super); 6070 function WindowScrollController() { 6071 return (_super !== null && _super.apply(this, arguments)) || this; 6072 } 6073 WindowScrollController.prototype.getScrollTop = function () { 6074 return window.pageYOffset; 6075 }; 6076 WindowScrollController.prototype.getScrollLeft = function () { 6077 return window.pageXOffset; 6078 }; 6079 WindowScrollController.prototype.setScrollTop = function (n) { 6080 window.scroll(window.pageXOffset, n); 6081 }; 6082 WindowScrollController.prototype.setScrollLeft = function (n) { 6083 window.scroll(n, window.pageYOffset); 6084 }; 6085 WindowScrollController.prototype.getScrollWidth = function () { 6086 return document.documentElement.scrollWidth; 6087 }; 6088 WindowScrollController.prototype.getScrollHeight = function () { 6089 return document.documentElement.scrollHeight; 6090 }; 6091 WindowScrollController.prototype.getClientHeight = function () { 6092 return document.documentElement.clientHeight; 6093 }; 6094 WindowScrollController.prototype.getClientWidth = function () { 6095 return document.documentElement.clientWidth; 6096 }; 6097 return WindowScrollController; 6098 })(ScrollController); 6099 6100 var Theme = /** @class */ (function () { 6101 function Theme(calendarOptions) { 6102 if (this.iconOverrideOption) { 6103 this.setIconOverride(calendarOptions[this.iconOverrideOption]); 6104 } 6105 } 6106 Theme.prototype.setIconOverride = function (iconOverrideHash) { 6107 var iconClassesCopy; 6108 var buttonName; 6109 if (typeof iconOverrideHash === "object" && iconOverrideHash) { 6110 // non-null object 6111 iconClassesCopy = __assign({}, this.iconClasses); 6112 for (buttonName in iconOverrideHash) { 6113 iconClassesCopy[buttonName] = this.applyIconOverridePrefix( 6114 iconOverrideHash[buttonName] 6115 ); 6116 } 6117 this.iconClasses = iconClassesCopy; 6118 } else if (iconOverrideHash === false) { 6119 this.iconClasses = {}; 6120 } 6121 }; 6122 Theme.prototype.applyIconOverridePrefix = function (className) { 6123 var prefix = this.iconOverridePrefix; 6124 if (prefix && className.indexOf(prefix) !== 0) { 6125 // if not already present 6126 className = prefix + className; 6127 } 6128 return className; 6129 }; 6130 Theme.prototype.getClass = function (key) { 6131 return this.classes[key] || ""; 6132 }; 6133 Theme.prototype.getIconClass = function (buttonName, isRtl) { 6134 var className; 6135 if (isRtl && this.rtlIconClasses) { 6136 className = 6137 this.rtlIconClasses[buttonName] || this.iconClasses[buttonName]; 6138 } else { 6139 className = this.iconClasses[buttonName]; 6140 } 6141 if (className) { 6142 return this.baseIconClass + " " + className; 6143 } 6144 return ""; 6145 }; 6146 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 6147 var className; 6148 if (this.iconOverrideCustomButtonOption) { 6149 className = customButtonProps[this.iconOverrideCustomButtonOption]; 6150 if (className) { 6151 return ( 6152 this.baseIconClass + " " + this.applyIconOverridePrefix(className) 6153 ); 6154 } 6155 } 6156 return ""; 6157 }; 6158 return Theme; 6159 })(); 6160 Theme.prototype.classes = {}; 6161 Theme.prototype.iconClasses = {}; 6162 Theme.prototype.baseIconClass = ""; 6163 Theme.prototype.iconOverridePrefix = ""; 6164 6165 /// <reference types="@fullcalendar/core-vdom" /> 6166 if (typeof FullCalendarVDom === "undefined") { 6167 throw new Error( 6168 "Please import the top-level fullcalendar lib before attempting to import a plugin." 6169 ); 6170 } 6171 var Component = FullCalendarVDom.Component; 6172 var createElement = FullCalendarVDom.createElement; 6173 var render = FullCalendarVDom.render; 6174 var createRef = FullCalendarVDom.createRef; 6175 var Fragment = FullCalendarVDom.Fragment; 6176 var createContext$1 = FullCalendarVDom.createContext; 6177 var flushToDom$1 = FullCalendarVDom.flushToDom; 6178 6179 var ScrollResponder = /** @class */ (function () { 6180 function ScrollResponder(execFunc, emitter, scrollTime) { 6181 var _this = this; 6182 this.execFunc = execFunc; 6183 this.emitter = emitter; 6184 this.scrollTime = scrollTime; 6185 this.handleScrollRequest = function (request) { 6186 _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request); 6187 _this.drain(); 6188 }; 6189 emitter.on("_scrollRequest", this.handleScrollRequest); 6190 this.fireInitialScroll(); 6191 } 6192 ScrollResponder.prototype.detach = function () { 6193 this.emitter.off("_scrollRequest", this.handleScrollRequest); 6194 }; 6195 ScrollResponder.prototype.update = function (isDatesNew) { 6196 if (isDatesNew) { 6197 this.fireInitialScroll(); // will drain 6198 } else { 6199 this.drain(); 6200 } 6201 }; 6202 ScrollResponder.prototype.fireInitialScroll = function () { 6203 this.handleScrollRequest({ 6204 time: this.scrollTime, 6205 }); 6206 };
6207 ScrollResponder.prototype.drain = function () { 6208 if (this.queuedRequest && this.execFunc(this.queuedRequest)) { 6209 this.queuedRequest = null; 6210 } 6211 }; 6212 return ScrollResponder; 6213 })(); 6214 6215 var ViewContextType = createContext$1({}); // for Components 6216 function buildViewContext( 6217 viewSpec, 6218 viewApi, 6219 viewOptions, 6220 dateProfileGenerator, 6221 dateEnv, 6222 theme, 6223 pluginHooks, 6224 dispatch, 6225 getCurrentData, 6226 emitter, 6227 calendarApi, 6228 registerInteractiveComponent, 6229 unregisterInteractiveComponent 6230 ) { 6231 return { 6232 dateEnv: dateEnv, 6233 options: viewOptions, 6234 pluginHooks: pluginHooks, 6235 emitter: emitter, 6236 dispatch: dispatch, 6237 getCurrentData: getCurrentData, 6238 calendarApi: calendarApi, 6239 viewSpec: viewSpec, 6240 viewApi: viewApi, 6241 dateProfileGenerator: dateProfileGenerator, 6242 theme: theme, 6243 isRtl: viewOptions.direction === "rtl", 6244 addResizeHandler: function (handler) { 6245 emitter.on("_resize", handler); 6246 }, 6247 removeResizeHandler: function (handler) { 6248 emitter.off("_resize", handler); 6249 }, 6250 createScrollResponder: function (execFunc) { 6251 return new ScrollResponder( 6252 execFunc, 6253 emitter, 6254 createDuration(viewOptions.scrollTime) 6255 ); 6256 }, 6257 registerInteractiveComponent: registerInteractiveComponent, 6258 unregisterInteractiveComponent: unregisterInteractiveComponent, 6259 }; 6260 } 6261 6262 var PureComponent = /** @class */ (function (_super) { 6263 __extends(PureComponent, _super); 6264 function PureComponent() { 6265 return (_super !== null && _super.apply(this, arguments)) || this; 6266 } 6267 PureComponent.prototype.shouldComponentUpdate = function ( 6268 nextProps, 6269 nextState 6270 ) { 6271 if (this.debug) { 6272 console.log( 6273 getUnequalProps(nextProps, this.props), 6274 getUnequalProps(nextState, this.state) 6275 ); 6276 } 6277 return ( 6278 !compareObjs(this.props, nextProps, this.propEquality) || 6279 !compareObjs(this.state, nextState, this.stateEquality) 6280 ); 6281 }; 6282 PureComponent.addPropsEquality = addPropsEquality; 6283 PureComponent.addStateEquality = addStateEquality; 6284 PureComponent.contextType = ViewContextType; 6285 return PureComponent; 6286 })(Component); 6287 PureComponent.prototype.propEquality = {}; 6288 PureComponent.prototype.stateEquality = {}; 6289 var BaseComponent = /** @class */ (function (_super) { 6290 __extends(BaseComponent, _super); 6291 function BaseComponent() { 6292 return (_super !== null && _super.apply(this, arguments)) || this; 6293 } 6294 BaseComponent.contextType = ViewContextType; 6295 return BaseComponent; 6296 })(PureComponent); 6297 function addPropsEquality(propEquality) { 6298 var hash = Object.create(this.prototype.propEquality); 6299 __assign(hash, propEquality); 6300 this.prototype.propEquality = hash; 6301 } 6302 function addStateEquality(stateEquality) { 6303 var hash = Object.create(this.prototype.stateEquality); 6304 __assign(hash, stateEquality); 6305 this.prototype.stateEquality = hash; 6306 } 6307 // use other one 6308 function setRef(ref, current) { 6309 if (typeof ref === "function") { 6310 ref(current); 6311 } else if (ref) { 6312 // see https://github.com/facebook/react/issues/13029 6313 ref.current = current; 6314 } 6315 } 6316 6317 function reduceEventStore( 6318 eventStore, 6319 action, 6320 eventSources, 6321 dateProfile, 6322 context 6323 ) { 6324 switch (action.type) { 6325 case "RECEIVE_EVENTS": // raw 6326 return receiveRawEvents( 6327 eventStore, 6328 eventSources[action.sourceId], 6329 action.fetchId, 6330 action.fetchRange, 6331 action.rawEvents, 6332 context 6333 ); 6334 case "ADD_EVENTS": // already parsed, but not expanded 6335 return addEvent( 6336 eventStore, 6337 action.eventStore, // new ones 6338 dateProfile ? dateProfile.activeRange : null, 6339 context 6340 ); 6341 case "MERGE_EVENTS": // already parsed and expanded 6342 return mergeEventStores(eventStore, action.eventStore); 6343 case "PREV": // TODO: how do we track all actions that affect dateProfile :( 6344 case "NEXT": 6345 case "CHANGE_DATE": 6346 case "CHANGE_VIEW_TYPE": 6347 if (dateProfile) { 6348 return expandRecurring(eventStore, dateProfile.activeRange, context); 6349 } else { 6350 return eventStore; 6351 }
6352 case "REMOVE_EVENTS": 6353 return excludeSubEventStore(eventStore, action.eventStore); 6354 case "REMOVE_EVENT_SOURCE": 6355 return excludeEventsBySourceId(eventStore, action.sourceId); 6356 case "REMOVE_ALL_EVENT_SOURCES": 6357 return filterEventStoreDefs(eventStore, function (eventDef) { 6358 return !eventDef.sourceId; // only keep events with no source id 6359 }); 6360 case "REMOVE_ALL_EVENTS": 6361 return createEmptyEventStore(); 6362 default: 6363 return eventStore; 6364 } 6365 } 6366 function receiveRawEvents( 6367 eventStore, 6368 eventSource, 6369 fetchId, 6370 fetchRange, 6371 rawEvents, 6372 context 6373 ) { 6374 if ( 6375 eventSource && // not already removed 6376 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 6377 ) { 6378 var subset = parseEvents( 6379 transformRawEvents(rawEvents, eventSource, context), 6380 eventSource, 6381 context 6382 ); 6383 if (fetchRange) { 6384 subset = expandRecurring(subset, fetchRange, context); 6385 } 6386 return mergeEventStores( 6387 excludeEventsBySourceId(eventStore, eventSource.sourceId), 6388 subset 6389 ); 6390 } 6391 return eventStore; 6392 } 6393 function transformRawEvents(rawEvents, eventSource, context) { 6394 var calEachTransform = context.options.eventDataTransform; 6395 var sourceEachTransform = eventSource 6396 ? eventSource.eventDataTransform 6397 : null; 6398 if (sourceEachTransform) { 6399 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 6400 } 6401 if (calEachTransform) { 6402 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 6403 } 6404 return rawEvents; 6405 } 6406 function transformEachRawEvent(rawEvents, func) { 6407 var refinedEvents; 6408 if (!func) { 6409 refinedEvents = rawEvents; 6410 } else { 6411 refinedEvents = []; 6412 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 6413 var rawEvent = rawEvents_1[_i]; 6414 var refinedEvent = func(rawEvent); 6415 if (refinedEvent) { 6416 refinedEvents.push(refinedEvent); 6417 } else if (refinedEvent == null) { 6418 refinedEvents.push(rawEvent); 6419 } // if a different falsy value, do nothing 6420 } 6421 } 6422 return refinedEvents; 6423 } 6424 function addEvent(eventStore, subset, expandRange, context) { 6425 if (expandRange) { 6426 subset = expandRecurring(subset, expandRange, context); 6427 } 6428 return mergeEventStores(eventStore, subset); 6429 } 6430 function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 6431 var defs = eventStore.defs; 6432 var instances = mapHash(eventStore.instances, function (instance) { 6433 var def = defs[instance.defId]; 6434 if (def.allDay || def.recurringDef) { 6435 return instance; // isn't dependent on timezone 6436 } else { 6437 return __assign(__assign({}, instance), { 6438 range: { 6439 start: newDateEnv.createMarker( 6440 oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo) 6441 ), 6442 end: newDateEnv.createMarker( 6443 oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo) 6444 ), 6445 }, 6446 forcedStartTzo: newDateEnv.canComputeOffset 6447 ? null 6448 : instance.forcedStartTzo, 6449 forcedEndTzo: newDateEnv.canComputeOffset 6450 ? null 6451 : instance.forcedEndTzo, 6452 }); 6453 } 6454 }); 6455 return { defs: defs, instances: instances }; 6456 } 6457 function excludeEventsBySourceId(eventStore, sourceId) { 6458 return filterEventStoreDefs(eventStore, function (eventDef) { 6459 return eventDef.sourceId !== sourceId; 6460 }); 6461 } 6462 // QUESTION: why not just return instances? do a general object-property-exclusion util 6463 function excludeInstances(eventStore, removals) { 6464 return { 6465 defs: eventStore.defs, 6466 instances: filterHash(eventStore.instances, function (instance) { 6467 return !removals[instance.instanceId]; 6468 }), 6469 }; 6470 } 6471 6472 // high-level segmenting-aware tester functions 6473 // ------------------------------------------------------------------------------------------------------------------------ 6474 function isInteractionValid(interaction, context) { 6475 return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions 6476 } 6477 function isDateSelectionValid(dateSelection, context) { 6478 return isNewPropsValid({ dateSelection: dateSelection }, context); 6479 } 6480 function isNewPropsValid(newProps, context) { 6481 var calendarState = context.getCurrentData(); 6482 var props = __assign( 6483 { 6484 businessHours: calendarState.businessHours, 6485 dateSelection: "", 6486 eventStore: calendarState.eventStore, 6487 eventUiBases: calendarState.eventUiBases, 6488 eventSelection: "", 6489 eventDrag: null, 6490 eventResize: null, 6491 }, 6492 newProps 6493 ); 6494 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 6495 } 6496 function isPropsValid(state, context, dateSpanMeta, filterConfig) {
6497 if (dateSpanMeta === void 0) { 6498 dateSpanMeta = {}; 6499 } 6500 if ( 6501 state.eventDrag && 6502 !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) 6503 ) { 6504 return false; 6505 } 6506 if ( 6507 state.dateSelection && 6508 !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) 6509 ) { 6510 return false; 6511 } 6512 return true; 6513 } 6514 // Moving Event Validation 6515 // ------------------------------------------------------------------------------------------------------------------------ 6516 function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 6517 var currentState = context.getCurrentData(); 6518 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 6519 var subjectEventStore = interaction.mutatedEvents; 6520 var subjectDefs = subjectEventStore.defs; 6521 var subjectInstances = subjectEventStore.instances; 6522 var subjectConfigs = compileEventUis( 6523 subjectDefs, 6524 interaction.isEvent 6525 ? state.eventUiBases 6526 : { "": currentState.selectionConfig } // if not a real event, validate as a selection 6527 ); 6528 if (filterConfig) { 6529 subjectConfigs = mapHash(subjectConfigs, filterConfig); 6530 } 6531 var otherEventStore = excludeInstances( 6532 state.eventStore, 6533 interaction.affectedEvents.instances 6534 ); // exclude the subject events. TODO: exclude defs too? 6535 var otherDefs = otherEventStore.defs; 6536 var otherInstances = otherEventStore.instances; 6537 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 6538 for (var subjectInstanceId in subjectInstances) { 6539 var subjectInstance = subjectInstances[subjectInstanceId]; 6540 var subjectRange = subjectInstance.range; 6541 var subjectConfig = subjectConfigs[subjectInstance.defId]; 6542 var subjectDef = subjectDefs[subjectInstance.defId]; 6543 // constraint 6544 if ( 6545 !allConstraintsPass( 6546 subjectConfig.constraints, 6547 subjectRange, 6548 otherEventStore, 6549 state.businessHours, 6550 context 6551 ) 6552 ) { 6553 return false; 6554 } 6555 // overlap 6556 var eventOverlap = context.options.eventOverlap; 6557 var eventOverlapFunc = 6558 typeof eventOverlap === "function" ? eventOverlap : null; 6559 for (var otherInstanceId in otherInstances) { 6560 var otherInstance = otherInstances[otherInstanceId]; 6561 // intersect! evaluate 6562 if (rangesIntersect(subjectRange, otherInstance.range)) { 6563 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 6564 // consider the other event's overlap. only do this if the subject event is a "real" event 6565 if (otherOverlap === false && interaction.isEvent) { 6566 return false; 6567 } 6568 if (subjectConfig.overlap === false) { 6569 return false; 6570 } 6571 if ( 6572 eventOverlapFunc && 6573 !eventOverlapFunc( 6574 new EventApi( 6575 context, 6576 otherDefs[otherInstance.defId], 6577 otherInstance 6578 ), // still event 6579 new EventApi(context, subjectDef, subjectInstance) // moving event 6580 ) 6581 ) { 6582 return false; 6583 } 6584 } 6585 } 6586 // allow (a function) 6587 var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state 6588 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 6589 var subjectAllow = _a[_i]; 6590 var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { 6591 range: subjectInstance.range, 6592 allDay: subjectDef.allDay, 6593 }); 6594 var origDef = calendarEventStore.defs[subjectDef.defId]; 6595 var origInstance = calendarEventStore.instances[subjectInstanceId]; 6596 var eventApi = void 0; 6597 if (origDef) { 6598 // was previously in the calendar 6599 eventApi = new EventApi(context, origDef, origInstance); 6600 } else { 6601 // was an external event 6602 eventApi = new EventApi(context, subjectDef); // no instance, because had no dates 6603 } 6604 if ( 6605 !subjectAllow( 6606 buildDateSpanApiWithContext(subjectDateSpan, context), 6607 eventApi 6608 ) 6609 ) { 6610 return false;
6611 } 6612 } 6613 } 6614 return true; 6615 } 6616 // Date Selection Validation 6617 // ------------------------------------------------------------------------------------------------------------------------ 6618 function isDateSelectionPropsValid( 6619 state, 6620 context, 6621 dateSpanMeta, 6622 filterConfig 6623 ) { 6624 var relevantEventStore = state.eventStore; 6625 var relevantDefs = relevantEventStore.defs; 6626 var relevantInstances = relevantEventStore.instances; 6627 var selection = state.dateSelection; 6628 var selectionRange = selection.range; 6629 var selectionConfig = context.getCurrentData().selectionConfig; 6630 if (filterConfig) { 6631 selectionConfig = filterConfig(selectionConfig); 6632 } 6633 // constraint 6634 if ( 6635 !allConstraintsPass( 6636 selectionConfig.constraints, 6637 selectionRange, 6638 relevantEventStore, 6639 state.businessHours, 6640 context 6641 ) 6642 ) { 6643 return false; 6644 } 6645 // overlap 6646 var selectOverlap = context.options.selectOverlap; 6647 var selectOverlapFunc = 6648 typeof selectOverlap === "function" ? selectOverlap : null; 6649 for (var relevantInstanceId in relevantInstances) { 6650 var relevantInstance = relevantInstances[relevantInstanceId]; 6651 // intersect! evaluate 6652 if (rangesIntersect(selectionRange, relevantInstance.range)) { 6653 if (selectionConfig.overlap === false) { 6654 return false; 6655 } 6656 if ( 6657 selectOverlapFunc && 6658 !selectOverlapFunc( 6659 new EventApi( 6660 context, 6661 relevantDefs[relevantInstance.defId], 6662 relevantInstance 6663 ), 6664 null 6665 ) 6666 ) { 6667 return false; 6668 } 6669 } 6670 } 6671 // allow (a function) 6672 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 6673 var selectionAllow = _a[_i]; 6674 var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection); 6675 if ( 6676 !selectionAllow( 6677 buildDateSpanApiWithContext(fullDateSpan, context), 6678 null 6679 ) 6680 ) { 6681 return false; 6682 } 6683 } 6684 return true; 6685 } 6686 // Constraint Utils 6687 // ------------------------------------------------------------------------------------------------------------------------ 6688 function allConstraintsPass( 6689 constraints, 6690 subjectRange, 6691 otherEventStore, 6692 businessHoursUnexpanded, 6693 context 6694 ) { 6695 for ( 6696 var _i = 0, constraints_1 = constraints; 6697 _i < constraints_1.length; 6698 _i++ 6699 ) { 6700 var constraint = constraints_1[_i]; 6701 if ( 6702 !anyRangesContainRange( 6703 constraintToRanges( 6704 constraint, 6705 subjectRange, 6706 otherEventStore, 6707 businessHoursUnexpanded, 6708 context 6709 ), 6710 subjectRange 6711 ) 6712 ) { 6713 return false; 6714 } 6715 } 6716 return true; 6717 } 6718 function constraintToRanges( 6719 constraint, 6720 subjectRange, // for expanding a recurring constraint, or expanding business hours 6721 otherEventStore, // for if constraint is an even group ID 6722 businessHoursUnexpanded, // for if constraint is 'businessHours' 6723 context // for expanding businesshours 6724 ) { 6725 if (constraint === "businessHours") { 6726 return eventStoreToRanges( 6727 expandRecurring(businessHoursUnexpanded, subjectRange, context) 6728 ); 6729 } else if (typeof constraint === "string") { 6730 // an group ID 6731 return eventStoreToRanges( 6732 filterEventStoreDefs(otherEventStore, function (eventDef) { 6733 return eventDef.groupId === constraint; 6734 }) 6735 ); 6736 } else if (typeof constraint === "object" && constraint) { 6737 // non-null object 6738 return eventStoreToRanges( 6739 expandRecurring(constraint, subjectRange, context) 6740 ); 6741 } 6742 return []; // if it's false 6743 } 6744 // TODO: move to event-store file? 6745 function eventStoreToRanges(eventStore) { 6746 var instances = eventStore.instances; 6747 var ranges = []; 6748 for (var instanceId in instances) { 6749 ranges.push(instances[instanceId].range); 6750 } 6751 return ranges; 6752 } 6753 // TODO: move to geom file? 6754 function anyRangesContainRange(outerRanges, innerRange) { 6755 for ( 6756 var _i = 0, outerRanges_1 = outerRanges; 6757 _i < outerRanges_1.length; 6758 _i++ 6759 ) { 6760 var outerRange = outerRanges_1[_i]; 6761 if (rangeContainsRange(outerRange, innerRange)) { 6762 return true; 6763 } 6764 } 6765 return false;
6766 } 6767 6768 /* 6769 an INTERACTABLE date component 6770 6771 PURPOSES: 6772 - hook up to fg, fill, and mirror renderers 6773 - interface for dragging and hits 6774 */ 6775 var DateComponent = /** @class */ (function (_super) { 6776 __extends(DateComponent, _super); 6777 function DateComponent() { 6778 var _this = (_super !== null && _super.apply(this, arguments)) || this; 6779 _this.uid = guid(); 6780 return _this; 6781 } 6782 // Hit System 6783 // ----------------------------------------------------------------------------------------------------------------- 6784 DateComponent.prototype.prepareHits = function () {}; 6785 DateComponent.prototype.queryHit = function ( 6786 positionLeft, 6787 positionTop, 6788 elWidth, 6789 elHeight 6790 ) { 6791 return null; // this should be abstract 6792 }; 6793 // Validation 6794 // ----------------------------------------------------------------------------------------------------------------- 6795 DateComponent.prototype.isInteractionValid = function (interaction) { 6796 var dateProfile = this.props.dateProfile; // HACK 6797 var instances = interaction.mutatedEvents.instances; 6798 if (dateProfile) { 6799 // HACK for MorePopover 6800 for (var instanceId in instances) { 6801 if ( 6802 !rangeContainsRange( 6803 dateProfile.validRange, 6804 instances[instanceId].range 6805 ) 6806 ) { 6807 return false; 6808 } 6809 } 6810 } 6811 return isInteractionValid(interaction, this.context); 6812 }; 6813 DateComponent.prototype.isDateSelectionValid = function (selection) { 6814 var dateProfile = this.props.dateProfile; // HACK 6815 if ( 6816 dateProfile && // HACK for MorePopover 6817 !rangeContainsRange(dateProfile.validRange, selection.range) 6818 ) { 6819 return false; 6820 } 6821 return isDateSelectionValid(selection, this.context); 6822 }; 6823 // Pointer Interaction Utils 6824 // ----------------------------------------------------------------------------------------------------------------- 6825 DateComponent.prototype.isValidSegDownEl = function (el) { 6826 return ( 6827 !this.props.eventDrag && // HACK 6828 !this.props.eventResize && // HACK 6829 !elementClosest(el, ".fc-event-mirror") && 6830 (this.isPopover() || !this.isInPopover(el)) 6831 ); 6832 // ^above line ensures we don't detect a seg interaction within a nested component. 6833 // it's a HACK because it only supports a popover as the nested component. 6834 }; 6835 DateComponent.prototype.isValidDateDownEl = function (el) { 6836 return ( 6837 !elementClosest(el, ".fc-event:not(.fc-bg-event)") && 6838 !elementClosest(el, ".fc-daygrid-more-link") && // a "more.." link 6839 !elementClosest(el, "a[data-navlink]") && // a clickable nav link 6840 !this.isInPopover(el) 6841 ); 6842 }; 6843 DateComponent.prototype.isPopover = function () { 6844 return false; 6845 }; 6846 DateComponent.prototype.isInPopover = function (el) { 6847 return Boolean(elementClosest(el, ".fc-popover")); 6848 }; 6849 return DateComponent; 6850 })(BaseComponent); 6851 6852 // TODO: easier way to add new hooks? need to update a million things 6853 function createPlugin(input) { 6854 return { 6855 id: guid(), 6856 deps: input.deps || [], 6857 reducers: input.reducers || [], 6858 contextInit: [].concat(input.contextInit || []), 6859 eventRefiners: input.eventRefiners || {}, 6860 eventDefMemberAdders: input.eventDefMemberAdders || [], 6861 eventSourceRefiners: input.eventSourceRefiners || {}, 6862 isDraggableTransformers: input.isDraggableTransformers || [], 6863 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 6864 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 6865 dateSelectionTransformers: input.dateSelectionTransformers || [], 6866 datePointTransforms: input.datePointTransforms || [], 6867 dateSpanTransforms: input.dateSpanTransforms || [], 6868 views: input.views || {}, 6869 viewPropsTransformers: input.viewPropsTransformers || [], 6870 isPropsValid: input.isPropsValid || null, 6871 externalDefTransforms: input.externalDefTransforms || [], 6872 eventResizeJoinTransforms: input.eventResizeJoinTransforms || [], 6873 viewContainerAppends: input.viewContainerAppends || [], 6874 eventDropTransformers: input.eventDropTransformers || [], 6875 componentInteractions: input.componentInteractions || [], 6876 calendarInteractions: input.calendarInteractions || [],
6877 themeClasses: input.themeClasses || {}, 6878 eventSourceDefs: input.eventSourceDefs || [], 6879 cmdFormatter: input.cmdFormatter, 6880 recurringTypes: input.recurringTypes || [], 6881 namedTimeZonedImpl: input.namedTimeZonedImpl, 6882 initialView: input.initialView || "", 6883 elementDraggingImpl: input.elementDraggingImpl, 6884 optionChangeHandlers: input.optionChangeHandlers || {}, 6885 scrollGridImpl: input.scrollGridImpl || null, 6886 contentTypeHandlers: input.contentTypeHandlers || {}, 6887 listenerRefiners: input.listenerRefiners || {}, 6888 optionRefiners: input.optionRefiners || {}, 6889 propSetHandlers: input.propSetHandlers || {}, 6890 }; 6891 } 6892 function buildPluginHooks(pluginDefs, globalDefs) { 6893 var isAdded = {}; 6894 var hooks = { 6895 reducers: [], 6896 contextInit: [], 6897 eventRefiners: {}, 6898 eventDefMemberAdders: [], 6899 eventSourceRefiners: {}, 6900 isDraggableTransformers: [], 6901 eventDragMutationMassagers: [], 6902 eventDefMutationAppliers: [], 6903 dateSelectionTransformers: [], 6904 datePointTransforms: [], 6905 dateSpanTransforms: [], 6906 views: {}, 6907 viewPropsTransformers: [], 6908 isPropsValid: null, 6909 externalDefTransforms: [], 6910 eventResizeJoinTransforms: [], 6911 viewContainerAppends: [], 6912 eventDropTransformers: [], 6913 componentInteractions: [], 6914 calendarInteractions: [], 6915 themeClasses: {}, 6916 eventSourceDefs: [], 6917 cmdFormatter: null, 6918 recurringTypes: [], 6919 namedTimeZonedImpl: null, 6920 initialView: "", 6921 elementDraggingImpl: null, 6922 optionChangeHandlers: {}, 6923 scrollGridImpl: null, 6924 contentTypeHandlers: {}, 6925 listenerRefiners: {}, 6926 optionRefiners: {}, 6927 propSetHandlers: {}, 6928 }; 6929 function addDefs(defs) { 6930 for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) { 6931 var def = defs_1[_i]; 6932 if (!isAdded[def.id]) { 6933 isAdded[def.id] = true; 6934 addDefs(def.deps); 6935 hooks = combineHooks(hooks, def); 6936 } 6937 } 6938 } 6939 if (pluginDefs) { 6940 addDefs(pluginDefs); 6941 } 6942 addDefs(globalDefs); 6943 return hooks; 6944 } 6945 function buildBuildPluginHooks() { 6946 var currentOverrideDefs = []; 6947 var currentGlobalDefs = []; 6948 var currentHooks; 6949 return function (overrideDefs, globalDefs) { 6950 if ( 6951 !currentHooks || 6952 !isArraysEqual(overrideDefs, currentOverrideDefs) || 6953 !isArraysEqual(globalDefs, currentGlobalDefs) 6954 ) { 6955 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 6956 } 6957 currentOverrideDefs = overrideDefs; 6958 currentGlobalDefs = globalDefs; 6959 return currentHooks; 6960 }; 6961 } 6962 function combineHooks(hooks0, hooks1) { 6963 return { 6964 reducers: hooks0.reducers.concat(hooks1.reducers), 6965 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 6966 eventRefiners: __assign( 6967 __assign({}, hooks0.eventRefiners), 6968 hooks1.eventRefiners 6969 ), 6970 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat( 6971 hooks1.eventDefMemberAdders 6972 ), 6973 eventSourceRefiners: __assign( 6974 __assign({}, hooks0.eventSourceRefiners), 6975 hooks1.eventSourceRefiners 6976 ), 6977 isDraggableTransformers: hooks0.isDraggableTransformers.concat( 6978 hooks1.isDraggableTransformers 6979 ), 6980 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat( 6981 hooks1.eventDragMutationMassagers 6982 ), 6983 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat( 6984 hooks1.eventDefMutationAppliers 6985 ), 6986 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat( 6987 hooks1.dateSelectionTransformers 6988 ), 6989 datePointTransforms: hooks0.datePointTransforms.concat( 6990 hooks1.datePointTransforms 6991 ), 6992 dateSpanTransforms: hooks0.dateSpanTransforms.concat( 6993 hooks1.dateSpanTransforms 6994 ), 6995 views: __assign(__assign({}, hooks0.views), hooks1.views), 6996 viewPropsTransformers: hooks0.viewPropsTransformers.concat( 6997 hooks1.viewPropsTransformers 6998 ), 6999 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 7000 externalDefTransforms: hooks0.externalDefTransforms.concat( 7001 hooks1.externalDefTransforms 7002 ), 7003 eventResizeJoinTransforms: hooks0.eventResizeJoinTransforms.concat( 7004 hooks1.eventResizeJoinTransforms 7005 ), 7006 viewContainerAppends: hooks0.viewContainerAppends.concat( 7007 hooks1.viewContainerAppends 7008 ), 7009 eventDropTransformers: hooks0.eventDropTransformers.concat( 7010 hooks1.eventDropTransformers 7011 ), 7012 calendarInteractions: hooks0.calendarInteractions.concat( 7013 hooks1.calendarInteractions 7014 ), 7015 componentInteractions: hooks0.componentInteractions.concat( 7016 hooks1.componentInteractions 7017 ),
7018 themeClasses: __assign( 7019 __assign({}, hooks0.themeClasses), 7020 hooks1.themeClasses 7021 ), 7022 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 7023 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 7024 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 7025 namedTimeZonedImpl: 7026 hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 7027 initialView: hooks0.initialView || hooks1.initialView, 7028 elementDraggingImpl: 7029 hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 7030 optionChangeHandlers: __assign( 7031 __assign({}, hooks0.optionChangeHandlers), 7032 hooks1.optionChangeHandlers 7033 ), 7034 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 7035 contentTypeHandlers: __assign( 7036 __assign({}, hooks0.contentTypeHandlers), 7037 hooks1.contentTypeHandlers 7038 ), 7039 listenerRefiners: __assign( 7040 __assign({}, hooks0.listenerRefiners), 7041 hooks1.listenerRefiners 7042 ), 7043 optionRefiners: __assign( 7044 __assign({}, hooks0.optionRefiners), 7045 hooks1.optionRefiners 7046 ), 7047 propSetHandlers: __assign( 7048 __assign({}, hooks0.propSetHandlers), 7049 hooks1.propSetHandlers 7050 ), 7051 }; 7052 } 7053 7054 var StandardTheme = /** @class */ (function (_super) { 7055 __extends(StandardTheme, _super); 7056 function StandardTheme() { 7057 return (_super !== null && _super.apply(this, arguments)) || this; 7058 } 7059 return StandardTheme; 7060 })(Theme); 7061 StandardTheme.prototype.classes = { 7062 root: "fc-theme-standard", 7063 tableCellShaded: "fc-cell-shaded", 7064 buttonGroup: "fc-button-group", 7065 button: "fc-button fc-button-primary", 7066 buttonActive: "fc-button-active", 7067 }; 7068 StandardTheme.prototype.baseIconClass = "fc-icon"; 7069 StandardTheme.prototype.iconClasses = { 7070 close: "fc-icon-x", 7071 prev: "fc-icon-chevron-left", 7072 next: "fc-icon-chevron-right", 7073 prevYear: "fc-icon-chevrons-left", 7074 nextYear: "fc-icon-chevrons-right", 7075 }; 7076 StandardTheme.prototype.rtlIconClasses = { 7077 prev: "fc-icon-chevron-right", 7078 next: "fc-icon-chevron-left", 7079 prevYear: "fc-icon-chevrons-right", 7080 nextYear: "fc-icon-chevrons-left", 7081 }; 7082 StandardTheme.prototype.iconOverrideOption = "buttonIcons"; // TODO: make TS-friendly 7083 StandardTheme.prototype.iconOverrideCustomButtonOption = "icon"; 7084 StandardTheme.prototype.iconOverridePrefix = "fc-icon-"; 7085 7086 function compileViewDefs(defaultConfigs, overrideConfigs) { 7087 var hash = {}; 7088 var viewType; 7089 for (viewType in defaultConfigs) { 7090 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7091 } 7092 for (viewType in overrideConfigs) { 7093 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7094 } 7095 return hash; 7096 } 7097 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 7098 if (hash[viewType]) { 7099 return hash[viewType]; 7100 } 7101 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7102 if (viewDef) { 7103 hash[viewType] = viewDef; 7104 } 7105 return viewDef; 7106 } 7107 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 7108 var defaultConfig = defaultConfigs[viewType]; 7109 var overrideConfig = overrideConfigs[viewType]; 7110 var queryProp = function (name) { 7111 return defaultConfig && defaultConfig[name] !== null 7112 ? defaultConfig[name] 7113 : overrideConfig && overrideConfig[name] !== null 7114 ? overrideConfig[name] 7115 : null; 7116 }; 7117 var theComponent = queryProp("component"); 7118 var superType = queryProp("superType"); 7119 var superDef = null; 7120 if (superType) { 7121 if (superType === viewType) { 7122 throw new Error("Can't have a custom view type that references itself"); 7123 } 7124 superDef = ensureViewDef( 7125 superType, 7126 hash, 7127 defaultConfigs, 7128 overrideConfigs 7129 ); 7130 } 7131 if (!theComponent && superDef) { 7132 theComponent = superDef.component; 7133 } 7134 if (!theComponent) { 7135 return null; // don't throw a warning, might be settings for a single-unit view 7136 } 7137 return { 7138 type: viewType, 7139 component: theComponent, 7140 defaults: __assign( 7141 __assign({}, superDef ? superDef.defaults : {}), 7142 defaultConfig ? defaultConfig.rawOptions : {} 7143 ), 7144 overrides: __assign( 7145 __assign({}, superDef ? superDef.overrides : {}), 7146 overrideConfig ? overrideConfig.rawOptions : {} 7147 ), 7148 }; 7149 } 7150 7151 // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any??? 7152 var RenderHook = /** @class */ (function (_super) { 7153 __extends(RenderHook, _super);
7154 function RenderHook() { 7155 var _this = (_super !== null && _super.apply(this, arguments)) || this; 7156 _this.rootElRef = createRef(); 7157 _this.handleRootEl = function (el) { 7158 setRef(_this.rootElRef, el); 7159 if (_this.props.elRef) { 7160 setRef(_this.props.elRef, el); 7161 } 7162 }; 7163 return _this; 7164 } 7165 RenderHook.prototype.render = function () { 7166 var _this = this; 7167 var props = this.props; 7168 var hookProps = props.hookProps; 7169 return createElement( 7170 MountHook, 7171 { 7172 hookProps: hookProps, 7173 didMount: props.didMount, 7174 willUnmount: props.willUnmount, 7175 elRef: this.handleRootEl, 7176 }, 7177 function (rootElRef) { 7178 return createElement( 7179 ContentHook, 7180 { 7181 hookProps: hookProps, 7182 content: props.content, 7183 defaultContent: props.defaultContent, 7184 backupElRef: _this.rootElRef, 7185 }, 7186 function (innerElRef, innerContent) { 7187 return props.children( 7188 rootElRef, 7189 normalizeClassNames(props.classNames, hookProps), 7190 innerElRef, 7191 innerContent 7192 ); 7193 } 7194 ); 7195 } 7196 ); 7197 }; 7198 return RenderHook; 7199 })(BaseComponent); 7200 // for forcing rerender of components that use the ContentHook 7201 var CustomContentRenderContext = createContext$1(0); 7202 function ContentHook(props) { 7203 return createElement( 7204 CustomContentRenderContext.Consumer, 7205 null, 7206 function (renderId) { 7207 return createElement( 7208 ContentHookInner, 7209 __assign({ renderId: renderId }, props) 7210 ); 7211 } 7212 ); 7213 } 7214 var ContentHookInner = /** @class */ (function (_super) { 7215 __extends(ContentHookInner, _super); 7216 function ContentHookInner() { 7217 var _this = (_super !== null && _super.apply(this, arguments)) || this; 7218 _this.innerElRef = createRef(); 7219 return _this; 7220 } 7221 ContentHookInner.prototype.render = function () { 7222 return this.props.children(this.innerElRef, this.renderInnerContent()); 7223 }; 7224 ContentHookInner.prototype.componentDidMount = function () { 7225 this.updateCustomContent(); 7226 }; 7227 ContentHookInner.prototype.componentDidUpdate = function () { 7228 this.updateCustomContent(); 7229 }; 7230 ContentHookInner.prototype.renderInnerContent = function () { 7231 var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers; 7232 var _a = this, 7233 props = _a.props, 7234 customContentInfo = _a.customContentInfo; 7235 var rawVal = props.content; 7236 var innerContent = normalizeContent(rawVal, props.hookProps); 7237 var innerContentVDom = null; 7238 if (innerContent === undefined) { 7239 // use the default 7240 innerContent = normalizeContent(props.defaultContent, props.hookProps); 7241 } 7242 if (innerContent !== undefined) { 7243 // we allow custom content handlers to return nothing 7244 if (customContentInfo) { 7245 customContentInfo.contentVal = 7246 innerContent[customContentInfo.contentKey]; 7247 } else if (typeof innerContent === "object") { 7248 // look for a prop that would indicate a custom content handler is needed 7249 for (var contentKey in contentTypeHandlers) { 7250 if (innerContent[contentKey] !== undefined) { 7251 customContentInfo = this.customContentInfo = { 7252 contentKey: contentKey, 7253 contentVal: innerContent[contentKey], 7254 handler: contentTypeHandlers[contentKey](), 7255 }; 7256 break; 7257 } 7258 } 7259 } 7260 if (customContentInfo) { 7261 innerContentVDom = []; // signal that something was specified 7262 } else { 7263 innerContentVDom = innerContent; // assume a [p]react vdom node. use it 7264 } 7265 } 7266 return innerContentVDom; 7267 }; 7268 ContentHookInner.prototype.updateCustomContent = function () { 7269 if (this.customContentInfo) { 7270 this.customContentInfo.handler( 7271 this.innerElRef.current || this.props.backupElRef.current, // the element to render into 7272 this.customContentInfo.contentVal 7273 ); 7274 } 7275 }; 7276 return ContentHookInner; 7277 })(BaseComponent); 7278 var MountHook = /** @class */ (function (_super) { 7279 __extends(MountHook, _super); 7280 function MountHook() { 7281 var _this = (_super !== null && _super.apply(this, arguments)) || this; 7282 _this.handleRootEl = function (rootEl) { 7283 _this.rootEl = rootEl; 7284 if (_this.props.elRef) { 7285 setRef(_this.props.elRef, rootEl); 7286 } 7287 }; 7288 return _this; 7289 } 7290 MountHook.prototype.render = function () { 7291 return this.props.children(this.handleRootEl); 7292 }; 7293 MountHook.prototype.componentDidMount = function () { 7294 var callback = this.props.didMount; 7295 callback && 7296 callback( 7297 __assign(__assign({}, this.props.hookProps), { el: this.rootEl }) 7298 ); 7299 }; 7300 MountHook.prototype.componentWillUnmount = function () { 7301 var callback = this.props.willUnmount; 7302 callback && 7303 callback( 7304 __assign(__assign({}, this.props.hookProps), { el: this.rootEl }) 7305 ); 7306 }; 7307 return MountHook; 7308 })(BaseComponent); 7309 function buildClassNameNormalizer() { 7310 var currentGenerator; 7311 var currentHookProps; 7312 var currentClassNames = []; 7313 return function (generator, hookProps) { 7314 if ( 7315 !currentHookProps || 7316 !isPropsEqual(currentHookProps, hookProps) || 7317 generator !== currentGenerator 7318 ) { 7319 currentGenerator = generator; 7320 currentHookProps = hookProps; 7321 currentClassNames = normalizeClassNames(generator, hookProps); 7322 } 7323 return currentClassNames; 7324 }; 7325 } 7326 function normalizeClassNames(classNames, hookProps) { 7327 if (typeof classNames === "function") { 7328 classNames = classNames(hookProps); 7329 } 7330 return parseClassNames(classNames); 7331 } 7332 function normalizeContent(input, hookProps) { 7333 if (typeof input === "function") { 7334 return input(hookProps, createElement); // give the function the vdom-creation func 7335 } else { 7336 return input; 7337 } 7338 } 7339 7340 var ViewRoot = /** @class */ (function (_super) { 7341 __extends(ViewRoot, _super); 7342 function ViewRoot() { 7343 var _this = (_super !== null && _super.apply(this, arguments)) || this; 7344 _this.normalizeClassNames = buildClassNameNormalizer(); 7345 return _this; 7346 } 7347 ViewRoot.prototype.render = function () { 7348 var _a = this, 7349 props = _a.props, 7350 context = _a.context; 7351 var options = context.options; 7352 var hookProps = { view: context.viewApi }; 7353 var customClassNames = this.normalizeClassNames( 7354 options.viewClassNames, 7355 hookProps 7356 ); 7357 return createElement( 7358 MountHook, 7359 { 7360 hookProps: hookProps, 7361 didMount: options.viewDidMount, 7362 willUnmount: options.viewWillUnmount, 7363 elRef: props.elRef, 7364 }, 7365 function (rootElRef) { 7366 return props.children( 7367 rootElRef, 7368 ["fc-" + props.viewSpec.type + "-view", "fc-view"].concat( 7369 customClassNames 7370 ) 7371 ); 7372 } 7373 ); 7374 }; 7375 return ViewRoot; 7376 })(BaseComponent); 7377 7378 function parseViewConfigs(inputs) { 7379 return mapHash(inputs, parseViewConfig); 7380 } 7381 function parseViewConfig(input) { 7382 var rawOptions = typeof input === "function" ? { component: input } : input; 7383 var component = rawOptions.component; 7384 if (rawOptions.content) { 7385 component = createViewHookComponent(rawOptions); 7386 // TODO: remove content/classNames/didMount/etc from options? 7387 } 7388 return { 7389 superType: rawOptions.type, 7390 component: component, 7391 rawOptions: rawOptions, // includes type and component too :( 7392 }; 7393 } 7394 function createViewHookComponent(options) { 7395 return function (viewProps) { 7396 return createElement(ViewContextType.Consumer, null, function (context) { 7397 return createElement( 7398 ViewRoot, 7399 { viewSpec: context.viewSpec }, 7400 function (rootElRef, viewClassNames) { 7401 var hookProps = __assign(__assign({}, viewProps), { 7402 nextDayThreshold: context.options.nextDayThreshold, 7403 }); 7404 return createElement( 7405 RenderHook, 7406 { 7407 hookProps: hookProps, 7408 classNames: options.classNames, 7409 content: options.content, 7410 didMount: options.didMount, 7411 willUnmount: options.willUnmount, 7412 elRef: rootElRef, 7413 }, 7414 function (rootElRef, customClassNames, innerElRef, innerContent) { 7415 return createElement( 7416 "div", 7417 { 7418 className: viewClassNames 7419 .concat(customClassNames) 7420 .join(" "), 7421 ref: rootElRef, 7422 }, 7423 innerContent 7424 ); 7425 } 7426 ); 7427 } 7428 ); 7429 }); 7430 }; 7431 } 7432 7433 function buildViewSpecs( 7434 defaultInputs, 7435 optionOverrides, 7436 dynamicOptionOverrides, 7437 localeDefaults 7438 ) { 7439 var defaultConfigs = parseViewConfigs(defaultInputs); 7440 var overrideConfigs = parseViewConfigs(optionOverrides.views); 7441 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 7442 return mapHash(viewDefs, function (viewDef) { 7443 return buildViewSpec( 7444 viewDef, 7445 overrideConfigs, 7446 optionOverrides, 7447 dynamicOptionOverrides, 7448 localeDefaults 7449 ); 7450 }); 7451 } 7452 function buildViewSpec( 7453 viewDef, 7454 overrideConfigs, 7455 optionOverrides, 7456 dynamicOptionOverrides, 7457 localeDefaults 7458 ) { 7459 var durationInput = 7460 viewDef.overrides.duration || 7461 viewDef.defaults.duration || 7462 dynamicOptionOverrides.duration || 7463 optionOverrides.duration; 7464 var duration = null; 7465 var durationUnit = ""; 7466 var singleUnit = ""; 7467 var singleUnitOverrides = {}; 7468 if (durationInput) { 7469 duration = createDurationCached(durationInput); 7470 if (duration) { 7471 // valid? 7472 var denom = greatestDurationDenominator(duration); 7473 durationUnit = denom.unit; 7474 if (denom.value === 1) { 7475 singleUnit = durationUnit; 7476 singleUnitOverrides = overrideConfigs[durationUnit] 7477 ? overrideConfigs[durationUnit].rawOptions 7478 : {}; 7479 } 7480 } 7481 } 7482 var queryButtonText = function (optionsSubset) { 7483 var buttonTextMap = optionsSubset.buttonText || {}; 7484 var buttonTextKey = viewDef.defaults.buttonTextKey; 7485 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 7486 return buttonTextMap[buttonTextKey]; 7487 } 7488 if (buttonTextMap[viewDef.type] != null) { 7489 return buttonTextMap[viewDef.type]; 7490 } 7491 if (buttonTextMap[singleUnit] != null) { 7492 return buttonTextMap[singleUnit]; 7493 } 7494 }; 7495 return { 7496 type: viewDef.type, 7497 component: viewDef.component, 7498 duration: duration, 7499 durationUnit: durationUnit, 7500 singleUnit: singleUnit, 7501 optionDefaults: viewDef.defaults, 7502 optionOverrides: __assign( 7503 __assign({}, singleUnitOverrides), 7504 viewDef.overrides 7505 ), 7506 buttonTextOverride: 7507 queryButtonText(dynamicOptionOverrides) || 7508 queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 7509 viewDef.overrides.buttonText, 7510 buttonTextDefault: 7511 queryButtonText(localeDefaults) || 7512 viewDef.defaults.buttonText || 7513 queryButtonText(BASE_OPTION_DEFAULTS) || 7514 viewDef.type, // fall back to given view name 7515 }; 7516 } 7517 // hack to get memoization working 7518 var durationInputMap = {}; 7519 function createDurationCached(durationInput) { 7520 var json = JSON.stringify(durationInput); 7521 var res = durationInputMap[json]; 7522 if (res === undefined) { 7523 res = createDuration(durationInput); 7524 durationInputMap[json] = res; 7525 } 7526 return res; 7527 } 7528 7529 var DateProfileGenerator = /** @class */ (function () { 7530 function DateProfileGenerator(props) { 7531 this.props = props; 7532 this.nowDate = getNow(props.nowInput, props.dateEnv); 7533 this.initHiddenDays(); 7534 } 7535 /* Date Range Computation 7536 ------------------------------------------------------------------------------------------------------------------*/ 7537 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 7538 DateProfileGenerator.prototype.buildPrev = function ( 7539 currentDateProfile, 7540 currentDate, 7541 forceToValid 7542 ) { 7543 var dateEnv = this.props.dateEnv; 7544 var prevDate = dateEnv.subtract( 7545 dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 7546 currentDateProfile.dateIncrement 7547 ); 7548 return this.build(prevDate, -1, forceToValid); 7549 }; 7550 // Builds a structure with info about what the dates/ranges will be for the "next" view. 7551 DateProfileGenerator.prototype.buildNext = function ( 7552 currentDateProfile, 7553 currentDate, 7554 forceToValid 7555 ) { 7556 var dateEnv = this.props.dateEnv; 7557 var nextDate = dateEnv.add( 7558 dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 7559 currentDateProfile.dateIncrement 7560 ); 7561 return this.build(nextDate, 1, forceToValid); 7562 }; 7563 // Builds a structure holding dates/ranges for rendering around the given date. 7564 // Optional direction param indicates whether the date is being incremented/decremented 7565 // from its previous value. decremented = -1, incremented = 1 (default). 7566 DateProfileGenerator.prototype.build = function ( 7567 currentDate, 7568 direction, 7569 forceToValid 7570 ) { 7571 if (forceToValid === void 0) { 7572 forceToValid = true; 7573 } 7574 var props = this.props;
7575 var validRange; 7576 var currentInfo; 7577 var isRangeAllDay; 7578 var renderRange; 7579 var activeRange; 7580 var isValid; 7581 validRange = this.buildValidRange(); 7582 validRange = this.trimHiddenDays(validRange); 7583 if (forceToValid) { 7584 currentDate = constrainMarkerToRange(currentDate, validRange); 7585 } 7586 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 7587 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 7588 renderRange = this.buildRenderRange( 7589 this.trimHiddenDays(currentInfo.range), 7590 currentInfo.unit, 7591 isRangeAllDay 7592 ); 7593 renderRange = this.trimHiddenDays(renderRange); 7594 activeRange = renderRange; 7595 if (!props.showNonCurrentDates) { 7596 activeRange = intersectRanges(activeRange, currentInfo.range); 7597 } 7598 activeRange = this.adjustActiveRange(activeRange); 7599 activeRange = intersectRanges(activeRange, validRange); // might return null 7600 // it's invalid if the originally requested date is not contained, 7601 // or if the range is completely outside of the valid range. 7602 isValid = rangesIntersect(currentInfo.range, validRange); 7603 return { 7604 // constraint for where prev/next operations can go and where events can be dragged/resized to. 7605 // an object with optional start and end properties. 7606 validRange: validRange, 7607 // range the view is formally responsible for. 7608 // for example, a month view might have 1st-31st, excluding padded dates 7609 currentRange: currentInfo.range, 7610 // name of largest unit being displayed, like "month" or "week" 7611 currentRangeUnit: currentInfo.unit, 7612 isRangeAllDay: isRangeAllDay, 7613 // dates that display events and accept drag-n-drop 7614 // will be `null` if no dates accept events 7615 activeRange: activeRange, 7616 // date range with a rendered skeleton 7617 // includes not-active days that need some sort of DOM 7618 renderRange: renderRange, 7619 // Duration object that denotes the first visible time of any given day 7620 slotMinTime: props.slotMinTime, 7621 // Duration object that denotes the exclusive visible end time of any given day 7622 slotMaxTime: props.slotMaxTime, 7623 isValid: isValid, 7624 // how far the current date will move for a prev/next operation 7625 dateIncrement: this.buildDateIncrement(currentInfo.duration), 7626 // pass a fallback (might be null) ^ 7627 }; 7628 }; 7629 // Builds an object with optional start/end properties. 7630 // Indicates the minimum/maximum dates to display. 7631 // not responsible for trimming hidden days. 7632 DateProfileGenerator.prototype.buildValidRange = function () { 7633 var input = this.props.validRangeInput; 7634 var simpleInput = 7635 typeof input === "function" 7636 ? input.call(this.props.calendarApi, this.nowDate) 7637 : input; 7638 return this.refineRange(simpleInput) || { start: null, end: null }; // completely open-ended 7639 }; 7640 // Builds a structure with info about the "current" range, the range that is 7641 // highlighted as being the current month for example. 7642 // See build() for a description of `direction`. 7643 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 7644 DateProfileGenerator.prototype.buildCurrentRangeInfo = function ( 7645 date, 7646 direction 7647 ) { 7648 var props = this.props; 7649 var duration = null; 7650 var unit = null; 7651 var range = null; 7652 var dayCount; 7653 if (props.duration) { 7654 duration = props.duration; 7655 unit = props.durationUnit; 7656 range = this.buildRangeFromDuration(date, direction, duration, unit); 7657 } else if ((dayCount = this.props.dayCount)) { 7658 unit = "day"; 7659 range = this.buildRangeFromDayCount(date, direction, dayCount); 7660 } else if ((range = this.buildCustomVisibleRange(date))) { 7661 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 7662 } else { 7663 duration = this.getFallbackDuration(); 7664 unit = greatestDurationDenominator(duration).unit; 7665 range = this.buildRangeFromDuration(date, direction, duration, unit); 7666 } 7667 return { duration: duration, unit: unit, range: range }; 7668 }; 7669 DateProfileGenerator.prototype.getFallbackDuration = function () { 7670 return createDuration({ day: 1 }); 7671 }; 7672 // Returns a new activeRange to have time values (un-ambiguate) 7673 // slotMinTime or slotMaxTime causes the range to expand. 7674 DateProfileGenerator.prototype.adjustActiveRange = function (range) { 7675 var _a = this.props, 7676 dateEnv = _a.dateEnv, 7677 usesMinMaxTime = _a.usesMinMaxTime, 7678 slotMinTime = _a.slotMinTime, 7679 slotMaxTime = _a.slotMaxTime; 7680 var start = range.start; 7681 var end = range.end; 7682 if (usesMinMaxTime) { 7683 // expand active range if slotMinTime is negative (why not when positive?) 7684 if (asRoughDays(slotMinTime) < 0) { 7685 start = startOfDay(start); // necessary? 7686 start = dateEnv.add(start, slotMinTime); 7687 } 7688 // expand active range if slotMaxTime is beyond one day (why not when negative?) 7689 if (asRoughDays(slotMaxTime) > 1) { 7690 end = startOfDay(end); // necessary? 7691 end = addDays(end, -1); 7692 end = dateEnv.add(end, slotMaxTime); 7693 } 7694 } 7695 return { start: start, end: end }; 7696 }; 7697 // Builds the "current" range when it is specified as an explicit duration. 7698 // `unit` is the already-computed greatestDurationDenominator unit of duration. 7699 DateProfileGenerator.prototype.buildRangeFromDuration = function ( 7700 date, 7701 direction, 7702 duration, 7703 unit 7704 ) { 7705 var _a = this.props, 7706 dateEnv = _a.dateEnv, 7707 dateAlignment = _a.dateAlignment; 7708 var start; 7709 var end; 7710 var res; 7711 // compute what the alignment should be 7712 if (!dateAlignment) { 7713 var dateIncrement = this.props.dateIncrement; 7714 if (dateIncrement) { 7715 // use the smaller of the two units 7716 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 7717 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 7718 } else { 7719 dateAlignment = unit; 7720 } 7721 } else { 7722 dateAlignment = unit; 7723 } 7724 }
7725 // if the view displays a single day or smaller 7726 if (asRoughDays(duration) <= 1) { 7727 if (this.isHiddenDay(start)) { 7728 start = this.skipHiddenDays(start, direction); 7729 start = startOfDay(start); 7730 } 7731 } 7732 function computeRes() { 7733 start = dateEnv.startOf(date, dateAlignment); 7734 end = dateEnv.add(start, duration); 7735 res = { start: start, end: end }; 7736 } 7737 computeRes(); 7738 // if range is completely enveloped by hidden days, go past the hidden days 7739 if (!this.trimHiddenDays(res)) { 7740 date = this.skipHiddenDays(date, direction); 7741 computeRes(); 7742 } 7743 return res; 7744 }; 7745 // Builds the "current" range when a dayCount is specified. 7746 DateProfileGenerator.prototype.buildRangeFromDayCount = function ( 7747 date, 7748 direction, 7749 dayCount 7750 ) { 7751 var _a = this.props, 7752 dateEnv = _a.dateEnv, 7753 dateAlignment = _a.dateAlignment; 7754 var runningCount = 0; 7755 var start = date; 7756 var end; 7757 if (dateAlignment) { 7758 start = dateEnv.startOf(start, dateAlignment); 7759 } 7760 start = startOfDay(start); 7761 start = this.skipHiddenDays(start, direction); 7762 end = start; 7763 do { 7764 end = addDays(end, 1); 7765 if (!this.isHiddenDay(end)) { 7766 runningCount++; 7767 } 7768 } while (runningCount < dayCount); 7769 return { start: start, end: end }; 7770 }; 7771 // Builds a normalized range object for the "visible" range, 7772 // which is a way to define the currentRange and activeRange at the same time. 7773 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 7774 var props = this.props; 7775 var input = props.visibleRangeInput; 7776 var simpleInput = 7777 typeof input === "function" 7778 ? input.call(props.calendarApi, props.dateEnv.toDate(date)) 7779 : input; 7780 var range = this.refineRange(simpleInput); 7781 if (range && (range.start == null || range.end == null)) { 7782 return null; 7783 } 7784 return range; 7785 }; 7786 // Computes the range that will represent the element/cells for *rendering*, 7787 // but which may have voided days/times. 7788 // not responsible for trimming hidden days. 7789 DateProfileGenerator.prototype.buildRenderRange = function ( 7790 currentRange, 7791 currentRangeUnit, 7792 isRangeAllDay 7793 ) { 7794 return currentRange; 7795 }; 7796 // Compute the duration value that should be added/substracted to the current date 7797 // when a prev/next operation happens. 7798 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 7799 var dateIncrement = this.props.dateIncrement; 7800 var customAlignment; 7801 if (dateIncrement) { 7802 return dateIncrement; 7803 } else if ((customAlignment = this.props.dateAlignment)) { 7804 return createDuration(1, customAlignment); 7805 } else if (fallback) { 7806 return fallback; 7807 } else { 7808 return createDuration({ days: 1 }); 7809 } 7810 }; 7811 DateProfileGenerator.prototype.refineRange = function (rangeInput) { 7812 if (rangeInput) { 7813 var range = parseRange(rangeInput, this.props.dateEnv); 7814 if (range) { 7815 range = computeVisibleDayRange(range); 7816 } 7817 return range; 7818 } 7819 return null; 7820 }; 7821 /* Hidden Days 7822 ------------------------------------------------------------------------------------------------------------------*/ 7823 // Initializes internal variables related to calculating hidden days-of-week 7824 DateProfileGenerator.prototype.initHiddenDays = function () { 7825 var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden 7826 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 7827 var dayCnt = 1; 7828 var i; 7829 if (this.props.weekends === false) { 7830 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 7831 } 7832 for (i = 0; i < 6; i++) { 7833 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 7834 dayCnt++; 7835 } 7836 } 7837 if (!dayCnt) { 7838 throw new Error("invalid hiddenDays"); // all days were hidden? bad. 7839 }
7840 this.isHiddenDayHash = isHiddenDayHash; 7841 }; 7842 // Remove days from the beginning and end of the range that are computed as hidden. 7843 // If the whole range is trimmed off, returns null 7844 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 7845 var start = range.start; 7846 var end = range.end; 7847 if (start) { 7848 start = this.skipHiddenDays(start); 7849 } 7850 if (end) { 7851 end = this.skipHiddenDays(end, -1, true); 7852 } 7853 if (start == null || end == null || start < end) { 7854 return { start: start, end: end }; 7855 } 7856 return null; 7857 }; 7858 // Is the current day hidden? 7859 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 7860 DateProfileGenerator.prototype.isHiddenDay = function (day) { 7861 if (day instanceof Date) { 7862 day = day.getUTCDay(); 7863 } 7864 return this.isHiddenDayHash[day]; 7865 }; 7866 // Incrementing the current day until it is no longer a hidden day, returning a copy. 7867 // DOES NOT CONSIDER validRange! 7868 // If the initial value of `date` is not a hidden day, don't do anything. 7869 // Pass `isExclusive` as `true` if you are dealing with an end date. 7870 // `inc` defaults to `1` (increment one day forward each time) 7871 DateProfileGenerator.prototype.skipHiddenDays = function ( 7872 date, 7873 inc, 7874 isExclusive 7875 ) { 7876 if (inc === void 0) { 7877 inc = 1; 7878 } 7879 if (isExclusive === void 0) { 7880 isExclusive = false; 7881 } 7882 while ( 7883 this.isHiddenDayHash[ 7884 (date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7 7885 ] 7886 ) { 7887 date = addDays(date, inc); 7888 } 7889 return date; 7890 }; 7891 return DateProfileGenerator; 7892 })(); 7893 7894 function reduceViewType(viewType, action) { 7895 switch (action.type) { 7896 case "CHANGE_VIEW_TYPE": 7897 return (viewType = action.viewType); 7898 } 7899 return viewType; 7900 } 7901 7902 function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 7903 var _a; 7904 switch (action.type) { 7905 case "SET_OPTION": 7906 return __assign( 7907 __assign({}, dynamicOptionOverrides), 7908 ((_a = {}), (_a[action.optionName] = action.rawOptionValue), _a) 7909 ); 7910 default: 7911 return dynamicOptionOverrides; 7912 } 7913 } 7914 7915 function reduceDateProfile( 7916 currentDateProfile, 7917 action, 7918 currentDate, 7919 dateProfileGenerator 7920 ) { 7921 var dp; 7922 switch (action.type) { 7923 case "CHANGE_VIEW_TYPE": 7924 return dateProfileGenerator.build(action.dateMarker || currentDate); 7925 case "CHANGE_DATE": 7926 if ( 7927 !currentDateProfile.activeRange || 7928 !rangeContainsMarker( 7929 currentDateProfile.currentRange, 7930 action.dateMarker 7931 ) // don't move if date already in view 7932 ) { 7933 return dateProfileGenerator.build(action.dateMarker); 7934 } 7935 break; 7936 case "PREV": 7937 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 7938 if (dp.isValid) { 7939 return dp; 7940 } 7941 break; 7942 case "NEXT": 7943 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 7944 if (dp.isValid) { 7945 return dp; 7946 } 7947 break; 7948 } 7949 return currentDateProfile; 7950 } 7951 7952 function initEventSources(calendarOptions, dateProfile, context) { 7953 var activeRange = dateProfile ? dateProfile.activeRange : null; 7954 return addSources( 7955 {}, 7956 parseInitialSources(calendarOptions, context), 7957 activeRange, 7958 context 7959 ); 7960 } 7961 function reduceEventSources(eventSources, action, dateProfile, context) { 7962 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 7963 switch (action.type) { 7964 case "ADD_EVENT_SOURCES": // already parsed 7965 return addSources(eventSources, action.sources, activeRange, context); 7966 case "REMOVE_EVENT_SOURCE": 7967 return removeSource(eventSources, action.sourceId); 7968 case "PREV": // TODO: how do we track all actions that affect dateProfile :( 7969 case "NEXT": 7970 case "CHANGE_DATE": 7971 case "CHANGE_VIEW_TYPE": 7972 if (dateProfile) {
7973 return fetchDirtySources(eventSources, activeRange, context); 7974 } else { 7975 return eventSources; 7976 } 7977 case "FETCH_EVENT_SOURCES": 7978 return fetchSourcesByIds( 7979 eventSources, 7980 action.sourceIds // why no type? 7981 ? arrayToHash(action.sourceIds) 7982 : excludeStaticSources(eventSources, context), 7983 activeRange, 7984 context 7985 ); 7986 case "RECEIVE_EVENTS": 7987 case "RECEIVE_EVENT_ERROR": 7988 return receiveResponse( 7989 eventSources, 7990 action.sourceId, 7991 action.fetchId, 7992 action.fetchRange 7993 ); 7994 case "REMOVE_ALL_EVENT_SOURCES": 7995 return {}; 7996 default: 7997 return eventSources; 7998 } 7999 } 8000 function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 8001 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 8002 return fetchSourcesByIds( 8003 eventSources, 8004 excludeStaticSources(eventSources, context), 8005 activeRange, 8006 context 8007 ); 8008 } 8009 function computeEventSourceLoadingLevel(eventSources) { 8010 var cnt = 0; 8011 for (var sourceId in eventSources) { 8012 if (eventSources[sourceId].isFetching) { 8013 cnt++; 8014 } 8015 } 8016 return cnt; 8017 } 8018 function addSources(eventSourceHash, sources, fetchRange, context) { 8019 var hash = {}; 8020 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 8021 var source = sources_1[_i]; 8022 hash[source.sourceId] = source; 8023 } 8024 if (fetchRange) { 8025 hash = fetchDirtySources(hash, fetchRange, context); 8026 } 8027 return __assign(__assign({}, eventSourceHash), hash); 8028 } 8029 function removeSource(eventSourceHash, sourceId) { 8030 return filterHash(eventSourceHash, function (eventSource) { 8031 return eventSource.sourceId !== sourceId; 8032 }); 8033 } 8034 function fetchDirtySources(sourceHash, fetchRange, context) { 8035 return fetchSourcesByIds( 8036 sourceHash, 8037 filterHash(sourceHash, function (eventSource) { 8038 return isSourceDirty(eventSource, fetchRange, context); 8039 }), 8040 fetchRange, 8041 context 8042 ); 8043 } 8044 function isSourceDirty(eventSource, fetchRange, context) { 8045 if (!doesSourceNeedRange(eventSource, context)) { 8046 return !eventSource.latestFetchId; 8047 } else { 8048 return ( 8049 !context.options.lazyFetching || 8050 !eventSource.fetchRange || 8051 eventSource.isFetching || // always cancel outdated in-progress fetches 8052 fetchRange.start < eventSource.fetchRange.start || 8053 fetchRange.end > eventSource.fetchRange.end 8054 ); 8055 } 8056 } 8057 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, context) { 8058 var nextSources = {}; 8059 for (var sourceId in prevSources) { 8060 var source = prevSources[sourceId]; 8061 if (sourceIdHash[sourceId]) { 8062 nextSources[sourceId] = fetchSource(source, fetchRange, context); 8063 } else { 8064 nextSources[sourceId] = source; 8065 } 8066 } 8067 return nextSources; 8068 } 8069 function fetchSource(eventSource, fetchRange, context) { 8070 var options = context.options, 8071 calendarApi = context.calendarApi; 8072 var sourceDef = 8073 context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 8074 var fetchId = guid(); 8075 sourceDef.fetch( 8076 { 8077 eventSource: eventSource, 8078 range: fetchRange, 8079 context: context, 8080 }, 8081 function (res) { 8082 var rawEvents = res.rawEvents; 8083 if (options.eventSourceSuccess) { 8084 rawEvents = 8085 options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || 8086 rawEvents; 8087 } 8088 if (eventSource.success) { 8089 rawEvents = 8090 eventSource.success.call(calendarApi, rawEvents, res.xhr) || 8091 rawEvents; 8092 } 8093 context.dispatch({ 8094 type: "RECEIVE_EVENTS", 8095 sourceId: eventSource.sourceId, 8096 fetchId: fetchId, 8097 fetchRange: fetchRange, 8098 rawEvents: rawEvents, 8099 }); 8100 }, 8101 function (error) { 8102 console.warn(error.message, error); 8103 if (options.eventSourceFailure) { 8104 options.eventSourceFailure.call(calendarApi, error); 8105 } 8106 if (eventSource.failure) { 8107 eventSource.failure(error); 8108 } 8109 context.dispatch({ 8110 type: "RECEIVE_EVENT_ERROR", 8111 sourceId: eventSource.sourceId, 8112 fetchId: fetchId, 8113 fetchRange: fetchRange, 8114 error: error, 8115 }); 8116 } 8117 ); 8118 return __assign(__assign({}, eventSource), { 8119 isFetching: true, 8120 latestFetchId: fetchId, 8121 }); 8122 } 8123 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 8124 var _a; 8125 var eventSource = sourceHash[sourceId]; 8126 if ( 8127 eventSource && // not already removed 8128 fetchId === eventSource.latestFetchId 8129 ) { 8130 return __assign( 8131 __assign({}, sourceHash), 8132 ((_a = {}), 8133 (_a[sourceId] = __assign(__assign({}, eventSource), { 8134 isFetching: false, 8135 fetchRange: fetchRange, // also serves as a marker that at least one fetch has completed 8136 })), 8137 _a) 8138 ); 8139 } 8140 return sourceHash; 8141 } 8142 function excludeStaticSources(eventSources, context) { 8143 return filterHash(eventSources, function (eventSource) { 8144 return doesSourceNeedRange(eventSource, context); 8145 }); 8146 } 8147 function parseInitialSources(rawOptions, context) { 8148 var refiners = buildEventSourceRefiners(context); 8149 var rawSources = [].concat(rawOptions.eventSources || []); 8150 var sources = []; // parsed 8151 if (rawOptions.initialEvents) { 8152 rawSources.unshift(rawOptions.initialEvents); 8153 } 8154 if (rawOptions.events) { 8155 rawSources.unshift(rawOptions.events); 8156 } 8157 for ( 8158 var _i = 0, rawSources_1 = rawSources; 8159 _i < rawSources_1.length; 8160 _i++ 8161 ) { 8162 var rawSource = rawSources_1[_i]; 8163 var source = parseEventSource(rawSource, context, refiners); 8164 if (source) { 8165 sources.push(source); 8166 } 8167 } 8168 return sources; 8169 } 8170 function doesSourceNeedRange(eventSource, context) { 8171 var defs = context.pluginHooks.eventSourceDefs; 8172 return !defs[eventSource.sourceDefId].ignoreRange; 8173 } 8174 8175 function reduceDateSelection(currentSelection, action) { 8176 switch (action.type) { 8177 case "UNSELECT_DATES": 8178 return null; 8179 case "SELECT_DATES": 8180 return action.selection; 8181 default: 8182 return currentSelection; 8183 } 8184 } 8185 8186 function reduceSelectedEvent(currentInstanceId, action) { 8187 switch (action.type) { 8188 case "UNSELECT_EVENT": 8189 return ""; 8190 case "SELECT_EVENT": 8191 return action.eventInstanceId; 8192 default: 8193 return currentInstanceId; 8194 } 8195 } 8196 8197 function reduceEventDrag(currentDrag, action) { 8198 var newDrag; 8199 switch (action.type) { 8200 case "UNSET_EVENT_DRAG": 8201 return null; 8202 case "SET_EVENT_DRAG": 8203 newDrag = action.state; 8204 return { 8205 affectedEvents: newDrag.affectedEvents, 8206 mutatedEvents: newDrag.mutatedEvents, 8207 isEvent: newDrag.isEvent, 8208 }; 8209 default: 8210 return currentDrag; 8211 } 8212 } 8213 8214 function reduceEventResize(currentResize, action) { 8215 var newResize; 8216 switch (action.type) { 8217 case "UNSET_EVENT_RESIZE": 8218 return null; 8219 case "SET_EVENT_RESIZE": 8220 newResize = action.state; 8221 return { 8222 affectedEvents: newResize.affectedEvents, 8223 mutatedEvents: newResize.mutatedEvents, 8224 isEvent: newResize.isEvent, 8225 }; 8226 default: 8227 return currentResize; 8228 } 8229 } 8230 8231 function parseToolbars( 8232 calendarOptions, 8233 calendarOptionOverrides, 8234 theme, 8235 viewSpecs, 8236 calendarApi 8237 ) { 8238 var viewsWithButtons = []; 8239 var headerToolbar = calendarOptions.headerToolbar 8240 ? parseToolbar( 8241 calendarOptions.headerToolbar, 8242 calendarOptions, 8243 calendarOptionOverrides, 8244 theme, 8245 viewSpecs, 8246 calendarApi, 8247 viewsWithButtons 8248 ) 8249 : null; 8250 var footerToolbar = calendarOptions.footerToolbar 8251 ? parseToolbar( 8252 calendarOptions.footerToolbar, 8253 calendarOptions, 8254 calendarOptionOverrides, 8255 theme, 8256 viewSpecs, 8257 calendarApi, 8258 viewsWithButtons 8259 ) 8260 : null; 8261 return { 8262 headerToolbar: headerToolbar, 8263 footerToolbar: footerToolbar, 8264 viewsWithButtons: viewsWithButtons, 8265 }; 8266 } 8267 function parseToolbar( 8268 sectionStrHash, 8269 calendarOptions, 8270 calendarOptionOverrides, 8271 theme, 8272 viewSpecs, 8273 calendarApi, 8274 viewsWithButtons // dump side effects 8275 ) { 8276 return mapHash(sectionStrHash, function (sectionStr) { 8277 return parseSection( 8278 sectionStr, 8279 calendarOptions, 8280 calendarOptionOverrides, 8281 theme, 8282 viewSpecs, 8283 calendarApi, 8284 viewsWithButtons 8285 ); 8286 }); 8287 } 8288 /* 8289 BAD: querying icons and text here. should be done at render time 8290 */ 8291 function parseSection( 8292 sectionStr, 8293 calendarOptions, 8294 calendarOptionOverrides, 8295 theme, 8296 viewSpecs, 8297 calendarApi, 8298 viewsWithButtons // dump side effects 8299 ) { 8300 var isRtl = calendarOptions.direction === "rtl"; 8301 var calendarCustomButtons = calendarOptions.customButtons || {}; 8302 var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 8303 var calendarButtonText = calendarOptions.buttonText || {}; 8304 var sectionSubstrs = sectionStr ? sectionStr.split(" ") : []; 8305 return sectionSubstrs.map(function (buttonGroupStr) { 8306 return buttonGroupStr.split(",").map(function (buttonName) { 8307 if (buttonName === "title") { 8308 return { buttonName: buttonName }; 8309 } else { 8310 var customButtonProps_1; 8311 var viewSpec = void 0; 8312 var buttonClick = void 0; 8313 var buttonIcon = void 0; // only one of these will be set 8314 var buttonText = void 0; // " 8315 if ((customButtonProps_1 = calendarCustomButtons[buttonName])) { 8316 buttonClick = function (ev) { 8317 if (customButtonProps_1.click) { 8318 customButtonProps_1.click.call(ev.target, ev, ev.target); 8319 } 8320 }; 8321 (buttonIcon = 8322 theme.getCustomButtonIconClass(customButtonProps_1)) || 8323 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 8324 (buttonText = customButtonProps_1.text); 8325 } else if ((viewSpec = viewSpecs[buttonName])) { 8326 viewsWithButtons.push(buttonName); 8327 buttonClick = function () { 8328 calendarApi.changeView(buttonName); 8329 }; 8330 (buttonText = viewSpec.buttonTextOverride) || 8331 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 8332 (buttonText = viewSpec.buttonTextDefault); 8333 } else if (calendarApi[buttonName]) { 8334 // a calendarApi method 8335 buttonClick = function () { 8336 calendarApi[buttonName](); 8337 }; 8338 (buttonText = calendarButtonTextOverrides[buttonName]) || 8339 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 8340 (buttonText = calendarButtonText[buttonName]); 8341 // ^ everything else is considered default 8342 } 8343 return { 8344 buttonName: buttonName, 8345 buttonClick: buttonClick, 8346 buttonIcon: buttonIcon, 8347 buttonText: buttonText, 8348 }; 8349 } 8350 }); 8351 }); 8352 } 8353 8354 var eventSourceDef = { 8355 ignoreRange: true, 8356 parseMeta: function (refined) { 8357 if (Array.isArray(refined.events)) { 8358 return refined.events; 8359 } 8360 return null; 8361 }, 8362 fetch: function (arg, success) { 8363 success({ 8364 rawEvents: arg.eventSource.meta, 8365 }); 8366 }, 8367 }; 8368 var arrayEventSourcePlugin = createPlugin({ 8369 eventSourceDefs: [eventSourceDef], 8370 }); 8371 8372 var eventSourceDef$1 = { 8373 parseMeta: function (refined) { 8374 if (typeof refined.events === "function") { 8375 return refined.events; 8376 } 8377 return null; 8378 }, 8379 fetch: function (arg, success, failure) { 8380 var dateEnv = arg.context.dateEnv; 8381 var func = arg.eventSource.meta; 8382 unpromisify( 8383 func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), 8384 function (rawEvents) { 8385 success({ rawEvents: rawEvents }); // needs an object response 8386 }, 8387 failure // send errorObj directly to failure callback 8388 ); 8389 }, 8390 }; 8391 var funcEventSourcePlugin = createPlugin({ 8392 eventSourceDefs: [eventSourceDef$1], 8393 }); 8394 8395 function requestJson(method, url, params, successCallback, failureCallback) { 8396 method = method.toUpperCase(); 8397 var body = null; 8398 if (method === "GET") { 8399 url = injectQueryStringParams(url, params); 8400 } else { 8401 body = encodeParams(params); 8402 } 8403 var xhr = new XMLHttpRequest(); 8404 xhr.open(method, url, true); 8405 if (method !== "GET") { 8406 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 8407 } 8408 xhr.onload = function () { 8409 if (xhr.status >= 200 && xhr.status < 400) { 8410 var parsed = false;
8411 var res = void 0; 8412 try { 8413 res = JSON.parse(xhr.responseText); 8414 parsed = true; 8415 } catch (err) { 8416 // will handle parsed=false 8417 } 8418 if (parsed) { 8419 successCallback(res, xhr); 8420 } else { 8421 failureCallback("Failure parsing JSON", xhr); 8422 } 8423 } else { 8424 failureCallback("Request failed", xhr); 8425 } 8426 }; 8427 xhr.onerror = function () { 8428 failureCallback("Request failed", xhr); 8429 }; 8430 xhr.send(body); 8431 } 8432 function injectQueryStringParams(url, params) { 8433 return url + (url.indexOf("?") === -1 ? "?" : "&") + encodeParams(params); 8434 } 8435 function encodeParams(params) { 8436 var parts = []; 8437 for (var key in params) { 8438 parts.push( 8439 encodeURIComponent(key) + "=" + encodeURIComponent(params[key]) 8440 ); 8441 } 8442 return parts.join("&"); 8443 } 8444 8445 var JSON_FEED_EVENT_SOURCE_REFINERS = { 8446 method: String, 8447 extraParams: identity, 8448 startParam: String, 8449 endParam: String, 8450 timeZoneParam: String, 8451 }; 8452 8453 var eventSourceDef$2 = { 8454 parseMeta: function (refined) { 8455 if (refined.url) { 8456 return { 8457 url: refined.url, 8458 method: (refined.method || "GET").toUpperCase(), 8459 extraParams: refined.extraParams, 8460 startParam: refined.startParam, 8461 endParam: refined.endParam, 8462 timeZoneParam: refined.timeZoneParam, 8463 }; 8464 } 8465 return null; 8466 }, 8467 fetch: function (arg, success, failure) { 8468 var meta = arg.eventSource.meta; 8469 var requestParams = buildRequestParams(meta, arg.range, arg.context); 8470 requestJson( 8471 meta.method, 8472 meta.url, 8473 requestParams, 8474 function (rawEvents, xhr) { 8475 success({ rawEvents: rawEvents, xhr: xhr }); 8476 }, 8477 function (errorMessage, xhr) { 8478 failure({ message: errorMessage, xhr: xhr }); 8479 } 8480 ); 8481 }, 8482 }; 8483 var jsonFeedEventSourcePlugin = createPlugin({ 8484 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 8485 eventSourceDefs: [eventSourceDef$2], 8486 }); 8487 function buildRequestParams(meta, range, context) { 8488 var dateEnv = context.dateEnv, 8489 options = context.options; 8490 var startParam; 8491 var endParam; 8492 var timeZoneParam;
8493 var customRequestParams; 8494 var params = {}; 8495 startParam = meta.startParam; 8496 if (startParam == null) { 8497 startParam = options.startParam; 8498 } 8499 endParam = meta.endParam; 8500 if (endParam == null) { 8501 endParam = options.endParam; 8502 } 8503 timeZoneParam = meta.timeZoneParam; 8504 if (timeZoneParam == null) { 8505 timeZoneParam = options.timeZoneParam; 8506 } 8507 // retrieve any outbound GET/POST data from the options 8508 if (typeof meta.extraParams === "function") { 8509 // supplied as a function that returns a key/value object 8510 customRequestParams = meta.extraParams(); 8511 } else { 8512 // probably supplied as a straight key/value object 8513 customRequestParams = meta.extraParams || {}; 8514 } 8515 __assign(params, customRequestParams); 8516 params[startParam] = dateEnv.formatIso(range.start); 8517 params[endParam] = dateEnv.formatIso(range.end); 8518 if (dateEnv.timeZone !== "local") { 8519 params[timeZoneParam] = dateEnv.timeZone; 8520 } 8521 return params; 8522 } 8523 8524 var SIMPLE_RECURRING_REFINERS = { 8525 daysOfWeek: identity, 8526 startTime: createDuration, 8527 endTime: createDuration, 8528 duration: createDuration, 8529 startRecur: identity, 8530 endRecur: identity, 8531 }; 8532 8533 var recurring = { 8534 parse: function (refined, dateEnv) { 8535 if ( 8536 refined.daysOfWeek || 8537 refined.startTime || 8538 refined.endTime || 8539 refined.startRecur || 8540 refined.endRecur 8541 ) { 8542 var recurringData = { 8543 daysOfWeek: refined.daysOfWeek || null, 8544 startTime: refined.startTime || null, 8545 endTime: refined.endTime || null, 8546 startRecur: refined.startRecur 8547 ? dateEnv.createMarker(refined.startRecur) 8548 : null, 8549 endRecur: refined.endRecur 8550 ? dateEnv.createMarker(refined.endRecur) 8551 : null, 8552 }; 8553 var duration = void 0; 8554 if (refined.duration) { 8555 duration = refined.duration; 8556 } 8557 if (!duration && refined.startTime && refined.endTime) { 8558 duration = subtractDurations(refined.endTime, refined.startTime); 8559 } 8560 return { 8561 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 8562 duration: duration, 8563 typeData: recurringData, // doesn't need endTime anymore but oh well 8564 }; 8565 } 8566 return null; 8567 }, 8568 expand: function (typeData, framingRange, dateEnv) { 8569 var clippedFramingRange = intersectRanges(framingRange, { 8570 start: typeData.startRecur, 8571 end: typeData.endRecur, 8572 }); 8573 if (clippedFramingRange) { 8574 return expandRanges( 8575 typeData.daysOfWeek, 8576 typeData.startTime, 8577 clippedFramingRange, 8578 dateEnv 8579 ); 8580 } else { 8581 return []; 8582 } 8583 }, 8584 }; 8585 var simpleRecurringEventsPlugin = createPlugin({ 8586 recurringTypes: [recurring], 8587 eventRefiners: SIMPLE_RECURRING_REFINERS, 8588 }); 8589 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 8590 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 8591 var dayMarker = startOfDay(framingRange.start); 8592 var endMarker = framingRange.end; 8593 var instanceStarts = []; 8594 while (dayMarker < endMarker) { 8595 var instanceStart = 8596 // if everyday, or this particular day-of-week 8597 void 0; 8598 // if everyday, or this particular day-of-week 8599 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 8600 if (startTime) { 8601 instanceStart = dateEnv.add(dayMarker, startTime); 8602 } else { 8603 instanceStart = dayMarker; 8604 } 8605 instanceStarts.push(instanceStart); 8606 } 8607 dayMarker = addDays(dayMarker, 1); 8608 } 8609 return instanceStarts; 8610 } 8611 8612 var changeHandlerPlugin = createPlugin({ 8613 optionChangeHandlers: { 8614 events: function (events, context) { 8615 handleEventSources([events], context); 8616 }, 8617 eventSources: handleEventSources, 8618 }, 8619 }); 8620 /* 8621 BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out 8622 */ 8623 function handleEventSources(inputs, context) { 8624 var unfoundSources = hashValuesToArray( 8625 context.getCurrentData().eventSources 8626 );
8627 var newInputs = []; 8628 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 8629 var input = inputs_1[_i]; 8630 var inputFound = false; 8631 for (var i = 0; i < unfoundSources.length; i++) { 8632 if (unfoundSources[i]._raw === input) { 8633 unfoundSources.splice(i, 1); // delete 8634 inputFound = true; 8635 break; 8636 } 8637 } 8638 if (!inputFound) { 8639 newInputs.push(input); 8640 } 8641 } 8642 for ( 8643 var _a = 0, unfoundSources_1 = unfoundSources; 8644 _a < unfoundSources_1.length; 8645 _a++ 8646 ) { 8647 var unfoundSource = unfoundSources_1[_a]; 8648 context.dispatch({ 8649 type: "REMOVE_EVENT_SOURCE", 8650 sourceId: unfoundSource.sourceId, 8651 }); 8652 } 8653 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 8654 var newInput = newInputs_1[_b]; 8655 context.calendarApi.addEventSource(newInput); 8656 } 8657 } 8658 8659 function handleDateProfile(dateProfile, context) { 8660 context.emitter.trigger( 8661 "datesSet", 8662 __assign( 8663 __assign( 8664 {}, 8665 buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv) 8666 ), 8667 { view: context.viewApi } 8668 ) 8669 ); 8670 } 8671 8672 function handleEventStore(eventStore, context) { 8673 var emitter = context.emitter; 8674 if (emitter.hasHandlers("eventsSet")) { 8675 emitter.trigger("eventsSet", buildEventApis(eventStore, context)); 8676 } 8677 } 8678 8679 /* 8680 this array is exposed on the root namespace so that UMD plugins can add to it. 8681 see the rollup-bundles script. 8682 */ 8683 var globalPlugins = [ 8684 arrayEventSourcePlugin, 8685 funcEventSourcePlugin, 8686 jsonFeedEventSourcePlugin, 8687 simpleRecurringEventsPlugin, 8688 changeHandlerPlugin, 8689 createPlugin({ 8690 contentTypeHandlers: { 8691 html: function () { 8692 return injectHtml; 8693 }, 8694 domNodes: function () { 8695 return injectDomNodes; 8696 }, 8697 }, 8698 propSetHandlers: { 8699 dateProfile: handleDateProfile, 8700 eventStore: handleEventStore, 8701 }, 8702 }), 8703 ]; 8704 function injectHtml(el, html) { 8705 el.innerHTML = html; 8706 } 8707 function injectDomNodes(el, domNodes) { 8708 var oldNodes = Array.prototype.slice.call(el.childNodes); // TODO: use array util 8709 var newNodes = Array.prototype.slice.call(domNodes); // TODO: use array util 8710 if (!isArraysEqual(oldNodes, newNodes)) { 8711 for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) { 8712 var newNode = newNodes_1[_i]; 8713 el.appendChild(newNode); 8714 } 8715 oldNodes.forEach(removeElement); 8716 } 8717 } 8718 8719 var DelayedRunner = /** @class */ (function () { 8720 function DelayedRunner(drainedOption) { 8721 this.drainedOption = drainedOption; 8722 this.isRunning = false; 8723 this.isDirty = false; 8724 this.pauseDepths = {}; 8725 this.timeoutId = 0; 8726 } 8727 DelayedRunner.prototype.request = function (delay) { 8728 this.isDirty = true; 8729 if (!this.isPaused()) { 8730 this.clearTimeout(); 8731 if (delay == null) { 8732 this.tryDrain(); 8733 } else { 8734 this.timeoutId = setTimeout( 8735 // NOT OPTIMAL! TODO: look at debounce 8736 this.tryDrain.bind(this), 8737 delay 8738 ); 8739 } 8740 } 8741 }; 8742 DelayedRunner.prototype.pause = function (scope) { 8743 if (scope === void 0) { 8744 scope = ""; 8745 } 8746 var pauseDepths = this.pauseDepths; 8747 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 8748 this.clearTimeout(); 8749 }; 8750 DelayedRunner.prototype.resume = function (scope, force) { 8751 if (scope === void 0) { 8752 scope = ""; 8753 } 8754 var pauseDepths = this.pauseDepths; 8755 if (scope in pauseDepths) { 8756 if (force) { 8757 delete pauseDepths[scope]; 8758 } else { 8759 var depth = --pauseDepths[scope]; 8760 if (depth <= 0) { 8761 delete pauseDepths[scope]; 8762 } 8763 } 8764 this.tryDrain(); 8765 } 8766 }; 8767 DelayedRunner.prototype.isPaused = function () { 8768 return Object.keys(this.pauseDepths).length; 8769 }; 8770 DelayedRunner.prototype.tryDrain = function () { 8771 if (!this.isRunning && !this.isPaused()) { 8772 this.isRunning = true; 8773 while (this.isDirty) { 8774 this.isDirty = false;
8775 this.drained(); // might set isDirty to true again 8776 } 8777 this.isRunning = false; 8778 } 8779 }; 8780 DelayedRunner.prototype.clear = function () { 8781 this.clearTimeout(); 8782 this.isDirty = false; 8783 this.pauseDepths = {}; 8784 }; 8785 DelayedRunner.prototype.clearTimeout = function () { 8786 if (this.timeoutId) { 8787 clearTimeout(this.timeoutId); 8788 this.timeoutId = 0; 8789 } 8790 }; 8791 DelayedRunner.prototype.drained = function () { 8792 if (this.drainedOption) { 8793 this.drainedOption(); 8794 } 8795 }; 8796 return DelayedRunner; 8797 })(); 8798 var TaskRunner = /** @class */ (function () { 8799 function TaskRunner(runTaskOption, drainedOption) { 8800 this.runTaskOption = runTaskOption; 8801 this.drainedOption = drainedOption; 8802 this.queue = []; 8803 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 8804 } 8805 TaskRunner.prototype.request = function (task, delay) { 8806 this.queue.push(task); 8807 this.delayedRunner.request(delay); 8808 }; 8809 TaskRunner.prototype.pause = function (scope) { 8810 this.delayedRunner.pause(scope); 8811 }; 8812 TaskRunner.prototype.resume = function (scope, force) { 8813 this.delayedRunner.resume(scope, force); 8814 }; 8815 TaskRunner.prototype.drain = function () { 8816 var queue = this.queue; 8817 while (queue.length) { 8818 var completedTasks = []; 8819 var task = void 0; 8820 while ((task = queue.shift())) { 8821 this.runTask(task); 8822 completedTasks.push(task); 8823 } 8824 this.drained(completedTasks); 8825 } // keep going, in case new tasks were added in the drained handler 8826 }; 8827 TaskRunner.prototype.runTask = function (task) { 8828 if (this.runTaskOption) { 8829 this.runTaskOption(task); 8830 } 8831 }; 8832 TaskRunner.prototype.drained = function (completedTasks) { 8833 if (this.drainedOption) { 8834 this.drainedOption(completedTasks); 8835 } 8836 }; 8837 return TaskRunner; 8838 })(); 8839 8840 // Computes what the title at the top of the calendarApi should be for this view 8841 function buildTitle(dateProfile, viewOptions, dateEnv) { 8842 var range; 8843 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 8844 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 8845 range = dateProfile.currentRange; 8846 } else { 8847 // for day units or smaller, use the actual day range 8848 range = dateProfile.activeRange; 8849 } 8850 return dateEnv.formatRange( 8851 range.start, 8852 range.end, 8853 createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), 8854 { 8855 isEndExclusive: dateProfile.isRangeAllDay, 8856 defaultSeparator: viewOptions.titleRangeSeparator, 8857 } 8858 ); 8859 } 8860 // Generates the format string that should be used to generate the title for the current date range. 8861 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 8862 function buildTitleFormat(dateProfile) { 8863 var currentRangeUnit = dateProfile.currentRangeUnit; 8864 if (currentRangeUnit === "year") { 8865 return { year: "numeric" }; 8866 } else if (currentRangeUnit === "month") { 8867 return { year: "numeric", month: "long" }; // like "September 2014" 8868 } else { 8869 var days = diffWholeDays( 8870 dateProfile.currentRange.start, 8871 dateProfile.currentRange.end 8872 ); 8873 if (days !== null && days > 1) { 8874 // multi-day range. shorter, like "Sep 9 - 10 2014"
8875 return { year: "numeric", month: "short", day: "numeric" }; 8876 } else { 8877 // one day. longer, like "September 9 2014" 8878 return { year: "numeric", month: "long", day: "numeric" }; 8879 } 8880 } 8881 } 8882 8883 // in future refactor, do the redux-style function(state=initial) for initial-state 8884 // also, whatever is happening in constructor, have it happen in action queue too 8885 var CalendarDataManager = /** @class */ (function () { 8886 function CalendarDataManager(props) { 8887 var _this = this; 8888 this.computeOptionsData = memoize(this._computeOptionsData); 8889 this.computeCurrentViewData = memoize(this._computeCurrentViewData); 8890 this.organizeRawLocales = memoize(organizeRawLocales); 8891 this.buildLocale = memoize(buildLocale); 8892 this.buildPluginHooks = buildBuildPluginHooks(); 8893 this.buildDateEnv = memoize(buildDateEnv$1); 8894 this.buildTheme = memoize(buildTheme); 8895 this.parseToolbars = memoize(parseToolbars); 8896 this.buildViewSpecs = memoize(buildViewSpecs); 8897 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 8898 this.buildViewApi = memoize(buildViewApi); 8899 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 8900 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 8901 this.buildEventUiBases = memoize(buildEventUiBases); 8902 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 8903 this.buildTitle = memoize(buildTitle); 8904 this.emitter = new Emitter(); 8905 this.actionRunner = new TaskRunner( 8906 this._handleAction.bind(this), 8907 this.updateData.bind(this) 8908 ); 8909 this.currentCalendarOptionsInput = {}; 8910 this.currentCalendarOptionsRefined = {}; 8911 this.currentViewOptionsInput = {}; 8912 this.currentViewOptionsRefined = {}; 8913 this.currentCalendarOptionsRefiners = {}; 8914 this.getCurrentData = function () { 8915 return _this.data; 8916 }; 8917 this.dispatch = function (action) { 8918 _this.actionRunner.request(action); // protects against recursive calls to _handleAction 8919 }; 8920 this.props = props; 8921 this.actionRunner.pause(); 8922 var dynamicOptionOverrides = {}; 8923 var optionsData = this.computeOptionsData( 8924 props.optionOverrides, 8925 dynamicOptionOverrides, 8926 props.calendarApi 8927 ); 8928 var currentViewType = 8929 optionsData.calendarOptions.initialView || 8930 optionsData.pluginHooks.initialView; 8931 var currentViewData = this.computeCurrentViewData( 8932 currentViewType, 8933 optionsData, 8934 props.optionOverrides, 8935 dynamicOptionOverrides 8936 ); 8937 // wire things up 8938 // TODO: not DRY 8939 props.calendarApi.currentDataManager = this; 8940 this.emitter.setThisContext(props.calendarApi); 8941 this.emitter.setOptions(currentViewData.options); 8942 var currentDate = getInitialDate( 8943 optionsData.calendarOptions, 8944 optionsData.dateEnv 8945 ); 8946 var dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 8947 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 8948 currentDate = dateProfile.currentRange.start; 8949 } 8950 var calendarContext = { 8951 dateEnv: optionsData.dateEnv, 8952 options: optionsData.calendarOptions, 8953 pluginHooks: optionsData.pluginHooks, 8954 calendarApi: props.calendarApi, 8955 dispatch: this.dispatch, 8956 emitter: this.emitter, 8957 getCurrentData: this.getCurrentData, 8958 }; 8959 // needs to be after setThisContext 8960 for ( 8961 var _i = 0, _a = optionsData.pluginHooks.contextInit; 8962 _i < _a.length; 8963 _i++ 8964 ) { 8965 var callback = _a[_i]; 8966 callback(calendarContext); 8967 } 8968 // NOT DRY 8969 var eventSources = initEventSources( 8970 optionsData.calendarOptions, 8971 dateProfile, 8972 calendarContext 8973 ); 8974 var initialState = { 8975 dynamicOptionOverrides: dynamicOptionOverrides, 8976 currentViewType: currentViewType, 8977 currentDate: currentDate, 8978 dateProfile: dateProfile, 8979 businessHours: this.parseContextBusinessHours(calendarContext), 8980 eventSources: eventSources, 8981 eventUiBases: {}, 8982 loadingLevel: computeEventSourceLoadingLevel(eventSources), 8983 eventStore: createEmptyEventStore(), 8984 renderableEventStore: createEmptyEventStore(), 8985 dateSelection: null, 8986 eventSelection: "", 8987 eventDrag: null, 8988 eventResize: null, 8989 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig, 8990 }; 8991 var contextAndState = __assign( 8992 __assign({}, calendarContext), 8993 initialState 8994 ); 8995 for ( 8996 var _b = 0, _c = optionsData.pluginHooks.reducers; 8997 _b < _c.length; 8998 _b++ 8999 ) { 9000 var reducer = _c[_b]; 9001 __assign(initialState, reducer(null, null, contextAndState)); 9002 } 9003 if (initialState.loadingLevel) { 9004 this.emitter.trigger("loading", true); // NOT DRY 9005 } 9006 this.state = initialState; 9007 this.updateData(); 9008 this.actionRunner.resume(); 9009 } 9010 CalendarDataManager.prototype.resetOptions = function ( 9011 optionOverrides, 9012 append 9013 ) { 9014 var props = this.props; 9015 props.optionOverrides = append 9016 ? __assign(__assign({}, props.optionOverrides), optionOverrides) 9017 : optionOverrides; 9018 this.actionRunner.request({ 9019 type: "NOTHING", 9020 }); 9021 }; 9022 CalendarDataManager.prototype._handleAction = function (action) { 9023 var _a = this, 9024 props = _a.props, 9025 state = _a.state, 9026 emitter = _a.emitter; 9027 var dynamicOptionOverrides = reduceDynamicOptionOverrides( 9028 state.dynamicOptionOverrides, 9029 action 9030 ); 9031 var optionsData = this.computeOptionsData( 9032 props.optionOverrides, 9033 dynamicOptionOverrides, 9034 props.calendarApi 9035 ); 9036 var currentViewType = reduceViewType(state.currentViewType, action); 9037 var currentViewData = this.computeCurrentViewData( 9038 currentViewType, 9039 optionsData, 9040 props.optionOverrides, 9041 dynamicOptionOverrides 9042 ); 9043 // wire things up 9044 // TODO: not DRY 9045 props.calendarApi.currentDataManager = this; 9046 emitter.setThisContext(props.calendarApi); 9047 emitter.setOptions(currentViewData.options); 9048 var calendarContext = { 9049 dateEnv: optionsData.dateEnv, 9050 options: optionsData.calendarOptions, 9051 pluginHooks: optionsData.pluginHooks, 9052 calendarApi: props.calendarApi, 9053 dispatch: this.dispatch, 9054 emitter: emitter, 9055 getCurrentData: this.getCurrentData, 9056 }; 9057 var currentDate = state.currentDate; 9058 var dateProfile = state.dateProfile; 9059 if ( 9060 this.data && 9061 this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator 9062 ) { 9063 // hack 9064 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 9065 } 9066 currentDate = reduceCurrentDate(currentDate, action); 9067 dateProfile = reduceDateProfile( 9068 dateProfile, 9069 action, 9070 currentDate, 9071 currentViewData.dateProfileGenerator 9072 ); 9073 if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) { 9074 currentDate = dateProfile.currentRange.start; 9075 } 9076 var eventSources = reduceEventSources( 9077 state.eventSources, 9078 action, 9079 dateProfile, 9080 calendarContext 9081 ); 9082 var eventSourceLoadingLevel = 9083 computeEventSourceLoadingLevel(eventSources); 9084 var eventStore = reduceEventStore( 9085 state.eventStore, 9086 action, 9087 eventSources, 9088 dateProfile, 9089 calendarContext 9090 ); 9091 var renderableEventStore = 9092 eventSourceLoadingLevel && 9093 !currentViewData.options.progressiveEventRendering 9094 ? state.renderableEventStore || eventStore // try from previous state 9095 : eventStore; 9096 var _b = this.buildViewUiProps(calendarContext), 9097 eventUiSingleBase = _b.eventUiSingleBase, 9098 selectionConfig = _b.selectionConfig; // will memoize obj 9099 var eventUiBySource = this.buildEventUiBySource(eventSources); 9100 var eventUiBases = this.buildEventUiBases( 9101 renderableEventStore.defs, 9102 eventUiSingleBase, 9103 eventUiBySource 9104 ); 9105 var prevLoadingLevel = state.loadingLevel || 0; 9106 var loadingLevel = eventSourceLoadingLevel; 9107 var newState = { 9108 dynamicOptionOverrides: dynamicOptionOverrides, 9109 currentViewType: currentViewType, 9110 currentDate: currentDate, 9111 dateProfile: dateProfile, 9112 eventSources: eventSources, 9113 eventStore: eventStore, 9114 renderableEventStore: renderableEventStore, 9115 selectionConfig: selectionConfig, 9116 eventUiBases: eventUiBases, 9117 loadingLevel: loadingLevel, 9118 businessHours: this.parseContextBusinessHours(calendarContext), 9119 dateSelection: reduceDateSelection(state.dateSelection, action), 9120 eventSelection: reduceSelectedEvent(state.eventSelection, action), 9121 eventDrag: reduceEventDrag(state.eventDrag, action), 9122 eventResize: reduceEventResize(state.eventResize, action), 9123 }; 9124 var contextAndState = __assign(__assign({}, calendarContext), newState); 9125 for ( 9126 var _i = 0, _c = optionsData.pluginHooks.reducers; 9127 _i < _c.length; 9128 _i++ 9129 ) { 9130 var reducer = _c[_i]; 9131 __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value 9132 } 9133 // TODO: use propSetHandlers in plugin system 9134 if (!prevLoadingLevel && loadingLevel) { 9135 emitter.trigger("loading", true); 9136 } else if (prevLoadingLevel && !loadingLevel) { 9137 emitter.trigger("loading", false); 9138 } 9139 this.state = newState; 9140 if (props.onAction) { 9141 props.onAction(action); 9142 } 9143 }; 9144 CalendarDataManager.prototype.updateData = function () { 9145 var _a = this, 9146 props = _a.props, 9147 state = _a.state; 9148 var oldData = this.data; 9149 var optionsData = this.computeOptionsData( 9150 props.optionOverrides, 9151 state.dynamicOptionOverrides, 9152 props.calendarApi 9153 ); 9154 var currentViewData = this.computeCurrentViewData( 9155 state.currentViewType, 9156 optionsData, 9157 props.optionOverrides, 9158 state.dynamicOptionOverrides 9159 ); 9160 var data = (this.data = __assign( 9161 __assign( 9162 __assign( 9163 { 9164 viewTitle: this.buildTitle( 9165 state.dateProfile, 9166 currentViewData.options, 9167 optionsData.dateEnv 9168 ), 9169 calendarApi: props.calendarApi, 9170 dispatch: this.dispatch, 9171 emitter: this.emitter, 9172 getCurrentData: this.getCurrentData, 9173 }, 9174 optionsData 9175 ), 9176 currentViewData 9177 ), 9178 state 9179 )); 9180 var changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 9181 var oldCalendarOptions = oldData && oldData.calendarOptions; 9182 var newCalendarOptions = optionsData.calendarOptions; 9183 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 9184 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 9185 // hack 9186 state.eventSources = data.eventSources =
9187 reduceEventSourcesNewTimeZone( 9188 data.eventSources, 9189 state.dateProfile, 9190 data 9191 ); 9192 state.eventStore = data.eventStore = rezoneEventStoreDates( 9193 data.eventStore, 9194 oldData.dateEnv, 9195 data.dateEnv 9196 ); 9197 } 9198 for (var optionName in changeHandlers) { 9199 if ( 9200 oldCalendarOptions[optionName] !== newCalendarOptions[optionName] 9201 ) { 9202 changeHandlers[optionName](newCalendarOptions[optionName], data); 9203 } 9204 } 9205 } 9206 if (props.onData) { 9207 props.onData(data); 9208 } 9209 }; 9210 CalendarDataManager.prototype._computeOptionsData = function ( 9211 optionOverrides, 9212 dynamicOptionOverrides, 9213 calendarApi 9214 ) { 9215 // TODO: blacklist options that are handled by optionChangeHandlers 9216 var _a = this.processRawCalendarOptions( 9217 optionOverrides, 9218 dynamicOptionOverrides 9219 ), 9220 refinedOptions = _a.refinedOptions, 9221 pluginHooks = _a.pluginHooks, 9222 localeDefaults = _a.localeDefaults, 9223 availableLocaleData = _a.availableLocaleData, 9224 extra = _a.extra; 9225 warnUnknownOptions(extra); 9226 var dateEnv = this.buildDateEnv( 9227 refinedOptions.timeZone, 9228 refinedOptions.locale, 9229 refinedOptions.weekNumberCalculation, 9230 refinedOptions.firstDay, 9231 refinedOptions.weekText, 9232 pluginHooks, 9233 availableLocaleData, 9234 refinedOptions.defaultRangeSeparator 9235 ); 9236 var viewSpecs = this.buildViewSpecs( 9237 pluginHooks.views, 9238 optionOverrides, 9239 dynamicOptionOverrides, 9240 localeDefaults 9241 ); 9242 var theme = this.buildTheme(refinedOptions, pluginHooks); 9243 var toolbarConfig = this.parseToolbars( 9244 refinedOptions, 9245 optionOverrides, 9246 theme, 9247 viewSpecs, 9248 calendarApi 9249 ); 9250 return { 9251 calendarOptions: refinedOptions, 9252 pluginHooks: pluginHooks, 9253 dateEnv: dateEnv, 9254 viewSpecs: viewSpecs, 9255 theme: theme, 9256 toolbarConfig: toolbarConfig, 9257 localeDefaults: localeDefaults, 9258 availableRawLocales: availableLocaleData.map, 9259 }; 9260 }; 9261 // always called from behind a memoizer 9262 CalendarDataManager.prototype.processRawCalendarOptions = function ( 9263 optionOverrides, 9264 dynamicOptionOverrides 9265 ) { 9266 var _a = mergeRawOptions([ 9267 BASE_OPTION_DEFAULTS, 9268 optionOverrides, 9269 dynamicOptionOverrides, 9270 ]), 9271 locales = _a.locales, 9272 locale = _a.locale; 9273 var availableLocaleData = this.organizeRawLocales(locales); 9274 var availableRawLocales = availableLocaleData.map; 9275 var localeDefaults = this.buildLocale( 9276 locale || availableLocaleData.defaultCode, 9277 availableRawLocales 9278 ).options; 9279 var pluginHooks = this.buildPluginHooks( 9280 optionOverrides.plugins || [], 9281 globalPlugins 9282 ); 9283 var refiners = (this.currentCalendarOptionsRefiners = __assign( 9284 __assign( 9285 __assign( 9286 __assign( 9287 __assign({}, BASE_OPTION_REFINERS), 9288 CALENDAR_LISTENER_REFINERS 9289 ), 9290 CALENDAR_OPTION_REFINERS 9291 ), 9292 pluginHooks.listenerRefiners 9293 ), 9294 pluginHooks.optionRefiners 9295 )); 9296 var extra = {}; 9297 var raw = mergeRawOptions([ 9298 BASE_OPTION_DEFAULTS, 9299 localeDefaults, 9300 optionOverrides, 9301 dynamicOptionOverrides, 9302 ]); 9303 var refined = {}; 9304 var currentRaw = this.currentCalendarOptionsInput; 9305 var currentRefined = this.currentCalendarOptionsRefined; 9306 var anyChanges = false; 9307 for (var optionName in raw) { 9308 if (optionName !== "plugins") { 9309 // because plugins is special-cased 9310 if ( 9311 raw[optionName] === currentRaw[optionName] || 9312 (COMPLEX_OPTION_COMPARATORS[optionName] && 9313 optionName in currentRaw && 9314 COMPLEX_OPTION_COMPARATORS[optionName]( 9315 currentRaw[optionName], 9316 raw[optionName] 9317 )) 9318 ) { 9319 refined[optionName] = currentRefined[optionName]; 9320 } else if (refiners[optionName]) { 9321 refined[optionName] = refiners[optionName](raw[optionName]); 9322 anyChanges = true; 9323 } else { 9324 extra[optionName] = currentRaw[optionName]; 9325 } 9326 } 9327 }
9328 if (anyChanges) { 9329 this.currentCalendarOptionsInput = raw; 9330 this.currentCalendarOptionsRefined = refined; 9331 } 9332 return { 9333 rawOptions: this.currentCalendarOptionsInput, 9334 refinedOptions: this.currentCalendarOptionsRefined, 9335 pluginHooks: pluginHooks, 9336 availableLocaleData: availableLocaleData, 9337 localeDefaults: localeDefaults, 9338 extra: extra, 9339 }; 9340 }; 9341 CalendarDataManager.prototype._computeCurrentViewData = function ( 9342 viewType, 9343 optionsData, 9344 optionOverrides, 9345 dynamicOptionOverrides 9346 ) { 9347 var viewSpec = optionsData.viewSpecs[viewType]; 9348 if (!viewSpec) { 9349 throw new Error( 9350 'viewType "' + 9351 viewType + 9352 "\" is not available. Please make sure you've loaded all neccessary plugins" 9353 ); 9354 } 9355 var _a = this.processRawViewOptions( 9356 viewSpec, 9357 optionsData.pluginHooks, 9358 optionsData.localeDefaults, 9359 optionOverrides, 9360 dynamicOptionOverrides 9361 ), 9362 refinedOptions = _a.refinedOptions, 9363 extra = _a.extra; 9364 warnUnknownOptions(extra); 9365 var dateProfileGenerator = this.buildDateProfileGenerator({ 9366 dateProfileGeneratorClass: 9367 viewSpec.optionDefaults.dateProfileGeneratorClass, 9368 duration: viewSpec.duration, 9369 durationUnit: viewSpec.durationUnit, 9370 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 9371 dateEnv: optionsData.dateEnv, 9372 calendarApi: this.props.calendarApi, 9373 slotMinTime: refinedOptions.slotMinTime, 9374 slotMaxTime: refinedOptions.slotMaxTime, 9375 showNonCurrentDates: refinedOptions.showNonCurrentDates, 9376 dayCount: refinedOptions.dayCount, 9377 dateAlignment: refinedOptions.dateAlignment, 9378 dateIncrement: refinedOptions.dateIncrement, 9379 hiddenDays: refinedOptions.hiddenDays, 9380 weekends: refinedOptions.weekends, 9381 nowInput: refinedOptions.now, 9382 validRangeInput: refinedOptions.validRange, 9383 visibleRangeInput: refinedOptions.visibleRange, 9384 monthMode: refinedOptions.monthMode, 9385 fixedWeekCount: refinedOptions.fixedWeekCount, 9386 }); 9387 var viewApi = this.buildViewApi( 9388 viewType, 9389 this.getCurrentData, 9390 optionsData.dateEnv 9391 ); 9392 return { 9393 viewSpec: viewSpec, 9394 options: refinedOptions, 9395 dateProfileGenerator: dateProfileGenerator, 9396 viewApi: viewApi, 9397 }; 9398 }; 9399 CalendarDataManager.prototype.processRawViewOptions = function ( 9400 viewSpec, 9401 pluginHooks, 9402 localeDefaults, 9403 optionOverrides, 9404 dynamicOptionOverrides 9405 ) { 9406 var raw = mergeRawOptions([ 9407 BASE_OPTION_DEFAULTS, 9408 viewSpec.optionDefaults, 9409 localeDefaults, 9410 optionOverrides, 9411 viewSpec.optionOverrides, 9412 dynamicOptionOverrides, 9413 ]); 9414 var refiners = __assign( 9415 __assign( 9416 __assign( 9417 __assign( 9418 __assign( 9419 __assign({}, BASE_OPTION_REFINERS), 9420 CALENDAR_LISTENER_REFINERS 9421 ), 9422 CALENDAR_OPTION_REFINERS 9423 ), 9424 VIEW_OPTION_REFINERS 9425 ), 9426 pluginHooks.listenerRefiners 9427 ), 9428 pluginHooks.optionRefiners 9429 ); 9430 var refined = {}; 9431 var currentRaw = this.currentViewOptionsInput; 9432 var currentRefined = this.currentViewOptionsRefined; 9433 var anyChanges = false; 9434 var extra = {}; 9435 for (var optionName in raw) { 9436 if (raw[optionName] === currentRaw[optionName]) { 9437 refined[optionName] = currentRefined[optionName]; 9438 } else { 9439 if ( 9440 raw[optionName] === this.currentCalendarOptionsInput[optionName] 9441 ) { 9442 if (optionName in this.currentCalendarOptionsRefined) { 9443 // might be an "extra" prop 9444 refined[optionName] = 9445 this.currentCalendarOptionsRefined[optionName]; 9446 } 9447 } else if (refiners[optionName]) { 9448 refined[optionName] = refiners[optionName](raw[optionName]); 9449 } else { 9450 extra[optionName] = raw[optionName]; 9451 } 9452 anyChanges = true; 9453 } 9454 }
9455 if (anyChanges) { 9456 this.currentViewOptionsInput = raw; 9457 this.currentViewOptionsRefined = refined; 9458 } 9459 return { 9460 rawOptions: this.currentViewOptionsInput, 9461 refinedOptions: this.currentViewOptionsRefined, 9462 extra: extra, 9463 }; 9464 }; 9465 return CalendarDataManager; 9466 })(); 9467 function buildDateEnv$1( 9468 timeZone, 9469 explicitLocale, 9470 weekNumberCalculation, 9471 firstDay, 9472 weekText, 9473 pluginHooks, 9474 availableLocaleData, 9475 defaultSeparator 9476 ) { 9477 var locale = buildLocale( 9478 explicitLocale || availableLocaleData.defaultCode, 9479 availableLocaleData.map 9480 ); 9481 return new DateEnv({ 9482 calendarSystem: "gregory", 9483 timeZone: timeZone, 9484 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 9485 locale: locale, 9486 weekNumberCalculation: weekNumberCalculation, 9487 firstDay: firstDay, 9488 weekText: weekText, 9489 cmdFormatter: pluginHooks.cmdFormatter, 9490 defaultSeparator: defaultSeparator, 9491 }); 9492 } 9493 function buildTheme(options, pluginHooks) { 9494 var ThemeClass = 9495 pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 9496 return new ThemeClass(options); 9497 } 9498 function buildDateProfileGenerator(props) { 9499 var DateProfileGeneratorClass = 9500 props.dateProfileGeneratorClass || DateProfileGenerator; 9501 return new DateProfileGeneratorClass(props); 9502 } 9503 function buildViewApi(type, getCurrentData, dateEnv) { 9504 return new ViewApi(type, getCurrentData, dateEnv); 9505 } 9506 function buildEventUiBySource(eventSources) { 9507 return mapHash(eventSources, function (eventSource) { 9508 return eventSource.ui; 9509 }); 9510 } 9511 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 9512 var eventUiBases = { "": eventUiSingleBase }; 9513 for (var defId in eventDefs) { 9514 var def = eventDefs[defId]; 9515 if (def.sourceId && eventUiBySource[def.sourceId]) { 9516 eventUiBases[defId] = eventUiBySource[def.sourceId]; 9517 } 9518 } 9519 return eventUiBases; 9520 } 9521 function buildViewUiProps(calendarContext) { 9522 var options = calendarContext.options; 9523 return { 9524 eventUiSingleBase: createEventUi( 9525 { 9526 display: options.eventDisplay, 9527 editable: options.editable, 9528 startEditable: options.eventStartEditable, 9529 durationEditable: options.eventDurationEditable, 9530 constraint: options.eventConstraint, 9531 overlap: 9532 typeof options.eventOverlap === "boolean" 9533 ? options.eventOverlap 9534 : undefined, 9535 allow: options.eventAllow, 9536 backgroundColor: options.eventBackgroundColor, 9537 borderColor: options.eventBorderColor, 9538 textColor: options.eventTextColor, 9539 color: options.eventColor, 9540 // classNames: options.eventClassNames // render hook will handle this 9541 }, 9542 calendarContext 9543 ), 9544 selectionConfig: createEventUi( 9545 { 9546 constraint: options.selectConstraint, 9547 overlap: 9548 typeof options.selectOverlap === "boolean" 9549 ? options.selectOverlap 9550 : undefined, 9551 allow: options.selectAllow, 9552 }, 9553 calendarContext 9554 ), 9555 }; 9556 } 9557 function parseContextBusinessHours(calendarContext) { 9558 return parseBusinessHours( 9559 calendarContext.options.businessHours, 9560 calendarContext 9561 ); 9562 } 9563 function warnUnknownOptions(options, viewName) { 9564 for (var optionName in options) { 9565 console.warn( 9566 "Unknown option '" + 9567 optionName + 9568 "'" + 9569 (viewName ? " for view '" + viewName + "'" : "") 9570 ); 9571 } 9572 } 9573 9574 // TODO: move this to react plugin? 9575 var CalendarDataProvider = /** @class */ (function (_super) { 9576 __extends(CalendarDataProvider, _super); 9577 function CalendarDataProvider(props) { 9578 var _this = _super.call(this, props) || this; 9579 _this.handleData = function (data) { 9580 if (!_this.dataManager) { 9581 // still within initial run, before assignment in constructor 9582 // eslint-disable-next-line react/no-direct-mutation-state 9583 _this.state = data; // can't use setState yet 9584 } else { 9585 _this.setState(data); 9586 } 9587 }; 9588 _this.dataManager = new CalendarDataManager({ 9589 optionOverrides: props.optionOverrides, 9590 calendarApi: props.calendarApi, 9591 onData: _this.handleData, 9592 }); 9593 return _this; 9594 } 9595 CalendarDataProvider.prototype.render = function () { 9596 return this.props.children(this.state); 9597 }; 9598 CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) { 9599 var newOptionOverrides = this.props.optionOverrides; 9600 if (newOptionOverrides !== prevProps.optionOverrides) { 9601 // prevent recursive handleData 9602 this.dataManager.resetOptions(newOptionOverrides); 9603 } 9604 }; 9605 return CalendarDataProvider; 9606 })(Component); 9607 9608 // HELPERS 9609 /* 9610 if nextDayThreshold is specified, slicing is done in an all-day fashion. 9611 you can get nextDayThreshold from context.nextDayThreshold 9612 */ 9613 function sliceEvents(props, allDay) { 9614 return sliceEventStore( 9615 props.eventStore, 9616 props.eventUiBases, 9617 props.dateProfile.activeRange, 9618 allDay ? props.nextDayThreshold : null 9619 ).fg; 9620 } 9621 9622 var NamedTimeZoneImpl = /** @class */ (function () { 9623 function NamedTimeZoneImpl(timeZoneName) { 9624 this.timeZoneName = timeZoneName; 9625 } 9626 return NamedTimeZoneImpl; 9627 })(); 9628 9629 var Interaction = /** @class */ (function () { 9630 function Interaction(settings) { 9631 this.component = settings.component; 9632 } 9633 Interaction.prototype.destroy = function () {}; 9634 return Interaction; 9635 })(); 9636 function parseInteractionSettings(component, input) { 9637 return { 9638 component: component, 9639 el: input.el, 9640 useEventCenter: 9641 input.useEventCenter != null ? input.useEventCenter : true, 9642 }; 9643 } 9644 function interactionSettingsToStore(settings) { 9645 var _a; 9646 return (_a = {}), (_a[settings.component.uid] = settings), _a; 9647 } 9648 // global state 9649 var interactionSettingsStore = {}; 9650 9651 /* 9652 An abstraction for a dragging interaction originating on an event. 9653 Does higher-level things than PointerDragger, such as possibly: 9654 - a "mirror" that moves with the pointer 9655 - a minimum number of pixels or other criteria for a true drag to begin 9656 9657 subclasses must emit: 9658 - pointerdown 9659 - dragstart 9660 - dragmove 9661 - pointerup 9662 - dragend 9663 */ 9664 var ElementDragging = /** @class */ (function () { 9665 function ElementDragging(el, selector) { 9666 this.emitter = new Emitter(); 9667 } 9668 ElementDragging.prototype.destroy = function () {}; 9669 ElementDragging.prototype.setMirrorIsVisible = function (bool) {
9670 // optional if subclass doesn't want to support a mirror 9671 }; 9672 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 9673 // optional if subclass doesn't want to support a mirror 9674 }; 9675 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 9676 // optional 9677 }; 9678 return ElementDragging; 9679 })(); 9680 9681 // TODO: get rid of this in favor of options system, 9682 // tho it's really easy to access this globally rather than pass thru options. 9683 var config = {}; 9684 9685 /* 9686 Information about what will happen when an external element is dragged-and-dropped 9687 onto a calendar. Contains information for creating an event. 9688 */ 9689 var DRAG_META_REFINERS = { 9690 startTime: createDuration, 9691 duration: createDuration, 9692 create: Boolean, 9693 sourceId: String, 9694 }; 9695 function parseDragMeta(raw) { 9696 var _a = refineProps(raw, DRAG_META_REFINERS), 9697 refined = _a.refined, 9698 extra = _a.extra; 9699 return { 9700 startTime: refined.startTime || null, 9701 duration: refined.duration || null, 9702 create: refined.create != null ? refined.create : true, 9703 sourceId: refined.sourceId, 9704 leftoverProps: extra, 9705 }; 9706 } 9707 9708 var Toolbar = /** @class */ (function (_super) { 9709 __extends(Toolbar, _super); 9710 function Toolbar() { 9711 return (_super !== null && _super.apply(this, arguments)) || this; 9712 } 9713 Toolbar.prototype.render = function () { 9714 var _a = this.props, 9715 model = _a.model, 9716 extraClassName = _a.extraClassName; 9717 var forceLtr = false; 9718 var startContent, endContent; 9719 var centerContent = model.center; 9720 if (model.left) { 9721 forceLtr = true; 9722 startContent = model.left; 9723 } else { 9724 startContent = model.start; 9725 } 9726 if (model.right) { 9727 forceLtr = true; 9728 endContent = model.right; 9729 } else { 9730 endContent = model.end; 9731 } 9732 var classNames = [ 9733 extraClassName || "", 9734 "fc-toolbar", 9735 forceLtr ? "fc-toolbar-ltr" : "", 9736 ]; 9737 return createElement( 9738 "div", 9739 { className: classNames.join(" ") }, 9740 this.renderSection("start", startContent || []), 9741 this.renderSection("center", centerContent || []), 9742 this.renderSection("end", endContent || []) 9743 ); 9744 }; 9745 Toolbar.prototype.renderSection = function (key, widgetGroups) { 9746 var props = this.props; 9747 return createElement(ToolbarSection, { 9748 key: key, 9749 widgetGroups: widgetGroups, 9750 title: props.title, 9751 activeButton: props.activeButton, 9752 isTodayEnabled: props.isTodayEnabled, 9753 isPrevEnabled: props.isPrevEnabled, 9754 isNextEnabled: props.isNextEnabled, 9755 }); 9756 }; 9757 return Toolbar; 9758 })(BaseComponent); 9759 var ToolbarSection = /** @class */ (function (_super) { 9760 __extends(ToolbarSection, _super); 9761 function ToolbarSection() { 9762 return (_super !== null && _super.apply(this, arguments)) || this; 9763 } 9764 ToolbarSection.prototype.render = function () { 9765 var _this = this; 9766 var children = this.props.widgetGroups.map(function (widgetGroup) { 9767 return _this.renderWidgetGroup(widgetGroup); 9768 }); 9769 return createElement.apply( 9770 void 0, 9771 __spreadArrays(["div", { className: "fc-toolbar-chunk" }], children) 9772 ); 9773 }; 9774 ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) { 9775 var props = this.props; 9776 var theme = this.context.theme; 9777 var children = []; 9778 var isOnlyButtons = true; 9779 for ( 9780 var _i = 0, widgetGroup_1 = widgetGroup; 9781 _i < widgetGroup_1.length; 9782 _i++ 9783 ) { 9784 var widget = widgetGroup_1[_i]; 9785 var buttonName = widget.buttonName, 9786 buttonClick = widget.buttonClick, 9787 buttonText = widget.buttonText, 9788 buttonIcon = widget.buttonIcon; 9789 if (buttonName === "title") { 9790 isOnlyButtons = false; 9791 children.push( 9792 createElement("h2", { className: "fc-toolbar-title" }, props.title) 9793 ); 9794 } else { 9795 var ariaAttrs = buttonIcon ? { "aria-label": buttonName } : {};
9796 var buttonClasses = [ 9797 "fc-" + buttonName + "-button", 9798 theme.getClass("button"), 9799 ]; 9800 if (buttonName === props.activeButton) { 9801 buttonClasses.push(theme.getClass("buttonActive")); 9802 } 9803 var isDisabled = 9804 (!props.isTodayEnabled && buttonName === "today") || 9805 (!props.isPrevEnabled && buttonName === "prev") || 9806 (!props.isNextEnabled && buttonName === "next"); 9807 children.push( 9808 createElement( 9809 "button", 9810 __assign( 9811 { 9812 disabled: isDisabled, 9813 className: buttonClasses.join(" "), 9814 onClick: buttonClick, 9815 type: "button", 9816 }, 9817 ariaAttrs 9818 ), 9819 buttonText || 9820 (buttonIcon 9821 ? createElement("span", { className: buttonIcon }) 9822 : "") 9823 ) 9824 ); 9825 } 9826 } 9827 if (children.length > 1) { 9828 var groupClassName = 9829 (isOnlyButtons && theme.getClass("buttonGroup")) || ""; 9830 return createElement.apply( 9831 void 0, 9832 __spreadArrays(["div", { className: groupClassName }], children) 9833 ); 9834 } else { 9835 return children[0]; 9836 } 9837 }; 9838 return ToolbarSection; 9839 })(BaseComponent); 9840 9841 // TODO: do function component? 9842 var ViewContainer = /** @class */ (function (_super) { 9843 __extends(ViewContainer, _super); 9844 function ViewContainer() { 9845 var _this = (_super !== null && _super.apply(this, arguments)) || this; 9846 _this.state = { 9847 availableWidth: null, 9848 }; 9849 _this.handleEl = function (el) { 9850 _this.el = el; 9851 setRef(_this.props.elRef, el); 9852 _this.updateAvailableWidth(); 9853 }; 9854 _this.handleResize = function () { 9855 _this.updateAvailableWidth(); 9856 }; 9857 return _this; 9858 } 9859 ViewContainer.prototype.render = function () { 9860 var _a = this, 9861 props = _a.props, 9862 state = _a.state; 9863 var aspectRatio = props.aspectRatio; 9864 var classNames = [ 9865 "fc-view-harness", 9866 aspectRatio || props.liquid || props.height 9867 ? "fc-view-harness-active" // harness controls the height 9868 : "fc-view-harness-passive", // let the view do the height 9869 ]; 9870 var height = ""; 9871 var paddingBottom = ""; 9872 if (aspectRatio) { 9873 if (state.availableWidth !== null) { 9874 height = state.availableWidth / aspectRatio; 9875 } else { 9876 // while waiting to know availableWidth, we can't set height to *zero* 9877 // because will cause lots of unnecessary scrollbars within scrollgrid. 9878 // BETTER: don't start rendering ANYTHING yet until we know container width 9879 // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606) 9880 paddingBottom = (1 / aspectRatio) * 100 + "%"; 9881 } 9882 } else { 9883 height = props.height || ""; 9884 } 9885 return createElement( 9886 "div", 9887 { 9888 ref: this.handleEl, 9889 onClick: props.onClick, 9890 className: classNames.join(" "), 9891 style: { height: height, paddingBottom: paddingBottom }, 9892 }, 9893 props.children 9894 ); 9895 }; 9896 ViewContainer.prototype.componentDidMount = function () { 9897 this.context.addResizeHandler(this.handleResize); 9898 }; 9899 ViewContainer.prototype.componentWillUnmount = function () { 9900 this.context.removeResizeHandler(this.handleResize); 9901 }; 9902 ViewContainer.prototype.updateAvailableWidth = function () { 9903 if ( 9904 this.el && // needed. but why? 9905 this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth 9906 ) { 9907 this.setState({ availableWidth: this.el.offsetWidth }); 9908 } 9909 }; 9910 return ViewContainer; 9911 })(BaseComponent); 9912 9913 /* 9914 Detects when the user clicks on an event within a DateComponent 9915 */ 9916 var EventClicking = /** @class */ (function (_super) { 9917 __extends(EventClicking, _super);
9918 function EventClicking(settings) { 9919 var _this = _super.call(this, settings) || this; 9920 _this.handleSegClick = function (ev, segEl) { 9921 var component = _this.component; 9922 var context = component.context; 9923 var seg = getElSeg(segEl); 9924 if ( 9925 seg && // might be the <div> surrounding the more link 9926 component.isValidSegDownEl(ev.target) 9927 ) { 9928 // our way to simulate a link click for elements that can't be <a> tags 9929 // grab before trigger fired in case trigger trashes DOM thru rerendering 9930 var hasUrlContainer = elementClosest( 9931 ev.target, 9932 ".fc-event-forced-url" 9933 ); 9934 var url = hasUrlContainer 9935 ? hasUrlContainer.querySelector("a[href]").href 9936 : ""; 9937 context.emitter.trigger("eventClick", { 9938 el: segEl, 9939 event: new EventApi( 9940 component.context, 9941 seg.eventRange.def, 9942 seg.eventRange.instance 9943 ), 9944 jsEvent: ev, 9945 view: context.viewApi, 9946 }); 9947 if (url && !ev.defaultPrevented) { 9948 window.location.href = url; 9949 } 9950 } 9951 }; 9952 _this.destroy = listenBySelector( 9953 settings.el, 9954 "click", 9955 ".fc-event", // on both fg and bg events 9956 _this.handleSegClick 9957 ); 9958 return _this; 9959 } 9960 return EventClicking; 9961 })(Interaction); 9962 9963 /* 9964 Triggers events and adds/removes core classNames when the user's pointer 9965 enters/leaves event-elements of a component. 9966 */ 9967 var EventHovering = /** @class */ (function (_super) { 9968 __extends(EventHovering, _super); 9969 function EventHovering(settings) { 9970 var _this = _super.call(this, settings) || this; 9971 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 9972 _this.handleEventElRemove = function (el) { 9973 if (el === _this.currentSegEl) { 9974 _this.handleSegLeave(null, _this.currentSegEl); 9975 } 9976 }; 9977 _this.handleSegEnter = function (ev, segEl) { 9978 if (getElSeg(segEl)) { 9979 // TODO: better way to make sure not hovering over more+ link or its wrapper 9980 _this.currentSegEl = segEl; 9981 _this.triggerEvent("eventMouseEnter", ev, segEl); 9982 } 9983 }; 9984 _this.handleSegLeave = function (ev, segEl) { 9985 if (_this.currentSegEl) { 9986 _this.currentSegEl = null; 9987 _this.triggerEvent("eventMouseLeave", ev, segEl); 9988 } 9989 }; 9990 _this.removeHoverListeners = listenToHoverBySelector( 9991 settings.el, 9992 ".fc-event", // on both fg and bg events 9993 _this.handleSegEnter, 9994 _this.handleSegLeave 9995 ); 9996 return _this; 9997 } 9998 EventHovering.prototype.destroy = function () { 9999 this.removeHoverListeners(); 10000 }; 10001 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 10002 var component = this.component; 10003 var context = component.context; 10004 var seg = getElSeg(segEl); 10005 if (!ev || component.isValidSegDownEl(ev.target)) { 10006 context.emitter.trigger(publicEvName, { 10007 el: segEl, 10008 event: new EventApi( 10009 context, 10010 seg.eventRange.def, 10011 seg.eventRange.instance 10012 ), 10013 jsEvent: ev, 10014 view: context.viewApi, 10015 }); 10016 } 10017 }; 10018 return EventHovering; 10019 })(Interaction); 10020 10021 var CalendarContent = /** @class */ (function (_super) { 10022 __extends(CalendarContent, _super); 10023 function CalendarContent() { 10024 var _this = (_super !== null && _super.apply(this, arguments)) || this; 10025 _this.buildViewContext = memoize(buildViewContext); 10026 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 10027 _this.buildToolbarProps = memoize(buildToolbarProps); 10028 _this.handleNavLinkClick = buildDelegationHandler( 10029 "a[data-navlink]", 10030 _this._handleNavLinkClick.bind(_this) 10031 ); 10032 _this.headerRef = createRef(); 10033 _this.footerRef = createRef(); 10034 _this.interactionsStore = {}; 10035 // Component Registration 10036 // ----------------------------------------------------------------------------------------------------------------- 10037 _this.registerInteractiveComponent = function (component, settingsInput) { 10038 var settings = parseInteractionSettings(component, settingsInput); 10039 var DEFAULT_INTERACTIONS = [EventClicking, EventHovering]; 10040 var interactionClasses = DEFAULT_INTERACTIONS.concat( 10041 _this.props.pluginHooks.componentInteractions 10042 ); 10043 var interactions = interactionClasses.map(function (interactionClass) { 10044 return new interactionClass(settings); 10045 }); 10046 _this.interactionsStore[component.uid] = interactions; 10047 interactionSettingsStore[component.uid] = settings; 10048 }; 10049 _this.unregisterInteractiveComponent = function (component) { 10050 for ( 10051 var _i = 0, _a = _this.interactionsStore[component.uid]; 10052 _i < _a.length; 10053 _i++ 10054 ) { 10055 var listener = _a[_i]; 10056 listener.destroy(); 10057 } 10058 delete _this.interactionsStore[component.uid]; 10059 delete interactionSettingsStore[component.uid]; 10060 }; 10061 // Resizing 10062 // ----------------------------------------------------------------------------------------------------------------- 10063 _this.resizeRunner = new DelayedRunner(function () { 10064 _this.props.emitter.trigger("_resize", true); // should window resizes be considered "forced" ? 10065 _this.props.emitter.trigger("windowResize", { 10066 view: _this.props.viewApi, 10067 }); 10068 }); 10069 _this.handleWindowResize = function (ev) { 10070 var options = _this.props.options; 10071 if ( 10072 options.handleWindowResize && 10073 ev.target === window // avoid jqui events 10074 ) { 10075 _this.resizeRunner.request(options.windowResizeDelay); 10076 } 10077 }; 10078 return _this; 10079 } 10080 /* 10081 renders INSIDE of an outer div 10082 */ 10083 CalendarContent.prototype.render = function () { 10084 var props = this.props; 10085 var toolbarConfig = props.toolbarConfig, 10086 options = props.options; 10087 var toolbarProps = this.buildToolbarProps( 10088 props.viewSpec, 10089 props.dateProfile, 10090 props.dateProfileGenerator, 10091 props.currentDate, 10092 getNow(props.options.now, props.dateEnv), // TODO: use NowTimer???? 10093 props.viewTitle 10094 ); 10095 var viewVGrow = false;
10096 var viewHeight = ""; 10097 var viewAspectRatio; 10098 if (props.isHeightAuto || props.forPrint) { 10099 viewHeight = ""; 10100 } else if (options.height != null) { 10101 viewVGrow = true; 10102 } else if (options.contentHeight != null) { 10103 viewHeight = options.contentHeight; 10104 } else { 10105 viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall 10106 } 10107 var viewContext = this.buildViewContext( 10108 props.viewSpec, 10109 props.viewApi, 10110 props.options, 10111 props.dateProfileGenerator, 10112 props.dateEnv, 10113 props.theme, 10114 props.pluginHooks, 10115 props.dispatch, 10116 props.getCurrentData, 10117 props.emitter, 10118 props.calendarApi, 10119 this.registerInteractiveComponent, 10120 this.unregisterInteractiveComponent 10121 ); 10122 return createElement( 10123 ViewContextType.Provider, 10124 { value: viewContext }, 10125 toolbarConfig.headerToolbar && 10126 createElement( 10127 Toolbar, 10128 __assign( 10129 { 10130 ref: this.headerRef, 10131 extraClassName: "fc-header-toolbar", 10132 model: toolbarConfig.headerToolbar, 10133 }, 10134 toolbarProps 10135 ) 10136 ), 10137 createElement( 10138 ViewContainer, 10139 { 10140 liquid: viewVGrow, 10141 height: viewHeight, 10142 aspectRatio: viewAspectRatio, 10143 onClick: this.handleNavLinkClick, 10144 }, 10145 this.renderView(props), 10146 this.buildAppendContent() 10147 ), 10148 toolbarConfig.footerToolbar && 10149 createElement( 10150 Toolbar, 10151 __assign( 10152 { 10153 ref: this.footerRef, 10154 extraClassName: "fc-footer-toolbar", 10155 model: toolbarConfig.footerToolbar, 10156 }, 10157 toolbarProps 10158 ) 10159 ) 10160 ); 10161 }; 10162 CalendarContent.prototype.componentDidMount = function () { 10163 var props = this.props; 10164 this.calendarInteractions = props.pluginHooks.calendarInteractions.map( 10165 function (calendarInteractionClass) { 10166 return new calendarInteractionClass(props); 10167 } 10168 ); 10169 window.addEventListener("resize", this.handleWindowResize); 10170 var propSetHandlers = props.pluginHooks.propSetHandlers; 10171 for (var propName in propSetHandlers) { 10172 propSetHandlers[propName](props[propName], props); 10173 } 10174 }; 10175 CalendarContent.prototype.componentDidUpdate = function (prevProps) { 10176 var props = this.props; 10177 var propSetHandlers = props.pluginHooks.propSetHandlers; 10178 for (var propName in propSetHandlers) { 10179 if (props[propName] !== prevProps[propName]) { 10180 propSetHandlers[propName](props[propName], props); 10181 } 10182 } 10183 }; 10184 CalendarContent.prototype.componentWillUnmount = function () { 10185 window.removeEventListener("resize", this.handleWindowResize); 10186 this.resizeRunner.clear(); 10187 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 10188 var interaction = _a[_i]; 10189 interaction.destroy(); 10190 } 10191 this.props.emitter.trigger("_unmount"); 10192 }; 10193 CalendarContent.prototype._handleNavLinkClick = function (ev, anchorEl) { 10194 var _a = this.props, 10195 dateEnv = _a.dateEnv, 10196 options = _a.options, 10197 calendarApi = _a.calendarApi; 10198 var navLinkOptions = anchorEl.getAttribute("data-navlink"); 10199 navLinkOptions = navLinkOptions ? JSON.parse(navLinkOptions) : {}; 10200 var dateMarker = dateEnv.createMarker(navLinkOptions.date); 10201 var viewType = navLinkOptions.type; 10202 var customAction = 10203 viewType === "day" 10204 ? options.navLinkDayClick 10205 : viewType === "week" 10206 ? options.navLinkWeekClick 10207 : null; 10208 if (typeof customAction === "function") { 10209 customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev); 10210 } else { 10211 if (typeof customAction === "string") { 10212 viewType = customAction; 10213 } 10214 calendarApi.zoomTo(dateMarker, viewType); 10215 } 10216 }; 10217 CalendarContent.prototype.buildAppendContent = function () { 10218 var props = this.props; 10219 var children = props.pluginHooks.viewContainerAppends.map(function ( 10220 buildAppendContent 10221 ) { 10222 return buildAppendContent(props); 10223 }); 10224 return createElement.apply( 10225 void 0, 10226 __spreadArrays([Fragment, {}], children) 10227 ); 10228 }; 10229 CalendarContent.prototype.renderView = function (props) { 10230 var pluginHooks = props.pluginHooks; 10231 var viewSpec = props.viewSpec; 10232 var viewProps = { 10233 dateProfile: props.dateProfile, 10234 businessHours: props.businessHours, 10235 eventStore: props.renderableEventStore, 10236 eventUiBases: props.eventUiBases, 10237 dateSelection: props.dateSelection, 10238 eventSelection: props.eventSelection, 10239 eventDrag: props.eventDrag, 10240 eventResize: props.eventResize, 10241 isHeightAuto: props.isHeightAuto, 10242 forPrint: props.forPrint, 10243 }; 10244 var transformers = this.buildViewPropTransformers( 10245 pluginHooks.viewPropsTransformers 10246 ); 10247 for ( 10248 var _i = 0, transformers_1 = transformers; 10249 _i < transformers_1.length; 10250 _i++ 10251 ) { 10252 var transformer = transformers_1[_i]; 10253 __assign(viewProps, transformer.transform(viewProps, props)); 10254 } 10255 var ViewComponent = viewSpec.component; 10256 return createElement(ViewComponent, __assign({}, viewProps)); 10257 }; 10258 return CalendarContent; 10259 })(PureComponent); 10260 function buildToolbarProps( 10261 viewSpec, 10262 dateProfile, 10263 dateProfileGenerator, 10264 currentDate, 10265 now, 10266 title 10267 ) { 10268 // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid 10269 var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason 10270 var prevInfo = dateProfileGenerator.buildPrev( 10271 dateProfile, 10272 currentDate, 10273 false 10274 ); 10275 var nextInfo = dateProfileGenerator.buildNext( 10276 dateProfile, 10277 currentDate, 10278 false 10279 ); 10280 return { 10281 title: title, 10282 activeButton: viewSpec.type, 10283 isTodayEnabled: 10284 todayInfo.isValid && 10285 !rangeContainsMarker(dateProfile.currentRange, now), 10286 isPrevEnabled: prevInfo.isValid, 10287 isNextEnabled: nextInfo.isValid, 10288 }; 10289 } 10290 // Plugin 10291 // ----------------------------------------------------------------------------------------------------------------- 10292 function buildViewPropTransformers(theClasses) { 10293 return theClasses.map(function (theClass) { 10294 return new theClass(); 10295 }); 10296 } 10297 10298 var CalendarRoot = /** @class */ (function (_super) { 10299 __extends(CalendarRoot, _super); 10300 function CalendarRoot() { 10301 var _this = (_super !== null && _super.apply(this, arguments)) || this; 10302 _this.state = { 10303 forPrint: false, 10304 }; 10305 _this.handleBeforePrint = function () { 10306 _this.setState({ forPrint: true }); 10307 }; 10308 _this.handleAfterPrint = function () { 10309 _this.setState({ forPrint: false }); 10310 }; 10311 return _this; 10312 } 10313 CalendarRoot.prototype.render = function () { 10314 var props = this.props; 10315 var options = props.options; 10316 var forPrint = this.state.forPrint; 10317 var isHeightAuto = 10318 forPrint || 10319 options.height === "auto" || 10320 options.contentHeight === "auto"; 10321 var height = 10322 !isHeightAuto && options.height != null ? options.height : ""; 10323 var classNames = [ 10324 "fc", 10325 forPrint ? "fc-media-print" : "fc-media-screen", 10326 "fc-direction-" + options.direction, 10327 props.theme.getClass("root"), 10328 ]; 10329 if (!getCanVGrowWithinCell()) { 10330 classNames.push("fc-liquid-hack"); 10331 } 10332 return props.children(classNames, height, isHeightAuto, forPrint); 10333 }; 10334 CalendarRoot.prototype.componentDidMount = function () { 10335 var emitter = this.props.emitter; 10336 emitter.on("_beforeprint", this.handleBeforePrint); 10337 emitter.on("_afterprint", this.handleAfterPrint); 10338 }; 10339 CalendarRoot.prototype.componentWillUnmount = function () { 10340 var emitter = this.props.emitter; 10341 emitter.off("_beforeprint", this.handleBeforePrint); 10342 emitter.off("_afterprint", this.handleAfterPrint); 10343 }; 10344 return CalendarRoot; 10345 })(BaseComponent); 10346 10347 // Computes a default column header formatting string if `colFormat` is not explicitly defined 10348 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 10349 // if more than one week row, or if there are a lot of columns with not much space, 10350 // put just the day numbers will be in each cell 10351 if (!datesRepDistinctDays || dayCnt > 10) { 10352 return createFormatter({ weekday: "short" }); // "Sat" 10353 } else if (dayCnt > 1) { 10354 return createFormatter({ 10355 weekday: "short", 10356 month: "numeric", 10357 day: "numeric", 10358 omitCommas: true, 10359 }); // "Sat 11/12" 10360 } else { 10361 return createFormatter({ weekday: "long" }); // "Saturday" 10362 } 10363 } 10364 10365 var CLASS_NAME = "fc-col-header-cell"; // do the cushion too? no 10366 var TableDateCell = /** @class */ (function (_super) { 10367 __extends(TableDateCell, _super); 10368 function TableDateCell() { 10369 return (_super !== null && _super.apply(this, arguments)) || this; 10370 } 10371 TableDateCell.prototype.render = function () { 10372 var _a = this.context, 10373 dateEnv = _a.dateEnv, 10374 options = _a.options, 10375 theme = _a.theme, 10376 viewApi = _a.viewApi; 10377 var props = this.props; 10378 var date = props.date, 10379 dateProfile = props.dateProfile;
10380 var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 10381 var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 10382 var text = dateEnv.format(date, props.dayHeaderFormat); 10383 // if colCnt is 1, we are already in a day-view and don't need a navlink 10384 var navLinkAttrs = 10385 options.navLinks && !dayMeta.isDisabled && props.colCnt > 1 10386 ? { "data-navlink": buildNavLinkData(date), tabIndex: 0 } 10387 : {}; 10388 var hookProps = __assign( 10389 __assign( 10390 __assign( 10391 { date: dateEnv.toDate(date), view: viewApi }, 10392 props.extraHookProps 10393 ), 10394 { text: text } 10395 ), 10396 dayMeta 10397 ); 10398 return createElement( 10399 RenderHook, 10400 { 10401 hookProps: hookProps, 10402 classNames: options.dayHeaderClassNames, 10403 content: options.dayHeaderContent, 10404 defaultContent: renderInner, 10405 didMount: options.dayHeaderDidMount, 10406 willUnmount: options.dayHeaderWillUnmount, 10407 }, 10408 function (rootElRef, customClassNames, innerElRef, innerContent) { 10409 return createElement( 10410 "th", 10411 __assign( 10412 { 10413 ref: rootElRef, 10414 className: classNames.concat(customClassNames).join(" "), 10415 "data-date": !dayMeta.isDisabled 10416 ? formatDayString(date) 10417 : undefined, 10418 colSpan: props.colSpan, 10419 }, 10420 props.extraDataAttrs 10421 ), 10422 createElement( 10423 "div", 10424 { className: "fc-scrollgrid-sync-inner" }, 10425 !dayMeta.isDisabled && 10426 createElement( 10427 "a", 10428 __assign( 10429 { 10430 ref: innerElRef, 10431 className: [ 10432 "fc-col-header-cell-cushion", 10433 props.isSticky ? "fc-sticky" : "", 10434 ].join(" "), 10435 }, 10436 navLinkAttrs 10437 ), 10438 innerContent 10439 ) 10440 ) 10441 ); 10442 } 10443 ); 10444 }; 10445 return TableDateCell; 10446 })(BaseComponent); 10447 var TableDowCell = /** @class */ (function (_super) { 10448 __extends(TableDowCell, _super); 10449 function TableDowCell() { 10450 return (_super !== null && _super.apply(this, arguments)) || this; 10451 } 10452 TableDowCell.prototype.render = function () { 10453 var props = this.props; 10454 var _a = this.context, 10455 dateEnv = _a.dateEnv, 10456 theme = _a.theme, 10457 viewApi = _a.viewApi, 10458 options = _a.options; 10459 var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT 10460 var dateMeta = { 10461 dow: props.dow, 10462 isDisabled: false, 10463 isFuture: false, 10464 isPast: false, 10465 isToday: false, 10466 isOther: false, 10467 }; 10468 var classNames = [CLASS_NAME].concat( 10469 getDayClassNames(dateMeta, theme), 10470 props.extraClassNames || [] 10471 ); 10472 var text = dateEnv.format(date, props.dayHeaderFormat); 10473 var hookProps = __assign( 10474 __assign( 10475 __assign( 10476 __assign( 10477 { 10478 // TODO: make this public? 10479 date: date, 10480 }, 10481 dateMeta 10482 ), 10483 { view: viewApi } 10484 ), 10485 props.extraHookProps 10486 ), 10487 { text: text } 10488 ); 10489 return createElement( 10490 RenderHook, 10491 { 10492 hookProps: hookProps, 10493 classNames: options.dayHeaderClassNames, 10494 content: options.dayHeaderContent, 10495 defaultContent: renderInner, 10496 didMount: options.dayHeaderDidMount, 10497 willUnmount: options.dayHeaderWillUnmount, 10498 }, 10499 function (rootElRef, customClassNames, innerElRef, innerContent) { 10500 return createElement( 10501 "th", 10502 __assign( 10503 { 10504 ref: rootElRef, 10505 className: classNames.concat(customClassNames).join(" "), 10506 colSpan: props.colSpan, 10507 }, 10508 props.extraDataAttrs 10509 ), 10510 createElement( 10511 "div", 10512 { className: "fc-scrollgrid-sync-inner" }, 10513 createElement( 10514 "a", 10515 { 10516 className: [ 10517 "fc-col-header-cell-cushion", 10518 props.isSticky ? "fc-sticky" : "", 10519 ].join(" "), 10520 ref: innerElRef, 10521 }, 10522 innerContent 10523 ) 10524 ) 10525 ); 10526 } 10527 ); 10528 }; 10529 return TableDowCell; 10530 })(BaseComponent); 10531 function renderInner(hookProps) { 10532 return hookProps.text; 10533 } 10534 10535 var NowTimer = /** @class */ (function (_super) { 10536 __extends(NowTimer, _super); 10537 function NowTimer(props, context) { 10538 var _this = _super.call(this, props, context) || this; 10539 _this.initialNowDate = getNow(context.options.now, context.dateEnv); 10540 _this.initialNowQueriedMs = new Date().valueOf(); 10541 _this.state = _this.computeTiming().currentState; 10542 return _this; 10543 } 10544 NowTimer.prototype.render = function () { 10545 var _a = this, 10546 props = _a.props, 10547 state = _a.state; 10548 return props.children(state.nowDate, state.todayRange); 10549 }; 10550 NowTimer.prototype.componentDidMount = function () { 10551 this.setTimeout(); 10552 }; 10553 NowTimer.prototype.componentDidUpdate = function (prevProps) { 10554 if (prevProps.unit !== this.props.unit) { 10555 this.clearTimeout(); 10556 this.setTimeout(); 10557 } 10558 }; 10559 NowTimer.prototype.componentWillUnmount = function () { 10560 this.clearTimeout(); 10561 }; 10562 NowTimer.prototype.computeTiming = function () { 10563 var _a = this, 10564 props = _a.props, 10565 context = _a.context; 10566 var unroundedNow = addMs( 10567 this.initialNowDate, 10568 new Date().valueOf() - this.initialNowQueriedMs 10569 ); 10570 var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 10571 var nextUnitStart = context.dateEnv.add( 10572 currentUnitStart, 10573 createDuration(1, props.unit) 10574 ); 10575 var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 10576 return { 10577 currentState: { 10578 nowDate: currentUnitStart, 10579 todayRange: buildDayRange(currentUnitStart), 10580 }, 10581 nextState: { 10582 nowDate: nextUnitStart, 10583 todayRange: buildDayRange(nextUnitStart), 10584 }, 10585 waitMs: waitMs, 10586 }; 10587 }; 10588 NowTimer.prototype.setTimeout = function () { 10589 var _this = this; 10590 var _a = this.computeTiming(), 10591 nextState = _a.nextState, 10592 waitMs = _a.waitMs; 10593 this.timeoutId = setTimeout(function () { 10594 _this.setState(nextState, function () { 10595 _this.setTimeout(); 10596 }); 10597 }, waitMs); 10598 }; 10599 NowTimer.prototype.clearTimeout = function () { 10600 if (this.timeoutId) { 10601 clearTimeout(this.timeoutId); 10602 } 10603 }; 10604 NowTimer.contextType = ViewContextType; 10605 return NowTimer; 10606 })(Component); 10607 function buildDayRange(date) { 10608 var start = startOfDay(date); 10609 var end = addDays(start, 1); 10610 return { start: start, end: end }; 10611 } 10612 10613 var DayHeader = /** @class */ (function (_super) { 10614 __extends(DayHeader, _super); 10615 function DayHeader() { 10616 var _this = (_super !== null && _super.apply(this, arguments)) || this; 10617 _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 10618 return _this; 10619 } 10620 DayHeader.prototype.render = function () { 10621 var context = this.context; 10622 var _a = this.props, 10623 dates = _a.dates, 10624 dateProfile = _a.dateProfile, 10625 datesRepDistinctDays = _a.datesRepDistinctDays, 10626 renderIntro = _a.renderIntro; 10627 var dayHeaderFormat = this.createDayHeaderFormatter( 10628 context.options.dayHeaderFormat, 10629 datesRepDistinctDays, 10630 dates.length 10631 ); 10632 return createElement( 10633 NowTimer, 10634 { unit: "day" }, 10635 function (nowDate, todayRange) { 10636 return createElement( 10637 "tr", 10638 null, 10639 renderIntro && renderIntro(), 10640 dates.map(function (date) { 10641 return datesRepDistinctDays 10642 ? createElement(TableDateCell, { 10643 key: date.toISOString(), 10644 date: date, 10645 dateProfile: dateProfile, 10646 todayRange: todayRange, 10647 colCnt: dates.length, 10648 dayHeaderFormat: dayHeaderFormat, 10649 }) 10650 : createElement(TableDowCell, { 10651 key: date.getUTCDay(), 10652 dow: date.getUTCDay(), 10653 dayHeaderFormat: dayHeaderFormat, 10654 }); 10655 }) 10656 ); 10657 } 10658 ); 10659 }; 10660 return DayHeader; 10661 })(BaseComponent); 10662 function createDayHeaderFormatter( 10663 explicitFormat, 10664 datesRepDistinctDays, 10665 dateCnt 10666 ) { 10667 return ( 10668 explicitFormat || 10669 computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt) 10670 ); 10671 } 10672
10673 var DaySeriesModel = /** @class */ (function () { 10674 function DaySeriesModel(range, dateProfileGenerator) { 10675 var date = range.start; 10676 var end = range.end; 10677 var indices = []; 10678 var dates = []; 10679 var dayIndex = -1; 10680 while (date < end) { 10681 // loop each day from start to end 10682 if (dateProfileGenerator.isHiddenDay(date)) { 10683 indices.push(dayIndex + 0.5); // mark that it's between indices 10684 } else { 10685 dayIndex++; 10686 indices.push(dayIndex); 10687 dates.push(date); 10688 } 10689 date = addDays(date, 1); 10690 } 10691 this.dates = dates; 10692 this.indices = indices; 10693 this.cnt = dates.length; 10694 } 10695 DaySeriesModel.prototype.sliceRange = function (range) { 10696 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 10697 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 10698 var clippedFirstIndex = Math.max(0, firstIndex); 10699 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 10700 // deal with in-between indices 10701 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 10702 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 10703 if (clippedFirstIndex <= clippedLastIndex) { 10704 return { 10705 firstIndex: clippedFirstIndex, 10706 lastIndex: clippedLastIndex, 10707 isStart: firstIndex === clippedFirstIndex, 10708 isEnd: lastIndex === clippedLastIndex, 10709 }; 10710 } else { 10711 return null; 10712 } 10713 }; 10714 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 10715 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 10716 // If before the first offset, returns a negative number. 10717 // If after the last offset, returns an offset past the last cell offset. 10718 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 10719 DaySeriesModel.prototype.getDateDayIndex = function (date) { 10720 var indices = this.indices; 10721 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 10722 if (dayOffset < 0) { 10723 return indices[0] - 1; 10724 } else if (dayOffset >= indices.length) { 10725 return indices[indices.length - 1] + 1; 10726 } else { 10727 return indices[dayOffset]; 10728 } 10729 };
10730 return DaySeriesModel; 10731 })(); 10732 10733 var DayTableModel = /** @class */ (function () { 10734 function DayTableModel(daySeries, breakOnWeeks) { 10735 var dates = daySeries.dates; 10736 var daysPerRow; 10737 var firstDay; 10738 var rowCnt; 10739 if (breakOnWeeks) { 10740 // count columns until the day-of-week repeats 10741 firstDay = dates[0].getUTCDay(); 10742 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow++) { 10743 if (dates[daysPerRow].getUTCDay() === firstDay) { 10744 break; 10745 } 10746 } 10747 rowCnt = Math.ceil(dates.length / daysPerRow); 10748 } else { 10749 rowCnt = 1; 10750 daysPerRow = dates.length; 10751 } 10752 this.rowCnt = rowCnt; 10753 this.colCnt = daysPerRow; 10754 this.daySeries = daySeries; 10755 this.cells = this.buildCells(); 10756 this.headerDates = this.buildHeaderDates(); 10757 } 10758 DayTableModel.prototype.buildCells = function () { 10759 var rows = []; 10760 for (var row = 0; row < this.rowCnt; row++) { 10761 var cells = []; 10762 for (var col = 0; col < this.colCnt; col++) { 10763 cells.push(this.buildCell(row, col)); 10764 } 10765 rows.push(cells); 10766 } 10767 return rows; 10768 }; 10769 DayTableModel.prototype.buildCell = function (row, col) { 10770 var date = this.daySeries.dates[row * this.colCnt + col]; 10771 return { 10772 key: date.toISOString(), 10773 date: date, 10774 }; 10775 }; 10776 DayTableModel.prototype.buildHeaderDates = function () { 10777 var dates = []; 10778 for (var col = 0; col < this.colCnt; col++) { 10779 dates.push(this.cells[0][col].date); 10780 } 10781 return dates; 10782 }; 10783 DayTableModel.prototype.sliceRange = function (range) { 10784 var colCnt = this.colCnt; 10785 var seriesSeg = this.daySeries.sliceRange(range); 10786 var segs = []; 10787 if (seriesSeg) { 10788 var firstIndex = seriesSeg.firstIndex, 10789 lastIndex = seriesSeg.lastIndex; 10790 var index = firstIndex; 10791 while (index <= lastIndex) { 10792 var row = Math.floor(index / colCnt); 10793 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 10794 segs.push({ 10795 row: row, 10796 firstCol: index % colCnt, 10797 lastCol: (nextIndex - 1) % colCnt, 10798 isStart: seriesSeg.isStart && index === firstIndex, 10799 isEnd: seriesSeg.isEnd && nextIndex - 1 === lastIndex, 10800 }); 10801 index = nextIndex; 10802 } 10803 } 10804 return segs; 10805 }; 10806 return DayTableModel; 10807 })(); 10808 10809 var Slicer = /** @class */ (function () { 10810 function Slicer() { 10811 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 10812 this.sliceDateSelection = memoize(this._sliceDateSpan); 10813 this.sliceEventStore = memoize(this._sliceEventStore); 10814 this.sliceEventDrag = memoize(this._sliceInteraction); 10815 this.sliceEventResize = memoize(this._sliceInteraction); 10816 this.forceDayIfListItem = false; // hack 10817 } 10818 Slicer.prototype.sliceProps = function ( 10819 props, 10820 dateProfile, 10821 nextDayThreshold, 10822 context 10823 ) { 10824 var extraArgs = []; 10825 for (var _i = 4; _i < arguments.length; _i++) { 10826 extraArgs[_i - 4] = arguments[_i]; 10827 } 10828 var eventUiBases = props.eventUiBases; 10829 var eventSegs = this.sliceEventStore.apply( 10830 this, 10831 __spreadArrays( 10832 [props.eventStore, eventUiBases, dateProfile, nextDayThreshold], 10833 extraArgs 10834 ) 10835 ); 10836 return { 10837 dateSelectionSegs: this.sliceDateSelection.apply( 10838 this, 10839 __spreadArrays( 10840 [props.dateSelection, eventUiBases, context], 10841 extraArgs 10842 ) 10843 ), 10844 businessHourSegs: this.sliceBusinessHours.apply( 10845 this, 10846 __spreadArrays( 10847 [props.businessHours, dateProfile, nextDayThreshold, context], 10848 extraArgs 10849 ) 10850 ), 10851 fgEventSegs: eventSegs.fg, 10852 bgEventSegs: eventSegs.bg, 10853 eventDrag: this.sliceEventDrag.apply( 10854 this, 10855 __spreadArrays( 10856 [props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], 10857 extraArgs 10858 ) 10859 ), 10860 eventResize: this.sliceEventResize.apply( 10861 this, 10862 __spreadArrays( 10863 [props.eventResize, eventUiBases, dateProfile, nextDayThreshold], 10864 extraArgs 10865 ) 10866 ), 10867 eventSelection: props.eventSelection, 10868 }; // TODO: give interactionSegs? 10869 }; 10870 Slicer.prototype.sliceNowDate = function ( 10871 // does not memoize 10872 date, 10873 context 10874 ) { 10875 var extraArgs = []; 10876 for (var _i = 2; _i < arguments.length; _i++) { 10877 extraArgs[_i - 2] = arguments[_i]; 10878 } 10879 return this._sliceDateSpan.apply( 10880 this, 10881 __spreadArrays( 10882 [ 10883 { range: { start: date, end: addMs(date, 1) }, allDay: false }, 10884 {}, 10885 context, 10886 ], 10887 extraArgs 10888 ) 10889 ); 10890 }; 10891 Slicer.prototype._sliceBusinessHours = function ( 10892 businessHours, 10893 dateProfile, 10894 nextDayThreshold, 10895 context 10896 ) { 10897 var extraArgs = []; 10898 for (var _i = 4; _i < arguments.length; _i++) { 10899 extraArgs[_i - 4] = arguments[_i]; 10900 } 10901 if (!businessHours) { 10902 return []; 10903 } 10904 return this._sliceEventStore.apply( 10905 this, 10906 __spreadArrays( 10907 [ 10908 expandRecurring( 10909 businessHours, 10910 computeActiveRange(dateProfile, Boolean(nextDayThreshold)), 10911 context 10912 ), 10913 {}, 10914 dateProfile, 10915 nextDayThreshold, 10916 ], 10917 extraArgs 10918 ) 10919 ).bg; 10920 }; 10921 Slicer.prototype._sliceEventStore = function ( 10922 eventStore, 10923 eventUiBases, 10924 dateProfile, 10925 nextDayThreshold 10926 ) { 10927 var extraArgs = []; 10928 for (var _i = 4; _i < arguments.length; _i++) { 10929 extraArgs[_i - 4] = arguments[_i]; 10930 } 10931 if (eventStore) { 10932 var rangeRes = sliceEventStore( 10933 eventStore, 10934 eventUiBases, 10935 computeActiveRange(dateProfile, Boolean(nextDayThreshold)), 10936 nextDayThreshold 10937 ); 10938 return { 10939 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 10940 fg: this.sliceEventRanges(rangeRes.fg, extraArgs), 10941 }; 10942 } else { 10943 return { bg: [], fg: [] }; 10944 } 10945 }; 10946 Slicer.prototype._sliceInteraction = function ( 10947 interaction, 10948 eventUiBases, 10949 dateProfile, 10950 nextDayThreshold 10951 ) { 10952 var extraArgs = []; 10953 for (var _i = 4; _i < arguments.length; _i++) { 10954 extraArgs[_i - 4] = arguments[_i]; 10955 } 10956 if (!interaction) { 10957 return null; 10958 } 10959 var rangeRes = sliceEventStore( 10960 interaction.mutatedEvents, 10961 eventUiBases, 10962 computeActiveRange(dateProfile, Boolean(nextDayThreshold)), 10963 nextDayThreshold 10964 ); 10965 return { 10966 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 10967 affectedInstances: interaction.affectedEvents.instances, 10968 isEvent: interaction.isEvent, 10969 }; 10970 }; 10971 Slicer.prototype._sliceDateSpan = function ( 10972 dateSpan, 10973 eventUiBases, 10974 context 10975 ) { 10976 var extraArgs = []; 10977 for (var _i = 3; _i < arguments.length; _i++) { 10978 extraArgs[_i - 3] = arguments[_i]; 10979 } 10980 if (!dateSpan) { 10981 return []; 10982 } 10983 var eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 10984 var segs = this.sliceRange.apply( 10985 this, 10986 __spreadArrays([dateSpan.range], extraArgs) 10987 ); 10988 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 10989 var seg = segs_1[_a]; 10990 seg.eventRange = eventRange; 10991 } 10992 return segs; 10993 }; 10994 /* 10995 "complete" seg means it has component and eventRange 10996 */ 10997 Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) { 10998 var segs = []; 10999 for ( 11000 var _i = 0, eventRanges_1 = eventRanges; 11001 _i < eventRanges_1.length; 11002 _i++ 11003 ) { 11004 var eventRange = eventRanges_1[_i]; 11005 segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs)); 11006 } 11007 return segs; 11008 }; 11009 /* 11010 "complete" seg means it has component and eventRange 11011 */ 11012 Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) { 11013 var dateRange = eventRange.range; 11014 // hack to make multi-day events that are being force-displayed as list-items to take up only one day 11015 if (this.forceDayIfListItem && eventRange.ui.display === "list-item") { 11016 dateRange = { 11017 start: dateRange.start, 11018 end: addDays(dateRange.start, 1), 11019 }; 11020 } 11021 var segs = this.sliceRange.apply( 11022 this, 11023 __spreadArrays([dateRange], extraArgs) 11024 ); 11025 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 11026 var seg = segs_2[_i]; 11027 seg.eventRange = eventRange; 11028 seg.isStart = eventRange.isStart && seg.isStart; 11029 seg.isEnd = eventRange.isEnd && seg.isEnd; 11030 } 11031 return segs; 11032 }; 11033 return Slicer; 11034 })(); 11035 /* 11036 for incorporating slotMinTime/slotMaxTime if appropriate 11037 TODO: should be part of DateProfile! 11038 TimelineDateProfile already does this btw 11039 */ 11040 function computeActiveRange(dateProfile, isComponentAllDay) { 11041 var range = dateProfile.activeRange; 11042 if (isComponentAllDay) { 11043 return range; 11044 } 11045 return { 11046 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 11047 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day 11048 }; 11049 } 11050 11051 var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 11052 var Scroller = /** @class */ (function (_super) { 11053 __extends(Scroller, _super); 11054 function Scroller() { 11055 var _this = (_super !== null && _super.apply(this, arguments)) || this; 11056 _this.handleEl = function (el) { 11057 _this.el = el; 11058 setRef(_this.props.elRef, el); 11059 }; 11060 return _this; 11061 } 11062 Scroller.prototype.render = function () { 11063 var props = this.props; 11064 var liquid = props.liquid, 11065 liquidIsAbsolute = props.liquidIsAbsolute; 11066 var isAbsolute = liquid && liquidIsAbsolute; 11067 var className = ["fc-scroller"]; 11068 if (liquid) { 11069 if (liquidIsAbsolute) { 11070 className.push("fc-scroller-liquid-absolute"); 11071 } else { 11072 className.push("fc-scroller-liquid"); 11073 } 11074 } 11075 return createElement( 11076 "div", 11077 { 11078 ref: this.handleEl, 11079 className: className.join(" "), 11080 style: { 11081 overflowX: props.overflowX, 11082 overflowY: props.overflowY, 11083 left: (isAbsolute && -(props.overcomeLeft || 0)) || "",
11084 right: (isAbsolute && -(props.overcomeRight || 0)) || "", 11085 bottom: (isAbsolute && -(props.overcomeBottom || 0)) || "", 11086 marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || "", 11087 marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || "", 11088 marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || "", 11089 maxHeight: props.maxHeight || "", 11090 }, 11091 }, 11092 props.children 11093 ); 11094 }; 11095 Scroller.prototype.needsXScrolling = function () { 11096 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 11097 return false; 11098 } 11099 // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers. 11100 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 11101 // inner-child margins and absolute positioning 11102 var el = this.el; 11103 var realClientWidth = 11104 this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 11105 var children = el.children; 11106 for (var i = 0; i < children.length; i++) { 11107 var childEl = children[i]; 11108 if (childEl.getBoundingClientRect().width > realClientWidth) { 11109 return true; 11110 } 11111 } 11112 return false; 11113 }; 11114 Scroller.prototype.needsYScrolling = function () { 11115 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 11116 return false; 11117 } 11118 // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers. 11119 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 11120 // inner-child margins and absolute positioning 11121 var el = this.el; 11122 var realClientHeight = 11123 this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 11124 var children = el.children; 11125 for (var i = 0; i < children.length; i++) { 11126 var childEl = children[i]; 11127 if (childEl.getBoundingClientRect().height > realClientHeight) { 11128 return true; 11129 } 11130 } 11131 return false; 11132 }; 11133 Scroller.prototype.getXScrollbarWidth = function () { 11134 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 11135 return 0; 11136 } else { 11137 return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important? 11138 } 11139 }; 11140 Scroller.prototype.getYScrollbarWidth = function () { 11141 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 11142 return 0; 11143 } else { 11144 return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important? 11145 } 11146 }; 11147 return Scroller; 11148 })(BaseComponent); 11149 11150 /* 11151 TODO: somehow infer OtherArgs from masterCallback? 11152 TODO: infer RefType from masterCallback if provided 11153 */ 11154 var RefMap = /** @class */ (function () { 11155 function RefMap(masterCallback) { 11156 var _this = this; 11157 this.masterCallback = masterCallback; 11158 this.currentMap = {}; 11159 this.depths = {}; 11160 this.callbackMap = {}; 11161 this.handleValue = function (val, key) { 11162 var _a = _this, 11163 depths = _a.depths, 11164 currentMap = _a.currentMap; 11165 var removed = false; 11166 var added = false; 11167 if (val !== null) { 11168 removed = key in currentMap; // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore 11169 currentMap[key] = val; 11170 depths[key] = (depths[key] || 0) + 1; 11171 added = true; 11172 } else if (--depths[key] === 0) { 11173 delete currentMap[key]; 11174 delete _this.callbackMap[key]; 11175 removed = true; 11176 } 11177 if (_this.masterCallback) { 11178 if (removed) { 11179 _this.masterCallback(null, String(key)); 11180 } 11181 if (added) { 11182 _this.masterCallback(val, String(key)); 11183 } 11184 } 11185 }; 11186 } 11187 RefMap.prototype.createRef = function (key) { 11188 var _this = this; 11189 var refCallback = this.callbackMap[key]; 11190 if (!refCallback) { 11191 refCallback = this.callbackMap[key] = function (val) { 11192 _this.handleValue(val, String(key)); 11193 }; 11194 } 11195 return refCallback; 11196 }; 11197 // TODO: check callers that don't care about order. should use getAll instead 11198 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 11199 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 11200 RefMap.prototype.collect = function (startIndex, endIndex, step) { 11201 return collectFromHash(this.currentMap, startIndex, endIndex, step); 11202 }; 11203 RefMap.prototype.getAll = function () { 11204 return hashValuesToArray(this.currentMap); 11205 }; 11206 return RefMap; 11207 })(); 11208 11209 function computeShrinkWidth(chunkEls) { 11210 var shrinkCells = findElements(chunkEls, ".fc-scrollgrid-shrink"); 11211 var largestWidth = 0; 11212 for ( 11213 var _i = 0, shrinkCells_1 = shrinkCells; 11214 _i < shrinkCells_1.length; 11215 _i++ 11216 ) { 11217 var shrinkCell = shrinkCells_1[_i]; 11218 largestWidth = Math.max( 11219 largestWidth, 11220 computeSmallestCellWidth(shrinkCell) 11221 ); 11222 } 11223 return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits 11224 } 11225 function getSectionHasLiquidHeight(props, sectionConfig) { 11226 return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well) 11227 } 11228 function getAllowYScrolling(props, sectionConfig) { 11229 return ( 11230 sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 11231 getSectionHasLiquidHeight(props, sectionConfig) 11232 ); // if the section is liquid height, it might condense enough to require scrollbars 11233 } 11234 // TODO: ONLY use `arg`. force out internal function to use same API 11235 function renderChunkContent(sectionConfig, chunkConfig, arg) { 11236 var expandRows = arg.expandRows; 11237 var content = 11238 typeof chunkConfig.content === "function" 11239 ? chunkConfig.content(arg) 11240 : createElement( 11241 "table", 11242 { 11243 className: [ 11244 chunkConfig.tableClassName, 11245 sectionConfig.syncRowHeights ? "fc-scrollgrid-sync-table" : "", 11246 ].join(" "), 11247 style: { 11248 minWidth: arg.tableMinWidth, 11249 width: arg.clientWidth, 11250 height: expandRows ? arg.clientHeight : "", // css `height` on a <table> serves as a min-height 11251 }, 11252 }, 11253 arg.tableColGroupNode, 11254 createElement( 11255 "tbody", 11256 {}, 11257 typeof chunkConfig.rowContent === "function" 11258 ? chunkConfig.rowContent(arg) 11259 : chunkConfig.rowContent 11260 ) 11261 ); 11262 return content; 11263 } 11264 function isColPropsEqual(cols0, cols1) { 11265 return isArraysEqual(cols0, cols1, isPropsEqual); 11266 } 11267 function renderMicroColGroup(cols, shrinkWidth) { 11268 var colNodes = []; 11269 /* 11270 for ColProps with spans, it would have been great to make a single <col span=""> 11271 HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans. 11272 SOLUTION: making individual <col> elements makes Chrome behave. 11273 */ 11274 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) { 11275 var colProps = cols_1[_i]; 11276 var span = colProps.span || 1; 11277 for (var i = 0; i < span; i++) {
11278 colNodes.push( 11279 createElement("col", { 11280 style: { 11281 width: 11282 colProps.width === "shrink" 11283 ? sanitizeShrinkWidth(shrinkWidth) 11284 : colProps.width || "", 11285 minWidth: colProps.minWidth || "", 11286 }, 11287 }) 11288 ); 11289 } 11290 } 11291 return createElement.apply( 11292 void 0, 11293 __spreadArrays(["colgroup", {}], colNodes) 11294 ); 11295 } 11296 function sanitizeShrinkWidth(shrinkWidth) { 11297 /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth 11298 4 accounts for 2 2-pixel borders. TODO: better solution? */ 11299 return shrinkWidth == null ? 4 : shrinkWidth; 11300 } 11301 function hasShrinkWidth(cols) { 11302 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) { 11303 var col = cols_2[_i]; 11304 if (col.width === "shrink") { 11305 return true; 11306 } 11307 } 11308 return false; 11309 } 11310 function getScrollGridClassNames(liquid, context) { 11311 var classNames = ["fc-scrollgrid", context.theme.getClass("table")]; 11312 if (liquid) { 11313 classNames.push("fc-scrollgrid-liquid"); 11314 } 11315 return classNames; 11316 } 11317 function getSectionClassNames(sectionConfig, wholeTableVGrow) { 11318 var classNames = [ 11319 "fc-scrollgrid-section", 11320 "fc-scrollgrid-section-" + sectionConfig.type, 11321 sectionConfig.className, // used? 11322 ]; 11323 if ( 11324 wholeTableVGrow && 11325 sectionConfig.liquid && 11326 sectionConfig.maxHeight == null 11327 ) { 11328 classNames.push("fc-scrollgrid-section-liquid"); 11329 } 11330 if (sectionConfig.isSticky) { 11331 classNames.push("fc-scrollgrid-section-sticky"); 11332 } 11333 return classNames; 11334 }
11335 function renderScrollShim(arg) { 11336 return createElement("div", { 11337 className: "fc-scrollgrid-sticky-shim", 11338 style: { 11339 width: arg.clientWidth, 11340 minWidth: arg.tableMinWidth, 11341 }, 11342 }); 11343 } 11344 function getStickyHeaderDates(options) { 11345 var stickyHeaderDates = options.stickyHeaderDates; 11346 if (stickyHeaderDates == null || stickyHeaderDates === "auto") { 11347 stickyHeaderDates = 11348 options.height === "auto" || options.viewHeight === "auto"; 11349 } 11350 return stickyHeaderDates; 11351 } 11352 function getStickyFooterScrollbar(options) { 11353 var stickyFooterScrollbar = options.stickyFooterScrollbar; 11354 if (stickyFooterScrollbar == null || stickyFooterScrollbar === "auto") { 11355 stickyFooterScrollbar = 11356 options.height === "auto" || options.viewHeight === "auto"; 11357 } 11358 return stickyFooterScrollbar; 11359 } 11360 11361 var SimpleScrollGrid = /** @class */ (function (_super) { 11362 __extends(SimpleScrollGrid, _super); 11363 function SimpleScrollGrid() { 11364 var _this = (_super !== null && _super.apply(this, arguments)) || this; 11365 _this.processCols = memoize(function (a) { 11366 return a; 11367 }, isColPropsEqual); // so we get same `cols` props every time 11368 _this.renderMicroColGroup = memoize(renderMicroColGroup); // yucky to memoize VNodes, but much more efficient for consumers 11369 _this.scrollerRefs = new RefMap(); 11370 _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this)); 11371 _this.state = { 11372 shrinkWidth: null, 11373 forceYScrollbars: false, 11374 scrollerClientWidths: {}, 11375 scrollerClientHeights: {}, 11376 }; 11377 // TODO: can do a really simple print-view. dont need to join rows 11378 _this.handleSizing = function () { 11379 _this.setState( 11380 __assign( 11381 { shrinkWidth: _this.computeShrinkWidth() }, 11382 _this.computeScrollerDims() 11383 ) 11384 ); 11385 }; 11386 return _this; 11387 } 11388 SimpleScrollGrid.prototype.render = function () { 11389 var _a = this, 11390 props = _a.props, 11391 state = _a.state, 11392 context = _a.context; 11393 var sectionConfigs = props.sections || []; 11394 var cols = this.processCols(props.cols); 11395 var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 11396 var classNames = getScrollGridClassNames(props.liquid, context); 11397 // TODO: make DRY 11398 var configCnt = sectionConfigs.length; 11399 var configI = 0; 11400 var currentConfig; 11401 var headSectionNodes = []; 11402 var bodySectionNodes = []; 11403 var footSectionNodes = []; 11404 while ( 11405 configI < configCnt && 11406 (currentConfig = sectionConfigs[configI]).type === "header" 11407 ) { 11408 headSectionNodes.push( 11409 this.renderSection(currentConfig, configI, microColGroupNode) 11410 ); 11411 configI++; 11412 } 11413 while ( 11414 configI < configCnt && 11415 (currentConfig = sectionConfigs[configI]).type === "body" 11416 ) { 11417 bodySectionNodes.push( 11418 this.renderSection(currentConfig, configI, microColGroupNode) 11419 ); 11420 configI++; 11421 } 11422 while ( 11423 configI < configCnt && 11424 (currentConfig = sectionConfigs[configI]).type === "footer" 11425 ) { 11426 footSectionNodes.push( 11427 this.renderSection(currentConfig, configI, microColGroupNode) 11428 ); 11429 configI++; 11430 } 11431 // firefox bug: when setting height on table and there is a thead or tfoot, 11432 // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524) 11433 // use getCanVGrowWithinCell as a way to detect table-stupid firefox. 11434 // if so, use a simpler dom structure, jam everything into a lone tbody. 11435 var isBuggy = !getCanVGrowWithinCell(); 11436 return createElement( 11437 "table", 11438 { 11439 className: classNames.join(" "), 11440 style: { height: props.height }, 11441 }, 11442 Boolean(!isBuggy && headSectionNodes.length) && 11443 createElement.apply( 11444 void 0, 11445 __spreadArrays(["thead", {}], headSectionNodes) 11446 ), 11447 Boolean(!isBuggy && bodySectionNodes.length) && 11448 createElement.apply( 11449 void 0, 11450 __spreadArrays(["tbody", {}
11450], bodySectionNodes) 11451 ), 11452 Boolean(!isBuggy && footSectionNodes.length) && 11453 createElement.apply( 11454 void 0, 11455 __spreadArrays(["tfoot", {}], footSectionNodes) 11456 ), 11457 isBuggy && 11458 createElement.apply( 11459 void 0, 11460 __spreadArrays( 11461 ["tbody", {}], 11462 headSectionNodes, 11463 bodySectionNodes, 11464 footSectionNodes 11465 ) 11466 ) 11467 ); 11468 }; 11469 SimpleScrollGrid.prototype.renderSection = function ( 11470 sectionConfig, 11471 sectionI, 11472 microColGroupNode 11473 ) { 11474 if ("outerContent" in sectionConfig) { 11475 return createElement( 11476 Fragment, 11477 { key: sectionConfig.key }, 11478 sectionConfig.outerContent 11479 ); 11480 } 11481 return createElement( 11482 "tr", 11483 { 11484 key: sectionConfig.key, 11485 className: getSectionClassNames( 11486 sectionConfig, 11487 this.props.liquid 11488 ).join(" "), 11489 }, 11490 this.renderChunkTd( 11491 sectionConfig, 11492 sectionI, 11493 microColGroupNode, 11494 sectionConfig.chunk 11495 ) 11496 ); 11497 }; 11498 SimpleScrollGrid.prototype.renderChunkTd = function ( 11499 sectionConfig, 11500 sectionI, 11501 microColGroupNode, 11502 chunkConfig 11503 ) { 11504 if ("outerContent" in chunkConfig) { 11505 return chunkConfig.outerContent; 11506 } 11507 var props = this.props; 11508 var _a = this.state, 11509 forceYScrollbars = _a.forceYScrollbars, 11510 scrollerClientWidths = _a.scrollerClientWidths, 11511 scrollerClientHeights = _a.scrollerClientHeights; 11512 var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config? 11513 var isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 11514 // for `!props.liquid` - is WHOLE scrollgrid natural height? 11515 // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars 11516 var overflowY = !props.liquid 11517 ? "visible" 11518 : forceYScrollbars 11519 ? "scroll" 11520 : !needsYScrolling 11521 ? "hidden" 11522 : "auto"; 11523 var content = renderChunkContent(sectionConfig, chunkConfig, { 11524 tableColGroupNode: microColGroupNode, 11525 tableMinWidth: "", 11526 clientWidth: 11527 scrollerClientWidths[sectionI] !== undefined 11528 ? scrollerClientWidths[sectionI] 11529 : null, 11530 clientHeight: 11531 scrollerClientHeights[sectionI] !== undefined 11532 ? scrollerClientHeights[sectionI] 11533 : null, 11534 expandRows: sectionConfig.expandRows, 11535 syncRowHeights: false, 11536 rowSyncHeights: [], 11537 reportRowHeightChange: function () {}, 11538 }); 11539 return createElement( 11540 "td", 11541 { ref: chunkConfig.elRef }, 11542 createElement( 11543 "div", 11544 { 11545 className: 11546 "fc-scroller-harness" + 11547 (isLiquid ? " fc-scroller-harness-liquid" : ""), 11548 }, 11549 createElement( 11550 Scroller, 11551 { 11552 ref: this.scrollerRefs.createRef(sectionI), 11553 elRef: this.scrollerElRefs.createRef(sectionI), 11554 overflowY: overflowY, 11555 overflowX: !props.liquid 11556 ? "visible" 11557 : "hidden" /* natural height? */, 11558 maxHeight: sectionConfig.maxHeight, 11559 liquid: isLiquid, 11560 liquidIsAbsolute: true /* because its within a harness */, 11561 }, 11562 content 11563 ) 11564 ) 11565 ); 11566 }; 11567 SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) { 11568 var sectionI = parseInt(key, 10); 11569 var chunkConfig = this.props.sections[sectionI].chunk; 11570 setRef(chunkConfig.scrollerElRef, scrollerEl); 11571 }; 11572 SimpleScrollGrid.prototype.componentDidMount = function () { 11573 this.handleSizing(); 11574 this.context.addResizeHandler(this.handleSizing); 11575 }; 11576 SimpleScrollGrid.prototype.componentDidUpdate = function () { 11577 // TODO: need better solution when state contains non-sizing things
11578 this.handleSizing(); 11579 }; 11580 SimpleScrollGrid.prototype.componentWillUnmount = function () { 11581 this.context.removeResizeHandler(this.handleSizing); 11582 }; 11583 SimpleScrollGrid.prototype.computeShrinkWidth = function () { 11584 return hasShrinkWidth(this.props.cols) 11585 ? computeShrinkWidth(this.scrollerElRefs.getAll()) 11586 : 0; 11587 }; 11588 SimpleScrollGrid.prototype.computeScrollerDims = function () { 11589 var scrollbarWidth = getScrollbarWidths(); 11590 var sectionCnt = this.props.sections.length; 11591 var _a = this, 11592 scrollerRefs = _a.scrollerRefs, 11593 scrollerElRefs = _a.scrollerElRefs; 11594 var forceYScrollbars = false; 11595 var scrollerClientWidths = {}; 11596 var scrollerClientHeights = {}; 11597 for (var sectionI = 0; sectionI < sectionCnt; sectionI++) { 11598 // along edge 11599 var scroller = scrollerRefs.currentMap[sectionI]; 11600 if (scroller && scroller.needsYScrolling()) { 11601 forceYScrollbars = true; 11602 break; 11603 } 11604 } 11605 for (var sectionI = 0; sectionI < sectionCnt; sectionI++) { 11606 // along edge 11607 var scrollerEl = scrollerElRefs.currentMap[sectionI]; 11608 if (scrollerEl) { 11609 var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders 11610 scrollerClientWidths[sectionI] = Math.floor( 11611 harnessEl.getBoundingClientRect().width - 11612 (forceYScrollbars 11613 ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future 11614 : 0) 11615 ); 11616 scrollerClientHeights[sectionI] = Math.floor( 11617 harnessEl.getBoundingClientRect().height // never has horizontal scrollbars 11618 ); 11619 } 11620 } 11621 return { 11622 forceYScrollbars: forceYScrollbars, 11623 scrollerClientWidths: scrollerClientWidths, 11624 scrollerClientHeights: scrollerClientHeights, 11625 }; 11626 }; 11627 return SimpleScrollGrid; 11628 })(BaseComponent); 11629 SimpleScrollGrid.addStateEquality({ 11630 scrollerClientWidths: isPropsEqual, 11631 scrollerClientHeights: isPropsEqual, 11632 }); 11633 11634 var EventRoot = /** @class */ (function (_super) { 11635 __extends(EventRoot, _super); 11636 function EventRoot() { 11637 var _this = (_super !== null && _super.apply(this, arguments)) || this; 11638 _this.elRef = createRef(); 11639 return _this; 11640 } 11641 EventRoot.prototype.render = function () { 11642 var _a = this, 11643 props = _a.props, 11644 context = _a.context; 11645 var options = context.options; 11646 var seg = props.seg; 11647 var eventRange = seg.eventRange; 11648 var ui = eventRange.ui; 11649 var hookProps = { 11650 event: new EventApi(context, eventRange.def, eventRange.instance), 11651 view: context.viewApi, 11652 timeText: props.timeText, 11653 textColor: ui.textColor, 11654 backgroundColor: ui.backgroundColor, 11655 borderColor: ui.borderColor, 11656 isDraggable: 11657 !props.disableDragging && computeSegDraggable(seg, context), 11658 isStartResizable: 11659 !props.disableResizing && computeSegStartResizable(seg, context), 11660 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 11661 isMirror: Boolean( 11662 props.isDragging || props.isResizing || props.isDateSelecting 11663 ), 11664 isStart: Boolean(seg.isStart), 11665 isEnd: Boolean(seg.isEnd), 11666 isPast: Boolean(props.isPast), 11667 isFuture: Boolean(props.isFuture), 11668 isToday: Boolean(props.isToday), 11669 isSelected: Boolean(props.isSelected), 11670 isDragging: Boolean(props.isDragging), 11671 isResizing: Boolean(props.isResizing), 11672 }; 11673 var standardClassNames = getEventClassNames(hookProps).concat( 11674 ui.classNames 11675 ); 11676 return createElement( 11677 RenderHook, 11678 { 11679 hookProps: hookProps, 11680 classNames: options.eventClassNames, 11681 content: options.eventContent, 11682 defaultContent: props.defaultContent, 11683 didMount: options.eventDidMount, 11684 willUnmount: options.eventWillUnmount, 11685 elRef: this.elRef, 11686 }, 11687 function (rootElRef, customClassNames, innerElRef, innerContent) { 11688 return props.children( 11689 rootElRef,
11690 standardClassNames.concat(customClassNames), 11691 innerElRef, 11692 innerContent, 11693 hookProps 11694 ); 11695 } 11696 ); 11697 }; 11698 EventRoot.prototype.componentDidMount = function () { 11699 setElSeg(this.elRef.current, this.props.seg); 11700 }; 11701 /* 11702 need to re-assign seg to the element if seg changes, even if the element is the same 11703 */ 11704 EventRoot.prototype.componentDidUpdate = function (prevProps) { 11705 var seg = this.props.seg; 11706 if (seg !== prevProps.seg) { 11707 setElSeg(this.elRef.current, seg); 11708 } 11709 }; 11710 return EventRoot; 11711 })(BaseComponent); 11712 11713 // should not be a purecomponent 11714 var StandardEvent = /** @class */ (function (_super) { 11715 __extends(StandardEvent, _super); 11716 function StandardEvent() { 11717 return (_super !== null && _super.apply(this, arguments)) || this; 11718 } 11719 StandardEvent.prototype.render = function () { 11720 var _a = this, 11721 props = _a.props, 11722 context = _a.context; 11723 var seg = props.seg; 11724 var timeFormat = 11725 context.options.eventTimeFormat || props.defaultTimeFormat; 11726 var timeText = buildSegTimeText( 11727 seg, 11728 timeFormat, 11729 context, 11730 props.defaultDisplayEventTime, 11731 props.defaultDisplayEventEnd 11732 ); 11733 return createElement( 11734 EventRoot, 11735 { 11736 seg: seg, 11737 timeText: timeText, 11738 disableDragging: props.disableDragging, 11739 disableResizing: props.disableResizing, 11740 defaultContent: props.defaultContent || renderInnerContent, 11741 isDragging: props.isDragging, 11742 isResizing: props.isResizing, 11743 isDateSelecting: props.isDateSelecting, 11744 isSelected: props.isSelected, 11745 isPast: props.isPast, 11746 isFuture: props.isFuture, 11747 isToday: props.isToday, 11748 }, 11749 function (rootElRef, classNames, innerElRef, innerContent, hookProps) { 11750 return createElement( 11751 "a", 11752 __assign( 11753 { 11754 className: props.extraClassNames.concat(classNames).join(" "), 11755 style: { 11756 borderColor: hookProps.borderColor, 11757 backgroundColor: hookProps.backgroundColor, 11758 }, 11759 ref: rootElRef, 11760 }, 11761 getSegAnchorAttrs(seg) 11762 ), 11763 createElement( 11764 "div", 11765 { 11766 className: "fc-event-main", 11767 ref: innerElRef, 11768 style: { color: hookProps.textColor }, 11769 }, 11770 innerContent 11771 ), 11772 hookProps.isStartResizable && 11773 createElement("div", { 11774 className: "fc-event-resizer fc-event-resizer-start", 11775 }), 11776 hookProps.isEndResizable && 11777 createElement("div", { 11778 className: "fc-event-resizer fc-event-resizer-end", 11779 }) 11780 ); 11781 } 11782 ); 11783 }; 11784 return StandardEvent; 11785 })(BaseComponent); 11786 function renderInnerContent(innerProps) { 11787 return createElement( 11788 "div", 11789 { className: "fc-event-main-frame" }, 11790 innerProps.timeText && 11791 createElement( 11792 "div", 11793 { className: "fc-event-time" }, 11794 innerProps.timeText 11795 ), 11796 createElement( 11797 "div", 11798 { className: "fc-event-title-container" }, 11799 createElement( 11800 "div", 11801 { className: "fc-event-title fc-sticky" }, 11802 innerProps.event.title || createElement(Fragment, null, "\u00A0") 11803 ) 11804 ) 11805 ); 11806 } 11807 function getSegAnchorAttrs(seg) { 11808 var url = seg.eventRange.def.url; 11809 return url ? { href: url } : {}; 11810 } 11811 11812 var NowIndicatorRoot = function (props) { 11813 return createElement(ViewContextType.Consumer, null, function (context) { 11814 var options = context.options; 11815 var hookProps = { 11816 isAxis: props.isAxis, 11817 date: context.dateEnv.toDate(props.date), 11818 view: context.viewApi, 11819 }; 11820 return createElement( 11821 RenderHook, 11822 { 11823 hookProps: hookProps, 11824 classNames: options.nowIndicatorClassNames, 11825 content: options.nowIndicatorContent, 11826 didMount: options.nowIndicatorDidMount, 11827 willUnmount: options.nowIndicatorWillUnmount, 11828 }, 11829 props.children 11830 ); 11831 }); 11832 }; 11833
11834 var DAY_NUM_FORMAT = createFormatter({ day: "numeric" }); 11835 var DayCellRoot = /** @class */ (function (_super) { 11836 __extends(DayCellRoot, _super); 11837 function DayCellRoot() { 11838 var _this = (_super !== null && _super.apply(this, arguments)) || this; 11839 _this.refineHookProps = memoizeObjArg(refineHookProps); 11840 _this.normalizeClassNames = buildClassNameNormalizer(); 11841 return _this; 11842 } 11843 DayCellRoot.prototype.render = function () { 11844 var _a = this, 11845 props = _a.props, 11846 context = _a.context; 11847 var options = context.options; 11848 var hookProps = this.refineHookProps({ 11849 date: props.date, 11850 dateProfile: props.dateProfile, 11851 todayRange: props.todayRange, 11852 showDayNumber: props.showDayNumber, 11853 extraProps: props.extraHookProps, 11854 viewApi: context.viewApi, 11855 dateEnv: context.dateEnv, 11856 }); 11857 var classNames = getDayClassNames(hookProps, context.theme).concat( 11858 hookProps.isDisabled 11859 ? [] // don't use custom classNames if disabled 11860 : this.normalizeClassNames(options.dayCellClassNames, hookProps) 11861 ); 11862 var dataAttrs = hookProps.isDisabled 11863 ? {} 11864 : { 11865 "data-date": formatDayString(props.date), 11866 }; 11867 return createElement( 11868 MountHook, 11869 { 11870 hookProps: hookProps, 11871 didMount: options.dayCellDidMount, 11872 willUnmount: options.dayCellWillUnmount, 11873 elRef: props.elRef, 11874 }, 11875 function (rootElRef) { 11876 return props.children( 11877 rootElRef, 11878 classNames, 11879 dataAttrs, 11880 hookProps.isDisabled 11881 ); 11882 } 11883 ); 11884 }; 11885 return DayCellRoot; 11886 })(BaseComponent); 11887 var DayCellContent = /** @class */ (function (_super) { 11888 __extends(DayCellContent, _super); 11889 function DayCellContent() { 11890 return (_super !== null && _super.apply(this, arguments)) || this; 11891 } 11892 DayCellContent.prototype.render = function () { 11893 var _a = this, 11894 props = _a.props, 11895 context = _a.context; 11896 var options = context.options; 11897 var hookProps = refineHookProps({ 11898 date: props.date, 11899 dateProfile: props.dateProfile, 11900 todayRange: props.todayRange, 11901 showDayNumber: props.showDayNumber, 11902 extraProps: props.extraHookProps, 11903 viewApi: context.viewApi, 11904 dateEnv: context.dateEnv, 11905 }); 11906 return createElement( 11907 ContentHook, 11908 { 11909 hookProps: hookProps, 11910 content: options.dayCellContent, 11911 defaultContent: props.defaultContent, 11912 }, 11913 props.children 11914 ); 11915 }; 11916 return DayCellContent; 11917 })(BaseComponent); 11918 function refineHookProps(raw) { 11919 var date = raw.date, 11920 dateEnv = raw.dateEnv; 11921 var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile); 11922 return __assign( 11923 __assign( 11924 __assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), 11925 { 11926 dayNumberText: raw.showDayNumber 11927 ? dateEnv.format(date, DAY_NUM_FORMAT) 11928 : "", 11929 } 11930 ), 11931 raw.extraProps 11932 ); 11933 } 11934 11935 function renderFill(fillType) { 11936 return createElement("div", { className: "fc-" + fillType }); 11937 } 11938 var BgEvent = function (props) { 11939 return createElement( 11940 EventRoot, 11941 { 11942 defaultContent: renderInnerContent$1, 11943 seg: props.seg /* uselesss i think */, 11944 timeText: "" /* weird */, 11945 disableDragging: true, 11946 disableResizing: true, 11947 isDragging: false, 11948 isResizing: false, 11949 isDateSelecting: false, 11950 isSelected: false, 11951 isPast: props.isPast, 11952 isFuture: props.isFuture, 11953 isToday: props.isToday, 11954 }, 11955 function (rootElRef, classNames, innerElRef, innerContent, hookProps) { 11956 return createElement( 11957 "div", 11958 { 11959 ref: rootElRef, 11960 className: ["fc-bg-event"].concat(classNames).join(" "), 11961 style: { 11962 backgroundColor: hookProps.backgroundColor, 11963 }, 11964 }, 11965 innerContent 11966 ); 11967 } 11968 ); 11969 }; 11970 function renderInnerContent$1(props) { 11971 var title = props.event.title; 11972 return ( 11973 title && 11974 createElement("div", { className: "fc-event-title" }, props.event.title) 11975 ); 11976 } 11977 11978 var WeekNumberRoot = function (props) { 11979 return createElement(ViewContextType.Consumer, null, function (context) { 11980 var dateEnv = context.dateEnv, 11981 options = context.options; 11982 var date = props.date; 11983 var format = options.weekNumberFormat || props.defaultFormat; 11984 var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well? 11985 var text = dateEnv.format(date, format); 11986 var hookProps = { num: num, text: text, date: date }; 11987 return createElement( 11988 RenderHook, 11989 { 11990 hookProps: hookProps, 11991 classNames: options.weekNumberClassNames, 11992 content: options.weekNumberContent, 11993 defaultContent: renderInner$1, 11994 didMount: options.weekNumberDidMount, 11995 willUnmount: options.weekNumberWillUnmount, 11996 }, 11997 props.children 11998 ); 11999 }); 12000 }; 12001 function renderInner$1(innerProps) { 12002 return innerProps.text; 12003 } 12004 12005 // exports 12006 // -------------------------------------------------------------------------------------------------- 12007 var version = "<%= version %>"; // important to type it, so .d.ts has generic string 12008 12009 var Calendar = /** @class */ (function (_super) { 12010 __extends(Calendar, _super); 12011 function Calendar(el, optionOverrides) { 12012 if (optionOverrides === void 0) { 12013 optionOverrides = {}; 12014 } 12015 var _this = _super.call(this) || this; 12016 _this.isRendering = false;
12017 _this.isRendered = false; 12018 _this.currentClassNames = []; 12019 _this.customContentRenderId = 0; // will affect custom generated classNames? 12020 _this.handleAction = function (action) { 12021 // actions we know we want to render immediately 12022 switch (action.type) { 12023 case "SET_EVENT_DRAG": 12024 case "SET_EVENT_RESIZE": 12025 _this.renderRunner.tryDrain(); 12026 } 12027 }; 12028 _this.handleData = function (data) { 12029 _this.currentData = data; 12030 _this.renderRunner.request(data.calendarOptions.rerenderDelay); 12031 }; 12032 _this.handleRenderRequest = function () { 12033 if (_this.isRendering) { 12034 _this.isRendered = true; 12035 var currentData_1 = _this.currentData; 12036 render( 12037 createElement( 12038 CalendarRoot, 12039 { 12040 options: currentData_1.calendarOptions, 12041 theme: currentData_1.theme, 12042 emitter: currentData_1.emitter, 12043 }, 12044 function (classNames, height, isHeightAuto, forPrint) { 12045 _this.setClassNames(classNames); 12046 _this.setHeight(height); 12047 return createElement( 12048 CustomContentRenderContext.Provider, 12049 { value: _this.customContentRenderId }, 12050 createElement( 12051 CalendarContent, 12052 __assign( 12053 { isHeightAuto: isHeightAuto, forPrint: forPrint }, 12054 currentData_1 12055 ) 12056 ) 12057 ); 12058 } 12059 ), 12060 _this.el 12061 ); 12062 } else if (_this.isRendered) { 12063 _this.isRendered = false; 12064 render(null, _this.el); 12065 _this.setClassNames([]); 12066 _this.setHeight(""); 12067 } 12068 flushToDom$1(); 12069 }; 12070 _this.el = el; 12071 _this.renderRunner = new DelayedRunner(_this.handleRenderRequest); 12072 new CalendarDataManager({ 12073 optionOverrides: optionOverrides, 12074 calendarApi: _this, 12075 onAction: _this.handleAction, 12076 onData: _this.handleData, 12077 }); 12078 return _this; 12079 } 12080 Object.defineProperty(Calendar.prototype, "view", { 12081 get: function () { 12082 return this.currentData.viewApi; 12083 }, // for public API 12084 enumerable: false, 12085 configurable: true, 12086 }); 12087 Calendar.prototype.render = function () { 12088 var wasRendering = this.isRendering; 12089 if (!wasRendering) { 12090 this.isRendering = true; 12091 } else { 12092 this.customContentRenderId++; 12093 } 12094 this.renderRunner.request(); 12095 if (wasRendering) { 12096 this.updateSize(); 12097 } 12098 }; 12099 Calendar.prototype.destroy = function () { 12100 if (this.isRendering) { 12101 this.isRendering = false; 12102 this.renderRunner.request(); 12103 } 12104 }; 12105 Calendar.prototype.updateSize = function () { 12106 _super.prototype.updateSize.call(this); 12107 flushToDom$1(); 12108 }; 12109 Calendar.prototype.batchRendering = function (func) { 12110 this.renderRunner.pause("batchRendering"); 12111 func(); 12112 this.renderRunner.resume("batchRendering"); 12113 }; 12114 Calendar.prototype.pauseRendering = function () { 12115 this.renderRunner.pause("pauseRendering"); 12116 }; 12117 Calendar.prototype.resumeRendering = function () { 12118 this.renderRunner.resume("pauseRendering", true); 12119 }; 12120 Calendar.prototype.resetOptions = function (optionOverrides, append) { 12121 this.currentDataManager.resetOptions(optionOverrides, append); 12122 }; 12123 Calendar.prototype.setClassNames = function (classNames) { 12124 if (!isArraysEqual(classNames, this.currentClassNames)) { 12125 var classList = this.el.classList; 12126 for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) { 12127 var className = _a[_i]; 12128 classList.remove(className); 12129 } 12130 for ( 12131 var _b = 0, classNames_1 = classNames; 12132 _b < classNames_1.length; 12133 _b++ 12134 ) { 12135 var className = classNames_1[_b]; 12136 classList.add(className); 12137 } 12138 this.currentClassNames = classNames; 12139 } 12140 }; 12141 Calendar.prototype.setHeight = function (height) { 12142 applyStyleProp(this.el, "height", height); 12143 }; 12144 return Calendar; 12145 })(CalendarApi); 12146 12147 config.touchMouseIgnoreWait = 500; 12148 var ignoreMouseDepth = 0; 12149 var listenerCnt = 0; 12150 var isWindowTouchMoveCancelled = false;
12151 /* 12152 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 12153 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 12154 12155 Also, tracks if there was touch-scrolling. 12156 Also, can prevent touch-scrolling from happening. 12157 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 12158 12159 emits: 12160 - pointerdown 12161 - pointermove 12162 - pointerup 12163 */ 12164 var PointerDragging = /** @class */ (function () { 12165 function PointerDragging(containerEl) { 12166 var _this = this; 12167 this.subjectEl = null; 12168 // options that can be directly assigned by caller 12169 this.selector = ""; // will cause subjectEl in all emitted events to be this element 12170 this.handleSelector = ""; 12171 this.shouldIgnoreMove = false; 12172 this.shouldWatchScroll = true; // for simulating pointermove on scroll 12173 // internal states 12174 this.isDragging = false; 12175 this.isTouchDragging = false; 12176 this.wasTouchScroll = false; 12177 // Mouse 12178 // ---------------------------------------------------------------------------------------------------- 12179 this.handleMouseDown = function (ev) { 12180 if ( 12181 !_this.shouldIgnoreMouse() && 12182 isPrimaryMouseButton(ev) && 12183 _this.tryStart(ev) 12184 ) { 12185 var pev = _this.createEventFromMouse(ev, true); 12186 _this.emitter.trigger("pointerdown", pev); 12187 _this.initScrollWatch(pev); 12188 if (!_this.shouldIgnoreMove) { 12189 document.addEventListener("mousemove", _this.handleMouseMove); 12190 } 12191 document.addEventListener("mouseup", _this.handleMouseUp); 12192 } 12193 }; 12194 this.handleMouseMove = function (ev) { 12195 var pev = _this.createEventFromMouse(ev); 12196 _this.recordCoords(pev); 12197 _this.emitter.trigger("pointermove", pev); 12198 }; 12199 this.handleMouseUp = function (ev) { 12200 document.removeEventListener("mousemove", _this.handleMouseMove); 12201 document.removeEventListener("mouseup", _this.handleMouseUp); 12202 _this.emitter.trigger("pointerup", _this.createEventFromMouse(ev)); 12203 _this.cleanup(); // call last so that pointerup has access to props 12204 }; 12205 // Touch 12206 // ---------------------------------------------------------------------------------------------------- 12207 this.handleTouchStart = function (ev) { 12208 if (_this.tryStart(ev)) { 12209 _this.isTouchDragging = true; 12210 var pev = _this.createEventFromTouch(ev, true); 12211 _this.emitter.trigger("pointerdown", pev); 12212 _this.initScrollWatch(pev); 12213 // unlike mouse, need to attach to target, not document 12214 // https://stackoverflow.com/a/45760014 12215 var targetEl = ev.target; 12216 if (!_this.shouldIgnoreMove) { 12217 targetEl.addEventListener("touchmove", _this.handleTouchMove); 12218 } 12219 targetEl.addEventListener("touchend", _this.handleTouchEnd); 12220 targetEl.addEventListener("touchcancel", _this.handleTouchEnd); // treat it as a touch end 12221 // attach a handler to get called when ANY scroll action happens on the page. 12222 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 12223 // http://stackoverflow.com/a/32954565/96342 12224 window.addEventListener( 12225 "scroll", 12226 _this.handleTouchScroll, 12227 true // useCapture 12228 ); 12229 } 12230 }; 12231 this.handleTouchMove = function (ev) { 12232 var pev = _this.createEventFromTouch(ev); 12233 _this.recordCoords(pev); 12234 _this.emitter.trigger("pointermove", pev); 12235 }; 12236 this.handleTouchEnd = function (ev) { 12237 if (_this.isDragging) { 12238 // done to guard against touchend followed by touchcancel 12239 var targetEl = ev.target; 12240 targetEl.removeEventListener("touchmove", _this.handleTouchMove); 12241 targetEl.removeEventListener("touchend", _this.handleTouchEnd); 12242 targetEl.removeEventListener("touchcancel", _this.handleTouchEnd); 12243 window.removeEventListener("scroll", _this.handleTouchScroll, true); // useCaptured=true 12244 _this.emitter.trigger("pointerup", _this.createEventFromTouch(ev)); 12245 _this.cleanup(); // call last so that pointerup has access to props 12246 _this.isTouchDragging = false;
12247 startIgnoringMouse(); 12248 } 12249 }; 12250 this.handleTouchScroll = function () { 12251 _this.wasTouchScroll = true; 12252 }; 12253 this.handleScroll = function (ev) { 12254 if (!_this.shouldIgnoreMove) { 12255 var pageX = window.pageXOffset - _this.prevScrollX + _this.prevPageX; 12256 var pageY = window.pageYOffset - _this.prevScrollY + _this.prevPageY; 12257 _this.emitter.trigger("pointermove", { 12258 origEvent: ev, 12259 isTouch: _this.isTouchDragging, 12260 subjectEl: _this.subjectEl, 12261 pageX: pageX, 12262 pageY: pageY, 12263 deltaX: pageX - _this.origPageX, 12264 deltaY: pageY - _this.origPageY, 12265 }); 12266 } 12267 }; 12268 this.containerEl = containerEl; 12269 this.emitter = new Emitter(); 12270 containerEl.addEventListener("mousedown", this.handleMouseDown); 12271 containerEl.addEventListener("touchstart", this.handleTouchStart, { 12272 passive: true, 12273 }); 12274 listenerCreated(); 12275 } 12276 PointerDragging.prototype.destroy = function () { 12277 this.containerEl.removeEventListener("mousedown", this.handleMouseDown); 12278 this.containerEl.removeEventListener( 12279 "touchstart", 12280 this.handleTouchStart, 12281 { passive: true } 12282 ); 12283 listenerDestroyed(); 12284 }; 12285 PointerDragging.prototype.tryStart = function (ev) { 12286 var subjectEl = this.querySubjectEl(ev); 12287 var downEl = ev.target; 12288 if ( 12289 subjectEl && 12290 (!this.handleSelector || elementClosest(downEl, this.handleSelector)) 12291 ) { 12292 this.subjectEl = subjectEl; 12293 this.isDragging = true; // do this first so cancelTouchScroll will work 12294 this.wasTouchScroll = false; 12295 return true; 12296 } 12297 return false; 12298 }; 12299 PointerDragging.prototype.cleanup = function () { 12300 isWindowTouchMoveCancelled = false; 12301 this.isDragging = false; 12302 this.subjectEl = null; 12303 // keep wasTouchScroll around for later access 12304 this.destroyScrollWatch(); 12305 }; 12306 PointerDragging.prototype.querySubjectEl = function (ev) { 12307 if (this.selector) { 12308 return elementClosest(ev.target, this.selector); 12309 } else { 12310 return this.containerEl; 12311 } 12312 }; 12313 PointerDragging.prototype.shouldIgnoreMouse = function () { 12314 return ignoreMouseDepth || this.isTouchDragging; 12315 }; 12316 // can be called by user of this class, to cancel touch-based scrolling for the current drag 12317 PointerDragging.prototype.cancelTouchScroll = function () { 12318 if (this.isDragging) { 12319 isWindowTouchMoveCancelled = true; 12320 } 12321 }; 12322 // Scrolling that simulates pointermoves 12323 // ---------------------------------------------------------------------------------------------------- 12324 PointerDragging.prototype.initScrollWatch = function (ev) { 12325 if (this.shouldWatchScroll) { 12326 this.recordCoords(ev); 12327 window.addEventListener("scroll", this.handleScroll, true); // useCapture=true 12328 } 12329 }; 12330 PointerDragging.prototype.recordCoords = function (ev) { 12331 if (this.shouldWatchScroll) { 12332 this.prevPageX = ev.pageX; 12333 this.prevPageY = ev.pageY; 12334 this.prevScrollX = window.pageXOffset; 12335 this.prevScrollY = window.pageYOffset; 12336 } 12337 }; 12338 PointerDragging.prototype.destroyScrollWatch = function () { 12339 if (this.shouldWatchScroll) { 12340 window.removeEventListener("scroll", this.handleScroll, true); // useCaptured=true 12341 } 12342 }; 12343 // Event Normalization 12344 // ---------------------------------------------------------------------------------------------------- 12345 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 12346 var deltaX = 0; 12347 var deltaY = 0; 12348 // TODO: repeat code 12349 if (isFirst) { 12350 this.origPageX = ev.pageX; 12351 this.origPageY = ev.pageY; 12352 } else { 12353 deltaX = ev.pageX - this.origPageX; 12354 deltaY = ev.pageY - this.origPageY; 12355 } 12356 return { 12357 origEvent: ev, 12358 isTouch: false, 12359 subjectEl: this.subjectEl, 12360 pageX: ev.pageX, 12361 pageY: ev.pageY, 12362 deltaX: deltaX, 12363 deltaY: deltaY, 12364 }; 12365 }; 12366 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 12367 var touches = ev.touches; 12368 var pageX; 12369 var pageY; 12370 var deltaX = 0; 12371 var deltaY = 0; 12372 // if touch coords available, prefer, 12373 // because FF would give bad ev.pageX ev.pageY 12374 if (touches && touches.length) { 12375 pageX = touches[0].pageX; 12376 pageY = touches[0].pageY; 12377 } else { 12378 pageX = ev.pageX; 12379 pageY = ev.pageY; 12380 } 12381 // TODO: repeat code 12382 if (isFirst) { 12383 this.origPageX = pageX; 12384 this.origPageY = pageY; 12385 } else { 12386 deltaX = pageX - this.origPageX; 12387 deltaY = pageY - this.origPageY; 12388 } 12389 return { 12390 origEvent: ev, 12391 isTouch: true, 12392 subjectEl: this.subjectEl, 12393 pageX: pageX, 12394 pageY: pageY, 12395 deltaX: deltaX, 12396 deltaY: deltaY, 12397 }; 12398 }; 12399 return PointerDragging; 12400 })();
12401 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 12402 function isPrimaryMouseButton(ev) { 12403 return ev.button === 0 && !ev.ctrlKey; 12404 } 12405 // Ignoring fake mouse events generated by touch 12406 // ---------------------------------------------------------------------------------------------------- 12407 function startIgnoringMouse() { 12408 ignoreMouseDepth++; 12409 setTimeout(function () { 12410 ignoreMouseDepth--; 12411 }, config.touchMouseIgnoreWait); 12412 } 12413 // We want to attach touchmove as early as possible for Safari 12414 // ---------------------------------------------------------------------------------------------------- 12415 function listenerCreated() { 12416 if (!listenerCnt++) { 12417 window.addEventListener("touchmove", onWindowTouchMove, { 12418 passive: false, 12419 }); 12420 } 12421 } 12422 function listenerDestroyed() { 12423 if (!--listenerCnt) { 12424 window.removeEventListener("touchmove", onWindowTouchMove, { 12425 passive: false, 12426 }); 12427 } 12428 } 12429 function onWindowTouchMove(ev) { 12430 if (isWindowTouchMoveCancelled) { 12431 ev.preventDefault(); 12432 } 12433 } 12434 12435 /* 12436 An effect in which an element follows the movement of a pointer across the screen. 12437 The moving element is a clone of some other element. 12438 Must call start + handleMove + stop. 12439 */ 12440 var ElementMirror = /** @class */ (function () { 12441 function ElementMirror() { 12442 this.isVisible = false; // must be explicitly enabled 12443 this.sourceEl = null; 12444 this.mirrorEl = null; 12445 this.sourceElRect = null; // screen coords relative to viewport 12446 // options that can be set directly by caller 12447 this.parentNode = document.body; 12448 this.zIndex = 9999; 12449 this.revertDuration = 0; 12450 } 12451 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 12452 this.sourceEl = sourceEl; 12453 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 12454 this.origScreenX = pageX - window.pageXOffset; 12455 this.origScreenY = pageY - window.pageYOffset; 12456 this.deltaX = 0; 12457 this.deltaY = 0; 12458 this.updateElPosition(); 12459 }; 12460 ElementMirror.prototype.handleMove = function (pageX, pageY) { 12461 this.deltaX = pageX - window.pageXOffset - this.origScreenX; 12462 this.deltaY = pageY - window.pageYOffset - this.origScreenY; 12463 this.updateElPosition(); 12464 }; 12465 // can be called before start 12466 ElementMirror.prototype.setIsVisible = function (bool) { 12467 if (bool) { 12468 if (!this.isVisible) { 12469 if (this.mirrorEl) { 12470 this.mirrorEl.style.display = ""; 12471 } 12472 this.isVisible = bool; // needs to happen before updateElPosition 12473 this.updateElPosition(); // because was not updating the position while invisible 12474 } 12475 } else { 12476 if (this.isVisible) { 12477 if (this.mirrorEl) { 12478 this.mirrorEl.style.display = "none"; 12479 } 12480 this.isVisible = bool; 12481 } 12482 } 12483 }; 12484 // always async 12485 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 12486 var _this = this; 12487 var done = function () { 12488 _this.cleanup(); 12489 callback(); 12490 }; 12491 if ( 12492 needsRevertAnimation && 12493 this.mirrorEl && 12494 this.isVisible && 12495 this.revertDuration && // if 0, transition won't work 12496 (this.deltaX || this.deltaY) // if same coords, transition won't work 12497 ) { 12498 this.doRevertAnimation(done, this.revertDuration); 12499 } else { 12500 setTimeout(done, 0); 12501 } 12502 }; 12503 ElementMirror.prototype.doRevertAnimation = function ( 12504 callback, 12505 revertDuration 12506 ) { 12507 var mirrorEl = this.mirrorEl; 12508 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 12509 mirrorEl.style.transition = 12510 "top " + revertDuration + "ms," + "left " + revertDuration + "ms"; 12511 applyStyle(mirrorEl, { 12512 left: finalSourceElRect.left, 12513 top: finalSourceElRect.top, 12514 }); 12515 whenTransitionDone(mirrorEl, function () { 12516 mirrorEl.style.transition = ""; 12517 callback(); 12518 }); 12519 }; 12520 ElementMirror.prototype.cleanup = function () { 12521 if (this.mirrorEl) { 12522 removeElement(this.mirrorEl); 12523 this.mirrorEl = null; 12524 } 12525 this.sourceEl = null; 12526 }; 12527 ElementMirror.prototype.updateElPosition = function () { 12528 if (this.sourceEl && this.isVisible) { 12529 applyStyle(this.getMirrorEl(), { 12530 left: this.sourceElRect.left + this.deltaX,
12531 top: this.sourceElRect.top + this.deltaY, 12532 }); 12533 } 12534 }; 12535 ElementMirror.prototype.getMirrorEl = function () { 12536 var sourceElRect = this.sourceElRect; 12537 var mirrorEl = this.mirrorEl; 12538 if (!mirrorEl) { 12539 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 12540 // we don't want long taps or any mouse interaction causing selection/menus. 12541 // would use preventSelection(), but that prevents selectstart, causing problems. 12542 mirrorEl.classList.add("fc-unselectable"); 12543 mirrorEl.classList.add("fc-event-dragging"); 12544 applyStyle(mirrorEl, { 12545 position: "fixed", 12546 zIndex: this.zIndex, 12547 visibility: "", 12548 boxSizing: "border-box", 12549 width: sourceElRect.right - sourceElRect.left, 12550 height: sourceElRect.bottom - sourceElRect.top, 12551 right: "auto", 12552 bottom: "auto", 12553 margin: 0, 12554 }); 12555 this.parentNode.appendChild(mirrorEl); 12556 } 12557 return mirrorEl; 12558 }; 12559 return ElementMirror; 12560 })(); 12561 12562 /* 12563 Is a cache for a given element's scroll information (all the info that ScrollController stores) 12564 in addition the "client rectangle" of the element.. the area within the scrollbars. 12565 12566 The cache can be in one of two modes: 12567 - doesListening:false - ignores when the container is scrolled by someone else 12568 - doesListening:true - watch for scrolling and update the cache 12569 */ 12570 var ScrollGeomCache = /** @class */ (function (_super) { 12571 __extends(ScrollGeomCache, _super); 12572 function ScrollGeomCache(scrollController, doesListening) { 12573 var _this = _super.call(this) || this; 12574 _this.handleScroll = function () { 12575 _this.scrollTop = _this.scrollController.getScrollTop(); 12576 _this.scrollLeft = _this.scrollController.getScrollLeft(); 12577 _this.handleScrollChange(); 12578 }; 12579 _this.scrollController = scrollController; 12580 _this.doesListening = doesListening; 12581 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 12582 _this.scrollLeft = _this.origScrollLeft = 12583 scrollController.getScrollLeft();
12584 _this.scrollWidth = scrollController.getScrollWidth(); 12585 _this.scrollHeight = scrollController.getScrollHeight(); 12586 _this.clientWidth = scrollController.getClientWidth(); 12587 _this.clientHeight = scrollController.getClientHeight(); 12588 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 12589 if (_this.doesListening) { 12590 _this.getEventTarget().addEventListener("scroll", _this.handleScroll); 12591 } 12592 return _this; 12593 } 12594 ScrollGeomCache.prototype.destroy = function () { 12595 if (this.doesListening) { 12596 this.getEventTarget().removeEventListener("scroll", this.handleScroll); 12597 } 12598 }; 12599 ScrollGeomCache.prototype.getScrollTop = function () { 12600 return this.scrollTop; 12601 }; 12602 ScrollGeomCache.prototype.getScrollLeft = function () { 12603 return this.scrollLeft; 12604 }; 12605 ScrollGeomCache.prototype.setScrollTop = function (top) { 12606 this.scrollController.setScrollTop(top); 12607 if (!this.doesListening) { 12608 // we are not relying on the element to normalize out-of-bounds scroll values 12609 // so we need to sanitize ourselves 12610 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 12611 this.handleScrollChange(); 12612 } 12613 }; 12614 ScrollGeomCache.prototype.setScrollLeft = function (top) { 12615 this.scrollController.setScrollLeft(top); 12616 if (!this.doesListening) { 12617 // we are not relying on the element to normalize out-of-bounds scroll values 12618 // so we need to sanitize ourselves 12619 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 12620 this.handleScrollChange(); 12621 } 12622 }; 12623 ScrollGeomCache.prototype.getClientWidth = function () { 12624 return this.clientWidth; 12625 }; 12626 ScrollGeomCache.prototype.getClientHeight = function () { 12627 return this.clientHeight; 12628 }; 12629 ScrollGeomCache.prototype.getScrollWidth = function () { 12630 return this.scrollWidth; 12631 }; 12632 ScrollGeomCache.prototype.getScrollHeight = function () { 12633 return this.scrollHeight; 12634 }; 12635 ScrollGeomCache.prototype.handleScrollChange = function () {}; 12636 return ScrollGeomCache; 12637 })(ScrollController); 12638 var ElementScrollGeomCache = /** @class */ (function (_super) { 12639 __extends(ElementScrollGeomCache, _super); 12640 function ElementScrollGeomCache(el, doesListening) { 12641 return ( 12642 _super.call(this, new ElementScrollController(el), doesListening) || 12643 this 12644 ); 12645 } 12646 ElementScrollGeomCache.prototype.getEventTarget = function () { 12647 return this.scrollController.el; 12648 }; 12649 ElementScrollGeomCache.prototype.computeClientRect = function () { 12650 return computeInnerRect(this.scrollController.el); 12651 }; 12652 return ElementScrollGeomCache; 12653 })(ScrollGeomCache); 12654 var WindowScrollGeomCache = /** @class */ (function (_super) { 12655 __extends(WindowScrollGeomCache, _super); 12656 function WindowScrollGeomCache(doesListening) { 12657 return ( 12658 _super.call(this, new WindowScrollController(), doesListening) || this 12659 ); 12660 } 12661 WindowScrollGeomCache.prototype.getEventTarget = function () { 12662 return window; 12663 }; 12664 WindowScrollGeomCache.prototype.computeClientRect = function () { 12665 return { 12666 left: this.scrollLeft, 12667 right: this.scrollLeft + this.clientWidth, 12668 top: this.scrollTop, 12669 bottom: this.scrollTop + this.clientHeight, 12670 }; 12671 }; 12672 // the window is the only scroll object that changes it's rectangle relative 12673 // to the document's topleft as it scrolls 12674 WindowScrollGeomCache.prototype.handleScrollChange = function () { 12675 this.clientRect = this.computeClientRect(); 12676 }; 12677 return WindowScrollGeomCache; 12678 })(ScrollGeomCache); 12679 12680 // If available we are using native "performance" API instead of "Date" 12681 // Read more about it on MDN: 12682 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 12683 var getTime = typeof performance === "function" ? performance.now : Date.now; 12684 /* 12685 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 12686 approaches the edge. 12687 12688 The caller must call start + handleMove + stop. 12689 */ 12690 var AutoScroller = /** @class */ (function () { 12691 function AutoScroller() { 12692 var _this = this; 12693 // options that can be set by caller 12694 this.isEnabled = true; 12695 this.scrollQuery = [window, ".fc-scroller"]; 12696 this.edgeThreshold = 50; // pixels 12697 this.maxVelocity = 300; // pixels per second 12698 // internal state 12699 this.pointerScreenX = null; 12700 this.pointerScreenY = null; 12701 this.isAnimating = false;
12702 this.scrollCaches = null; 12703 // protect against the initial pointerdown being too close to an edge and starting the scroll 12704 this.everMovedUp = false; 12705 this.everMovedDown = false; 12706 this.everMovedLeft = false; 12707 this.everMovedRight = false; 12708 this.animate = function () { 12709 if (_this.isAnimating) { 12710 // wasn't cancelled between animation calls 12711 var edge = _this.computeBestEdge( 12712 _this.pointerScreenX + window.pageXOffset, 12713 _this.pointerScreenY + window.pageYOffset 12714 ); 12715 if (edge) { 12716 var now = getTime(); 12717 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 12718 _this.requestAnimation(now); 12719 } else { 12720 _this.isAnimating = false; // will stop animation 12721 } 12722 } 12723 }; 12724 } 12725 AutoScroller.prototype.start = function (pageX, pageY) { 12726 if (this.isEnabled) { 12727 this.scrollCaches = this.buildCaches(); 12728 this.pointerScreenX = null; 12729 this.pointerScreenY = null; 12730 this.everMovedUp = false; 12731 this.everMovedDown = false; 12732 this.everMovedLeft = false; 12733 this.everMovedRight = false; 12734 this.handleMove(pageX, pageY); 12735 } 12736 }; 12737 AutoScroller.prototype.handleMove = function (pageX, pageY) { 12738 if (this.isEnabled) { 12739 var pointerScreenX = pageX - window.pageXOffset; 12740 var pointerScreenY = pageY - window.pageYOffset; 12741 var yDelta = 12742 this.pointerScreenY === null 12743 ? 0 12744 : pointerScreenY - this.pointerScreenY; 12745 var xDelta = 12746 this.pointerScreenX === null 12747 ? 0 12748 : pointerScreenX - this.pointerScreenX; 12749 if (yDelta < 0) { 12750 this.everMovedUp = true; 12751 } else if (yDelta > 0) { 12752 this.everMovedDown = true; 12753 } 12754 if (xDelta < 0) { 12755 this.everMovedLeft = true; 12756 } else if (xDelta > 0) { 12757 this.everMovedRight = true; 12758 } 12759 this.pointerScreenX = pointerScreenX; 12760 this.pointerScreenY = pointerScreenY; 12761 if (!this.isAnimating) { 12762 this.isAnimating = true; 12763 this.requestAnimation(getTime()); 12764 } 12765 } 12766 }; 12767 AutoScroller.prototype.stop = function () { 12768 if (this.isEnabled) { 12769 this.isAnimating = false; // will stop animation 12770 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 12771 var scrollCache = _a[_i]; 12772 scrollCache.destroy(); 12773 } 12774 this.scrollCaches = null; 12775 } 12776 }; 12777 AutoScroller.prototype.requestAnimation = function (now) { 12778 this.msSinceRequest = now; 12779 requestAnimationFrame(this.animate); 12780 }; 12781 AutoScroller.prototype.handleSide = function (edge, seconds) { 12782 var scrollCache = edge.scrollCache; 12783 var edgeThreshold = this.edgeThreshold; 12784 var invDistance = edgeThreshold - edge.distance; 12785 var velocity = // the closer to the edge, the faster we scroll 12786 ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic 12787 this.maxVelocity * 12788 seconds; 12789 var sign = 1; 12790 switch (edge.name) { 12791 case "left": 12792 sign = -1; 12793 // falls through 12794 case "right": 12795 scrollCache.setScrollLeft( 12796 scrollCache.getScrollLeft() + velocity * sign 12797 ); 12798 break; 12799 case "top": 12800 sign = -1; 12801 // falls through 12802 case "bottom": 12803 scrollCache.setScrollTop( 12804 scrollCache.getScrollTop() + velocity * sign 12805 ); 12806 break; 12807 } 12808 }; 12809 // left/top are relative to document topleft 12810 AutoScroller.prototype.computeBestEdge = function (left, top) { 12811 var edgeThreshold = this.edgeThreshold; 12812 var bestSide = null; 12813 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 12814 var scrollCache = _a[_i]; 12815 var rect = scrollCache.clientRect; 12816 var leftDist = left - rect.left; 12817 var rightDist = rect.right - left; 12818 var topDist = top - rect.top; 12819 var bottomDist = rect.bottom - top; 12820 // completely within the rect? 12821 if ( 12822 leftDist >= 0 && 12823 rightDist >= 0 && 12824 topDist >= 0 && 12825 bottomDist >= 0 12826 ) { 12827 if ( 12828 topDist <= edgeThreshold && 12829 this.everMovedUp && 12830 scrollCache.canScrollUp() && 12831 (!bestSide || bestSide.distance > topDist) 12832 ) { 12833 bestSide = { 12834 scrollCache: scrollCache, 12835 name: "top", 12836 distance: topDist, 12837 }; 12838 } 12839 if ( 12840 bottomDist <= edgeThreshold && 12841 this.everMovedDown && 12842 scrollCache.canScrollDown() && 12843 (!bestSide || bestSide.distance > bottomDist) 12844 ) { 12845 bestSide = { 12846 scrollCache: scrollCache, 12847 name: "bottom", 12848 distance: bottomDist, 12849 }; 12850 } 12851 if ( 12852 leftDist <= edgeThreshold && 12853 this.everMovedLeft && 12854 scrollCache.canScrollLeft() && 12855 (!bestSide || bestSide.distance > leftDist) 12856 ) { 12857 bestSide = { 12858 scrollCache: scrollCache, 12859 name: "left", 12860 distance: leftDist, 12861 }; 12862 } 12863 if ( 12864 rightDist <= edgeThreshold && 12865 this.everMovedRight && 12866 scrollCache.canScrollRight() && 12867 (!bestSide || bestSide.distance > rightDist) 12868 ) { 12869 bestSide = { 12870 scrollCache: scrollCache, 12871 name: "right", 12872 distance: rightDist, 12873 }; 12874 } 12875 } 12876 } 12877 return bestSide; 12878 }; 12879 AutoScroller.prototype.buildCaches = function () { 12880 return this.queryScrollEls().map(function (el) { 12881 if (el === window) { 12882 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 12883 } else { 12884 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 12885 } 12886 }); 12887 }; 12888 AutoScroller.prototype.queryScrollEls = function () { 12889 var els = []; 12890 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 12891 var query = _a[_i]; 12892 if (typeof query === "object") { 12893 els.push(query); 12894 } else { 12895 els.push.apply( 12896 els, 12897 Array.prototype.slice.call(document.querySelectorAll(query)) 12898 ); 12899 } 12900 } 12901 return els; 12902 }; 12903 return AutoScroller; 12904 })(); 12905 12906 /* 12907 Monitors dragging on an element. Has a number of high-level features: 12908 - minimum distance required before dragging 12909 - minimum wait time ("delay") before dragging 12910 - a mirror element that follows the pointer 12911 */ 12912 var FeaturefulElementDragging = /** @class */ (function (_super) { 12913 __extends(FeaturefulElementDragging, _super); 12914 function FeaturefulElementDragging(containerEl, selector) { 12915 var _this = _super.call(this, containerEl) || this; 12916 // options that can be directly set by caller 12917 // the caller can also set the PointerDragging's options as well 12918 _this.delay = null; 12919 _this.minDistance = 0; 12920 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 12921 _this.mirrorNeedsRevert = false;
12922 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 12923 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 12924 _this.isDelayEnded = false; 12925 _this.isDistanceSurpassed = false; 12926 _this.delayTimeoutId = null; 12927 _this.onPointerDown = function (ev) { 12928 if (!_this.isDragging) { 12929 // so new drag doesn't happen while revert animation is going 12930 _this.isInteracting = true; 12931 _this.isDelayEnded = false; 12932 _this.isDistanceSurpassed = false; 12933 preventSelection(document.body); 12934 preventContextMenu(document.body); 12935 // prevent links from being visited if there's an eventual drag. 12936 // also prevents selection in older browsers (maybe?). 12937 // not necessary for touch, besides, browser would complain about passiveness. 12938 if (!ev.isTouch) { 12939 ev.origEvent.preventDefault(); 12940 } 12941 _this.emitter.trigger("pointerdown", ev); 12942 if ( 12943 _this.isInteracting && // not destroyed via pointerdown handler 12944 !_this.pointer.shouldIgnoreMove 12945 ) { 12946 // actions related to initiating dragstart+dragmove+dragend... 12947 _this.mirror.setIsVisible(false); // reset. caller must set-visible 12948 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 12949 _this.startDelay(ev); 12950 if (!_this.minDistance) { 12951 _this.handleDistanceSurpassed(ev); 12952 } 12953 } 12954 } 12955 }; 12956 _this.onPointerMove = function (ev) { 12957 if (_this.isInteracting) { 12958 _this.emitter.trigger("pointermove", ev); 12959 if (!_this.isDistanceSurpassed) { 12960 var minDistance = _this.minDistance; 12961 var distanceSq = void 0; // current distance from the origin, squared 12962 var deltaX = ev.deltaX, 12963 deltaY = ev.deltaY; 12964 distanceSq = deltaX * deltaX + deltaY * deltaY; 12965 if (distanceSq >= minDistance * minDistance) { 12966 // use pythagorean theorem 12967 _this.handleDistanceSurpassed(ev); 12968 } 12969 } 12970 if (_this.isDragging) { 12971 // a real pointer move? (not one simulated by scrolling) 12972 if (ev.origEvent.type !== "scroll") { 12973 _this.mirror.handleMove(ev.pageX, ev.pageY); 12974 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 12975 } 12976 _this.emitter.trigger("dragmove", ev); 12977 } 12978 } 12979 }; 12980 _this.onPointerUp = function (ev) { 12981 if (_this.isInteracting) { 12982 _this.isInteracting = false; 12983 allowSelection(document.body); 12984 allowContextMenu(document.body); 12985 _this.emitter.trigger("pointerup", ev); // can potentially set mirrorNeedsRevert 12986 if (_this.isDragging) { 12987 _this.autoScroller.stop(); 12988 _this.tryStopDrag(ev); // which will stop the mirror 12989 } 12990 if (_this.delayTimeoutId) { 12991 clearTimeout(_this.delayTimeoutId); 12992 _this.delayTimeoutId = null; 12993 } 12994 } 12995 }; 12996 var pointer = (_this.pointer = new PointerDragging(containerEl)); 12997 pointer.emitter.on("pointerdown", _this.onPointerDown); 12998 pointer.emitter.on("pointermove", _this.onPointerMove); 12999 pointer.emitter.on("pointerup", _this.onPointerUp); 13000 if (selector) { 13001 pointer.selector = selector; 13002 } 13003 _this.mirror = new ElementMirror(); 13004 _this.autoScroller = new AutoScroller(); 13005 return _this; 13006 } 13007 FeaturefulElementDragging.prototype.destroy = function () { 13008 this.pointer.destroy(); 13009 // HACK: simulate a pointer-up to end the current drag
13010 // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) 13011 this.onPointerUp({}); 13012 }; 13013 FeaturefulElementDragging.prototype.startDelay = function (ev) { 13014 var _this = this; 13015 if (typeof this.delay === "number") { 13016 this.delayTimeoutId = setTimeout(function () { 13017 _this.delayTimeoutId = null; 13018 _this.handleDelayEnd(ev); 13019 }, this.delay); // not assignable to number! 13020 } else { 13021 this.handleDelayEnd(ev); 13022 } 13023 }; 13024 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 13025 this.isDelayEnded = true; 13026 this.tryStartDrag(ev); 13027 }; 13028 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function ( 13029 ev 13030 ) { 13031 this.isDistanceSurpassed = true; 13032 this.tryStartDrag(ev); 13033 }; 13034 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 13035 if (this.isDelayEnded && this.isDistanceSurpassed) { 13036 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 13037 this.isDragging = true; 13038 this.mirrorNeedsRevert = false; 13039 this.autoScroller.start(ev.pageX, ev.pageY); 13040 this.emitter.trigger("dragstart", ev); 13041 if (this.touchScrollAllowed === false) { 13042 this.pointer.cancelTouchScroll(); 13043 } 13044 } 13045 } 13046 }; 13047 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 13048 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 13049 // that come from the document to fire beforehand. much more convenient this way. 13050 this.mirror.stop( 13051 this.mirrorNeedsRevert, 13052 this.stopDrag.bind(this, ev) // bound with args 13053 ); 13054 }; 13055 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 13056 this.isDragging = false; 13057 this.emitter.trigger("dragend", ev); 13058 }; 13059 // fill in the implementations... 13060 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 13061 this.pointer.shouldIgnoreMove = bool; 13062 }; 13063 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 13064 this.mirror.setIsVisible(bool); 13065 }; 13066 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 13067 this.mirrorNeedsRevert = bool; 13068 }; 13069 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 13070 this.autoScroller.isEnabled = bool; 13071 }; 13072 return FeaturefulElementDragging; 13073 })(ElementDragging); 13074 13075 /* 13076 When this class is instantiated, it records the offset of an element (relative to the document topleft), 13077 and continues to monitor scrolling, updating the cached coordinates if it needs to. 13078 Does not access the DOM after instantiation, so highly performant. 13079 13080 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 13081 and an determine if a given point is inside the combined clipping rectangle. 13082 */ 13083 var OffsetTracker = /** @class */ (function () { 13084 function OffsetTracker(el) { 13085 this.origRect = computeRect(el); 13086 // will work fine for divs that have overflow:hidden 13087 this.scrollCaches = getClippingParents(el).map(function (el) { 13088 return new ElementScrollGeomCache(el, true); // listen=true 13089 }); 13090 } 13091 OffsetTracker.prototype.destroy = function () { 13092 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 13093 var scrollCache = _a[_i]; 13094 scrollCache.destroy(); 13095 } 13096 }; 13097 OffsetTracker.prototype.computeLeft = function () { 13098 var left = this.origRect.left; 13099 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 13100 var scrollCache = _a[_i]; 13101 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 13102 } 13103 return left; 13104 }; 13105 OffsetTracker.prototype.computeTop = function () { 13106 var top = this.origRect.top; 13107 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 13108 var scrollCache = _a[_i]; 13109 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 13110 } 13111 return top; 13112 }; 13113 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 13114 var point = { left: pageX, top: pageY }; 13115 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 13116 var scrollCache = _a[_i]; 13117 if (
13118 !isIgnoredClipping(scrollCache.getEventTarget()) && 13119 !pointInsideRect(point, scrollCache.clientRect) 13120 ) { 13121 return false; 13122 } 13123 } 13124 return true; 13125 }; 13126 return OffsetTracker; 13127 })(); 13128 // certain clipping containers should never constrain interactions, like <html> and <body> 13129 // https://github.com/fullcalendar/fullcalendar/issues/3615 13130 function isIgnoredClipping(node) { 13131 var tagName = node.tagName; 13132 return tagName === "HTML" || tagName === "BODY"; 13133 } 13134 13135 /* 13136 Tracks movement over multiple droppable areas (aka "hits") 13137 that exist in one or more DateComponents. 13138 Relies on an existing draggable. 13139 13140 emits: 13141 - pointerdown 13142 - dragstart 13143 - hitchange - fires initially, even if not over a hit 13144 - pointerup 13145 - (hitchange - again, to null, if ended over a hit) 13146 - dragend 13147 */ 13148 var HitDragging = /** @class */ (function () { 13149 function HitDragging(dragging, droppableStore) { 13150 var _this = this; 13151 // options that can be set by caller 13152 this.useSubjectCenter = false; 13153 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 13154 this.initialHit = null; 13155 this.movingHit = null; 13156 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 13157 this.handlePointerDown = function (ev) { 13158 var dragging = _this.dragging; 13159 _this.initialHit = null; 13160 _this.movingHit = null; 13161 _this.finalHit = null; 13162 _this.prepareHits(); 13163 _this.processFirstCoord(ev); 13164 if (_this.initialHit || !_this.requireInitial) { 13165 dragging.setIgnoreMove(false); 13166 _this.emitter.trigger("pointerdown", ev); // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 13167 } else { 13168 dragging.setIgnoreMove(true); 13169 } 13170 }; 13171 this.handleDragStart = function (ev) { 13172 _this.emitter.trigger("dragstart", ev); 13173 _this.handleMove(ev, true); // force = fire even if initially null 13174 }; 13175 this.handleDragMove = function (ev) { 13176 _this.emitter.trigger("dragmove", ev); 13177 _this.handleMove(ev); 13178 }; 13179 this.handlePointerUp = function (ev) { 13180 _this.releaseHits(); 13181 _this.emitter.trigger("pointerup", ev); 13182 }; 13183 this.handleDragEnd = function (ev) { 13184 if (_this.movingHit) { 13185 _this.emitter.trigger("hitupdate", null, true, ev); 13186 } 13187 _this.finalHit = _this.movingHit; 13188 _this.movingHit = null; 13189 _this.emitter.trigger("dragend", ev); 13190 }; 13191 this.droppableStore = droppableStore; 13192 dragging.emitter.on("pointerdown", this.handlePointerDown); 13193 dragging.emitter.on("dragstart", this.handleDragStart); 13194 dragging.emitter.on("dragmove", this.handleDragMove); 13195 dragging.emitter.on("pointerup", this.handlePointerUp); 13196 dragging.emitter.on("dragend", this.handleDragEnd); 13197 this.dragging = dragging; 13198 this.emitter = new Emitter(); 13199 } 13200 // sets initialHit 13201 // sets coordAdjust 13202 HitDragging.prototype.processFirstCoord = function (ev) { 13203 var origPoint = { left: ev.pageX, top: ev.pageY }; 13204 var adjustedPoint = origPoint; 13205 var subjectEl = ev.subjectEl; 13206 var subjectRect; 13207 if (subjectEl !== document) { 13208 subjectRect = computeRect(subjectEl); 13209 adjustedPoint = constrainPoint(adjustedPoint, subjectRect); 13210 } 13211 var initialHit = (this.initialHit = this.queryHitForOffset( 13212 adjustedPoint.left, 13213 adjustedPoint.top 13214 )); 13215 if (initialHit) { 13216 if (this.useSubjectCenter && subjectRect) { 13217 var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect); 13218 if (slicedSubjectRect) { 13219 adjustedPoint = getRectCenter(slicedSubjectRect); 13220 } 13221 } 13222 this.coordAdjust = diffPoints(adjustedPoint, origPoint); 13223 } else { 13224 this.coordAdjust = { left: 0, top: 0 }; 13225 } 13226 }; 13227 HitDragging.prototype.handleMove = function (ev, forceHandle) { 13228 var hit = this.queryHitForOffset( 13229 ev.pageX + this.coordAdjust.left, 13230 ev.pageY + this.coordAdjust.top 13231 ); 13232 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 13233 this.movingHit = hit; 13234 this.emitter.trigger("hitupdate", hit, false, ev); 13235 } 13236 }; 13237 HitDragging.prototype.prepareHits = function () { 13238 this.offsetTrackers = mapHash( 13239 this.droppableStore, 13240 function (interactionSettings) { 13241 interactionSettings.component.prepareHits(); 13242 return new OffsetTracker(interactionSettings.el); 13243 } 13244 ); 13245 }; 13246 HitDragging.prototype.releaseHits = function () { 13247 var offsetTrackers = this.offsetTrackers; 13248 for (var id in offsetTrackers) { 13249 offsetTrackers[id].destroy(); 13250 } 13251 this.offsetTrackers = {}; 13252 }; 13253 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 13254 var _a = this, 13255 droppableStore = _a.droppableStore, 13256 offsetTrackers = _a.offsetTrackers; 13257 var bestHit = null; 13258 for (var id in droppableStore) { 13259 var component = droppableStore[id].component; 13260 var offsetTracker = offsetTrackers[id]; 13261 if ( 13262 offsetTracker && // wasn't destroyed mid-drag 13263 offsetTracker.isWithinClipping(offsetLeft, offsetTop) 13264 ) { 13265 var originLeft = offsetTracker.computeLeft(); 13266 var originTop = offsetTracker.computeTop(); 13267 var positionLeft = offsetLeft - originLeft; 13268 var positionTop = offsetTop - originTop; 13269 var origRect = offsetTracker.origRect; 13270 var width = origRect.right - origRect.left; 13271 var height = origRect.bottom - origRect.top; 13272 if ( 13273 // must be within the element's bounds 13274 positionLeft >= 0 && 13275 positionLeft < width && 13276 positionTop >= 0 && 13277 positionTop < height 13278 ) { 13279 var hit = component.queryHit( 13280 positionLeft, 13281 positionTop, 13282 width, 13283 height 13284 ); 13285 var dateProfile = component.context.getCurrentData().dateProfile; 13286 if ( 13287 hit && 13288 // make sure the hit is within activeRange, meaning it's not a deal cell 13289 rangeContainsRange(dateProfile.activeRange, hit.dateSpan.range) && 13290 (!bestHit || hit.layer > bestHit.layer) 13291 ) { 13292 // TODO: better way to re-orient rectangle 13293 hit.rect.left += originLeft; 13294 hit.rect.right += originLeft; 13295 hit.rect.top += originTop; 13296 hit.rect.bottom += originTop; 13297 bestHit = hit; 13298 } 13299 } 13300 } 13301 } 13302 return bestHit; 13303 }; 13304 return HitDragging; 13305 })(); 13306 function isHitsEqual(hit0, hit1) { 13307 if (!hit0 && !hit1) { 13308 return true; 13309 } 13310 if (Boolean(hit0) !== Boolean(hit1)) { 13311 return false;
13312 } 13313 return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 13314 } 13315 13316 function buildDatePointApiWithContext(dateSpan, context) { 13317 var props = {}; 13318 for ( 13319 var _i = 0, _a = context.pluginHooks.datePointTransforms; 13320 _i < _a.length; 13321 _i++ 13322 ) { 13323 var transform = _a[_i]; 13324 __assign(props, transform(dateSpan, context)); 13325 } 13326 __assign(props, buildDatePointApi(dateSpan, context.dateEnv)); 13327 return props; 13328 } 13329 function buildDatePointApi(span, dateEnv) { 13330 return { 13331 date: dateEnv.toDate(span.range.start), 13332 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 13333 allDay: span.allDay, 13334 }; 13335 } 13336 13337 /* 13338 Monitors when the user clicks on a specific date/time of a component. 13339 A pointerdown+pointerup on the same "hit" constitutes a click. 13340 */ 13341 var DateClicking = /** @class */ (function (_super) { 13342 __extends(DateClicking, _super); 13343 function DateClicking(settings) { 13344 var _this = _super.call(this, settings) || this; 13345 _this.handlePointerDown = function (pev) { 13346 var dragging = _this.dragging; 13347 var downEl = pev.origEvent.target; 13348 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 13349 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl)); 13350 }; 13351 // won't even fire if moving was ignored 13352 _this.handleDragEnd = function (ev) { 13353 var component = _this.component; 13354 var pointer = _this.dragging.pointer; 13355 if (!pointer.wasTouchScroll) { 13356 var _a = _this.hitDragging, 13357 initialHit = _a.initialHit, 13358 finalHit = _a.finalHit; 13359 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 13360 var context = component.context; 13361 var arg = __assign( 13362 __assign( 13363 {}, 13364 buildDatePointApiWithContext(initialHit.dateSpan, context) 13365 ), 13366 { 13367 dayEl: initialHit.dayEl, 13368 jsEvent: ev.origEvent, 13369 view: context.viewApi || context.calendarApi.view, 13370 } 13371 ); 13372 context.emitter.trigger("dateClick", arg); 13373 } 13374 } 13375 }; 13376 // we DO want to watch pointer moves because otherwise finalHit won't get populated 13377 _this.dragging = new FeaturefulElementDragging(settings.el); 13378 _this.dragging.autoScroller.isEnabled = false; 13379 var hitDragging = (_this.hitDragging = new HitDragging( 13380 _this.dragging, 13381 interactionSettingsToStore(settings) 13382 )); 13383 hitDragging.emitter.on("pointerdown", _this.handlePointerDown); 13384 hitDragging.emitter.on("dragend", _this.handleDragEnd); 13385 return _this; 13386 } 13387 DateClicking.prototype.destroy = function () { 13388 this.dragging.destroy(); 13389 }; 13390 return DateClicking; 13391 })(Interaction); 13392 13393 /* 13394 Tracks when the user selects a portion of time of a component, 13395 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 13396 */ 13397 var DateSelecting = /** @class */ (function (_super) { 13398 __extends(DateSelecting, _super); 13399 function DateSelecting(settings) { 13400 var _this = _super.call(this, settings) || this; 13401 _this.dragSelection = null; 13402 _this.handlePointerDown = function (ev) { 13403 var _a = _this, 13404 component = _a.component, 13405 dragging = _a.dragging; 13406 var options = component.context.options; 13407 var canSelect = 13408 options.selectable && 13409 component.isValidDateDownEl(ev.origEvent.target); 13410 // don't bother to watch expensive moves if component won't do selection 13411 dragging.setIgnoreMove(!canSelect); 13412 // if touch, require user to hold down 13413 dragging.delay = ev.isTouch ? getComponentTouchDelay(component) : null; 13414 }; 13415 _this.handleDragStart = function (ev) { 13416 _this.component.context.calendarApi.unselect(ev); // unselect previous selections 13417 }; 13418 _this.handleHitUpdate = function (hit, isFinal) { 13419 var context = _this.component.context; 13420 var dragSelection = null; 13421 var isInvalid = false;
13422 if (hit) { 13423 dragSelection = joinHitsIntoSelection( 13424 _this.hitDragging.initialHit, 13425 hit, 13426 context.pluginHooks.dateSelectionTransformers 13427 ); 13428 if ( 13429 !dragSelection || 13430 !_this.component.isDateSelectionValid(dragSelection) 13431 ) { 13432 isInvalid = true; 13433 dragSelection = null; 13434 } 13435 } 13436 if (dragSelection) { 13437 context.dispatch({ type: "SELECT_DATES", selection: dragSelection }); 13438 } else if (!isFinal) { 13439 // only unselect if moved away while dragging 13440 context.dispatch({ type: "UNSELECT_DATES" }); 13441 } 13442 if (!isInvalid) { 13443 enableCursor(); 13444 } else { 13445 disableCursor(); 13446 } 13447 if (!isFinal) { 13448 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 13449 } 13450 }; 13451 _this.handlePointerUp = function (pev) { 13452 if (_this.dragSelection) { 13453 // selection is already rendered, so just need to report selection 13454 triggerDateSelect(_this.dragSelection, pev, _this.component.context); 13455 _this.dragSelection = null; 13456 } 13457 }; 13458 var component = settings.component; 13459 var options = component.context.options; 13460 var dragging = (_this.dragging = new FeaturefulElementDragging( 13461 settings.el 13462 )); 13463 dragging.touchScrollAllowed = false; 13464 dragging.minDistance = options.selectMinDistance || 0; 13465 dragging.autoScroller.isEnabled = options.dragScroll; 13466 var hitDragging = (_this.hitDragging = new HitDragging( 13467 _this.dragging, 13468 interactionSettingsToStore(settings) 13469 )); 13470 hitDragging.emitter.on("pointerdown", _this.handlePointerDown); 13471 hitDragging.emitter.on("dragstart", _this.handleDragStart); 13472 hitDragging.emitter.on("hitupdate", _this.handleHitUpdate); 13473 hitDragging.emitter.on("pointerup", _this.handlePointerUp); 13474 return _this; 13475 } 13476 DateSelecting.prototype.destroy = function () { 13477 this.dragging.destroy(); 13478 }; 13479 return DateSelecting; 13480 })(Interaction); 13481 function getComponentTouchDelay(component) { 13482 var options = component.context.options; 13483 var delay = options.selectLongPressDelay; 13484 if (delay == null) { 13485 delay = options.longPressDelay; 13486 } 13487 return delay; 13488 } 13489 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 13490 var dateSpan0 = hit0.dateSpan; 13491 var dateSpan1 = hit1.dateSpan; 13492 var ms = [ 13493 dateSpan0.range.start, 13494 dateSpan0.range.end, 13495 dateSpan1.range.start, 13496 dateSpan1.range.end, 13497 ]; 13498 ms.sort(compareNumbers); 13499 var props = {}; 13500 for ( 13501 var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; 13502 _i < dateSelectionTransformers_1.length; 13503 _i++ 13504 ) { 13505 var transformer = dateSelectionTransformers_1[_i]; 13506 var res = transformer(hit0, hit1); 13507 if (res === false) { 13508 return null; 13509 } else if (res) { 13510 __assign(props, res); 13511 } 13512 } 13513 props.range = { start: ms[0], end: ms[3] }; 13514 props.allDay = dateSpan0.allDay; 13515 return props; 13516 } 13517 13518 var EventDragging = /** @class */ (function (_super) { 13519 __extends(EventDragging, _super); 13520 function EventDragging(settings) { 13521 var _this = _super.call(this, settings) || this; 13522 // internal state 13523 _this.subjectEl = null; 13524 _this.subjectSeg = null; // the seg being selected/dragged 13525 _this.isDragging = false; 13526 _this.eventRange = null; 13527 _this.relevantEvents = null; // the events being dragged 13528 _this.receivingContext = null; 13529 _this.validMutation = null; 13530 _this.mutatedRelevantEvents = null; 13531 _this.handlePointerDown = function (ev) { 13532 var origTarget = ev.origEvent.target; 13533 var _a = _this, 13534 component = _a.component, 13535 dragging = _a.dragging; 13536 var mirror = dragging.mirror; 13537 var options = component.context.options; 13538 var initialContext = component.context; 13539 _this.subjectEl = ev.subjectEl; 13540 var subjectSeg = (_this.subjectSeg = getElSeg(ev.subjectEl)); 13541 var eventRange = (_this.eventRange = subjectSeg.eventRange); 13542 var eventInstanceId = eventRange.instance.instanceId; 13543 _this.relevantEvents = getRelevantEvents( 13544 initialContext.getCurrentData().eventStore, 13545 eventInstanceId 13546 ); 13547 dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance; 13548 dragging.delay = 13549 // only do a touch delay if touch and this event hasn't been selected yet 13550 ev.isTouch && eventInstanceId !== component.props.eventSelection 13551 ? getComponentTouchDelay$1(component) 13552 : null; 13553 mirror.parentNode = elementClosest(origTarget, ".fc"); 13554 mirror.revertDuration = options.dragRevertDuration; 13555 var isValid = 13556 component.isValidSegDownEl(origTarget) && 13557 !elementClosest(origTarget, ".fc-event-resizer"); // NOT on a resizer 13558 dragging.setIgnoreMove(!isValid); 13559 // disable dragging for elements that are resizable (ie, selectable) 13560 // but are not draggable 13561 _this.isDragging = 13562 isValid && ev.subjectEl.classList.contains("fc-event-draggable"); 13563 }; 13564 _this.handleDragStart = function (ev) { 13565 var initialContext = _this.component.context; 13566 var eventRange = _this.eventRange; 13567 var eventInstanceId = eventRange.instance.instanceId; 13568 if (ev.isTouch) { 13569 // need to select a different event? 13570 if (eventInstanceId !== _this.component.props.eventSelection) { 13571 initialContext.dispatch({ 13572 type: "SELECT_EVENT", 13573 eventInstanceId: eventInstanceId, 13574 }); 13575 } 13576 } else { 13577 // if now using mouse, but was previous touch interaction, clear selected event 13578 initialContext.dispatch({ type: "UNSELECT_EVENT" }); 13579 } 13580 if (_this.isDragging) { 13581 initialContext.calendarApi.unselect(ev); // unselect *date* selection 13582 initialContext.emitter.trigger("eventDragStart", { 13583 el: _this.subjectEl, 13584 event: new EventApi( 13585 initialContext, 13586 eventRange.def, 13587 eventRange.instance 13588 ), 13589 jsEvent: ev.origEvent, 13590 view: initialContext.viewApi, 13591 }); 13592 } 13593 }; 13594 _this.handleHitUpdate = function (hit, isFinal) { 13595 if (!_this.isDragging) { 13596 return; 13597 } 13598 var relevantEvents = _this.relevantEvents; 13599 var initialHit = _this.hitDragging.initialHit; 13600 var initialContext = _this.component.context; 13601 // states based on new hit 13602 var receivingContext = null; 13603 var mutation = null; 13604 var mutatedRelevantEvents = null; 13605 var isInvalid = false;
13606 var interaction = { 13607 affectedEvents: relevantEvents, 13608 mutatedEvents: createEmptyEventStore(), 13609 isEvent: true, 13610 }; 13611 if (hit) { 13612 var receivingComponent = hit.component; 13613 receivingContext = receivingComponent.context; 13614 var receivingOptions = receivingContext.options; 13615 if ( 13616 initialContext === receivingContext || 13617 (receivingOptions.editable && receivingOptions.droppable) 13618 ) { 13619 mutation = computeEventMutation( 13620 initialHit, 13621 hit, 13622 receivingContext.getCurrentData().pluginHooks 13623 .eventDragMutationMassagers 13624 ); 13625 if (mutation) { 13626 mutatedRelevantEvents = applyMutationToEventStore( 13627 relevantEvents, 13628 receivingContext.getCurrentData().eventUiBases, 13629 mutation, 13630 receivingContext 13631 ); 13632 interaction.mutatedEvents = mutatedRelevantEvents; 13633 if (!receivingComponent.isInteractionValid(interaction)) { 13634 isInvalid = true; 13635 mutation = null; 13636 mutatedRelevantEvents = null; 13637 interaction.mutatedEvents = createEmptyEventStore(); 13638 } 13639 } 13640 } else { 13641 receivingContext = null; 13642 } 13643 } 13644 _this.displayDrag(receivingContext, interaction); 13645 if (!isInvalid) { 13646 enableCursor(); 13647 } else { 13648 disableCursor(); 13649 } 13650 if (!isFinal) { 13651 if ( 13652 initialContext === receivingContext && // TODO: write test for this 13653 isHitsEqual(initialHit, hit) 13654 ) { 13655 mutation = null; 13656 } 13657 _this.dragging.setMirrorNeedsRevert(!mutation); 13658 // render the mirror if no already-rendered mirror 13659 // TODO: wish we could somehow wait for dispatch to guarantee render 13660 _this.dragging.setMirrorIsVisible( 13661 !hit || !document.querySelector(".fc-event-mirror") 13662 ); 13663 // assign states based on new hit 13664 _this.receivingContext = receivingContext; 13665 _this.validMutation = mutation; 13666 _this.mutatedRelevantEvents = mutatedRelevantEvents; 13667 } 13668 }; 13669 _this.handlePointerUp = function () { 13670 if (!_this.isDragging) { 13671 _this.cleanup(); // because handleDragEnd won't fire 13672 } 13673 }; 13674 _this.handleDragEnd = function (ev) { 13675 if (_this.isDragging) { 13676 var initialContext_1 = _this.component.context; 13677 var initialView = initialContext_1.viewApi; 13678 var _a = _this, 13679 receivingContext_1 = _a.receivingContext, 13680 validMutation = _a.validMutation; 13681 var eventDef = _this.eventRange.def; 13682 var eventInstance = _this.eventRange.instance; 13683 var eventApi = new EventApi( 13684 initialContext_1, 13685 eventDef, 13686 eventInstance 13687 ); 13688 var relevantEvents_1 = _this.relevantEvents; 13689 var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents; 13690 var finalHit = _this.hitDragging.finalHit; 13691 _this.clearDrag(); // must happen after revert animation 13692 initialContext_1.emitter.trigger("eventDragStop", { 13693 el: _this.subjectEl, 13694 event: eventApi, 13695 jsEvent: ev.origEvent, 13696 view: initialView, 13697 }); 13698 if (validMutation) { 13699 // dropped within same calendar 13700 if (receivingContext_1 === initialContext_1) { 13701 var updatedEventApi = new EventApi( 13702 initialContext_1, 13703 mutatedRelevantEvents_1.defs[eventDef.defId], 13704 eventInstance 13705 ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] 13706 : null 13707 ); 13708 initialContext_1.dispatch({ 13709 type: "MERGE_EVENTS", 13710 eventStore: mutatedRelevantEvents_1, 13711 }); 13712 var eventChangeArg = { 13713 oldEvent: eventApi, 13714 event: updatedEventApi, 13715 relatedEvents: buildEventApis( 13716 mutatedRelevantEvents_1, 13717 initialContext_1, 13718 eventInstance 13719 ), 13720 revert: function () { 13721 initialContext_1.dispatch({ 13722 type: "MERGE_EVENTS", 13723 eventStore: relevantEvents_1, // the pre-change data 13724 }); 13725 }, 13726 }; 13727 var transformed = {}; 13728 for ( 13729 var _i = 0, 13730 _b = 13731 initialContext_1.getCurrentData().pluginHooks 13732 .eventDropTransformers; 13733 _i < _b.length; 13734 _i++ 13735 ) { 13736 var transformer = _b[_i]; 13737 __assign( 13738 transformed, 13739 transformer(validMutation, initialContext_1) 13740 ); 13741 } 13742 initialContext_1.emitter.trigger( 13743 "eventDrop", 13744 __assign(__assign(__assign({}, eventChangeArg), transformed), { 13745 el: ev.subjectEl, 13746 delta: validMutation.datesDelta, 13747 jsEvent: ev.origEvent, 13748 view: initialView, 13749 }) 13750 ); 13751 initialContext_1.emitter.trigger("eventChange", eventChangeArg); 13752 // dropped in different calendar 13753 } else if (receivingContext_1) { 13754 var eventRemoveArg = { 13755 event: eventApi, 13756 relatedEvents: buildEventApis( 13757 relevantEvents_1, 13758 initialContext_1, 13759 eventInstance 13760 ), 13761 revert: function () { 13762 initialContext_1.dispatch({ 13763 type: "MERGE_EVENTS", 13764 eventStore: relevantEvents_1, 13765 }); 13766 }, 13767 }; 13768 initialContext_1.emitter.trigger( 13769 "eventLeave", 13770 __assign(__assign({}, eventRemoveArg), { 13771 draggedEl: ev.subjectEl, 13772 view: initialView, 13773 }) 13774 ); 13775 initialContext_1.dispatch({
13776 type: "REMOVE_EVENTS", 13777 eventStore: relevantEvents_1, 13778 }); 13779 initialContext_1.emitter.trigger("eventRemove", eventRemoveArg); 13780 var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId]; 13781 var addedEventInstance = 13782 mutatedRelevantEvents_1.instances[eventInstance.instanceId]; 13783 var addedEventApi = new EventApi( 13784 receivingContext_1, 13785 addedEventDef, 13786 addedEventInstance 13787 ); 13788 receivingContext_1.dispatch({ 13789 type: "MERGE_EVENTS", 13790 eventStore: mutatedRelevantEvents_1, 13791 }); 13792 var eventAddArg = { 13793 event: addedEventApi, 13794 relatedEvents: buildEventApis( 13795 mutatedRelevantEvents_1, 13796 receivingContext_1, 13797 addedEventInstance 13798 ), 13799 revert: function () { 13800 receivingContext_1.dispatch({ 13801 type: "REMOVE_EVENTS", 13802 eventStore: mutatedRelevantEvents_1, 13803 }); 13804 }, 13805 }; 13806 receivingContext_1.emitter.trigger("eventAdd", eventAddArg); 13807 if (ev.isTouch) { 13808 receivingContext_1.dispatch({ 13809 type: "SELECT_EVENT", 13810 eventInstanceId: eventInstance.instanceId, 13811 }); 13812 } 13813 receivingContext_1.emitter.trigger( 13814 "drop", 13815 __assign( 13816 __assign( 13817 {}, 13818 buildDatePointApiWithContext( 13819 finalHit.dateSpan, 13820 receivingContext_1 13821 ) 13822 ), 13823 { 13824 draggedEl: ev.subjectEl, 13825 jsEvent: ev.origEvent, 13826 view: finalHit.component.context.viewApi, 13827 } 13828 ) 13829 ); 13830 receivingContext_1.emitter.trigger( 13831 "eventReceive", 13832 __assign(__assign({}, eventAddArg), { 13833 draggedEl: ev.subjectEl, 13834 view: finalHit.component.context.viewApi, 13835 }) 13836 ); 13837 } 13838 } else { 13839 initialContext_1.emitter.trigger("_noEventDrop"); 13840 } 13841 } 13842 _this.cleanup(); 13843 }; 13844 var component = _this.component; 13845 var options = component.context.options; 13846 var dragging = (_this.dragging = new FeaturefulElementDragging( 13847 settings.el 13848 )); 13849 dragging.pointer.selector = EventDragging.SELECTOR; 13850 dragging.touchScrollAllowed = false; 13851 dragging.autoScroller.isEnabled = options.dragScroll; 13852 var hitDragging = (_this.hitDragging = new HitDragging( 13853 _this.dragging, 13854 interactionSettingsStore 13855 )); 13856 hitDragging.useSubjectCenter = settings.useEventCenter; 13857 hitDragging.emitter.on("pointerdown", _this.handlePointerDown); 13858 hitDragging.emitter.on("dragstart", _this.handleDragStart); 13859 hitDragging.emitter.on("hitupdate", _this.handleHitUpdate); 13860 hitDragging.emitter.on("pointerup", _this.handlePointerUp); 13861 hitDragging.emitter.on("dragend", _this.handleDragEnd); 13862 return _this; 13863 } 13864 EventDragging.prototype.destroy = function () { 13865 this.dragging.destroy(); 13866 }; 13867 // render a drag state on the next receivingCalendar 13868 EventDragging.prototype.displayDrag = function (nextContext, state) { 13869 var initialContext = this.component.context; 13870 var prevContext = this.receivingContext; 13871 // does the previous calendar need to be cleared? 13872 if (prevContext && prevContext !== nextContext) { 13873 // does the initial calendar need to be cleared? 13874 // if so, don't clear all the way. we still need to to hide the affectedEvents 13875 if (prevContext === initialContext) { 13876 prevContext.dispatch({ 13877 type: "SET_EVENT_DRAG", 13878 state: { 13879 affectedEvents: state.affectedEvents, 13880 mutatedEvents: createEmptyEventStore(), 13881 isEvent: true, 13882 }, 13883 }); 13884 // completely clear the old calendar if it wasn't the initial 13885 } else { 13886 prevContext.dispatch({ type: "UNSET_EVENT_DRAG" }); 13887 } 13888 } 13889 if (nextContext) { 13890 nextContext.dispatch({ type: "SET_EVENT_DRAG", state: state }); 13891 } 13892 }; 13893 EventDragging.prototype.clearDrag = function () { 13894 var initialCalendar = this.component.context; 13895 var receivingContext = this.receivingContext; 13896 if (receivingContext) { 13897 receivingContext.dispatch({ type: "UNSET_EVENT_DRAG" }); 13898 } 13899 // the initial calendar might have an dummy drag state from displayDrag 13900 if (initialCalendar !== receivingContext) { 13901 initialCalendar.dispatch({ type: "UNSET_EVENT_DRAG" }); 13902 } 13903 }; 13904 EventDragging.prototype.cleanup = function () { 13905 this.subjectSeg = null; 13906 this.isDragging = false;
13907 this.eventRange = null; 13908 this.relevantEvents = null; 13909 this.receivingContext = null; 13910 this.validMutation = null; 13911 this.mutatedRelevantEvents = null; 13912 }; 13913 // TODO: test this in IE11 13914 // QUESTION: why do we need it on the resizable??? 13915 EventDragging.SELECTOR = ".fc-event-draggable, .fc-event-resizable"; 13916 return EventDragging; 13917 })(Interaction); 13918 function computeEventMutation(hit0, hit1, massagers) { 13919 var dateSpan0 = hit0.dateSpan; 13920 var dateSpan1 = hit1.dateSpan; 13921 var date0 = dateSpan0.range.start; 13922 var date1 = dateSpan1.range.start; 13923 var standardProps = {}; 13924 if (dateSpan0.allDay !== dateSpan1.allDay) { 13925 standardProps.allDay = dateSpan1.allDay; 13926 standardProps.hasEnd = 13927 hit1.component.context.options.allDayMaintainDuration; 13928 if (dateSpan1.allDay) { 13929 // means date1 is already start-of-day, 13930 // but date0 needs to be converted 13931 date0 = startOfDay(date0); 13932 } 13933 } 13934 var delta = diffDates( 13935 date0, 13936 date1, 13937 hit0.component.context.dateEnv, 13938 hit0.component === hit1.component ? hit0.component.largeUnit : null 13939 ); 13940 if (delta.milliseconds) { 13941 // has hours/minutes/seconds 13942 standardProps.allDay = false; 13943 } 13944 var mutation = { 13945 datesDelta: delta, 13946 standardProps: standardProps, 13947 }; 13948 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 13949 var massager = massagers_1[_i]; 13950 massager(mutation, hit0, hit1); 13951 } 13952 return mutation; 13953 } 13954 function getComponentTouchDelay$1(component) { 13955 var options = component.context.options; 13956 var delay = options.eventLongPressDelay; 13957 if (delay == null) { 13958 delay = options.longPressDelay; 13959 } 13960 return delay; 13961 } 13962 13963 var EventResizing = /** @class */ (function (_super) { 13964 __extends(EventResizing, _super); 13965 function EventResizing(settings) { 13966 var _this = _super.call(this, settings) || this; 13967 // internal state 13968 _this.draggingSegEl = null; 13969 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 13970 _this.eventRange = null; 13971 _this.relevantEvents = null; 13972 _this.validMutation = null; 13973 _this.mutatedRelevantEvents = null; 13974 _this.handlePointerDown = function (ev) { 13975 var component = _this.component; 13976 var segEl = _this.querySegEl(ev); 13977 var seg = getElSeg(segEl); 13978 var eventRange = (_this.eventRange = seg.eventRange); 13979 _this.dragging.minDistance = 13980 component.context.options.eventDragMinDistance; 13981 // if touch, need to be working with a selected event 13982 _this.dragging.setIgnoreMove( 13983 !_this.component.isValidSegDownEl(ev.origEvent.target) || 13984 (ev.isTouch && 13985 _this.component.props.eventSelection !== 13986 eventRange.instance.instanceId) 13987 ); 13988 }; 13989 _this.handleDragStart = function (ev) { 13990 var context = _this.component.context; 13991 var eventRange = _this.eventRange; 13992 _this.relevantEvents = getRelevantEvents( 13993 context.getCurrentData().eventStore, 13994 _this.eventRange.instance.instanceId 13995 ); 13996 var segEl = _this.querySegEl(ev); 13997 _this.draggingSegEl = segEl; 13998 _this.draggingSeg = getElSeg(segEl); 13999 context.calendarApi.unselect(); 14000 context.emitter.trigger("eventResizeStart", { 14001 el: segEl, 14002 event: new EventApi(context, eventRange.def, eventRange.instance), 14003 jsEvent: ev.origEvent, 14004 view: context.viewApi, 14005 }); 14006 }; 14007 _this.handleHitUpdate = function (hit, isFinal, ev) { 14008 var context = _this.component.context; 14009 var relevantEvents = _this.relevantEvents; 14010 var initialHit = _this.hitDragging.initialHit; 14011 var eventInstance = _this.eventRange.instance; 14012 var mutation = null; 14013 var mutatedRelevantEvents = null; 14014 var isInvalid = false; 14015 var interaction = { 14016 affectedEvents: relevantEvents, 14017 mutatedEvents: createEmptyEventStore(), 14018 isEvent: true, 14019 }; 14020 if (hit) { 14021 mutation = computeMutation( 14022 initialHit, 14023 hit, 14024 ev.subjectEl.classList.contains("fc-event-resizer-start"), 14025 eventInstance.range, 14026 context.pluginHooks.eventResizeJoinTransforms 14027 ); 14028 } 14029 if (mutation) { 14030 mutatedRelevantEvents = applyMutationToEventStore( 14031 relevantEvents, 14032 context.getCurrentData().eventUiBases, 14033 mutation, 14034 context 14035 ); 14036 interaction.mutatedEvents = mutatedRelevantEvents; 14037 if (!_this.component.isInteractionValid(interaction)) { 14038 isInvalid = true; 14039 mutation = null; 14040 mutatedRelevantEvents = null; 14041 interaction.mutatedEvents = null; 14042 } 14043 } 14044 if (mutatedRelevantEvents) { 14045 context.dispatch({ 14046 type: "SET_EVENT_RESIZE", 14047 state: interaction, 14048 }); 14049 } else { 14050 context.dispatch({ type: "UNSET_EVENT_RESIZE" }); 14051 } 14052 if (!isInvalid) {
14053 enableCursor(); 14054 } else { 14055 disableCursor(); 14056 } 14057 if (!isFinal) { 14058 if (mutation && isHitsEqual(initialHit, hit)) { 14059 mutation = null; 14060 } 14061 _this.validMutation = mutation; 14062 _this.mutatedRelevantEvents = mutatedRelevantEvents; 14063 } 14064 }; 14065 _this.handleDragEnd = function (ev) { 14066 var context = _this.component.context; 14067 var eventDef = _this.eventRange.def; 14068 var eventInstance = _this.eventRange.instance; 14069 var eventApi = new EventApi(context, eventDef, eventInstance); 14070 var relevantEvents = _this.relevantEvents; 14071 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 14072 context.emitter.trigger("eventResizeStop", { 14073 el: _this.draggingSegEl, 14074 event: eventApi, 14075 jsEvent: ev.origEvent, 14076 view: context.viewApi, 14077 }); 14078 if (_this.validMutation) { 14079 var updatedEventApi = new EventApi( 14080 context, 14081 mutatedRelevantEvents.defs[eventDef.defId], 14082 eventInstance 14083 ? mutatedRelevantEvents.instances[eventInstance.instanceId] 14084 : null 14085 ); 14086 context.dispatch({ 14087 type: "MERGE_EVENTS", 14088 eventStore: mutatedRelevantEvents, 14089 }); 14090 var eventChangeArg = { 14091 oldEvent: eventApi, 14092 event: updatedEventApi, 14093 relatedEvents: buildEventApis( 14094 mutatedRelevantEvents, 14095 context, 14096 eventInstance 14097 ), 14098 revert: function () { 14099 context.dispatch({ 14100 type: "MERGE_EVENTS", 14101 eventStore: relevantEvents, // the pre-change events 14102 }); 14103 }, 14104 }; 14105 context.emitter.trigger( 14106 "eventResize", 14107 __assign(__assign({}, eventChangeArg), { 14108 el: _this.draggingSegEl, 14109 startDelta: _this.validMutation.startDelta || createDuration(0), 14110 endDelta: _this.validMutation.endDelta || createDuration(0), 14111 jsEvent: ev.origEvent, 14112 view: context.viewApi, 14113 }) 14114 ); 14115 context.emitter.trigger("eventChange", eventChangeArg); 14116 } else { 14117 context.emitter.trigger("_noEventResize"); 14118 } 14119 // reset all internal state 14120 _this.draggingSeg = null; 14121 _this.relevantEvents = null; 14122 _this.validMutation = null; 14123 // okay to keep eventInstance around. useful to set it in handlePointerDown 14124 }; 14125 var component = settings.component; 14126 var dragging = (_this.dragging = new FeaturefulElementDragging( 14127 settings.el 14128 )); 14129 dragging.pointer.selector = ".fc-event-resizer"; 14130 dragging.touchScrollAllowed = false; 14131 dragging.autoScroller.isEnabled = component.context.options.dragScroll; 14132 var hitDragging = (_this.hitDragging = new HitDragging( 14133 _this.dragging, 14134 interactionSettingsToStore(settings) 14135 )); 14136 hitDragging.emitter.on("pointerdown", _this.handlePointerDown); 14137 hitDragging.emitter.on("dragstart", _this.handleDragStart); 14138 hitDragging.emitter.on("hitupdate", _this.handleHitUpdate); 14139 hitDragging.emitter.on("dragend", _this.handleDragEnd); 14140 return _this; 14141 } 14142 EventResizing.prototype.destroy = function () { 14143 this.dragging.destroy(); 14144 }; 14145 EventResizing.prototype.querySegEl = function (ev) { 14146 return elementClosest(ev.subjectEl, ".fc-event"); 14147 }; 14148 return EventResizing; 14149 })(Interaction); 14150 function computeMutation(hit0, hit1, isFromStart, instanceRange, transforms) { 14151 var dateEnv = hit0.component.context.dateEnv; 14152 var date0 = hit0.dateSpan.range.start; 14153 var date1 = hit1.dateSpan.range.start; 14154 var delta = diffDates(date0, date1, dateEnv, hit0.component.largeUnit); 14155 var props = {}; 14156 for ( 14157 var _i = 0, transforms_1 = transforms; 14158 _i < transforms_1.length; 14159 _i++ 14160 ) { 14161 var transform = transforms_1[_i]; 14162 var res = transform(hit0, hit1); 14163 if (res === false) { 14164 return null; 14165 } else if (res) { 14166 __assign(props, res); 14167 } 14168 } 14169 if (isFromStart) { 14170 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 14171 props.startDelta = delta; 14172 return props; 14173 } 14174 } else { 14175 if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 14176 props.endDelta = delta; 14177 return props; 14178 } 14179 } 14180 return null; 14181 } 14182 14183 var UnselectAuto = /** @class */ (function () { 14184 function UnselectAuto(context) { 14185 var _this = this; 14186 this.context = context; 14187 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 14188 this.matchesCancel = false;
14189 this.matchesEvent = false; 14190 this.onSelect = function (selectInfo) { 14191 if (selectInfo.jsEvent) { 14192 _this.isRecentPointerDateSelect = true; 14193 } 14194 }; 14195 this.onDocumentPointerDown = function (pev) { 14196 var unselectCancel = _this.context.options.unselectCancel; 14197 var downEl = pev.origEvent.target; 14198 _this.matchesCancel = !!elementClosest(downEl, unselectCancel); 14199 _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event? 14200 }; 14201 this.onDocumentPointerUp = function (pev) { 14202 var context = _this.context; 14203 var documentPointer = _this.documentPointer; 14204 var calendarState = context.getCurrentData(); 14205 // touch-scrolling should never unfocus any type of selection 14206 if (!documentPointer.wasTouchScroll) { 14207 if ( 14208 calendarState.dateSelection && // an existing date selection? 14209 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 14210 ) { 14211 var unselectAuto = context.options.unselectAuto; 14212 if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) { 14213 context.calendarApi.unselect(pev); 14214 } 14215 } 14216 if ( 14217 calendarState.eventSelection && // an existing event selected? 14218 !_this.matchesEvent // interaction DIDN'T start on an event 14219 ) { 14220 context.dispatch({ type: "UNSELECT_EVENT" }); 14221 } 14222 } 14223 _this.isRecentPointerDateSelect = false; 14224 }; 14225 var documentPointer = (this.documentPointer = new PointerDragging( 14226 document 14227 )); 14228 documentPointer.shouldIgnoreMove = true; 14229 documentPointer.shouldWatchScroll = false; 14230 documentPointer.emitter.on("pointerdown", this.onDocumentPointerDown); 14231 documentPointer.emitter.on("pointerup", this.onDocumentPointerUp); 14232 /* 14233 TODO: better way to know about whether there was a selection with the pointer 14234 */ 14235 context.emitter.on("select", this.onSelect); 14236 } 14237 UnselectAuto.prototype.destroy = function () { 14238 this.context.emitter.off("select", this.onSelect); 14239 this.documentPointer.destroy(); 14240 }; 14241 return UnselectAuto; 14242 })(); 14243 14244 var LISTENER_REFINERS = { 14245 dateClick: identity, 14246 eventDragStart: identity, 14247 eventDragStop: identity, 14248 eventDrop: identity, 14249 eventResizeStart: identity, 14250 eventResizeStop: identity, 14251 eventResize: identity, 14252 drop: identity, 14253 eventReceive: identity, 14254 eventLeave: identity, 14255 }; 14256 14257 /* 14258 Given an already instantiated draggable object for one-or-more elements, 14259 Interprets any dragging as an attempt to drag an events that lives outside 14260 of a calendar onto a calendar. 14261 */ 14262 var ExternalElementDragging = /** @class */ (function () { 14263 function ExternalElementDragging(dragging, suppliedDragMeta) { 14264 var _this = this; 14265 this.receivingContext = null; 14266 this.droppableEvent = null; // will exist for all drags, even if create:false 14267 this.suppliedDragMeta = null; 14268 this.dragMeta = null; 14269 this.handleDragStart = function (ev) { 14270 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 14271 }; 14272 this.handleHitUpdate = function (hit, isFinal, ev) { 14273 var dragging = _this.hitDragging.dragging; 14274 var receivingContext = null; 14275 var droppableEvent = null; 14276 var isInvalid = false; 14277 var interaction = { 14278 affectedEvents: createEmptyEventStore(), 14279 mutatedEvents: createEmptyEventStore(), 14280 isEvent: _this.dragMeta.create, 14281 }; 14282 if (hit) { 14283 receivingContext = hit.component.context; 14284 if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) { 14285 droppableEvent = computeEventForDateSpan( 14286 hit.dateSpan, 14287 _this.dragMeta, 14288 receivingContext 14289 ); 14290 interaction.mutatedEvents = eventTupleToStore(droppableEvent); 14291 isInvalid = !isInteractionValid(interaction, receivingContext); 14292 if (isInvalid) { 14293 interaction.mutatedEvents = createEmptyEventStore(); 14294 droppableEvent = null; 14295 } 14296 } 14297 } 14298 _this.displayDrag(receivingContext, interaction); 14299 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 14300 // TODO: wish we could somehow wait for dispatch to guarantee render 14301 dragging.setMirrorIsVisible( 14302 isFinal || 14303 !droppableEvent || 14304 !document.querySelector(".fc-event-mirror") 14305 ); 14306 if (!isInvalid) {
14307 enableCursor(); 14308 } else { 14309 disableCursor(); 14310 } 14311 if (!isFinal) { 14312 dragging.setMirrorNeedsRevert(!droppableEvent); 14313 _this.receivingContext = receivingContext; 14314 _this.droppableEvent = droppableEvent; 14315 } 14316 }; 14317 this.handleDragEnd = function (pev) { 14318 var _a = _this, 14319 receivingContext = _a.receivingContext, 14320 droppableEvent = _a.droppableEvent; 14321 _this.clearDrag(); 14322 if (receivingContext && droppableEvent) { 14323 var finalHit = _this.hitDragging.finalHit; 14324 var finalView = finalHit.component.context.viewApi; 14325 var dragMeta = _this.dragMeta; 14326 receivingContext.emitter.trigger( 14327 "drop", 14328 __assign( 14329 __assign( 14330 {}, 14331 buildDatePointApiWithContext( 14332 finalHit.dateSpan, 14333 receivingContext 14334 ) 14335 ), 14336 { 14337 draggedEl: pev.subjectEl, 14338 jsEvent: pev.origEvent, 14339 view: finalView, 14340 } 14341 ) 14342 ); 14343 if (dragMeta.create) { 14344 var addingEvents_1 = eventTupleToStore(droppableEvent); 14345 receivingContext.dispatch({ 14346 type: "MERGE_EVENTS", 14347 eventStore: addingEvents_1, 14348 }); 14349 if (pev.isTouch) { 14350 receivingContext.dispatch({ 14351 type: "SELECT_EVENT", 14352 eventInstanceId: droppableEvent.instance.instanceId, 14353 }); 14354 } 14355 // signal that an external event landed 14356 receivingContext.emitter.trigger("eventReceive", { 14357 event: new EventApi( 14358 receivingContext, 14359 droppableEvent.def, 14360 droppableEvent.instance 14361 ), 14362 relatedEvents: [], 14363 revert: function () { 14364 receivingContext.dispatch({ 14365 type: "REMOVE_EVENTS", 14366 eventStore: addingEvents_1, 14367 }); 14368 }, 14369 draggedEl: pev.subjectEl, 14370 view: finalView, 14371 }); 14372 } 14373 } 14374 _this.receivingContext = null; 14375 _this.droppableEvent = null; 14376 }; 14377 var hitDragging = (this.hitDragging = new HitDragging( 14378 dragging, 14379 interactionSettingsStore 14380 )); 14381 hitDragging.requireInitial = false; // will start outside of a component 14382 hitDragging.emitter.on("dragstart", this.handleDragStart); 14383 hitDragging.emitter.on("hitupdate", this.handleHitUpdate); 14384 hitDragging.emitter.on("dragend", this.handleDragEnd); 14385 this.suppliedDragMeta = suppliedDragMeta; 14386 } 14387 ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) { 14388 if (typeof this.suppliedDragMeta === "object") { 14389 return parseDragMeta(this.suppliedDragMeta); 14390 } else if (typeof this.suppliedDragMeta === "function") { 14391 return parseDragMeta(this.suppliedDragMeta(subjectEl)); 14392 } else { 14393 return getDragMetaFromEl(subjectEl); 14394 } 14395 }; 14396 ExternalElementDragging.prototype.displayDrag = function ( 14397 nextContext, 14398 state 14399 ) { 14400 var prevContext = this.receivingContext; 14401 if (prevContext && prevContext !== nextContext) { 14402 prevContext.dispatch({ type: "UNSET_EVENT_DRAG" }); 14403 } 14404 if (nextContext) { 14405 nextContext.dispatch({ type: "SET_EVENT_DRAG", state: state }); 14406 } 14407 }; 14408 ExternalElementDragging.prototype.clearDrag = function () { 14409 if (this.receivingContext) { 14410 this.receivingContext.dispatch({ type: "UNSET_EVENT_DRAG" }); 14411 } 14412 }; 14413 ExternalElementDragging.prototype.canDropElOnCalendar = function ( 14414 el, 14415 receivingContext 14416 ) { 14417 var dropAccept = receivingContext.options.dropAccept; 14418 if (typeof dropAccept === "function") { 14419 return dropAccept.call(receivingContext.calendarApi, el); 14420 } else if (typeof dropAccept === "string" && dropAccept) { 14421 return Boolean(elementMatches(el, dropAccept)); 14422 } 14423 return true; 14424 }; 14425 return ExternalElementDragging; 14426 })(); 14427 // Utils for computing event store from the DragMeta 14428 // ---------------------------------------------------------------------------------------------------- 14429 function computeEventForDateSpan(dateSpan, dragMeta, context) { 14430 var defProps = __assign({}, dragMeta.leftoverProps); 14431 for ( 14432 var _i = 0, _a = context.pluginHooks.externalDefTransforms; 14433 _i < _a.length; 14434 _i++ 14435 ) { 14436 var transform = _a[_i]; 14437 __assign(defProps, transform(dateSpan, dragMeta)); 14438 } 14439 var _b = refineEventDef(defProps, context),
14440 refined = _b.refined, 14441 extra = _b.extra; 14442 var def = parseEventDef( 14443 refined, 14444 extra, 14445 dragMeta.sourceId, 14446 dateSpan.allDay, 14447 context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd 14448 context 14449 ); 14450 var start = dateSpan.range.start; 14451 // only rely on time info if drop zone is all-day, 14452 // otherwise, we already know the time 14453 if (dateSpan.allDay && dragMeta.startTime) { 14454 start = context.dateEnv.add(start, dragMeta.startTime); 14455 } 14456 var end = dragMeta.duration 14457 ? context.dateEnv.add(start, dragMeta.duration) 14458 : getDefaultEventEnd(dateSpan.allDay, start, context); 14459 var instance = createEventInstance(def.defId, { start: start, end: end }); 14460 return { def: def, instance: instance }; 14461 } 14462 // Utils for extracting data from element 14463 // ---------------------------------------------------------------------------------------------------- 14464 function getDragMetaFromEl(el) { 14465 var str = getEmbeddedElData(el, "event"); 14466 var obj = str ? JSON.parse(str) : { create: false }; // if no embedded data, assume no event creation 14467 return parseDragMeta(obj); 14468 } 14469 config.dataAttrPrefix = ""; 14470 function getEmbeddedElData(el, name) { 14471 var prefix = config.dataAttrPrefix; 14472 var prefixedName = (prefix ? prefix + "-" : "") + name; 14473 return el.getAttribute("data-" + prefixedName) || ""; 14474 } 14475 14476 /* 14477 Makes an element (that is *external* to any calendar) draggable. 14478 Can pass in data that determines how an event will be created when dropped onto a calendar. 14479 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 14480 */ 14481 var ExternalDraggable = /** @class */ (function () { 14482 function ExternalDraggable(el, settings) { 14483 var _this = this; 14484 if (settings === void 0) { 14485 settings = {}; 14486 } 14487 this.handlePointerDown = function (ev) { 14488 var dragging = _this.dragging; 14489 var _a = _this.settings, 14490 minDistance = _a.minDistance, 14491 longPressDelay = _a.longPressDelay; 14492 dragging.minDistance = 14493 minDistance != null 14494 ? minDistance 14495 : ev.isTouch 14496 ? 0 14497 : BASE_OPTION_DEFAULTS.eventDragMinDistance; 14498 dragging.delay = ev.isTouch // TODO: eventually read eventLongPressDelay instead vvv 14499 ? longPressDelay != null 14500 ? longPressDelay 14501 : BASE_OPTION_DEFAULTS.longPressDelay 14502 : 0; 14503 }; 14504 this.handleDragStart = function (ev) { 14505 if ( 14506 ev.isTouch && 14507 _this.dragging.delay && 14508 ev.subjectEl.classList.contains("fc-event") 14509 ) { 14510 _this.dragging.mirror 14511 .getMirrorEl() 14512 .classList.add("fc-event-selected"); 14513 } 14514 }; 14515 this.settings = settings; 14516 var dragging = (this.dragging = new FeaturefulElementDragging(el)); 14517 dragging.touchScrollAllowed = false; 14518 if (settings.itemSelector != null) { 14519 dragging.pointer.selector = settings.itemSelector; 14520 } 14521 if (settings.appendTo != null) { 14522 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 14523 } 14524 dragging.emitter.on("pointerdown", this.handlePointerDown); 14525 dragging.emitter.on("dragstart", this.handleDragStart); 14526 new ExternalElementDragging(dragging, settings.eventData); 14527 } 14528 ExternalDraggable.prototype.destroy = function () { 14529 this.dragging.destroy(); 14530 }; 14531 return ExternalDraggable; 14532 })(); 14533 14534 /* 14535 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 14536 The third-party system is responsible for drawing the visuals effects of the drag. 14537 This class simply monitors for pointer movements and fires events. 14538 It also has the ability to hide the moving element (the "mirror") during the drag. 14539 */ 14540 var InferredElementDragging = /** @class */ (function (_super) { 14541 __extends(InferredElementDragging, _super); 14542 function InferredElementDragging(containerEl) { 14543 var _this = _super.call(this, containerEl) || this; 14544 _this.shouldIgnoreMove = false;
14545 _this.mirrorSelector = ""; 14546 _this.currentMirrorEl = null; 14547 _this.handlePointerDown = function (ev) { 14548 _this.emitter.trigger("pointerdown", ev); 14549 if (!_this.shouldIgnoreMove) { 14550 // fire dragstart right away. does not support delay or min-distance 14551 _this.emitter.trigger("dragstart", ev); 14552 } 14553 }; 14554 _this.handlePointerMove = function (ev) { 14555 if (!_this.shouldIgnoreMove) { 14556 _this.emitter.trigger("dragmove", ev); 14557 } 14558 }; 14559 _this.handlePointerUp = function (ev) { 14560 _this.emitter.trigger("pointerup", ev); 14561 if (!_this.shouldIgnoreMove) { 14562 // fire dragend right away. does not support a revert animation 14563 _this.emitter.trigger("dragend", ev); 14564 } 14565 }; 14566 var pointer = (_this.pointer = new PointerDragging(containerEl)); 14567 pointer.emitter.on("pointerdown", _this.handlePointerDown); 14568 pointer.emitter.on("pointermove", _this.handlePointerMove); 14569 pointer.emitter.on("pointerup", _this.handlePointerUp); 14570 return _this; 14571 } 14572 InferredElementDragging.prototype.destroy = function () { 14573 this.pointer.destroy(); 14574 }; 14575 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 14576 this.shouldIgnoreMove = bool; 14577 }; 14578 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 14579 if (bool) { 14580 // restore a previously hidden element. 14581 // use the reference in case the selector class has already been removed. 14582 if (this.currentMirrorEl) { 14583 this.currentMirrorEl.style.visibility = ""; 14584 this.currentMirrorEl = null; 14585 } 14586 } else { 14587 var mirrorEl = this.mirrorSelector 14588 ? document.querySelector(this.mirrorSelector) 14589 : null; 14590 if (mirrorEl) { 14591 this.currentMirrorEl = mirrorEl; 14592 mirrorEl.style.visibility = "hidden"; 14593 } 14594 } 14595 }; 14596 return InferredElementDragging; 14597 })(ElementDragging); 14598 14599 /* 14600 Bridges third-party drag-n-drop systems with FullCalendar. 14601 Must be instantiated and destroyed by caller. 14602 */ 14603 var ThirdPartyDraggable = /** @class */ (function () { 14604 function ThirdPartyDraggable(containerOrSettings, settings) { 14605 var containerEl = document; 14606 if ( 14607 // wish we could just test instanceof EventTarget, but doesn't work in IE11 14608 containerOrSettings === document || 14609 containerOrSettings instanceof Element 14610 ) { 14611 containerEl = containerOrSettings; 14612 settings = settings || {}; 14613 } else { 14614 settings = containerOrSettings || {}; 14615 } 14616 var dragging = (this.dragging = new InferredElementDragging(containerEl)); 14617 if (typeof settings.itemSelector === "string") { 14618 dragging.pointer.selector = settings.itemSelector; 14619 } else if (containerEl === document) { 14620 dragging.pointer.selector = "[data-event]"; 14621 } 14622 if (typeof settings.mirrorSelector === "string") { 14623 dragging.mirrorSelector = settings.mirrorSelector; 14624 } 14625 new ExternalElementDragging(dragging, settings.eventData); 14626 } 14627 ThirdPartyDraggable.prototype.destroy = function () { 14628 this.dragging.destroy(); 14629 }; 14630 return ThirdPartyDraggable; 14631 })(); 14632 14633 var interactionPlugin = createPlugin({ 14634 componentInteractions: [ 14635 DateClicking, 14636 DateSelecting, 14637 EventDragging, 14638 EventResizing, 14639 ], 14640 calendarInteractions: [UnselectAuto], 14641 elementDraggingImpl: FeaturefulElementDragging, 14642 listenerRefiners: LISTENER_REFINERS, 14643 }); 14644 14645 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 14646 ----------------------------------------------------------------------------------------------------------------------*/ 14647 // It is a manager for a Table subcomponent, which does most of the heavy lifting. 14648 // It is responsible for managing width/height. 14649 var TableView = /** @class */ (function (_super) { 14650 __extends(TableView, _super); 14651 function TableView() { 14652 var _this = (_super !== null && _super.apply(this, arguments)) || this; 14653 _this.headerElRef = createRef(); 14654 return _this; 14655 } 14656 TableView.prototype.renderSimpleLayout = function ( 14657 headerRowContent, 14658 bodyContent 14659 ) { 14660 var _a = this, 14661 props = _a.props, 14662 context = _a.context; 14663 var sections = []; 14664 var stickyHeaderDates = getStickyHeaderDates(context.options); 14665 if (headerRowContent) { 14666 sections.push({ 14667 type: "header", 14668 key: "header", 14669 isSticky: stickyHeaderDates, 14670 chunk: { 14671 elRef: this.headerElRef, 14672 tableClassName: "fc-col-header", 14673 rowContent: headerRowContent, 14674 }, 14675 }); 14676 } 14677 sections.push({ 14678 type: "body", 14679 key: "body", 14680 liquid: true, 14681 chunk: { content: bodyContent }, 14682 }); 14683 return createElement( 14684 ViewRoot, 14685 { viewSpec: context.viewSpec }, 14686 function (rootElRef, classNames) { 14687 return createElement( 14688 "div", 14689 { 14690 ref: rootElRef,
14691 className: ["fc-daygrid"].concat(classNames).join(" "), 14692 }, 14693 createElement(SimpleScrollGrid, { 14694 liquid: !props.isHeightAuto && !props.forPrint, 14695 cols: [] /* TODO: make optional? */, 14696 sections: sections, 14697 }) 14698 ); 14699 } 14700 ); 14701 }; 14702 TableView.prototype.renderHScrollLayout = function ( 14703 headerRowContent, 14704 bodyContent, 14705 colCnt, 14706 dayMinWidth 14707 ) { 14708 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 14709 if (!ScrollGrid) { 14710 throw new Error("No ScrollGrid implementation"); 14711 } 14712 var _a = this, 14713 props = _a.props, 14714 context = _a.context; 14715 var stickyHeaderDates = 14716 !props.forPrint && getStickyHeaderDates(context.options); 14717 var stickyFooterScrollbar = 14718 !props.forPrint && getStickyFooterScrollbar(context.options); 14719 var sections = []; 14720 if (headerRowContent) { 14721 sections.push({ 14722 type: "header", 14723 key: "header", 14724 isSticky: stickyHeaderDates, 14725 chunks: [ 14726 { 14727 key: "main", 14728 elRef: this.headerElRef, 14729 tableClassName: "fc-col-header", 14730 rowContent: headerRowContent, 14731 }, 14732 ], 14733 }); 14734 } 14735 sections.push({ 14736 type: "body", 14737 key: "body", 14738 liquid: true, 14739 chunks: [ 14740 { 14741 key: "main", 14742 content: bodyContent, 14743 }, 14744 ], 14745 }); 14746 if (stickyFooterScrollbar) { 14747 sections.push({ 14748 type: "footer", 14749 key: "footer", 14750 isSticky: true, 14751 chunks: [ 14752 { 14753 key: "main", 14754 content: renderScrollShim, 14755 }, 14756 ], 14757 }); 14758 } 14759 return createElement( 14760 ViewRoot, 14761 { viewSpec: context.viewSpec }, 14762 function (rootElRef, classNames) { 14763 return createElement( 14764 "div", 14765 { 14766 ref: rootElRef, 14767 className: ["fc-daygrid"].concat(classNames).join(" "), 14768 }, 14769 createElement(ScrollGrid, { 14770 liquid: !props.isHeightAuto && !props.forPrint, 14771 colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], 14772 sections: sections, 14773 }) 14774 ); 14775 } 14776 ); 14777 }; 14778 return TableView; 14779 })(DateComponent); 14780 14781 function splitSegsByRow(segs, rowCnt) { 14782 var byRow = []; 14783 for (var i = 0; i < rowCnt; i++) { 14784 byRow[i] = []; 14785 } 14786 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 14787 var seg = segs_1[_i]; 14788 byRow[seg.row].push(seg); 14789 } 14790 return byRow; 14791 } 14792 function splitSegsByFirstCol(segs, colCnt) { 14793 var byCol = []; 14794 for (var i = 0; i < colCnt; i++) { 14795 byCol[i] = []; 14796 } 14797 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 14798 var seg = segs_2[_i]; 14799 byCol[seg.firstCol].push(seg); 14800 } 14801 return byCol; 14802 } 14803 function splitInteractionByRow(ui, rowCnt) { 14804 var byRow = []; 14805 if (!ui) { 14806 for (var i = 0; i < rowCnt; i++) { 14807 byRow[i] = null; 14808 } 14809 } else { 14810 for (var i = 0; i < rowCnt; i++) { 14811 byRow[i] = { 14812 affectedInstances: ui.affectedInstances, 14813 isEvent: ui.isEvent, 14814 segs: [], 14815 }; 14816 } 14817 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 14818 var seg = _a[_i]; 14819 byRow[seg.row].segs.push(seg); 14820 } 14821 } 14822 return byRow; 14823 } 14824 14825 var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: "narrow" }); 14826 var TableCell = /** @class */ (function (_super) { 14827 __extends(TableCell, _super); 14828 function TableCell() { 14829 var _this = (_super !== null && _super.apply(this, arguments)) || this; 14830 _this.handleRootEl = function (el) { 14831 _this.rootEl = el; 14832 setRef(_this.props.elRef, el); 14833 }; 14834 _this.handleMoreLinkClick = function (ev) { 14835 var props = _this.props; 14836 if (props.onMoreClick) { 14837 var allSegs = props.segsByEachCol; 14838 var hiddenSegs = allSegs.filter(function (seg) { 14839 return props.segIsHidden[seg.eventRange.instance.instanceId]; 14840 }); 14841 props.onMoreClick({ 14842 date: props.date, 14843 allSegs: allSegs, 14844 hiddenSegs: hiddenSegs, 14845 moreCnt: props.moreCnt, 14846 dayEl: _this.rootEl, 14847 ev: ev, 14848 }); 14849 } 14850 }; 14851 return _this; 14852 } 14853 TableCell.prototype.render = function () { 14854 var _this = this; 14855 var _a = this.context, 14856 options = _a.options, 14857 viewApi = _a.viewApi; 14858 var props = this.props; 14859 var date = props.date, 14860 dateProfile = props.dateProfile; 14861 var hookProps = { 14862 num: props.moreCnt, 14863 text: props.buildMoreLinkText(props.moreCnt), 14864 view: viewApi, 14865 }; 14866 var navLinkAttrs = options.navLinks 14867 ? { "data-navlink": buildNavLinkData(date, "week"), tabIndex: 0 } 14868 : {}; 14869 return createElement( 14870 DayCellRoot, 14871 { 14872 date: date, 14873 dateProfile: dateProfile, 14874 todayRange: props.todayRange, 14875 showDayNumber: props.showDayNumber, 14876 extraHookProps: props.extraHookProps, 14877 elRef: this.handleRootEl, 14878 }, 14879 function (rootElRef, classNames, rootDataAttrs, isDisabled) { 14880 return createElement( 14881 "td", 14882 __assign( 14883 { 14884 ref: rootElRef,
14885 className: ["fc-daygrid-day"] 14886 .concat(classNames, props.extraClassNames || []) 14887 .join(" "), 14888 }, 14889 rootDataAttrs, 14890 props.extraDataAttrs 14891 ), 14892 createElement( 14893 "div", 14894 { 14895 className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", 14896 ref: props.innerElRef /* different from hook system! RENAME */, 14897 }, 14898 props.showWeekNumber && 14899 createElement( 14900 WeekNumberRoot, 14901 { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, 14902 function (rootElRef, classNames, innerElRef, innerContent) { 14903 return createElement( 14904 "a", 14905 __assign( 14906 { 14907 ref: rootElRef, 14908 className: ["fc-daygrid-week-number"] 14909 .concat(classNames) 14910 .join(" "), 14911 }, 14912 navLinkAttrs 14913 ), 14914 innerContent 14915 ); 14916 } 14917 ), 14918 !isDisabled && 14919 createElement(TableCellTop, { 14920 date: date, 14921 dateProfile: dateProfile, 14922 showDayNumber: props.showDayNumber, 14923 forceDayTop: props.forceDayTop, 14924 todayRange: props.todayRange, 14925 extraHookProps: props.extraHookProps, 14926 }), 14927 createElement( 14928 "div", 14929 { 14930 className: "fc-daygrid-day-events", 14931 ref: props.fgContentElRef, 14932 style: { paddingBottom: props.fgPaddingBottom }, 14933 }, 14934 props.fgContent, 14935 Boolean(props.moreCnt) && 14936 createElement( 14937 "div", 14938 { 14939 className: "fc-daygrid-day-bottom", 14940 style: { marginTop: props.moreMarginTop }, 14941 }, 14942 createElement( 14943 RenderHook, 14944 { 14945 hookProps: hookProps, 14946 classNames: options.moreLinkClassNames, 14947 content: options.moreLinkContent, 14948 defaultContent: renderMoreLinkInner, 14949 didMount: options.moreLinkDidMount, 14950 willUnmount: options.moreLinkWillUnmount, 14951 }, 14952 function ( 14953 rootElRef, 14954 classNames, 14955 innerElRef, 14956 innerContent 14957 ) { 14958 return createElement( 14959 "a", 14960 { 14961 onClick: _this.handleMoreLinkClick, 14962 ref: rootElRef, 14963 className: ["fc-daygrid-more-link"] 14964 .concat(classNames) 14965 .join(" "), 14966 }, 14967 innerContent 14968 ); 14969 } 14970 ) 14971 ) 14972 ), 14973 createElement( 14974 "div", 14975 { className: "fc-daygrid-day-bg" }, 14976 props.bgContent 14977 ) 14978 ) 14979 ); 14980 } 14981 ); 14982 }; 14983 return TableCell; 14984 })(DateComponent); 14985 function renderTopInner(props) { 14986 return props.dayNumberText; 14987 } 14988 function renderMoreLinkInner(props) { 14989 return props.text; 14990 } 14991 var TableCellTop = /** @class */ (function (_super) { 14992 __extends(TableCellTop, _super); 14993 function TableCellTop() { 14994 return (_super !== null && _super.apply(this, arguments)) || this; 14995 } 14996 TableCellTop.prototype.render = function () { 14997 var props = this.props; 14998 var navLinkAttrs = this.context.options.navLinks 14999 ? { "data-navlink": buildNavLinkData(props.date), tabIndex: 0 } 15000 : {}; 15001 return createElement( 15002 DayCellContent, 15003 { 15004 date: props.date, 15005 dateProfile: props.dateProfile, 15006 todayRange: props.todayRange, 15007 showDayNumber: props.showDayNumber, 15008 extraHookProps: props.extraHookProps, 15009 defaultContent: renderTopInner, 15010 }, 15011 function (innerElRef, innerContent) { 15012 return ( 15013 (innerContent || props.forceDayTop) && 15014 createElement( 15015 "div",
15016 { className: "fc-daygrid-day-top", ref: innerElRef }, 15017 createElement( 15018 "a", 15019 __assign({ className: "fc-daygrid-day-number" }, navLinkAttrs), 15020 innerContent || createElement(Fragment, null, "\u00A0") 15021 ) 15022 ) 15023 ); 15024 } 15025 ); 15026 }; 15027 return TableCellTop; 15028 })(BaseComponent); 15029 15030 var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 15031 hour: "numeric", 15032 minute: "2-digit", 15033 omitZeroMinute: true, 15034 meridiem: "narrow", 15035 }); 15036 function hasListItemDisplay(seg) { 15037 var display = seg.eventRange.ui.display; 15038 return ( 15039 display === "list-item" || 15040 (display === "auto" && 15041 !seg.eventRange.def.allDay && 15042 seg.firstCol === seg.lastCol && // can't be multi-day 15043 seg.isStart && // " 15044 seg.isEnd) // " 15045 ); 15046 } 15047 15048 var TableListItemEvent = /** @class */ (function (_super) { 15049 __extends(TableListItemEvent, _super); 15050 function TableListItemEvent() { 15051 return (_super !== null && _super.apply(this, arguments)) || this; 15052 } 15053 TableListItemEvent.prototype.render = function () { 15054 var _a = this, 15055 props = _a.props, 15056 context = _a.context; 15057 var timeFormat = 15058 context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 15059 var timeText = buildSegTimeText( 15060 props.seg, 15061 timeFormat, 15062 context, 15063 true, 15064 props.defaultDisplayEventEnd 15065 ); 15066 return createElement( 15067 EventRoot, 15068 { 15069 seg: props.seg, 15070 timeText: timeText, 15071 defaultContent: renderInnerContent$2, 15072 isDragging: props.isDragging, 15073 isResizing: false, 15074 isDateSelecting: false, 15075 isSelected: props.isSelected, 15076 isPast: props.isPast, 15077 isFuture: props.isFuture, 15078 isToday: props.isToday, 15079 }, 15080 function (rootElRef, classNames, innerElRef, innerContent) { 15081 return ( 15082 // we don't use styles! 15083 createElement( 15084 "a", 15085 __assign( 15086 { 15087 className: ["fc-daygrid-event", "fc-daygrid-dot-event"] 15088 .concat(classNames) 15089 .join(" "), 15090 ref: rootElRef, 15091 }, 15092 getSegAnchorAttrs$1(props.seg) 15093 ), 15094 innerContent 15095 ) 15096 ); 15097 } 15098 ); 15099 }; 15100 return TableListItemEvent; 15101 })(BaseComponent); 15102 function renderInnerContent$2(innerProps) { 15103 return createElement( 15104 Fragment, 15105 null, 15106 createElement("div", { 15107 className: "fc-daygrid-event-dot", 15108 style: { 15109 borderColor: innerProps.borderColor || innerProps.backgroundColor, 15110 }, 15111 }), 15112 innerProps.timeText && 15113 createElement( 15114 "div", 15115 { className: "fc-event-time" }, 15116 innerProps.timeText 15117 ), 15118 createElement( 15119 "div", 15120 { className: "fc-event-title" }, 15121 innerProps.event.title || createElement(Fragment, null, "\u00A0") 15122 ) 15123 ); 15124 } 15125 function getSegAnchorAttrs$1(seg) { 15126 var url = seg.eventRange.def.url; 15127 return url ? { href: url } : {}; 15128 } 15129 15130 var TableBlockEvent = /** @class */ (function (_super) { 15131 __extends(TableBlockEvent, _super); 15132 function TableBlockEvent() { 15133 return (_super !== null && _super.apply(this, arguments)) || this; 15134 } 15135 TableBlockEvent.prototype.render = function () { 15136 var props = this.props; 15137 return createElement( 15138 StandardEvent, 15139 __assign({}, props, { 15140 extraClassNames: [
15141 "fc-daygrid-event", 15142 "fc-daygrid-block-event", 15143 "fc-h-event", 15144 ], 15145 defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, 15146 defaultDisplayEventEnd: props.defaultDisplayEventEnd, 15147 disableResizing: !props.seg.eventRange.def.allDay, 15148 }) 15149 ); 15150 }; 15151 return TableBlockEvent; 15152 })(BaseComponent); 15153 15154 function computeFgSegPlacement( // for one row. TODO: print mode? 15155 cellModels, 15156 segs, 15157 dayMaxEvents, 15158 dayMaxEventRows, 15159 eventHeights, 15160 maxContentHeight, 15161 colCnt, 15162 eventOrderSpecs 15163 ) { 15164 var colPlacements = []; // if event spans multiple cols, its present in each col 15165 var moreCnts = []; // by-col 15166 var segIsHidden = {}; 15167 var segTops = {}; // always populated for each seg 15168 var segMarginTops = {}; // simetimes populated for each seg 15169 var moreTops = {}; 15170 var paddingBottoms = {}; // for each cell's inner-wrapper div 15171 for (var i = 0; i < colCnt; i++) { 15172 colPlacements.push([]); 15173 moreCnts.push(0); 15174 } 15175 segs = sortEventSegs(segs, eventOrderSpecs); 15176 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 15177 var seg = segs_1[_i]; 15178 var instanceId = seg.eventRange.instance.instanceId; 15179 var eventHeight = eventHeights[instanceId + ":" + seg.firstCol]; 15180 placeSeg(seg, eventHeight || 0); // will keep colPlacements sorted by top 15181 } 15182 if (dayMaxEvents === true || dayMaxEventRows === true) { 15183 limitByMaxHeight(moreCnts, segIsHidden, colPlacements, maxContentHeight); // populates moreCnts/segIsHidden 15184 } else if (typeof dayMaxEvents === "number") { 15185 limitByMaxEvents(moreCnts, segIsHidden, colPlacements, dayMaxEvents); // populates moreCnts/segIsHidden 15186 } else if (typeof dayMaxEventRows === "number") { 15187 limitByMaxRows(moreCnts, segIsHidden, colPlacements, dayMaxEventRows); // populates moreCnts/segIsHidden 15188 } 15189 // computes segTops/segMarginTops/moreTops/paddingBottoms 15190 for (var col = 0; col < colCnt; col++) { 15191 var placements = colPlacements[col]; 15192 var currentNonAbsBottom = 0; 15193 var runningAbsHeight = 0; 15194 for ( 15195 var _a = 0, placements_1 = placements; 15196 _a < placements_1.length; 15197 _a++ 15198 ) { 15199 var placement = placements_1[_a]; 15200 var seg = placement.seg; 15201 if (!segIsHidden[seg.eventRange.instance.instanceId]) { 15202 segTops[seg.eventRange.instance.instanceId] = placement.top; // from top of container 15203 if (seg.firstCol === seg.lastCol && seg.isStart && seg.isEnd) { 15204 // TODO: simpler way? NOT DRY 15205 segMarginTops[seg.eventRange.instance.instanceId] = 15206 placement.top - currentNonAbsBottom; // from previous seg bottom 15207 runningAbsHeight = 0; 15208 currentNonAbsBottom = placement.bottom; 15209 } else { 15210 // multi-col event, abs positioned 15211 runningAbsHeight += placement.bottom - placement.top; 15212 } 15213 } 15214 } 15215 if (runningAbsHeight) { 15216 if (moreCnts[col]) { 15217 moreTops[col] = runningAbsHeight; 15218 } else { 15219 paddingBottoms[col] = runningAbsHeight; 15220 } 15221 } 15222 } 15223 function placeSeg(seg, segHeight) { 15224 if (!tryPlaceSegAt(seg, segHeight, 0)) { 15225 for (var col = seg.firstCol; col <= seg.lastCol; col++) { 15226 for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) { 15227 // will repeat multi-day segs!!!!!!! bad!!!!!! 15228 var placement = _a[_i]; 15229 if (tryPlaceSegAt(seg, segHeight, placement.bottom)) { 15230 return; 15231 } 15232 } 15233 } 15234 } 15235 } 15236 function tryPlaceSegAt(seg, segHeight, top) { 15237 if (canPlaceSegAt(seg, segHeight, top)) { 15238 for (var col = seg.firstCol; col <= seg.lastCol; col++) { 15239 var placements = colPlacements[col]; 15240 var insertionIndex = 0; 15241 while ( 15242 insertionIndex < placements.length && 15243 top >= placements[insertionIndex].top 15244 ) { 15245 insertionIndex++; 15246 } 15247 placements.splice(insertionIndex, 0, { 15248 seg: seg, 15249 top: top, 15250 bottom: top + segHeight, 15251 }); 15252 } 15253 return true; 15254 } else { 15255 return false;
15256 } 15257 } 15258 function canPlaceSegAt(seg, segHeight, top) { 15259 for (var col = seg.firstCol; col <= seg.lastCol; col++) { 15260 for (var _i = 0, _a = colPlacements[col]; _i < _a.length; _i++) { 15261 var placement = _a[_i]; 15262 if (top < placement.bottom && top + segHeight > placement.top) { 15263 // collide? 15264 return false; 15265 } 15266 } 15267 } 15268 return true; 15269 } 15270 // what does this do!? 15271 for (var instanceIdAndFirstCol in eventHeights) { 15272 if (!eventHeights[instanceIdAndFirstCol]) { 15273 segIsHidden[instanceIdAndFirstCol.split(":")[0]] = true; 15274 } 15275 } 15276 var segsByFirstCol = colPlacements.map(extractFirstColSegs); // operates on the sorted cols 15277 var segsByEachCol = colPlacements.map(function (placements, col) { 15278 var segs = extractAllColSegs(placements); 15279 segs = resliceDaySegs(segs, cellModels[col].date, col); 15280 return segs; 15281 }); 15282 return { 15283 segsByFirstCol: segsByFirstCol, 15284 segsByEachCol: segsByEachCol, 15285 segIsHidden: segIsHidden, 15286 segTops: segTops, 15287 segMarginTops: segMarginTops, 15288 moreCnts: moreCnts, 15289 moreTops: moreTops, 15290 paddingBottoms: paddingBottoms, 15291 }; 15292 } 15293 function extractFirstColSegs(oneColPlacements, col) { 15294 var segs = []; 15295 for ( 15296 var _i = 0, oneColPlacements_1 = oneColPlacements; 15297 _i < oneColPlacements_1.length; 15298 _i++ 15299 ) { 15300 var placement = oneColPlacements_1[_i]; 15301 if (placement.seg.firstCol === col) { 15302 segs.push(placement.seg); 15303 } 15304 } 15305 return segs; 15306 } 15307 function extractAllColSegs(oneColPlacements) { 15308 var segs = []; 15309 for ( 15310 var _i = 0, oneColPlacements_2 = oneColPlacements; 15311 _i < oneColPlacements_2.length; 15312 _i++ 15313 ) { 15314 var placement = oneColPlacements_2[_i]; 15315 segs.push(placement.seg); 15316 } 15317 return segs; 15318 } 15319 function limitByMaxHeight( 15320 hiddenCnts, 15321 segIsHidden, 15322 colPlacements, 15323 maxContentHeight 15324 ) { 15325 limitEvents( 15326 hiddenCnts, 15327 segIsHidden, 15328 colPlacements, 15329 true, 15330 function (placement) { 15331 return placement.bottom <= maxContentHeight; 15332 } 15333 ); 15334 } 15335 function limitByMaxEvents( 15336 hiddenCnts, 15337 segIsHidden, 15338 colPlacements, 15339 dayMaxEvents 15340 ) { 15341 limitEvents( 15342 hiddenCnts, 15343 segIsHidden, 15344 colPlacements, 15345 false, 15346 function (placement, levelIndex) { 15347 return levelIndex < dayMaxEvents; 15348 } 15349 ); 15350 } 15351 function limitByMaxRows( 15352 hiddenCnts, 15353 segIsHidden, 15354 colPlacements, 15355 dayMaxEventRows 15356 ) { 15357 limitEvents( 15358 hiddenCnts, 15359 segIsHidden, 15360 colPlacements, 15361 true, 15362 function (placement, levelIndex) { 15363 return levelIndex < dayMaxEventRows; 15364 } 15365 ); 15366 } 15367 /* 15368 populates the given hiddenCnts/segIsHidden, which are supplied empty. 15369 TODO: return them instead 15370 */ 15371 function limitEvents( 15372 hiddenCnts, 15373 segIsHidden, 15374 colPlacements, 15375 moreLinkConsumesLevel, 15376 isPlacementInBounds 15377 ) { 15378 var colCnt = hiddenCnts.length; 15379 var segIsVisible = {}; // TODO: instead, use segIsHidden with true/false? 15380 var visibleColPlacements = []; // will mirror colPlacements 15381 for (var col = 0; col < colCnt; col++) { 15382 visibleColPlacements.push([]); 15383 } 15384 for (var col = 0; col < colCnt; col++) { 15385 var placements = colPlacements[col]; 15386 var level = 0; 15387 for ( 15388 var _i = 0, placements_2 = placements; 15389 _i < placements_2.length; 15390 _i++ 15391 ) { 15392 var placement = placements_2[_i]; 15393 if (isPlacementInBounds(placement, level)) { 15394 recordVisible(placement); 15395 } else { 15396 recordHidden(placement); 15397 } 15398 // only considered a level if the seg had height 15399 if (placement.top !== placement.bottom) { 15400 level++; 15401 } 15402 } 15403 } 15404 function recordVisible(placement) { 15405 var seg = placement.seg; 15406 var instanceId = seg.eventRange.instance.instanceId; 15407 if (!segIsVisible[instanceId]) { 15408 segIsVisible[instanceId] = true; 15409 for (var col = seg.firstCol; col <= seg.lastCol; col++) { 15410 visibleColPlacements[col].push(placement); 15411 } 15412 } 15413 } 15414 function recordHidden(placement) { 15415 var seg = placement.seg; 15416 var instanceId = seg.eventRange.instance.instanceId; 15417 if (!segIsHidden[instanceId]) { 15418 segIsHidden[instanceId] = true;
15419 for (var col = seg.firstCol; col <= seg.lastCol; col++) { 15420 var hiddenCnt = ++hiddenCnts[col]; 15421 if (moreLinkConsumesLevel && hiddenCnt === 1) { 15422 var lastVisiblePlacement = visibleColPlacements[col].pop(); 15423 if (lastVisiblePlacement) { 15424 recordHidden(lastVisiblePlacement); 15425 } 15426 } 15427 } 15428 } 15429 } 15430 } 15431 // Given the events within an array of segment objects, reslice them to be in a single day 15432 function resliceDaySegs(segs, dayDate, colIndex) { 15433 var dayStart = dayDate; 15434 var dayEnd = addDays(dayStart, 1); 15435 var dayRange = { start: dayStart, end: dayEnd }; 15436 var newSegs = []; 15437 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 15438 var seg = segs_2[_i]; 15439 var eventRange = seg.eventRange; 15440 var origRange = eventRange.range; 15441 var slicedRange = intersectRanges(origRange, dayRange); 15442 if (slicedRange) { 15443 newSegs.push( 15444 __assign(__assign({}, seg), { 15445 firstCol: colIndex, 15446 lastCol: colIndex, 15447 eventRange: { 15448 def: eventRange.def, 15449 ui: __assign(__assign({}, eventRange.ui), { 15450 durationEditable: false, 15451 }), 15452 instance: eventRange.instance, 15453 range: slicedRange, 15454 }, 15455 isStart: 15456 seg.isStart && 15457 slicedRange.start.valueOf() === origRange.start.valueOf(), 15458 isEnd: 15459 seg.isEnd && 15460 slicedRange.end.valueOf() === origRange.end.valueOf(), 15461 }) 15462 ); 15463 } 15464 } 15465 return newSegs; 15466 } 15467 15468 var TableRow = /** @class */ (function (_super) { 15469 __extends(TableRow, _super); 15470 function TableRow() { 15471 var _this = (_super !== null && _super.apply(this, arguments)) || this; 15472 _this.cellElRefs = new RefMap(); // the <td> 15473 _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame 15474 _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events 15475 _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol" 15476 _this.rootElRef = createRef(); 15477 _this.state = { 15478 framePositions: null, 15479 maxContentHeight: null, 15480 segHeights: {}, 15481 }; 15482 return _this; 15483 } 15484 TableRow.prototype.render = function () { 15485 var _this = this; 15486 var _a = this, 15487 props = _a.props, 15488 state = _a.state, 15489 context = _a.context; 15490 var colCnt = props.cells.length; 15491 var businessHoursByCol = splitSegsByFirstCol( 15492 props.businessHourSegs, 15493 colCnt 15494 ); 15495 var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 15496 var highlightSegsByCol = splitSegsByFirstCol( 15497 this.getHighlightSegs(), 15498 colCnt 15499 ); 15500 var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 15501 var _b = computeFgSegPlacement( 15502 props.cells, 15503 props.fgEventSegs, 15504 props.dayMaxEvents, 15505 props.dayMaxEventRows, 15506 state.segHeights, 15507 state.maxContentHeight, 15508 colCnt, 15509 context.options.eventOrder 15510 ), 15511 paddingBottoms = _b.paddingBottoms, 15512 segsByFirstCol = _b.segsByFirstCol, 15513 segsByEachCol = _b.segsByEachCol, 15514 segIsHidden = _b.segIsHidden, 15515 segTops = _b.segTops, 15516 segMarginTops = _b.segMarginTops, 15517 moreCnts = _b.moreCnts, 15518 moreTops = _b.moreTops; 15519 var selectedInstanceHash = // TODO: messy way to compute this 15520 (props.eventDrag && props.eventDrag.affectedInstances) || 15521 (props.eventResize && props.eventResize.affectedInstances) || 15522 {}; 15523 return createElement( 15524 "tr", 15525 { ref: this.rootElRef }, 15526 props.renderIntro && props.renderIntro(), 15527 props.cells.map(function (cell, col) { 15528 var normalFgNodes = _this.renderFgSegs( 15529 segsByFirstCol[col], 15530 segIsHidden, 15531 segTops, 15532 segMarginTops, 15533 selectedInstanceHash, 15534 props.todayRange 15535 ); 15536 var mirrorFgNodes = _this.renderFgSegs( 15537 mirrorSegsByCol[col], 15538 {}, 15539 segTops, // use same tops as real rendering 15540 {}, 15541 {}, 15542 props.todayRange, 15543 Boolean(props.eventDrag), 15544 Boolean(props.eventResize), 15545 false // date-selecting (because mirror is never drawn for date selection) 15546 ); 15547 return createElement(TableCell, { 15548 key: cell.key, 15549 elRef: _this.cellElRefs.createRef(cell.key), 15550 innerElRef: _this.frameElRefs.createRef( 15551 cell.key 15552 ) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, 15553 dateProfile: props.dateProfile, 15554 date: cell.date, 15555 showDayNumber: props.showDayNumbers, 15556 showWeekNumber: props.showWeekNumbers && col === 0, 15557 forceDayTop: 15558 props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, 15559 todayRange: props.todayRange, 15560 extraHookProps: cell.extraHookProps, 15561 extraDataAttrs: cell.extraDataAttrs, 15562 extraClassNames: cell.extraClassNames, 15563 moreCnt: moreCnts[col], 15564 buildMoreLinkText: props.buildMoreLinkText, 15565 onMoreClick: props.onMoreClick, 15566 segIsHidden: segIsHidden, 15567 moreMarginTop: moreTops[col] /* rename */, 15568 segsByEachCol: segsByEachCol[col], 15569 fgPaddingBottom: paddingBottoms[col], 15570 fgContentElRef: _this.fgElRefs.createRef(cell.key), 15571 // Fragment scopes the keys 15572 fgContent: createElement( 15573 Fragment, 15574 null, 15575 createElement(Fragment, null, normalFgNodes), 15576 createElement(Fragment, null, mirrorFgNodes) 15577 ), 15578 // Fragment scopes the keys 15579 bgContent: createElement( 15580 Fragment, 15581 null, 15582 _this.renderFillSegs(highlightSegsByCol[col], "highlight"), 15583 _this.renderFillSegs(businessHoursByCol[col], "non-business"), 15584 _this.renderFillSegs(bgEventSegsByCol[col], "bg-event") 15585 ), 15586 }); 15587 }) 15588 ); 15589 }; 15590 TableRow.prototype.componentDidMount = function () { 15591 this.updateSizing(true); 15592 }; 15593 TableRow.prototype.componentDidUpdate = function (prevProps, prevState) { 15594 var currentProps = this.props; 15595 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 15596 }; 15597 TableRow.prototype.getHighlightSegs = function () { 15598 var props = this.props; 15599 if (props.eventDrag && props.eventDrag.segs.length) { 15600 // messy check 15601 return props.eventDrag.segs; 15602 } else if (props.eventResize && props.eventResize.segs.length) { 15603 // messy check 15604 return props.eventResize.segs; 15605 } else { 15606 return props.dateSelectionSegs; 15607 } 15608 }; 15609 TableRow.prototype.getMirrorSegs = function () { 15610 var props = this.props; 15611 if (props.eventResize && props.eventResize.segs.length) { 15612 // messy check 15613 return props.eventResize.segs; 15614 } else { 15615 return []; 15616 } 15617 }; 15618 TableRow.prototype.renderFgSegs = function ( 15619 segs, 15620 segIsHidden, // does NOT mean display:hidden 15621 segTops, 15622 segMarginTops, 15623 selectedInstanceHash, 15624 todayRange, 15625 isDragging, 15626 isResizing, 15627 isDateSelecting 15628 ) { 15629 var context = this.context; 15630 var eventSelection = this.props.eventSelection; 15631 var framePositions = this.state.framePositions; 15632 var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1 15633 var nodes = []; 15634 if (framePositions) { 15635 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 15636 var seg = segs_1[_i]; 15637 var instanceId = seg.eventRange.instance.instanceId; 15638 var isMirror = isDragging || isResizing || isDateSelecting; 15639 var isSelected = selectedInstanceHash[instanceId]; 15640 var isInvisible = segIsHidden[instanceId] || isSelected; 15641 var isAbsolute = 15642 segIsHidden[instanceId] || 15643 isMirror || 15644 seg.firstCol !== seg.lastCol || 15645 !seg.isStart || 15646 !seg.isEnd; // TODO: simpler way? NOT DRY 15647 var marginTop = void 0; 15648 var top_1 = void 0; 15649 var left = void 0; 15650 var right = void 0; 15651 if (isAbsolute) { 15652 top_1 = segTops[instanceId]; 15653 if (context.isRtl) { 15654 right = 0; 15655 left = 15656 framePositions.lefts[seg.lastCol] - 15657 framePositions.lefts[seg.firstCol]; 15658 } else { 15659 left = 0; 15660 right = 15661 framePositions.rights[seg.firstCol] - 15662 framePositions.rights[seg.lastCol]; 15663 } 15664 } else { 15665 marginTop = segMarginTops[instanceId]; 15666 } 15667 /* 15668 known bug: events that are force to be list-item but span multiple days still take up space in later columns 15669 */ 15670 nodes.push( 15671 createElement( 15672 "div", 15673 { 15674 className:
15675 "fc-daygrid-event-harness" + 15676 (isAbsolute ? " fc-daygrid-event-harness-abs" : ""), 15677 key: instanceId, 15678 ref: isMirror 15679 ? null 15680 : this.segHarnessRefs.createRef( 15681 instanceId + ":" + seg.firstCol 15682 ) /* in print mode when in mult cols, could collide */, 15683 style: { 15684 visibility: isInvisible ? "hidden" : "", 15685 marginTop: marginTop || "", 15686 top: top_1 || "", 15687 left: left || "", 15688 right: right || "", 15689 }, 15690 }, 15691 hasListItemDisplay(seg) 15692 ? createElement( 15693 TableListItemEvent, 15694 __assign( 15695 { 15696 seg: seg, 15697 isDragging: isDragging, 15698 isSelected: instanceId === eventSelection, 15699 defaultDisplayEventEnd: defaultDisplayEventEnd, 15700 }, 15701 getSegMeta(seg, todayRange) 15702 ) 15703 ) 15704 : createElement( 15705 TableBlockEvent, 15706 __assign( 15707 { 15708 seg: seg, 15709 isDragging: isDragging, 15710 isResizing: isResizing, 15711 isDateSelecting: isDateSelecting, 15712 isSelected: instanceId === eventSelection, 15713 defaultDisplayEventEnd: defaultDisplayEventEnd, 15714 }, 15715 getSegMeta(seg, todayRange) 15716 ) 15717 ) 15718 ) 15719 ); 15720 } 15721 } 15722 return nodes; 15723 }; 15724 TableRow.prototype.renderFillSegs = function (segs, fillType) { 15725 var isRtl = this.context.isRtl; 15726 var todayRange = this.props.todayRange; 15727 var framePositions = this.state.framePositions; 15728 var nodes = []; 15729 if (framePositions) { 15730 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 15731 var seg = segs_2[_i]; 15732 var leftRightCss = isRtl 15733 ? { 15734 right: 0, 15735 left: 15736 framePositions.lefts[seg.lastCol] - 15737 framePositions.lefts[seg.firstCol], 15738 } 15739 : { 15740 left: 0, 15741 right: 15742 framePositions.rights[seg.firstCol] - 15743 framePositions.rights[seg.lastCol], 15744 }; 15745 nodes.push( 15746 createElement( 15747 "div", 15748 { 15749 key: buildEventRangeKey(seg.eventRange), 15750 className: "fc-daygrid-bg-harness", 15751 style: leftRightCss, 15752 }, 15753 fillType === "bg-event" 15754 ? createElement( 15755 BgEvent, 15756 __assign({ seg: seg }, getSegMeta(seg, todayRange)) 15757 ) 15758 : renderFill(fillType) 15759 ) 15760 ); 15761 } 15762 } 15763 return createElement.apply(void 0, __spreadArrays([Fragment, {}], nodes)); 15764 }; 15765 TableRow.prototype.updateSizing = function (isExternalSizingChange) { 15766 var _a = this, 15767 props = _a.props, 15768 frameElRefs = _a.frameElRefs; 15769 if (props.clientWidth !== null) { 15770 // positioning ready? 15771 if (isExternalSizingChange) { 15772 var frameEls = props.cells.map(function (cell) { 15773 return frameElRefs.currentMap[cell.key]; 15774 }); 15775 if (frameEls.length) { 15776 var originEl = this.rootElRef.current; 15777 this.setState({ 15778 framePositions: new PositionCache( 15779 originEl, 15780 frameEls, 15781 true, // isHorizontal 15782 false 15783 ), 15784 }); 15785 } 15786 } 15787 var limitByContentHeight = 15788 props.dayMaxEvents === true || props.dayMaxEventRows === true; 15789 this.setState({ 15790 segHeights: this.computeSegHeights(), 15791 maxContentHeight: limitByContentHeight 15792 ? this.computeMaxContentHeight() 15793 : null, 15794 }); 15795 } 15796 }; 15797 TableRow.prototype.computeSegHeights = function () { 15798 return mapHash(this.segHarnessRefs.currentMap, function (eventHarnessEl) { 15799 return eventHarnessEl.getBoundingClientRect().height; 15800 }); 15801 }; 15802 TableRow.prototype.computeMaxContentHeight = function () { 15803 var firstKey = this.props.cells[0].key; 15804 var cellEl = this.cellElRefs.currentMap[firstKey]; 15805 var fcContainerEl = this.fgElRefs.currentMap[firstKey]; 15806 return ( 15807 cellEl.getBoundingClientRect().bottom - 15808 fcContainerEl.getBoundingClientRect().top 15809 ); 15810 }; 15811 TableRow.prototype.getCellEls = function () { 15812 var elMap = this.cellElRefs.currentMap; 15813 return this.props.cells.map(function (cell) { 15814 return elMap[cell.key]; 15815 }); 15816 }; 15817 return TableRow; 15818 })(DateComponent); 15819 TableRow.addStateEquality({ 15820 segHeights: isPropsEqual, 15821 }); 15822 15823 var PADDING_FROM_VIEWPORT = 10; 15824 var SCROLL_DEBOUNCE = 10; 15825 var Popover = /** @class */ (function (_super) { 15826 __extends(Popover, _super); 15827 function Popover() { 15828 var _this = (_super !== null && _super.apply(this, arguments)) || this; 15829 _this.repositioner = new DelayedRunner(_this.updateSize.bind(_this)); 15830 _this.handleRootEl = function (el) { 15831 _this.rootEl = el; 15832 if (_this.props.elRef) { 15833 setRef(_this.props.elRef, el); 15834 } 15835 }; 15836 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 15837 _this.handleDocumentMousedown = function (ev) { 15838 var onClose = _this.props.onClose; 15839 // only hide the popover if the click happened outside the popover 15840 if (onClose && !_this.rootEl.contains(ev.target)) { 15841 onClose(); 15842 } 15843 }; 15844 _this.handleDocumentScroll = function () { 15845 _this.repositioner.request(SCROLL_DEBOUNCE); 15846 }; 15847 _this.handleCloseClick = function () { 15848 var onClose = _this.props.onClose; 15849 if (onClose) { 15850 onClose(); 15851 } 15852 }; 15853 return _this; 15854 } 15855 Popover.prototype.render = function () { 15856 var theme = this.context.theme; 15857 var props = this.props; 15858 var classNames = ["fc-popover", theme.getClass("popover")].concat( 15859 props.extraClassNames || [] 15860 ); 15861 return createElement( 15862 "div", 15863 __assign({ className: classNames.join(" ") }, props.extraAttrs, { 15864 ref: this.handleRootEl, 15865 }), 15866 createElement( 15867 "div", 15868 { className: "fc-popover-header " + theme.getClass("popoverHeader") }, 15869 createElement("span", { className: "fc-popover-title" }, props.title), 15870 createElement("span", { 15871 className: "fc-popover-close " + theme.getIconClass("close"), 15872 onClick: this.handleCloseClick, 15873 }) 15874 ), 15875 createElement( 15876 "div", 15877 { className: "fc-popover-body " + theme.getClass("popoverContent") },
15878 props.children 15879 ) 15880 ); 15881 }; 15882 Popover.prototype.componentDidMount = function () { 15883 document.addEventListener("mousedown", this.handleDocumentMousedown); 15884 document.addEventListener("scroll", this.handleDocumentScroll); 15885 this.updateSize(); 15886 }; 15887 Popover.prototype.componentWillUnmount = function () { 15888 document.removeEventListener("mousedown", this.handleDocumentMousedown); 15889 document.removeEventListener("scroll", this.handleDocumentScroll); 15890 }; 15891 // TODO: adjust on window resize 15892 /* 15893 NOTE: the popover is position:fixed, so coordinates are relative to the viewport 15894 NOTE: the PARENT calls this as well, on window resize. we would have wanted to use the repositioner, 15895 but need to ensure that all other components have updated size first (for alignmentEl) 15896 */ 15897 Popover.prototype.updateSize = function () { 15898 var _a = this.props, 15899 alignmentEl = _a.alignmentEl, 15900 topAlignmentEl = _a.topAlignmentEl; 15901 var rootEl = this.rootEl; 15902 if (!rootEl) { 15903 return; // not sure why this was null, but we shouldn't let external components call updateSize() anyway 15904 } 15905 var dims = rootEl.getBoundingClientRect(); // only used for width,height 15906 var alignment = alignmentEl.getBoundingClientRect(); 15907 var top = topAlignmentEl 15908 ? topAlignmentEl.getBoundingClientRect().top 15909 : alignment.top; 15910 top = Math.min( 15911 top, 15912 window.innerHeight - dims.height - PADDING_FROM_VIEWPORT 15913 ); 15914 top = Math.max(top, PADDING_FROM_VIEWPORT); 15915 var left; 15916 if (this.context.isRtl) { 15917 left = alignment.right - dims.width; 15918 } else { 15919 left = alignment.left; 15920 } 15921 left = Math.min( 15922 left, 15923 window.innerWidth - dims.width - PADDING_FROM_VIEWPORT 15924 ); 15925 left = Math.max(left, PADDING_FROM_VIEWPORT); 15926 applyStyle(rootEl, { top: top, left: left }); 15927 }; 15928 return Popover; 15929 })(BaseComponent); 15930 15931 var MorePopover = /** @class */ (function (_super) { 15932 __extends(MorePopover, _super); 15933 function MorePopover() { 15934 var _this = (_super !== null && _super.apply(this, arguments)) || this; 15935 _this.handlePopoverEl = function (popoverEl) { 15936 _this.popoverEl = popoverEl; 15937 if (popoverEl) { 15938 _this.context.registerInteractiveComponent(_this, { 15939 el: popoverEl, 15940 useEventCenter: false, 15941 }); 15942 } else { 15943 _this.context.unregisterInteractiveComponent(_this); 15944 } 15945 }; 15946 return _this; 15947 } 15948 MorePopover.prototype.render = function () { 15949 var _a = this.context, 15950 options = _a.options, 15951 dateEnv = _a.dateEnv; 15952 var props = this.props; 15953 var date = props.date, 15954 hiddenInstances = props.hiddenInstances, 15955 todayRange = props.todayRange, 15956 dateProfile = props.dateProfile, 15957 selectedInstanceId = props.selectedInstanceId; 15958 var title = dateEnv.format(date, options.dayPopoverFormat); 15959 return createElement( 15960 DayCellRoot, 15961 { 15962 date: date, 15963 dateProfile: dateProfile, 15964 todayRange: todayRange, 15965 elRef: this.handlePopoverEl, 15966 }, 15967 function (rootElRef, dayClassNames, dataAttrs) { 15968 return createElement( 15969 Popover, 15970 { 15971 elRef: rootElRef, 15972 title: title, 15973 extraClassNames: ["fc-more-popover"].concat(dayClassNames), 15974 extraAttrs: dataAttrs, 15975 onClose: props.onCloseClick, 15976 alignmentEl: props.alignmentEl, 15977 topAlignmentEl: props.topAlignmentEl, 15978 }, 15979 createElement( 15980 DayCellContent, 15981 { date: date, dateProfile: dateProfile, todayRange: todayRange }, 15982 function (innerElRef, innerContent) { 15983 return ( 15984 innerContent && 15985 createElement( 15986 "div", 15987 { className: "fc-more-popover-misc", ref: innerElRef }, 15988 innerContent 15989 ) 15990 ); 15991 } 15992 ), 15993 props.segs.map(function (seg) { 15994 var instanceId = seg.eventRange.instance.instanceId; 15995 return createElement( 15996 "div", 15997 {
15998 className: "fc-daygrid-event-harness", 15999 key: instanceId, 16000 style: { 16001 visibility: hiddenInstances[instanceId] ? "hidden" : "", 16002 }, 16003 }, 16004 hasListItemDisplay(seg) 16005 ? createElement( 16006 TableListItemEvent, 16007 __assign( 16008 { 16009 seg: seg, 16010 isDragging: false, 16011 isSelected: instanceId === selectedInstanceId, 16012 defaultDisplayEventEnd: false, 16013 }, 16014 getSegMeta(seg, todayRange) 16015 ) 16016 ) 16017 : createElement( 16018 TableBlockEvent, 16019 __assign( 16020 { 16021 seg: seg, 16022 isDragging: false, 16023 isResizing: false, 16024 isDateSelecting: false, 16025 isSelected: instanceId === selectedInstanceId, 16026 defaultDisplayEventEnd: false, 16027 }, 16028 getSegMeta(seg, todayRange) 16029 ) 16030 ) 16031 ); 16032 }) 16033 ); 16034 } 16035 ); 16036 }; 16037 MorePopover.prototype.queryHit = function ( 16038 positionLeft, 16039 positionTop, 16040 elWidth, 16041 elHeight 16042 ) { 16043 var date = this.props.date; 16044 if (positionLeft < elWidth && positionTop < elHeight) { 16045 return { 16046 component: this, 16047 dateSpan: { 16048 allDay: true, 16049 range: { start: date, end: addDays(date, 1) }, 16050 }, 16051 dayEl: this.popoverEl, 16052 rect: { 16053 left: 0, 16054 top: 0, 16055 right: elWidth, 16056 bottom: elHeight, 16057 }, 16058 layer: 1, 16059 }; 16060 } 16061 }; 16062 MorePopover.prototype.isPopover = function () { 16063 return true; // gross 16064 }; 16065 return MorePopover; 16066 })(DateComponent); 16067 16068 var Table = /** @class */ (function (_super) { 16069 __extends(Table, _super); 16070 function Table() { 16071 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16072 _this.splitBusinessHourSegs = memoize(splitSegsByRow); 16073 _this.splitBgEventSegs = memoize(splitSegsByRow); 16074 _this.splitFgEventSegs = memoize(splitSegsByRow); 16075 _this.splitDateSelectionSegs = memoize(splitSegsByRow); 16076 _this.splitEventDrag = memoize(splitInteractionByRow); 16077 _this.splitEventResize = memoize(splitInteractionByRow); 16078 _this.buildBuildMoreLinkText = memoize(buildBuildMoreLinkText); 16079 _this.rowRefs = new RefMap(); 16080 _this.state = { 16081 morePopoverState: null, 16082 }; 16083 _this.handleRootEl = function (rootEl) { 16084 _this.rootEl = rootEl; 16085 setRef(_this.props.elRef, rootEl); 16086 }; 16087 _this.handleMoreLinkClick = function (arg) { 16088 var context = _this.context; 16089 var dateEnv = context.dateEnv; 16090 var clickOption = context.options.moreLinkClick; 16091 function segForPublic(seg) { 16092 var _a = seg.eventRange, 16093 def = _a.def, 16094 instance = _a.instance, 16095 range = _a.range; 16096 return { 16097 event: new EventApi(context, def, instance), 16098 start: dateEnv.toDate(range.start), 16099 end: dateEnv.toDate(range.end), 16100 isStart: seg.isStart, 16101 isEnd: seg.isEnd, 16102 }; 16103 } 16104 if (typeof clickOption === "function") { 16105 clickOption = clickOption({ 16106 date: dateEnv.toDate(arg.date), 16107 allDay: true, 16108 allSegs: arg.allSegs.map(segForPublic), 16109 hiddenSegs: arg.hiddenSegs.map(segForPublic), 16110 jsEvent: arg.ev, 16111 view: context.viewApi, 16112 }); // hack to handle void 16113 } 16114 if (!clickOption || clickOption === "popover") { 16115 _this.setState({ 16116 morePopoverState: __assign(__assign({}, arg), { 16117 currentFgEventSegs: _this.props.fgEventSegs, 16118 }), 16119 }); 16120 } else if (typeof clickOption === "string") {
16121 // a view name 16122 context.calendarApi.zoomTo(arg.date, clickOption); 16123 } 16124 }; 16125 _this.handleMorePopoverClose = function () { 16126 _this.setState({ 16127 morePopoverState: null, 16128 }); 16129 }; 16130 return _this; 16131 } 16132 Table.prototype.render = function () { 16133 var _this = this; 16134 var props = this.props; 16135 var dateProfile = props.dateProfile, 16136 dayMaxEventRows = props.dayMaxEventRows, 16137 dayMaxEvents = props.dayMaxEvents, 16138 expandRows = props.expandRows; 16139 var morePopoverState = this.state.morePopoverState; 16140 var rowCnt = props.cells.length; 16141 var businessHourSegsByRow = this.splitBusinessHourSegs( 16142 props.businessHourSegs, 16143 rowCnt 16144 ); 16145 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 16146 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 16147 var dateSelectionSegsByRow = this.splitDateSelectionSegs( 16148 props.dateSelectionSegs, 16149 rowCnt 16150 ); 16151 var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 16152 var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt); 16153 var buildMoreLinkText = this.buildBuildMoreLinkText( 16154 this.context.options.moreLinkText 16155 ); 16156 var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 16157 // if rows can't expand to fill fixed height, can't do balanced-height event limit 16158 // TODO: best place to normalize these options? 16159 if (limitViaBalanced && !expandRows) { 16160 limitViaBalanced = false; 16161 dayMaxEventRows = null; 16162 dayMaxEvents = null; 16163 } 16164 var classNames = [
16165 "fc-daygrid-body", 16166 limitViaBalanced 16167 ? "fc-daygrid-body-balanced" 16168 : "fc-daygrid-body-unbalanced", 16169 expandRows ? "" : "fc-daygrid-body-natural", // will height of one row depend on the others? 16170 ]; 16171 return createElement( 16172 "div", 16173 { 16174 className: classNames.join(" "), 16175 ref: this.handleRootEl, 16176 style: { 16177 // these props are important to give this wrapper correct dimensions for interactions 16178 // TODO: if we set it here, can we avoid giving to inner tables? 16179 width: props.clientWidth, 16180 minWidth: props.tableMinWidth, 16181 }, 16182 }, 16183 createElement( 16184 NowTimer, 16185 { unit: "day" }, 16186 function (nowDate, todayRange) { 16187 return createElement( 16188 Fragment, 16189 null, 16190 createElement( 16191 "table", 16192 { 16193 className: "fc-scrollgrid-sync-table", 16194 style: { 16195 width: props.clientWidth, 16196 minWidth: props.tableMinWidth, 16197 height: expandRows ? props.clientHeight : "", 16198 }, 16199 }, 16200 props.colGroupNode, 16201 createElement( 16202 "tbody", 16203 null, 16204 props.cells.map(function (cells, row) { 16205 return createElement(TableRow, { 16206 ref: _this.rowRefs.createRef(row), 16207 key: cells.length 16208 ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ 16209 : row, // in case there are no cells (like when resource view is loading) 16210 showDayNumbers: rowCnt > 1, 16211 showWeekNumbers: props.showWeekNumbers, 16212 todayRange: todayRange, 16213 dateProfile: dateProfile, 16214 cells: cells, 16215 renderIntro: props.renderRowIntro, 16216 businessHourSegs: businessHourSegsByRow[row], 16217 eventSelection: props.eventSelection, 16218 bgEventSegs: 16219 bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, 16220 fgEventSegs: fgEventSegsByRow[row], 16221 dateSelectionSegs: dateSelectionSegsByRow[row], 16222 eventDrag: eventDragByRow[row], 16223 eventResize: eventResizeByRow[row], 16224 dayMaxEvents: dayMaxEvents, 16225 dayMaxEventRows: dayMaxEventRows, 16226 clientWidth: props.clientWidth, 16227 clientHeight: props.clientHeight, 16228 buildMoreLinkText: buildMoreLinkText, 16229 onMoreClick: _this.handleMoreLinkClick, 16230 }); 16231 }) 16232 ) 16233 ), 16234 !props.forPrint && 16235 morePopoverState && 16236 morePopoverState.currentFgEventSegs === props.fgEventSegs && // clear popover on event mod 16237 createElement(MorePopover, { 16238 date: morePopoverState.date, 16239 dateProfile: dateProfile, 16240 segs: morePopoverState.allSegs, 16241 alignmentEl: morePopoverState.dayEl, 16242 topAlignmentEl: 16243 rowCnt === 1 ? props.headerAlignElRef.current : null, 16244 onCloseClick: _this.handleMorePopoverClose, 16245 selectedInstanceId: props.eventSelection, 16246 // yuck 16247 hiddenInstances: 16248 (props.eventDrag 16249 ? props.eventDrag.affectedInstances 16250 : null) || 16251 (props.eventResize 16252 ? props.eventResize.affectedInstances 16253 : null) || 16254 {}, 16255 todayRange: todayRange, 16256 }) 16257 ); 16258 } 16259 ) 16260 ); 16261 }; 16262 // Hit System 16263 // ---------------------------------------------------------------------------------------------------- 16264 Table.prototype.prepareHits = function () { 16265 this.rowPositions = new PositionCache( 16266 this.rootEl, 16267 this.rowRefs.collect().map(function (rowObj) { 16268 return rowObj.getCellEls()[0]; 16269 }), // first cell el in each row. TODO: not optimal 16270 false, 16271 true // vertical 16272 ); 16273 this.colPositions = new PositionCache( 16274 this.rootEl, 16275 this.rowRefs.currentMap[0].getCellEls(), // cell els in first row 16276 true, // horizontal 16277 false 16278 ); 16279 }; 16280 Table.prototype.positionToHit = function (leftPosition, topPosition) { 16281 var _a = this, 16282 colPositions = _a.colPositions, 16283 rowPositions = _a.rowPositions; 16284 var col = colPositions.leftToIndex(leftPosition); 16285 var row = rowPositions.topToIndex(topPosition); 16286 if (row != null && col != null) { 16287 return { 16288 row: row, 16289 col: col, 16290 dateSpan: { 16291 range: this.getCellRange(row, col), 16292 allDay: true, 16293 }, 16294 dayEl: this.getCellEl(row, col), 16295 relativeRect: { 16296 left: colPositions.lefts[col], 16297 right: colPositions.rights[col], 16298 top: rowPositions.tops[row], 16299 bottom: rowPositions.bottoms[row], 16300 }, 16301 }; 16302 } 16303 }; 16304 Table.prototype.getCellEl = function (row, col) { 16305 return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal 16306 }; 16307 Table.prototype.getCellRange = function (row, col) { 16308 var start = this.props.cells[row][col].date; 16309 var end = addDays(start, 1); 16310 return { start: start, end: end }; 16311 }; 16312 return Table; 16313 })(DateComponent); 16314 function buildBuildMoreLinkText(moreLinkTextInput) { 16315 if (typeof moreLinkTextInput === "function") { 16316 return moreLinkTextInput; 16317 } else { 16318 return function (num) { 16319 return "+" + num + " " + moreLinkTextInput; 16320 }; 16321 } 16322 } 16323 function isSegAllDay(seg) { 16324 return seg.eventRange.def.allDay; 16325 } 16326 16327 var DayTable = /** @class */ (function (_super) { 16328 __extends(DayTable, _super); 16329 function DayTable() { 16330 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16331 _this.slicer = new DayTableSlicer(); 16332 _this.tableRef = createRef(); 16333 _this.handleRootEl = function (rootEl) { 16334 if (rootEl) { 16335 _this.context.registerInteractiveComponent(_this, { el: rootEl }); 16336 } else { 16337 _this.context.unregisterInteractiveComponent(_this); 16338 } 16339 }; 16340 return _this; 16341 } 16342 DayTable.prototype.render = function () { 16343 var _a = this, 16344 props = _a.props, 16345 context = _a.context; 16346 return createElement( 16347 Table, 16348 __assign( 16349 { ref: this.tableRef, elRef: this.handleRootEl }, 16350 this.slicer.sliceProps( 16351 props, 16352 props.dateProfile, 16353 props.nextDayThreshold, 16354 context, 16355 props.dayTableModel 16356 ), 16357 { 16358 dateProfile: props.dateProfile, 16359 cells: props.dayTableModel.cells, 16360 colGroupNode: props.colGroupNode, 16361 tableMinWidth: props.tableMinWidth, 16362 renderRowIntro: props.renderRowIntro, 16363 dayMaxEvents: props.dayMaxEvents, 16364 dayMaxEventRows: props.dayMaxEventRows, 16365 showWeekNumbers: props.showWeekNumbers, 16366 expandRows: props.expandRows, 16367 headerAlignElRef: props.headerAlignElRef, 16368 clientWidth: props.clientWidth, 16369 clientHeight: props.clientHeight, 16370 forPrint: props.forPrint, 16371 } 16372 ) 16373 ); 16374 }; 16375 DayTable.prototype.prepareHits = function () { 16376 this.tableRef.current.prepareHits(); 16377 }; 16378 DayTable.prototype.queryHit = function (positionLeft, positionTop) { 16379 var rawHit = this.tableRef.current.positionToHit( 16380 positionLeft, 16381 positionTop 16382 ); 16383 if (rawHit) { 16384 return { 16385 component: this, 16386 dateSpan: rawHit.dateSpan, 16387 dayEl: rawHit.dayEl, 16388 rect: { 16389 left: rawHit.relativeRect.left, 16390 right: rawHit.relativeRect.right, 16391 top: rawHit.relativeRect.top, 16392 bottom: rawHit.relativeRect.bottom, 16393 }, 16394 layer: 0, 16395 }; 16396 } 16397 }; 16398 return DayTable; 16399 })(DateComponent); 16400 var DayTableSlicer = /** @class */ (function (_super) { 16401 __extends(DayTableSlicer, _super); 16402 function DayTableSlicer() { 16403 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16404 _this.forceDayIfListItem = true; 16405 return _this; 16406 } 16407 DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) { 16408 return dayTableModel.sliceRange(dateRange); 16409 }; 16410 return DayTableSlicer; 16411 })(Slicer); 16412 16413 var DayTableView = /** @class */ (function (_super) { 16414 __extends(DayTableView, _super); 16415 function DayTableView() { 16416 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16417 _this.buildDayTableModel = memoize(buildDayTableModel); 16418 _this.headerRef = createRef(); 16419 _this.tableRef = createRef(); 16420 return _this; 16421 } 16422 DayTableView.prototype.render = function () { 16423 var _this = this; 16424 var _a = this.context, 16425 options = _a.options, 16426 dateProfileGenerator = _a.dateProfileGenerator; 16427 var props = this.props; 16428 var dayTableModel = this.buildDayTableModel( 16429 props.dateProfile, 16430 dateProfileGenerator 16431 ); 16432 var headerContent = 16433 options.dayHeaders && 16434 createElement(DayHeader, { 16435 ref: this.headerRef, 16436 dateProfile: props.dateProfile, 16437 dates: dayTableModel.headerDates, 16438 datesRepDistinctDays: dayTableModel.rowCnt === 1, 16439 }); 16440 var bodyContent = function (contentArg) { 16441 return createElement(DayTable, { 16442 ref: _this.tableRef, 16443 dateProfile: props.dateProfile, 16444 dayTableModel: dayTableModel, 16445 businessHours: props.businessHours, 16446 dateSelection: props.dateSelection, 16447 eventStore: props.eventStore, 16448 eventUiBases: props.eventUiBases, 16449 eventSelection: props.eventSelection, 16450 eventDrag: props.eventDrag, 16451 eventResize: props.eventResize, 16452 nextDayThreshold: options.nextDayThreshold, 16453 colGroupNode: contentArg.tableColGroupNode, 16454 tableMinWidth: contentArg.tableMinWidth, 16455 dayMaxEvents: options.dayMaxEvents, 16456 dayMaxEventRows: options.dayMaxEventRows, 16457 showWeekNumbers: options.weekNumbers, 16458 expandRows: !props.isHeightAuto, 16459 headerAlignElRef: _this.headerElRef, 16460 clientWidth: contentArg.clientWidth, 16461 clientHeight: contentArg.clientHeight, 16462 forPrint: props.forPrint, 16463 }); 16464 }; 16465 return options.dayMinWidth 16466 ? this.renderHScrollLayout( 16467 headerContent, 16468 bodyContent, 16469 dayTableModel.colCnt, 16470 options.dayMinWidth 16471 ) 16472 : this.renderSimpleLayout(headerContent, bodyContent); 16473 }; 16474 return DayTableView; 16475 })(TableView); 16476 function buildDayTableModel(dateProfile, dateProfileGenerator) {
16477 var daySeries = new DaySeriesModel( 16478 dateProfile.renderRange, 16479 dateProfileGenerator 16480 ); 16481 return new DayTableModel( 16482 daySeries, 16483 /year|month|week/.test(dateProfile.currentRangeUnit) 16484 ); 16485 } 16486 16487 var TableDateProfileGenerator = /** @class */ (function (_super) { 16488 __extends(TableDateProfileGenerator, _super); 16489 function TableDateProfileGenerator() { 16490 return (_super !== null && _super.apply(this, arguments)) || this; 16491 } 16492 // Computes the date range that will be rendered. 16493 TableDateProfileGenerator.prototype.buildRenderRange = function ( 16494 currentRange, 16495 currentRangeUnit, 16496 isRangeAllDay 16497 ) { 16498 var dateEnv = this.props.dateEnv; 16499 var renderRange = _super.prototype.buildRenderRange.call( 16500 this, 16501 currentRange, 16502 currentRangeUnit, 16503 isRangeAllDay 16504 ); 16505 var start = renderRange.start; 16506 var end = renderRange.end; 16507 var endOfWeek; 16508 // year and month views should be aligned with weeks. this is already done for week 16509 if (/^(year|month)$/.test(currentRangeUnit)) { 16510 start = dateEnv.startOfWeek(start); 16511 // make end-of-week if not already 16512 endOfWeek = dateEnv.startOfWeek(end); 16513 if (endOfWeek.valueOf() !== end.valueOf()) { 16514 end = addWeeks(endOfWeek, 1); 16515 } 16516 } 16517 // ensure 6 weeks 16518 if (this.props.monthMode && this.props.fixedWeekCount) { 16519 var rowCnt = Math.ceil( 16520 // could be partial weeks due to hiddenDays 16521 diffWeeks(start, end) 16522 ); 16523 end = addWeeks(end, 6 - rowCnt); 16524 } 16525 return { start: start, end: end }; 16526 }; 16527 return TableDateProfileGenerator; 16528 })(DateProfileGenerator); 16529 16530 var OPTION_REFINERS = { 16531 moreLinkClick: identity, 16532 moreLinkClassNames: identity, 16533 moreLinkContent: identity, 16534 moreLinkDidMount: identity, 16535 moreLinkWillUnmount: identity, 16536 }; 16537 16538 var dayGridPlugin = createPlugin({ 16539 initialView: "dayGridMonth", 16540 optionRefiners: OPTION_REFINERS, 16541 views: { 16542 dayGrid: { 16543 component: DayTableView, 16544 dateProfileGeneratorClass: TableDateProfileGenerator, 16545 }, 16546 dayGridDay: { 16547 type: "dayGrid", 16548 duration: { days: 1 }, 16549 }, 16550 dayGridWeek: { 16551 type: "dayGrid", 16552 duration: { weeks: 1 }, 16553 }, 16554 dayGridMonth: { 16555 type: "dayGrid", 16556 duration: { months: 1 }, 16557 monthMode: true, 16558 fixedWeekCount: true, 16559 }, 16560 }, 16561 }); 16562 16563 var AllDaySplitter = /** @class */ (function (_super) { 16564 __extends(AllDaySplitter, _super); 16565 function AllDaySplitter() { 16566 return (_super !== null && _super.apply(this, arguments)) || this; 16567 } 16568 AllDaySplitter.prototype.getKeyInfo = function () { 16569 return { 16570 allDay: {}, 16571 timed: {}, 16572 }; 16573 }; 16574 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 16575 if (dateSpan.allDay) { 16576 return ["allDay"]; 16577 } else { 16578 return ["timed"]; 16579 } 16580 }; 16581 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 16582 if (!eventDef.allDay) { 16583 return ["timed"]; 16584 } else if (hasBgRendering(eventDef)) { 16585 return ["timed", "allDay"]; 16586 } else { 16587 return ["allDay"]; 16588 } 16589 }; 16590 return AllDaySplitter; 16591 })(Splitter); 16592 16593 var TimeColsSlatsCoords = /** @class */ (function () { 16594 function TimeColsSlatsCoords(positions, dateProfile, slatMetas) { 16595 this.positions = positions; 16596 this.dateProfile = dateProfile; 16597 this.slatMetas = slatMetas; 16598 } 16599 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) { 16600 var dateProfile = this.dateProfile; 16601 if (rangeContainsMarker(dateProfile.currentRange, date)) { 16602 var startOfDayDate = startOfDay(date); 16603 var timeMs = date.valueOf() - startOfDayDate.valueOf(); 16604 if ( 16605 timeMs >= asRoughMs(dateProfile.slotMinTime) && 16606 timeMs < asRoughMs(dateProfile.slotMaxTime) 16607 ) { 16608 return this.computeTimeTop(createDuration(timeMs)); 16609 } 16610 } 16611 }; 16612 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 16613 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 16614 TimeColsSlatsCoords.prototype.computeDateTop = function ( 16615 when, 16616 startOfDayDate 16617 ) { 16618 if (!startOfDayDate) { 16619 startOfDayDate = startOfDay(when); 16620 } 16621 return this.computeTimeTop( 16622 createDuration(when.valueOf() - startOfDayDate.valueOf()) 16623 ); 16624 }; 16625 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 16626 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 16627 // Eventually allow computation with arbirary slat dates. 16628 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) { 16629 var _a = this, 16630 positions = _a.positions, 16631 dateProfile = _a.dateProfile, 16632 slatMetas = _a.slatMetas; 16633 var len = positions.els.length; 16634 var slotDurationMs = 16635 slatMetas[1].date.valueOf() - slatMetas[0].date.valueOf(); // we assume dates are uniform 16636 var slatCoverage = 16637 (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / 16638 slotDurationMs; // floating-point value of # of slots covered 16639 var slatIndex; 16640 var slatRemainder; 16641 // compute a floating-point number for how many slats should be progressed through. 16642 // from 0 to number of slats (inclusive) 16643 // constrained because slotMinTime/slotMaxTime might be customized. 16644 slatCoverage = Math.max(0, slatCoverage); 16645 slatCoverage = Math.min(len, slatCoverage); 16646 // an integer index of the furthest whole slat 16647 // from 0 to number slats (*exclusive*, so len-1) 16648 slatIndex = Math.floor(slatCoverage); 16649 slatIndex = Math.min(slatIndex, len - 1); 16650 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 16651 // could be 1.0 if slatCoverage is covering *all* the slots 16652 slatRemainder = slatCoverage - slatIndex; 16653 return ( 16654 positions.tops[slatIndex] + 16655 positions.getHeight(slatIndex) * slatRemainder 16656 ); 16657 }; 16658 return TimeColsSlatsCoords; 16659 })(); 16660 16661 // potential nice values for the slot-duration and interval-duration 16662 // from largest to smallest 16663 var STOCK_SUB_DURATIONS = [ 16664 { hours: 1 }, 16665 { minutes: 30 }, 16666 { minutes: 15 }, 16667 { seconds: 30 }, 16668 { seconds: 15 }, 16669 ]; 16670 /* 16671 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 16672 */ 16673 var TimeColsSlats = /** @class */ (function (_super) { 16674 __extends(TimeColsSlats, _super); 16675 function TimeColsSlats() { 16676 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16677 _this.rootElRef = createRef(); 16678 _this.slatElRefs = new RefMap(); 16679 return _this; 16680 } 16681 TimeColsSlats.prototype.render = function () { 16682 var _a = this, 16683 props = _a.props, 16684 context = _a.context; 16685 return createElement( 16686 "div", 16687 { className: "fc-timegrid-slots", ref: this.rootElRef }, 16688 createElement( 16689 "table", 16690 { 16691 className: context.theme.getClass("table"), 16692 style: { 16693 minWidth: props.tableMinWidth, 16694 width: props.clientWidth, 16695 height: props.minHeight, 16696 }, 16697 }, 16698 props.tableColGroupNode /* relies on there only being a single <col> for the axis */, 16699 createElement(TimeColsSlatsBody, { 16700 slatElRefs: this.slatElRefs, 16701 axis: props.axis, 16702 slatMetas: props.slatMetas, 16703 }) 16704 ) 16705 ); 16706 }; 16707 TimeColsSlats.prototype.componentDidMount = function () {
16708 this.updateSizing(); 16709 }; 16710 TimeColsSlats.prototype.componentDidUpdate = function () { 16711 this.updateSizing(); 16712 }; 16713 TimeColsSlats.prototype.componentWillUnmount = function () { 16714 if (this.props.onCoords) { 16715 this.props.onCoords(null); 16716 } 16717 }; 16718 TimeColsSlats.prototype.updateSizing = function () { 16719 var props = this.props; 16720 if ( 16721 props.onCoords && 16722 props.clientWidth !== null // means sizing has stabilized 16723 ) { 16724 var rootEl = this.rootElRef.current; 16725 if (rootEl.offsetHeight) { 16726 // not hidden by css 16727 props.onCoords( 16728 new TimeColsSlatsCoords( 16729 new PositionCache( 16730 this.rootElRef.current, 16731 collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), 16732 false, 16733 true // vertical 16734 ), 16735 this.props.dateProfile, 16736 props.slatMetas 16737 ) 16738 ); 16739 } 16740 } 16741 }; 16742 return TimeColsSlats; 16743 })(BaseComponent); 16744 function collectSlatEls(elMap, slatMetas) { 16745 return slatMetas.map(function (slatMeta) { 16746 return elMap[slatMeta.key]; 16747 }); 16748 } 16749 var TimeColsSlatsBody = /** @class */ (function (_super) { 16750 __extends(TimeColsSlatsBody, _super); 16751 function TimeColsSlatsBody() { 16752 return (_super !== null && _super.apply(this, arguments)) || this; 16753 } 16754 TimeColsSlatsBody.prototype.render = function () { 16755 var _a = this, 16756 props = _a.props, 16757 context = _a.context; 16758 var options = context.options; 16759 var slatElRefs = props.slatElRefs; 16760 return createElement( 16761 "tbody", 16762 null, 16763 props.slatMetas.map(function (slatMeta, i) { 16764 var hookProps = { 16765 time: slatMeta.time, 16766 date: context.dateEnv.toDate(slatMeta.date), 16767 view: context.viewApi, 16768 }; 16769 var classNames = [ 16770 "fc-timegrid-slot", 16771 "fc-timegrid-slot-lane", 16772 slatMeta.isLabeled ? "" : "fc-timegrid-slot-minor", 16773 ]; 16774 return createElement( 16775 "tr", 16776 { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) }, 16777 props.axis && 16778 createElement(TimeColsAxisCell, __assign({}, slatMeta)), 16779 createElement( 16780 RenderHook, 16781 { 16782 hookProps: hookProps, 16783 classNames: options.slotLaneClassNames, 16784 content: options.slotLaneContent, 16785 didMount: options.slotLaneDidMount, 16786 willUnmount: options.slotLaneWillUnmount, 16787 }, 16788 function (rootElRef, customClassNames, innerElRef, innerContent) { 16789 return createElement( 16790 "td", 16791 { 16792 ref: rootElRef, 16793 className: classNames.concat(customClassNames).join(" "), 16794 "data-time": slatMeta.isoTimeStr, 16795 }, 16796 innerContent 16797 ); 16798 } 16799 ) 16800 ); 16801 }) 16802 ); 16803 }; 16804 return TimeColsSlatsBody; 16805 })(BaseComponent); 16806 var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 16807 hour: "numeric", 16808 minute: "2-digit", 16809 omitZeroMinute: true, 16810 meridiem: "short", 16811 }); 16812 function TimeColsAxisCell(props) { 16813 var classNames = [ 16814 "fc-timegrid-slot", 16815 "fc-timegrid-slot-label", 16816 props.isLabeled ? "fc-scrollgrid-shrink" : "fc-timegrid-slot-minor", 16817 ]; 16818 return createElement(ViewContextType.Consumer, null, function (context) { 16819 if (!props.isLabeled) { 16820 return createElement("td", { 16821 className: classNames.join(" "), 16822 "data-time": props.isoTimeStr, 16823 }); 16824 } else { 16825 var dateEnv = context.dateEnv, 16826 options = context.options, 16827 viewApi = context.viewApi; 16828 var labelFormat = // TODO: fully pre-parse 16829 options.slotLabelFormat == null 16830 ? DEFAULT_SLAT_LABEL_FORMAT 16831 : Array.isArray(options.slotLabelFormat) 16832 ? createFormatter(options.slotLabelFormat[0]) 16833 : createFormatter(options.slotLabelFormat); 16834 var hookProps = { 16835 level: 0, 16836 time: props.time, 16837 date: dateEnv.toDate(props.date), 16838 view: viewApi, 16839 text: dateEnv.format(props.date, labelFormat), 16840 }; 16841 return createElement( 16842 RenderHook, 16843 { 16844 hookProps: hookProps, 16845 classNames: options.slotLabelClassNames, 16846 content: options.slotLabelContent, 16847 defaultContent: renderInnerContent$3, 16848 didMount: options.slotLabelDidMount, 16849 willUnmount: options.slotLabelWillUnmount, 16850 }, 16851 function (rootElRef, customClassNames, innerElRef, innerContent) { 16852 return createElement( 16853 "td", 16854 { 16855 ref: rootElRef,
16856 className: classNames.concat(customClassNames).join(" "), 16857 "data-time": props.isoTimeStr, 16858 }, 16859 createElement( 16860 "div", 16861 { 16862 className: 16863 "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame", 16864 }, 16865 createElement( 16866 "div", 16867 { 16868 className: 16869 "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", 16870 ref: innerElRef, 16871 }, 16872 innerContent 16873 ) 16874 ) 16875 ); 16876 } 16877 ); 16878 } 16879 }); 16880 } 16881 function renderInnerContent$3(props) { 16882 return props.text; 16883 } 16884 function buildSlatMetas( 16885 slotMinTime, 16886 slotMaxTime, 16887 explicitLabelInterval, 16888 slotDuration, 16889 dateEnv 16890 ) { 16891 var dayStart = new Date(0); 16892 var slatTime = slotMinTime; 16893 var slatIterator = createDuration(0); 16894 var labelInterval = 16895 explicitLabelInterval || computeLabelInterval(slotDuration); 16896 var metas = []; 16897 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 16898 var date = dateEnv.add(dayStart, slatTime); 16899 var isLabeled = 16900 wholeDivideDurations(slatIterator, labelInterval) !== null; 16901 metas.push({ 16902 date: date, 16903 time: slatTime, 16904 key: date.toISOString(), 16905 isoTimeStr: formatIsoTimeString(date), 16906 isLabeled: isLabeled, 16907 }); 16908 slatTime = addDurations(slatTime, slotDuration); 16909 slatIterator = addDurations(slatIterator, slotDuration); 16910 } 16911 return metas; 16912 } 16913 // Computes an automatic value for slotLabelInterval 16914 function computeLabelInterval(slotDuration) { 16915 var i; 16916 var labelInterval; 16917 var slotsPerLabel; 16918 // find the smallest stock label interval that results in more than one slots-per-label 16919 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) { 16920 labelInterval = createDuration(STOCK_SUB_DURATIONS[i]); 16921 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
16922 if (slotsPerLabel !== null && slotsPerLabel > 1) { 16923 return labelInterval; 16924 } 16925 } 16926 return slotDuration; // fall back 16927 } 16928 16929 var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: "short" }); 16930 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 16931 var TimeColsView = /** @class */ (function (_super) { 16932 __extends(TimeColsView, _super); 16933 function TimeColsView() { 16934 var _this = (_super !== null && _super.apply(this, arguments)) || this; 16935 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses 16936 _this.headerElRef = createRef(); 16937 _this.rootElRef = createRef(); 16938 _this.scrollerElRef = createRef(); 16939 _this.state = { 16940 slatCoords: null, 16941 }; 16942 _this.handleScrollTopRequest = function (scrollTop) { 16943 var scrollerEl = _this.scrollerElRef.current; 16944 if (scrollerEl) { 16945 // TODO: not sure how this could ever be null. weirdness with the reducer 16946 scrollerEl.scrollTop = scrollTop; 16947 } 16948 }; 16949 /* Header Render Methods 16950 ------------------------------------------------------------------------------------------------------------------*/ 16951 _this.renderHeadAxis = function (frameHeight) { 16952 if (frameHeight === void 0) { 16953 frameHeight = ""; 16954 } 16955 var options = _this.context.options; 16956 var dateProfile = _this.props.dateProfile; 16957 var range = dateProfile.renderRange; 16958 var dayCnt = diffDays(range.start, range.end); 16959 var navLinkAttrs = 16960 options.navLinks && dayCnt === 1 // only do in day views (to avoid doing in week views that dont need it) 16961 ? { 16962 "data-navlink": buildNavLinkData(range.start, "week"), 16963 tabIndex: 0, 16964 } 16965 : {}; 16966 if (options.weekNumbers) { 16967 return createElement( 16968 WeekNumberRoot, 16969 { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, 16970 function (rootElRef, classNames, innerElRef, innerContent) { 16971 return createElement( 16972 "th", 16973 { 16974 ref: rootElRef, 16975 className: ["fc-timegrid-axis", "fc-scrollgrid-shrink"] 16976 .concat(classNames) 16977 .join(" "), 16978 }, 16979 createElement( 16980 "div", 16981 { 16982 className: 16983 "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", 16984 style: { height: frameHeight }, 16985 }, 16986 createElement( 16987 "a", 16988 __assign( 16989 { 16990 ref: innerElRef, 16991 className: 16992 "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", 16993 }, 16994 navLinkAttrs 16995 ), 16996 innerContent 16997 ) 16998 ) 16999 ); 17000 } 17001 ); 17002 } 17003 return createElement( 17004 "th", 17005 { className: "fc-timegrid-axis" }, 17006 createElement("div", { 17007 className: "fc-timegrid-axis-frame", 17008 style: { height: frameHeight }, 17009 }) 17010 ); 17011 }; 17012 /* Table Component Render Methods 17013 ------------------------------------------------------------------------------------------------------------------*/ 17014 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid, 17015 // but DayGrid still needs to have classNames on inner elements in order to measure. 17016 _this.renderTableRowAxis = function (rowHeight) { 17017 var _a = _this.context, 17018 options = _a.options, 17019 viewApi = _a.viewApi; 17020 var hookProps = { 17021 text: options.allDayText, 17022 view: viewApi, 17023 }; 17024 return ( 17025 // TODO: make reusable hook. used in list view too 17026 createElement( 17027 RenderHook, 17028 { 17029 hookProps: hookProps, 17030 classNames: options.allDayClassNames, 17031 content: options.allDayContent, 17032 defaultContent: renderAllDayInner, 17033 didMount: options.allDayDidMount, 17034 willUnmount: options.allDayWillUnmount, 17035 }, 17036 function (rootElRef, classNames, innerElRef, innerContent) { 17037 return createElement( 17038 "td", 17039 { 17040 ref: rootElRef, 17041 className: ["fc-timegrid-axis", "fc-scrollgrid-shrink"] 17042 .concat(classNames) 17043 .join(" "), 17044 }, 17045 createElement( 17046 "div", 17047 { 17048 className: 17049 "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame" + 17050 (rowHeight == null 17051 ? " fc-timegrid-axis-frame-liquid" 17052 : ""), 17053 style: { height: rowHeight }, 17054 }, 17055 createElement( 17056 "span", 17057 { 17058 className: 17059 "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", 17060 ref: innerElRef, 17061 }, 17062 innerContent 17063 ) 17064 ) 17065 ); 17066 } 17067 ) 17068 ); 17069 }; 17070 _this.handleSlatCoords = function (slatCoords) {
17071 _this.setState({ slatCoords: slatCoords }); 17072 }; 17073 return _this; 17074 } 17075 // rendering 17076 // ---------------------------------------------------------------------------------------------------- 17077 TimeColsView.prototype.renderSimpleLayout = function ( 17078 headerRowContent, 17079 allDayContent, 17080 timeContent 17081 ) { 17082 var _a = this, 17083 context = _a.context, 17084 props = _a.props; 17085 var sections = []; 17086 var stickyHeaderDates = getStickyHeaderDates(context.options); 17087 if (headerRowContent) { 17088 sections.push({ 17089 type: "header", 17090 key: "header", 17091 isSticky: stickyHeaderDates, 17092 chunk: { 17093 elRef: this.headerElRef, 17094 tableClassName: "fc-col-header", 17095 rowContent: headerRowContent, 17096 }, 17097 }); 17098 } 17099 if (allDayContent) { 17100 sections.push({ 17101 type: "body", 17102 key: "all-day", 17103 chunk: { content: allDayContent }, 17104 }); 17105 sections.push({ 17106 type: "body", 17107 key: "all-day-divider", 17108 // TODO: rename to cellContent so don't need to define <tr>? 17109 outerContent: createElement( 17110 "tr", 17111 { className: "fc-scrollgrid-section" }, 17112 createElement("td", { 17113 className: 17114 "fc-timegrid-divider " + 17115 context.theme.getClass("tableCellShaded"), 17116 }) 17117 ), 17118 }); 17119 } 17120 sections.push({ 17121 type: "body", 17122 key: "body", 17123 liquid: true, 17124 expandRows: Boolean(context.options.expandRows), 17125 chunk: { 17126 scrollerElRef: this.scrollerElRef, 17127 content: timeContent, 17128 }, 17129 }); 17130 return createElement( 17131 ViewRoot, 17132 { viewSpec: context.viewSpec, elRef: this.rootElRef }, 17133 function (rootElRef, classNames) { 17134 return createElement( 17135 "div", 17136 { 17137 className: ["fc-timegrid"].concat(classNames).join(" "), 17138 ref: rootElRef, 17139 }, 17140 createElement(SimpleScrollGrid, { 17141 liquid: !props.isHeightAuto && !props.forPrint, 17142 cols: [{ width: "shrink" }], 17143 sections: sections, 17144 }) 17145 ); 17146 } 17147 ); 17148 }; 17149 TimeColsView.prototype.renderHScrollLayout = function ( 17150 headerRowContent, 17151 allDayContent, 17152 timeContent, 17153 colCnt, 17154 dayMinWidth, 17155 slatMetas, 17156 slatCoords // yuck 17157 ) { 17158 var _this = this; 17159 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 17160 if (!ScrollGrid) { 17161 throw new Error("No ScrollGrid implementation"); 17162 } 17163 var _a = this, 17164 context = _a.context, 17165 props = _a.props; 17166 var stickyHeaderDates = 17167 !props.forPrint && getStickyHeaderDates(context.options); 17168 var stickyFooterScrollbar = 17169 !props.forPrint && getStickyFooterScrollbar(context.options); 17170 var sections = []; 17171 if (headerRowContent) { 17172 sections.push({ 17173 type: "header", 17174 key: "header", 17175 isSticky: stickyHeaderDates, 17176 syncRowHeights: true, 17177 chunks: [ 17178 { 17179 key: "axis", 17180 rowContent: function (arg) { 17181 return createElement( 17182 "tr", 17183 null, 17184 _this.renderHeadAxis(arg.rowSyncHeights[0]) 17185 ); 17186 }, 17187 }, 17188 { 17189 key: "cols", 17190 elRef: this.headerElRef, 17191 tableClassName: "fc-col-header", 17192 rowContent: headerRowContent, 17193 }, 17194 ], 17195 }); 17196 } 17197 if (allDayContent) { 17198 sections.push({ 17199 type: "body", 17200 key: "all-day", 17201 syncRowHeights: true, 17202 chunks: [ 17203 { 17204 key: "axis", 17205 rowContent: function (contentArg) { 17206 return createElement( 17207 "tr", 17208 null, 17209 _this.renderTableRowAxis(contentArg.rowSyncHeights[0]) 17210 ); 17211 }, 17212 }, 17213 { 17214 key: "cols", 17215 content: allDayContent, 17216 }, 17217 ], 17218 }); 17219 sections.push({ 17220 key: "all-day-divider", 17221 type: "body", 17222 // TODO: rename to cellContent so don't need to define <tr>? 17223 outerContent: createElement( 17224 "tr", 17225 { className: "fc-scrollgrid-section" }, 17226 createElement("td", { 17227 colSpan: 2, 17228 className: 17229 "fc-timegrid-divider " + 17230 context.theme.getClass("tableCellShaded"), 17231 }) 17232 ), 17233 }); 17234 } 17235 var isNowIndicator = context.options.nowIndicator; 17236 sections.push({ 17237 type: "body", 17238 key: "body", 17239 liquid: true, 17240 expandRows: Boolean(context.options.expandRows), 17241 chunks: [ 17242 { 17243 key: "axis", 17244 content: function (arg) { 17245 // TODO: make this now-indicator arrow more DRY with TimeColsContent 17246 return createElement( 17247 "div", 17248 { className: "fc-timegrid-axis-chunk" }, 17249 createElement( 17250 "table", 17251 { style: { height: arg.expandRows ? arg.clientHeight : "" } }, 17252 arg.tableColGroupNode, 17253 createElement( 17254 "tbody", 17255 null, 17256 createElement(TimeBodyAxis, { slatMetas: slatMetas }) 17257 ) 17258 ), 17259 createElement( 17260 "div", 17261 { className: "fc-timegrid-now-indicator-container" }, 17262 createElement( 17263 NowTimer, 17264 { unit: isNowIndicator ? "minute" : "day" /* hacky */ }, 17265 function (nowDate) { 17266 var nowIndicatorTop = 17267 isNowIndicator && 17268 slatCoords && 17269 slatCoords.safeComputeTop(nowDate); // might return void 17270 if (typeof nowIndicatorTop === "number") { 17271 return createElement( 17272 NowIndicatorRoot, 17273 { isAxis: true, date: nowDate }, 17274 function ( 17275 rootElRef, 17276 classNames, 17277 innerElRef, 17278 innerContent 17279 ) { 17280 return createElement( 17281 "div", 17282 { 17283 ref: rootElRef, 17284 className: ["fc-timegrid-now-indicator-arrow"] 17285 .concat(classNames) 17286 .join(" "), 17287 style: { top: nowIndicatorTop }, 17288 }, 17289 innerContent 17290 ); 17291 } 17292 ); 17293 } 17294 return null; 17295 } 17296 ) 17297 ) 17298 ); 17299 }, 17300 }, 17301 { 17302 key: "cols", 17303 scrollerElRef: this.scrollerElRef, 17304 content: timeContent, 17305 }, 17306 ], 17307 }); 17308 if (stickyFooterScrollbar) { 17309 sections.push({ 17310 key: "footer", 17311 type: "footer", 17312 isSticky: true, 17313 chunks: [ 17314 { 17315 key: "axis", 17316 content: renderScrollShim, 17317 }, 17318 { 17319 key: "cols", 17320 content: renderScrollShim, 17321 }, 17322 ], 17323 }); 17324 } 17325 return createElement( 17326 ViewRoot, 17327 { viewSpec: context.viewSpec, elRef: this.rootElRef }, 17328 function (rootElRef, classNames) { 17329 return createElement( 17330 "div", 17331 { 17332 className: ["fc-timegrid"].concat(classNames).join(" "), 17333 ref: rootElRef, 17334 }, 17335 createElement(ScrollGrid, { 17336 liquid: !props.isHeightAuto && !props.forPrint, 17337 colGroups: [ 17338 { width: "shrink", cols: [{ width: "shrink" }] }, 17339 { cols: [{ span: colCnt, minWidth: dayMinWidth }] }, 17340 ], 17341 sections: sections, 17342 }) 17343 ); 17344 } 17345 ); 17346 }; 17347 /* Dimensions 17348 ------------------------------------------------------------------------------------------------------------------*/ 17349 TimeColsView.prototype.getAllDayMaxEventProps = function () { 17350 var _a = this.context.options, 17351 dayMaxEvents = _a.dayMaxEvents, 17352 dayMaxEventRows = _a.dayMaxEventRows; 17353 if (dayMaxEvents === true || dayMaxEventRows === true) { 17354 // is auto? 17355 dayMaxEvents = undefined; 17356 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number 17357 } 17358 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows }; 17359 }; 17360 return TimeColsView; 17361 })(DateComponent); 17362 function renderAllDayInner(hookProps) { 17363 return hookProps.text; 17364 } 17365 var TimeBodyAxis = /** @class */ (function (_super) { 17366 __extends(TimeBodyAxis, _super); 17367 function TimeBodyAxis() { 17368 return (_super !== null && _super.apply(this, arguments)) || this; 17369 } 17370 TimeBodyAxis.prototype.render = function () { 17371 return this.props.slatMetas.map(function (slatMeta) { 17372 return createElement( 17373 "tr", 17374 { key: slatMeta.key }, 17375 createElement(TimeColsAxisCell, __assign({}, slatMeta)) 17376 ); 17377 }); 17378 }; 17379 return TimeBodyAxis; 17380 })(BaseComponent); 17381 17382 function splitSegsByCol(segs, colCnt) { 17383 var segsByCol = []; 17384 var i; 17385 for (i = 0; i < colCnt; i++) { 17386 segsByCol.push([]); 17387 } 17388 if (segs) { 17389 for (i = 0; i < segs.length; i++) { 17390 segsByCol[segs[i].col].push(segs[i]); 17391 } 17392 } 17393 return segsByCol; 17394 } 17395 function splitInteractionByCol(ui, colCnt) { 17396 var byRow = []; 17397 if (!ui) { 17398 for (var i = 0; i < colCnt; i++) { 17399 byRow[i] = null; 17400 } 17401 } else { 17402 for (var i = 0; i < colCnt; i++) { 17403 byRow[i] = { 17404 affectedInstances: ui.affectedInstances, 17405 isEvent: ui.isEvent, 17406 segs: [], 17407 }; 17408 } 17409 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 17410 var seg = _a[_i]; 17411 byRow[seg.col].segs.push(seg); 17412 } 17413 } 17414 return byRow; 17415 } 17416 17417 // UNFORTUNATELY, assigns results to the top/bottom/level/forwardCoord/backwardCoord props of the actual segs. 17418 // TODO: return hash (by instanceId) of results 17419 function computeSegCoords( 17420 segs, 17421 dayDate, 17422 slatCoords, 17423 eventMinHeight, 17424 eventOrderSpecs 17425 ) { 17426 computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight); 17427 return computeSegHorizontals(segs, eventOrderSpecs); // requires top/bottom from computeSegVerticals 17428 } 17429 // For each segment in an array, computes and assigns its top and bottom properties 17430 function computeSegVerticals(segs, dayDate, slatCoords, eventMinHeight) { 17431 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 17432 var seg = segs_1[_i]; 17433 seg.top = slatCoords.computeDateTop(seg.start, dayDate); 17434 seg.bottom = Math.max(
17435 seg.top + (eventMinHeight || 0), // yuck 17436 slatCoords.computeDateTop(seg.end, dayDate) 17437 ); 17438 } 17439 } 17440 // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each. 17441 // Assumed the segs are already ordered. 17442 // NOTE: Also reorders the given array by date! 17443 function computeSegHorizontals(segs, eventOrderSpecs) { 17444 // IMPORTANT TO CLEAR OLD RESULTS :( 17445 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 17446 var seg = segs_2[_i]; 17447 seg.level = null; 17448 seg.forwardCoord = null; 17449 seg.backwardCoord = null; 17450 seg.forwardPressure = null; 17451 } 17452 segs = sortEventSegs(segs, eventOrderSpecs); 17453 var level0; 17454 var levels = buildSlotSegLevels(segs); 17455 computeForwardSlotSegs(levels); 17456 if ((level0 = levels[0])) { 17457 for (var _a = 0, level0_1 = level0; _a < level0_1.length; _a++) { 17458 var seg = level0_1[_a]; 17459 computeSlotSegPressures(seg); 17460 } 17461 for (var _b = 0, level0_2 = level0; _b < level0_2.length; _b++) { 17462 var seg = level0_2[_b]; 17463 computeSegForwardBack(seg, 0, 0, eventOrderSpecs); 17464 } 17465 } 17466 return segs; 17467 } 17468 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is 17469 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date. 17470 function buildSlotSegLevels(segs) { 17471 var levels = []; 17472 var i; 17473 var seg; 17474 var j; 17475 for (i = 0; i < segs.length; i++) { 17476 seg = segs[i]; 17477 // go through all the levels and stop on the first level where there are no collisions 17478 for (j = 0; j < levels.length; j++) { 17479 if (!computeSlotSegCollisions(seg, levels[j]).length) { 17480 break; 17481 } 17482 } 17483 seg.level = j; 17484 (levels[j] || (levels[j] = [])).push(seg); 17485 } 17486 return levels; 17487 } 17488 // Find all the segments in `otherSegs` that vertically collide with `seg`. 17489 // Append into an optionally-supplied `results` array and return. 17490 function computeSlotSegCollisions(seg, otherSegs, results) { 17491 if (results === void 0) { 17492 results = []; 17493 } 17494 for (var i = 0; i < otherSegs.length; i++) { 17495 if (isSlotSegCollision(seg, otherSegs[i])) { 17496 results.push(otherSegs[i]); 17497 } 17498 } 17499 return results; 17500 } 17501 // Do these segments occupy the same vertical space? 17502 function isSlotSegCollision(seg1, seg2) { 17503 return seg1.bottom > seg2.top && seg1.top < seg2.bottom; 17504 } 17505 // For every segment, figure out the other segments that are in subsequent 17506 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs 17507 function computeForwardSlotSegs(levels) { 17508 var i; 17509 var level; 17510 var j; 17511 var seg; 17512 var k; 17513 for (i = 0; i < levels.length; i++) { 17514 level = levels[i]; 17515 for (j = 0; j < level.length; j++) { 17516 seg = level[j]; 17517 seg.forwardSegs = []; 17518 for (k = i + 1; k < levels.length; k++) { 17519 computeSlotSegCollisions(seg, levels[k], seg.forwardSegs); 17520 } 17521 } 17522 } 17523 } 17524 // Figure out which path forward (via seg.forwardSegs) results in the longest path until 17525 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure 17526 function computeSlotSegPressures(seg) { 17527 var forwardSegs = seg.forwardSegs; 17528 var forwardPressure = 0; 17529 var i; 17530 var forwardSeg; 17531 if (seg.forwardPressure == null) { 17532 // not already computed 17533 for (i = 0; i < forwardSegs.length; i++) { 17534 forwardSeg = forwardSegs[i]; 17535 // figure out the child's maximum forward path 17536 computeSlotSegPressures(forwardSeg); 17537 // either use the existing maximum, or use the child's forward pressure 17538 // plus one (for the forwardSeg itself) 17539 forwardPressure = Math.max( 17540 forwardPressure, 17541 1 + forwardSeg.forwardPressure 17542 ); 17543 } 17544 seg.forwardPressure = forwardPressure; 17545 } 17546 } 17547 // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range 17548 // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and 17549 // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left. 17550 // 17551 // The segment might be part of a "series", which means consecutive segments with the same pressure 17552 // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of 17553 // segments behind this one in the current series, and `seriesBackwardCoord` is the starting 17554 // coordinate of the first segment in the series. 17555 function computeSegForwardBack( 17556 seg, 17557 seriesBackwardPressure, 17558 seriesBackwardCoord, 17559 eventOrderSpecs 17560 ) { 17561 var forwardSegs = seg.forwardSegs; 17562 var i; 17563 if (seg.forwardCoord == null) { 17564 // not already computed 17565 if (!forwardSegs.length) { 17566 // if there are no forward segments, this segment should butt up against the edge 17567 seg.forwardCoord = 1; 17568 } else { 17569 // sort highest pressure first 17570 sortForwardSegs(forwardSegs, eventOrderSpecs); 17571 // this segment's forwardCoord will be calculated from the backwardCoord of the 17572 // highest-pressure forward segment. 17573 computeSegForwardBack( 17574 forwardSegs[0], 17575 seriesBackwardPressure + 1, 17576 seriesBackwardCoord, 17577 eventOrderSpecs 17578 ); 17579 seg.forwardCoord = forwardSegs[0].backwardCoord; 17580 } 17581 // calculate the backwardCoord from the forwardCoord. consider the series 17582 seg.backwardCoord = 17583 seg.forwardCoord - 17584 (seg.forwardCoord - seriesBackwardCoord) / // available width for series 17585 (seriesBackwardPressure + 1); // # of segments in the series
17586 // use this segment's coordinates to computed the coordinates of the less-pressurized 17587 // forward segments 17588 for (i = 0; i < forwardSegs.length; i++) { 17589 computeSegForwardBack( 17590 forwardSegs[i], 17591 0, 17592 seg.forwardCoord, 17593 eventOrderSpecs 17594 ); 17595 } 17596 } 17597 } 17598 function sortForwardSegs(forwardSegs, eventOrderSpecs) { 17599 var objs = forwardSegs.map(buildTimeGridSegCompareObj); 17600 var specs = [ 17601 // put higher-pressure first 17602 { field: "forwardPressure", order: -1 }, 17603 // put segments that are closer to initial edge first (and favor ones with no coords yet) 17604 { field: "backwardCoord", order: 1 }, 17605 ].concat(eventOrderSpecs); 17606 objs.sort(function (obj0, obj1) { 17607 return compareByFieldSpecs(obj0, obj1, specs); 17608 }); 17609 return objs.map(function (c) { 17610 return c._seg; 17611 }); 17612 } 17613 function buildTimeGridSegCompareObj(seg) { 17614 var obj = buildSegCompareObj(seg); 17615 obj.forwardPressure = seg.forwardPressure; 17616 obj.backwardCoord = seg.backwardCoord; 17617 return obj; 17618 } 17619 17620 var DEFAULT_TIME_FORMAT = createFormatter({ 17621 hour: "numeric", 17622 minute: "2-digit", 17623 meridiem: false, 17624 }); 17625 var TimeColEvent = /** @class */ (function (_super) { 17626 __extends(TimeColEvent, _super); 17627 function TimeColEvent() { 17628 return (_super !== null && _super.apply(this, arguments)) || this; 17629 } 17630 TimeColEvent.prototype.render = function () { 17631 var classNames = ["fc-timegrid-event", "fc-v-event"]; 17632 if (this.props.isCondensed) { 17633 classNames.push("fc-timegrid-event-condensed"); 17634 } 17635 return createElement( 17636 StandardEvent, 17637 __assign({}, this.props, { 17638 defaultTimeFormat: DEFAULT_TIME_FORMAT, 17639 extraClassNames: classNames, 17640 }) 17641 ); 17642 }; 17643 return TimeColEvent; 17644 })(BaseComponent); 17645 17646 config.timeGridEventCondensedHeight = 30; 17647 var TimeCol = /** @class */ (function (_super) { 17648 __extends(TimeCol, _super); 17649 function TimeCol() { 17650 return (_super !== null && _super.apply(this, arguments)) || this; 17651 } 17652 TimeCol.prototype.render = function () { 17653 var _this = this; 17654 var _a = this, 17655 props = _a.props, 17656 context = _a.context; 17657 var isSelectMirror = context.options.selectMirror; 17658 var mirrorSegs = 17659 (props.eventDrag && props.eventDrag.segs) || 17660 (props.eventResize && props.eventResize.segs) || 17661 (isSelectMirror && props.dateSelectionSegs) || 17662 []; 17663 var interactionAffectedInstances = // TODO: messy way to compute this 17664 (props.eventDrag && props.eventDrag.affectedInstances) || 17665 (props.eventResize && props.eventResize.affectedInstances) || 17666 {}; 17667 return createElement( 17668 DayCellRoot, 17669 { 17670 elRef: props.elRef, 17671 date: props.date, 17672 dateProfile: props.dateProfile, 17673 todayRange: props.todayRange, 17674 extraHookProps: props.extraHookProps, 17675 }, 17676 function (rootElRef, classNames, dataAttrs) { 17677 return createElement( 17678 "td", 17679 __assign( 17680 { 17681 ref: rootElRef, 17682 className: ["fc-timegrid-col"] 17683 .concat(classNames, props.extraClassNames || []) 17684 .join(" "), 17685 }, 17686 dataAttrs, 17687 props.extraDataAttrs 17688 ), 17689 createElement( 17690 "div", 17691 { className: "fc-timegrid-col-frame" }, 17692 createElement( 17693 "div", 17694 { className: "fc-timegrid-col-bg" }, 17695 _this.renderFillSegs(props.businessHourSegs, "non-business"), 17696 _this.renderFillSegs(props.bgEventSegs, "bg-event"), 17697 _this.renderFillSegs(props.dateSelectionSegs, "highlight") 17698 ), 17699 createElement( 17700 "div", 17701 { className: "fc-timegrid-col-events" }, 17702 _this.renderFgSegs( 17703 props.fgEventSegs, 17704 interactionAffectedInstances 17705 ) 17706 ), 17707 createElement( 17708 "div", 17709 { className: "fc-timegrid-col-events" }, 17710 _this.renderFgSegs( 17711 mirrorSegs, 17712 {}, 17713 Boolean(props.eventDrag), 17714 Boolean(props.eventResize), 17715 Boolean(isSelectMirror) 17716 // TODO: pass in left/right instead of using only computeSegTopB
17716ottomCss 17717 ) 17718 ), 17719 createElement( 17720 "div", 17721 { className: "fc-timegrid-now-indicator-container" }, 17722 _this.renderNowIndicator(props.nowIndicatorSegs) 17723 ), 17724 createElement(TimeColMisc, { 17725 date: props.date, 17726 dateProfile: props.dateProfile, 17727 todayRange: props.todayRange, 17728 extraHookProps: props.extraHookProps, 17729 }) 17730 ) 17731 ); 17732 } 17733 ); 17734 }; 17735 TimeCol.prototype.renderFgSegs = function ( 17736 segs, 17737 segIsInvisible, 17738 isDragging, 17739 isResizing, 17740 isDateSelecting 17741 ) { 17742 var props = this.props; 17743 if (props.forPrint) { 17744 return this.renderPrintFgSegs(segs); 17745 } else if (props.slatCoords) { 17746 return this.renderPositionedFgSegs( 17747 segs, 17748 segIsInvisible, 17749 isDragging, 17750 isResizing, 17751 isDateSelecting 17752 ); 17753 } 17754 }; 17755 TimeCol.prototype.renderPrintFgSegs = function (segs) { 17756 var _a = this, 17757 props = _a.props, 17758 context = _a.context; 17759 // not DRY 17760 segs = sortEventSegs(segs, context.options.eventOrder); 17761 return segs.map(function (seg) { 17762 return createElement( 17763 "div", 17764 { 17765 className: "fc-timegrid-event-harness", 17766 key: seg.eventRange.instance.instanceId, 17767 }, 17768 createElement( 17769 TimeColEvent, 17770 __assign( 17771 { 17772 seg: seg, 17773 isDragging: false, 17774 isResizing: false, 17775 isDateSelecting: false, 17776 isSelected: false, 17777 isCondensed: false, 17778 }, 17779 getSegMeta(seg, props.todayRange, props.nowDate) 17780 ) 17781 ) 17782 ); 17783 }); 17784 }; 17785 TimeCol.prototype.renderPositionedFgSegs = function ( 17786 segs, 17787 segIsInvisible, 17788 isDragging, 17789 isResizing, 17790 isDateSelecting 17791 ) { 17792 var _this = this; 17793 var _a = this, 17794 context = _a.context, 17795 props = _a.props; 17796 // assigns TO THE SEGS THEMSELVES 17797 // also, receives resorted array 17798 segs = computeSegCoords( 17799 segs, 17800 props.date, 17801 props.slatCoords, 17802 context.options.eventMinHeight, 17803 context.options.eventOrder 17804 ); 17805 return segs.map(function (seg) { 17806 var instanceId = seg.eventRange.instance.instanceId; 17807 var isMirror = isDragging || isResizing || isDateSelecting; 17808 var positionCss = isMirror 17809 ? __assign({ left: 0, right: 0 }, _this.computeSegTopBottomCss(seg)) 17810 : _this.computeFgSegPositionCss(seg); 17811 return createElement( 17812 "div", 17813 { 17814 className: 17815 "fc-timegrid-event-harness" + 17816 (seg.level > 0 ? " fc-timegrid-event-harness-inset" : ""), 17817 key: instanceId, 17818 style: __assign( 17819 { visibility: segIsInvisible[instanceId] ? "hidden" : "" }, 17820 positionCss 17821 ), 17822 }, 17823 createElement( 17824 TimeColEvent, 17825 __assign( 17826 { 17827 seg: seg, 17828 isDragging: isDragging, 17829 isResizing: isResizing, 17830 isDateSelecting: isDateSelecting, 17831 isSelected: instanceId === props.eventSelection, 17832 isCondensed: 17833 seg.bottom - seg.top < config.timeGridEventCondensedHeight, 17834 }, 17835 getSegMeta(seg, props.todayRange, props.nowDate) 17836 ) 17837 ) 17838 ); 17839 }); 17840 }; 17841 TimeCol.prototype.renderFillSegs = function (segs, fillType) { 17842 var _this = this; 17843 var _a = this, 17844 context = _a.context, 17845 props = _a.props; 17846 if (!props.slatCoords) { 17847 return; 17848 } 17849 // BAD: assigns TO THE SEGS THEMSELVES 17850 computeSegVerticals( 17851 segs, 17852 props.date, 17853 props.slatCoords, 17854 context.options.eventMinHeight 17855 ); 17856 var children = segs.map(function (seg) { 17857 return createElement( 17858 "div", 17859 { 17860 key: buildEventRangeKey(seg.eventRange), 17861 className: "fc-timegrid-bg-harness",
17862 style: _this.computeSegTopBottomCss(seg), 17863 }, 17864 fillType === "bg-event" 17865 ? createElement( 17866 BgEvent, 17867 __assign( 17868 { seg: seg }, 17869 getSegMeta(seg, props.todayRange, props.nowDate) 17870 ) 17871 ) 17872 : renderFill(fillType) 17873 ); 17874 }); 17875 return createElement(Fragment, null, children); 17876 }; 17877 TimeCol.prototype.renderNowIndicator = function (segs) { 17878 var _a = this.props, 17879 slatCoords = _a.slatCoords, 17880 date = _a.date; 17881 if (!slatCoords) { 17882 return; 17883 } 17884 return segs.map(function (seg, i) { 17885 return createElement( 17886 NowIndicatorRoot, 17887 { 17888 isAxis: false, 17889 date: date, 17890 key: i /* key doesn't matter. will only ever be one */, 17891 }, 17892 function (rootElRef, classNames, innerElRef, innerContent) { 17893 return createElement( 17894 "div", 17895 { 17896 ref: rootElRef, 17897 className: ["fc-timegrid-now-indicator-line"] 17898 .concat(classNames) 17899 .join(" "), 17900 style: { top: slatCoords.computeDateTop(seg.start, date) }, 17901 }, 17902 innerContent 17903 ); 17904 } 17905 ); 17906 }); 17907 }; 17908 TimeCol.prototype.computeFgSegPositionCss = function (seg) { 17909 var _a = this.context, 17910 isRtl = _a.isRtl, 17911 options = _a.options; 17912 var shouldOverlap = options.slotEventOverlap; 17913 var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point 17914 var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point 17915 var left; // amount of space from left edge, a fraction of the total width 17916 var right; // amount of space from right edge, a fraction of the total width 17917 if (shouldOverlap) { 17918 // double the width, but don't go beyond the maximum forward coordinate (1.0) 17919 forwardCoord = Math.min( 17920 1, 17921 backwardCoord + (forwardCoord - backwardCoord) * 2 17922 ); 17923 } 17924 if (isRtl) { 17925 left = 1 - forwardCoord; 17926 right = backwardCoord; 17927 } else { 17928 left = backwardCoord; 17929 right = 1 - forwardCoord; 17930 } 17931 var props = { 17932 zIndex: seg.level + 1, 17933 left: left * 100 + "%", 17934 right: right * 100 + "%", 17935 }; 17936 if (shouldOverlap && seg.forwardPressure) { 17937 // add padding to the edge so that forward stacked events don't cover the resizer's icon 17938 props[isRtl ? "marginLeft" : "marginRight"] = 10 * 2; // 10 is a guesstimate of the icon's width 17939 } 17940 return __assign(__assign({}, props), this.computeSegTopBottomCss(seg)); 17941 }; 17942 TimeCol.prototype.computeSegTopBottomCss = function (seg) { 17943 return { 17944 top: seg.top, 17945 bottom: -seg.bottom, 17946 }; 17947 }; 17948 return TimeCol; 17949 })(BaseComponent); 17950 var TimeColMisc = /** @class */ (function (_super) { 17951 __extends(TimeColMisc, _super); 17952 function TimeColMisc() { 17953 return (_super !== null && _super.apply(this, arguments)) || this; 17954 } 17955 TimeColMisc.prototype.render = function () { 17956 var props = this.props; 17957 return createElement( 17958 DayCellContent, 17959 { 17960 date: props.date, 17961 dateProfile: props.dateProfile, 17962 todayRange: props.todayRange, 17963 extraHookProps: props.extraHookProps, 17964 }, 17965 function (innerElRef, innerContent) { 17966 return ( 17967 innerContent && 17968 createElement( 17969 "div", 17970 { className: "fc-timegrid-col-misc", ref: innerElRef }, 17971 innerContent 17972 ) 17973 ); 17974 } 17975 ); 17976 }; 17977 return TimeColMisc; 17978 })(BaseComponent); 17979 17980 var TimeColsContent = /** @class */ (function (_super) { 17981 __extends(TimeColsContent, _super); 17982 function TimeColsContent() { 17983 var _this = (_super !== null && _super.apply(this, arguments)) || this; 17984 _this.splitFgEventSegs = memoize(splitSegsByCol); 17985 _this.splitBgEventSegs = memoize(splitSegsByCol); 17986 _this.splitBusinessHourSegs = memoize(splitSegsByCol); 17987 _this.splitNowIndicatorSegs = memoize(splitSegsByCol); 17988 _this.splitDateSelectionSegs = memoize(splitSegsByCol); 17989 _this.splitEventDrag = memoize(splitInteractionByCol); 17990 _this.splitEventResize = memoize(splitInteractionByCol); 17991 _this.rootElRef = createRef(); 17992 _this.cellElRefs = new RefMap(); 17993 return _this; 17994 } 17995 TimeColsContent.prototype.render = function () { 17996 var _this = this; 17997 var _a = this, 17998 props = _a.props, 17999 context = _a.context; 18000 var nowIndicatorTop = 18001 context.options.nowIndicator && 18002 props.slatCoords && 18003 props.slatCoords.safeComputeTop(props.nowDate); // might return void 18004 var colCnt = props.cells.length; 18005 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 18006 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 18007 var businessHourSegsByRow = this.splitBusinessHourSegs( 18008 props.businessHourSegs, 18009 colCnt 18010 ); 18011 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs( 18012 props.nowIndicatorSegs, 18013 colCnt 18014 ); 18015 var dateSelectionSegsByRow = this.splitDateSelectionSegs( 18016 props.dateSelectionSegs, 18017 colCnt 18018 ); 18019 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 18020 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 18021 return createElement( 18022 "div", 18023 { className: "fc-timegrid-cols", ref: this.rootElRef }, 18024 createElement( 18025 "table", 18026 { 18027 style: { 18028 minWidth: props.tableMinWidth, 18029 width: props.clientWidth, 18030 }, 18031 }, 18032 props.tableColGroupNode, 18033 createElement( 18034 "tbody", 18035 null, 18036 createElement( 18037 "tr", 18038 null, 18039 props.axis && 18040 createElement( 18041 "td", 18042 { className: "fc-timegrid-col fc-timegrid-axis" }, 18043 createElement( 18044 "div", 18045 { className: "fc-timegrid-col-frame" }, 18046 createElement( 18047 "div", 18048 { className: "fc-timegrid-now-indicator-container" }, 18049 typeof nowIndicatorTop === "number" && 18050 createElement( 18051 NowIndicatorRoot, 18052 { isAxis: true, date: props.nowDate }, 18053 function ( 18054 rootElRef, 18055 classNames, 18056 innerElRef, 18057 innerContent 18058 ) { 18059 return createElement( 18060 "div", 18061 { 18062 ref: rootElRef, 18063 className: ["fc-timegrid-now-indicator-arrow"] 18064 .concat(classNames) 18065 .join(" "), 18066 style: { top: nowIndicatorTop }, 18067 }, 18068 innerContent 18069 ); 18070 } 18071 ) 18072 ) 18073 ) 18074 ), 18075 props.cells.map(function (cell, i) { 18076 return createElement(TimeCol, { 18077 key: cell.key, 18078 elRef: _this.cellElRefs.createRef(cell.key), 18079 dateProfile: props.dateProfile, 18080 date: cell.date, 18081 nowDate: props.nowDate, 18082 todayRange: props.todayRange, 18083 extraHookProps: cell.extraHookProps, 18084 extraDataAttrs: cell.extraDataAttrs, 18085 extraClassNames: cell.extraClassNames, 18086 fgEventSegs: fgEventSegsByRow[i], 18087 bgEventSegs: bgEventSegsByRow[i], 18088 businessHourSegs: businessHourSegsByRow[i], 18089 nowIndicatorSegs: nowIndicatorSegsByRow[i], 18090 dateSelectionSegs: dateSelectionSegsByRow[i], 18091 eventDrag: eventDragByRow[i], 18092 eventResize: eventResizeByRow[i], 18093 slatCoords: props.slatCoords, 18094 eventSelection: props.eventSelection, 18095 forPrint: props.forPrint, 18096 }); 18097 }) 18098 ) 18099 ) 18100 ) 18101 ); 18102 }; 18103 TimeColsContent.prototype.componentDidMount = function () { 18104 this.updateCoords(); 18105 }; 18106 TimeColsContent.prototype.componentDidUpdate = function () { 18107 this.updateCoords(); 18108 }; 18109 TimeColsContent.prototype.updateCoords = function () { 18110 var props = this.props; 18111 if ( 18112 props.onColCoords && 18113 props.clientWidth !== null // means sizing has stabilized 18114 ) { 18115 props.onColCoords( 18116 new PositionCache( 18117 this.rootElRef.current, 18118 collectCellEls(this.cellElRefs.currentMap, props.cells), 18119 true, // horizontal 18120 false 18121 ) 18122 ); 18123 } 18124 }; 18125 return TimeColsContent; 18126 })(BaseComponent); 18127 function collectCellEls(elMap, cells) { 18128 return cells.map(function (cell) { 18129 return elMap[cell.key]; 18130 }); 18131 } 18132 18133 /* A component that renders one or more columns of vertical time slots 18134 ----------------------------------------------------------------------------------------------------------------------*/ 18135 var TimeCols = /** @class */ (function (_super) { 18136 __extends(TimeCols, _super); 18137 function TimeCols() { 18138 var _this = (_super !== null && _super.apply(this, arguments)) || this; 18139 _this.processSlotOptions = memoize(processSlotOptions); 18140 _this.state = { 18141 slatCoords: null, 18142 }; 18143 _this.handleScrollRequest = function (request) { 18144 var onScrollTopRequest = _this.props.onScrollTopRequest; 18145 var slatCoords = _this.state.slatCoords; 18146 if (onScrollTopRequest && slatCoords) { 18147 if (request.time) { 18148 var top_1 = slatCoords.computeTimeTop(request.time); 18149 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further 18150 if (top_1) { 18151 top_1++; 18152 } // to overcome top border that slots beyond the first have. looks better 18153 onScrollTopRequest(top_1); 18154 } 18155 return true; 18156 } 18157 }; 18158 _this.handleColCoords = function (colCoords) { 18159 _this.colCoords = colCoords; 18160 }; 18161 _this.handleSlatCoords = function (slatCoords) {
18162 _this.setState({ slatCoords: slatCoords }); 18163 if (_this.props.onSlatCoords) { 18164 _this.props.onSlatCoords(slatCoords); 18165 } 18166 }; 18167 return _this; 18168 } 18169 TimeCols.prototype.render = function () { 18170 var _a = this, 18171 props = _a.props, 18172 state = _a.state; 18173 return createElement( 18174 "div", 18175 { 18176 className: "fc-timegrid-body", 18177 ref: props.rootElRef, 18178 style: { 18179 // these props are important to give this wrapper correct dimensions for interactions 18180 // TODO: if we set it here, can we avoid giving to inner tables? 18181 width: props.clientWidth, 18182 minWidth: props.tableMinWidth, 18183 }, 18184 }, 18185 createElement(TimeColsSlats, { 18186 axis: props.axis, 18187 dateProfile: props.dateProfile, 18188 slatMetas: props.slatMetas, 18189 clientWidth: props.clientWidth, 18190 minHeight: props.expandRows ? props.clientHeight : "", 18191 tableMinWidth: props.tableMinWidth, 18192 tableColGroupNode: props.axis 18193 ? props.tableColGroupNode 18194 : null /* axis depends on the colgroup's shrinking */, 18195 onCoords: this.handleSlatCoords, 18196 }), 18197 createElement(TimeColsContent, { 18198 cells: props.cells, 18199 axis: props.axis, 18200 dateProfile: props.dateProfile, 18201 businessHourSegs: props.businessHourSegs,
18202 bgEventSegs: props.bgEventSegs, 18203 fgEventSegs: props.fgEventSegs, 18204 dateSelectionSegs: props.dateSelectionSegs, 18205 eventSelection: props.eventSelection, 18206 eventDrag: props.eventDrag, 18207 eventResize: props.eventResize, 18208 todayRange: props.todayRange, 18209 nowDate: props.nowDate, 18210 nowIndicatorSegs: props.nowIndicatorSegs, 18211 clientWidth: props.clientWidth, 18212 tableMinWidth: props.tableMinWidth, 18213 tableColGroupNode: props.tableColGroupNode, 18214 slatCoords: state.slatCoords, 18215 onColCoords: this.handleColCoords, 18216 forPrint: props.forPrint, 18217 }) 18218 ); 18219 }; 18220 TimeCols.prototype.componentDidMount = function () { 18221 this.scrollResponder = this.context.createScrollResponder( 18222 this.handleScrollRequest 18223 ); 18224 }; 18225 TimeCols.prototype.componentDidUpdate = function (prevProps) { 18226 this.scrollResponder.update( 18227 prevProps.dateProfile !== this.props.dateProfile 18228 ); 18229 }; 18230 TimeCols.prototype.componentWillUnmount = function () { 18231 this.scrollResponder.detach(); 18232 }; 18233 TimeCols.prototype.positionToHit = function (positionLeft, positionTop) { 18234 var _a = this.context, 18235 dateEnv = _a.dateEnv, 18236 options = _a.options; 18237 var colCoords = this.colCoords; 18238 var dateProfile = this.props.dateProfile; 18239 var slatCoords = this.state.slatCoords; 18240 var _b = this.processSlotOptions( 18241 this.props.slotDuration, 18242 options.snapDuration 18243 ), 18244 snapDuration = _b.snapDuration, 18245 snapsPerSlot = _b.snapsPerSlot; 18246 var colIndex = colCoords.leftToIndex(positionLeft); 18247 var slatIndex = slatCoords.positions.topToIndex(positionTop); 18248 if (colIndex != null && slatIndex != null) { 18249 var slatTop = slatCoords.positions.tops[slatIndex]; 18250 var slatHeight = slatCoords.positions.getHeight(slatIndex); 18251 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 18252 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 18253 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 18254 var dayDate = this.props.cells[colIndex].date; 18255 var time = addDurations( 18256 dateProfile.slotMinTime, 18257 multiplyDuration(snapDuration, snapIndex) 18258 ); 18259 var start = dateEnv.add(dayDate, time); 18260 var end = dateEnv.add(start, snapDuration); 18261 return { 18262 col: colIndex, 18263 dateSpan: { 18264 range: { start: start, end: end }, 18265 allDay: false, 18266 }, 18267 dayEl: colCoords.els[colIndex], 18268 relativeRect: { 18269 left: colCoords.lefts[colIndex], 18270 right: colCoords.rights[colIndex], 18271 top: slatTop, 18272 bottom: slatTop + slatHeight, 18273 }, 18274 }; 18275 } 18276 }; 18277 return TimeCols; 18278 })(BaseComponent); 18279 function processSlotOptions(slotDuration, snapDurationOverride) { 18280 var snapDuration = snapDurationOverride || slotDuration; 18281 var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 18282 if (snapsPerSlot === null) { 18283 snapDuration = slotDuration; 18284 snapsPerSlot = 1; 18285 // TODO: say warning? 18286 } 18287 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot }; 18288 } 18289 18290 var DayTimeCols = /** @class */ (function (_super) { 18291 __extends(DayTimeCols, _super); 18292 function DayTimeCols() { 18293 var _this = (_super !== null && _super.apply(this, arguments)) || this; 18294 _this.buildDayRanges = memoize(buildDayRanges); 18295 _this.slicer = new DayTimeColsSlicer(); 18296 _this.timeColsRef = createRef(); 18297 _this.handleRootEl = function (rootEl) { 18298 if (rootEl) { 18299 _this.context.registerInteractiveComponent(_this, { el: rootEl }); 18300 } else { 18301 _this.context.unregisterInteractiveComponent(_this); 18302 } 18303 }; 18304 return _this; 18305 } 18306 DayTimeCols.prototype.render = function () { 18307 var _this = this; 18308 var _a = this, 18309 props = _a.props, 18310 context = _a.context; 18311 var dateProfile = props.dateProfile, 18312 dayTableModel = props.dayTableModel; 18313 var isNowIndicator = context.options.nowIndicator; 18314 var dayRanges = this.buildDayRanges( 18315 dayTableModel, 18316 dateProfile, 18317 context.dateEnv 18318 ); 18319 // give it the first row of cells 18320 // TODO: would move this further down hierarchy, but sliceNowDate needs it 18321 return createElement( 18322 NowTimer, 18323 { unit: isNowIndicator ? "minute" : "day" }, 18324 function (nowDate, todayRange) { 18325 return createElement( 18326 TimeCols, 18327 __assign( 18328 { ref: _this.timeColsRef, rootElRef: _this.handleRootEl }, 18329 _this.slicer.sliceProps( 18330 props, 18331 dateProfile, 18332 null, 18333 context, 18334 dayRanges 18335 ), 18336 { 18337 forPrint: props.forPrint, 18338 axis: props.axis, 18339 dateProfile: dateProfile, 18340 slatMetas: props.slatMetas, 18341 slotDuration: props.slotDuration, 18342 cells: dayTableModel.cells[0], 18343 tableColGroupNode: props.tableColGroupNode, 18344 tableMinWidth: props.tableMinWidth, 18345 clientWidth: props.clientWidth, 18346 clientHeight: props.clientHeight, 18347 expandRows: props.expandRows,
18348 nowDate: nowDate, 18349 nowIndicatorSegs: 18350 isNowIndicator && 18351 _this.slicer.sliceNowDate(nowDate, context, dayRanges), 18352 todayRange: todayRange, 18353 onScrollTopRequest: props.onScrollTopRequest, 18354 onSlatCoords: props.onSlatCoords, 18355 } 18356 ) 18357 ); 18358 } 18359 ); 18360 }; 18361 DayTimeCols.prototype.queryHit = function (positionLeft, positionTop) { 18362 var rawHit = this.timeColsRef.current.positionToHit( 18363 positionLeft, 18364 positionTop 18365 ); 18366 if (rawHit) { 18367 return { 18368 component: this, 18369 dateSpan: rawHit.dateSpan, 18370 dayEl: rawHit.dayEl, 18371 rect: { 18372 left: rawHit.relativeRect.left, 18373 right: rawHit.relativeRect.right, 18374 top: rawHit.relativeRect.top, 18375 bottom: rawHit.relativeRect.bottom, 18376 }, 18377 layer: 0, 18378 }; 18379 } 18380 }; 18381 return DayTimeCols; 18382 })(DateComponent); 18383 function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 18384 var ranges = []; 18385 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) { 18386 var date = _a[_i]; 18387 ranges.push({ 18388 start: dateEnv.add(date, dateProfile.slotMinTime), 18389 end: dateEnv.add(date, dateProfile.slotMaxTime), 18390 }); 18391 } 18392 return ranges; 18393 } 18394 var DayTimeColsSlicer = /** @class */ (function (_super) { 18395 __extends(DayTimeColsSlicer, _super); 18396 function DayTimeColsSlicer() { 18397 return (_super !== null && _super.apply(this, arguments)) || this; 18398 } 18399 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) { 18400 var segs = []; 18401 for (var col = 0; col < dayRanges.length; col++) { 18402 var segRange = intersectRanges(range, dayRanges[col]); 18403 if (segRange) { 18404 segs.push({ 18405 start: segRange.start, 18406 end: segRange.end, 18407 isStart: segRange.start.valueOf() === range.start.valueOf(), 18408 isEnd: segRange.end.valueOf() === range.end.valueOf(), 18409 col: col, 18410 }); 18411 } 18412 } 18413 return segs; 18414 }; 18415 return DayTimeColsSlicer; 18416 })(Slicer); 18417 18418 var DayTimeColsView = /** @class */ (function (_super) { 18419 __extends(DayTimeColsView, _super); 18420 function DayTimeColsView() { 18421 var _this = (_super !== null && _super.apply(this, arguments)) || this; 18422 _this.buildTimeColsModel = memoize(buildTimeColsModel); 18423 _this.buildSlatMetas = memoize(buildSlatMetas); 18424 return _this; 18425 } 18426 DayTimeColsView.prototype.render = function () { 18427 var _this = this; 18428 var _a = this.context, 18429 options = _a.options, 18430 dateEnv = _a.dateEnv, 18431 dateProfileGenerator = _a.dateProfileGenerator; 18432 var props = this.props; 18433 var dateProfile = props.dateProfile; 18434 var dayTableModel = this.buildTimeColsModel( 18435 dateProfile, 18436 dateProfileGenerator 18437 ); 18438 var splitProps = this.allDaySplitter.splitProps(props); 18439 var slatMetas = this.buildSlatMetas( 18440 dateProfile.slotMinTime, 18441 dateProfile.slotMaxTime, 18442 options.slotLabelInterval, 18443 options.slotDuration, 18444 dateEnv 18445 ); 18446 var dayMinWidth = options.dayMinWidth; 18447 var hasAttachedAxis = !dayMinWidth; 18448 var hasDetachedAxis = dayMinWidth; 18449 var headerContent = 18450 options.dayHeaders && 18451 createElement(DayHeader, { 18452 dates: dayTableModel.headerDates, 18453 dateProfile: dateProfile, 18454 datesRepDistinctDays: true, 18455 renderIntro: hasAttachedAxis ? this.renderHeadAxis : null, 18456 }); 18457 var allDayContent = 18458 options.allDaySlot !== false && 18459 function (contentArg) { 18460 return createElement( 18461 DayTable, 18462 __assign( 18463 {}, 18464 splitProps["allDay"], 18465 { 18466 dateProfile: dateProfile, 18467 dayTableModel: dayTableModel, 18468 nextDayThreshold: options.nextDayThreshold, 18469 tableMinWidth: contentArg.tableMinWidth, 18470 colGroupNode: contentArg.tableColGroupNode, 18471 renderRowIntro: hasAttachedAxis 18472 ? _this.renderTableRowAxis 18473 : null, 18474 showWeekNumbers: false, 18475 expandRows: false, 18476 headerAlignElRef: _this.headerElRef, 18477 clientWidth: contentArg.clientWidth, 18478 clientHeight: contentArg.clientHeight, 18479 forPrint: props.forPrint, 18480 }, 18481 _this.getAllDayMaxEventProps() 18482 ) 18483 ); 18484 }; 18485 var timeGridContent = function (contentArg) { 18486 return createElement( 18487 DayTimeCols, 18488 __assign({}, splitProps["timed"], { 18489 dayTableModel: dayTableModel, 18490 dateProfile: dateProfile, 18491 axis: hasAttachedAxis, 18492 slotDuration: options.slotDuration, 18493 slatMetas: slatMetas, 18494 forPrint: props.forPrint, 18495 tableColGroupNode: contentArg.tableColGroupNode, 18496 tableMinWidth: contentArg.tableMinWidth, 18497 clientWidth: contentArg.clientWidth, 18498 clientHeight: contentArg.clientHeight, 18499 onSlatCoords: _this.handleSlatCoords, 18500 expandRows: contentArg.expandRows, 18501 onScrollTopRequest: _this.handleScrollTopRequest, 18502 }) 18503 ); 18504 }; 18505 return hasDetachedAxis 18506 ? this.renderHScrollLayout( 18507 headerContent, 18508 allDayContent, 18509 timeGridContent, 18510 dayTableModel.colCnt, 18511 dayMinWidth, 18512 slatMetas, 18513 this.state.slatCoords 18514 ) 18515 : this.renderSimpleLayout( 18516 headerContent, 18517 allDayContent, 18518 timeGridContent 18519 ); 18520 }; 18521 return DayTimeColsView; 18522 })(TimeColsView);
18523 function buildTimeColsModel(dateProfile, dateProfileGenerator) { 18524 var daySeries = new DaySeriesModel( 18525 dateProfile.renderRange, 18526 dateProfileGenerator 18527 ); 18528 return new DayTableModel(daySeries, false); 18529 } 18530 18531 var OPTION_REFINERS$1 = { 18532 allDaySlot: Boolean, 18533 }; 18534 18535 var timeGridPlugin = createPlugin({ 18536 initialView: "timeGridWeek", 18537 optionRefiners: OPTION_REFINERS$1, 18538 views: { 18539 timeGrid: { 18540 component: DayTimeColsView, 18541 usesMinMaxTime: true, 18542 allDaySlot: true, 18543 slotDuration: "00:30:00", 18544 slotEventOverlap: true, // a bad name. confused with overlap/constraint system 18545 }, 18546 timeGridDay: { 18547 type: "timeGrid", 18548 duration: { days: 1 }, 18549 }, 18550 timeGridWeek: { 18551 type: "timeGrid", 18552 duration: { weeks: 1 }, 18553 }, 18554 }, 18555 }); 18556 18557 var ListViewHeaderRow = /** @class */ (function (_super) { 18558 __extends(ListViewHeaderRow, _super); 18559 function ListViewHeaderRow() { 18560 return (_super !== null && _super.apply(this, arguments)) || this; 18561 } 18562 ListViewHeaderRow.prototype.render = function () { 18563 var _a = this.props, 18564 dayDate = _a.dayDate, 18565 todayRange = _a.todayRange; 18566 var _b = this.context, 18567 theme = _b.theme, 18568 dateEnv = _b.dateEnv, 18569 options = _b.options, 18570 viewApi = _b.viewApi; 18571 var dayMeta = getDateMeta(dayDate, todayRange); 18572 var text = options.listDayFormat 18573 ? dateEnv.format(dayDate, options.listDayFormat) 18574 : ""; // will ever be falsy? 18575 var sideText = options.listDaySideFormat 18576 ? dateEnv.format(dayDate, options.listDaySideFormat) 18577 : ""; // will ever be falsy? also, BAD NAME "alt" 18578 var navLinkData = options.navLinks ? buildNavLinkData(dayDate) : null; 18579 var hookProps = __assign( 18580 { 18581 date: dateEnv.toDate(dayDate), 18582 view: viewApi, 18583 text: text, 18584 sideText: sideText, 18585 navLinkData: navLinkData, 18586 }, 18587 dayMeta 18588 ); 18589 var classNames = ["fc-list-day"].concat(getDayClassNames(dayMeta, theme)); 18590 // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too) 18591 return createElement( 18592 RenderHook, 18593 { 18594 hookProps: hookProps, 18595 classNames: options.dayHeaderClassNames, 18596 content: options.dayHeaderContent, 18597 defaultContent: renderInnerContent$4, 18598 didMount: options.dayHeaderDidMount, 18599 willUnmount: options.dayHeaderWillUnmount, 18600 }, 18601 function (rootElRef, customClassNames, innerElRef, innerContent) { 18602 return createElement( 18603 "tr", 18604 { 18605 ref: rootElRef, 18606 className: classNames.concat(customClassNames).join(" "), 18607 "data-date": formatDayString(dayDate), 18608 }, 18609 createElement( 18610 "th", 18611 { colSpan: 3 }, 18612 createElement( 18613 "div", 18614 { 18615 className: 18616 "fc-list-day-cushion " + theme.getClass("tableCellShaded"), 18617 ref: innerElRef, 18618 }, 18619 innerContent 18620 ) 18621 ) 18622 ); 18623 } 18624 ); 18625 }; 18626 return ListViewHeaderRow; 18627 })(BaseComponent); 18628 function renderInnerContent$4(props) { 18629 var navLinkAttrs = props.navLinkData // is there a type for this? 18630 ? { "data-navlink": props.navLinkData, tabIndex: 0 } 18631 : {}; 18632 return createElement( 18633 Fragment, 18634 null, 18635 props.text && 18636 createElement( 18637 "a", 18638 __assign({ className: "fc-list-day-text" }, navLinkAttrs), 18639 props.text 18640 ), 18641 props.sideText && 18642 createElement( 18643 "a", 18644 __assign({ className: "fc-list-day-side-text" }, navLinkAttrs), 18645 props.sideText 18646 ) 18647 ); 18648 } 18649 18650 var DEFAULT_TIME_FORMAT$1 = createFormatter({ 18651 hour: "numeric", 18652 minute: "2-digit", 18653 meridiem: "short", 18654 }); 18655 var ListViewEventRow = /** @class */ (function (_super) { 18656 __extends(ListViewEventRow, _super); 18657 function ListViewEventRow() { 18658 return (_super !== null && _super.apply(this, arguments)) || this; 18659 } 18660 ListViewEventRow.prototype.render = function () { 18661 var _a = this, 18662 props = _a.props, 18663 context = _a.context; 18664 var seg = props.seg; 18665 var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT$1; 18666 return createElement( 18667 EventRoot, 18668 { 18669 seg: seg, 18670 timeText: "" /* BAD. because of all-day content */, 18671 disableDragging: true, 18672 disableResizing: true, 18673 defaultContent: renderEventInnerContent, 18674 isPast: props.isPast, 18675 isFuture: props.isFuture, 18676 isToday: props.isToday,
18677 isSelected: props.isSelected, 18678 isDragging: props.isDragging, 18679 isResizing: props.isResizing, 18680 isDateSelecting: props.isDateSelecting, 18681 }, 18682 function (rootElRef, classNames, innerElRef, innerContent, hookProps) { 18683 return createElement( 18684 "tr", 18685 { 18686 className: [ 18687 "fc-list-event", 18688 hookProps.event.url ? "fc-event-forced-url" : "", 18689 ] 18690 .concat(classNames) 18691 .join(" "), 18692 ref: rootElRef, 18693 }, 18694 buildTimeContent(seg, timeFormat, context), 18695 createElement( 18696 "td", 18697 { className: "fc-list-event-graphic" }, 18698 createElement("span", { 18699 className: "fc-list-event-dot", 18700 style: { 18701 borderColor: 18702 hookProps.borderColor || hookProps.backgroundColor, 18703 }, 18704 }) 18705 ), 18706 createElement( 18707 "td", 18708 { className: "fc-list-event-title", ref: innerElRef }, 18709 innerContent 18710 ) 18711 ); 18712 } 18713 ); 18714 }; 18715 return ListViewEventRow; 18716 })(BaseComponent); 18717 function renderEventInnerContent(props) { 18718 var event = props.event; 18719 var url = event.url; 18720 var anchorAttrs = url ? { href: url } : {}; 18721 return createElement("a", __assign({}, anchorAttrs), event.title); 18722 } 18723 function buildTimeContent(seg, timeFormat, context) { 18724 var options = context.options; 18725 if (options.displayEventTime !== false) { 18726 var eventDef = seg.eventRange.def; 18727 var eventInstance = seg.eventRange.instance; 18728 var doAllDay = false; 18729 var timeText = void 0; 18730 if (eventDef.allDay) { 18731 doAllDay = true; 18732 } else if (isMultiDayRange(seg.eventRange.range)) { 18733 // TODO: use (!isStart || !isEnd) instead? 18734 if (seg.isStart) { 18735 timeText = buildSegTimeText( 18736 seg, 18737 timeFormat, 18738 context, 18739 null, 18740 null, 18741 eventInstance.range.start, 18742 seg.end 18743 ); 18744 } else if (seg.isEnd) { 18745 timeText = buildSegTimeText( 18746 seg, 18747 timeFormat, 18748 context, 18749 null, 18750 null, 18751 seg.start, 18752 eventInstance.range.end 18753 ); 18754 } else { 18755 doAllDay = true; 18756 } 18757 } else { 18758 timeText = buildSegTimeText(seg, timeFormat, context); 18759 } 18760 if (doAllDay) { 18761 var hookProps = { 18762 text: context.options.allDayText, 18763 view: context.viewApi, 18764 }; 18765 return createElement( 18766 RenderHook, 18767 { 18768 hookProps: hookProps, 18769 classNames: options.allDayClassNames, 18770 content: options.allDayContent, 18771 defaultContent: renderAllDayInner$1, 18772 didMount: options.allDayDidMount, 18773 willUnmount: options.allDayWillUnmount, 18774 }, 18775 function (rootElRef, classNames, innerElRef, innerContent) { 18776 return createElement( 18777 "td", 18778 { 18779 className: ["fc-list-event-time"].concat(classNames).join(" "), 18780 ref: rootElRef, 18781 }, 18782 innerContent 18783 ); 18784 } 18785 ); 18786 } else { 18787 return createElement( 18788 "td", 18789 { className: "fc-list-event-time" }, 18790 timeText 18791 ); 18792 } 18793 } 18794 return null; 18795 } 18796 function renderAllDayInner$1(hookProps) { 18797 return hookProps.text; 18798 } 18799 18800 /* 18801 Responsible for the scroller, and forwarding event-related actions into the "grid". 18802 */ 18803 var ListView = /** @class */ (function (_super) { 18804 __extends(ListView, _super); 18805 function ListView() { 18806 var _this = (_super !== null && _super.apply(this, arguments)) || this; 18807 _this.computeDateVars = memoize(computeDateVars); 18808 _this.eventStoreToSegs = memoize(_this._eventStoreToSegs); 18809 _this.setRootEl = function (rootEl) { 18810 if (rootEl) { 18811 _this.context.registerInteractiveComponent(_this, { 18812 el: rootEl, 18813 }); 18814 } else { 18815 _this.context.unregisterInteractiveComponent(_this); 18816 } 18817 }; 18818 return _this; 18819 } 18820 ListView.prototype.render = function () { 18821 var _this = this; 18822 var _a = this, 18823 props = _a.props, 18824 context = _a.context; 18825 var extraClassNames = [ 18826 "fc-list", 18827 context.theme.getClass("table"), 18828 context.options.stickyHeaderDates !== false ? "fc-list-sticky" : "", 18829 ]; 18830 var _b = this.computeDateVars(props.dateProfile), 18831 dayDates = _b.dayDates, 18832 dayRanges = _b.dayRanges; 18833 var eventSegs = this.eventStoreToSegs( 18834 props.eventStore, 18835 props.eventUiBases, 18836 dayRanges 18837 ); 18838 return createElement( 18839 ViewRoot, 18840 { viewSpec: context.viewSpec, elRef: this.setRootEl }, 18841 function (rootElRef, classNames) { 18842 return createElement( 18843 "div", 18844 { 18845 ref: rootElRef,
18846 className: extraClassNames.concat(classNames).join(" "), 18847 }, 18848 createElement( 18849 Scroller, 18850 { 18851 liquid: !props.isHeightAuto, 18852 overflowX: props.isHeightAuto ? "visible" : "hidden", 18853 overflowY: props.isHeightAuto ? "visible" : "auto", 18854 }, 18855 eventSegs.length > 0 18856 ? _this.renderSegList(eventSegs, dayDates) 18857 : _this.renderEmptyMessage() 18858 ) 18859 ); 18860 } 18861 ); 18862 }; 18863 ListView.prototype.renderEmptyMessage = function () { 18864 var _a = this.context, 18865 options = _a.options, 18866 viewApi = _a.viewApi; 18867 var hookProps = { 18868 text: options.noEventsText, 18869 view: viewApi, 18870 }; 18871 return createElement( 18872 RenderHook, 18873 { 18874 hookProps: hookProps, 18875 classNames: options.noEventsClassNames, 18876 content: options.noEventsContent, 18877 defaultContent: renderNoEventsInner, 18878 didMount: options.noEventsDidMount, 18879 willUnmount: options.noEventsWillUnmount, 18880 }, 18881 function (rootElRef, classNames, innerElRef, innerContent) { 18882 return createElement( 18883 "div", 18884 { 18885 className: ["fc-list-empty"].concat(classNames).join(" "), 18886 ref: rootElRef, 18887 }, 18888 createElement( 18889 "div", 18890 { className: "fc-list-empty-cushion", ref: innerElRef }, 18891 innerContent 18892 ) 18893 ); 18894 } 18895 ); 18896 }; 18897 ListView.prototype.renderSegList = function (allSegs, dayDates) { 18898 var _a = this.context, 18899 theme = _a.theme, 18900 options = _a.options; 18901 var segsByDay = groupSegsByDay(allSegs); // sparse array 18902 return createElement( 18903 NowTimer, 18904 { unit: "day" }, 18905 function (nowDate, todayRange) { 18906 var innerNodes = []; 18907 for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { 18908 var daySegs = segsByDay[dayIndex]; 18909 if (daySegs) { 18910 // sparse array, so might be undefined 18911 var dayStr = dayDates[dayIndex].toISOString(); 18912 // append a day header 18913 innerNodes.push( 18914 createElement(ListViewHeaderRow, { 18915 key: dayStr, 18916 dayDate: dayDates[dayIndex], 18917 todayRange: todayRange, 18918 }) 18919 ); 18920 daySegs = sortEventSegs(daySegs, options.eventOrder); 18921 for ( 18922 var _i = 0, daySegs_1 = daySegs; 18923 _i < daySegs_1.length; 18924 _i++ 18925 ) { 18926 var seg = daySegs_1[_i]; 18927 innerNodes.push( 18928 createElement( 18929 ListViewEventRow, 18930 __assign( 18931 { 18932 key: 18933 dayStr + 18934 ":" + 18935 seg.eventRange.instance 18936 .instanceId /* are multiple segs for an instanceId */, 18937 seg: seg, 18938 isDragging: false, 18939 isResizing: false, 18940 isDateSelecting: false, 18941 isSelected: false, 18942 }, 18943 getSegMeta(seg, todayRange, nowDate) 18944 ) 18945 ) 18946 ); 18947 } 18948 } 18949 } 18950 return createElement( 18951 "table", 18952 { className: "fc-list-table " + theme.getClass("table") }, 18953 createElement("tbody", null, innerNodes) 18954 ); 18955 } 18956 ); 18957 }; 18958 ListView.prototype._eventStoreToSegs = function ( 18959 eventStore, 18960 eventUiBases, 18961 dayRanges 18962 ) { 18963 return this.eventRangesToSegs( 18964 sliceEventStore( 18965 eventStore, 18966 eventUiBases, 18967 this.props.dateProfile.activeRange, 18968 this.context.options.nextDayThreshold 18969 ).fg, 18970 dayRanges 18971 ); 18972 }; 18973 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 18974 var segs = []; 18975 for ( 18976 var _i = 0, eventRanges_1 = eventRanges; 18977 _i < eventRanges_1.length; 18978 _i++ 18979 ) { 18980 var eventRange = eventRanges_1[_i]; 18981 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 18982 } 18983 return segs; 18984 }; 18985 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 18986 var dateEnv = this.context.dateEnv; 18987 var nextDayThreshold = this.context.options.nextDayThreshold; 18988 var range = eventRange.range; 18989 var allDay = eventRange.def.allDay; 18990 var dayIndex; 18991 var segRange; 18992 var seg; 18993 var segs = []; 18994 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { 18995 segRange = intersectRanges(range, dayRanges[dayIndex]); 18996 if (segRange) { 18997 seg = { 18998 component: this, 18999 eventRange: eventRange, 19000 start: segRange.start, 19001 end: segRange.end, 19002 isStart: 19003 eventRange.isStart && 19004 segRange.start.valueOf() === range.start.valueOf(), 19005 isEnd: 19006 eventRange.isEnd && 19007 segRange.end.valueOf() === range.end.valueOf(), 19008 dayIndex: dayIndex, 19009 }; 19010 segs.push(seg); 19011 // detect when range won't go fully into the next day, 19012 // and mutate the latest seg to the be the end. 19013 if ( 19014 !seg.isEnd && 19015 !allDay && 19016 dayIndex + 1 < dayRanges.length && 19017 range.end < 19018 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold) 19019 ) { 19020 seg.end = range.end; 19021 seg.isEnd = true; 19022 break; 19023 } 19024 } 19025 } 19026 return segs; 19027 }; 19028 return ListView; 19029 })(DateComponent); 19030 function renderNoEventsInner(hookProps) { 19031 return hookProps.text; 19032 } 19033 function computeDateVars(dateProfile) { 19034 var dayStart = startOfDay(dateProfile.renderRange.start); 19035 var viewEnd = dateProfile.renderRange.end; 19036 var dayDates = []; 19037 var dayRanges = []; 19038 while (dayStart < viewEnd) { 19039 dayDates.push(dayStart); 19040 dayRanges.push({ 19041 start: dayStart, 19042 end: addDays(dayStart, 1), 19043 }); 19044 dayStart = addDays(dayStart, 1); 19045 } 19046 return { dayDates: dayDates, dayRanges: dayRanges }; 19047 } 19048 // Returns a sparse array of arrays, segs grouped by their dayIndex 19049 function groupSegsByDay(segs) { 19050 var segsByDay = []; // sparse array 19051 var i; 19052 var seg; 19053 for (i = 0; i < segs.length; i++) { 19054 seg = segs[i]; 19055 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])).push(seg); 19056 } 19057 return segsByDay; 19058 } 19059 19060 var OPTION_REFINERS$2 = { 19061 listDayFormat: createFalsableFormatter, 19062 listDaySideFormat: createFalsableFormatter, 19063 noEventsClassNames: identity, 19064 noEventsContent: identity, 19065 noEventsDidMount: identity, 19066 noEventsWillUnmount: identity, 19067 // noEventsText is defined in base options 19068 }; 19069 function createFalsableFormatter(input) { 19070 return input === false ? null : createFormatter(input); 19071 } 19072 19073 var listPlugin = createPlugin({ 19074 optionRefiners: OPTION_REFINERS$2, 19075 views: { 19076 list: { 19077 component: ListView, 19078 buttonTextKey: "list",
19079 listDayFormat: { month: "long", day: "numeric", year: "numeric" }, // like "January 1, 2016" 19080 }, 19081 listDay: { 19082 type: "list", 19083 duration: { days: 1 }, 19084 listDayFormat: { weekday: "long" }, // day-of-week is all we need. full date is probably in headerToolbar 19085 }, 19086 listWeek: { 19087 type: "list", 19088 duration: { weeks: 1 }, 19089 listDayFormat: { weekday: "long" }, 19090 listDaySideFormat: { month: "long", day: "numeric", year: "numeric" }, 19091 }, 19092 listMonth: { 19093 type: "list", 19094 duration: { month: 1 }, 19095 listDaySideFormat: { weekday: "long" }, // day-of-week is nice-to-have 19096 }, 19097 listYear: { 19098 type: "list", 19099 duration: { year: 1 }, 19100 listDaySideFormat: { weekday: "long" }, // day-of-week is nice-to-have 19101 }, 19102 }, 19103 }); 19104 19105 var BootstrapTheme = /** @class */ (function (_super) { 19106 __extends(BootstrapTheme, _super); 19107 function BootstrapTheme() { 19108 return (_super !== null && _super.apply(this, arguments)) || this; 19109 } 19110 return BootstrapTheme; 19111 })(Theme); 19112 BootstrapTheme.prototype.classes = { 19113 root: "fc-theme-bootstrap", 19114 table: "table-bordered", 19115 tableCellShaded: "table-active", 19116 buttonGroup: "btn-group", 19117 button: "btn btn-primary", 19118 buttonActive: "active", 19119 popover: "popover", 19120 popoverHeader: "popover-header", 19121 popoverContent: "popover-body", 19122 }; 19123 BootstrapTheme.prototype.baseIconClass = "fa"; 19124 BootstrapTheme.prototype.iconClasses = { 19125 close: "fa-times", 19126 prev: "fa-chevron-left", 19127 next: "fa-chevron-right", 19128 prevYear: "fa-angle-double-left", 19129 nextYear: "fa-angle-double-right", 19130 }; 19131 BootstrapTheme.prototype.rtlIconClasses = { 19132 prev: "fa-chevron-right", 19133 next: "fa-chevron-left", 19134 prevYear: "fa-angle-double-right", 19135 nextYear: "fa-angle-double-left", 19136 }; 19137 BootstrapTheme.prototype.iconOverrideOption = "bootstrapFontAwesome"; // TODO: make TS-friendly. move the option-processing into this plugin 19138 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 19139 "bootstrapFontAwesome"; 19140 BootstrapTheme.prototype.iconOverridePrefix = "fa-"; 19141 var plugin = createPlugin({ 19142 themeClasses: { 19143 bootstrap: BootstrapTheme, 19144 }, 19145 }); 19146 19147 // rename this file to options.ts like other packages? 19148 var OPTION_REFINERS$3 = { 19149 googleCalendarApiKey: String, 19150 }; 19151 19152 var EVENT_SOURCE_REFINERS$1 = { 19153 googleCalendarApiKey: String, 19154 googleCalendarId: String, 19155 googleCalendarApiBase: String, 19156 extraParams: identity, 19157 }; 19158 19159 // TODO: expose somehow 19160 var API_BASE = "https://www.googleapis.com/calendar/v3/calendars"; 19161 var eventSourceDef$3 = { 19162 parseMeta: function (refined) { 19163 var googleCalendarId = refined.googleCalendarId; 19164 if (!googleCalendarId && refined.url) { 19165 googleCalendarId = parseGoogleCalendarId(refined.url); 19166 } 19167 if (googleCalendarId) { 19168 return { 19169 googleCalendarId: googleCalendarId, 19170 googleCalendarApiKey: refined.googleCalendarApiKey, 19171 googleCalendarApiBase: refined.googleCalendarApiBase, 19172 extraParams: refined.extraParams, 19173 }; 19174 } 19175 return null; 19176 }, 19177 fetch: function (arg, onSuccess, onFailure) { 19178 var _a = arg.context, 19179 dateEnv = _a.dateEnv, 19180 options = _a.options; 19181 var meta = arg.eventSource.meta; 19182 var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; 19183 if (!apiKey) { 19184 onFailure({ 19185 message: 19186 "Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/", 19187 }); 19188 } else { 19189 var url = buildUrl(meta); 19190 // TODO: make DRY with json-feed-event-source 19191 var extraParams = meta.extraParams; 19192 var extraParamsObj = 19193 typeof extraParams === "function" ? extraParams() : extraParams; 19194 var requestParams_1 = buildRequestParams$1( 19195 arg.range, 19196 apiKey, 19197 extraParamsObj, 19198 dateEnv 19199 ); 19200 requestJson( 19201 "GET", 19202 url, 19203 requestParams_1, 19204 function (body, xhr) { 19205 if (body.error) { 19206 onFailure({ 19207 message: "Google Calendar API: " + body.error.message, 19208 errors: body.error.errors, 19209 xhr: xhr, 19210 }); 19211 } else { 19212 onSuccess({ 19213 rawEvents: gcalItemsToRawEventDefs( 19214 body.items,
19215 requestParams_1.timeZone 19216 ), 19217 xhr: xhr, 19218 }); 19219 } 19220 }, 19221 function (message, xhr) { 19222 onFailure({ message: message, xhr: xhr }); 19223 } 19224 ); 19225 } 19226 }, 19227 }; 19228 function parseGoogleCalendarId(url) { 19229 var match; 19230 // detect if the ID was specified as a single string. 19231 // will match calendars like "[email protected]" in addition to person email calendars. 19232 if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 19233 return url; 19234 } else if ( 19235 (match = 19236 /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec( 19237 url 19238 )) || 19239 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url)) 19240 ) { 19241 return decodeURIComponent(match[1]); 19242 } 19243 } 19244 function buildUrl(meta) { 19245 var apiBase = meta.googleCalendarApiBase; 19246 if (!apiBase) { 19247 apiBase = API_BASE; 19248 } 19249 return ( 19250 apiBase + "/" + encodeURIComponent(meta.googleCalendarId) + "/events" 19251 ); 19252 } 19253 function buildRequestParams$1(range, apiKey, extraParams, dateEnv) { 19254 var params; 19255 var startStr; 19256 var endStr; 19257 if (dateEnv.canComputeOffset) { 19258 // strings will naturally have offsets, which GCal needs 19259 startStr = dateEnv.formatIso(range.start); 19260 endStr = dateEnv.formatIso(range.end); 19261 } else { 19262 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 19263 // from the UTC day-start to guarantee we're getting all the events 19264 // (start/end will be UTC-coerced dates, so toISOString is okay) 19265 startStr = addDays(range.start, -1).toISOString(); 19266 endStr = addDays(range.end, 1).toISOString(); 19267 } 19268 params = __assign(__assign({}, extraParams || {}), { 19269 key: apiKey, 19270 timeMin: startStr, 19271 timeMax: endStr, 19272 singleEvents: true, 19273 maxResults: 9999, 19274 }); 19275 if (dateEnv.timeZone !== "local") { 19276 params.timeZone = dateEnv.timeZone; 19277 } 19278 return params; 19279 } 19280 function gcalItemsToRawEventDefs(items, gcalTimezone) { 19281 return items.map(function (item) { 19282 return gcalItemToRawEventDef(item, gcalTimezone); 19283 }); 19284 } 19285 function gcalItemToRawEventDef(item, gcalTimezone) { 19286 var url = item.htmlLink || null; 19287 // make the URLs for each event show times in the correct timezone 19288 if (url && gcalTimezone) { 19289 url = injectQsComponent(url, "ctz=" + gcalTimezone); 19290 } 19291 return { 19292 id: item.id, 19293 title: item.summary, 19294 start: item.start.dateTime || item.start.date, 19295 end: item.end.dateTime || item.end.date, 19296 url: url, 19297 location: item.location, 19298 description: item.description, 19299 }; 19300 } 19301 // Injects a string like "arg=value" into the querystring of a URL 19302 // TODO: move to a general util file? 19303 function injectQsComponent(url, component) { 19304 // inject it after the querystring but before the fragment 19305 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { 19306 return (qs ? qs + "&" : "?") + component + hash; 19307 }); 19308 } 19309 var googleCalendarPlugin = createPlugin({ 19310 eventSourceDefs: [eventSourceDef$3], 19311 optionRefiners: OPTION_REFINERS$3, 19312 eventSourceRefiners: EVENT_SOURCE_REFINERS$1, 19313 }); 19314 19315 globalPlugins.push( 19316 interactionPlugin, 19317 dayGridPlugin, 19318 timeGridPlugin, 19319 listPlugin, 19320 plugin, 19321 googleCalendarPlugin 19322 ); 19323 19324 exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS; 19325 exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS; 19326 exports.BaseComponent = BaseComponent; 19327 exports.BgEvent = BgEvent; 19328 exports.BootstrapTheme = BootstrapTheme; 19329 exports.Calendar = Calendar; 19330 exports.CalendarApi = CalendarApi; 19331 exports.CalendarContent = CalendarContent; 19332 exports.CalendarDataManager = CalendarDataManager; 19333 exports.CalendarDataProvider = CalendarDataProvider; 19334 exports.CalendarRoot = CalendarRoot; 19335 exports.Component = Component; 19336 exports.ContentHook = ContentHook; 19337 exports.CustomContentRenderContext = CustomContentRenderContext; 19338 exports.DateComponent = DateComponent; 19339 exports.DateEnv = DateEnv; 19340 exports.DateProfileGenerator = DateProfileGenerator; 19341 exports.DayCellContent = DayCellContent; 19342 exports.DayCellRoot = DayCellRoot; 19343 exports.DayGridView = DayTableView; 19344 exports.DayHeader = DayHeader;
19345 exports.DaySeriesModel = DaySeriesModel; 19346 exports.DayTable = DayTable; 19347 exports.DayTableModel = DayTableModel; 19348 exports.DayTableSlicer = DayTableSlicer; 19349 exports.DayTimeCols = DayTimeCols; 19350 exports.DayTimeColsSlicer = DayTimeColsSlicer; 19351 exports.DayTimeColsView = DayTimeColsView; 19352 exports.DelayedRunner = DelayedRunner; 19353 exports.Draggable = ExternalDraggable; 19354 exports.ElementDragging = ElementDragging; 19355 exports.ElementScrollController = ElementScrollController; 19356 exports.Emitter = Emitter; 19357 exports.EventApi = EventApi; 19358 exports.EventRoot = EventRoot; 19359 exports.EventSourceApi = EventSourceApi; 19360 exports.FeaturefulElementDragging = FeaturefulElementDragging; 19361 exports.Fragment = Fragment; 19362 exports.Interaction = Interaction; 19363 exports.ListView = ListView; 19364 exports.MountHook = MountHook; 19365 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 19366 exports.NowIndicatorRoot = NowIndicatorRoot; 19367 exports.NowTimer = NowTimer; 19368 exports.PointerDragging = PointerDragging; 19369 exports.PositionCache = PositionCache; 19370 exports.RefMap = RefMap; 19371 exports.RenderHook = RenderHook; 19372 exports.ScrollController = ScrollController; 19373 exports.ScrollResponder = ScrollResponder; 19374 exports.Scroller = Scroller; 19375 exports.SimpleScrollGrid = SimpleScrollGrid; 19376 exports.Slicer = Slicer; 19377 exports.Splitter = Splitter; 19378 exports.StandardEvent = StandardEvent; 19379 exports.Table = Table; 19380 exports.TableDateCell = TableDateCell; 19381 exports.TableDowCell = TableDowCell; 19382 exports.TableView = TableView; 19383 exports.Theme = Theme; 19384 exports.ThirdPartyDraggable = ThirdPartyDraggable; 19385 exports.TimeCols = TimeCols; 19386 exports.TimeColsSlatsCoords = TimeColsSlatsCoords; 19387 exports.TimeColsView = TimeColsView; 19388 exports.ViewApi = ViewApi; 19389 exports.ViewContextType = ViewContextType; 19390 exports.ViewRoot = ViewRoot; 19391 exports.WeekNumberRoot = WeekNumberRoot; 19392 exports.WindowScrollController = WindowScrollController; 19393 exports.addDays = addDays; 19394 exports.addDurations = addDurations; 19395 exports.addMs = addMs; 19396 exports.addWeeks = addWeeks; 19397 exports.allowContextMenu = allowContextMenu; 19398 exports.allowSelection = allowSelection; 19399 exports.applyMutationToEventStore = applyMutationToEventStore; 19400 exports.applyStyle = applyStyle; 19401 exports.applyStyleProp = applyStyleProp; 19402 exports.asCleanDays = asCleanDays; 19403 exports.asRoughMinutes = asRoughMinutes; 19404 exports.asRoughMs = asRoughMs; 19405 exports.asRoughSeconds = asRoughSeconds; 19406 exports.buildClassNameNormalizer = buildClassNameNormalizer; 19407 exports.buildDayRanges = buildDayRanges; 19408 exports.buildDayTableModel = buildDayTableModel; 19409 exports.buildEventApis = buildEventApis; 19410 exports.buildEventRangeKey = buildEventRangeKey; 19411 exports.buildHashFromArray = buildHashFromArray; 19412 exports.buildNavLinkData = buildNavLinkData; 19413 exports.buildSegCompareObj = buildSegCompareObj; 19414 exports.buildSegTimeText = buildSegTimeText; 19415 exports.buildSlatMetas = buildSlatMetas; 19416 exports.buildTimeColsModel = buildTimeColsModel; 19417 exports.collectFromHash = collectFromHash; 19418 exports.combineEventUis = combineEventUis; 19419 exports.compareByFieldSpec = compareByFieldSpec; 19420 exports.compareByFieldSpecs = compareByFieldSpecs; 19421 exports.compareNumbers = compareNumbers; 19422 exports.compareObjs = compareObjs; 19423 exports.computeEdges = computeEdges; 19424 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 19425 exports.computeHeightAndMargins = computeHeightAndMargins; 19426 exports.computeInnerRect = computeInnerRect; 19427 exports.computeRect = computeRect; 19428 exports.computeSegDraggable = computeSegDraggable; 19429 exports.computeSegEndResizable = computeSegEndResizable; 19430 exports.computeSegStartResizable = computeSegStartResizable; 19431 exports.computeShrinkWidth = computeShrinkWidth; 19432 exports.computeSmallestCellWidth = computeSmallestCellWidth; 19433 exports.computeVisibleDayRange = computeVisibleDayRange; 19434 exports.config = config; 19435 exports.constrainPoint = constrainPoint; 19436 exports.createContext = createContext$1; 19437 exports.createDuration = createDuration; 19438 exports.createElement = createElement; 19439 exports.createEmptyEventStore = createEmptyEventStore; 19440 exports.createEventInstance = createEventInstance; 19441 exports.createEventUi = createEventUi; 19442 exports.createFormatter = createFormatter; 19443 exports.createPlugin = createPlugin; 19444 exports.createRef = createRef; 19445 exports.diffDates = diffDates; 19446 exports.diffDayAndTime = diffDayAndTime; 19447 exports.diffDays = diffDays; 19448 exports.diffPoints = diffPoints; 19449 exports.diffWeeks = diffWeeks; 19450 exports.diffWholeDays = diffWholeDays; 19451 exports.diffWholeWeeks = diffWholeWeeks; 19452 exports.disableCursor = disableCursor; 19453 exports.elementClosest = elementClosest; 19454 exports.elementMatches = elementMatches; 19455 exports.enableCursor = enableCursor; 19456 exports.eventTupleToStore = eventTupleToStore; 19457 exports.filterEventStoreDefs = filterEventStoreDefs; 19458 exports.filterHash = filterHash; 19459 exports.findDirectChildren = findDirectChildren; 19460 exports.findElements = findElements; 19461 exports.flexibleCompare = flexibleCompare; 19462 exports.flushToDom = flushToDom$1; 19463 exports.formatDate = formatDate; 19464 exports.formatDayString = formatDayString; 19465 exports.formatIsoTimeString = formatIsoTimeString; 19466 exports.formatRange = formatRange; 19467 exports.getAllowYScrolling = getAllowYScrolling; 19468 exports.getCanVGrowWithinCell = getCanVGrowWithinCell; 19469 exports.getClippingParents = getClippingParents; 19470 exports.getDateMeta = getDateMeta; 19471 exports.getDayClassNames = getDayClassNames; 19472 exports.getDefaultEventEnd = getDefaultEventEnd; 19473 exports.getElSeg = getElSeg; 19474 exports.getEventClassNames = getEventClassNames; 19475 exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft; 19476 exports.getRectCenter = getRectCenter; 19477 exports.getRelevantEvents = getRelevantEvents; 19478 exports.getScrollGridClassNames = getScrollGridClassNames;
19479 exports.getScrollbarWidths = getScrollbarWidths; 19480 exports.getSectionClassNames = getSectionClassNames; 19481 exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight; 19482 exports.getSegMeta = getSegMeta; 19483 exports.getSlotClassNames = getSlotClassNames; 19484 exports.getStickyFooterScrollbar = getStickyFooterScrollbar; 19485 exports.getStickyHeaderDates = getStickyHeaderDates; 19486 exports.getUnequalProps = getUnequalProps; 19487 exports.globalLocales = globalLocales; 19488 exports.globalPlugins = globalPlugins; 19489 exports.greatestDurationDenominator = greatestDurationDenominator; 19490 exports.guid = guid; 19491 exports.hasBgRendering = hasBgRendering; 19492 exports.hasShrinkWidth = hasShrinkWidth; 19493 exports.identity = identity; 19494 exports.interactionSettingsStore = interactionSettingsStore; 19495 exports.interactionSettingsToStore = interactionSettingsToStore; 19496 exports.intersectRanges = intersectRanges; 19497 exports.intersectRects = intersectRects; 19498 exports.isArraysEqual = isArraysEqual; 19499 exports.isColPropsEqual = isColPropsEqual; 19500 exports.isDateSpansEqual = isDateSpansEqual; 19501 exports.isInt = isInt; 19502 exports.isInteractionValid = isInteractionValid; 19503 exports.isMultiDayRange = isMultiDayRange; 19504 exports.isPropsEqual = isPropsEqual; 19505 exports.isPropsValid = isPropsValid; 19506 exports.isValidDate = isValidDate; 19507 exports.listenBySelector = listenBySelector; 19508 exports.mapHash = mapHash; 19509 exports.memoize = memoize; 19510 exports.memoizeArraylike = memoizeArraylike; 19511 exports.memoizeHashlike = memoizeHashlike; 19512 exports.memoizeObjArg = memoizeObjArg; 19513 exports.mergeEventStores = mergeEventStores; 19514 exports.multiplyDuration = multiplyDuration; 19515 exports.padStart = padStart; 19516 exports.parseBusinessHours = parseBusinessHours; 19517 exports.parseClassNames = parseClassNames; 19518 exports.parseDragMeta = parseDragMeta; 19519 exports.parseEventDef = parseEventDef; 19520 exports.parseFieldSpecs = parseFieldSpecs; 19521 exports.parseMarker = parse; 19522 exports.pointInsideRect = pointInsideRect; 19523 exports.preventContextMenu = preventContextMenu; 19524 exports.preventDefault = preventDefault; 19525 exports.preventSelection = preventSelection; 19526 exports.rangeContainsMarker = rangeContainsMarker; 19527 exports.rangeContainsRange = rangeContainsRange; 19528 exports.rangesEqual = rangesEqual; 19529 exports.rangesIntersect = rangesIntersect; 19530 exports.refineEventDef = refineEventDef; 19531 exports.refineProps = refineProps; 19532 exports.removeElement = removeElement; 19533 exports.removeExact = removeExact; 19534 exports.render = render; 19535 exports.renderChunkContent = renderChunkContent; 19536 exports.renderFill = renderFill; 19537 exports.renderMicroColGroup = renderMicroColGroup; 19538 exports.renderScrollShim = renderScrollShim; 19539 exports.requestJson = requestJson; 19540 exports.sanitizeShrinkWidth = sanitizeShrinkWidth; 19541 exports.setElSeg = setElSeg; 19542 exports.setRef = setRef; 19543 exports.sliceEventStore = sliceEventStore; 19544 exports.sliceEvents = sliceEvents; 19545 exports.sortEventSegs = sortEventSegs; 19546 exports.startOfDay = startOfDay; 19547 exports.translateRect = translateRect; 19548 exports.triggerDateSelect = triggerDateSelect; 19549 exports.unpromisify = unpromisify; 19550 exports.version = version; 19551 exports.whenTransitionDone = whenTransitionDone; 19552 exports.wholeDivideDurations = wholeDivideDurations; 19553 19554 return exports; 19555})({});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.