vendor: 4,325 bytes, lines 1-57
1/*! 2FullCalendar v5.7.2 3Docs & License: https://fullcalendar.io/ 4(c) 2021 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 = Object.setPrototypeOf || 27 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 28 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 29 return extendStatics(d, b); 30 }; 31 32 function __extends(d, b) { 33 if (typeof b !== "function" && b !== null) 34 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 35 extendStatics(d, b); 36 function __() { this.constructor = d; } 37 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 38 } 39 40 var __assign = function() { 41 __assign = Object.assign || function __assign(t) { 42 for (var s, i = 1, n = arguments.length; i < n; i++) { 43 s = arguments[i]; 44 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; 45 } 46 return t; 47 }; 48 return __assign.apply(this, arguments); 49 }; 50 51 function __spreadArray(to, from) { 52 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) 53 to[j] = from[i]; 54 return to; 55 } 56 57 var n,u,i$1,t,o,r$1={},f$1=[],e$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c$1(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n);}function a$1(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o<arguments.length;o++)u.push(r[o]);if(null!=u&&(f.children=u),"function"==typeof n&&null!=n.defaultProps)for(o in n.defaultProps)void 0===f[o]&&(f[o]=n.defaultProps[o]);return v$1(n,f,i,t,null)}function v$1(l,u,i,t,o){var r={type:l,props:u,key:i,ref:t,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++n.__v:o};return null!=n.vnode&&n.vnode(r),r}function h(){return {current:null}}function y(n){return n.children}function p(n,l){this.props=n,this.context=l;}function d(n,l){if(null==l)return n.__?d(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?d(n):null}function _(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return _(n)}}function k(l){(!l.__d&&(l.__d=!0)&&u.push(l)&&!b$1.__r++||t!==n.debounceRendering)&&((t=n.debounceRendering)||i$1)(b$1);}function b$1(){for(var n;b$1.__r=u.length;)n=u.sort(function(n,l){return n.__v.__b-l.__v.__b}),u=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=c$1({},t)).__v=t.__v+1,I$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?d(t):o,t.__h),T$1(u,t),t.__e!=o&&_(t)));});}function m(n,l,u,i,t,o,e,c,s,a){var h,p,_,k,b,m,w,A=i&&i.__k||f$1,P=A.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(y,{children:k},null,null,null):k.__b>
vendor: 7,710 bytes, line 57
570?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p<P;p++){if((_=A[p])&&k.key==_.key&&k.type===_.type){A[p]=void 0;break}_=null;}I$1(n,k,_=_||r$1,t,o,e,c,s,a),b=k.__e,(p=k.ref)&&_.ref!=p&&(w||(w=[]),_.ref&&w.push(_.ref,null,k),w.push(p,k.__c||b,k)),null!=b?(null==m&&(m=b),"function"==typeof k.type&&null!=k.__k&&k.__k===_.__k?k.__d=s=g$1(k,s,n):s=x$1(n,k,_,A,b,s),a||"option"!==u.type?"function"==typeof u.type&&(u.__d=s):n.value=""):s&&_.__e==s&&s.parentNode!=n&&(s=d(_));}for(u.__e=m,h=P;h--;)null!=A[h]&&("function"==typeof u.type&&null!=A[h].__e&&A[h].__e==u.__d&&(u.__d=d(i,h+1)),L$1(A[h],A[h]));if(w)for(h=0;h<w.length;h++)z(w[h],w[++h],w[++h]);}function g$1(n,l,u){var i,t;for(i=0;i<n.__k.length;i++)(t=n.__k[i])&&(t.__=n,l="function"==typeof t.type?g$1(t,l,u):x$1(u,t,t,n.__k,t.__e,l));return l}function w$1(n,l){return l=l||[],null==n||"boolean"==typeof n||(Array.isArray(n)?n.some(function(n){w$1(n,l);}):l.push(n)),l}function x$1(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function A$1(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||C$1(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||C$1(n,o,l[o],u[o],i);}function P$1(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||e$1.test(l)?u:u+"px";}function C$1(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||P$1(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||P$1(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?H$1:$$1,o):n.removeEventListener(l,o?H$1:$$1,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink[H:h]/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function $$1(l){this.l[l.type+!1](n.event?n.event(l):l);}function H$1(l){this.l[l.type+!0](n.event?n.event(l):l);}function I$1(l,u,i,t,o,r,f,e,s){var a,v,h,d,_,k,b,g,w,x,A,P=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(s=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=n.__b)&&a(u);try{n:if("function"==typeof P){if(g=u.props,w=(a=P.contextType)&&t[a.__c],x=a?w?w.props.value:a.__:t,i.__c?b=(v=u.__c=i.__c).__=v.__E:("prototype"in P&&P.prototype.render?u.__c=v=new P(g,x):(u.__c=v=new p(g,x),v.constructor=P,v.render=M$1),w&&w.sub(v),v.props=g,v.state||(v.state={}),v.context=x,v.__n=t,h=v.__d=!0,v.__h=[]),null==v.__s&&(v.__s=v.state),null!=P.getDerivedStateFromProps&&(v.__s==v.state&&(v.__s=c$1({},v.__s)),c$1(v.__s,P.getDerivedStateFromProps(g,v.__s))),d=v.props,_=v.state,h)null==P.getDerivedStateFromProps&&null!=v.componentWillMount&&v.componentWillMount(),null!=v.componentDidMount&&v.__h.push(v.componentDidMount);else {if(null==P.getDerivedStateFromProps&&g!==d&&null!=v.componentWillReceiveProps&&v.componentWillReceiveProps(g,x),!v.__e&&null!=v.shouldComponentUpdate&&!1===v.shouldComponentUpdate(g,v.__s,x)||u.__v===i.__v){v.props=g,v.state=v.__s,u.__v!==i.__v&&(v.__d=!1),v.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),v.__h.length&&f.push(v);break n}null!=v.componentWillUpdate&&v.componentWillUpdate(g,v.__s,x),null!=v.componentDidUpdate&&v.__h.push(function(){v.componentDidUpdate(d,_,k);});}v.context=x,v.props=g,v.state=v.__s,(a=n.__r)&&a(u),v.__d=!1,v.__v=u,v.__P=l,a=v.render(v.props,v.state,v.context),v.state=v.__s,null!=v.getChildContext&&(t=c$1(c$1({},t),v.getChildContext())),h||null==v.getSnapshotBeforeUpdate||(k=v.getSnapshotBeforeUpdate(d,_)),A=null!=a&&a.type===y&&null==a.key?a.props.children:a,m(l,Array.isArray(A)?A:[A],u,i,t,o,r,f,e,s),v.base=u.__e,u.__h=null,v.__h.length&&f.push(v),b&&(v.__E=v.__=null),v.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=j$2(i.__e,u,i,t,o,r,f,s);(a=n.diffed)&&a(u);}catch(l){u.__v=null,(s||null!=r)&&(u.__e=e,u.__h=!!s,r[r.indexOf(e)]=null),n.__e(l,u,i);}}function T$1(l,u){n.__c&&n.__c(u,l),l.some(function(u){try{l=u.__h,u.__h=[],l.some(function(n){n.call(u);});}catch(l){n.__e(l,u.__v);}});}function j$2(n,l,u,i,t,o,e,c){var a,v,h,y,p=u.props,d=l.props,_=l.type,k=0;if("svg"===_&&(t=!0),null!=o)for(;k<o.length;k++)if((a=o[k])&&(a===n||(_?a.localName==_:3==a.nodeType))){n=a,o[k]=null;break}if(null==n){if(null===_)return document.createTextNode(d);n=t?document.createElementNS("http://www.w3.org/2000/svg",_):document.createElement(_,d.is&&d),o=null,c=!1;}if(null===_)p===d||c&&n.data===d||(n.data=d);else {if(o=o&&f$1.slice.call(n.childNodes),v=(p=u.props||r$1).dangerouslySetInnerHTML,h=d.dangerouslySetInnerHTML,!c){if(null!=o)for(p={},y=0;y<n.attributes.length;y++)p[n.attributes[y].name]=n.attributes[y].value;(h||v)&&(h&&(v&&h.__html==v.__html||h.__html===n.innerHTML)||(n.innerHTML=h&&h.__html||""));}if(A$1(n,d,p,t,c),h)l.__k=[];else if(k=l.props.children,m(n,Array.isArray(k)?k:[k],l,u,i,t&&"foreignObject"!==_,o,e,n.firstChild,c),null!=o)for(k=o.length;k--;)null!=o[k]&&s(o[k]);c||("value"in d&&void 0!==(k=d.value)&&(k!==n.value||"progress"===_&&!k)&&C$1(n,"value",k,p.value,!1),"checked"in d&&void 0!==(k=d.checked)&&k!==n.checked&&C$1(n,"checked",k,p.checked,!1));}return n}function z(l,u,i){try{"function"==typeof l?l(u):l.current=u;}catch(l){n.__e(l,i);}}function L$1(l,u,i){var t,o,r;if(n.unmount&&n.unmount(l),(t=l.ref)&&(t.current&&t.current!==l.__e||z(t,null,u)),i||"function"==typeof l.type||(i=null!=(o=l.__e)),l.__e=l.__d=void 0,null!=(t=l.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(l){n.__e(l,u);}t.base=t.__P=null;}if(t=l.__k)for(r=0;r<t.length;r++)t[r]&&L$1(t[r],u,i);null!=o&&s(o);}function M$1(n,l,u){return this.constructor(n,u)}function N(l,u,i){var t,o,e;n.__&&n.__(l,u),o=(t="function"==typeof i)?null:i&&i.__k||u.__k,e=[],I$1(u,l=(!t&&i||u).__k=a$1(y,null,[l]),o||r$1,r$1,void 0!==u.ownerSVGElement,!t&&i?[i]:o?null:u.firstChild?f$1.slice.call(u.childNodes):null,e,!t&&i?i:o?o.__e:u.firstChild,t),T$1(e,l);}function q(n,l){var u={__c:l="__cC"+o++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(k);},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n);};}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n={__e:function(n,l){for(var u,i,t;l=l.__;)if((u=l.__c)&&!u.__)try{if((i=u.constructor)&&null!=i.getDerivedStateFromError&&(u.setState(i.getDerivedStateFromError(n)),t=u.__d),null!=u.componentDidCatch&&(u.componentDidCatch(n),t=u.__d),t)return u.__E=u}catch(l){n=l;}throw n},__v:0},p.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=c$1({},this.state),"function"==typeof n&&(n=n(c$1({},u),this.props)),n&&c$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),k(this));},p.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),k(this));},p.prototype.render=y,u=[],i$1="function"==typeof Promise?Promise.prototype.then.bind(Prom
vendor: 5,073 bytes, lines 57-61
57ise.resolve()):setTimeout,b$1.__r=0,o=0; 58 59 var r,i=[],c=n.__b,f=n.__r,e=n.diffed,a=n.__c,v=n.unmount;function x(){i.forEach(function(t){if(t.__P)try{t.__H.__h.forEach(g),t.__H.__h.forEach(j$1),t.__H.__h=[];}catch(u){t.__H.__h=[],n.__e(u,t.__v);}}),i=[];}n.__b=function(n){c&&c(n);},n.__r=function(n){f&&f(n);var r=(n.__c).__H;r&&(r.__h.forEach(g),r.__h.forEach(j$1),r.__h=[]);},n.diffed=function(t){e&&e(t);var o=t.__c;o&&o.__H&&o.__H.__h.length&&(1!==i.push(o)&&r===n.requestAnimationFrame||((r=n.requestAnimationFrame)||function(n){var t,u=function(){clearTimeout(r),b&&cancelAnimationFrame(t),setTimeout(n);},r=setTimeout(u,100);b&&(t=requestAnimationFrame(u));})(x));},n.__c=function(t,u){u.some(function(t){try{t.__h.forEach(g),t.__h=t.__h.filter(function(n){return !n.__||j$1(n)});}catch(r){u.some(function(n){n.__h&&(n.__h=[]);}),u=[],n.__e(r,t.__v);}}),a&&a(t,u);},n.unmount=function(t){v&&v(t);var u=t.__c;if(u&&u.__H)try{u.__H.__.forEach(g);}catch(t){n.__e(t,u.__v);}};var b="function"==typeof requestAnimationFrame;function g(n){"function"==typeof n.__c&&n.__c();}function j$1(n){n.__c=n.__();} 60 61 function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return !0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return !0;return !1}function E(n){this.props=n;}(E.prototype=new p).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=n.__b;n.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n);};var A=n.__e;n.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e);};var O=n.unmount;function L(){this.__u=0,this.t=null,this.__b=null;}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function F(){this.u=null,this.o=null;}n.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n);},(L.prototype=new p).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l());};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O);}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate();}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i);},L.prototype.componentWillUnmount=function(){this.t=[];},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c();}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P);}this.__b=null;}var u=t.__e&&a$1(y,null,n.fallback);return u&&(u.__h=null),[a$1(y,null,t.__e?null:n.children),u]};var M=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]<e[0])break;n.u=e=e[2];}};function T(n){return this.getChildContext=function(){return n.context},n.children}function j(n){var t=this,e=n.i;t.componentWillUnmount=function(){N(null,t.l),t.l=null,t.i=null;},t.i&&t.i!==e&&t.componentWillUnmount(),n.__v?(t.l||(t.i=e,t.l={nodeType:1,parentNode:e,childNodes:[],appendChild:function(n){this.childNodes.push(n),t.i.appendChild(n);},insertBefore:function(n,e){this.childNodes.push(n),t.i.appendChild(n);},removeChild:function(n){this.childNodes.splice(this.childNodes.indexOf(n)>>>1,1),t.i.removeChild(n);}}),N(a$1(T,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount();}function I(n,t){return a$1(j,{__v:n,i:t})}(F.prototype=new p).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),M(t,n,r)):u();};e?e(o):o();}},F.prototype.render=function(n){this.u=null,this.o=new Map;var t=w$1(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},F.prototype.componentDidUpdate=F.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){M(n,e,t);});};var W="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return ("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};p.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(p.prototype,n,{
61configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t});}});});var H=n.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}n.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var G={configurable:!0,get:function(){return this.class}},J=n.vnode;n.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o);}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value);})),"select"==t&&null!=r.defaultValue&&(r.value=w$1(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value;})),n.props=r;}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=W,J&&J(n);};var K=n.__r;n.__r=function(n){K&&K(n);};"object"==typeof performance&&"function"==typeof performance.now?performance.now.bind(performance):function(){return Date.now()}; 62 63 var globalObj = typeof globalThis !== 'undefined' ? globalThis : window; // // TODO: streamline when killing IE11 support 64 if (globalObj.FullCalendarVDom) { 65 console.warn('FullCalendar VDOM already loaded'); 66 } 67 else { 68 globalObj.FullCalendarVDom = { 69 Component: p, 70 createElement: a$1, 71 render: N, 72 createRef: h, 73 Fragment: y, 74 createContext: createContext$1, 75 createPortal: I, 76 flushToDom: flushToDom$1, 77 unmountComponentAtNode: unmountComponentAtNode$1, 78 }; 79 } 80 // HACKS... 81 // TODO: lock version 82 // TODO: link gh issues 83 function flushToDom$1() { 84 var oldDebounceRendering = n.debounceRendering; // orig 85 var callbackQ = []; 86 function execCallbackSync(callback) { 87 callbackQ.push(callback); 88 } 89 n.debounceRendering = execCallbackSync; 90 N(a$1(FakeComponent, {}), document.createElement('div')); 91 while (callbackQ.length) { 92 callbackQ.shift()(); 93 } 94 n.debounceRendering = oldDebounceRendering; 95 } 96 var FakeComponent = /** @class */ (function (_super) { 97 __extends(FakeComponent, _super); 98 function FakeComponent() { 99 return _super !== null && _super.apply(this, arguments) || this; 100 } 101 FakeComponent.prototype.render = function () { return a$1('div', {}); }; 102 FakeComponent.prototype.componentDidMount = function () { this.setState({}); }; 103 return FakeComponent; 104 }(p)); 105 function createContext$1(defaultValue) { 106 var ContextType = q(defaultValue); 107 var origProvider = ContextType.Provider; 108 ContextType.Provider = function () { 109 var _this = this; 110 var isNew = !this.getChildContext; 111 var children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params 112 if (isNew) { 113 var subs_1 = []; 114 this.shouldComponentUpdate = function (_props) { 115 if (_this.props.value !== _props.value) { 116 subs_1.forEach(function (c) { 117 c.context = _props.value; 118 c.forceUpdate(); 119 }); 120 } 121 }; 122 this.sub = function (c) { 123 subs_1.push(c); 124 var old = c.componentWillUnmount; 125 c.componentWillUnmount = function () { 126 subs_1.splice(subs_1.indexOf(c), 1); 127 old && old.call(c); 128 }; 129 }; 130 } 131 return children; 132 }; 133 return ContextType; 134 } 135 function unmountComponentAtNode$1(node) { 136 N(null, node); 137 } 138 139 // no public types yet. when there are, export from: 140 // import {} from './api-type-deps' 141 var EventSourceApi = /** @class */ (function () { 142 function EventSourceApi(context, internalEventSource) { 143 this.context = context; 144 this.internalEventSource = internalEventSource; 145 } 146 EventSourceApi.prototype.remove = function () { 147 this.context.dispatch({
148 type: 'REMOVE_EVENT_SOURCE', 149 sourceId: this.internalEventSource.sourceId, 150 }); 151 }; 152 EventSourceApi.prototype.refetch = function () { 153 this.context.dispatch({ 154 type: 'FETCH_EVENT_SOURCES', 155 sourceIds: [this.internalEventSource.sourceId], 156 isRefetch: true, 157 }); 158 }; 159 Object.defineProperty(EventSourceApi.prototype, "id", { 160 get: function () { 161 return this.internalEventSource.publicId; 162 }, 163 enumerable: false, 164 configurable: true 165 }); 166 Object.defineProperty(EventSourceApi.prototype, "url", { 167 get: function () { 168 return this.internalEventSource.meta.url; 169 }, 170 enumerable: false, 171 configurable: true 172 }); 173 Object.defineProperty(EventSourceApi.prototype, "format", { 174 get: function () { 175 return this.internalEventSource.meta.format; // TODO: bad. not guaranteed 176 }, 177 enumerable: false, 178 configurable: true 179 }); 180 return EventSourceApi; 181 }()); 182 183 function removeElement(el) { 184 if (el.parentNode) { 185 el.parentNode.removeChild(el); 186 } 187 } 188 // Querying 189 // ---------------------------------------------------------------------------------------------------------------- 190 function elementClosest(el, selector) { 191 if (el.closest) { 192 return el.closest(selector); 193 // really bad fallback for IE 194 // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest 195 } 196 if (!document.documentElement.contains(el)) { 197 return null; 198 } 199 do { 200 if (elementMatches(el, selector)) { 201 return el; 202 } 203 el = (el.parentElement || el.parentNode); 204 } while (el !== null && el.nodeType === 1); 205 return null; 206 } 207 function elementMatches(el, selector) { 208 var method = el.matches || el.matchesSelector || el.msMatchesSelector; 209 return method.call(el, selector); 210 } 211 // accepts multiple subject els 212 // returns a real array. good for methods like forEach 213 // TODO: accept the document 214 function findElements(container, selector) { 215 var containers = container instanceof HTMLElement ? [container] : container; 216 var allMatches = []; 217 for (var i = 0; i < containers.length; i += 1) { 218 var matches = containers[i].querySelectorAll(selector); 219 for (var j = 0; j < matches.length; j += 1) { 220 allMatches.push(matches[j]); 221 } 222 } 223 return allMatches; 224 } 225 // accepts multiple subject els 226 // only queries direct child elements // TODO: rename to findDirectChildren! 227 function findDirectChildren(parent, selector) { 228 var parents = parent instanceof HTMLElement ? [parent] : parent; 229 var allMatches = []; 230 for (var i = 0; i < parents.length; i += 1) { 231 var childNodes = parents[i].children; // only ever elements 232 for (var j = 0; j < childNodes.length; j += 1) { 233 var childNode = childNodes[j]; 234 if (!selector || elementMatches(childNode, selector)) { 235 allMatches.push(childNode); 236 } 237 } 238 } 239 return allMatches; 240 } 241 // Style 242 // ---------------------------------------------------------------------------------------------------------------- 243 var PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 244 function applyStyle(el, props) { 245 for (var propName in props) { 246 applyStyleProp(el, propName, props[propName]); 247 } 248 } 249 function applyStyleProp(el, name, val) { 250 if (val == null) { 251 el.style[name] = ''; 252 } 253 else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) { 254 el.style[name] = val + "px"; 255 } 256 else { 257 el.style[name] = val; 258 } 259 } 260 // Event Handling 261 // ---------------------------------------------------------------------------------------------------------------- 262 // if intercepting bubbled events at the document/window/body level, 263 // and want to see originating element (the 'target'), use this util instead 264 // of `ev.target` because it goes within web-component boundaries. 265 function getEventTargetViaRoot(ev) { 266 var _a, _b; 267 return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target; 268 } 269 270 // Stops a mouse/touch event from doing it's native browser action 271 function preventDefault(ev) { 272 ev.preventDefault(); 273 } 274 // Event Delegation 275 // ---------------------------------------------------------------------------------------------------------------- 276 function buildDelegationHandler(selector, handler) { 277 return function (ev) {
vendor: 15,134 bytes, lines 278-709
278 var matchedChild = elementClosest(ev.target, selector); 279 if (matchedChild) { 280 handler.call(matchedChild, ev, matchedChild); 281 } 282 }; 283 } 284 function listenBySelector(container, eventType, selector, handler) { 285 var attachedHandler = buildDelegationHandler(selector, handler); 286 container.addEventListener(eventType, attachedHandler); 287 return function () { 288 container.removeEventListener(eventType, attachedHandler); 289 }; 290 } 291 function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) { 292 var currentMatchedChild; 293 return listenBySelector(container, 'mouseover', selector, function (mouseOverEv, matchedChild) { 294 if (matchedChild !== currentMatchedChild) { 295 currentMatchedChild = matchedChild; 296 onMouseEnter(mouseOverEv, matchedChild); 297 var realOnMouseLeave_1 = function (mouseLeaveEv) { 298 currentMatchedChild = null; 299 onMouseLeave(mouseLeaveEv, matchedChild); 300 matchedChild.removeEventListener('mouseleave', realOnMouseLeave_1); 301 }; 302 // listen to the next mouseleave, and then unattach 303 matchedChild.addEventListener('mouseleave', realOnMouseLeave_1); 304 } 305 }); 306 } 307 // Animation 308 // ---------------------------------------------------------------------------------------------------------------- 309 var transitionEventNames = [ 310 'webkitTransitionEnd', 311 'otransitionend', 312 'oTransitionEnd', 313 'msTransitionEnd', 314 'transitionend', 315 ]; 316 // triggered only when the next single subsequent transition finishes 317 function whenTransitionDone(el, callback) { 318 var realCallback = function (ev) { 319 callback(ev); 320 transitionEventNames.forEach(function (eventName) { 321 el.removeEventListener(eventName, realCallback); 322 }); 323 }; 324 transitionEventNames.forEach(function (eventName) { 325 el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes 326 }); 327 } 328 329 var guidNumber = 0; 330 function guid() { 331 guidNumber += 1; 332 return String(guidNumber); 333 } 334 /* FullCalendar-specific DOM Utilities 335 ----------------------------------------------------------------------------------------------------------------------*/ 336 // Make the mouse cursor express that an event is not allowed in the current area 337 function disableCursor() { 338 document.body.classList.add('fc-not-allowed'); 339 } 340 // Returns the mouse cursor to its original look 341 function enableCursor() { 342 document.body.classList.remove('fc-not-allowed'); 343 } 344 /* Selection 345 ----------------------------------------------------------------------------------------------------------------------*/ 346 function preventSelection(el) { 347 el.classList.add('fc-unselectable'); 348 el.addEventListener('selectstart', preventDefault); 349 } 350 function allowSelection(el) { 351 el.classList.remove('fc-unselectable'); 352 el.removeEventListener('selectstart', preventDefault); 353 } 354 /* Context Menu 355 ----------------------------------------------------------------------------------------------------------------------*/ 356 function preventContextMenu(el) { 357 el.addEventListener('contextmenu', preventDefault); 358 } 359 function allowContextMenu(el) { 360 el.removeEventListener('contextmenu', preventDefault); 361 } 362 function parseFieldSpecs(input) { 363 var specs = []; 364 var tokens = []; 365 var i; 366 var token; 367 if (typeof input === 'string') { 368 tokens = input.split(/\s*,\s*/); 369 } 370 else if (typeof input === 'function') { 371 tokens = [input]; 372 } 373 else if (Array.isArray(input)) { 374 tokens = input; 375 } 376 for (i = 0; i < tokens.length; i += 1) { 377 token = tokens[i]; 378 if (typeof token === 'string') { 379 specs.push(token.charAt(0) === '-' ? 380 { field: token.substring(1), order: -1 } : 381 { field: token, order: 1 }); 382 } 383 else if (typeof token === 'function') { 384 specs.push({ func: token }); 385 } 386 } 387 return specs; 388 } 389 function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 390 var i; 391 var cmp; 392 for (i = 0; i < fieldSpecs.length; i += 1) { 393 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]); 394 if (cmp) { 395 return cmp; 396 } 397 } 398 return 0; 399 } 400 function compareByFieldSpec(obj0, obj1, fieldSpec) { 401 if (fieldSpec.func) { 402 return fieldSpec.func(obj0, obj1); 403 } 404 return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) 405 * (fieldSpec.order || 1); 406 } 407 function flexibleCompare(a, b) { 408 if (!a && !b) { 409 return 0; 410 } 411 if (b == null) { 412 return -1; 413 } 414 if (a == null) { 415 return 1; 416 } 417 if (typeof a === 'string' || typeof b === 'string') { 418 return String(a).localeCompare(String(b)); 419 } 420 return a - b; 421 } 422 /* String Utilities 423 ----------------------------------------------------------------------------------------------------------------------*/ 424 function padStart(val, len) { 425 var s = String(val); 426 return '000'.substr(0, len - s.length) + s; 427 } 428 /* Number Utilities 429 ----------------------------------------------------------------------------------------------------------------------*/ 430 function compareNumbers(a, b) { 431 return a - b; 432 } 433 function isInt(n) { 434 return n % 1 === 0; 435 } 436 /* FC-specific DOM dimension stuff 437 ----------------------------------------------------------------------------------------------------------------------*/ 438 function computeSmallestCellWidth(cellEl) { 439 var allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame'); 440 var contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion'); 441 if (!allWidthEl) { 442 throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const 443 } 444 if (!contentWidthEl) { 445 throw new Error('needs fc-scrollgrid-shrink-cushion className'); 446 } 447 return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border 448 contentWidthEl.getBoundingClientRect().width; 449 } 450 451 var DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; 452 // Adding 453 function addWeeks(m, n) { 454 var a = dateToUtcArray(m); 455 a[2] += n * 7; 456 return arrayToUtcDate(a); 457 } 458 function addDays(m, n) { 459 var a = dateToUtcArray(m); 460 a[2] += n; 461 return arrayToUtcDate(a); 462 } 463 function addMs(m, n) { 464 var a = dateToUtcArray(m); 465 a[6] += n; 466 return arrayToUtcDate(a); 467 } 468 // Diffing (all return floats) 469 // TODO: why not use ranges? 470 function diffWeeks(m0, m1) { 471 return diffDays(m0, m1) / 7; 472 } 473 function diffDays(m0, m1) { 474 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24); 475 } 476 function diffHours(m0, m1) { 477 return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60); 478 } 479 function diffMinutes(m0, m1) { 480 return (m1.valueOf() - m0.valueOf()) / (1000 * 60); 481 } 482 function diffSeconds(m0, m1) { 483 return (m1.valueOf() - m0.valueOf()) / 1000; 484 } 485 function diffDayAndTime(m0, m1) { 486 var m0day = startOfDay(m0); 487 var m1day = startOfDay(m1); 488 return { 489 years: 0, 490 months: 0, 491 days: Math.round(diffDays(m0day, m1day)), 492 milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()), 493 }; 494 } 495 // Diffing Whole Units 496 function diffWholeWeeks(m0, m1) { 497 var d = diffWholeDays(m0, m1); 498 if (d !== null && d % 7 === 0) { 499 return d / 7; 500 } 501 return null; 502 } 503 function diffWholeDays(m0, m1) { 504 if (timeAsMs(m0) === timeAsMs(m1)) { 505 return Math.round(diffDays(m0, m1)); 506 } 507 return null; 508 } 509 // Start-Of 510 function startOfDay(m) { 511 return arrayToUtcDate([ 512 m.getUTCFullYear(), 513 m.getUTCMonth(), 514 m.getUTCDate(), 515 ]); 516 } 517 function startOfHour(m) { 518 return arrayToUtcDate([ 519 m.getUTCFullYear(), 520 m.getUTCMonth(), 521 m.getUTCDate(), 522 m.getUTCHours(), 523 ]); 524 } 525 function startOfMinute(m) { 526 return arrayToUtcDate([ 527 m.getUTCFullYear(), 528 m.getUTCMonth(), 529 m.getUTCDate(), 530 m.getUTCHours(), 531 m.getUTCMinutes(), 532 ]); 533 } 534 function startOfSecond(m) { 535 return arrayToUtcDate([ 536 m.getUTCFullYear(), 537 m.getUTCMonth(), 538 m.getUTCDate(), 539 m.getUTCHours(), 540 m.getUTCMinutes(), 541 m.getUTCSeconds(), 542 ]); 543 } 544 // Week Computation 545 function weekOfYear(marker, dow, doy) { 546 var y = marker.getUTCFullYear(); 547 var w = weekOfGivenYear(marker, y, dow, doy); 548 if (w < 1) { 549 return weekOfGivenYear(marker, y - 1, dow, doy); 550 } 551 var nextW = weekOfGivenYear(marker, y + 1, dow, doy); 552 if (nextW >= 1) { 553 return Math.min(w, nextW); 554 } 555 return w; 556 } 557 function weekOfGivenYear(marker, year, dow, doy) { 558 var firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]); 559 var dayStart = startOfDay(marker); 560 var days = Math.round(diffDays(firstWeekStart, dayStart)); 561 return Math.floor(days / 7) + 1; // zero-indexed 562 } 563 // start-of-first-week - start-of-year 564 function firstWeekOffset(year, dow, doy) { 565 // first-week day -- which january is always in the first week (4 for iso, 1 for other) 566 var fwd = 7 + dow - doy; 567 // first-week day local weekday -- which local weekday is fwd 568 var fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 569 return -fwdlw + fwd - 1; 570 } 571 // Array Conversion 572 function dateToLocalArray(date) { 573 return [ 574 date.getFullYear(), 575 date.getMonth(), 576 date.getDate(), 577 date.getHours(), 578 date.getMinutes(), 579 date.getSeconds(), 580 date.getMilliseconds(), 581 ]; 582 } 583 function arrayToLocalDate(a) { 584 return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month 585 a[3] || 0, a[4] || 0, a[5] || 0); 586 } 587 function dateToUtcArray(date) { 588 return [ 589 date.getUTCFullYear(), 590 date.getUTCMonth(), 591 date.getUTCDate(), 592 date.getUTCHours(), 593 date.getUTCMinutes(), 594 date.getUTCSeconds(), 595 date.getUTCMilliseconds(), 596 ]; 597 } 598 function arrayToUtcDate(a) { 599 // according to web standards (and Safari), a month index is required. 600 // massage if only given a year. 601 if (a.length === 1) { 602 a = a.concat([0]); 603 } 604 return new Date(Date.UTC.apply(Date, a)); 605 } 606 // Other Utils 607 function isValidDate(m) { 608 return !isNaN(m.valueOf()); 609 } 610 function timeAsMs(m) { 611 return m.getUTCHours() * 1000 * 60 * 60 + 612 m.getUTCMinutes() * 1000 * 60 + 613 m.getUTCSeconds() * 1000 + 614 m.getUTCMilliseconds(); 615 } 616 617 function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 618 return { 619 instanceId: guid(), 620 defId: defId, 621 range: range, 622 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 623 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo, 624 }; 625 } 626 627 var hasOwnProperty = Object.prototype.hasOwnProperty; 628 // Merges an array of objects into a single object. 629 // The second argument allows for an array of property names who's object values will be merged together. 630 function mergeProps(propObjs, complexPropsMap) { 631 var dest = {}; 632 if (complexPropsMap) { 633 for (var name_1 in complexPropsMap) { 634 var complexObjs = []; 635 // collect the trailing object values, stopping when a non-object is discovered 636 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 637 var val = propObjs[i][name_1]; 638 if (typeof val === 'object' && val) { // non-null object 639 complexObjs.unshift(val); 640 } 641 else if (val !== undefined) { 642 dest[name_1] = val; // if there were no objects, this value will be used 643 break; 644 } 645 } 646 // if the trailing values were objects, use the merged value 647 if (complexObjs.length) { 648 dest[name_1] = mergeProps(complexObjs); 649 } 650 } 651 } 652 // copy values into the destination, going from last to first 653 for (var i = propObjs.length - 1; i >= 0; i -= 1) { 654 var props = propObjs[i]; 655 for (var name_2 in props) { 656 if (!(name_2 in dest)) { // if already assigned by previous props or complex props, don't reassign 657 dest[name_2] = props[name_2]; 658 } 659 } 660 } 661 return dest; 662 } 663 function filterHash(hash, func) { 664 var filtered = {}; 665 for (var key in hash) { 666 if (func(hash[key], key)) { 667 filtered[key] = hash[key]; 668 } 669 } 670 return filtered; 671 } 672 function mapHash(hash, func) { 673 var newHash = {}; 674 for (var key in hash) { 675 newHash[key] = func(hash[key], key); 676 } 677 return newHash; 678 } 679 function arrayToHash(a) { 680 var hash = {}; 681 for (var _i = 0, a_1 = a; _i < a_1.length; _i++) { 682 var item = a_1[_i]; 683 hash[item] = true; 684 } 685 return hash; 686 } 687 function buildHashFromArray(a, func) { 688 var hash = {}; 689 for (var i = 0; i < a.length; i += 1) { 690 var tuple = func(a[i], i); 691 hash[tuple[0]] = tuple[1]; 692 } 693 return hash; 694 } 695 function hashValuesToArray(obj) { 696 var a = []; 697 for (var key in obj) { 698 a.push(obj[key]); 699 } 700 return a; 701 } 702 function isPropsEqual(obj0, obj1) { 703 if (obj0 === obj1) { 704 return true; 705 } 706 for (var key in obj0) { 707 if (hasOwnProperty.call(obj0, key)) { 708 if (!(key in obj1)) { 709 return false;
710 } 711 } 712 } 713 for (var key in obj1) { 714 if (hasOwnProperty.call(obj1, key)) { 715 if (obj0[key] !== obj1[key]) { 716 return false; 717 } 718 } 719 } 720 return true; 721 } 722 function getUnequalProps(obj0, obj1) { 723 var keys = []; 724 for (var key in obj0) { 725 if (hasOwnProperty.call(obj0, key)) { 726 if (!(key in obj1)) { 727 keys.push(key); 728 } 729 } 730 } 731 for (var key in obj1) { 732 if (hasOwnProperty.call(obj1, key)) { 733 if (obj0[key] !== obj1[key]) { 734 keys.push(key); 735 } 736 } 737 } 738 return keys; 739 } 740 function compareObjs(oldProps, newProps, equalityFuncs) { 741 if (equalityFuncs === void 0) { equalityFuncs = {}; } 742 if (oldProps === newProps) { 743 return true; 744 } 745 for (var key in newProps) { 746 if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ; 747 else { 748 return false; 749 } 750 } 751 // check for props that were omitted in the new 752 for (var key in oldProps) { 753 if (!(key in newProps)) { 754 return false; 755 } 756 } 757 return true; 758 } 759 /* 760 assumed "true" equality for handler names like "onReceiveSomething" 761 */ 762 function isObjValsEqual(val0, val1, comparator) { 763 if (val0 === val1 || comparator === true) { 764 return true; 765 } 766 if (comparator) { 767 return comparator(val0, val1); 768 } 769 return false; 770 } 771 function collectFromHash(hash, startIndex, endIndex, step) { 772 if (startIndex === void 0) { startIndex = 0; } 773 if (step === void 0) { step = 1; } 774 var res = []; 775 if (endIndex == null) { 776 endIndex = Object.keys(hash).length; 777 } 778 for (var i = startIndex; i < endIndex; i += step) { 779 var val = hash[i]; 780 if (val !== undefined) { // will disregard undefined for sparse arrays 781 res.push(val); 782 } 783 } 784 return res; 785 } 786 787 function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) { 788 for (var i = 0; i < recurringTypes.length; i += 1) { 789 var parsed = recurringTypes[i].parse(refined, dateEnv); 790 if (parsed) { 791 var allDay = refined.allDay; 792 if (allDay == null) { 793 allDay = defaultAllDay; 794 if (allDay == null) { 795 allDay = parsed.allDayGuess; 796 if (allDay == null) { 797 allDay = false; 798 } 799 } 800 } 801 return { 802 allDay: allDay, 803 duration: parsed.duration, 804 typeData: parsed.typeData, 805 typeId: i, 806 }; 807 } 808 } 809 return null; 810 } 811 function expandRecurring(eventStore, framingRange, context) { 812 var dateEnv = context.dateEnv, pluginHooks = context.pluginHooks, options = context.options; 813 var defs = eventStore.defs, instances = eventStore.instances; 814 // remove existing recurring instances 815 // TODO: bad. always expand events as a second step 816 instances = filterHash(instances, function (instance) { return !defs[instance.defId].recurringDef; }); 817 for (var defId in defs) { 818 var def = defs[defId]; 819 if (def.recurringDef) { 820 var duration = def.recurringDef.duration; 821 if (!duration) { 822 duration = def.allDay ? 823 options.defaultAllDayEventDuration : 824 options.defaultTimedEventDuration; 825 } 826 var starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes); 827 for (var _i = 0, starts_1 = starts; _i < starts_1.length; _i++) { 828 var start = starts_1[_i]; 829 var instance = createEventInstance(defId, { 830 start: start, 831 end: dateEnv.add(start, duration), 832 }); 833 instances[instance.instanceId] = instance; 834 } 835 } 836 } 837 return { defs: defs, instances: instances }; 838 } 839 /* 840 Event MUST have a recurringDef 841 */ 842 function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) { 843 var typeDef = recurringTypes[eventDef.recurringDef.typeId]; 844 var markers = typeDef.expand(eventDef.recurringDef.typeData, { 845 start: dateEnv.subtract(framingRange.start, duration), 846 end: framingRange.end, 847 }, dateEnv); 848 // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to 849 if (eventDef.allDay) { 850 markers = markers.map(startOfDay); 851 } 852 return markers; 853 } 854 855 var INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
vendor: 7,706 bytes, lines 856-1081
856 var PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 857 // Parsing and Creation 858 function createDuration(input, unit) { 859 var _a; 860 if (typeof input === 'string') { 861 return parseString(input); 862 } 863 if (typeof input === 'object' && input) { // non-null object 864 return parseObject(input); 865 } 866 if (typeof input === 'number') { 867 return parseObject((_a = {}, _a[unit || 'milliseconds'] = input, _a)); 868 } 869 return null; 870 } 871 function parseString(s) { 872 var m = PARSE_RE.exec(s); 873 if (m) { 874 var sign = m[1] ? -1 : 1; 875 return { 876 years: 0, 877 months: 0, 878 days: sign * (m[2] ? parseInt(m[2], 10) : 0), 879 milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours 880 (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes 881 (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds 882 (m[6] ? parseInt(m[6], 10) : 0) // ms 883 ), 884 }; 885 } 886 return null; 887 } 888 function parseObject(obj) { 889 var duration = { 890 years: obj.years || obj.year || 0, 891 months: obj.months || obj.month || 0, 892 days: obj.days || obj.day || 0, 893 milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours 894 (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes 895 (obj.seconds || obj.second || 0) * 1000 + // seconds 896 (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms 897 }; 898 var weeks = obj.weeks || obj.week; 899 if (weeks) { 900 duration.days += weeks * 7; 901 duration.specifiedWeeks = true; 902 } 903 return duration; 904 } 905 // Equality 906 function durationsEqual(d0, d1) { 907 return d0.years === d1.years && 908 d0.months === d1.months && 909 d0.days === d1.days && 910 d0.milliseconds === d1.milliseconds; 911 } 912 function asCleanDays(dur) { 913 if (!dur.years && !dur.months && !dur.milliseconds) { 914 return dur.days; 915 } 916 return 0; 917 } 918 // Simple Math 919 function addDurations(d0, d1) { 920 return { 921 years: d0.years + d1.years, 922 months: d0.months + d1.months, 923 days: d0.days + d1.days, 924 milliseconds: d0.milliseconds + d1.milliseconds, 925 }; 926 } 927 function subtractDurations(d1, d0) { 928 return { 929 years: d1.years - d0.years, 930 months: d1.months - d0.months, 931 days: d1.days - d0.days, 932 milliseconds: d1.milliseconds - d0.milliseconds, 933 }; 934 } 935 function multiplyDuration(d, n) { 936 return { 937 years: d.years * n, 938 months: d.months * n, 939 days: d.days * n, 940 milliseconds: d.milliseconds * n, 941 }; 942 } 943 // Conversions 944 // "Rough" because they are based on average-case Gregorian months/years 945 function asRoughYears(dur) { 946 return asRoughDays(dur) / 365; 947 } 948 function asRoughMonths(dur) { 949 return asRoughDays(dur) / 30; 950 } 951 function asRoughDays(dur) { 952 return asRoughMs(dur) / 864e5; 953 } 954 function asRoughMinutes(dur) { 955 return asRoughMs(dur) / (1000 * 60); 956 } 957 function asRoughSeconds(dur) { 958 return asRoughMs(dur) / 1000; 959 } 960 function asRoughMs(dur) { 961 return dur.years * (365 * 864e5) + 962 dur.months * (30 * 864e5) + 963 dur.days * 864e5 + 964 dur.milliseconds; 965 } 966 // Advanced Math 967 function wholeDivideDurations(numerator, denominator) { 968 var res = null; 969 for (var i = 0; i < INTERNAL_UNITS.length; i += 1) { 970 var unit = INTERNAL_UNITS[i]; 971 if (denominator[unit]) { 972 var localRes = numerator[unit] / denominator[unit]; 973 if (!isInt(localRes) || (res !== null && res !== localRes)) { 974 return null; 975 } 976 res = localRes; 977 } 978 else if (numerator[unit]) { 979 // needs to divide by something but can't! 980 return null; 981 } 982 } 983 return res; 984 } 985 function greatestDurationDenominator(dur) { 986 var ms = dur.milliseconds; 987 if (ms) { 988 if (ms % 1000 !== 0) { 989 return { unit: 'millisecond', value: ms }; 990 } 991 if (ms % (1000 * 60) !== 0) { 992 return { unit: 'second', value: ms / 1000 }; 993 } 994 if (ms % (1000 * 60 * 60) !== 0) { 995 return { unit: 'minute', value: ms / (1000 * 60) }; 996 } 997 if (ms) { 998 return { unit: 'hour', value: ms / (1000 * 60 * 60) }; 999 } 1000 } 1001 if (dur.days) { 1002 if (dur.specifiedWeeks && dur.days % 7 === 0) { 1003 return { unit: 'week', value: dur.days / 7 }; 1004 } 1005 return { unit: 'day', value: dur.days }; 1006 } 1007 if (dur.months) { 1008 return { unit: 'month', value: dur.months }; 1009 } 1010 if (dur.years) { 1011 return { unit: 'year', value: dur.years }; 1012 } 1013 return { unit: 'millisecond', value: 0 }; 1014 } 1015 1016 // timeZoneOffset is in minutes 1017 function buildIsoString(marker, timeZoneOffset, stripZeroTime) { 1018 if (stripZeroTime === void 0) { stripZeroTime = false; } 1019 var s = marker.toISOString(); 1020 s = s.replace('.000', ''); 1021 if (stripZeroTime) { 1022 s = s.replace('T00:00:00Z', ''); 1023 } 1024 if (s.length > 10) { // time part wasn't stripped, can add timezone info 1025 if (timeZoneOffset == null) { 1026 s = s.replace('Z', ''); 1027 } 1028 else if (timeZoneOffset !== 0) { 1029 s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true)); 1030 } 1031 // otherwise, its UTC-0 and we want to keep the Z 1032 } 1033 return s; 1034 } 1035 // formats the date, but with no time part 1036 // TODO: somehow merge with buildIsoString and stripZeroTime 1037 // TODO: rename. omit "string" 1038 function formatDayString(marker) { 1039 return marker.toISOString().replace(/T.*$/, ''); 1040 } 1041 // TODO: use Date::toISOString and use everything after the T? 1042 function formatIsoTimeString(marker) { 1043 return padStart(marker.getUTCHours(), 2) + ':' + 1044 padStart(marker.getUTCMinutes(), 2) + ':' + 1045 padStart(marker.getUTCSeconds(), 2); 1046 } 1047 function formatTimeZoneOffset(minutes, doIso) { 1048 if (doIso === void 0) { doIso = false; } 1049 var sign = minutes < 0 ? '-' : '+'; 1050 var abs = Math.abs(minutes); 1051 var hours = Math.floor(abs / 60); 1052 var mins = Math.round(abs % 60); 1053 if (doIso) { 1054 return sign + padStart(hours, 2) + ":" + padStart(mins, 2); 1055 } 1056 return "GMT" + sign + hours + (mins ? ":" + padStart(mins, 2) : ''); 1057 } 1058 1059 // TODO: new util arrayify? 1060 function removeExact(array, exactVal) { 1061 var removeCnt = 0; 1062 var i = 0; 1063 while (i < array.length) { 1064 if (array[i] === exactVal) { 1065 array.splice(i, 1); 1066 removeCnt += 1; 1067 } 1068 else { 1069 i += 1; 1070 } 1071 } 1072 return removeCnt; 1073 } 1074 function isArraysEqual(a0, a1, equalityFunc) { 1075 if (a0 === a1) { 1076 return true; 1077 } 1078 var len = a0.length; 1079 var i; 1080 if (len !== a1.length) { // not array? or not same length? 1081 return false;
1082 } 1083 for (i = 0; i < len; i += 1) { 1084 if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) { 1085 return false; 1086 } 1087 } 1088 return true; 1089 } 1090 1091 function memoize(workerFunc, resEquality, teardownFunc) { 1092 var currentArgs; 1093 var currentRes; 1094 return function () { 1095 var newArgs = []; 1096 for (var _i = 0; _i < arguments.length; _i++) { 1097 newArgs[_i] = arguments[_i]; 1098 } 1099 if (!currentArgs) { 1100 currentRes = workerFunc.apply(this, newArgs); 1101 } 1102 else if (!isArraysEqual(currentArgs, newArgs)) { 1103 if (teardownFunc) { 1104 teardownFunc(currentRes); 1105 } 1106 var res = workerFunc.apply(this, newArgs); 1107 if (!resEquality || !resEquality(res, currentRes)) { 1108 currentRes = res; 1109 } 1110 } 1111 currentArgs = newArgs; 1112 return currentRes; 1113 }; 1114 } 1115 function memoizeObjArg(workerFunc, resEquality, teardownFunc) { 1116 var _this = this; 1117 var currentArg; 1118 var currentRes; 1119 return function (newArg) { 1120 if (!currentArg) { 1121 currentRes = workerFunc.call(_this, newArg); 1122 } 1123 else if (!isPropsEqual(currentArg, newArg)) { 1124 if (teardownFunc) { 1125 teardownFunc(currentRes); 1126 } 1127 var res = workerFunc.call(_this, newArg); 1128 if (!resEquality || !resEquality(res, currentRes)) { 1129 currentRes = res; 1130 } 1131 } 1132 currentArg = newArg; 1133 return currentRes; 1134 }; 1135 } 1136 function memoizeArraylike(// used at all? 1137 workerFunc, resEquality, teardownFunc) { 1138 var _this = this; 1139 var currentArgSets = []; 1140 var currentResults = []; 1141 return function (newArgSets) { 1142 var currentLen = currentArgSets.length; 1143 var newLen = newArgSets.length; 1144 var i = 0; 1145 for (; i < currentLen; i += 1) { 1146 if (!newArgSets[i]) { // one of the old sets no longer exists 1147 if (teardownFunc) { 1148 teardownFunc(currentResults[i]); 1149 } 1150 } 1151 else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) { 1152 if (teardownFunc) { 1153 teardownFunc(currentResults[i]); 1154 } 1155 var res = workerFunc.apply(_this, newArgSets[i]); 1156 if (!resEquality || !resEquality(res, currentResults[i])) { 1157 currentResults[i] = res; 1158 } 1159 } 1160 } 1161 for (; i < newLen; i += 1) { 1162 currentResults[i] = workerFunc.apply(_this, newArgSets[i]); 1163 } 1164 currentArgSets = newArgSets; 1165 currentResults.splice(newLen); // remove excess 1166 return currentResults; 1167 }; 1168 } 1169 function memoizeHashlike(// used? 1170 workerFunc, resEquality, teardownFunc) { 1171 var _this = this; 1172 var currentArgHash = {}; 1173 var currentResHash = {}; 1174 return function (newArgHash) { 1175 var newResHash = {}; 1176 for (var key in newArgHash) { 1177 if (!currentResHash[key]) { 1178 newResHash[key] = workerFunc.apply(_this, newArgHash[key]); 1179 } 1180 else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) { 1181 if (teardownFunc) { 1182 teardownFunc(currentResHash[key]); 1183 } 1184 var res = workerFunc.apply(_this, newArgHash[key]); 1185 newResHash[key] = (resEquality && resEquality(res, currentResHash[key])) 1186 ? currentResHash[key] 1187 : res; 1188 } 1189 else { 1190 newResHash[key] = currentResHash[key]; 1191 } 1192 } 1193 currentArgHash = newArgHash; 1194 currentResHash = newResHash; 1195 return newResHash; 1196 }; 1197 } 1198 1199 var EXTENDED_SETTINGS_AND_SEVERITIES = { 1200 week: 3, 1201 separator: 0, 1202 omitZeroMinute: 0, 1203 meridiem: 0, 1204 omitCommas: 0, 1205 }; 1206 var STANDARD_DATE_PROP_SEVERITIES = { 1207 timeZoneName: 7, 1208 era: 6, 1209 year: 5, 1210 month: 4, 1211 day: 2, 1212 weekday: 2, 1213 hour: 1, 1214 minute: 1, 1215 second: 1, 1216 }; 1217 var MERIDIEM_RE = /\s*([ap])\.?m\.?/i;
1217 // eats up leading spaces too 1218 var COMMA_RE = /,/g; // we need re for globalness 1219 var MULTI_SPACE_RE = /\s+/g; 1220 var LTR_RE = /\u200e/g; // control character 1221 var UTC_RE = /UTC|GMT/; 1222 var NativeFormatter = /** @class */ (function () { 1223 function NativeFormatter(formatSettings) { 1224 var standardDateProps = {}; 1225 var extendedSettings = {}; 1226 var severity = 0; 1227 for (var name_1 in formatSettings) { 1228 if (name_1 in EXTENDED_SETTINGS_AND_SEVERITIES) { 1229 extendedSettings[name_1] = formatSettings[name_1]; 1230 severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name_1], severity); 1231 } 1232 else { 1233 standardDateProps[name_1] = formatSettings[name_1]; 1234 if (name_1 in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity 1235 severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name_1], severity); 1236 } 1237 } 1238 } 1239 this.standardDateProps = standardDateProps; 1240 this.extendedSettings = extendedSettings; 1241 this.severity = severity; 1242 this.buildFormattingFunc = memoize(buildFormattingFunc); 1243 } 1244 NativeFormatter.prototype.format = function (date, context) { 1245 return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date); 1246 }; 1247 NativeFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1248 var _a = this, standardDateProps = _a.standardDateProps, extendedSettings = _a.extendedSettings; 1249 var diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem); 1250 if (!diffSeverity) { 1251 return this.format(start, context); 1252 } 1253 var biggestUnitForPartial = diffSeverity; 1254 if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1255 (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') && 1256 (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') && 1257 (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) { 1258 biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time 1259 } 1260 var full0 = this.format(start, context); 1261 var full1 = this.format(end, context); 1262 if (full0 === full1) { 1263 return full0; 1264 } 1265 var partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial); 1266 var partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context); 1267 var partial0 = partialFormattingFunc(start); 1268 var partial1 = partialFormattingFunc(end); 1269 var insertion = findCommonInsertion(full0, partial0, full1, partial1); 1270 var separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || ''; 1271 if (insertion) { 1272 return insertion.before + partial0 + separator + partial1 + insertion.after; 1273 } 1274 return full0 + separator + full1; 1275 }; 1276 NativeFormatter.prototype.getLargestUnit = function () { 1277 switch (this.severity) { 1278 case 7: 1279 case 6: 1280 case 5: 1281 return 'year'; 1282 case 4: 1283 return 'month'; 1284 case 3: 1285 return 'week'; 1286 case 2: 1287 return 'day'; 1288 default: 1289 return 'time'; // really? 1290 } 1291 }; 1292 return NativeFormatter; 1293 }()); 1294 function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1295 var standardDatePropCnt = Object.keys(standardDateProps).length; 1296 if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') { 1297 return function (date) { return (formatTimeZoneOffset(date.timeZoneOffset)); }; 1298 } 1299 if (standardDatePropCnt === 0 && extendedSettings.week) { 1300 return function (date) { return (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.locale, extendedSettings.week)); }; 1301 } 1302 return buildNativeFormattingFunc(standardDateProps, extendedSettings, context); 1303 } 1304 function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) { 1305 standardDateProps = __assign({}, standardDateProps); // copy 1306 extendedSettings = __assign({}, extendedSettings); // copy 1307 sanitizeSettings(standardDateProps, extendedSettings); 1308 standardDateProps.timeZone = 'UTC';
1308 // we leverage the only guaranteed timeZone for our UTC markers 1309 var normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps); 1310 var zeroFormat; // needed? 1311 if (extendedSettings.omitZeroMinute) { 1312 var zeroProps = __assign({}, standardDateProps); 1313 delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings 1314 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 1315 } 1316 return function (date) { 1317 var marker = date.marker; 1318 var format; 1319 if (zeroFormat && !marker.getUTCMinutes()) { 1320 format = zeroFormat; 1321 } 1322 else { 1323 format = normalFormat; 1324 } 1325 var s = format.format(marker); 1326 return postProcess(s, date, standardDateProps, extendedSettings, context); 1327 }; 1328 } 1329 function sanitizeSettings(standardDateProps, extendedSettings) { 1330 // deal with a browser inconsistency where formatting the timezone 1331 // requires that the hour/minute be present. 1332 if (standardDateProps.timeZoneName) { 1333 if (!standardDateProps.hour) { 1334 standardDateProps.hour = '2-digit'; 1335 } 1336 if (!standardDateProps.minute) { 1337 standardDateProps.minute = '2-digit'; 1338 } 1339 } 1340 // only support short timezone names 1341 if (standardDateProps.timeZoneName === 'long') { 1342 standardDateProps.timeZoneName = 'short'; 1343 } 1344 // if requesting to display seconds, MUST display minutes 1345 if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) { 1346 delete extendedSettings.omitZeroMinute; 1347 } 1348 } 1349 function postProcess(s, date, standardDateProps, extendedSettings, context) { 1350 s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes 1351 if (standardDateProps.timeZoneName === 'short') { 1352 s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ? 1353 'UTC' : // important to normalize for IE, which does "GMT" 1354 formatTimeZoneOffset(date.timeZoneOffset)); 1355 } 1356 if (extendedSettings.omitCommas) { 1357 s = s.replace(COMMA_RE, '').trim(); 1358 } 1359 if (extendedSettings.omitZeroMinute) { 1360 s = s.replace(':00', ''); // zeroFormat doesn't always achieve this 1361 } 1362 // ^ do anything that might create adjacent spaces before this point, 1363 // because MERIDIEM_RE likes to eat up loading spaces 1364 if (extendedSettings.meridiem === false) { 1365 s = s.replace(MERIDIEM_RE, '').trim(); 1366 } 1367 else if (extendedSettings.meridiem === 'narrow') { // a/p 1368 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase(); }); 1369 } 1370 else if (extendedSettings.meridiem === 'short') { // am/pm 1371 s = s.replace(MERIDIEM_RE, function (m0, m1) { return m1.toLocaleLowerCase() + "m"; }); 1372 } 1373 else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase 1374 s = s.replace(MERIDIEM_RE, function (m0) { return m0.toLocaleLowerCase(); }); 1375 } 1376 s = s.replace(MULTI_SPACE_RE, ' '); 1377 s = s.trim(); 1378 return s; 1379 } 1380 function injectTzoStr(s, tzoStr) { 1381 var replaced = false; 1382 s = s.replace(UTC_RE, function () { 1383 replaced = true; 1384 return tzoStr; 1385 }); 1386 // IE11 doesn't include UTC/GMT in the original string, so append to end 1387 if (!replaced) { 1388 s += " " + tzoStr; 1389 } 1390 return s; 1391 } 1392 function formatWeekNumber(num, weekText, locale, display) { 1393 var parts = []; 1394 if (display === 'narrow') { 1395 parts.push(weekText); 1396 } 1397 else if (display === 'short') { 1398 parts.push(weekText, ' '); 1399 } 1400 // otherwise, considered 'numeric' 1401 parts.push(locale.simpleNumberFormat.format(num)); 1402 if (locale.options.direction === 'rtl') { // TODO: use control characters instead? 1403 parts.reverse(); 1404 } 1405 return parts.join(''); 1406 } 1407 // Range Formatting Utils 1408 // 0 = exactly the same 1409 // 1 = different by time 1410 // and bigger 1411 function computeMarkerDiffSeverity(d0, d1, ca) { 1412 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 1413 return 5; 1414 } 1415 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 1416 return 4; 1417 } 1418 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 1419 return 2; 1420 } 1421 if (timeAsMs(d0) !== timeAsMs(d1)) { 1422 return 1; 1423 } 1424 return 0; 1425 } 1426 function computePartialFormattingOptions(options, biggestUnit) { 1427 var partialOptions = {}; 1428 for (var name_2 in options) { 1429 if (!(name_2 in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 1430 STANDARD_DATE_PROP_SEVERITIES[name_2] <= biggestUnit) { 1431 partialOptions[name_2] = options[name_2]; 1432 } 1433 } 1434 return partialOptions; 1435 } 1436 function findCommonInsertion(full0, partial0, full1, partial1) { 1437 var i0 = 0; 1438 while (i0 < full0.length) { 1439 var found0 = full0.indexOf(partial0, i0); 1440 if (found0 === -1) { 1441 break; 1442 } 1443 var before0 = full0.substr(0, found0); 1444 i0 = found0 + partial0.length; 1445 var after0 = full0.substr(i0); 1446 var i1 = 0; 1447 while (i1 < full1.length) { 1448 var found1 = full1.indexOf(partial1, i1);
1449 if (found1 === -1) { 1450 break; 1451 } 1452 var before1 = full1.substr(0, found1); 1453 i1 = found1 + partial1.length; 1454 var after1 = full1.substr(i1); 1455 if (before0 === before1 && after0 === after1) { 1456 return { 1457 before: before0, 1458 after: after0, 1459 }; 1460 } 1461 } 1462 } 1463 return null; 1464 } 1465 1466 function expandZonedMarker(dateInfo, calendarSystem) { 1467 var a = calendarSystem.markerToArray(dateInfo.marker); 1468 return { 1469 marker: dateInfo.marker, 1470 timeZoneOffset: dateInfo.timeZoneOffset, 1471 array: a, 1472 year: a[0], 1473 month: a[1], 1474 day: a[2], 1475 hour: a[3], 1476 minute: a[4], 1477 second: a[5], 1478 millisecond: a[6], 1479 }; 1480 } 1481 1482 function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) { 1483 var startInfo = expandZonedMarker(start, context.calendarSystem); 1484 var endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 1485 return { 1486 date: startInfo, 1487 start: startInfo, 1488 end: endInfo, 1489 timeZone: context.timeZone, 1490 localeCodes: context.locale.codes, 1491 defaultSeparator: betterDefaultSeparator || context.defaultSeparator, 1492 }; 1493 } 1494 1495 /* 1496 TODO: fix the terminology of "formatter" vs "formatting func" 1497 */ 1498 /* 1499 At the time of instantiation, this object does not know which cmd-formatting system it will use. 1500 It receives this at the time of formatting, as a setting. 1501 */ 1502 var CmdFormatter = /** @class */ (function () { 1503 function CmdFormatter(cmdStr) { 1504 this.cmdStr = cmdStr; 1505 } 1506 CmdFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1507 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1508 }; 1509 CmdFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1510 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1511 }; 1512 return CmdFormatter; 1513 }()); 1514 1515 var FuncFormatter = /** @class */ (function () { 1516 function FuncFormatter(func) { 1517 this.func = func; 1518 } 1519 FuncFormatter.prototype.format = function (date, context, betterDefaultSeparator) { 1520 return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1521 }; 1522 FuncFormatter.prototype.formatRange = function (start, end, context, betterDefaultSeparator) { 1523 return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1524 }; 1525 return FuncFormatter; 1526 }()); 1527 1528 function createFormatter(input) { 1529 if (typeof input === 'object' && input) { // non-null object 1530 return new NativeFormatter(input); 1531 } 1532 if (typeof input === 'string') { 1533 return new CmdFormatter(input); 1534 } 1535 if (typeof input === 'function') { 1536 return new FuncFormatter(input); 1537 } 1538 return null; 1539 } 1540 1541 // base options 1542 // ------------ 1543 var BASE_OPTION_REFINERS = { 1544 navLinkDayClick: identity, 1545 navLinkWeekClick: identity, 1546 duration: createDuration, 1547 bootstrapFontAwesome: identity, 1548 buttonIcons: identity, 1549 customButtons: identity, 1550 defaultAllDayEventDuration: createDuration, 1551 defaultTimedEventDuration: createDuration, 1552 nextDayThreshold: createDuration, 1553 scrollTime: createDuration, 1554 scrollTimeReset: Boolean, 1555 slotMinTime: createDuration, 1556 slotMaxTime: createDuration, 1557 dayPopoverFormat: createFormatter, 1558 slotDuration: createDuration, 1559 snapDuration: createDuration, 1560 headerToolbar: identity, 1561 footerToolbar: identity, 1562 defaultRangeSeparator: String, 1563 titleRangeSeparator: String, 1564 forceEventDuration: Boolean, 1565 dayHeaders: Boolean, 1566 dayHeaderFormat: createFormatter, 1567 dayHeaderClassNames: identity, 1568 dayHeaderContent: identity, 1569 dayHeaderDidMount: identity, 1570 dayHeaderWillUnmount: identity, 1571 dayCellClassNames: identity, 1572 dayCellContent: identity, 1573 dayCellDidMount: identity, 1574 dayCellWillUnmount: identity, 1575 initialView: String, 1576 aspectRatio: Number, 1577 weekends: Boolean, 1578 weekNumberCalculation: identity, 1579 weekNumbers: Boolean, 1580 weekNumberClassNames: identity, 1581 weekNumberContent: identity, 1582 weekNumberDidMount: identity, 1583 weekNumberWillUnmount: identity, 1584 editable: Boolean, 1585 viewClassNames: identity, 1586 viewDidMount: identity, 1587 viewWillUnmount: identity, 1588 nowIndicator: Boolean, 1589 nowIndicatorClassNames: identity, 1590 nowIndicatorContent: identity, 1591 nowIndicatorDidMount: identity, 1592 nowIndicatorWillUnmount: identity, 1593 showNonCurrentDates: Boolean, 1594 lazyFetching: Boolean, 1595 startParam: String, 1596 endParam: String, 1597 timeZoneParam: String, 1598 timeZone: String, 1599 locales: identity, 1600 locale: identity, 1601 themeSystem: String, 1602 dragRevertDuration: Number, 1603 dragScroll: Boolean, 1604 allDayMaintainDuration: Boolean, 1605 unselectAuto: Boolean, 1606 dropAccept: identity, 1607 eventOrder: parseFieldSpecs, 1608 eventOrderStrict: Boolean, 1609 handleWindowResize: Boolean, 1610 windowResizeDelay: Number, 1611 longPressDelay: Number, 1612 eventDragMinDistance: Number, 1613 expandRows: Boolean, 1614 height: identity, 1615 contentHeight: identity, 1616 direction: String, 1617 weekNumberFormat: createFormatter, 1618 eventResizableFromStart: Boolean, 1619 displayEventTime: Boolean, 1620 displayEventEnd: Boolean, 1621 weekText: String, 1622 progressiveEventRendering: Boolean, 1623 businessHours: identity, 1624 initialDate: identity, 1625 now: identity, 1626 eventDataTransform: identity, 1627 stickyHeaderDates: identity, 1628 stickyFooterScrollbar: identity, 1629 viewHeight: identity, 1630 defaultAllDay: Boolean, 1631 eventSourceFailure: identity, 1632 eventSourceSuccess: identity, 1633 eventDisplay: String, 1634 eventStartEditable: Boolean, 1635 eventDurationEditable: Boolean, 1636 eventOverlap: identity, 1637 eventConstraint: identity, 1638 eventAllow: identity,
1639 eventBackgroundColor: String, 1640 eventBorderColor: String, 1641 eventTextColor: String, 1642 eventColor: String, 1643 eventClassNames: identity, 1644 eventContent: identity, 1645 eventDidMount: identity, 1646 eventWillUnmount: identity, 1647 selectConstraint: identity, 1648 selectOverlap: identity, 1649 selectAllow: identity, 1650 droppable: Boolean, 1651 unselectCancel: String, 1652 slotLabelFormat: identity, 1653 slotLaneClassNames: identity, 1654 slotLaneContent: identity, 1655 slotLaneDidMount: identity, 1656 slotLaneWillUnmount: identity, 1657 slotLabelClassNames: identity, 1658 slotLabelContent: identity, 1659 slotLabelDidMount: identity, 1660 slotLabelWillUnmount: identity, 1661 dayMaxEvents: identity, 1662 dayMaxEventRows: identity, 1663 dayMinWidth: Number, 1664 slotLabelInterval: createDuration, 1665 allDayText: String, 1666 allDayClassNames: identity, 1667 allDayContent: identity, 1668 allDayDidMount: identity, 1669 allDayWillUnmount: identity, 1670 slotMinWidth: Number, 1671 navLinks: Boolean, 1672 eventTimeFormat: createFormatter, 1673 rerenderDelay: Number, 1674 moreLinkText: identity, 1675 selectMinDistance: Number, 1676 selectable: Boolean, 1677 selectLongPressDelay: Number, 1678 eventLongPressDelay: Number, 1679 selectMirror: Boolean, 1680 eventMaxStack: Number, 1681 eventMinHeight: Number, 1682 eventMinWidth: Number, 1683 eventShortHeight: Number, 1684 slotEventOverlap: Boolean, 1685 plugins: identity, 1686 firstDay: Number, 1687 dayCount: Number, 1688 dateAlignment: String, 1689 dateIncrement: createDuration, 1690 hiddenDays: identity, 1691 monthMode: Boolean, 1692 fixedWeekCount: Boolean, 1693 validRange: identity, 1694 visibleRange: identity, 1695 titleFormat: identity, 1696 // only used by list-view, but languages define the value, so we need it in base options 1697 noEventsText: String, 1698 moreLinkClick: identity, 1699 moreLinkClassNames: identity, 1700 moreLinkContent: identity, 1701 moreLinkDidMount: identity, 1702 moreLinkWillUnmount: identity, 1703 }; 1704 // do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results. 1705 // raw values. 1706 var BASE_OPTION_DEFAULTS = { 1707 eventDisplay: 'auto', 1708 defaultRangeSeparator: ' - ', 1709 titleRangeSeparator: ' \u2013 ', 1710 defaultTimedEventDuration: '01:00:00', 1711 defaultAllDayEventDuration: { day: 1 }, 1712 forceEventDuration: false, 1713 nextDayThreshold: '00:00:00', 1714 dayHeaders: true, 1715 initialView: '', 1716 aspectRatio: 1.35, 1717 headerToolbar: { 1718 start: 'title', 1719 center: '', 1720 end: 'today prev,next', 1721 }, 1722 weekends: true, 1723 weekNumbers: false, 1724 weekNumberCalculation: 'local', 1725 editable: false, 1726 nowIndicator: false, 1727 scrollTime: '06:00:00', 1728 scrollTimeReset: true, 1729 slotMinTime: '00:00:00', 1730 slotMaxTime: '24:00:00', 1731 showNonCurrentDates: true, 1732 lazyFetching: true, 1733 startParam: 'start', 1734 endParam: 'end', 1735 timeZoneParam: 'timeZone', 1736 timeZone: 'local', 1737 locales: [], 1738 locale: '', 1739 themeSystem: 'standard', 1740 dragRevertDuration: 500, 1741 dragScroll: true, 1742 allDayMaintainDuration: false, 1743 unselectAuto: true, 1744 dropAccept: '*', 1745 eventOrder: 'start,-duration,allDay,title', 1746 dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 1747 handleWindowResize: true, 1748 windowResizeDelay: 100, 1749 longPressDelay: 1000, 1750 eventDragMinDistance: 5, 1751 expandRows: false, 1752 navLinks: false, 1753 selectable: false, 1754 eventMinHeight: 15, 1755 eventMinWidth: 30, 1756 eventShortHeight: 30, 1757 }; 1758 // calendar listeners 1759 // ------------------ 1760 var CALENDAR_LISTENER_REFINERS = { 1761 datesSet: identity, 1762 eventsSet: identity, 1763 eventAdd: identity, 1764 eventChange: identity, 1765 eventRemove: identity, 1766 windowResize: identity, 1767 eventClick: identity, 1768 eventMouseEnter: identity, 1769 eventMouseLeave: identity, 1770 select: identity, 1771 unselect: identity, 1772 loading: identity, 1773 // internal 1774 _unmount: identity, 1775 _beforeprint: identity, 1776 _afterprint: identity, 1777 _noEventDrop: identity, 1778 _noEventResize: identity, 1779 _resize: identity, 1780 _scrollRequest: identity, 1781 }; 1782 // calendar-specific options 1783 // ------------------------- 1784 var CALENDAR_OPTION_REFINERS = { 1785 buttonText: identity, 1786 views: identity, 1787 plugins: identity, 1788 initialEvents: identity,
1789 events: identity, 1790 eventSources: identity, 1791 }; 1792 var COMPLEX_OPTION_COMPARATORS = { 1793 headerToolbar: isBoolComplexEqual, 1794 footerToolbar: isBoolComplexEqual, 1795 buttonText: isBoolComplexEqual, 1796 buttonIcons: isBoolComplexEqual, 1797 }; 1798 function isBoolComplexEqual(a, b) { 1799 if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects 1800 return isPropsEqual(a, b); 1801 } 1802 return a === b; 1803 } 1804 // view-specific options 1805 // --------------------- 1806 var VIEW_OPTION_REFINERS = { 1807 type: String, 1808 component: identity, 1809 buttonText: String, 1810 buttonTextKey: String, 1811 dateProfileGeneratorClass: identity, 1812 usesMinMaxTime: Boolean, 1813 classNames: identity, 1814 content: identity, 1815 didMount: identity, 1816 willUnmount: identity, 1817 }; 1818 // util funcs 1819 // ---------------------------------------------------------------------------------------------------- 1820 function mergeRawOptions(optionSets) { 1821 return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS); 1822 } 1823 function refineProps(input, refiners) { 1824 var refined = {}; 1825 var extra = {}; 1826 for (var propName in refiners) { 1827 if (propName in input) { 1828 refined[propName] = refiners[propName](input[propName]); 1829 } 1830 } 1831 for (var propName in input) { 1832 if (!(propName in refiners)) { 1833 extra[propName] = input[propName]; 1834 } 1835 } 1836 return { refined: refined, extra: extra }; 1837 } 1838 function identity(raw) { 1839 return raw; 1840 } 1841 1842 function parseEvents(rawEvents, eventSource, context, allowOpenRange) { 1843 var eventStore = createEmptyEventStore(); 1844 var eventRefiners = buildEventRefiners(context); 1845 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 1846 var rawEvent = rawEvents_1[_i]; 1847 var tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners); 1848 if (tuple) { 1849 eventTupleToStore(tuple, eventStore); 1850 } 1851 } 1852 return eventStore; 1853 } 1854 function eventTupleToStore(tuple, eventStore) { 1855 if (eventStore === void 0) { eventStore = createEmptyEventStore(); } 1856 eventStore.defs[tuple.def.defId] = tuple.def; 1857 if (tuple.instance) { 1858 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 1859 } 1860 return eventStore; 1861 } 1862 // retrieves events that have the same groupId as the instance specified by `instanceId` 1863 // or they are the same as the instance. 1864 // why might instanceId not be in the store? an event from another calendar? 1865 function getRelevantEvents(eventStore, instanceId) { 1866 var instance = eventStore.instances[instanceId]; 1867 if (instance) { 1868 var def_1 = eventStore.defs[instance.defId]; 1869 // get events/instances with same group 1870 var newStore = filterEventStoreDefs(eventStore, function (lookDef) { return isEventDefsGrouped(def_1, lookDef); }); 1871 // add the original 1872 // TODO: wish we could use eventTupleToStore or something like it 1873 newStore.defs[def_1.defId] = def_1; 1874 newStore.instances[instance.instanceId] = instance; 1875 return newStore; 1876 } 1877 return createEmptyEventStore(); 1878 } 1879 function isEventDefsGrouped(def0, def1) { 1880 return Boolean(def0.groupId && def0.groupId === def1.groupId); 1881 } 1882 function createEmptyEventStore() { 1883 return { defs: {}, instances: {} }; 1884 } 1885 function mergeEventStores(store0, store1) { 1886 return { 1887 defs: __assign(__assign({}, store0.defs), store1.defs), 1888 instances: __assign(__assign({}, store0.instances), store1.instances), 1889 }; 1890 } 1891 function filterEventStoreDefs(eventStore, filterFunc) { 1892 var defs = filterHash(eventStore.defs, filterFunc); 1893 var instances = filterHash(eventStore.instances, function (instance) { return (defs[instance.defId] // still exists? 1894 ); }); 1895 return { defs: defs, instances: instances }; 1896 } 1897 function excludeSubEventStore(master, sub) { 1898 var defs = master.defs, instances = master.instances; 1899 var filteredDefs = {}; 1900 var filteredInstances = {}; 1901 for (var defId in defs) { 1902 if (!sub.defs[defId]) { // not explicitly excluded
vendor: 4,622 bytes, lines 1903-2021
1903 filteredDefs[defId] = defs[defId]; 1904 } 1905 } 1906 for (var instanceId in instances) { 1907 if (!sub.instances[instanceId] && // not explicitly excluded 1908 filteredDefs[instances[instanceId].defId] // def wasn't filtered away 1909 ) { 1910 filteredInstances[instanceId] = instances[instanceId]; 1911 } 1912 } 1913 return { 1914 defs: filteredDefs, 1915 instances: filteredInstances, 1916 }; 1917 } 1918 1919 function normalizeConstraint(input, context) { 1920 if (Array.isArray(input)) { 1921 return parseEvents(input, null, context, true); // allowOpenRange=true 1922 } 1923 if (typeof input === 'object' && input) { // non-null object 1924 return parseEvents([input], null, context, true); // allowOpenRange=true 1925 } 1926 if (input != null) { 1927 return String(input); 1928 } 1929 return null; 1930 } 1931 1932 function parseClassNames(raw) { 1933 if (Array.isArray(raw)) { 1934 return raw; 1935 } 1936 if (typeof raw === 'string') { 1937 return raw.split(/\s+/); 1938 } 1939 return []; 1940 } 1941 1942 // TODO: better called "EventSettings" or "EventConfig" 1943 // TODO: move this file into structs 1944 // TODO: separate constraint/overlap/allow, because selection uses only that, not other props 1945 var EVENT_UI_REFINERS = { 1946 display: String, 1947 editable: Boolean, 1948 startEditable: Boolean, 1949 durationEditable: Boolean, 1950 constraint: identity, 1951 overlap: identity, 1952 allow: identity, 1953 className: parseClassNames, 1954 classNames: parseClassNames, 1955 color: String, 1956 backgroundColor: String, 1957 borderColor: String, 1958 textColor: String, 1959 }; 1960 var EMPTY_EVENT_UI = { 1961 display: null, 1962 startEditable: null, 1963 durationEditable: null, 1964 constraints: [], 1965 overlap: null, 1966 allows: [], 1967 backgroundColor: '', 1968 borderColor: '', 1969 textColor: '', 1970 classNames: [], 1971 }; 1972 function createEventUi(refined, context) { 1973 var constraint = normalizeConstraint(refined.constraint, context); 1974 return { 1975 display: refined.display || null, 1976 startEditable: refined.startEditable != null ? refined.startEditable : refined.editable, 1977 durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable, 1978 constraints: constraint != null ? [constraint] : [], 1979 overlap: refined.overlap != null ? refined.overlap : null, 1980 allows: refined.allow != null ? [refined.allow] : [], 1981 backgroundColor: refined.backgroundColor || refined.color || '', 1982 borderColor: refined.borderColor || refined.color || '', 1983 textColor: refined.textColor || '', 1984 classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural 1985 }; 1986 } 1987 // TODO: prevent against problems with <2 args! 1988 function combineEventUis(uis) { 1989 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 1990 } 1991 function combineTwoEventUis(item0, item1) { 1992 return { 1993 display: item1.display != null ? item1.display : item0.display, 1994 startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable, 1995 durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable, 1996 constraints: item0.constraints.concat(item1.constraints), 1997 overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap, 1998 allows: item0.allows.concat(item1.allows), 1999 backgroundColor: item1.backgroundColor || item0.backgroundColor, 2000 borderColor: item1.borderColor || item0.borderColor, 2001 textColor: item1.textColor || item0.textColor, 2002 classNames: item0.classNames.concat(item1.classNames), 2003 }; 2004 } 2005 2006 var EVENT_NON_DATE_REFINERS = { 2007 id: String, 2008 groupId: String, 2009 title: String, 2010 url: String, 2011 }; 2012 var EVENT_DATE_REFINERS = { 2013 start: identity, 2014 end: identity, 2015 date: identity, 2016 allDay: Boolean, 2017 }; 2018 var EVENT_REFINERS = __assign(__assign(__assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity }); 2019 function parseEvent(raw, eventSource, context, allowOpenRange, refiners) { 2020 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2021 var _a = refineEventDef(raw, context, refiners), refined
2021= _a.refined, extra = _a.extra; 2022 var defaultAllDay = computeIsDefaultAllDay(eventSource, context); 2023 var recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes); 2024 if (recurringRes) { 2025 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context); 2026 def.recurringDef = { 2027 typeId: recurringRes.typeId, 2028 typeData: recurringRes.typeData, 2029 duration: recurringRes.duration, 2030 }; 2031 return { def: def, instance: null }; 2032 } 2033 var singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange); 2034 if (singleRes) { 2035 var def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context); 2036 var instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo); 2037 return { def: def, instance: instance }; 2038 } 2039 return null; 2040 } 2041 function refineEventDef(raw, context, refiners) { 2042 if (refiners === void 0) { refiners = buildEventRefiners(context); } 2043 return refineProps(raw, refiners); 2044 } 2045 function buildEventRefiners(context) { 2046 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners); 2047 } 2048 /* 2049 Will NOT populate extendedProps with the leftover properties. 2050 Will NOT populate date-related props. 2051 */ 2052 function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) { 2053 var def = { 2054 title: refined.title || '', 2055 groupId: refined.groupId || '', 2056 publicId: refined.id || '', 2057 url: refined.url || '', 2058 recurringDef: null, 2059 defId: guid(), 2060 sourceId: sourceId, 2061 allDay: allDay, 2062 hasEnd: hasEnd, 2063 ui: createEventUi(refined, context), 2064 extendedProps: __assign(__assign({}, (refined.extendedProps || {})), extra), 2065 }; 2066 for (var _i = 0, _a = context.pluginHooks.eventDefMemberAdders; _i < _a.length; _i++) { 2067 var memberAdder = _a[_i]; 2068 __assign(def, memberAdder(refined)); 2069 } 2070 // help out EventApi from having user modify props 2071 Object.freeze(def.ui.classNames); 2072 Object.freeze(def.extendedProps); 2073 return def; 2074 } 2075 function parseSingle(refined, defaultAllDay, context, allowOpenRange) { 2076 var allDay = refined.allDay; 2077 var startMeta; 2078 var startMarker = null; 2079 var hasEnd = false; 2080 var endMeta; 2081 var endMarker = null; 2082 var startInput = refined.start != null ? refined.start : refined.date; 2083 startMeta = context.dateEnv.createMarkerMeta(startInput); 2084 if (startMeta) { 2085 startMarker = startMeta.marker; 2086 } 2087 else if (!allowOpenRange) { 2088 return null; 2089 } 2090 if (refined.end != null) { 2091 endMeta = context.dateEnv.createMarkerMeta(refined.end); 2092 } 2093 if (allDay == null) { 2094 if (defaultAllDay != null) { 2095 allDay = defaultAllDay; 2096 } 2097 else { 2098 // fall back to the date props LAST 2099 allDay = (!startMeta || startMeta.isTimeUnspecified) && 2100 (!endMeta || endMeta.isTimeUnspecified); 2101 } 2102 } 2103 if (allDay && startMarker) { 2104 startMarker = startOfDay(startMarker); 2105 } 2106 if (endMeta) { 2107 endMarker = endMeta.marker; 2108 if (allDay) { 2109 endMarker = startOfDay(endMarker); 2110 } 2111 if (startMarker && endMarker <= startMarker) { 2112 endMarker = null; 2113 } 2114 } 2115 if (endMarker) { 2116 hasEnd = true; 2117 } 2118 else if (!allowOpenRange) { 2119 hasEnd = context.options.forceEventDuration || false; 2120 endMarker = context.dateEnv.add(startMarker, allDay ? 2121 context.options.defaultAllDayEventDuration : 2122 context.options.defaultTimedEventDuration); 2123 } 2124 return { 2125 allDay: allDay, 2126 hasEnd: hasEnd, 2127 range: { start: startMarker, end: endMarker }, 2128 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 2129 forcedEndTzo: endMeta ? endMeta.forcedTzo : null, 2130 }; 2131 } 2132 function computeIsDefaultAllDay(eventSource, context) { 2133 var res = null; 2134 if (eventSource) { 2135 res = eventSource.defaultAllDay; 2136 } 2137 if (res == null) { 2138 res = context.options.defaultAllDay; 2139 } 2140 return res; 2141 } 2142 2143 /* Date stuff that doesn't belong in datelib core 2144 ----------------------------------------------------------------------------------------------------------------------*/ 2145 // given a timed range, computes an all-day range that has the same exact duration, 2146 // but whose start time is aligned with the start of the day. 2147 function computeAlignedDayRange(timedRange) { 2148 var dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 2149 var start = startOfDay(timedRange.start); 2150 var end = addDays(start, dayCnt); 2151 return { start: start, end: end }; 2152 } 2153 // given a timed range, computes an all-day range based on how for the end date bleeds into the next day 2154 // TODO: give nextDayThreshold a default arg 2155 function computeVisibleDayRange(timedRange, nextDayThreshold) { 2156 if (nextDayThreshold === void 0) { nextDayThreshold = createDuration(0); } 2157 var startDay = null; 2158 var endDay = null; 2159 if (timedRange.end) { 2160 endDay = startOfDay(timedRange.end); 2161 var endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay` 2162 // If the end time is actually inclusively part of the next day and is equal to or
vendor: 16,001 bytes, lines 2163-2544
2163 // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`. 2164 // Otherwise, leaving it as inclusive will cause it to exclude `endDay`. 2165 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 2166 endDay = addDays(endDay, 1); 2167 } 2168 } 2169 if (timedRange.start) { 2170 startDay = startOfDay(timedRange.start); // the beginning of the day the range starts 2171 // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day. 2172 if (endDay && endDay <= startDay) { 2173 endDay = addDays(startDay, 1); 2174 } 2175 } 2176 return { start: startDay, end: endDay }; 2177 } 2178 // spans from one day into another? 2179 function isMultiDayRange(range) { 2180 var visibleRange = computeVisibleDayRange(range); 2181 return diffDays(visibleRange.start, visibleRange.end) > 1; 2182 } 2183 function diffDates(date0, date1, dateEnv, largeUnit) { 2184 if (largeUnit === 'year') { 2185 return createDuration(dateEnv.diffWholeYears(date0, date1), 'year'); 2186 } 2187 if (largeUnit === 'month') { 2188 return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month'); 2189 } 2190 return diffDayAndTime(date0, date1); // returns a duration 2191 } 2192 2193 function parseRange(input, dateEnv) { 2194 var start = null; 2195 var end = null; 2196 if (input.start) { 2197 start = dateEnv.createMarker(input.start); 2198 } 2199 if (input.end) { 2200 end = dateEnv.createMarker(input.end); 2201 } 2202 if (!start && !end) { 2203 return null; 2204 } 2205 if (start && end && end < start) { 2206 return null; 2207 } 2208 return { start: start, end: end }; 2209 } 2210 // SIDE-EFFECT: will mutate ranges. 2211 // Will return a new array result. 2212 function invertRanges(ranges, constraintRange) { 2213 var invertedRanges = []; 2214 var start = constraintRange.start; // the end of the previous range. the start of the new range 2215 var i; 2216 var dateRange; 2217 // ranges need to be in order. required for our date-walking algorithm 2218 ranges.sort(compareRanges); 2219 for (i = 0; i < ranges.length; i += 1) { 2220 dateRange = ranges[i]; 2221 // add the span of time before the event (if there is any) 2222 if (dateRange.start > start) { // compare millisecond time (skip any ambig logic) 2223 invertedRanges.push({ start: start, end: dateRange.start }); 2224 } 2225 if (dateRange.end > start) { 2226 start = dateRange.end; 2227 } 2228 } 2229 // add the span of time after the last event (if there is any) 2230 if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic) 2231 invertedRanges.push({ start: start, end: constraintRange.end }); 2232 } 2233 return invertedRanges; 2234 } 2235 function compareRanges(range0, range1) { 2236 return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first 2237 } 2238 function intersectRanges(range0, range1) { 2239 var start = range0.start, end = range0.end; 2240 var newRange = null; 2241 if (range1.start !== null) { 2242 if (start === null) { 2243 start = range1.start; 2244 } 2245 else { 2246 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 2247 } 2248 } 2249 if (range1.end != null) { 2250 if (end === null) { 2251 end = range1.end; 2252 } 2253 else { 2254 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 2255 } 2256 } 2257 if (start === null || end === null || start < end) { 2258 newRange = { start: start, end: end }; 2259 } 2260 return newRange; 2261 } 2262 function rangesEqual(range0, range1) { 2263 return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && 2264 (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf()); 2265 } 2266 function rangesIntersect(range0, range1) { 2267 return (range0.end === null || range1.start === null || range0.end > range1.start) && 2268 (range0.start === null || range1.end === null || range0.start < range1.end); 2269 } 2270 function rangeContainsRange(outerRange, innerRange) { 2271 return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) && 2272 (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end)); 2273 } 2274 function rangeContainsMarker(range, date) { 2275 return (range.start === null || date >= range.start) && 2276 (range.end === null || date < range.end); 2277 } 2278 // If the given date is not within the given range, move it inside. 2279 // (If it's past the end, make it one millisecond before the end). 2280 function constrainMarkerToRange(date, range) { 2281 if (range.start != null && date < range.start) { 2282 return range.start; 2283 } 2284 if (range.end != null && date >= range.end) { 2285 return new Date(range.end.valueOf() - 1); 2286 } 2287 return date; 2288 } 2289 2290 /* 2291 Specifying nextDayThreshold signals that all-day ranges should be sliced. 2292 */ 2293 function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) { 2294 var inverseBgByGroupId = {}; 2295 var inverseBgByDefId = {}; 2296 var defByGroupId = {}; 2297 var bgRanges = []; 2298 var fgRanges = []; 2299 var eventUis = compileEventUis(eventStore.defs, eventUiBases); 2300 for (var defId in eventStore.defs) { 2301 var def = eventStore.defs[defId]; 2302 var ui = eventUis[def.defId]; 2303 if (ui.display === 'inverse-background') { 2304 if (def.groupId) { 2305 inverseBgByGroupId[def.groupId] = []; 2306 if (!defByGroupId[def.groupId]) { 2307 defByGroupId[def.groupId] = def; 2308 } 2309 } 2310 else { 2311 inverseBgByDefId[defId] = []; 2312 } 2313 } 2314 } 2315 for (var instanceId in eventStore.instances) { 2316 var instance = eventStore.instances[instanceId]; 2317 var def = eventStore.defs[instance.defId]; 2318 var ui = eventUis[def.defId]; 2319 var origRange = instance.range; 2320 var normalRange = (!def.allDay && nextDayThreshold) ? 2321 computeVisibleDayRange(origRange, nextDayThreshold) : 2322 origRange; 2323 var slicedRange = intersectRanges(normalRange, framingRange); 2324 if (slicedRange) { 2325 if (ui.display === 'inverse-background') { 2326 if (def.groupId) { 2327 inverseBgByGroupId[def.groupId].push(slicedRange); 2328 } 2329 else { 2330 inverseBgByDefId[instance.defId].push(slicedRange); 2331 } 2332 } 2333 else if (ui.display !== 'none') { 2334 (ui.display === 'background' ? bgRanges : fgRanges).push({ 2335 def: def, 2336 ui: ui, 2337 instance: instance, 2338 range: slicedRange, 2339 isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(), 2340 isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(), 2341 }); 2342 } 2343 } 2344 } 2345 for (var groupId in inverseBgByGroupId) { // BY GROUP 2346 var ranges = inverseBgByGroupId[groupId]; 2347 var invertedRanges = invertRanges(ranges, framingRange); 2348 for (var _i = 0, invertedRanges_1 = invertedRanges; _i < invertedRanges_1.length; _i++) { 2349 var invertedRange = invertedRanges_1[_i]; 2350 var def = defByGroupId[groupId]; 2351 var ui = eventUis[def.defId]; 2352 bgRanges.push({ 2353 def: def, 2354 ui: ui, 2355 instance: null, 2356 range: invertedRange, 2357 isStart: false, 2358 isEnd: false, 2359 }); 2360 } 2361 } 2362 for (var defId in inverseBgByDefId) { 2363 var ranges = inverseBgByDefId[defId]; 2364 var invertedRanges = invertRanges(ranges, framingRange); 2365 for (var _a = 0, invertedRanges_2 = invertedRanges; _a < invertedRanges_2.length; _a++) { 2366 var invertedRange = invertedRanges_2[_a]; 2367 bgRanges.push({ 2368 def: eventStore.defs[defId], 2369 ui: eventUis[defId], 2370 instance: null, 2371 range: invertedRange, 2372 isStart: false, 2373 isEnd: false, 2374 }); 2375 } 2376 } 2377 return { bg: bgRanges, fg: fgRanges }; 2378 } 2379 function hasBgRendering(def) { 2380 return def.ui.display === 'background' || def.ui.display === 'inverse-background'; 2381 } 2382 function setElSeg(el, seg) { 2383 el.fcSeg = seg; 2384 } 2385 function getElSeg(el) { 2386 return el.fcSeg || 2387 el.parentNode.fcSeg || // for the harness 2388 null; 2389 } 2390 // event ui computation 2391 function compileEventUis(eventDefs, eventUiBases) { 2392 return mapHash(eventDefs, function (eventDef) { return compileEventUi(eventDef, eventUiBases); }); 2393 } 2394 function compileEventUi(eventDef, eventUiBases) { 2395 var uis = []; 2396 if (eventUiBases['']) { 2397 uis.push(eventUiBases['']); 2398 } 2399 if (eventUiBases[eventDef.defId]) { 2400 uis.push(eventUiBases[eventDef.defId]); 2401 } 2402 uis.push(eventDef.ui); 2403 return combineEventUis(uis); 2404 } 2405 function sortEventSegs(segs, eventOrderSpecs) { 2406 var objs = segs.map(buildSegCompareObj); 2407 objs.sort(function (obj0, obj1) { return compareByFieldSpecs(obj0, obj1, eventOrderSpecs); }); 2408 return objs.map(function (c) { return c._seg; }); 2409 } 2410 // returns a object with all primitive props that can be compared 2411 function buildSegCompareObj(seg) { 2412 var eventRange = seg.eventRange; 2413 var eventDef = eventRange.def; 2414 var range = eventRange.instance ? eventRange.instance.range : eventRange.range; 2415 var start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events 2416 var end = range.end ? range.end.valueOf() : 0; // " 2417 return __assign(__assign(__assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start: start, 2418 end: end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg }); 2419 } 2420 function computeSegDraggable(seg, context) { 2421 var pluginHooks = context.pluginHooks; 2422 var transformers = pluginHooks.isDraggableTransformers; 2423 var _a = seg.eventRange, def = _a.def, ui = _a.ui; 2424 var val = ui.startEditable; 2425 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 2426 var transformer = transformers_1[_i]; 2427 val = transformer(val, def, ui, context); 2428 } 2429 return val; 2430 } 2431 function computeSegStartResizable(seg, context) { 2432 return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart; 2433 } 2434 function computeSegEndResizable(seg, context) { 2435 return seg.isEnd && seg.eventRange.ui.durationEditable; 2436 } 2437 function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true 2438 defaultDisplayEventEnd, // defaults to true 2439 startOverride, endOverride) { 2440 var dateEnv = context.dateEnv, options = context.options; 2441 var displayEventTime = options.displayEventTime, displayEventEnd = options.displayEventEnd; 2442 var eventDef = seg.eventRange.def; 2443 var eventInstance = seg.eventRange.instance; 2444 if (displayEventTime == null) { 2445 displayEventTime = defaultDisplayEventTime !== false; 2446 } 2447 if (displayEventEnd == null) { 2448 displayEventEnd = defaultDisplayEventEnd !== false; 2449 } 2450 var wholeEventStart = eventInstance.range.start; 2451 var wholeEventEnd = eventInstance.range.end; 2452 var segStart = startOverride || seg.start || seg.eventRange.range.start; 2453 var segEnd = endOverride || seg.end || seg.eventRange.range.end; 2454 var isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf(); 2455 var isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf(); 2456 if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) { 2457 segStart = isStartDay ? wholeEventStart : segStart; 2458 segEnd = isEndDay ? wholeEventEnd : segEnd; 2459 if (displayEventEnd && eventDef.hasEnd) { 2460 return dateEnv.formatRange(segStart, segEnd, timeFormat, { 2461 forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo, 2462 forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo, 2463 }); 2464 } 2465 return dateEnv.format(segStart, timeFormat, { 2466 forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same 2467 }); 2468 } 2469 return ''; 2470 } 2471 function getSegMeta(seg, todayRange, nowDate) { 2472 var segRange = seg.eventRange.range; 2473 return { 2474 isPast: segRange.end < (nowDate || todayRange.start), 2475 isFuture: segRange.start >= (nowDate || todayRange.end), 2476 isToday: todayRange && rangeContainsMarker(todayRange, segRange.start), 2477 }; 2478 } 2479 function getEventClassNames(props) { 2480 var classNames = ['fc-event']; 2481 if (props.isMirror) { 2482 classNames.push('fc-event-mirror'); 2483 } 2484 if (props.isDraggable) { 2485 classNames.push('fc-event-draggable'); 2486 } 2487 if (props.isStartResizable || props.isEndResizable) { 2488 classNames.push('fc-event-resizable'); 2489 } 2490 if (props.isDragging) { 2491 classNames.push('fc-event-dragging'); 2492 } 2493 if (props.isResizing) { 2494 classNames.push('fc-event-resizing'); 2495 } 2496 if (props.isSelected) { 2497 classNames.push('fc-event-selected'); 2498 } 2499 if (props.isStart) { 2500 classNames.push('fc-event-start'); 2501 } 2502 if (props.isEnd) { 2503 classNames.push('fc-event-end'); 2504 } 2505 if (props.isPast) { 2506 classNames.push('fc-event-past'); 2507 } 2508 if (props.isToday) { 2509 classNames.push('fc-event-today'); 2510 } 2511 if (props.isFuture) { 2512 classNames.push('fc-event-future'); 2513 } 2514 return classNames; 2515 } 2516 function buildEventRangeKey(eventRange) { 2517 return eventRange.instance 2518 ? eventRange.instance.instanceId 2519 : eventRange.def.defId + ":" + eventRange.range.start.toISOString(); 2520 // inverse-background events don't have specific instances. TODO: better solution 2521 } 2522 2523 var STANDARD_PROPS = { 2524 start: identity, 2525 end: identity, 2526 allDay: Boolean, 2527 }; 2528 function parseDateSpan(raw, dateEnv, defaultDuration) { 2529 var span = parseOpenDateSpan(raw, dateEnv); 2530 var range = span.range; 2531 if (!range.start) { 2532 return null; 2533 } 2534 if (!range.end) { 2535 if (defaultDuration == null) { 2536 return null; 2537 } 2538 range.end = dateEnv.add(range.start, defaultDuration); 2539 } 2540 return span; 2541 } 2542 /* 2543 TODO: somehow combine with parseRange? 2544 Will return null if the start/end props were present but parsed invali
2544dly. 2545 */ 2546 function parseOpenDateSpan(raw, dateEnv) { 2547 var _a = refineProps(raw, STANDARD_PROPS), standardProps = _a.refined, extra = _a.extra; 2548 var startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null; 2549 var endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null; 2550 var allDay = standardProps.allDay; 2551 if (allDay == null) { 2552 allDay = (startMeta && startMeta.isTimeUnspecified) && 2553 (!endMeta || endMeta.isTimeUnspecified); 2554 } 2555 return __assign({ range: { 2556 start: startMeta ? startMeta.marker : null, 2557 end: endMeta ? endMeta.marker : null, 2558 }, allDay: allDay }, extra); 2559 } 2560 function isDateSpansEqual(span0, span1) { 2561 return rangesEqual(span0.range, span1.range) && 2562 span0.allDay === span1.allDay && 2563 isSpanPropsEqual(span0, span1); 2564 } 2565 // the NON-DATE-RELATED props 2566 function isSpanPropsEqual(span0, span1) { 2567 for (var propName in span1) { 2568 if (propName !== 'range' && propName !== 'allDay') { 2569 if (span0[propName] !== span1[propName]) { 2570 return false; 2571 } 2572 } 2573 } 2574 // are there any props that span0 has that span1 DOESN'T have? 2575 // both have range/allDay, so no need to special-case. 2576 for (var propName in span0) { 2577 if (!(propName in span1)) { 2578 return false; 2579 } 2580 } 2581 return true; 2582 } 2583 function buildDateSpanApi(span, dateEnv) { 2584 return __assign(__assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay }); 2585 } 2586 function buildRangeApiWithTimeZone(range, dateEnv, omitTime) { 2587 return __assign(__assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone }); 2588 } 2589 function buildRangeApi(range, dateEnv, omitTime) { 2590 return { 2591 start: dateEnv.toDate(range.start), 2592 end: dateEnv.toDate(range.end), 2593 startStr: dateEnv.formatIso(range.start, { omitTime: omitTime }), 2594 endStr: dateEnv.formatIso(range.end, { omitTime: omitTime }), 2595 }; 2596 } 2597 function fabricateEventRange(dateSpan, eventUiBases, context) { 2598 var res = refineEventDef({ editable: false }, context); 2599 var def = parseEventDef(res.refined, res.extra, '', // sourceId 2600 dateSpan.allDay, true, // hasEnd 2601 context); 2602 return { 2603 def: def, 2604 ui: compileEventUi(def, eventUiBases), 2605 instance: createEventInstance(def.defId, dateSpan.range), 2606 range: dateSpan.range, 2607 isStart: true, 2608 isEnd: true, 2609 }; 2610 } 2611 2612 function triggerDateSelect(selection, pev, context) { 2613 context.emitter.trigger('select', __assign(__assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view })); 2614 } 2615 function triggerDateUnselect(pev, context) { 2616 context.emitter.trigger('unselect', { 2617 jsEvent: pev ? pev.origEvent : null, 2618 view: context.viewApi || context.calendarApi.view, 2619 }); 2620 } 2621 function buildDateSpanApiWithContext(dateSpan, context) { 2622 var props = {}; 2623 for (var _i = 0, _a = context.pluginHooks.dateSpanTransforms; _i < _a.length; _i++) { 2624 var transform = _a[_i]; 2625 __assign(props, transform(dateSpan, context)); 2626 } 2627 __assign(props, buildDateSpanApi(dateSpan, context.dateEnv)); 2628 return props; 2629 } 2630 // Given an event's allDay status and start date, return what its fallback end date should be. 2631 // TODO: rename to computeDefaultEventEnd 2632 function getDefaultEventEnd(allDay, marker, context) { 2633 var dateEnv = context.dateEnv, options = context.options; 2634 var end = marker; 2635 if (allDay) { 2636 end = startOfDay(end); 2637 end = dateEnv.add(end, options.defaultAllDayEventDuration); 2638 } 2639 else { 2640 end = dateEnv.add(end, options.defaultTimedEventDuration); 2641 } 2642 return end; 2643 } 2644 2645 // applies the mutation to ALL defs/instances within the event store 2646 function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) { 2647 var eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 2648 var dest = createEmptyEventStore(); 2649 for (var defId in eventStore.defs) { 2650 var def = eventStore.defs[defId]; 2651 dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context); 2652 } 2653 for (var instanceId in eventStore.instances) { 2654 var instance = eventStore.instances[instanceId]; 2655 var def = dest.defs[instance.defId]; // important to grab the newly modified def 2656 dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context); 2657 } 2658 return dest; 2659 } 2660 function applyMutationToEventDef(eventDef, eventConfig, mutation, context) { 2661 var standardProps = mutation.standardProps || {}; 2662 // if hasEnd has not been specified, guess a good value based on deltas. 2663 // if duration will change, there's no way the default duration will persist, 2664 // and thus, we need to mark the event as having a real end 2665 if (standardProps.hasEnd == null && 2666 eventConfig.durationEditable && 2667 (mutation.startDelta || mutation.endDelta)) { 2668 standardProps.hasEnd = true; // TODO: is this mutation okay? 2669 } 2670 var copy = __assign(__assign(__assign({}, eventDef), standardProps), { ui: __assign(__assign({}, eventDef.ui), standardProps.ui) }); 2671 if (mutation.extendedProps) { 2672 copy.extendedProps = __assign(__assign({}, copy.extendedProps), mutation.extendedProps); 2673 } 2674 for (var _i = 0, _a = context.pluginHooks.eventDefMutationAppliers; _i < _a.length; _i++) { 2675 var applier = _a[_i]; 2676 applier(copy, mutation, context); 2677 } 2678 if (!copy.hasEnd && context.options.forceEventDuration) { 2679 copy.hasEnd = true; 2680 } 2681 return copy; 2682 } 2683 function applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef 2684 eventConfig, mutation, context) { 2685 var dateEnv = context.dateEnv; 2686 var forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true; 2687 var clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false; 2688 var copy = __assign({}, eventInstance); 2689 if (forceAllDay) { 2690 copy.range = computeAlignedDayRange(copy.range); 2691 } 2692 if (mutation.datesDelta && eventConfig.startEditable) { 2693 copy.range = { 2694 start: dateEnv.add(copy.range.start, mutation.datesDelta), 2695 end: dateEnv.add(copy.range.end, mutation.datesDelta), 2696 }; 2697 } 2698 if (mutation.startDelta && eventConfig.durationEditable) { 2699 copy.range = { 2700 start: dateEnv.add(copy.range.start, mutation.startDelta), 2701 end: copy.range.end, 2702 }; 2703 } 2704 if (mutation.endDelta && eventConfig.durationEditable) { 2705 copy.range = { 2706 start: copy.range.start, 2707 end: dateEnv.add(copy.range.end, mutation.endDelta), 2708 }; 2709 } 2710 if (clearEnd) { 2711 copy.range = { 2712 start: copy.range.start, 2713 end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context), 2714 }; 2715 } 2716 // in case event was all-day but the supplied deltas were not 2717 // better util for this? 2718 if (eventDef.allDay) { 2719 copy.range = { 2720 start: startOfDay(copy.range.start), 2721 end: startOfDay(copy.range.end), 2722 }; 2723 } 2724 // handle invalid durations 2725 if (copy.range.end < copy.range.start) { 2726 copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context); 2727 } 2728 return copy; 2729 } 2730 2731 // no public types yet. when there are, export from: 2732 // import {} from './api-type-deps' 2733 var ViewApi = /** @class */ (function () { 2734 function ViewApi(type, getCurrentData, dateEnv) { 2735 this.type = type; 2736 this.getCurrentData = getCurrentData; 2737 this.dateEnv = dateEnv; 2738 } 2739 Object.defineProperty(ViewApi.prototype, "calendar", { 2740 get: function () { 2741 return this.getCurrentData().calendarApi; 2742 }, 2743 enumerable: false, 2744 configurable: true 2745 }); 2746 Object.defineProperty(ViewApi.prototype, "title", { 2747 get: function () { 2748 return this.getCurrentData().viewTitle; 2749 }, 2750 enumerable: false, 2751 configurable: true 2752 }); 2753 Object.defineProperty(ViewApi.prototype, "activeStart", { 2754 get: function () { 2755 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start); 2756 }, 2757 enumerable: false, 2758 configurable: true 2759 }); 2760 Object.defineProperty(ViewApi.prototype, "activeEnd", { 2761 get: function () { 2762 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end); 2763 }, 2764 enumerable: false, 2765 configurable: true 2766 }); 2767 Object.defineProperty(ViewApi.prototype, "currentStart", { 2768 get: function () { 2769 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start); 2770 }, 2771 enumerable: false, 2772 configurable: true 2773 }); 2774 Object.defineProperty(ViewApi.prototype, "currentEnd", { 2775 get: function () { 2776 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end); 2777 }, 2778 enumerable: false, 2779 configurable: true 2780 }); 2781 ViewApi.prototype.getOption = function (name) { 2782 return this.getCurrentData().options[name]; // are the view-specific options 2783 }; 2784 return ViewApi; 2785 }()); 2786 2787 var EVENT_SOURCE_REFINERS$1 = { 2788 id: String, 2789 defaultAllDay: Boolean, 2790 url: String, 2791 format: String,
2792 events: identity, 2793 eventDataTransform: identity, 2794 // for any network-related sources 2795 success: identity, 2796 failure: identity, 2797 }; 2798 function parseEventSource(raw, context, refiners) { 2799 if (refiners === void 0) { refiners = buildEventSourceRefiners(context); } 2800 var rawObj; 2801 if (typeof raw === 'string') { 2802 rawObj = { url: raw }; 2803 } 2804 else if (typeof raw === 'function' || Array.isArray(raw)) { 2805 rawObj = { events: raw }; 2806 } 2807 else if (typeof raw === 'object' && raw) { // not null 2808 rawObj = raw; 2809 } 2810 if (rawObj) { 2811 var _a = refineProps(rawObj, refiners), refined = _a.refined, extra = _a.extra; 2812 var metaRes = buildEventSourceMeta(refined, context); 2813 if (metaRes) { 2814 return { 2815 _raw: raw, 2816 isFetching: false, 2817 latestFetchId: '', 2818 fetchRange: null, 2819 defaultAllDay: refined.defaultAllDay, 2820 eventDataTransform: refined.eventDataTransform, 2821 success: refined.success, 2822 failure: refined.failure, 2823 publicId: refined.id || '', 2824 sourceId: guid(), 2825 sourceDefId: metaRes.sourceDefId, 2826 meta: metaRes.meta, 2827 ui: createEventUi(refined, context), 2828 extendedProps: extra, 2829 }; 2830 } 2831 } 2832 return null; 2833 } 2834 function buildEventSourceRefiners(context) { 2835 return __assign(__assign(__assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS$1), context.pluginHooks.eventSourceRefiners); 2836 } 2837 function buildEventSourceMeta(raw, context) { 2838 var defs = context.pluginHooks.eventSourceDefs; 2839 for (var i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence 2840 var def = defs[i]; 2841 var meta = def.parseMeta(raw); 2842 if (meta) { 2843 return { sourceDefId: i, meta: meta }; 2844 } 2845 } 2846 return null; 2847 } 2848 2849 function reduceCurrentDate(currentDate, action) { 2850 switch (action.type) { 2851 case 'CHANGE_DATE': 2852 return action.dateMarker; 2853 default: 2854 return currentDate; 2855 } 2856 } 2857 function getInitialDate(options, dateEnv) { 2858 var initialDateInput = options.initialDate; 2859 // compute the initial ambig-timezone date 2860 if (initialDateInput != null) { 2861 return dateEnv.createMarker(initialDateInput); 2862 } 2863 return getNow(options.now, dateEnv); // getNow already returns unzoned 2864 } 2865 function getNow(nowInput, dateEnv) { 2866 if (typeof nowInput === 'function') { 2867 nowInput = nowInput(); 2868 } 2869 if (nowInput == null) { 2870 return dateEnv.createNowMarker(); 2871 } 2872 return dateEnv.createMarker(nowInput); 2873 } 2874 2875 var CalendarApi = /** @class */ (function () { 2876 function CalendarApi() { 2877 } 2878 CalendarApi.prototype.getCurrentData = function () { 2879 return this.currentDataManager.getCurrentData(); 2880 }; 2881 CalendarApi.prototype.dispatch = function (action) { 2882 return this.currentDataManager.dispatch(action); 2883 }; 2884 Object.defineProperty(CalendarApi.prototype, "view", { 2885 get: function () { return this.getCurrentData().viewApi; } // for public API 2886 , 2887 enumerable: false, 2888 configurable: true 2889 }); 2890 CalendarApi.prototype.batchRendering = function (callback) { 2891 callback(); 2892 }; 2893 CalendarApi.prototype.updateSize = function () { 2894 this.trigger('_resize', true); 2895 }; 2896 // Options 2897 // ----------------------------------------------------------------------------------------------------------------- 2898 CalendarApi.prototype.setOption = function (name, val) { 2899 this.dispatch({ 2900 type: 'SET_OPTION', 2901 optionName: name, 2902 rawOptionValue: val, 2903 }); 2904 }; 2905 CalendarApi.prototype.getOption = function (name) { 2906 return this.currentDataManager.currentCalendarOptionsInput[name]; 2907 }; 2908 CalendarApi.prototype.getAvailableLocaleCodes = function () { 2909 return Object.keys(this.getCurrentData().availableRawLocales); 2910 }; 2911 // Trigger 2912 // ----------------------------------------------------------------------------------------------------------------- 2913 CalendarApi.prototype.on = function (handlerName, handler) { 2914 var currentDataManager = this.currentDataManager; 2915 if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) { 2916 currentDataManager.emitter.on(handlerName, handler); 2917 } 2918 else { 2919 console.warn("Unknown listener name '" + handlerName + "'"); 2920 } 2921 }; 2922 CalendarApi.prototype.off = function (handlerName, handler) { 2923 this.currentDataManager.emitter.off(handlerName, handler); 2924 }; 2925 // not meant for public use 2926 CalendarApi.prototype.trigger = function (handlerName) { 2927 var _a; 2928 var args = []; 2929 for (var _i = 1; _i < arguments.length; _i++) { 2930 args[_i - 1] = arguments[_i]; 2931 } 2932 (_a = this.currentDataManager.emitter).trigger.apply(_a, __spreadArray([handlerName], args)); 2933 }; 2934 // View 2935 // ----------------------------------------------------------------------------------------------------------------- 2936 CalendarApi.prototype.changeView = function (viewType, dateOrRange) { 2937 var _this = this; 2938 this.batchRendering(function () { 2939 _this.unselect(); 2940 if (dateOrRange) { 2941 if (dateOrRange.start && dateOrRange.end) { // a range 2942 _this.dispatch({ 2943 type: 'CHANGE_VIEW_TYPE', 2944 viewType: viewType, 2945 }); 2946 _this.dispatch({ 2947 type: 'SET_OPTION', 2948 optionName: 'visibleRange', 2949 rawOptionValue: dateOrRange, 2950 }); 2951 } 2952 else { 2953 var dateEnv = _this.getCurrentData().dateEnv; 2954 _this.dispatch({ 2955 type: 'CHANGE_VIEW_TYPE', 2956 viewType: viewType, 2957 dateMarker: dateEnv.createMarker(dateOrRange), 2958 }); 2959 } 2960 } 2961 else { 2962 _this.dispatch({ 2963 type: 'CHANGE_VIEW_TYPE', 2964 viewType: viewType, 2965 }); 2966 } 2967 }); 2968 };
2969 // Forces navigation to a view for the given date. 2970 // `viewType` can be a specific view name or a generic one like "week" or "day". 2971 // needs to change 2972 CalendarApi.prototype.zoomTo = function (dateMarker, viewType) { 2973 var state = this.getCurrentData(); 2974 var spec; 2975 viewType = viewType || 'day'; // day is default zoom 2976 spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType); 2977 this.unselect(); 2978 if (spec) { 2979 this.dispatch({ 2980 type: 'CHANGE_VIEW_TYPE', 2981 viewType: spec.type, 2982 dateMarker: dateMarker, 2983 }); 2984 } 2985 else { 2986 this.dispatch({ 2987 type: 'CHANGE_DATE', 2988 dateMarker: dateMarker, 2989 }); 2990 } 2991 }; 2992 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 2993 // Preference is given to views that have corresponding buttons. 2994 CalendarApi.prototype.getUnitViewSpec = function (unit) { 2995 var _a = this.getCurrentData(), viewSpecs = _a.viewSpecs, toolbarConfig = _a.toolbarConfig; 2996 var viewTypes = [].concat(toolbarConfig.viewsWithButtons); 2997 var i; 2998 var spec; 2999 for (var viewType in viewSpecs) { 3000 viewTypes.push(viewType); 3001 } 3002 for (i = 0; i < viewTypes.length; i += 1) { 3003 spec = viewSpecs[viewTypes[i]]; 3004 if (spec) { 3005 if (spec.singleUnit === unit) { 3006 return spec; 3007 } 3008 } 3009 } 3010 return null; 3011 }; 3012 // Current Date 3013 // ----------------------------------------------------------------------------------------------------------------- 3014 CalendarApi.prototype.prev = function () { 3015 this.unselect(); 3016 this.dispatch({ type: 'PREV' }); 3017 }; 3018 CalendarApi.prototype.next = function () { 3019 this.unselect(); 3020 this.dispatch({ type: 'NEXT' }); 3021 }; 3022 CalendarApi.prototype.prevYear = function () { 3023 var state = this.getCurrentData(); 3024 this.unselect(); 3025 this.dispatch({ 3026 type: 'CHANGE_DATE', 3027 dateMarker: state.dateEnv.addYears(state.currentDate, -1), 3028 }); 3029 }; 3030 CalendarApi.prototype.nextYear = function () { 3031 var state = this.getCurrentData(); 3032 this.unselect(); 3033 this.dispatch({ 3034 type: 'CHANGE_DATE', 3035 dateMarker: state.dateEnv.addYears(state.currentDate, 1), 3036 }); 3037 }; 3038 CalendarApi.prototype.today = function () { 3039 var state = this.getCurrentData(); 3040 this.unselect(); 3041 this.dispatch({ 3042 type: 'CHANGE_DATE', 3043 dateMarker: getNow(state.calendarOptions.now, state.dateEnv), 3044 }); 3045 }; 3046 CalendarApi.prototype.gotoDate = function (zonedDateInput) { 3047 var state = this.getCurrentData(); 3048 this.unselect(); 3049 this.dispatch({ 3050 type: 'CHANGE_DATE', 3051 dateMarker: state.dateEnv.createMarker(zonedDateInput), 3052 }); 3053 }; 3054 CalendarApi.prototype.incrementDate = function (deltaInput) { 3055 var state = this.getCurrentData(); 3056 var delta = createDuration(deltaInput); 3057 if (delta) { // else, warn about invalid input? 3058 this.unselect(); 3059 this.dispatch({ 3060 type: 'CHANGE_DATE', 3061 dateMarker: state.dateEnv.add(state.currentDate, delta), 3062 }); 3063 } 3064 }; 3065 // for external API 3066 CalendarApi.prototype.getDate = function () { 3067 var state = this.getCurrentData(); 3068 return state.dateEnv.toDate(state.currentDate); 3069 }; 3070 // Date Formatting Utils 3071 // ----------------------------------------------------------------------------------------------------------------- 3072 CalendarApi.prototype.formatDate = function (d, formatter) { 3073 var dateEnv = this.getCurrentData().dateEnv; 3074 return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter)); 3075 }; 3076 // `settings` is for formatter AND isEndExclusive 3077 CalendarApi.prototype.formatRange = function (d0, d1, settings) { 3078 var dateEnv = this.getCurrentData().dateEnv; 3079 return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings); 3080 }; 3081 CalendarApi.prototype.formatIso = function (d, omitTime) { 3082 var dateEnv = this.getCurrentData().dateEnv; 3083 return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime: omitTime }); 3084 }; 3085 // Date Selection / Event Selection / DayClick 3086 // ----------------------------------------------------------------------------------------------------------------- 3087 // this public method receives start/end dates in any format, with any timezone 3088 // NOTE: args were changed from v3 3089 CalendarApi.prototype.select = function (dateOrObj, endDate) { 3090 var selectionInput; 3091 if (endDate == null) { 3092 if (dateOrObj.start != null) { 3093 selectionInput = dateOrObj; 3094 } 3095 else { 3096 selectionInput = { 3097 start: dateOrObj, 3098 end: null, 3099 }; 3100 } 3101 } 3102 else { 3103 selectionInput = { 3104 start: dateOrObj, 3105 end: endDate, 3106 }; 3107 } 3108 var state = this.getCurrentData(); 3109 var selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 })); 3110 if (selection) { // throw parse error otherwise? 3111 this.dispatch({ type: 'SELECT_DATES', selection: selection }); 3112 triggerDateSelect(selection, null, state); 3113 } 3114 }; 3115 // public method 3116 CalendarApi.prototype.unselect = function (pev) { 3117 var state = this.getCurrentData(); 3118 if (state.dateSelection) { 3119 this.dispatch({ type: 'UNSELECT_DATES' }); 3120 triggerDateUnselect(pev, state); 3121 } 3122 }; 3123 // Public Events API 3124 // ----------------------------------------------------------------------------------------------------------------- 3125 CalendarApi.prototype.addEvent = function (eventInput, sourceIn
3125put) { 3126 if (eventInput instanceof EventApi) { 3127 var def = eventInput._def; 3128 var instance = eventInput._instance; 3129 var currentData = this.getCurrentData(); 3130 // not already present? don't want to add an old snapshot 3131 if (!currentData.eventStore.defs[def.defId]) { 3132 this.dispatch({ 3133 type: 'ADD_EVENTS', 3134 eventStore: eventTupleToStore({ def: def, instance: instance }), // TODO: better util for two args? 3135 }); 3136 this.triggerEventAdd(eventInput); 3137 } 3138 return eventInput; 3139 } 3140 var state = this.getCurrentData(); 3141 var eventSource; 3142 if (sourceInput instanceof EventSourceApi) { 3143 eventSource = sourceInput.internalEventSource; 3144 } 3145 else if (typeof sourceInput === 'boolean') { 3146 if (sourceInput) { // true. part of the first event source 3147 eventSource = hashValuesToArray(state.eventSources)[0]; 3148 } 3149 } 3150 else if (sourceInput != null) { // an ID. accepts a number too 3151 var sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function 3152 if (!sourceApi) { 3153 console.warn("Could not find an event source with ID \"" + sourceInput + "\""); // TODO: test 3154 return null; 3155 } 3156 eventSource = sourceApi.internalEventSource; 3157 } 3158 var tuple = parseEvent(eventInput, eventSource, state, false); 3159 if (tuple) { 3160 var newEventApi = new EventApi(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance); 3161 this.dispatch({ 3162 type: 'ADD_EVENTS', 3163 eventStore: eventTupleToStore(tuple), 3164 }); 3165 this.triggerEventAdd(newEventApi); 3166 return newEventApi; 3167 } 3168 return null; 3169 }; 3170 CalendarApi.prototype.triggerEventAdd = function (eventApi) { 3171 var _this = this; 3172 var emitter = this.getCurrentData().emitter; 3173 emitter.trigger('eventAdd', { 3174 event: eventApi, 3175 relatedEvents: [], 3176 revert: function () { 3177 _this.dispatch({ 3178 type: 'REMOVE_EVENTS', 3179 eventStore: eventApiToStore(eventApi), 3180 }); 3181 }, 3182 }); 3183 }; 3184 // TODO: optimize 3185 CalendarApi.prototype.getEventById = function (id) { 3186 var state = this.getCurrentData(); 3187 var _a = state.eventStore, defs = _a.defs, instances = _a.instances; 3188 id = String(id); 3189 for (var defId in defs) { 3190 var def = defs[defId]; 3191 if (def.publicId === id) { 3192 if (def.recurringDef) { 3193 return new EventApi(state, def, null); 3194 } 3195 for (var instanceId in instances) { 3196 var instance = instances[instanceId]; 3197 if (instance.defId === def.defId) { 3198 return new EventApi(state, def, instance); 3199 } 3200 } 3201 } 3202 } 3203 return null; 3204 }; 3205 CalendarApi.prototype.getEvents = function () { 3206 var currentData = this.getCurrentData(); 3207 return buildEventApis(currentData.eventStore, currentData); 3208 }; 3209 CalendarApi.prototype.removeAllEvents = function () { 3210 this.dispatch({ type: 'REMOVE_ALL_EVENTS' }); 3211 }; 3212 // Public Event Sources API 3213 // ----------------------------------------------------------------------------------------------------------------- 3214 CalendarApi.prototype.getEventSources = function () { 3215 var state = this.getCurrentData(); 3216 var sourceHash = state.eventSources; 3217 var sourceApis = []; 3218 for (var internalId in sourceHash) { 3219 sourceApis.push(new EventSourceApi(state, sourceHash[internalId])); 3220 } 3221 return sourceApis; 3222 }; 3223 CalendarApi.prototype.getEventSourceById = function (id) { 3224 var state = this.getCurrentData(); 3225 var sourceHash = state.eventSources; 3226 id = String(id); 3227 for (var sourceId in sourceHash) { 3228 if (sourceHash[sourceId].publicId === id) { 3229 return new EventSourceApi(state, sourceHash[sourceId]); 3230 } 3231 } 3232 return null; 3233 }; 3234 CalendarApi.prototype.addEventSource = function (sourceInput) { 3235 var state = this.getCurrentData(); 3236 if (sourceInput instanceof EventSourceApi) { 3237 // not already present? don't want to add an old snapshot
3238 if (!state.eventSources[sourceInput.internalEventSource.sourceId]) { 3239 this.dispatch({ 3240 type: 'ADD_EVENT_SOURCES', 3241 sources: [sourceInput.internalEventSource], 3242 }); 3243 } 3244 return sourceInput; 3245 } 3246 var eventSource = parseEventSource(sourceInput, state); 3247 if (eventSource) { // TODO: error otherwise? 3248 this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] }); 3249 return new EventSourceApi(state, eventSource); 3250 } 3251 return null; 3252 }; 3253 CalendarApi.prototype.removeAllEventSources = function () { 3254 this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' }); 3255 }; 3256 CalendarApi.prototype.refetchEvents = function () { 3257 this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true }); 3258 }; 3259 // Scroll 3260 // ----------------------------------------------------------------------------------------------------------------- 3261 CalendarApi.prototype.scrollToTime = function (timeInput) { 3262 var time = createDuration(timeInput); 3263 if (time) { 3264 this.trigger('_scrollRequest', { time: time }); 3265 } 3266 }; 3267 return CalendarApi; 3268 }()); 3269 3270 var EventApi = /** @class */ (function () { 3271 // instance will be null if expressing a recurring event that has no current instances, 3272 // OR if trying to validate an incoming external event that has no dates assigned 3273 function EventApi(context, def, instance) { 3274 this._context = context; 3275 this._def = def; 3276 this._instance = instance || null; 3277 } 3278 /* 3279 TODO: make event struct more responsible for this 3280 */ 3281 EventApi.prototype.setProp = function (name, val) { 3282 var _a, _b; 3283 if (name in EVENT_DATE_REFINERS) { 3284 console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.'); 3285 // TODO: make proper aliasing system? 3286 } 3287 else if (name === 'id') { 3288 val = EVENT_NON_DATE_REFINERS[name](val); 3289 this.mutate({ 3290 standardProps: { publicId: val }, // hardcoded internal name 3291 }); 3292 } 3293 else if (name in EVENT_NON_DATE_REFINERS) { 3294 val = EVENT_NON_DATE_REFINERS[name](val); 3295 this.mutate({ 3296 standardProps: (_a = {}, _a[name] = val, _a), 3297 }); 3298 } 3299 else if (name in EVENT_UI_REFINERS) { 3300 var ui = EVENT_UI_REFINERS[name](val); 3301 if (name === 'color') { 3302 ui = { backgroundColor: val, borderColor: val }; 3303 } 3304 else if (name === 'editable') { 3305 ui = { startEditable: val, durationEditable: val }; 3306 } 3307 else { 3308 ui = (_b = {}, _b[name] = val, _b); 3309 } 3310 this.mutate({ 3311 standardProps: { ui: ui }, 3312 }); 3313 } 3314 else { 3315 console.warn("Could not set prop '" + name + "'. Use setExtendedProp instead."); 3316 } 3317 }; 3318 EventApi.prototype.setExtendedProp = function (name, val) { 3319 var _a; 3320 this.mutate({ 3321 extendedProps: (_a = {}, _a[name] = val, _a), 3322 }); 3323 }; 3324 EventApi.prototype.setStart = function (startInput, options) { 3325 if (options === void 0) { options = {}; } 3326 var dateEnv = this._context.dateEnv; 3327 var start = dateEnv.createMarker(startInput); 3328 if (start && this._instance) { // TODO: warning if parsed bad 3329 var instanceRange = this._instance.range; 3330 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!? 3331 if (options.maintainDuration) { 3332 this.mutate({ datesDelta: startDelta }); 3333 } 3334 else { 3335 this.mutate({ startDelta: startDelta }); 3336 } 3337 } 3338 }; 3339 EventApi.prototype.setEnd = function (endInput, options) { 3340 if (options === void 0) { options = {}; } 3341 var dateEnv = this._context.dateEnv; 3342 var end; 3343 if (endInput != null) { 3344 end = dateEnv.createMarker(endInput); 3345 if (!end) { 3346 return; // TODO: warning if parsed bad 3347 } 3348 } 3349 if (this._instance) { 3350 if (end) { 3351 var endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity); 3352 this.mutate({ endDelta: endDelta }); 3353 } 3354 else { 3355 this.mutate({ standardProps: { hasEnd: false } }); 3356 } 3357 } 3358 }; 3359 EventApi.prototype.setDates = function (startInput, endInput, options) { 3360 if (options === void 0) { options = {}; } 3361 var dateEnv = this._context.dateEnv; 3362 var standardProps = { allDay: options.allDay }; 3363 var start = dateEnv.createMarker(startInput); 3364 var end; 3365 if (!start) { 3366 return; // TODO: warning if parsed bad 3367 } 3368 if (endInput != null) { 3369 end = dateEnv.createMarker(endInput); 3370 if (!end) { // TODO: warning if parsed bad 3371 return; 3372 } 3373 } 3374 if (this._instance) { 3375 var instanceRange = this._instance.range; 3376 // when computing the diff for an event being converted to all-day, 3377 // compute diff off of the all-day values the way event-mutation does. 3378 if (options.allDay === true) { 3379 instanceRange = computeAlignedDayRange(instanceRange); 3380 } 3381 var startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 3382 if (end) { 3383 var endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity); 3384 if (durationsEqual(startDelta, endDelta)) { 3385 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3386 } 3387 else { 3388 this.mutate({ startDelta: startDelta, endDelta: endDelta, standardProps: standardProps }); 3389 } 3390 } 3391 else { // means "clear the end" 3392 standardProps.hasEnd = false;
3393 this.mutate({ datesDelta: startDelta, standardProps: standardProps }); 3394 } 3395 } 3396 }; 3397 EventApi.prototype.moveStart = function (deltaInput) { 3398 var delta = createDuration(deltaInput); 3399 if (delta) { // TODO: warning if parsed bad 3400 this.mutate({ startDelta: delta }); 3401 } 3402 }; 3403 EventApi.prototype.moveEnd = function (deltaInput) { 3404 var delta = createDuration(deltaInput); 3405 if (delta) { // TODO: warning if parsed bad 3406 this.mutate({ endDelta: delta }); 3407 } 3408 }; 3409 EventApi.prototype.moveDates = function (deltaInput) { 3410 var delta = createDuration(deltaInput); 3411 if (delta) { // TODO: warning if parsed bad 3412 this.mutate({ datesDelta: delta }); 3413 } 3414 }; 3415 EventApi.prototype.setAllDay = function (allDay, options) { 3416 if (options === void 0) { options = {}; } 3417 var standardProps = { allDay: allDay }; 3418 var maintainDuration = options.maintainDuration; 3419 if (maintainDuration == null) { 3420 maintainDuration = this._context.options.allDayMaintainDuration; 3421 } 3422 if (this._def.allDay !== allDay) { 3423 standardProps.hasEnd = maintainDuration; 3424 } 3425 this.mutate({ standardProps: standardProps }); 3426 }; 3427 EventApi.prototype.formatRange = function (formatInput) { 3428 var dateEnv = this._context.dateEnv; 3429 var instance = this._instance; 3430 var formatter = createFormatter(formatInput); 3431 if (this._def.hasEnd) { 3432 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, { 3433 forcedStartTzo: instance.forcedStartTzo, 3434 forcedEndTzo: instance.forcedEndTzo, 3435 }); 3436 } 3437 return dateEnv.format(instance.range.start, formatter, { 3438 forcedTzo: instance.forcedStartTzo, 3439 }); 3440 }; 3441 EventApi.prototype.mutate = function (mutation) { 3442 var instance = this._instance; 3443 if (instance) { 3444 var def = this._def; 3445 var context_1 = this._context; 3446 var eventStore_1 = context_1.getCurrentData().eventStore; 3447 var relevantEvents = getRelevantEvents(eventStore_1, instance.instanceId); 3448 var eventConfigBase = { 3449 '': { 3450 display: '', 3451 startEditable: true, 3452 durationEditable: true, 3453 constraints: [], 3454 overlap: null, 3455 allows: [], 3456 backgroundColor: '', 3457 borderColor: '', 3458 textColor: '', 3459 classNames: [], 3460 }, 3461 }; 3462 relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context_1); 3463 var oldEvent = new EventApi(context_1, def, instance); // snapshot 3464 this._def = relevantEvents.defs[def.defId]; 3465 this._instance = relevantEvents.instances[instance.instanceId]; 3466 context_1.dispatch({ 3467 type: 'MERGE_EVENTS', 3468 eventStore: relevantEvents, 3469 }); 3470 context_1.emitter.trigger('eventChange', { 3471 oldEvent: oldEvent, 3472 event: this, 3473 relatedEvents: buildEventApis(relevantEvents, context_1, instance), 3474 revert: function () { 3475 context_1.dispatch({ 3476 type: 'RESET_EVENTS', 3477 eventStore: eventStore_1, 3478 }); 3479 }, 3480 }); 3481 } 3482 }; 3483 EventApi.prototype.remove = function () { 3484 var context = this._context; 3485 var asStore = eventApiToStore(this); 3486 context.dispatch({
3487 type: 'REMOVE_EVENTS', 3488 eventStore: asStore, 3489 }); 3490 context.emitter.trigger('eventRemove', { 3491 event: this, 3492 relatedEvents: [], 3493 revert: function () { 3494 context.dispatch({ 3495 type: 'MERGE_EVENTS', 3496 eventStore: asStore, 3497 }); 3498 }, 3499 }); 3500 }; 3501 Object.defineProperty(EventApi.prototype, "source", { 3502 get: function () { 3503 var sourceId = this._def.sourceId; 3504 if (sourceId) { 3505 return new EventSourceApi(this._context, this._context.getCurrentData().eventSources[sourceId]); 3506 } 3507 return null; 3508 }, 3509 enumerable: false, 3510 configurable: true 3511 }); 3512 Object.defineProperty(EventApi.prototype, "start", { 3513 get: function () { 3514 return this._instance ? 3515 this._context.dateEnv.toDate(this._instance.range.start) : 3516 null; 3517 }, 3518 enumerable: false, 3519 configurable: true 3520 }); 3521 Object.defineProperty(EventApi.prototype, "end", { 3522 get: function () { 3523 return (this._instance && this._def.hasEnd) ? 3524 this._context.dateEnv.toDate(this._instance.range.end) : 3525 null; 3526 }, 3527 enumerable: false, 3528 configurable: true 3529 }); 3530 Object.defineProperty(EventApi.prototype, "startStr", { 3531 get: function () { 3532 var instance = this._instance; 3533 if (instance) { 3534 return this._context.dateEnv.formatIso(instance.range.start, { 3535 omitTime: this._def.allDay, 3536 forcedTzo: instance.forcedStartTzo, 3537 }); 3538 } 3539 return ''; 3540 }, 3541 enumerable: false, 3542 configurable: true 3543 }); 3544 Object.defineProperty(EventApi.prototype, "endStr", { 3545 get: function () { 3546 var instance = this._instance; 3547 if (instance && this._def.hasEnd) { 3548 return this._context.dateEnv.formatIso(instance.range.end, { 3549 omitTime: this._def.allDay, 3550 forcedTzo: instance.forcedEndTzo, 3551 }); 3552 } 3553 return ''; 3554 }, 3555 enumerable: false, 3556 configurable: true 3557 }); 3558 Object.defineProperty(EventApi.prototype, "id", { 3559 // computable props that all access the def
3560 // TODO: find a TypeScript-compatible way to do this at scale 3561 get: function () { return this._def.publicId; }, 3562 enumerable: false, 3563 configurable: true 3564 }); 3565 Object.defineProperty(EventApi.prototype, "groupId", { 3566 get: function () { return this._def.groupId; }, 3567 enumerable: false, 3568 configurable: true 3569 }); 3570 Object.defineProperty(EventApi.prototype, "allDay", { 3571 get: function () { return this._def.allDay; }, 3572 enumerable: false, 3573 configurable: true 3574 }); 3575 Object.defineProperty(EventApi.prototype, "title", { 3576 get: function () { return this._def.title; }, 3577 enumerable: false, 3578 configurable: true 3579 }); 3580 Object.defineProperty(EventApi.prototype, "url", { 3581 get: function () { return this._def.url; }, 3582 enumerable: false, 3583 configurable: true 3584 }); 3585 Object.defineProperty(EventApi.prototype, "display", { 3586 get: function () { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier 3587 , 3588 enumerable: false, 3589 configurable: true 3590 }); 3591 Object.defineProperty(EventApi.prototype, "startEditable", { 3592 get: function () { return this._def.ui.startEditable; }, 3593 enumerable: false, 3594 configurable: true 3595 }); 3596 Object.defineProperty(EventApi.prototype, "durationEditable", { 3597 get: function () { return this._def.ui.durationEditable; }, 3598 enumerable: false, 3599 configurable: true 3600 }); 3601 Object.defineProperty(EventApi.prototype, "constraint", { 3602 get: function () { return this._def.ui.constraints[0] || null; }, 3603 enumerable: false, 3604 configurable: true 3605 }); 3606 Object.defineProperty(EventApi.prototype, "overlap", { 3607 get: function () { return this._def.ui.overlap; }, 3608 enumerable: false, 3609 configurable: true 3610 }); 3611 Object.defineProperty(EventApi.prototype, "allow", { 3612 get: function () { return this._def.ui.allows[0] || null; }, 3613 enumerable: false, 3614 configurable: true 3615 }); 3616 Object.defineProperty(EventApi.prototype, "backgroundColor", { 3617 get: function () { return this._def.ui.backgroundColor; }, 3618 enumerable: false, 3619 configurable: true 3620 }); 3621 Object.defineProperty(EventApi.prototype, "borderColor", { 3622 get: function () { return this._def.ui.borderColor; }, 3623 enumerable: false, 3624 configurable: true 3625 }); 3626 Object.defineProperty(EventApi.prototype, "textColor", { 3627 get: function () { return this._def.ui.textColor; }, 3628 enumerable: false, 3629 configurable: true 3630 }); 3631 Object.defineProperty(EventApi.prototype, "classNames", { 3632 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 3633 get: function () { return this._def.ui.classNames; }, 3634 enumerable: false, 3635 configurable: true 3636 }); 3637 Object.defineProperty(EventApi.prototype, "extendedProps", { 3638 get: function () { return this._def.extendedProps; }, 3639 enumerable: false, 3640 configurable: true 3641 }); 3642 EventApi.prototype.toPlainObject = function (settings) { 3643 if (settings === void 0) { settings = {}; } 3644 var def = this._def; 3645 var ui = def.ui; 3646 var _a = this, startStr = _a.startStr, endStr = _a.endStr; 3647 var res = {}; 3648 if (def.title) { 3649 res.title = def.title; 3650 } 3651 if (startStr) { 3652 res.start = startStr; 3653 } 3654 if (endStr) { 3655 res.end = endStr; 3656 } 3657 if (def.publicId) { 3658 res.id = def.publicId; 3659 } 3660 if (def.groupId) { 3661 res.groupId = def.groupId; 3662 } 3663 if (def.url) { 3664 res.url = def.url; 3665 } 3666 if (ui.display && ui.display !== 'auto') { 3667 res.display = ui.display; 3668 } 3669 // TODO: what about recurring-event properties??? 3670 // TODO: include startEditable/durationEditable/constraint/overlap/allow 3671 if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) { 3672 res.color = ui.backgroundColor; 3673 } 3674 else { 3675 if (ui.backgroundColor) { 3676 res.backgroundColor = ui.backgroundColor; 3677 } 3678 if (ui.borderColor) { 3679 res.borderColor = ui.borderColor; 3680 } 3681 } 3682 if (ui.textColor) { 3683 res.textColor = ui.textColor; 3684 } 3685 if (ui.classNames.length) { 3686 res.classNames = ui.classNames; 3687 } 3688 if (Object.keys(def.extendedProps).length) { 3689 if (settings.collapseExtendedProps) { 3690 __assign(res, def.extendedProps); 3691 } 3692 else { 3693 res.extendedProps = def.extendedProps; 3694 } 3695 } 3696 return res; 3697 }; 3698 EventApi.prototype.toJSON = function () { 3699 return this.toPlainObject(); 3700 }; 3701 return EventApi; 3702 }()); 3703 function eventApiToStore(eventApi) { 3704 var _a, _b; 3705 var def = eventApi._def; 3706 var instance = eventApi._instance; 3707 return { 3708 defs: (_a = {}, _a[def.defId] = def, _a), 3709 instances: instance 3710 ? (_b = {}, _b[instance.instanceId] = instance, _b) : {}, 3711 }; 3712 } 3713 function buildEventApis(eventStore, context, excludeInstance) { 3714 var defs = eventStore.defs, instances = eventStore.instances; 3715 var eventApis = []; 3716 var excludeInstanceId = excludeInstance ? excludeInstance.instanceId : ''; 3717 for (var id in instances) { 3718 var instance = instances[id]; 3719 var def = defs[instance.defId]; 3720 if (instance.instanceId !== excludeInstanceId) { 3721 eventApis.push(new EventApi(context, def, instance)); 3722 } 3723 } 3724 return eventApis; 3725 } 3726 3727 var calendarSystemClassMap = {}; 3728 function registerCalendarSystem(name, theClass) { 3729 calendarSystemClassMap[name] = theClass; 3730 } 3731 function createCalendarSystem(name) { 3732 return new calendarSystemClassMap[name](); 3733 } 3734 var GregorianCalendarSystem = /** @class */ (function () { 3735 function GregorianCalendarSystem() { 3736 } 3737 GregorianCalendarSystem.prototype.getMarkerYear = function (d) { 3738 return d.getUTCFullYear(); 3739 }; 3740 GregorianCalendarSystem.prototype.getMarkerMonth = function (d) { 3741 return d.getUTCMonth(); 3742 }; 3743 GregorianCalendarSystem.prototype.getMarkerDay = function (d) { 3744 return d.getUTCDate(); 3745 }; 3746 GregorianCalendarSystem.prototype.arrayToMarker = function (arr) { 3747 return arrayToUtcDate(arr); 3748 }; 3749 GregorianCalendarSystem.prototype.markerToArray = function (marker) { 3750 return dateToUtcArray(marker); 3751 }; 3752 return GregorianCalendarSystem; 3753 }()); 3754 registerCalendarSystem('gregory', GregorianCalendarSystem); 3755 3756 var ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 3757 function parse(str) { 3758 var m = ISO_RE.exec(str); 3759 if (m) { 3760 var marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number("0." + m[12]) * 1000 : 0)); 3761 if (isValidDate(marker)) { 3762 var timeZoneOffset = null; 3763 if (m[13]) { 3764 timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 + 3765 Number(m[18] || 0)); 3766 } 3767 return { 3768 marker: marker, 3769 isTimeUnspecified: !m[6], 3770 timeZoneOffset: timeZoneOffset, 3771 }; 3772 } 3773 } 3774 return null; 3775 } 3776 3777 var DateEnv = /** @class */ (function () { 3778 function DateEnv(settings) { 3779 var timeZone = this.timeZone = settings.timeZone; 3780 var isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC'; 3781 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 3782 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 3783 } 3784 this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl); 3785 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 3786 this.locale = settings.locale; 3787 this.weekDow = settings.locale.week.dow; 3788 this.weekDoy = settings.locale.week.doy; 3789 if (settings.weekNumberCalculation === 'ISO') { 3790 this.weekDow = 1; 3791 this.weekDoy = 4; 3792 } 3793 if (typeof settings.firstDay === 'number') { 3794 this.weekDow = settings.firstDay; 3795 } 3796 if (typeof settings.weekNumberCalculation === 'function') {
vendor: 16,384 bytes, lines 3797-4208
3797 this.weekNumberFunc = settings.weekNumberCalculation; 3798 } 3799 this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText; 3800 this.cmdFormatter = settings.cmdFormatter; 3801 this.defaultSeparator = settings.defaultSeparator; 3802 } 3803 // Creating / Parsing 3804 DateEnv.prototype.createMarker = function (input) { 3805 var meta = this.createMarkerMeta(input); 3806 if (meta === null) { 3807 return null; 3808 } 3809 return meta.marker; 3810 }; 3811 DateEnv.prototype.createNowMarker = function () { 3812 if (this.canComputeOffset) { 3813 return this.timestampToMarker(new Date().valueOf()); 3814 } 3815 // if we can't compute the current date val for a timezone, 3816 // better to give the current local date vals than UTC 3817 return arrayToUtcDate(dateToLocalArray(new Date())); 3818 }; 3819 DateEnv.prototype.createMarkerMeta = function (input) { 3820 if (typeof input === 'string') { 3821 return this.parse(input); 3822 } 3823 var marker = null; 3824 if (typeof input === 'number') { 3825 marker = this.timestampToMarker(input); 3826 } 3827 else if (input instanceof Date) { 3828 input = input.valueOf(); 3829 if (!isNaN(input)) { 3830 marker = this.timestampToMarker(input); 3831 } 3832 } 3833 else if (Array.isArray(input)) { 3834 marker = arrayToUtcDate(input); 3835 } 3836 if (marker === null || !isValidDate(marker)) { 3837 return null; 3838 } 3839 return { marker: marker, isTimeUnspecified: false, forcedTzo: null }; 3840 }; 3841 DateEnv.prototype.parse = function (s) { 3842 var parts = parse(s); 3843 if (parts === null) { 3844 return null; 3845 } 3846 var marker = parts.marker; 3847 var forcedTzo = null; 3848 if (parts.timeZoneOffset !== null) { 3849 if (this.canComputeOffset) { 3850 marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000); 3851 } 3852 else { 3853 forcedTzo = parts.timeZoneOffset; 3854 } 3855 } 3856 return { marker: marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo: forcedTzo }; 3857 }; 3858 // Accessors 3859 DateEnv.prototype.getYear = function (marker) { 3860 return this.calendarSystem.getMarkerYear(marker); 3861 }; 3862 DateEnv.prototype.getMonth = function (marker) { 3863 return this.calendarSystem.getMarkerMonth(marker); 3864 }; 3865 // Adding / Subtracting 3866 DateEnv.prototype.add = function (marker, dur) { 3867 var a = this.calendarSystem.markerToArray(marker); 3868 a[0] += dur.years; 3869 a[1] += dur.months; 3870 a[2] += dur.days; 3871 a[6] += dur.milliseconds; 3872 return this.calendarSystem.arrayToMarker(a); 3873 }; 3874 DateEnv.prototype.subtract = function (marker, dur) { 3875 var a = this.calendarSystem.markerToArray(marker); 3876 a[0] -= dur.years; 3877 a[1] -= dur.months; 3878 a[2] -= dur.days; 3879 a[6] -= dur.milliseconds; 3880 return this.calendarSystem.arrayToMarker(a); 3881 }; 3882 DateEnv.prototype.addYears = function (marker, n) { 3883 var a = this.calendarSystem.markerToArray(marker); 3884 a[0] += n; 3885 return this.calendarSystem.arrayToMarker(a); 3886 }; 3887 DateEnv.prototype.addMonths = function (marker, n) { 3888 var a = this.calendarSystem.markerToArray(marker); 3889 a[1] += n; 3890 return this.calendarSystem.arrayToMarker(a); 3891 }; 3892 // Diffing Whole Units 3893 DateEnv.prototype.diffWholeYears = function (m0, m1) { 3894 var calendarSystem = this.calendarSystem; 3895 if (timeAsMs(m0) === timeAsMs(m1) && 3896 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && 3897 calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) { 3898 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0); 3899 } 3900 return null; 3901 }; 3902 DateEnv.prototype.diffWholeMonths = function (m0, m1) { 3903 var calendarSystem = this.calendarSystem; 3904 if (timeAsMs(m0) === timeAsMs(m1) && 3905 calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) { 3906 return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) + 3907 (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12; 3908 } 3909 return null; 3910 }; 3911 // Range / Duration 3912 DateEnv.prototype.greatestWholeUnit = function (m0, m1) { 3913 var n = this.diffWholeYears(m0, m1); 3914 if (n !== null) { 3915 return { unit: 'year', value: n }; 3916 } 3917 n = this.diffWholeMonths(m0, m1); 3918 if (n !== null) { 3919 return { unit: 'month', value: n }; 3920 } 3921 n = diffWholeWeeks(m0, m1); 3922 if (n !== null) { 3923 return { unit: 'week', value: n }; 3924 } 3925 n = diffWholeDays(m0, m1); 3926 if (n !== null) { 3927 return { unit: 'day', value: n }; 3928 } 3929 n = diffHours(m0, m1); 3930 if (isInt(n)) { 3931 return { unit: 'hour', value: n }; 3932 } 3933 n = diffMinutes(m0, m1); 3934 if (isInt(n)) { 3935 return { unit: 'minute', value: n }; 3936 } 3937 n = diffSeconds(m0, m1); 3938 if (isInt(n)) { 3939 return { unit: 'second', value: n }; 3940 } 3941 return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() }; 3942 }; 3943 DateEnv.prototype.countDurationsBetween = function (m0, m1, d) { 3944 // TODO: can use greatestWholeUnit 3945 var diff; 3946 if (d.years) { 3947 diff = this.diffWholeYears(m0, m1); 3948 if (diff !== null) { 3949 return diff / asRoughYears(d); 3950 } 3951 } 3952 if (d.months) { 3953 diff = this.diffWholeMonths(m0, m1); 3954 if (diff !== null) { 3955 return diff / asRoughMonths(d); 3956 } 3957 } 3958 if (d.days) { 3959 diff = diffWholeDays(m0, m1); 3960 if (diff !== null) { 3961 return diff / asRoughDays(d); 3962 } 3963 } 3964 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d); 3965 }; 3966 // Start-Of 3967 // these DON'T return zoned-dates. only UTC start-of dates 3968 DateEnv.prototype.startOf = function (m, unit) { 3969 if (unit === 'year') { 3970 return this.startOfYear(m); 3971 } 3972 if (unit === 'month') { 3973 return this.startOfMonth(m); 3974 } 3975 if (unit === 'week') { 3976 return this.startOfWeek(m); 3977 } 3978 if (unit === 'day') { 3979 return startOfDay(m); 3980 } 3981 if (unit === 'hour') { 3982 return startOfHour(m); 3983 } 3984 if (unit === 'minute') { 3985 return startOfMinute(m); 3986 } 3987 if (unit === 'second') { 3988 return startOfSecond(m); 3989 } 3990 return null; 3991 }; 3992 DateEnv.prototype.startOfYear = function (m) { 3993 return this.calendarSystem.arrayToMarker([ 3994 this.calendarSystem.getMarkerYear(m), 3995 ]); 3996 }; 3997 DateEnv.prototype.startOfMonth = function (m) { 3998 return this.calendarSystem.arrayToMarker([ 3999 this.calendarSystem.getMarkerYear(m), 4000 this.calendarSystem.getMarkerMonth(m), 4001 ]); 4002 }; 4003 DateEnv.prototype.startOfWeek = function (m) { 4004 return this.calendarSystem.arrayToMarker([ 4005 this.calendarSystem.getMarkerYear(m), 4006 this.calendarSystem.getMarkerMonth(m), 4007 m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7), 4008 ]); 4009 }; 4010 // Week Number 4011 DateEnv.prototype.computeWeekNumber = function (marker) { 4012 if (this.weekNumberFunc) { 4013 return this.weekNumberFunc(this.toDate(marker)); 4014 } 4015 return weekOfYear(marker, this.weekDow, this.weekDoy); 4016 }; 4017 // TODO: choke on timeZoneName: long 4018 DateEnv.prototype.format = function (marker, formatter, dateOptions) { 4019 if (dateOptions === void 0) { dateOptions = {}; } 4020 return formatter.format({ 4021 marker: marker, 4022 timeZoneOffset: dateOptions.forcedTzo != null ? 4023 dateOptions.forcedTzo : 4024 this.offsetForMarker(marker), 4025 }, this); 4026 }; 4027 DateEnv.prototype.formatRange = function (start, end, formatter, dateOptions) { 4028 if (dateOptions === void 0) { dateOptions = {}; } 4029 if (dateOptions.isEndExclusive) { 4030 end = addMs(end, -1); 4031 } 4032 return formatter.formatRange({ 4033 marker: start, 4034 timeZoneOffset: dateOptions.forcedStartTzo != null ? 4035 dateOptions.forcedStartTzo : 4036 this.offsetForMarker(start), 4037 }, { 4038 marker: end, 4039 timeZoneOffset: dateOptions.forcedEndTzo != null ? 4040 dateOptions.forcedEndTzo : 4041 this.offsetForMarker(end), 4042 }, this, dateOptions.defaultSeparator); 4043 }; 4044 /* 4045 DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that, 4046 might as well use buildIsoString or some other util directly 4047 */ 4048 DateEnv.prototype.formatIso = function (marker, extraOptions) { 4049 if (extraOptions === void 0) { extraOptions = {}; } 4050 var timeZoneOffset = null; 4051 if (!extraOptions.omitTimeZoneOffset) { 4052 if (extraOptions.forcedTzo != null) { 4053 timeZoneOffset = extraOptions.forcedTzo; 4054 } 4055 else { 4056 timeZoneOffset = this.offsetForMarker(marker); 4057 } 4058 } 4059 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 4060 }; 4061 // TimeZone 4062 DateEnv.prototype.timestampToMarker = function (ms) { 4063 if (this.timeZone === 'local') { 4064 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 4065 } 4066 if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) { 4067 return new Date(ms); 4068 } 4069 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 4070 }; 4071 DateEnv.prototype.offsetForMarker = function (m) { 4072 if (this.timeZone === 'local') { 4073 return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset 4074 } 4075 if (this.timeZone === 'UTC') { 4076 return 0; 4077 } 4078 if (this.namedTimeZoneImpl) { 4079 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)); 4080 } 4081 return null; 4082 }; 4083 // Conversion 4084 DateEnv.prototype.toDate = function (m, forcedTzo) { 4085 if (this.timeZone === 'local') { 4086 return arrayToLocalDate(dateToUtcArray(m)); 4087 } 4088 if (this.timeZone === 'UTC') { 4089 return new Date(m.valueOf()); // make sure it's a copy 4090 } 4091 if (!this.namedTimeZoneImpl) { 4092 return new Date(m.valueOf() - (forcedTzo || 0)); 4093 } 4094 return new Date(m.valueOf() - 4095 this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60); 4096 }; 4097 return DateEnv; 4098 }()); 4099 4100 var globalLocales = []; 4101 4102 var RAW_EN_LOCALE = { 4103 code: 'en', 4104 week: { 4105 dow: 0, 4106 doy: 4, // 4 days need to be within the year to be considered the first week 4107 }, 4108 direction: 'ltr', 4109 buttonText: { 4110 prev: 'prev', 4111 next: 'next', 4112 prevYear: 'prev year', 4113 nextYear: 'next year', 4114 year: 'year', 4115 today: 'today', 4116 month: 'month', 4117 week: 'week', 4118 day: 'day', 4119 list: 'list', 4120 }, 4121 weekText: 'W', 4122 allDayText: 'all-day', 4123 moreLinkText: 'more', 4124 noEventsText: 'No events to display', 4125 }; 4126 function organizeRawLocales(explicitRawLocales) { 4127 var defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en'; 4128 var allRawLocales = globalLocales.concat(explicitRawLocales); 4129 var rawLocaleMap = { 4130 en: RAW_EN_LOCALE, // necessary? 4131 }; 4132 for (var _i = 0, allRawLocales_1 = allRawLocales; _i < allRawLocales_1.length; _i++) { 4133 var rawLocale = allRawLocales_1[_i]; 4134 rawLocaleMap[rawLocale.code] = rawLocale; 4135 } 4136 return { 4137 map: rawLocaleMap, 4138 defaultCode: defaultCode, 4139 }; 4140 } 4141 function buildLocale(inputSingular, available) { 4142 if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) { 4143 return parseLocale(inputSingular.code, [inputSingular.code], inputSingular); 4144 } 4145 return queryLocale(inputSingular, available); 4146 } 4147 function queryLocale(codeArg, available) { 4148 var codes = [].concat(codeArg || []); // will convert to array 4149 var raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 4150 return parseLocale(codeArg, codes, raw); 4151 } 4152 function queryRawLocale(codes, available) { 4153 for (var i = 0; i < codes.length; i += 1) { 4154 var parts = codes[i].toLocaleLowerCase().split('-'); 4155 for (var j = parts.length; j > 0; j -= 1) { 4156 var simpleId = parts.slice(0, j).join('-'); 4157 if (available[simpleId]) { 4158 return available[simpleId]; 4159 } 4160 } 4161 } 4162 return null; 4163 } 4164 function parseLocale(codeArg, codes, raw) { 4165 var merged = mergeProps([RAW_EN_LOCALE, raw], ['buttonText']); 4166 delete merged.code; // don't want this part of the options 4167 var week = merged.week; 4168 delete merged.week; 4169 return { 4170 codeArg: codeArg, 4171 codes: codes, 4172 week: week, 4173 simpleNumberFormat: new Intl.NumberFormat(codeArg), 4174 options: merged, 4175 }; 4176 } 4177 4178 function formatDate(dateInput, options) { 4179 if (options === void 0) { options = {}; } 4180 var dateEnv = buildDateEnv$1(options); 4181 var formatter = createFormatter(options); 4182 var dateMeta = dateEnv.createMarkerMeta(dateInput); 4183 if (!dateMeta) { // TODO: warning? 4184 return ''; 4185 } 4186 return dateEnv.format(dateMeta.marker, formatter, { 4187 forcedTzo: dateMeta.forcedTzo, 4188 }); 4189 } 4190 function formatRange(startInput, endInput, options) { 4191 var dateEnv = buildDateEnv$1(typeof options === 'object' && options ? options : {}); // pass in if non-null object 4192 var formatter = createFormatter(options); 4193 var startMeta = dateEnv.createMarkerMeta(startInput); 4194 var endMeta = dateEnv.createMarkerMeta(endInput); 4195 if (!startMeta || !endMeta) { // TODO: warning? 4196 return ''; 4197 } 4198 return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, { 4199 forcedStartTzo: startMeta.forcedTzo, 4200 forcedEndTzo: endMeta.forcedTzo, 4201 isEndExclusive: options.isEndExclusive, 4202 defaultSeparator: BASE_OPTION_DEFAULTS.defaultRangeSeparator, 4203 }); 4204 } 4205 // TODO: more DRY and optimized 4206 function buildDateEnv$1(settings) { 4207 var locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere 4208 r
4208eturn new DateEnv(__assign(__assign({ timeZone: BASE_OPTION_DEFAULTS.timeZone, calendarSystem: 'gregory' }, settings), { locale: locale })); 4209 } 4210 4211 var DEF_DEFAULTS = { 4212 startTime: '09:00', 4213 endTime: '17:00', 4214 daysOfWeek: [1, 2, 3, 4, 5], 4215 display: 'inverse-background', 4216 classNames: 'fc-non-business', 4217 groupId: '_businessHours', // so multiple defs get grouped 4218 }; 4219 /* 4220 TODO: pass around as EventDefHash!!! 4221 */ 4222 function parseBusinessHours(input, context) { 4223 return parseEvents(refineInputs(input), null, context); 4224 } 4225 function refineInputs(input) { 4226 var rawDefs; 4227 if (input === true) { 4228 rawDefs = [{}]; // will get DEF_DEFAULTS verbatim 4229 } 4230 else if (Array.isArray(input)) { 4231 // if specifying an array, every sub-definition NEEDS a day-of-week 4232 rawDefs = input.filter(function (rawDef) { return rawDef.daysOfWeek; }); 4233 } 4234 else if (typeof input === 'object' && input) { // non-null object 4235 rawDefs = [input]; 4236 } 4237 else { // is probably false 4238 rawDefs = []; 4239 } 4240 rawDefs = rawDefs.map(function (rawDef) { return (__assign(__assign({}, DEF_DEFAULTS), rawDef)); }); 4241 return rawDefs; 4242 } 4243 4244 function pointInsideRect(point, rect) { 4245 return point.left >= rect.left && 4246 point.left < rect.right && 4247 point.top >= rect.top && 4248 point.top < rect.bottom; 4249 } 4250 // Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false 4251 function intersectRects(rect1, rect2) { 4252 var res = { 4253 left: Math.max(rect1.left, rect2.left), 4254 right: Math.min(rect1.right, rect2.right), 4255 top: Math.max(rect1.top, rect2.top), 4256 bottom: Math.min(rect1.bottom, rect2.bottom), 4257 }; 4258 if (res.left < res.right && res.top < res.bottom) { 4259 return res; 4260 } 4261 return false; 4262 } 4263 function translateRect(rect, deltaX, deltaY) { 4264 return { 4265 left: rect.left + deltaX, 4266 right: rect.right + deltaX, 4267 top: rect.top + deltaY, 4268 bottom: rect.bottom + deltaY, 4269 }; 4270 } 4271 // Returns a new point that will have been moved to reside within the given rectangle 4272 function constrainPoint(point, rect) { 4273 return { 4274 left: Math.min(Math.max(point.left, rect.left), rect.right), 4275 top: Math.min(Math.max(point.top, rect.top), rect.bottom), 4276 }; 4277 } 4278 // Returns a point that is the center of the given rectangle 4279 function getRectCenter(rect) { 4280 return { 4281 left: (rect.left + rect.right) / 2, 4282 top: (rect.top + rect.bottom) / 2, 4283 }; 4284 } 4285 // Subtracts point2's coordinates from point1's coordinates, returning a delta 4286 function diffPoints(point1, point2) { 4287 return { 4288 left: point1.left - point2.left, 4289 top: point1.top - point2.top, 4290 }; 4291 } 4292 4293 var canVGrowWithinCell; 4294 function getCanVGrowWithinCell() { 4295 if (canVGrowWithinCell == null) { 4296 canVGrowWithinCell = computeCanVGrowWithinCell(); 4297 } 4298 return canVGrowWithinCell; 4299 } 4300 function computeCanVGrowWithinCell() { 4301 // for SSR, because this function is call immediately at top-level 4302 // TODO: just make this logic execute top-level, immediately, instead of doing lazily 4303 if (typeof document === 'undefined') { 4304 return true; 4305 } 4306 var el = document.createElement('div'); 4307 el.style.position = 'absolute'; 4308 el.style.top = '0px'; 4309 el.style.left = '0px'; 4310 el.innerHTML = '<table><tr><td><div></div></td></tr></table>'; 4311 el.querySelector('table').style.height = '100px'; 4312 el.querySelector('div').style.height = '100%'; 4313 document.body.appendChild(el); 4314 var div = el.querySelector('div'); 4315 var possible = div.offsetHeight > 0; 4316 document.body.removeChild(el); 4317 return possible; 4318 } 4319 4320 var EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere 4321 var Splitter = /** @class */ (function () { 4322 function Splitter() {
4323 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 4324 this.splitDateSelection = memoize(this._splitDateSpan); 4325 this.splitEventStore = memoize(this._splitEventStore); 4326 this.splitIndividualUi = memoize(this._splitIndividualUi); 4327 this.splitEventDrag = memoize(this._splitInteraction); 4328 this.splitEventResize = memoize(this._splitInteraction); 4329 this.eventUiBuilders = {}; // TODO: typescript protection 4330 } 4331 Splitter.prototype.splitProps = function (props) { 4332 var _this = this; 4333 var keyInfos = this.getKeyInfo(props); 4334 var defKeys = this.getKeysForEventDefs(props.eventStore); 4335 var dateSelections = this.splitDateSelection(props.dateSelection); 4336 var individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases* 4337 var eventStores = this.splitEventStore(props.eventStore, defKeys); 4338 var eventDrags = this.splitEventDrag(props.eventDrag); 4339 var eventResizes = this.splitEventResize(props.eventResize); 4340 var splitProps = {}; 4341 this.eventUiBuilders = mapHash(keyInfos, function (info, key) { return _this.eventUiBuilders[key] || memoize(buildEventUiForKey); }); 4342 for (var key in keyInfos) { 4343 var keyInfo = keyInfos[key]; 4344 var eventStore = eventStores[key] || EMPTY_EVENT_STORE; 4345 var buildEventUi = this.eventUiBuilders[key]; 4346 splitProps[key] = { 4347 businessHours: keyInfo.businessHours || props.businessHours, 4348 dateSelection: dateSelections[key] || null, 4349 eventStore: eventStore, 4350 eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]), 4351 eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '', 4352 eventDrag: eventDrags[key] || null, 4353 eventResize: eventResizes[key] || null, 4354 }; 4355 } 4356 return splitProps; 4357 }; 4358 Splitter.prototype._splitDateSpan = function (dateSpan) { 4359 var dateSpans = {}; 4360 if (dateSpan) { 4361 var keys = this.getKeysForDateSpan(dateSpan); 4362 for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { 4363 var key = keys_1[_i]; 4364 dateSpans[key] = dateSpan; 4365 } 4366 } 4367 return dateSpans; 4368 }; 4369 Splitter.prototype._getKeysForEventDefs = function (eventStore) { 4370 var _this = this; 4371 return mapHash(eventStore.defs, function (eventDef) { return _this.getKeysForEventDef(eventDef); }); 4372 }; 4373 Splitter.prototype._splitEventStore = function (eventStore, defKeys) { 4374 var defs = eventStore.defs, instances = eventStore.instances; 4375 var splitStores = {}; 4376 for (var defId in defs) { 4377 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4378 var key = _a[_i]; 4379 if (!splitStores[key]) { 4380 splitStores[key] = createEmptyEventStore(); 4381 } 4382 splitStores[key].defs[defId] = defs[defId]; 4383 } 4384 } 4385 for (var instanceId in instances) { 4386 var instance = instances[instanceId]; 4387 for (var _b = 0, _c = defKeys[instance.defId]; _b < _c.length; _b++) { 4388 var key = _c[_b]; 4389 if (splitStores[key]) { // must have already been created 4390 splitStores[key].instances[instanceId] = instance; 4391 } 4392 } 4393 } 4394 return splitStores; 4395 }; 4396 Splitter.prototype._splitIndividualUi = function (eventUiBases, defKeys) { 4397 var splitHashes = {}; 4398 for (var defId in eventUiBases) { 4399 if (defId) { // not the '' key 4400 for (var _i = 0, _a = defKeys[defId]; _i < _a.length; _i++) { 4401 var key = _a[_i]; 4402 if (!splitHashes[key]) { 4403 splitHashes[key] = {}; 4404 } 4405 splitHashes[key][defId] = eventUiBases[defId]; 4406 } 4407 } 4408 } 4409 return splitHashes; 4410 }; 4411 Splitter.prototype._splitInteraction = function (interaction) { 4412 var splitStates = {}; 4413 if (interaction) { 4414 var affectedStores_1 = this._splitEventStore(interaction.affectedEvents, this._getKeys
4414ForEventDefs(interaction.affectedEvents)); 4415 // can't rely on defKeys because event data is mutated 4416 var mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents); 4417 var mutatedStores_1 = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId); 4418 var populate = function (key) { 4419 if (!splitStates[key]) { 4420 splitStates[key] = { 4421 affectedEvents: affectedStores_1[key] || EMPTY_EVENT_STORE, 4422 mutatedEvents: mutatedStores_1[key] || EMPTY_EVENT_STORE, 4423 isEvent: interaction.isEvent, 4424 }; 4425 } 4426 }; 4427 for (var key in affectedStores_1) { 4428 populate(key); 4429 } 4430 for (var key in mutatedStores_1) { 4431 populate(key); 4432 } 4433 } 4434 return splitStates; 4435 }; 4436 return Splitter; 4437 }()); 4438 function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 4439 var baseParts = []; 4440 if (allUi) { 4441 baseParts.push(allUi); 4442 } 4443 if (eventUiForKey) { 4444 baseParts.push(eventUiForKey); 4445 } 4446 var stuff = { 4447 '': combineEventUis(baseParts), 4448 }; 4449 if (individualUi) { 4450 __assign(stuff, individualUi); 4451 } 4452 return stuff; 4453 } 4454 4455 function getDateMeta(date, todayRange, nowDate, dateProfile) { 4456 return { 4457 dow: date.getUTCDay(), 4458 isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)), 4459 isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)), 4460 isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)), 4461 isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false), 4462 isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false), 4463 }; 4464 } 4465 function getDayClassNames(meta, theme) { 4466 var classNames = [ 4467 'fc-day', 4468 "fc-day-" + DAY_IDS[meta.dow], 4469 ]; 4470 if (meta.isDisabled) { 4471 classNames.push('fc-day-disabled'); 4472 } 4473 else { 4474 if (meta.isToday) { 4475 classNames.push('fc-day-today'); 4476 classNames.push(theme.getClass('today')); 4477 } 4478 if (meta.isPast) { 4479 classNames.push('fc-day-past'); 4480 } 4481 if (meta.isFuture) { 4482 classNames.push('fc-day-future'); 4483 } 4484 if (meta.isOther) { 4485 classNames.push('fc-day-other'); 4486 } 4487 } 4488 return classNames; 4489 } 4490 function getSlotClassNames(meta, theme) { 4491 var classNames = [ 4492 'fc-slot', 4493 "fc-slot-" + DAY_IDS[meta.dow], 4494 ]; 4495 if (meta.isDisabled) { 4496 classNames.push('fc-slot-disabled'); 4497 } 4498 else { 4499 if (meta.isToday) { 4500 classNames.push('fc-slot-today'); 4501 classNames.push(theme.getClass('today')); 4502 } 4503 if (meta.isPast) { 4504 classNames.push('fc-slot-past'); 4505 } 4506 if (meta.isFuture) { 4507 classNames.push('fc-slot-future'); 4508 } 4509 } 4510 return classNames; 4511 } 4512 4513 function buildNavLinkData(date, type) { 4514 if (type === void 0) { type = 'day'; } 4515 return JSON.stringify({ 4516 date: formatDayString(date), 4517 type: type, 4518 }); 4519 } 4520 4521 var _isRtlScrollbarOnLeft = null; 4522 function getIsRtlScrollbarOnLeft() { 4523 if (_isRtlScrollbarOnLeft === null) { 4524 _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 4525 } 4526 return _isRtlScrollbarOnLeft; 4527 } 4528 function computeIsRtlScrollbarOnLeft() { 4529 var outerEl = document.createElement('div'); 4530 applyStyle(outerEl, { 4531 position: 'absolute', 4532 top: -1000, 4533 left: 0, 4534 border: 0, 4535 padding: 0, 4536 overflow: 'scroll', 4537 direction: 'rtl', 4538 }); 4539 outerEl.innerHTML = '<div></div>'; 4540 document.body.appendChild(outerEl); 4541 var innerEl = outerEl.firstChild; 4542 var res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left; 4543 removeElement(outerEl); 4544 return res; 4545 } 4546 4547 var _scrollbarWidths; 4548 function getScrollbarWidths() { 4549 if (!_scrollbarWidths) {
4550 _scrollbarWidths = computeScrollbarWidths(); 4551 } 4552 return _scrollbarWidths; 4553 } 4554 function computeScrollbarWidths() { 4555 var el = document.createElement('div'); 4556 el.style.overflow = 'scroll'; 4557 el.style.position = 'absolute'; 4558 el.style.top = '-9999px'; 4559 el.style.left = '-9999px'; 4560 document.body.appendChild(el); 4561 var res = computeScrollbarWidthsForEl(el); 4562 document.body.removeChild(el); 4563 return res; 4564 } 4565 // WARNING: will include border 4566 function computeScrollbarWidthsForEl(el) { 4567 return { 4568 x: el.offsetHeight - el.clientHeight, 4569 y: el.offsetWidth - el.clientWidth, 4570 }; 4571 } 4572 4573 function computeEdges(el, getPadding) { 4574 if (getPadding === void 0) { getPadding = false; } 4575 var computedStyle = window.getComputedStyle(el); 4576 var borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 4577 var borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 4578 var borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 4579 var borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 4580 var badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border! 4581 var scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight; 4582 var scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom; 4583 var res = { 4584 borderLeft: borderLeft, 4585 borderRight: borderRight, 4586 borderTop: borderTop, 4587 borderBottom: borderBottom, 4588 scrollbarBottom: scrollbarBottom, 4589 scrollbarLeft: 0, 4590 scrollbarRight: 0, 4591 }; 4592 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side? 4593 res.scrollbarLeft = scrollbarLeftRight; 4594 } 4595 else { 4596 res.scrollbarRight = scrollbarLeftRight; 4597 } 4598 if (getPadding) { 4599 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 4600 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 4601 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 4602 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 4603 } 4604 return res; 4605 } 4606 function computeInnerRect(el, goWithinPadding, doFromWindowViewport) { 4607 if (goWithinPadding === void 0) { goWithinPadding = false; } 4608 var outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el); 4609 var edges = computeEdges(el, goWithinPadding); 4610 var res = { 4611 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 4612 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 4613 top: outerRect.top + edges.borderTop, 4614 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom, 4615 }; 4616 if (goWithinPadding) { 4617 res.left += edges.paddingLeft; 4618 res.right -= edges.paddingRight; 4619 res.top += edges.paddingTop; 4620 res.bottom -= edges.paddingBottom; 4621 } 4622 return res; 4623 } 4624 function computeRect(el) { 4625 var rect = el.getBoundingClientRect(); 4626 return { 4627 left: rect.left + window.pageXOffset, 4628 top: rect.top + window.pageYOffset, 4629 right: rect.right + window.pageXOffset, 4630 bottom: rect.bottom + window.pageYOffset, 4631 }; 4632 } 4633 function computeClippedClientRect(el) { 4634 var clippingParents = getClippingParents(el); 4635 var rect = el.getBoundingClientRect(); 4636 for (var _i = 0, clippingParents_1 = clippingParents; _i < clippingParents_1.length; _i++) { 4637 var clippingParent = clippingParents_1[_i]; 4638 var intersection = intersectRects(rect, clippingParent.getBoundingClientRect()); 4639 if (intersection) { 4640 rect = intersection; 4641 } 4642 else { 4643 return null; 4644 } 4645 } 4646 return rect; 4647 } 4648 function computeHeightAndMargins(el) { 4649 return el.getBoundingClientRect().height + computeVMargins(el); 4650 } 4651 function computeVMargins(el) { 4652 var computed = window.getComputedStyle(el); 4653 return parseInt(computed.marginTop, 10) + 4654 parseInt(computed.marginBottom, 10); 4655 } 4656 // does not return window 4657 function getClippingParents(el) { 4658 var parents = []; 4659 while (el instanceof HTMLElement) { // will stop when gets to document or null 4660 var computedStyle = window.getComputedStyle(el); 4661 if (computedStyle.position === 'fixed') { 4662 break; 4663 } 4664 if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) { 4665 parents.push(el); 4666 } 4667 el = el.parentNode; 4668 } 4669 return parents; 4670 } 4671 4672 // given a function that resolves a result asynchronously. 4673 // the function can either call passed-in success and failure callbacks, 4674 // or it can return a promise. 4675 // if you need to pass additional params to func, bind them first. 4676 function unpromisify(func, success, failure) { 4677 // guard against success/failure callbacks being called more than once 4678 // and guard against a promise AND callback being used together. 4679 var isResolved = false;
4680 var wrappedSuccess = function () { 4681 if (!isResolved) { 4682 isResolved = true; 4683 success.apply(this, arguments); // eslint-disable-line prefer-rest-params 4684 } 4685 }; 4686 var wrappedFailure = function () { 4687 if (!isResolved) { 4688 isResolved = true; 4689 if (failure) { 4690 failure.apply(this, arguments); // eslint-disable-line prefer-rest-params 4691 } 4692 } 4693 }; 4694 var res = func(wrappedSuccess, wrappedFailure); 4695 if (res && typeof res.then === 'function') { 4696 res.then(wrappedSuccess, wrappedFailure); 4697 } 4698 } 4699 4700 var Emitter = /** @class */ (function () { 4701 function Emitter() { 4702 this.handlers = {}; 4703 this.thisContext = null; 4704 } 4705 Emitter.prototype.setThisContext = function (thisContext) { 4706 this.thisContext = thisContext; 4707 }; 4708 Emitter.prototype.setOptions = function (options) { 4709 this.options = options; 4710 }; 4711 Emitter.prototype.on = function (type, handler) { 4712 addToHash(this.handlers, type, handler); 4713 }; 4714 Emitter.prototype.off = function (type, handler) { 4715 removeFromHash(this.handlers, type, handler); 4716 }; 4717 Emitter.prototype.trigger = function (type) { 4718 var args = []; 4719 for (var _i = 1; _i < arguments.length; _i++) { 4720 args[_i - 1] = arguments[_i]; 4721 } 4722 var attachedHandlers = this.handlers[type] || []; 4723 var optionHandler = this.options && this.options[type]; 4724 var handlers = [].concat(optionHandler || [], attachedHandlers); 4725 for (var _a = 0, handlers_1 = handlers; _a < handlers_1.length; _a++) { 4726 var handler = handlers_1[_a]; 4727 handler.apply(this.thisContext, args); 4728 } 4729 }; 4730 Emitter.prototype.hasHandlers = function (type) { 4731 return (this.handlers[type] && this.handlers[type].length) || 4732 (this.options && this.options[type]); 4733 }; 4734 return Emitter; 4735 }()); 4736 function addToHash(hash, type, handler) { 4737 (hash[type] || (hash[type] = [])) 4738 .push(handler); 4739 } 4740 function removeFromHash(hash, type, handler) { 4741 if (handler) { 4742 if (hash[type]) { 4743 hash[type] = hash[type].filter(function (func) { return func !== handler; }); 4744 } 4745 } 4746 else { 4747 delete hash[type]; // remove all handler funcs for this type 4748 } 4749 } 4750 4751 /* 4752 Records offset information for a set of elements, relative to an origin element. 4753 Can record the left/right OR the top/bottom OR both. 4754 Provides methods for querying the cache by position. 4755 */ 4756 var PositionCache = /** @class */ (function () { 4757 function PositionCache(originEl, els, isHorizontal, isVertical) { 4758 this.els = els; 4759 var originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left 4760 if (isHorizontal) { 4761 this.buildElHorizontals(originClientRect.left); 4762 } 4763 if (isVertical) { 4764 this.buildElVerticals(originClientRect.top); 4765 } 4766 } 4767 // Populates the left/right internal coordinate arrays 4768 PositionCache.prototype.buildElHorizontals = function (originClientLeft) { 4769 var lefts = []; 4770 var rights = []; 4771 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4772 var el = _a[_i]; 4773 var rect = el.getBoundingClientRect(); 4774 lefts.push(rect.left - originClientLeft); 4775 rights.push(rect.right - originClientLeft); 4776 } 4777 this.lefts = lefts; 4778 this.rights = rights; 4779 }; 4780 // Populates the top/bottom internal coordinate arrays 4781 PositionCache.prototype.buildElVerticals = function (originClientTop) { 4782 var tops = []; 4783 var bottoms = []; 4784 for (var _i = 0, _a = this.els; _i < _a.length; _i++) { 4785 var el = _a[_i]; 4786 var rect = el.getBoundingClientRect(); 4787 tops.push(rect.top - originClientTop); 4788 bottoms.push(rect.bottom - originClientTop); 4789 } 4790 this.tops = tops; 4791 this.bottoms = bottoms; 4792 }; 4793 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 4794 // If no intersection is made, returns undefined. 4795 PositionCache.prototype.leftToIndex = function (leftPosition) { 4796 var _a = this, lefts = _a.lefts, rights = _a.rights; 4797 var len = lefts.length; 4798 var i; 4799 for (i = 0; i < len; i += 1) { 4800 if (leftPosition >= lefts[i] && leftPosition < rights[i]) { 4801 return i; 4802 } 4803 } 4804 return undefined; // TODO: better 4805 }; 4806 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 4807 // If no intersection is made, returns undefined. 4808 PositionCache.prototype.topToIndex = function (topPosition) { 4809 var _a = this, tops = _a.tops, bottoms = _a.bottoms; 4810 var len = tops.length; 4811 var i; 4812 for (i = 0; i < len; i += 1) { 4813 if (topPosition >= tops[i] && topPosition < bottoms[i]) { 4814 return i; 4815 } 4816 } 4817 return undefined; // TODO: better 4818 }; 4819 // Gets the width of the element at the given index 4820 PositionCache.prototype.getWidth = function (leftIndex) { 4821 return this.rights[leftIndex] - this.lefts[leftIndex]; 4822 }; 4823 // Gets the height of the element at the given index 4824 PositionCache.prototype.getHeight = function (topIndex) { 4825 return this.bottoms[topIndex] - this.tops[topIndex]; 4826 }; 4827 return PositionCache; 4828 }()); 4829
4830 /* eslint max-classes-per-file: "off" */ 4831 /* 4832 An object for getting/setting scroll-related information for an element. 4833 Internally, this is done very differently for window versus DOM element, 4834 so this object serves as a common interface. 4835 */ 4836 var ScrollController = /** @class */ (function () { 4837 function ScrollController() { 4838 } 4839 ScrollController.prototype.getMaxScrollTop = function () { 4840 return this.getScrollHeight() - this.getClientHeight(); 4841 }; 4842 ScrollController.prototype.getMaxScrollLeft = function () { 4843 return this.getScrollWidth() - this.getClientWidth(); 4844 }; 4845 ScrollController.prototype.canScrollVertically = function () { 4846 return this.getMaxScrollTop() > 0; 4847 }; 4848 ScrollController.prototype.canScrollHorizontally = function () { 4849 return this.getMaxScrollLeft() > 0; 4850 }; 4851 ScrollController.prototype.canScrollUp = function () { 4852 return this.getScrollTop() > 0; 4853 }; 4854 ScrollController.prototype.canScrollDown = function () { 4855 return this.getScrollTop() < this.getMaxScrollTop(); 4856 }; 4857 ScrollController.prototype.canScrollLeft = function () { 4858 return this.getScrollLeft() > 0; 4859 }; 4860 ScrollController.prototype.canScrollRight = function () { 4861 return this.getScrollLeft() < this.getMaxScrollLeft(); 4862 }; 4863 return ScrollController; 4864 }()); 4865 var ElementScrollController = /** @class */ (function (_super) { 4866 __extends(ElementScrollController, _super); 4867 function ElementScrollController(el) { 4868 var _this = _super.call(this) || this; 4869 _this.el = el; 4870 return _this; 4871 } 4872 ElementScrollController.prototype.getScrollTop = function () { 4873 return this.el.scrollTop; 4874 }; 4875 ElementScrollController.prototype.getScrollLeft = function () { 4876 return this.el.scrollLeft; 4877 }; 4878 ElementScrollController.prototype.setScrollTop = function (top) { 4879 this.el.scrollTop = top; 4880 }; 4881 ElementScrollController.prototype.setScrollLeft = function (left) { 4882 this.el.scrollLeft = left; 4883 }; 4884 ElementScrollController.prototype.getScrollWidth = function () { 4885 return this.el.scrollWidth; 4886 }; 4887 ElementScrollController.prototype.getScrollHeight = function () { 4888 return this.el.scrollHeight; 4889 }; 4890 ElementScrollController.prototype.getClientHeight = function () { 4891 return this.el.clientHeight; 4892 }; 4893 ElementScrollController.prototype.getClientWidth = function () { 4894 return this.el.clientWidth; 4895 }; 4896 return ElementScrollController; 4897 }(ScrollController)); 4898 var WindowScrollController = /** @class */ (function (_super) { 4899 __extends(WindowScrollController, _super); 4900 function WindowScrollController() { 4901 return _super !== null && _super.apply(this, arguments) || this; 4902 } 4903 WindowScrollController.prototype.getScrollTop = function () { 4904 return window.pageYOffset; 4905 }; 4906 WindowScrollController.prototype.getScrollLeft = function () { 4907 return window.pageXOffset; 4908 }; 4909 WindowScrollController.prototype.setScrollTop = function (n) { 4910 window.scroll(window.pageXOffset, n); 4911 }; 4912 WindowScrollController.prototype.setScrollLeft = function (n) { 4913 window.scroll(n, window.pageYOffset); 4914 }; 4915 WindowScrollController.prototype.getScrollWidth = function () { 4916 return document.documentElement.scrollWidth; 4917 }; 4918 WindowScrollController.prototype.getScrollHeight = function () { 4919 return document.documentElement.scrollHeight; 4920 }; 4921 WindowScrollController.prototype.getClientHeight = function () { 4922 return document.documentElement.clientHeight; 4923 }; 4924 WindowScrollController.prototype.getClientWidth = function () { 4925 return document.documentElement.clientWidth; 4926 }; 4927 return WindowScrollController; 4928 }(ScrollController)); 4929 4930 var Theme = /** @class */ (function () { 4931 function Theme(calendarOptions) { 4932 if (this.iconOverrideOption) { 4933 this.setIconOverride(calendarOptions[this.iconOverrideOption]); 4934 } 4935 } 4936 Theme.prototype.setIconOverride = function (iconOverrideHash) { 4937 var iconClassesCopy; 4938 var buttonName; 4939 if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object 4940 iconClassesCopy = __assign({}, this.iconClasses); 4941 for (buttonName in iconOverrideHash) { 4942 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 4943 } 4944 this.iconClasses = iconClassesCopy; 4945 } 4946 else if (iconOverrideHash === false) { 4947 this.iconClasses = {}; 4948 } 4949 }; 4950 Theme.prototype.applyIconOverridePrefix = function (className) { 4951 var prefix = this.iconOverridePrefix; 4952 if (prefix && className.indexOf(prefix) !== 0) { // if not already present 4953 className = prefix + className; 4954 } 4955 return className; 4956 }; 4957 Theme.prototype.getClass = function (key) { 4958 return this.classes[key] || ''; 4959 }; 4960 Theme.prototype.getIconClass = function (buttonName, isRtl) { 4961 var className; 4962 if (isRtl && this.rtlIconClasses) { 4963 className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName]; 4964 } 4965 else { 4966 className = this.iconClasses[buttonName]; 4967 } 4968 if (className) { 4969 return this.baseIconClass + " " + className; 4970 } 4971 return ''; 4972 }; 4973 Theme.prototype.getCustomButtonIconClass = function (customButtonProps) { 4974 var className; 4975 if (this.iconOverrideCustomButtonOption) { 4976 className = customButtonProps[this.iconOverrideCustomButtonOption]; 4977 if (className) { 4978 return this.baseIconClass + " " + this.applyIconOverridePrefix(className); 4979 } 4980 } 4981 return ''; 4982 }; 4983 return Theme; 4984 }()); 4985 Theme.prototype.classes = {}; 4986 Theme.prototype.iconClasses = {}; 4987 Theme.prototype.baseIconClass = ''; 4988 Theme.prototype.iconOverridePrefix = ''; 4989 4990 /// <reference types="@fullcalendar/core-preact" /> 4991 if (typeof FullCalendarVDom === 'undefined') { 4992 throw new Error('Please import the top-level fullcalendar lib before attempting to import a plugin.'); 4993 } 4994 var Component = FullCalendarVDom.Component; 4995 var createElement = FullCalendarVDom.createElement; 4996 var render = FullCalendarVDom.render; 4997 var createRef = FullCalendarVDom.createRef; 4998 var Fragment = FullCalendarVDom.Fragment; 4999 var createContext = FullCalendarVDom.createContext; 5000 var createPortal = FullCalendarVDom.createPortal; 5001 var flushToDom = FullCalendarVDom.flushToDom; 5002 var unmountComponentAtNode = FullCalendarVDom.unmountComponentAtNode; 5003 /* eslint-enable */ 5004 5005 var ScrollResponder = /** @class */ (function () { 5006 function ScrollResponder(execFunc, emitter, scrollTime, scrollTimeReset) { 5007 var _this = this; 5008 this.execFunc = execFunc; 5009 this.emitter = emitter; 5010 this.scrollTime = scrollTime; 5011 this.scrollTimeReset = scrollTimeReset; 5012 this.handleScrollRequest = function (request) { 5013 _this.queuedRequest = __assign({}, _this.queuedRequest || {}, request); 5014 _this.drain(); 5015 }; 5016 emitter.on('_scrollRequest', this.handleScrollRequest); 5017 this.fireInitialScroll(); 5018 } 5019 ScrollResponder.prototype.detach = function () { 5020 this.emitter.off('_scrollRequest', this.handleScrollRequest); 5021 }; 5022 ScrollResponder.prototype.update = function (isDatesNew) { 5023 if (isDatesNew && this.scrollTimeReset) { 5024 this.fireInitialScroll(); // will drain 5025 } 5026 else { 5027 this.drain(); 5028 } 5029 }; 5030 ScrollResponder.prototype.fireInitialScroll = function () { 5031 this.handleScrollRequest({ 5032 time: this.scrollTime, 5033 }); 5034 };
5035 ScrollResponder.prototype.drain = function () { 5036 if (this.queuedRequest && this.execFunc(this.queuedRequest)) { 5037 this.queuedRequest = null; 5038 } 5039 }; 5040 return ScrollResponder; 5041 }()); 5042 5043 var ViewContextType = createContext({}); // for Components 5044 function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) { 5045 return { 5046 dateEnv: dateEnv, 5047 options: viewOptions, 5048 pluginHooks: pluginHooks, 5049 emitter: emitter, 5050 dispatch: dispatch, 5051 getCurrentData: getCurrentData, 5052 calendarApi: calendarApi, 5053 viewSpec: viewSpec, 5054 viewApi: viewApi, 5055 dateProfileGenerator: dateProfileGenerator, 5056 theme: theme, 5057 isRtl: viewOptions.direction === 'rtl', 5058 addResizeHandler: function (handler) { 5059 emitter.on('_resize', handler); 5060 }, 5061 removeResizeHandler: function (handler) { 5062 emitter.off('_resize', handler); 5063 }, 5064 createScrollResponder: function (execFunc) { 5065 return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset); 5066 }, 5067 registerInteractiveComponent: registerInteractiveComponent, 5068 unregisterInteractiveComponent: unregisterInteractiveComponent, 5069 }; 5070 } 5071 5072 /* eslint max-classes-per-file: off */ 5073 var PureComponent = /** @class */ (function (_super) { 5074 __extends(PureComponent, _super); 5075 function PureComponent() { 5076 return _super !== null && _super.apply(this, arguments) || this; 5077 } 5078 PureComponent.prototype.shouldComponentUpdate = function (nextProps, nextState) { 5079 if (this.debug) { 5080 // eslint-disable-next-line no-console 5081 console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state)); 5082 } 5083 return !compareObjs(this.props, nextProps, this.propEquality) || 5084 !compareObjs(this.state, nextState, this.stateEquality); 5085 }; 5086 PureComponent.addPropsEquality = addPropsEquality; 5087 PureComponent.addStateEquality = addStateEquality; 5088 PureComponent.contextType = ViewContextType; 5089 return PureComponent; 5090 }(Component)); 5091 PureComponent.prototype.propEquality = {}; 5092 PureComponent.prototype.stateEquality = {}; 5093 var BaseComponent = /** @class */ (function (_super) { 5094 __extends(BaseComponent, _super); 5095 function BaseComponent() { 5096 return _super !== null && _super.apply(this, arguments) || this; 5097 } 5098 BaseComponent.contextType = ViewContextType; 5099 return BaseComponent; 5100 }(PureComponent)); 5101 function addPropsEquality(propEquality) { 5102 var hash = Object.create(this.prototype.propEquality); 5103 __assign(hash, propEquality); 5104 this.prototype.propEquality = hash; 5105 } 5106 function addStateEquality(stateEquality) { 5107 var hash = Object.create(this.prototype.stateEquality); 5108 __assign(hash, stateEquality); 5109 this.prototype.stateEquality = hash; 5110 } 5111 // use other one 5112 function setRef(ref, current) { 5113 if (typeof ref === 'function') { 5114 ref(current); 5115 } 5116 else if (ref) { 5117 // see https://github.com/facebook/react/issues/13029 5118 ref.current = current; 5119 } 5120 } 5121 5122 /* 5123 an INTERACTABLE date component 5124 5125 PURPOSES: 5126 - hook up to fg, fill, and mirror renderers 5127 - interface for dragging and hits 5128 */ 5129 var DateComponent = /** @class */ (function (_super) { 5130 __extends(DateComponent, _super); 5131 function DateComponent() { 5132 var _this = _super !== null && _super.apply(this, arguments) || this; 5133 _this.uid = guid(); 5134 return _this; 5135 } 5136 // Hit System 5137 // ----------------------------------------------------------------------------------------------------------------- 5138 DateComponent.prototype.prepareHits = function () { 5139 }; 5140 DateComponent.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 5141 return null; // this should be abstract 5142 }; 5143 // Pointer Interaction Utils 5144 // ----------------------------------------------------------------------------------------------------------------- 5145 DateComponent.prototype.isValidSegDownEl = function (el) { 5146 return !this.props.eventDrag && // HACK 5147 !this.props.eventResize && // HACK 5148 !elementClosest(el, '.fc-event-mirror'); 5149 }; 5150 DateComponent.prototype.isValidDateDownEl = function (el) { 5151 return !elementClosest(el, '.fc-event:not(.fc-bg-event)') && 5152 !elementClosest(el, '.fc-more-link') && // a "more.." link 5153 !elementClosest(el, 'a[data-navlink]') && // a clickable nav link 5154 !elementClosest(el, '.fc-popover'); // hack 5155 }; 5156 return DateComponent; 5157 }(BaseComponent)); 5158 5159 // TODO: easier way to add new hooks? need to update a million things 5160 function createPlugin(input) { 5161 return { 5162 id: guid(), 5163 deps: input.deps || [], 5164 reducers: input.reducers || [], 5165 isLoadingFuncs: input.isLoadingFuncs || [], 5166 contextInit: [].concat(input.contextInit || []), 5167 eventRefiners: input.eventRefiners || {}, 5168 eventDefMemberAdders: input.eventDefMemberAdders || [], 5169 eventSourceRefiners: input.eventSourceRefiners || {}, 5170 isDraggableTransformers: input.isDraggableTransformers || [], 5171 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 5172 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 5173 dateSelectionTransformers: input.dateSelectionTransformers || [], 5174 datePointTransforms: input.datePointTransforms || [], 5175 dateSpanTransforms: input.dateSpanTransforms || [], 5176 views: input.views || {}, 5177 viewPropsTransformers: input.viewPropsTransformers || [], 5178 isPropsValid: input.isPropsValid || null, 5179 externalDefTransforms: input.externalDefTransforms || [], 5180 viewContainerAppends: input.viewContainerAppends || [], 5181 eventDropTransformers: input.eventDropTransformers || [], 5182 componentInteractions: input.componentInteractions || [], 5183 calendarInteractions: input.calendarInteractions || [],
5184 themeClasses: input.themeClasses || {}, 5185 eventSourceDefs: input.eventSourceDefs || [], 5186 cmdFormatter: input.cmdFormatter, 5187 recurringTypes: input.recurringTypes || [], 5188 namedTimeZonedImpl: input.namedTimeZonedImpl, 5189 initialView: input.initialView || '', 5190 elementDraggingImpl: input.elementDraggingImpl, 5191 optionChangeHandlers: input.optionChangeHandlers || {}, 5192 scrollGridImpl: input.scrollGridImpl || null, 5193 contentTypeHandlers: input.contentTypeHandlers || {}, 5194 listenerRefiners: input.listenerRefiners || {}, 5195 optionRefiners: input.optionRefiners || {}, 5196 propSetHandlers: input.propSetHandlers || {}, 5197 }; 5198 } 5199 function buildPluginHooks(pluginDefs, globalDefs) { 5200 var isAdded = {}; 5201 var hooks = { 5202 reducers: [], 5203 isLoadingFuncs: [], 5204 contextInit: [], 5205 eventRefiners: {}, 5206 eventDefMemberAdders: [], 5207 eventSourceRefiners: {}, 5208 isDraggableTransformers: [], 5209 eventDragMutationMassagers: [], 5210 eventDefMutationAppliers: [], 5211 dateSelectionTransformers: [], 5212 datePointTransforms: [], 5213 dateSpanTransforms: [], 5214 views: {}, 5215 viewPropsTransformers: [], 5216 isPropsValid: null, 5217 externalDefTransforms: [], 5218 viewContainerAppends: [], 5219 eventDropTransformers: [], 5220 componentInteractions: [], 5221 calendarInteractions: [], 5222 themeClasses: {}, 5223 eventSourceDefs: [], 5224 cmdFormatter: null, 5225 recurringTypes: [], 5226 namedTimeZonedImpl: null, 5227 initialView: '', 5228 elementDraggingImpl: null, 5229 optionChangeHandlers: {}, 5230 scrollGridImpl: null, 5231 contentTypeHandlers: {}, 5232 listenerRefiners: {}, 5233 optionRefiners: {}, 5234 propSetHandlers: {}, 5235 }; 5236 function addDefs(defs) { 5237 for (var _i = 0, defs_1 = defs; _i < defs_1.length; _i++) { 5238 var def = defs_1[_i]; 5239 if (!isAdded[def.id]) { 5240 isAdded[def.id] = true; 5241 addDefs(def.deps); 5242 hooks = combineHooks(hooks, def); 5243 } 5244 } 5245 } 5246 if (pluginDefs) { 5247 addDefs(pluginDefs); 5248 } 5249 addDefs(globalDefs); 5250 return hooks; 5251 } 5252 function buildBuildPluginHooks() { 5253 var currentOverrideDefs = []; 5254 var currentGlobalDefs = []; 5255 var currentHooks; 5256 return function (overrideDefs, globalDefs) { 5257 if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) { 5258 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 5259 } 5260 currentOverrideDefs = overrideDefs; 5261 currentGlobalDefs = globalDefs; 5262 return currentHooks; 5263 }; 5264 } 5265 function combineHooks(hooks0, hooks1) { 5266 return { 5267 reducers: hooks0.reducers.concat(hooks1.reducers), 5268 isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs), 5269 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 5270 eventRefiners: __assign(__assign({}, hooks0.eventRefiners), hooks1.eventRefiners), 5271 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders), 5272 eventSourceRefiners: __assign(__assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners), 5273 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 5274 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 5275 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 5276 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 5277 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 5278 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 5279 views: __assign(__assign({}, hooks0.views), hooks1.views), 5280 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 5281 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 5282 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 5283 viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends), 5284 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 5285 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 5286 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
5287 themeClasses: __assign(__assign({}, hooks0.themeClasses), hooks1.themeClasses), 5288 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 5289 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 5290 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 5291 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 5292 initialView: hooks0.initialView || hooks1.initialView, 5293 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 5294 optionChangeHandlers: __assign(__assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers), 5295 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 5296 contentTypeHandlers: __assign(__assign({}, hooks0.contentTypeHandlers), hooks1.contentTypeHandlers), 5297 listenerRefiners: __assign(__assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners), 5298 optionRefiners: __assign(__assign({}, hooks0.optionRefiners), hooks1.optionRefiners), 5299 propSetHandlers: __assign(__assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers), 5300 }; 5301 } 5302 5303 var StandardTheme = /** @class */ (function (_super) { 5304 __extends(StandardTheme, _super); 5305 function StandardTheme() { 5306 return _super !== null && _super.apply(this, arguments) || this; 5307 } 5308 return StandardTheme; 5309 }(Theme)); 5310 StandardTheme.prototype.classes = { 5311 root: 'fc-theme-standard', 5312 tableCellShaded: 'fc-cell-shaded', 5313 buttonGroup: 'fc-button-group', 5314 button: 'fc-button fc-button-primary', 5315 buttonActive: 'fc-button-active', 5316 }; 5317 StandardTheme.prototype.baseIconClass = 'fc-icon'; 5318 StandardTheme.prototype.iconClasses = { 5319 close: 'fc-icon-x', 5320 prev: 'fc-icon-chevron-left', 5321 next: 'fc-icon-chevron-right', 5322 prevYear: 'fc-icon-chevrons-left', 5323 nextYear: 'fc-icon-chevrons-right', 5324 }; 5325 StandardTheme.prototype.rtlIconClasses = { 5326 prev: 'fc-icon-chevron-right', 5327 next: 'fc-icon-chevron-left', 5328 prevYear: 'fc-icon-chevrons-right', 5329 nextYear: 'fc-icon-chevrons-left', 5330 }; 5331 StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly 5332 StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon'; 5333 StandardTheme.prototype.iconOverridePrefix = 'fc-icon-'; 5334 5335 function compileViewDefs(defaultConfigs, overrideConfigs) { 5336 var hash = {}; 5337 var viewType; 5338 for (viewType in defaultConfigs) { 5339 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5340 } 5341 for (viewType in overrideConfigs) { 5342 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5343 } 5344 return hash; 5345 } 5346 function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5347 if (hash[viewType]) { 5348 return hash[viewType]; 5349 } 5350 var viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 5351 if (viewDef) { 5352 hash[viewType] = viewDef; 5353 } 5354 return viewDef; 5355 } 5356 function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 5357 var defaultConfig = defaultConfigs[viewType]; 5358 var overrideConfig = overrideConfigs[viewType]; 5359 var queryProp = function (name) { return ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] : 5360 ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null)); }; 5361 var theComponent = queryProp('component'); 5362 var superType = queryProp('superType'); 5363 var superDef = null; 5364 if (superType) { 5365 if (superType === viewType) { 5366 throw new Error('Can\'t have a custom view type that references itself'); 5367 } 5368 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 5369 } 5370 if (!theComponent && superDef) { 5371 theComponent = superDef.component; 5372 } 5373 if (!theComponent) { 5374 return null; // don't throw a warning, might be settings for a single-unit view 5375 } 5376 return { 5377 type: viewType, 5378 component: theComponent, 5379 defaults: __assign(__assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})), 5380 overrides: __assign(__assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})), 5381 }; 5382 } 5383
5384 /* eslint max-classes-per-file: off */ 5385 // NOTE: in JSX, you should always use this class with <HookProps> arg. otherwise, will default to any??? 5386 var RenderHook = /** @class */ (function (_super) { 5387 __extends(RenderHook, _super); 5388 function RenderHook() { 5389 var _this = _super !== null && _super.apply(this, arguments) || this; 5390 _this.rootElRef = createRef(); 5391 _this.handleRootEl = function (el) { 5392 setRef(_this.rootElRef, el); 5393 if (_this.props.elRef) { 5394 setRef(_this.props.elRef, el); 5395 } 5396 }; 5397 return _this; 5398 } 5399 RenderHook.prototype.render = function () { 5400 var _this = this; 5401 var props = this.props; 5402 var hookProps = props.hookProps; 5403 return (createElement(MountHook, { hookProps: hookProps, didMount: props.didMount, willUnmount: props.willUnmount, elRef: this.handleRootEl }, function (rootElRef) { return (createElement(ContentHook, { hookProps: hookProps, content: props.content, defaultContent: props.defaultContent, backupElRef: _this.rootElRef }, function (innerElRef, innerContent) { return props.children(rootElRef, normalizeClassNames(props.classNames, hookProps), innerElRef, innerContent); })); })); 5404 }; 5405 return RenderHook; 5406 }(BaseComponent)); 5407 // TODO: rename to be about function, not default. use in above type 5408 // for forcing rerender of components that use the ContentHook 5409 var CustomContentRenderContext = createContext(0); 5410 function ContentHook(props) { 5411 return (createElement(CustomContentRenderContext.Consumer, null, function (renderId) { return (createElement(ContentHookInner, __assign({ renderId: renderId }, props))); })); 5412 } 5413 var ContentHookInner = /** @class */ (function (_super) { 5414 __extends(ContentHookInner, _super); 5415 function ContentHookInner() { 5416 var _this = _super !== null && _super.apply(this, arguments) || this; 5417 _this.innerElRef = createRef(); 5418 return _this; 5419 } 5420 ContentHookInner.prototype.render = function () { 5421 return this.props.children(this.innerElRef, this.renderInnerContent()); 5422 }; 5423 ContentHookInner.prototype.componentDidMount = function () { 5424 this.updateCustomContent(); 5425 }; 5426 ContentHookInner.prototype.componentDidUpdate = function () { 5427 this.updateCustomContent(); 5428 }; 5429 ContentHookInner.prototype.componentWillUnmount = function () { 5430 if (this.customContentInfo && this.customContentInfo.destroy) { 5431 this.customContentInfo.destroy(); 5432 } 5433 }; 5434 ContentHookInner.prototype.renderInnerContent = function () { 5435 var contentTypeHandlers = this.context.pluginHooks.contentTypeHandlers; 5436 var _a = this, props = _a.props, customContentInfo = _a.customContentInfo; 5437 var rawVal = props.content; 5438 var innerContent = normalizeContent(rawVal, props.hookProps); 5439 var innerContentVDom = null; 5440 if (innerContent === undefined) { // use the default 5441 innerContent = normalizeContent(props.defaultContent, props.hookProps); 5442 } 5443 if (innerContent !== undefined) { // we allow custom content handlers to return nothing 5444 if (customContentInfo) { 5445 customContentInfo.contentVal = innerContent[customContentInfo.contentKey]; 5446 } 5447 else if (typeof innerContent === 'object') { 5448 // look for a prop that would indicate a custom content handler is needed 5449 for (var contentKey in contentTypeHandlers) { 5450 if (innerContent[contentKey] !== undefined) { 5451 var stuff = contentTypeHandlers[contentKey](); 5452 customContentInfo = this.customContentInfo = __assign({ contentKey: contentKey, contentVal: innerContent[contentKey] }, stuff); 5453 break; 5454 } 5455 } 5456 } 5457 if (customContentInfo) { 5458 innerContentVDom = []; // signal that something was specified 5459 } 5460 else { 5461 innerContentVDom = innerContent; // assume a [p]react vdom node. use it 5462 } 5463 } 5464 return innerContentVDom; 5465 }; 5466 ContentHookInner.prototype.updateCustomContent = function () { 5467 if (this.customContentInfo) { 5468 this.customContentInfo.render(this.innerElRef.current || this.props.backupElRef.current, // the element to render into 5469 this.customContentInfo.contentVal); 5470 } 5471 }; 5472 return ContentHookInner; 5473 }(BaseComponent)); 5474 var MountHook = /** @class */ (function (_super) { 5475 __extends(MountHook, _super); 5476 function MountHook() { 5477 var _this = _super !== null && _super.apply(this, arguments) || this; 5478 _this.handleRootEl = function (rootEl) { 5479 _this.rootEl = rootEl; 5480 if (_this.props.elRef) { 5481 setRef(_this.props.elRef, rootEl); 5482 } 5483 }; 5484 return _this; 5485 } 5486 MountHook.prototype.render = function () { 5487 return this.props.children(this.handleRootEl); 5488 }; 5489 MountHook.prototype.componentDidMount = function () { 5490 var callback = this.props.didMount; 5491 if (callback) { 5492 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5493 } 5494 }; 5495 MountHook.prototype.componentWillUnmount = function () { 5496 var callback = this.props.willUnmount; 5497 if (callback) { 5498 callback(__assign(__assign({}, this.props.hookProps), { el: this.rootEl })); 5499 } 5500 }; 5501 return MountHook; 5502 }(BaseComponent)); 5503 function buildClassNameNormalizer() { 5504 var currentGenerator; 5505 var currentHookProps; 5506 var currentClassNames = []; 5507 return function (generator, hookProps) { 5508 if (!currentHookProps || !isPropsEqual(currentHookProps, hookProps) || generator !== currentGenerator) { 5509 currentGenerator = generator; 5510 currentHookProps = hookProps; 5511 currentClassNames = normalizeClassNames(generator, hookProps); 5512 } 5513 return currentClassNames; 5514 }; 5515 } 5516 function normalizeClassNames(classNames, hookProps) { 5517 if (typeof classNames === 'function') { 5518 classNames = classNames(hookProps); 5519 } 5520 return parseClassNames(classNames); 5521 } 5522 function normalizeContent(input, hookProps) { 5523 if (typeof input === 'function') { 5524 return input(hookProps, createElement); // give the function the vdom-creation func 5525 } 5526 return input; 5527 } 5528 5529 var ViewRoot = /** @class */ (function (_super) { 5530 __extends(ViewRoot, _super); 5531 function ViewRoot() { 5532 var _this = _super !== null && _super.apply(this, arguments) || this; 5533 _this.normalizeClassNames = buildClassNameNormalizer(); 5534 return _this; 5535 } 5536 ViewRoot.prototype.render = function () { 5537 var _a = this, props = _a.props, context = _a.context; 5538 var options = context.options; 5539 var hookProps = { view: context.viewApi }; 5540 var customClassNames = this.normalizeClassNames(options.viewClassNames, hookProps); 5541 return (createElement(MountHook, { hookProps: hookProps, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, ["fc-" + props.viewSpec.type + "-view", 'fc-view'].concat(customClassNames)); })); 5542 }; 5543 return ViewRoot; 5544 }(BaseComponent)); 5545 5546 function parseViewConfigs(inputs) { 5547 return mapHash(inputs, parseViewConfig); 5548 } 5549 function parseViewConfig(input) { 5550 var rawOptions = typeof input === 'function' ? 5551 { component: input } : 5552 input; 5553 var component = rawOptions.component; 5554 if (rawOptions.content) { 5555 component = createViewHookComponent(rawOptions); 5556 // TODO: remove content/classNames/didMount/etc from options? 5557 } 5558 return { 5559 superType: rawOptions.type, 5560 component: component, 5561 rawOptions: rawOptions, 5562 }; 5563 } 5564 function createViewHookComponent(options) { 5565 return function (viewProps) { return (createElement(ViewContextType.Consumer, null, function (context) { return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (viewElRef, viewClassNames) { 5566 var hookProps = __assign(__assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }); 5567 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.classNames, content: options.content, didMount: options.didMount, willUnmount: options.willUnmount, elRef: viewElRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("div", { className: viewClassNames.c
5567oncat(customClassNames).join(' '), ref: rootElRef }, innerContent)); })); 5568 })); })); }; 5569 } 5570 5571 function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5572 var defaultConfigs = parseViewConfigs(defaultInputs); 5573 var overrideConfigs = parseViewConfigs(optionOverrides.views); 5574 var viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 5575 return mapHash(viewDefs, function (viewDef) { return buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults); }); 5576 } 5577 function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 5578 var durationInput = viewDef.overrides.duration || 5579 viewDef.defaults.duration || 5580 dynamicOptionOverrides.duration || 5581 optionOverrides.duration; 5582 var duration = null; 5583 var durationUnit = ''; 5584 var singleUnit = ''; 5585 var singleUnitOverrides = {}; 5586 if (durationInput) { 5587 duration = createDurationCached(durationInput); 5588 if (duration) { // valid? 5589 var denom = greatestDurationDenominator(duration); 5590 durationUnit = denom.unit; 5591 if (denom.value === 1) { 5592 singleUnit = durationUnit; 5593 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {}; 5594 } 5595 } 5596 } 5597 var queryButtonText = function (optionsSubset) { 5598 var buttonTextMap = optionsSubset.buttonText || {}; 5599 var buttonTextKey = viewDef.defaults.buttonTextKey; 5600 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 5601 return buttonTextMap[buttonTextKey]; 5602 } 5603 if (buttonTextMap[viewDef.type] != null) { 5604 return buttonTextMap[viewDef.type]; 5605 } 5606 if (buttonTextMap[singleUnit] != null) { 5607 return buttonTextMap[singleUnit]; 5608 } 5609 return null; 5610 }; 5611 return { 5612 type: viewDef.type, 5613 component: viewDef.component, 5614 duration: duration, 5615 durationUnit: durationUnit, 5616 singleUnit: singleUnit, 5617 optionDefaults: viewDef.defaults, 5618 optionOverrides: __assign(__assign({}, singleUnitOverrides), viewDef.overrides), 5619 buttonTextOverride: queryButtonText(dynamicOptionOverrides) || 5620 queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 5621 viewDef.overrides.buttonText, 5622 buttonTextDefault: queryButtonText(localeDefaults) || 5623 viewDef.defaults.buttonText || 5624 queryButtonText(BASE_OPTION_DEFAULTS) || 5625 viewDef.type, // fall back to given view name 5626 }; 5627 } 5628 // hack to get memoization working 5629 var durationInputMap = {}; 5630 function createDurationCached(durationInput) { 5631 var json = JSON.stringify(durationInput); 5632 var res = durationInputMap[json]; 5633 if (res === undefined) { 5634 res = createDuration(durationInput); 5635 durationInputMap[json] = res; 5636 } 5637 return res; 5638 } 5639 5640 var DateProfileGenerator = /** @class */ (function () { 5641 function DateProfileGenerator(props) { 5642 this.props = props; 5643 this.nowDate = getNow(props.nowInput, props.dateEnv); 5644 this.initHiddenDays(); 5645 } 5646 /* Date Range Computation 5647 ------------------------------------------------------------------------------------------------------------------*/ 5648 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 5649 DateProfileGenerator.prototype.buildPrev = function (currentDateProfile, currentDate, forceToValid) { 5650 var dateEnv = this.props.dateEnv; 5651 var prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5652 currentDateProfile.dateIncrement); 5653 return this.build(prevDate, -1, forceToValid); 5654 }; 5655 // Builds a structure with info about what the dates/ranges will be for the "next" view. 5656 DateProfileGenerator.prototype.buildNext = function (currentDateProfile, currentDate, forceToValid) { 5657 var dateEnv = this.props.dateEnv; 5658 var nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month 5659 currentDateProfile.dateIncrement); 5660 return this.build(nextDate, 1, forceToValid); 5661 }; 5662 // Builds a structure holding dates/ranges for rendering around the given date. 5663 // Optional direction param indicates whether the date is being incremented/decremented 5664 // from its previous value. decremented = -1, incremented = 1 (default). 5665 DateProfileGenerator.prototype.build = function (currentDate, direction, forceToValid) { 5666 if (forceToValid === void 0) { forceToValid = true; } 5667 var props = this.props;
5668 var validRange; 5669 var currentInfo; 5670 var isRangeAllDay; 5671 var renderRange; 5672 var activeRange; 5673 var isValid; 5674 validRange = this.buildValidRange(); 5675 validRange = this.trimHiddenDays(validRange); 5676 if (forceToValid) { 5677 currentDate = constrainMarkerToRange(currentDate, validRange); 5678 } 5679 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 5680 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 5681 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 5682 renderRange = this.trimHiddenDays(renderRange); 5683 activeRange = renderRange; 5684 if (!props.showNonCurrentDates) { 5685 activeRange = intersectRanges(activeRange, currentInfo.range); 5686 } 5687 activeRange = this.adjustActiveRange(activeRange); 5688 activeRange = intersectRanges(activeRange, validRange); // might return null 5689 // it's invalid if the originally requested date is not contained, 5690 // or if the range is completely outside of the valid range. 5691 isValid = rangesIntersect(currentInfo.range, validRange); 5692 return { 5693 // constraint for where prev/next operations can go and where events can be dragged/resized to. 5694 // an object with optional start and end properties. 5695 validRange: validRange, 5696 // range the view is formally responsible for. 5697 // for example, a month view might have 1st-31st, excluding padded dates 5698 currentRange: currentInfo.range, 5699 // name of largest unit being displayed, like "month" or "week" 5700 currentRangeUnit: currentInfo.unit, 5701 isRangeAllDay: isRangeAllDay, 5702 // dates that display events and accept drag-n-drop 5703 // will be `null` if no dates accept events 5704 activeRange: activeRange, 5705 // date range with a rendered skeleton 5706 // includes not-active days that need some sort of DOM 5707 renderRange: renderRange, 5708 // Duration object that denotes the first visible time of any given day 5709 slotMinTime: props.slotMinTime, 5710 // Duration object that denotes the exclusive visible end time of any given day 5711 slotMaxTime: props.slotMaxTime, 5712 isValid: isValid, 5713 // how far the current date will move for a prev/next operation 5714 dateIncrement: this.buildDateIncrement(currentInfo.duration), 5715 // pass a fallback (might be null) ^ 5716 }; 5717 }; 5718 // Builds an object with optional start/end properties. 5719 // Indicates the minimum/maximum dates to display. 5720 // not responsible for trimming hidden days. 5721 DateProfileGenerator.prototype.buildValidRange = function () { 5722 var input = this.props.validRangeInput; 5723 var simpleInput = typeof input === 'function' 5724 ? input.call(this.props.calendarApi, this.nowDate) 5725 : input; 5726 return this.refineRange(simpleInput) || 5727 { start: null, end: null }; // completely open-ended 5728 }; 5729 // Builds a structure with info about the "current" range, the range that is 5730 // highlighted as being the current month for example. 5731 // See build() for a description of `direction`. 5732 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 5733 DateProfileGenerator.prototype.buildCurrentRangeInfo = function (date, direction) { 5734 var props = this.props; 5735 var duration = null; 5736 var unit = null; 5737 var range = null; 5738 var dayCount; 5739 if (props.duration) { 5740 duration = props.duration; 5741 unit = props.durationUnit; 5742 range = this.buildRangeFromDuration(date, direction, duration, unit); 5743 } 5744 else if ((dayCount = this.props.dayCount)) { 5745 unit = 'day'; 5746 range = this.buildRangeFromDayCount(date, direction, dayCount); 5747 } 5748 else if ((range = this.buildCustomVisibleRange(date))) { 5749 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 5750 } 5751 else { 5752 duration = this.getFallbackDuration(); 5753 unit = greatestDurationDenominator(duration).unit; 5754 range = this.buildRangeFromDuration(date, direction, duration, unit); 5755 } 5756 return { duration: duration, unit: unit, range: range }; 5757 }; 5758 DateProfileGenerator.prototype.getFallbackDuration = function () { 5759 return createDuration({ day: 1 }); 5760 }; 5761 // Returns a new activeRange to have time values (un-ambiguate) 5762 // slotMinTime or slotMaxTime causes the range to expand. 5763 DateProfileGenerator.prototype.adjustActiveRange = function (range) { 5764 var _a = this.props, dateEnv = _a.dateEnv, usesMinMaxTime = _a.usesMinMaxTime, slotMinTime = _a.slotMinTime, slotMaxTime = _a.slotMaxTime; 5765 var start = range.start, end = range.end; 5766 if (usesMinMaxTime) { 5767 // expand active range if slotMinTime is negative (why not when positive?) 5768 if (asRoughDays(slotMinTime) < 0) { 5769 start = startOfDay(start); // necessary? 5770 start = dateEnv.add(start, slotMinTime); 5771 } 5772 // expand active range if slotMaxTime is beyond one day (why not when negative?) 5773 if (asRoughDays(slotMaxTime) > 1) { 5774 end = startOfDay(end); // necessary? 5775 end = addDays(end, -1); 5776 end = dateEnv.add(end, slotMaxTime); 5777 } 5778 } 5779 return { start: start, end: end }; 5780 }; 5781 // Builds the "current" range when it is specified as an explicit duration. 5782 // `unit` is the already-computed greatestDurationDenominator unit of duration. 5783 DateProfileGenerator.prototype.buildRangeFromDuration = function (date, direction, duration, unit) { 5784 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5785 var start; 5786 var end; 5787 var res; 5788 // compute what the alignment should be 5789 if (!dateAlignment) { 5790 var dateIncrement = this.props.dateIncrement; 5791 if (dateIncrement) { 5792 // use the smaller of the two units 5793 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 5794 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 5795 } 5796 else { 5797 dateAlignment = unit; 5798 } 5799 } 5800 else { 5801 dateAlignment = unit; 5802 } 5803 }
5804 // if the view displays a single day or smaller 5805 if (asRoughDays(duration) <= 1) { 5806 if (this.isHiddenDay(start)) { 5807 start = this.skipHiddenDays(start, direction); 5808 start = startOfDay(start); 5809 } 5810 } 5811 function computeRes() { 5812 start = dateEnv.startOf(date, dateAlignment); 5813 end = dateEnv.add(start, duration); 5814 res = { start: start, end: end }; 5815 } 5816 computeRes(); 5817 // if range is completely enveloped by hidden days, go past the hidden days 5818 if (!this.trimHiddenDays(res)) { 5819 date = this.skipHiddenDays(date, direction); 5820 computeRes(); 5821 } 5822 return res; 5823 }; 5824 // Builds the "current" range when a dayCount is specified. 5825 DateProfileGenerator.prototype.buildRangeFromDayCount = function (date, direction, dayCount) { 5826 var _a = this.props, dateEnv = _a.dateEnv, dateAlignment = _a.dateAlignment; 5827 var runningCount = 0; 5828 var start = date; 5829 var end; 5830 if (dateAlignment) { 5831 start = dateEnv.startOf(start, dateAlignment); 5832 } 5833 start = startOfDay(start); 5834 start = this.skipHiddenDays(start, direction); 5835 end = start; 5836 do { 5837 end = addDays(end, 1); 5838 if (!this.isHiddenDay(end)) { 5839 runningCount += 1; 5840 } 5841 } while (runningCount < dayCount); 5842 return { start: start, end: end }; 5843 }; 5844 // Builds a normalized range object for the "visible" range, 5845 // which is a way to define the currentRange and activeRange at the same time. 5846 DateProfileGenerator.prototype.buildCustomVisibleRange = function (date) { 5847 var props = this.props; 5848 var input = props.visibleRangeInput; 5849 var simpleInput = typeof input === 'function' 5850 ? input.call(props.calendarApi, props.dateEnv.toDate(date)) 5851 : input; 5852 var range = this.refineRange(simpleInput); 5853 if (range && (range.start == null || range.end == null)) { 5854 return null; 5855 } 5856 return range; 5857 }; 5858 // Computes the range that will represent the element/cells for *rendering*, 5859 // but which may have voided days/times. 5860 // not responsible for trimming hidden days. 5861 DateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 5862 return currentRange; 5863 }; 5864 // Compute the duration value that should be added/substracted to the current date 5865 // when a prev/next operation happens. 5866 DateProfileGenerator.prototype.buildDateIncrement = function (fallback) { 5867 var dateIncrement = this.props.dateIncrement; 5868 var customAlignment; 5869 if (dateIncrement) { 5870 return dateIncrement; 5871 } 5872 if ((customAlignment = this.props.dateAlignment)) { 5873 return createDuration(1, customAlignment); 5874 } 5875 if (fallback) { 5876 return fallback; 5877 } 5878 return createDuration({ days: 1 }); 5879 }; 5880 DateProfileGenerator.prototype.refineRange = function (rangeInput) { 5881 if (rangeInput) { 5882 var range = parseRange(rangeInput, this.props.dateEnv); 5883 if (range) { 5884 range = computeVisibleDayRange(range); 5885 } 5886 return range; 5887 } 5888 return null; 5889 }; 5890 /* Hidden Days 5891 ------------------------------------------------------------------------------------------------------------------*/ 5892 // Initializes internal variables related to calculating hidden days-of-week 5893 DateProfileGenerator.prototype.initHiddenDays = function () { 5894 var hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
5895 var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool) 5896 var dayCnt = 0; 5897 var i; 5898 if (this.props.weekends === false) { 5899 hiddenDays.push(0, 6); // 0=sunday, 6=saturday 5900 } 5901 for (i = 0; i < 7; i += 1) { 5902 if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) { 5903 dayCnt += 1; 5904 } 5905 } 5906 if (!dayCnt) { 5907 throw new Error('invalid hiddenDays'); // all days were hidden? bad. 5908 } 5909 this.isHiddenDayHash = isHiddenDayHash; 5910 }; 5911 // Remove days from the beginning and end of the range that are computed as hidden. 5912 // If the whole range is trimmed off, returns null 5913 DateProfileGenerator.prototype.trimHiddenDays = function (range) { 5914 var start = range.start, end = range.end; 5915 if (start) { 5916 start = this.skipHiddenDays(start); 5917 } 5918 if (end) { 5919 end = this.skipHiddenDays(end, -1, true); 5920 } 5921 if (start == null || end == null || start < end) { 5922 return { start: start, end: end }; 5923 } 5924 return null; 5925 }; 5926 // Is the current day hidden? 5927 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 5928 DateProfileGenerator.prototype.isHiddenDay = function (day) { 5929 if (day instanceof Date) { 5930 day = day.getUTCDay(); 5931 } 5932 return this.isHiddenDayHash[day]; 5933 }; 5934 // Incrementing the current day until it is no longer a hidden day, returning a copy. 5935 // DOES NOT CONSIDER validRange! 5936 // If the initial value of `date` is not a hidden day, don't do anything. 5937 // Pass `isExclusive` as `true` if you are dealing with an end date. 5938 // `inc` defaults to `1` (increment one day forward each time) 5939 DateProfileGenerator.prototype.skipHiddenDays = function (date, inc, isExclusive) { 5940 if (inc === void 0) { inc = 1; } 5941 if (isExclusive === void 0) { isExclusive = false; } 5942 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 5943 date = addDays(date, inc); 5944 } 5945 return date; 5946 }; 5947 return DateProfileGenerator; 5948 }()); 5949 5950 function reduceViewType(viewType, action) { 5951 switch (action.type) { 5952 case 'CHANGE_VIEW_TYPE': 5953 viewType = action.viewType; 5954 } 5955 return viewType; 5956 } 5957 5958 function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 5959 var _a; 5960 switch (action.type) { 5961 case 'SET_OPTION': 5962 return __assign(__assign({}, dynamicOptionOverrides), (_a = {}, _a[action.optionName] = action.rawOptionValue, _a)); 5963 default: 5964 return dynamicOptionOverrides; 5965 } 5966 } 5967 5968 function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) { 5969 var dp; 5970 switch (action.type) { 5971 case 'CHANGE_VIEW_TYPE': 5972 return dateProfileGenerator.build(action.dateMarker || currentDate); 5973 case 'CHANGE_DATE': 5974 if (!currentDateProfile.activeRange || 5975 !rangeContainsMarker(currentDateProfile.currentRange, action.dateMarker) // don't move if date already in view 5976 ) { 5977 return dateProfileGenerator.build(action.dateMarker); 5978 } 5979 break; 5980 case 'PREV': 5981 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 5982 if (dp.isValid) { 5983 return dp; 5984 } 5985 break; 5986 case 'NEXT': 5987 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 5988 if (dp.isValid) { 5989 return dp; 5990 } 5991 break; 5992 } 5993 return currentDateProfile; 5994 } 5995 5996 function initEventSources(calendarOptions, dateProfile, context) { 5997 var activeRange = dateProfile ? dateProfile.activeRange : null; 5998 return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context); 5999 } 6000 function reduceEventSources(eventSources, action, dateProfile, context) { 6001 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6002 switch (action.type) { 6003 case 'ADD_EVENT_SOURCES': // already parsed 6004 return addSources(eventSources, action.sources, activeRange, context);
6005 case 'REMOVE_EVENT_SOURCE': 6006 return removeSource(eventSources, action.sourceId); 6007 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6008 case 'NEXT': 6009 case 'CHANGE_DATE': 6010 case 'CHANGE_VIEW_TYPE': 6011 if (dateProfile) { 6012 return fetchDirtySources(eventSources, activeRange, context); 6013 } 6014 return eventSources; 6015 case 'FETCH_EVENT_SOURCES': 6016 return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type? 6017 arrayToHash(action.sourceIds) : 6018 excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context); 6019 case 'RECEIVE_EVENTS': 6020 case 'RECEIVE_EVENT_ERROR': 6021 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 6022 case 'REMOVE_ALL_EVENT_SOURCES': 6023 return {}; 6024 default: 6025 return eventSources; 6026 } 6027 } 6028 function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 6029 var activeRange = dateProfile ? dateProfile.activeRange : null; // need this check? 6030 return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context); 6031 } 6032 function computeEventSourcesLoading(eventSources) { 6033 for (var sourceId in eventSources) { 6034 if (eventSources[sourceId].isFetching) { 6035 return true; 6036 } 6037 } 6038 return false; 6039 } 6040 function addSources(eventSourceHash, sources, fetchRange, context) { 6041 var hash = {}; 6042 for (var _i = 0, sources_1 = sources; _i < sources_1.length; _i++) { 6043 var source = sources_1[_i]; 6044 hash[source.sourceId] = source; 6045 } 6046 if (fetchRange) { 6047 hash = fetchDirtySources(hash, fetchRange, context); 6048 } 6049 return __assign(__assign({}, eventSourceHash), hash); 6050 } 6051 function removeSource(eventSourceHash, sourceId) { 6052 return filterHash(eventSourceHash, function (eventSource) { return eventSource.sourceId !== sourceId; }); 6053 } 6054 function fetchDirtySources(sourceHash, fetchRange, context) { 6055 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, function (eventSource) { return isSourceDirty(eventSource, fetchRange, context); }), fetchRange, false, context); 6056 } 6057 function isSourceDirty(eventSource, fetchRange, context) { 6058 if (!doesSourceNeedRange(eventSource, context)) { 6059 return !eventSource.latestFetchId; 6060 } 6061 return !context.options.lazyFetching || 6062 !eventSource.fetchRange || 6063 eventSource.isFetching || // always cancel outdated in-progress fetches 6064 fetchRange.start < eventSource.fetchRange.start || 6065 fetchRange.end > eventSource.fetchRange.end; 6066 } 6067 function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) { 6068 var nextSources = {}; 6069 for (var sourceId in prevSources) { 6070 var source = prevSources[sourceId]; 6071 if (sourceIdHash[sourceId]) { 6072 nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context); 6073 } 6074 else { 6075 nextSources[sourceId] = source; 6076 } 6077 } 6078 return nextSources; 6079 } 6080 function fetchSource(eventSource, fetchRange, isRefetch, context) { 6081 var options = context.options, calendarApi = context.calendarApi; 6082 var sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 6083 var fetchId = guid(); 6084 sourceDef.fetch({ 6085 eventSource: eventSource, 6086 range: fetchRange, 6087 isRefetch: isRefetch, 6088 context: context, 6089 }, function (res) { 6090 var rawEvents = res.rawEvents; 6091 if (options.eventSourceSuccess) { 6092 rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6093 } 6094 if (eventSource.success) { 6095 rawEvents = eventSource.success.call(calendarApi, rawEvents, res.xhr) || rawEvents; 6096 } 6097 context.dispatch({ 6098 type: 'RECEIVE_EVENTS', 6099 sourceId: eventSource.sourceId, 6100 fetchId: fetchId, 6101 fetchRange: fetchRange, 6102 rawEvents: rawEvents, 6103 }); 6104 }, function (error) { 6105 console.warn(error.message, error); 6106 if (options.eventSourceFailure) { 6107 options.eventSourceFailure.call(calendarApi, error); 6108 } 6109 if (eventSource.failure) { 6110 eventSource.failure(error); 6111 } 6112 context.dispatch({ 6113 type: 'RECEIVE_EVENT_ERROR', 6114 sourceId: eventSource.sourceId, 6115 fetchId: fetchId, 6116 fetchRange: fetchRange, 6117 error: error, 6118 }); 6119 }); 6120 return __assign(__assign({}, eventSource), { isFetching: true, latestFetchId: fetchId }); 6121 } 6122 function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 6123 var _a; 6124 var eventSource = sourceHash[sourceId]; 6125 if (eventSource && // not already removed 6126 fetchId === eventSource.latestFetchId) { 6127 return __assign(__assign({}, sourceHash), (_a = {}, _a[sourceId] = __assign(__assign({}, eventSource), { isFetching: false, fetchRange: fetchRange }), _a)); 6128 } 6129 return sourceHash; 6130 } 6131 function excludeStaticSources(eventSources, context) { 6132 return filterHash(eventSources, function (eventSource) { return doesSourceNeedRange(eventSource, context); }); 6133 } 6134 function parseInitialSources(rawOptions, context) { 6135 var refiners = buildEventSourceRefiners(context); 6136 var rawSources = [].concat(rawOptions.eventSources || []); 6137 var sources = []; // parsed 6138 if (rawOptions.initialEvents) { 6139 rawSources.unshift(rawOptions.initialEvents); 6140 } 6141 if (rawOptions.events) { 6142 rawSources.unshift(rawOptions.events); 6143 } 6144 for (var _i = 0, rawSources_1 = rawSources; _i < rawSources_1.length; _i++) { 6145 var rawSource = rawSources_1[_i]; 6146 var source = parseEventSource(rawSource, context, refiners); 6147 if (source) { 6148 sources.push(source); 6149 } 6150 } 6151 return sources; 6152 } 6153 function doesSourceNeedRange(eventSource, context) { 6154 var defs = context.pluginHooks.eventSourceDefs; 6155 return !defs[eventSource.sourceDefId].ignoreRange; 6156 } 6157 6158 function reduceEventStore(eventStore, action, eventSources, dateProfile, context) { 6159 switch (action.type) { 6160 case 'RECEIVE_EVENTS': // raw 6161 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context); 6162 case 'ADD_EVENTS': // already parsed, but not expanded 6163 return addEvent(eventStore, action.eventStore, // new ones 6164 dateProfile ? dateProfile.activeRange : null, context); 6165 case 'RESET_EVENTS': 6166 return action.eventStore; 6167 case 'MERGE_EVENTS': // already parsed and expanded 6168 return mergeEventStores(eventStore, action.eventStore); 6169 case 'PREV': // TODO: how do we track all actions that affect dateProfile :( 6170 case 'NEXT': 6171 case 'CHANGE_DATE': 6172 case 'CHANGE_VIEW_TYPE': 6173 if (dateProfile) { 6174 return expandRecurring(eventStore, dateProfile.activeRange, context); 6175 } 6176 return eventStore;
6177 case 'REMOVE_EVENTS': 6178 return excludeSubEventStore(eventStore, action.eventStore); 6179 case 'REMOVE_EVENT_SOURCE': 6180 return excludeEventsBySourceId(eventStore, action.sourceId); 6181 case 'REMOVE_ALL_EVENT_SOURCES': 6182 return filterEventStoreDefs(eventStore, function (eventDef) { return (!eventDef.sourceId // only keep events with no source id 6183 ); }); 6184 case 'REMOVE_ALL_EVENTS': 6185 return createEmptyEventStore(); 6186 default: 6187 return eventStore; 6188 } 6189 } 6190 function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) { 6191 if (eventSource && // not already removed 6192 fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources 6193 ) { 6194 var subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context); 6195 if (fetchRange) { 6196 subset = expandRecurring(subset, fetchRange, context); 6197 } 6198 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 6199 } 6200 return eventStore; 6201 } 6202 function transformRawEvents(rawEvents, eventSource, context) { 6203 var calEachTransform = context.options.eventDataTransform; 6204 var sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 6205 if (sourceEachTransform) { 6206 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 6207 } 6208 if (calEachTransform) { 6209 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 6210 } 6211 return rawEvents; 6212 } 6213 function transformEachRawEvent(rawEvents, func) { 6214 var refinedEvents; 6215 if (!func) { 6216 refinedEvents = rawEvents; 6217 } 6218 else { 6219 refinedEvents = []; 6220 for (var _i = 0, rawEvents_1 = rawEvents; _i < rawEvents_1.length; _i++) { 6221 var rawEvent = rawEvents_1[_i]; 6222 var refinedEvent = func(rawEvent); 6223 if (refinedEvent) { 6224 refinedEvents.push(refinedEvent); 6225 } 6226 else if (refinedEvent == null) { 6227 refinedEvents.push(rawEvent); 6228 } // if a different falsy value, do nothing 6229 } 6230 } 6231 return refinedEvents; 6232 } 6233 function addEvent(eventStore, subset, expandRange, context) { 6234 if (expandRange) { 6235 subset = expandRecurring(subset, expandRange, context); 6236 } 6237 return mergeEventStores(eventStore, subset); 6238 } 6239 function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 6240 var defs = eventStore.defs; 6241 var instances = mapHash(eventStore.instances, function (instance) { 6242 var def = defs[instance.defId]; 6243 if (def.allDay || def.recurringDef) { 6244 return instance; // isn't dependent on timezone 6245 } 6246 return __assign(__assign({}, instance), { range: { 6247 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 6248 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)), 6249 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 6250 }); 6251 return { defs: defs, instances: instances }; 6252 } 6253 function excludeEventsBySourceId(eventStore, sourceId) { 6254 return filterEventStoreDefs(eventStore, function (eventDef) { return eventDef.sourceId !== sourceId; }); 6255 } 6256 // QUESTION: why not just return instances? do a general object-property-exclusion util 6257 function excludeInstances(eventStore, removals) { 6258 return { 6259 defs: eventStore.defs, 6260 instances: filterHash(eventStore.instances, function (instance) { return !removals[instance.instanceId]; }), 6261 }; 6262 } 6263 6264 function reduceDateSelection(currentSelection, action) { 6265 switch (action.type) { 6266 case 'UNSELECT_DATES': 6267 return null; 6268 case 'SELECT_DATES': 6269 return action.selection; 6270 default: 6271 return currentSelection; 6272 } 6273 } 6274 6275 function reduceSelectedEvent(currentInstanceId, action) { 6276 switch (action.type) { 6277 case 'UNSELECT_EVENT': 6278 return ''; 6279 case 'SELECT_EVENT': 6280 return action.eventInstanceId; 6281 default: 6282 return currentInstanceId; 6283 } 6284 } 6285 6286 function reduceEventDrag(currentDrag, action) { 6287 var newDrag; 6288 switch (action.type) { 6289 case 'UNSET_EVENT_DRAG': 6290 return null; 6291 case 'SET_EVENT_DRAG': 6292 newDrag = action.state; 6293 return { 6294 affectedEvents: newDrag.affectedEvents, 6295 mutatedEvents: newDrag.mutatedEvents, 6296 isEvent: newDrag.isEvent, 6297 }; 6298 default: 6299 return currentDrag; 6300 } 6301 } 6302 6303 function reduceEventResize(currentResize, action) { 6304 var newResize; 6305 switch (action.type) { 6306 case 'UNSET_EVENT_RESIZE': 6307 return null; 6308 case 'SET_EVENT_RESIZE': 6309 newResize = action.state; 6310 return { 6311 affectedEvents: newResize.affectedEvents, 6312 mutatedEvents: newResize.mutatedEvents, 6313 isEvent: newResize.isEvent, 6314 }; 6315 default: 6316 return currentResize; 6317 } 6318 } 6319 6320 function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 6321 var viewsWithButtons = []; 6322 var headerToolbar = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null; 6323 var footerToolbar = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) : null; 6324 return { headerToolbar: headerToolbar, footerToolbar: footerToolbar, viewsWithButtons: viewsWithButtons }; 6325 } 6326 function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) { 6327 return mapHash(sectionStrHash, function (sectionStr) { return parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons); }); 6328 } 6329 /* 6330 BAD: querying icons and text here. should be done at render time 6331 */ 6332 function parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi, viewsWithButtons) { 6333 var isRtl = calendarOptions.direction === 'rtl'; 6334 var calendarCustomButtons = calendarOptions.customButtons || {}; 6335 var calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 6336 var calendarButtonText = calendarOptions.buttonText || {}; 6337 var sectionSubstrs = sectionStr ? sectionStr.split(' ') : []; 6338 return sectionSubstrs.map(function (buttonGroupStr) { return (buttonGroupStr.split(',').map(function (buttonName) { 6339 if (buttonName === 'title') { 6340 return { buttonName: buttonName }; 6341 } 6342 var customButtonProps; 6343 var viewSpec; 6344 var buttonClick; 6345 var buttonIcon; // only one of these will be set 6346 var buttonText; // " 6347 if ((customButtonProps = calendarCustomButtons[buttonName])) { 6348 buttonClick = function (ev) { 6349 if (customButtonProps.click) { 6350 customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context? 6351 } 6352 }; 6353 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || 6354 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6355 (buttonText = customButtonProps.text); 6356 } 6357 else if ((viewSpec = viewSpecs[buttonName])) { 6358 viewsWithButtons.push(buttonName); 6359 buttonClick = function () { 6360 calendarApi.changeView(buttonName); 6361 }; 6362 (buttonText = viewSpec.buttonTextOverride) || 6363 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6364 (buttonText = viewSpec.buttonTextDefault); 6365 } 6366 else if (calendarApi[buttonName]) { // a calendarApi method 6367 buttonClick = function () { 6368 calendarApi[buttonName](); 6369 }; 6370 (buttonText = calendarButtonTextOverrides[buttonName]) || 6371 (buttonIcon = theme.getIconClass(buttonName, isRtl)) || 6372 (buttonText = calendarButtonText[buttonName]); 6373 // ^ everything else is considered default 6374 } 6375 return { buttonName: buttonName, buttonClick: buttonClick, buttonIcon: buttonIcon, buttonText: buttonText }; 6376 })); }); 6377 } 6378 6379 var eventSourceDef$3 = { 6380 ignoreRange: true, 6381 parseMeta: function (refined) { 6382 if (Array.isArray(refined.events)) { 6383 return refined.events; 6384 } 6385 return null; 6386 }, 6387 fetch: function (arg, success) { 6388 success({ 6389 rawEvents: arg.eventSource.meta, 6390 }); 6391 }, 6392 }; 6393 var arrayEventSourcePlugin = createPlugin({ 6394 eventSourceDefs: [eventSourceDef$3], 6395 }); 6396 6397 var eventSourceDef$2 = { 6398 parseMeta: function (refined) { 6399 if (typeof refined.events === 'function') { 6400 return refined.events; 6401 } 6402 return null; 6403 }, 6404 fetch: function (arg, success, failure) { 6405 var dateEnv = arg.context.dateEnv; 6406 var func = arg.eventSource.meta; 6407 unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), function (rawEvents) { 6408 success({ rawEvents: rawEvents }); // needs an object response 6409 }, failure); 6410 }, 6411 }; 6412 var funcEventSourcePlugin = createPlugin({ 6413 eventSourceDefs: [eventSourceDef$2], 6414 }); 6415 6416 function requestJson(method, url, params, successCallback, failureCallback) { 6417 method = method.toUpperCase(); 6418 var body = null; 6419 if (method === 'GET') { 6420 url = injectQueryStringParams(url, params); 6421 } 6422 else { 6423 body = encodeParams(params); 6424 } 6425 var xhr = new XMLHttpRequest(); 6426 xhr.open(method, url, true); 6427 if (method !== 'GET') { 6428 xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 6429 xhr.setRequestHeader('X-Requested-With','XMLHttpRequest'); 6430 } 6431 xhr.onload = function () { 6432 if (xhr.status >= 200 && xhr.status < 400) { 6433 var parsed = false;
6434 var res = void 0; 6435 try { 6436 res = JSON.parse(xhr.responseText); 6437 parsed = true; 6438 } 6439 catch (err) { 6440 // will handle parsed=false 6441 } 6442 if (parsed) { 6443 successCallback(res, xhr); 6444 } 6445 else { 6446 failureCallback('Failure parsing JSON', xhr); 6447 } 6448 } 6449 else { 6450 failureCallback('Request failed', xhr); 6451 } 6452 }; 6453 xhr.onerror = function () { 6454 failureCallback('Request failed', xhr); 6455 }; 6456 xhr.send(body); 6457 } 6458 function injectQueryStringParams(url, params) { 6459 return url + 6460 (url.indexOf('?') === -1 ? '?' : '&') + 6461 encodeParams(params); 6462 } 6463 function encodeParams(params) { 6464 var parts = []; 6465 for (var key in params) { 6466 parts.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key])); 6467 } 6468 return parts.join('&'); 6469 } 6470 6471 var JSON_FEED_EVENT_SOURCE_REFINERS = { 6472 method: String, 6473 extraParams: identity, 6474 startParam: String, 6475 endParam: String, 6476 timeZoneParam: String, 6477 }; 6478 6479 var eventSourceDef$1 = { 6480 parseMeta: function (refined) { 6481 if (refined.url && (refined.format === 'json' || !refined.format)) { 6482 return { 6483 url: refined.url, 6484 format: 'json', 6485 method: (refined.method || 'GET').toUpperCase(), 6486 extraParams: refined.extraParams, 6487 startParam: refined.startParam, 6488 endParam: refined.endParam, 6489 timeZoneParam: refined.timeZoneParam, 6490 }; 6491 } 6492 return null; 6493 }, 6494 fetch: function (arg, success, failure) { 6495 var meta = arg.eventSource.meta; 6496 var requestParams = buildRequestParams$1(meta, arg.range, arg.context); 6497 requestJson(meta.method, meta.url, requestParams, function (rawEvents, xhr) { 6498 success({ rawEvents: rawEvents, xhr: xhr }); 6499 }, function (errorMessage, xhr) { 6500 failure({ message: errorMessage, xhr: xhr }); 6501 }); 6502 }, 6503 }; 6504 var jsonFeedEventSourcePlugin = createPlugin({ 6505 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 6506 eventSourceDefs: [eventSourceDef$1], 6507 }); 6508 function buildRequestParams$1(meta, range, context) { 6509 var dateEnv = context.dateEnv, options = context.options; 6510 var startParam; 6511 var endParam; 6512 var timeZoneParam;
6513 var customRequestParams; 6514 var params = {}; 6515 startParam = meta.startParam; 6516 if (startParam == null) { 6517 startParam = options.startParam; 6518 } 6519 endParam = meta.endParam; 6520 if (endParam == null) { 6521 endParam = options.endParam; 6522 } 6523 timeZoneParam = meta.timeZoneParam; 6524 if (timeZoneParam == null) { 6525 timeZoneParam = options.timeZoneParam; 6526 } 6527 // retrieve any outbound GET/POST data from the options 6528 if (typeof meta.extraParams === 'function') { 6529 // supplied as a function that returns a key/value object 6530 customRequestParams = meta.extraParams(); 6531 } 6532 else { 6533 // probably supplied as a straight key/value object 6534 customRequestParams = meta.extraParams || {}; 6535 } 6536 __assign(params, customRequestParams); 6537 params[startParam] = dateEnv.formatIso(range.start); 6538 params[endParam] = dateEnv.formatIso(range.end); 6539 if (dateEnv.timeZone !== 'local') { 6540 params[timeZoneParam] = dateEnv.timeZone; 6541 } 6542 return params; 6543 } 6544 6545 var SIMPLE_RECURRING_REFINERS = { 6546 daysOfWeek: identity, 6547 startTime: createDuration, 6548 endTime: createDuration, 6549 duration: createDuration, 6550 startRecur: identity, 6551 endRecur: identity, 6552 }; 6553 6554 var recurring = { 6555 parse: function (refined, dateEnv) { 6556 if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) { 6557 var recurringData = { 6558 daysOfWeek: refined.daysOfWeek || null, 6559 startTime: refined.startTime || null, 6560 endTime: refined.endTime || null, 6561 startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null, 6562 endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null, 6563 }; 6564 var duration = void 0; 6565 if (refined.duration) { 6566 duration = refined.duration; 6567 } 6568 if (!duration && refined.startTime && refined.endTime) { 6569 duration = subtractDurations(refined.endTime, refined.startTime); 6570 } 6571 return { 6572 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 6573 duration: duration, 6574 typeData: recurringData, // doesn't need endTime anymore but oh well 6575 }; 6576 } 6577 return null; 6578 }, 6579 expand: function (typeData, framingRange, dateEnv) { 6580 var clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 6581 if (clippedFramingRange) { 6582 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 6583 } 6584 return []; 6585 }, 6586 }; 6587 var simpleRecurringEventsPlugin = createPlugin({ 6588 recurringTypes: [recurring], 6589 eventRefiners: SIMPLE_RECURRING_REFINERS, 6590 }); 6591 function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 6592 var dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 6593 var dayMarker = startOfDay(framingRange.start); 6594 var endMarker = framingRange.end; 6595 var instanceStarts = []; 6596 while (dayMarker < endMarker) { 6597 var instanceStart 6598 // if everyday, or this particular day-of-week 6599 = void 0; 6600 // if everyday, or this particular day-of-week 6601 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 6602 if (startTime) { 6603 instanceStart = dateEnv.add(dayMarker, startTime); 6604 } 6605 else { 6606 instanceStart = dayMarker; 6607 } 6608 instanceStarts.push(instanceStart); 6609 } 6610 dayMarker = addDays(dayMarker, 1); 6611 } 6612 return instanceStarts; 6613 } 6614 6615 var changeHandlerPlugin = createPlugin({ 6616 optionChangeHandlers: { 6617 events: function (events, context) { 6618 handleEventSources([events], context); 6619 }, 6620 eventSources: handleEventSources, 6621 }, 6622 }); 6623 /* 6624 BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out 6625 */ 6626 function handleEventSources(inputs, context) { 6627 var unfoundSources = hashValuesToArray(context.getCurrentData().eventSources);
6628 var newInputs = []; 6629 for (var _i = 0, inputs_1 = inputs; _i < inputs_1.length; _i++) { 6630 var input = inputs_1[_i]; 6631 var inputFound = false; 6632 for (var i = 0; i < unfoundSources.length; i += 1) { 6633 if (unfoundSources[i]._raw === input) { 6634 unfoundSources.splice(i, 1); // delete 6635 inputFound = true; 6636 break; 6637 } 6638 } 6639 if (!inputFound) { 6640 newInputs.push(input); 6641 } 6642 } 6643 for (var _a = 0, unfoundSources_1 = unfoundSources; _a < unfoundSources_1.length; _a++) { 6644 var unfoundSource = unfoundSources_1[_a]; 6645 context.dispatch({ 6646 type: 'REMOVE_EVENT_SOURCE', 6647 sourceId: unfoundSource.sourceId, 6648 }); 6649 } 6650 for (var _b = 0, newInputs_1 = newInputs; _b < newInputs_1.length; _b++) { 6651 var newInput = newInputs_1[_b]; 6652 context.calendarApi.addEventSource(newInput); 6653 } 6654 } 6655 6656 function handleDateProfile(dateProfile, context) { 6657 context.emitter.trigger('datesSet', __assign(__assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi })); 6658 } 6659 6660 function handleEventStore(eventStore, context) { 6661 var emitter = context.emitter; 6662 if (emitter.hasHandlers('eventsSet')) { 6663 emitter.trigger('eventsSet', buildEventApis(eventStore, context)); 6664 } 6665 } 6666 6667 /* 6668 this array is exposed on the root namespace so that UMD plugins can add to it. 6669 see the rollup-bundles script. 6670 */ 6671 var globalPlugins = [ 6672 arrayEventSourcePlugin, 6673 funcEventSourcePlugin, 6674 jsonFeedEventSourcePlugin, 6675 simpleRecurringEventsPlugin, 6676 changeHandlerPlugin, 6677 createPlugin({ 6678 isLoadingFuncs: [ 6679 function (state) { return computeEventSourcesLoading(state.eventSources); }, 6680 ], 6681 contentTypeHandlers: { 6682 html: function () { return ({ render: injectHtml }); }, 6683 domNodes: function () { return ({ render: injectDomNodes }); }, 6684 }, 6685 propSetHandlers: { 6686 dateProfile: handleDateProfile, 6687 eventStore: handleEventStore, 6688 }, 6689 }), 6690 ]; 6691 function injectHtml(el, html) { 6692 el.innerHTML = html; 6693 } 6694 function injectDomNodes(el, domNodes) { 6695 var oldNodes = Array.prototype.slice.call(el.childNodes); // TODO: use array util 6696 var newNodes = Array.prototype.slice.call(domNodes); // TODO: use array util 6697 if (!isArraysEqual(oldNodes, newNodes)) { 6698 for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) { 6699 var newNode = newNodes_1[_i]; 6700 el.appendChild(newNode); 6701 } 6702 oldNodes.forEach(removeElement); 6703 } 6704 } 6705 6706 var DelayedRunner = /** @class */ (function () { 6707 function DelayedRunner(drainedOption) { 6708 this.drainedOption = drainedOption; 6709 this.isRunning = false; 6710 this.isDirty = false; 6711 this.pauseDepths = {}; 6712 this.timeoutId = 0; 6713 } 6714 DelayedRunner.prototype.request = function (delay) { 6715 this.isDirty = true; 6716 if (!this.isPaused()) { 6717 this.clearTimeout(); 6718 if (delay == null) { 6719 this.tryDrain(); 6720 } 6721 else { 6722 this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce 6723 this.tryDrain.bind(this), delay); 6724 } 6725 } 6726 }; 6727 DelayedRunner.prototype.pause = function (scope) { 6728 if (scope === void 0) { scope = ''; } 6729 var pauseDepths = this.pauseDepths; 6730 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 6731 this.clearTimeout(); 6732 }; 6733 DelayedRunner.prototype.resume = function (scope, force) { 6734 if (scope === void 0) { scope = ''; } 6735 var pauseDepths = this.pauseDepths; 6736 if (scope in pauseDepths) { 6737 if (force) { 6738 delete pauseDepths[scope]; 6739 } 6740 else { 6741 pauseDepths[scope] -= 1; 6742 var depth = pauseDepths[scope]; 6743 if (depth <= 0) { 6744 delete pauseDepths[scope]; 6745 } 6746 } 6747 this.tryDrain(); 6748 } 6749 }; 6750 DelayedRunner.prototype.isPaused = function () { 6751 return Object.keys(this.pauseDepths).length; 6752 }; 6753 DelayedRunner.prototype.tryDrain = function () { 6754 if (!this.isRunning && !this.isPaused()) { 6755 this.isRunning = true; 6756 while (this.isDirty) { 6757 this.isDirty = false;
6758 this.drained(); // might set isDirty to true again 6759 } 6760 this.isRunning = false; 6761 } 6762 }; 6763 DelayedRunner.prototype.clear = function () { 6764 this.clearTimeout(); 6765 this.isDirty = false; 6766 this.pauseDepths = {}; 6767 }; 6768 DelayedRunner.prototype.clearTimeout = function () { 6769 if (this.timeoutId) { 6770 clearTimeout(this.timeoutId); 6771 this.timeoutId = 0; 6772 } 6773 }; 6774 DelayedRunner.prototype.drained = function () { 6775 if (this.drainedOption) { 6776 this.drainedOption(); 6777 } 6778 }; 6779 return DelayedRunner; 6780 }()); 6781 6782 var TaskRunner = /** @class */ (function () { 6783 function TaskRunner(runTaskOption, drainedOption) { 6784 this.runTaskOption = runTaskOption; 6785 this.drainedOption = drainedOption; 6786 this.queue = []; 6787 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 6788 } 6789 TaskRunner.prototype.request = function (task, delay) { 6790 this.queue.push(task); 6791 this.delayedRunner.request(delay); 6792 }; 6793 TaskRunner.prototype.pause = function (scope) { 6794 this.delayedRunner.pause(scope); 6795 }; 6796 TaskRunner.prototype.resume = function (scope, force) { 6797 this.delayedRunner.resume(scope, force); 6798 }; 6799 TaskRunner.prototype.drain = function () { 6800 var queue = this.queue; 6801 while (queue.length) { 6802 var completedTasks = []; 6803 var task = void 0; 6804 while ((task = queue.shift())) { 6805 this.runTask(task); 6806 completedTasks.push(task); 6807 } 6808 this.drained(completedTasks); 6809 } // keep going, in case new tasks were added in the drained handler 6810 }; 6811 TaskRunner.prototype.runTask = function (task) { 6812 if (this.runTaskOption) { 6813 this.runTaskOption(task); 6814 } 6815 }; 6816 TaskRunner.prototype.drained = function (completedTasks) { 6817 if (this.drainedOption) { 6818 this.drainedOption(completedTasks); 6819 } 6820 }; 6821 return TaskRunner; 6822 }()); 6823 6824 // Computes what the title at the top of the calendarApi should be for this view 6825 function buildTitle(dateProfile, viewOptions, dateEnv) { 6826 var range; 6827 // for views that span a large unit of time, show the proper interval, ignoring stray days before and after 6828 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 6829 range = dateProfile.currentRange; 6830 } 6831 else { // for day units or smaller, use the actual day range 6832 range = dateProfile.activeRange; 6833 } 6834 return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), { 6835 isEndExclusive: dateProfile.isRangeAllDay, 6836 defaultSeparator: viewOptions.titleRangeSeparator, 6837 }); 6838 } 6839 // Generates the format string that should be used to generate the title for the current date range. 6840 // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`. 6841 function buildTitleFormat(dateProfile) { 6842 var currentRangeUnit = dateProfile.currentRangeUnit; 6843 if (currentRangeUnit === 'year') { 6844 return { year: 'numeric' }; 6845 } 6846 if (currentRangeUnit === 'month') { 6847 return { year: 'numeric', month: 'long' }; // like "September 2014" 6848 } 6849 var days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 6850 if (days !== null && days > 1) { 6851 // multi-day range. shorter, like "Sep 9 - 10 2014" 6852 return { year: 'numeric', month: 'short', day: 'numeric' }; 6853 } 6854 // one day. longer, like "September 9 2014" 6855 return { year: 'numeric', month: 'long', day: 'numeric' }; 6856 } 6857 6858 // in future refactor, do the redux-style function(state=initial) for initial-state 6859 // also, whatever is happening in constructor, have it happen in action queue too 6860 var CalendarDataManager = /** @class */ (function () { 6861 function CalendarDataManager(props) { 6862 var _this = this; 6863 this.computeOptionsData = memoize(this._computeOptionsData); 6864 this.computeCurrentViewData = memoize(this._computeCurrentViewData);
6865 this.organizeRawLocales = memoize(organizeRawLocales); 6866 this.buildLocale = memoize(buildLocale); 6867 this.buildPluginHooks = buildBuildPluginHooks(); 6868 this.buildDateEnv = memoize(buildDateEnv); 6869 this.buildTheme = memoize(buildTheme); 6870 this.parseToolbars = memoize(parseToolbars); 6871 this.buildViewSpecs = memoize(buildViewSpecs); 6872 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 6873 this.buildViewApi = memoize(buildViewApi); 6874 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 6875 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 6876 this.buildEventUiBases = memoize(buildEventUiBases); 6877 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 6878 this.buildTitle = memoize(buildTitle); 6879 this.emitter = new Emitter(); 6880 this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this)); 6881 this.currentCalendarOptionsInput = {}; 6882 this.currentCalendarOptionsRefined = {}; 6883 this.currentViewOptionsInput = {}; 6884 this.currentViewOptionsRefined = {}; 6885 this.currentCalendarOptionsRefiners = {}; 6886 this.getCurrentData = function () { return _this.data; }; 6887 this.dispatch = function (action) { 6888 _this.actionRunner.request(action); // protects against recursive calls to _handleAction 6889 }; 6890 this.props = props; 6891 this.actionRunner.pause(); 6892 var dynamicOptionOverrides = {}; 6893 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 6894 var currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView; 6895 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 6896 // wire things up 6897 // TODO: not DRY 6898 props.calendarApi.currentDataManager = this; 6899 this.emitter.setThisContext(props.calendarApi); 6900 this.emitter.setOptions(currentViewData.options); 6901 var currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv); 6902 var dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 6903 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 6904 currentDate = dateProfile.currentRange.start; 6905 } 6906 var calendarContext = { 6907 dateEnv: optionsData.dateEnv, 6908 options: optionsData.calendarOptions, 6909 pluginHooks: optionsData.pluginHooks, 6910 calendarApi: props.calendarApi, 6911 dispatch: this.dispatch, 6912 emitter: this.emitter, 6913 getCurrentData: this.getCurrentData, 6914 }; 6915 // needs to be after setThisContext 6916 for (var _i = 0, _a = optionsData.pluginHooks.contextInit; _i < _a.length; _i++) { 6917 var callback = _a[_i]; 6918 callback(calendarContext); 6919 } 6920 // NOT DRY 6921 var eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext); 6922 var initialState = { 6923 dynamicOptionOverrides: dynamicOptionOverrides, 6924 currentViewType: currentViewType, 6925 currentDate: currentDate, 6926 dateProfile: dateProfile, 6927 businessHours: this.parseContextBusinessHours(calendarContext), 6928 eventSources: eventSources, 6929 eventUiBases: {}, 6930 eventStore: createEmptyEventStore(), 6931 renderableEventStore: createEmptyEventStore(), 6932 dateSelection: null, 6933 eventSelection: '', 6934 eventDrag: null, 6935 eventResize: null, 6936 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig, 6937 }; 6938 var contextAndState = __assign(__assign({}, calendarContext), initialState); 6939 for (var _b = 0, _c = optionsData.pluginHooks.reducers; _b < _c.length; _b++) { 6940 var reducer = _c[_b]; 6941 __assign(initialState, reducer(null, null, contextAndState)); 6942 } 6943 if (computeIsLoading(initialState, calendarContext)) { 6944 this.emitter.trigger('loading', true); // NOT DRY 6945 } 6946 this.state = initialState; 6947 this.updateData(); 6948 this.actionRunner.resume(); 6949 } 6950 CalendarDataManager.prototype.resetOptions = function (optionOverrides, append) { 6951 var props = this.props; 6952 props.optionOverrides = append 6953 ? __assign(__assign({}, props.optionOverrides), optionOverrides) : optionOverrides; 6954 this.actionRunner.request({ 6955 type: 'NOTHING', 6956 }); 6957 }; 6958 CalendarDataManager.prototype._handleAction = function (action) { 6959 var _a = this, props = _a.props, state = _a.state, emitter = _a.emitter; 6960 var dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action); 6961 var optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 6962 var currentViewType = reduceViewType(state.currentViewType, action); 6963 var currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 6964 // wire things up 6965 // TODO: not DRY 6966 props.calendarApi.currentDataManager = this; 6967 emitter.setThisContext(props.calendarApi); 6968 emitter.setOptions(currentViewData.options); 6969 var calendarContext = { 6970 dateEnv: optionsData.dateEnv, 6971 options: optionsData.calendarOptions, 6972 pluginHooks: optionsData.pluginHooks, 6973 calendarApi: props.calendarApi, 6974 dispatch: this.dispatch, 6975 emitter: emitter, 6976 getCurrentData: this.getCurrentData, 6977 }; 6978 var currentDate = state.currentDate, dateProfile = state.dateProfile; 6979 if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack 6980 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 6981 } 6982 currentDate = reduceCurrentDate(currentDate, action); 6983 dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator); 6984 if (!rangeContainsMarker(dateProfile.currentRange, currentDate)) { 6985 currentDate = dateProfile.currentRange.start; 6986 } 6987 var eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext); 6988 var eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext); 6989 var isEventsLoading = computeEventSourcesLoading(eventSources);
6989 // BAD. also called in this func in computeIsLoading 6990 var renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ? 6991 (state.renderableEventStore || eventStore) : // try from previous state 6992 eventStore; 6993 var _b = this.buildViewUiProps(calendarContext), eventUiSingleBase = _b.eventUiSingleBase, selectionConfig = _b.selectionConfig; // will memoize obj 6994 var eventUiBySource = this.buildEventUiBySource(eventSources); 6995 var eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 6996 var newState = { 6997 dynamicOptionOverrides: dynamicOptionOverrides, 6998 currentViewType: currentViewType, 6999 currentDate: currentDate, 7000 dateProfile: dateProfile, 7001 eventSources: eventSources, 7002 eventStore: eventStore, 7003 renderableEventStore: renderableEventStore, 7004 selectionConfig: selectionConfig, 7005 eventUiBases: eventUiBases, 7006 businessHours: this.parseContextBusinessHours(calendarContext), 7007 dateSelection: reduceDateSelection(state.dateSelection, action), 7008 eventSelection: reduceSelectedEvent(state.eventSelection, action), 7009 eventDrag: reduceEventDrag(state.eventDrag, action), 7010 eventResize: reduceEventResize(state.eventResize, action), 7011 }; 7012 var contextAndState = __assign(__assign({}, calendarContext), newState); 7013 for (var _i = 0, _c = optionsData.pluginHooks.reducers; _i < _c.length; _i++) { 7014 var reducer = _c[_i]; 7015 __assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value 7016 } 7017 var wasLoading = computeIsLoading(state, calendarContext); 7018 var isLoading = computeIsLoading(newState, calendarContext); 7019 // TODO: use propSetHandlers in plugin system 7020 if (!wasLoading && isLoading) { 7021 emitter.trigger('loading', true); 7022 } 7023 else if (wasLoading && !isLoading) { 7024 emitter.trigger('loading', false); 7025 } 7026 this.state = newState; 7027 if (props.onAction) { 7028 props.onAction(action); 7029 } 7030 }; 7031 CalendarDataManager.prototype.updateData = function () { 7032 var _a = this, props = _a.props, state = _a.state; 7033 var oldData = this.data; 7034 var optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi); 7035 var currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides); 7036 var data = this.data = __assign(__assign(__assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state); 7037 var changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 7038 var oldCalendarOptions = oldData && oldData.calendarOptions; 7039 var newCalendarOptions = optionsData.calendarOptions; 7040 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 7041 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 7042 // hack 7043 state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data); 7044 state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv); 7045 } 7046 for (var optionName in changeHandlers) { 7047 if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) { 7048 changeHandlers[optionName](newCalendarOptions[optionName], data); 7049 } 7050 } 7051 } 7052 if (props.onData) { 7053 props.onData(data); 7054 } 7055 }; 7056 CalendarDataManager.prototype._computeOptionsData = function (optionOverrides, dynamicOptionOverrides, calendarApi) { 7057 // TODO: blacklist options that are handled by optionChangeHandlers 7058 var _a = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, pluginHooks = _a.pluginHooks, localeDefaults = _a.localeDefaults, availableLocaleData = _a.availableLocaleData, extra = _a.extra; 7059 warnUnknownOptions(extra); 7060 var dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator); 7061 var viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults); 7062 var theme = this.buildTheme(refinedOptions, pluginHooks); 7063 var toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi); 7064 return { 7065 calendarOptions: refinedOptions, 7066 pluginHooks: pluginHooks, 7067 dateEnv: dateEnv, 7068 viewSpecs: viewSpecs, 7069 theme: theme, 7070 toolbarConfig: toolbarConfig, 7071 localeDefaults: localeDefaults, 7072 availableRawLocales: availableLocaleData.map, 7073 }; 7074 }; 7075 // always called from behind a memoizer 7076 CalendarDataManager.prototype.processRawCalendarOptions = function (optionOverrides, dynamicOptionOverrides) { 7077 var _a = mergeRawOptions([ 7078 BASE_OPTION_DEFAULTS, 7079 optionOverrides, 7080 dynamicOptionOverrides, 7081 ]), locales = _a.locales, locale = _a.locale; 7082 var availableLocaleData = this.organizeRawLocales(locales); 7083 var availableRawLocales = availableLocaleData.map; 7084 var localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options; 7085 var pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins); 7086 var refiners = this.currentCalendarOptionsRefiners = __assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners); 7087 var extra = {}; 7088 var raw = mergeRawOptions([ 7089 BASE_OPTION_DEFAULTS, 7090 localeDefaults, 7091 optionOverrides, 7092 dynamicOptionOverrides, 7093 ]);
7094 var refined = {}; 7095 var currentRaw = this.currentCalendarOptionsInput; 7096 var currentRefined = this.currentCalendarOptionsRefined; 7097 var anyChanges = false; 7098 for (var optionName in raw) { 7099 if (optionName !== 'plugins') { // because plugins is special-cased 7100 if (raw[optionName] === currentRaw[optionName] || 7101 (COMPLEX_OPTION_COMPARATORS[optionName] && 7102 (optionName in currentRaw) && 7103 COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) { 7104 refined[optionName] = currentRefined[optionName]; 7105 } 7106 else if (refiners[optionName]) { 7107 refined[optionName] = refiners[optionName](raw[optionName]); 7108 anyChanges = true; 7109 } 7110 else { 7111 extra[optionName] = currentRaw[optionName]; 7112 } 7113 } 7114 } 7115 if (anyChanges) { 7116 this.currentCalendarOptionsInput = raw; 7117 this.currentCalendarOptionsRefined = refined; 7118 } 7119 return { 7120 rawOptions: this.currentCalendarOptionsInput, 7121 refinedOptions: this.currentCalendarOptionsRefined, 7122 pluginHooks: pluginHooks, 7123 availableLocaleData: availableLocaleData, 7124 localeDefaults: localeDefaults, 7125 extra: extra, 7126 }; 7127 }; 7128 CalendarDataManager.prototype._computeCurrentViewData = function (viewType, optionsData, optionOverrides, dynamicOptionOverrides) { 7129 var viewSpec = optionsData.viewSpecs[viewType]; 7130 if (!viewSpec) { 7131 throw new Error("viewType \"" + viewType + "\" is not available. Please make sure you've loaded all neccessary plugins"); 7132 } 7133 var _a = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides), refinedOptions = _a.refinedOptions, extra = _a.extra; 7134 warnUnknownOptions(extra); 7135 var dateProfileGenerator = this.buildDateProfileGenerator({ 7136 dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass, 7137 duration: viewSpec.duration, 7138 durationUnit: viewSpec.durationUnit, 7139 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 7140 dateEnv: optionsData.dateEnv, 7141 calendarApi: this.props.calendarApi, 7142 slotMinTime: refinedOptions.slotMinTime, 7143 slotMaxTime: refinedOptions.slotMaxTime, 7144 showNonCurrentDates: refinedOptions.showNonCurrentDates, 7145 dayCount: refinedOptions.dayCount, 7146 dateAlignment: refinedOptions.dateAlignment, 7147 dateIncrement: refinedOptions.dateIncrement, 7148 hiddenDays: refinedOptions.hiddenDays, 7149 weekends: refinedOptions.weekends, 7150 nowInput: refinedOptions.now, 7151 validRangeInput: refinedOptions.validRange, 7152 visibleRangeInput: refinedOptions.visibleRange, 7153 monthMode: refinedOptions.monthMode, 7154 fixedWeekCount: refinedOptions.fixedWeekCount, 7155 }); 7156 var viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv); 7157 return { viewSpec: viewSpec, options: refinedOptions, dateProfileGenerator: dateProfileGenerator, viewApi: viewApi }; 7158 }; 7159 CalendarDataManager.prototype.processRawViewOptions = function (viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) { 7160 var raw = mergeRawOptions([ 7161 BASE_OPTION_DEFAULTS, 7162 viewSpec.optionDefaults, 7163 localeDefaults, 7164 optionOverrides, 7165 viewSpec.optionOverrides, 7166 dynamicOptionOverrides, 7167 ]); 7168 var refiners = __assign(__assign(__assign(__assign(__assign(__assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
7169 var refined = {}; 7170 var currentRaw = this.currentViewOptionsInput; 7171 var currentRefined = this.currentViewOptionsRefined; 7172 var anyChanges = false; 7173 var extra = {}; 7174 for (var optionName in raw) { 7175 if (raw[optionName] === currentRaw[optionName]) { 7176 refined[optionName] = currentRefined[optionName]; 7177 } 7178 else { 7179 if (raw[optionName] === this.currentCalendarOptionsInput[optionName]) { 7180 if (optionName in this.currentCalendarOptionsRefined) { // might be an "extra" prop 7181 refined[optionName] = this.currentCalendarOptionsRefined[optionName]; 7182 } 7183 } 7184 else if (refiners[optionName]) { 7185 refined[optionName] = refiners[optionName](raw[optionName]); 7186 } 7187 else { 7188 extra[optionName] = raw[optionName]; 7189 } 7190 anyChanges = true; 7191 } 7192 } 7193 if (anyChanges) { 7194 this.currentViewOptionsInput = raw; 7195 this.currentViewOptionsRefined = refined; 7196 } 7197 return { 7198 rawOptions: this.currentViewOptionsInput, 7199 refinedOptions: this.currentViewOptionsRefined, 7200 extra: extra, 7201 }; 7202 }; 7203 return CalendarDataManager; 7204 }()); 7205 function buildDateEnv(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) { 7206 var locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map); 7207 return new DateEnv({ 7208 calendarSystem: 'gregory', 7209 timeZone: timeZone, 7210 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 7211 locale: locale, 7212 weekNumberCalculation: weekNumberCalculation, 7213 firstDay: firstDay, 7214 weekText: weekText, 7215 cmdFormatter: pluginHooks.cmdFormatter, 7216 defaultSeparator: defaultSeparator, 7217 }); 7218 } 7219 function buildTheme(options, pluginHooks) { 7220 var ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 7221 return new ThemeClass(options); 7222 } 7223 function buildDateProfileGenerator(props) { 7224 var DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator; 7225 return new DateProfileGeneratorClass(props); 7226 } 7227 function buildViewApi(type, getCurrentData, dateEnv) { 7228 return new ViewApi(type, getCurrentData, dateEnv); 7229 } 7230 function buildEventUiBySource(eventSources) { 7231 return mapHash(eventSources, function (eventSource) { return eventSource.ui; }); 7232 } 7233 function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 7234 var eventUiBases = { '': eventUiSingleBase }; 7235 for (var defId in eventDefs) { 7236 var def = eventDefs[defId]; 7237 if (def.sourceId && eventUiBySource[def.sourceId]) { 7238 eventUiBases[defId] = eventUiBySource[def.sourceId]; 7239 } 7240 } 7241 return eventUiBases; 7242 } 7243 function buildViewUiProps(calendarContext) { 7244 var options = calendarContext.options; 7245 return { 7246 eventUiSingleBase: createEventUi({ 7247 display: options.eventDisplay, 7248 editable: options.editable, 7249 startEditable: options.eventStartEditable, 7250 durationEditable: options.eventDurationEditable, 7251 constraint: options.eventConstraint, 7252 overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined, 7253 allow: options.eventAllow, 7254 backgroundColor: options.eventBackgroundColor, 7255 borderColor: options.eventBorderColor, 7256 textColor: options.eventTextColor, 7257 color: options.eventColor, 7258 // classNames: options.eventClassNames // render hook will handle this 7259 }, calendarContext), 7260 selectionConfig: createEventUi({ 7261 constraint: options.selectConstraint, 7262 overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined, 7263 allow: options.selectAllow, 7264 }, calendarContext), 7265 }; 7266 } 7267 function computeIsLoading(state, context) { 7268 for (var _i = 0, _a = context.pluginHooks.isLoadingFuncs; _i < _a.length; _i++) { 7269 var isLoadingFunc = _a[_i]; 7270 if (isLoadingFunc(state)) { 7271 return true; 7272 } 7273 } 7274 return false;
7275 } 7276 function parseContextBusinessHours(calendarContext) { 7277 return parseBusinessHours(calendarContext.options.businessHours, calendarContext); 7278 } 7279 function warnUnknownOptions(options, viewName) { 7280 for (var optionName in options) { 7281 console.warn("Unknown option '" + optionName + "'" + 7282 (viewName ? " for view '" + viewName + "'" : '')); 7283 } 7284 } 7285 7286 // TODO: move this to react plugin? 7287 var CalendarDataProvider = /** @class */ (function (_super) { 7288 __extends(CalendarDataProvider, _super); 7289 function CalendarDataProvider(props) { 7290 var _this = _super.call(this, props) || this; 7291 _this.handleData = function (data) { 7292 if (!_this.dataManager) { // still within initial run, before assignment in constructor 7293 // eslint-disable-next-line react/no-direct-mutation-state 7294 _this.state = data; // can't use setState yet 7295 } 7296 else { 7297 _this.setState(data); 7298 } 7299 }; 7300 _this.dataManager = new CalendarDataManager({ 7301 optionOverrides: props.optionOverrides, 7302 calendarApi: props.calendarApi, 7303 onData: _this.handleData, 7304 }); 7305 return _this; 7306 } 7307 CalendarDataProvider.prototype.render = function () { 7308 return this.props.children(this.state); 7309 }; 7310 CalendarDataProvider.prototype.componentDidUpdate = function (prevProps) { 7311 var newOptionOverrides = this.props.optionOverrides; 7312 if (newOptionOverrides !== prevProps.optionOverrides) { // prevent recursive handleData 7313 this.dataManager.resetOptions(newOptionOverrides); 7314 } 7315 }; 7316 return CalendarDataProvider; 7317 }(Component)); 7318 7319 // HELPERS 7320 /* 7321 if nextDayThreshold is specified, slicing is done in an all-day fashion. 7322 you can get nextDayThreshold from context.nextDayThreshold 7323 */ 7324 function sliceEvents(props, allDay) { 7325 return sliceEventStore(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg; 7326 } 7327 7328 var NamedTimeZoneImpl = /** @class */ (function () { 7329 function NamedTimeZoneImpl(timeZoneName) { 7330 this.timeZoneName = timeZoneName; 7331 } 7332 return NamedTimeZoneImpl; 7333 }()); 7334 7335 var SegHierarchy = /** @class */ (function () { 7336 function SegHierarchy() { 7337 // settings 7338 this.strictOrder = false; 7339 this.allowReslicing = false; 7340 this.maxCoord = -1; // -1 means no max 7341 this.maxStackCnt = -1; // -1 means no max 7342 this.levelCoords = []; // ordered 7343 this.entriesByLevel = []; // parallel with levelCoords 7344 this.stackCnts = {}; // TODO: use better technique!? 7345 } 7346 SegHierarchy.prototype.addSegs = function (segInputs) { 7347 var hiddenEntries = []; 7348 for (var _i = 0, segInputs_1 = segInputs; _i < segInputs_1.length; _i++) { 7349 var segInput = segInputs_1[_i]; 7350 this.insertEntry({ 7351 segInput: segInput, 7352 spanStart: segInput.spanStart, 7353 spanEnd: segInput.spanEnd, 7354 thickness: segInput.thickness, 7355 }, hiddenEntries); 7356 } 7357 return hiddenEntries; 7358 }; 7359 SegHierarchy.prototype.insertEntry = function (entry, hiddenEntries) { 7360 var insertion = this.findInsertion(entry); 7361 if (this.isInsertionValid(insertion, entry)) { 7362 this.insertEntryAt(entry, insertion); 7363 return 1; 7364 } 7365 return this.handleInvalidInsertion(insertion, entry, hiddenEntries); 7366 }; 7367 SegHierarchy.prototype.isInsertionValid = function (insertion, entry) { 7368 return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) && 7369 (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt); 7370 }; 7371 SegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) {
7372 if (this.allowReslicing && insertion.touchingEntry) { 7373 return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries); 7374 } 7375 hiddenEntries.push(entry); 7376 return 0; 7377 }; 7378 SegHierarchy.prototype.splitEntry = function (entry, barrier, hiddenEntries) { 7379 var partCnt = 0; 7380 var splitHiddenEntries = []; 7381 if (entry.spanStart < barrier.spanStart) { 7382 partCnt += this.insertEntry(__assign(__assign({}, entry), { spanStart: entry.spanStart, spanEnd: barrier.spanStart }), splitHiddenEntries); 7383 } 7384 if (barrier.spanEnd < entry.spanEnd) { 7385 partCnt += this.insertEntry(__assign(__assign({}, entry), { spanStart: barrier.spanEnd, spanEnd: entry.spanEnd }), splitHiddenEntries); 7386 } 7387 if (partCnt) { 7388 hiddenEntries.push.apply(hiddenEntries, __spreadArray([__assign(__assign({}, entry), { spanStart: Math.max(barrier.spanStart, entry.spanStart), spanEnd: Math.min(barrier.spanEnd, entry.spanEnd) })], splitHiddenEntries)); 7389 return partCnt; 7390 } 7391 hiddenEntries.push(entry); 7392 return 0; 7393 }; 7394 SegHierarchy.prototype.insertEntryAt = function (entry, insertion) { 7395 var nextLevel = insertion.nextLevel; 7396 // create a new level 7397 if (!nextLevel || this.levelCoords[nextLevel - 1] < insertion.levelCoord) { 7398 insertAt(this.levelCoords, nextLevel, insertion.levelCoord); 7399 insertAt(this.entriesByLevel, nextLevel, [entry]); 7400 // insert into existing level 7401 } 7402 else { 7403 insertAt(this.entriesByLevel[nextLevel - 1], insertion.lateralEnd, entry); 7404 } 7405 this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt; 7406 }; 7407 SegHierarchy.prototype.findInsertion = function (newEntry) { 7408 var _a = this, levelCoords = _a.levelCoords, entriesByLevel = _a.entriesByLevel, stackCnts = _a.stackCnts, strictOrder = _a.strictOrder; 7409 var levelCnt = levelCoords.length; 7410 var level; // running value while iterating all segs 7411 var levelCoord; // " 7412 var lateralStart = 0; // " 7413 var lateralEnd = 0; // " 7414 var resCoord = 0; // the levelCoord for newSeg 7415 var touchingEntry = null; 7416 for (level = 0; level < levelCnt; level += 1) { 7417 levelCoord = levelCoords[level]; 7418 // if the current level is past the placed entry, we have found a good 7419 // empty space and can stop. only if not strict-ordering mode. 7420 if (!strictOrder && levelCoord >= resCoord + newEntry.thickness) { 7421 break; 7422 } 7423 var entries = entriesByLevel[level]; 7424 var entry = void 0; 7425 var searchRes = binarySearch(entries, newEntry.spanStart, getEntrySpanEnd); 7426 lateralStart = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one 7427 lateralEnd = lateralStart; 7428 while ( // loop through entries that horizontally intersect 7429 (entry = entries[lateralEnd]) && // but not past the whole entry list 7430 entry.spanStart < newEntry.spanEnd) { 7431 if (strictOrder || 7432 ( // vertically intersects? 7433 resCoord < levelCoord + entry.thickness && 7434 resCoord + newEntry.thickness > levelCoord)) { 7435 // push down the potential destination 7436 touchingEntry = entry; 7437 resCoord = levelCoord + entry.thickness; // move to bottom of colliding entry 7438 } 7439 lateralEnd += 1; 7440 } 7441 } 7442 return { 7443 levelCoord: resCoord, 7444 nextLevel: level, 7445 lateralStart: lateralStart, 7446 lateralEnd: lateralEnd, 7447 touchingEntry: touchingEntry, 7448 stackCnt: touchingEntry ? stackCnts[buildEntryKey(touchingEntry
7448)] + 1 : 0, 7449 }; 7450 }; 7451 // sorted by levelCoord (lowest to highest) 7452 SegHierarchy.prototype.toRects = function () { 7453 var _a = this, entriesByLevel = _a.entriesByLevel, levelCoords = _a.levelCoords; 7454 var levelCnt = entriesByLevel.length; 7455 var rects = []; 7456 for (var level = 0; level < levelCnt; level += 1) { 7457 var entries = entriesByLevel[level]; 7458 var levelCoord = levelCoords[level]; 7459 for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { 7460 var entry = entries_1[_i]; 7461 rects.push(__assign(__assign({}, entry), { levelCoord: levelCoord })); 7462 } 7463 } 7464 return rects; 7465 }; 7466 return SegHierarchy; 7467 }()); 7468 function getEntrySpanEnd(entry) { 7469 return entry.spanEnd; 7470 } 7471 function buildEntryKey(entry) { 7472 return entry.segInput.index + ':' + entry.spanStart; 7473 } 7474 // returns groups with entries sorted by input order 7475 function groupIntersectingEntries(entries) { 7476 var merges = []; 7477 for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { 7478 var entry = entries_2[_i]; 7479 var filteredMerges = []; 7480 var hungryMerge = { 7481 spanStart: entry.spanStart, 7482 spanEnd: entry.spanEnd, 7483 entries: [entry], 7484 }; 7485 for (var _a = 0, merges_1 = merges; _a < merges_1.length; _a++) { 7486 var merge = merges_1[_a]; 7487 if (merge.spanStart < hungryMerge.spanEnd && merge.spanEnd > hungryMerge.spanStart) { // collides? 7488 hungryMerge = { 7489 spanStart: Math.min(merge.spanStart, hungryMerge.spanStart), 7490 spanEnd: Math.max(merge.spanEnd, hungryMerge.spanEnd), 7491 entries: merge.entries.concat(hungryMerge.entries), // keep preexisting merge's items first. maintains order 7492 }; 7493 } 7494 else { 7495 filteredMerges.push(merge); 7496 } 7497 } 7498 filteredMerges.push(hungryMerge); 7499 merges = filteredMerges; 7500 } 7501 return merges; 7502 } 7503 // general util 7504 // --------------------------------------------------------------------------------------------------------------------- 7505 function insertAt(arr, index, item) { 7506 arr.splice(index, 0, item); 7507 } 7508 function binarySearch(a, searchVal, getItemVal) { 7509 var startIndex = 0; 7510 var endIndex = a.length; // exclusive 7511 if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item 7512 return [0, 0]; 7513 } 7514 if (searchVal > getItemVal(a[endIndex - 1])) { // after last item 7515 return [endIndex, 0]; 7516 } 7517 while (startIndex < endIndex) { 7518 var middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2); 7519 var middleVal = getItemVal(a[middleIndex]); 7520 if (searchVal < middleVal) { 7521 endIndex = middleIndex; 7522 } 7523 else if (searchVal > middleVal) { 7524 startIndex = middleIndex + 1; 7525 } 7526 else { // equal! 7527 return [middleIndex, 1]; 7528 } 7529 } 7530 return [startIndex, 0]; 7531 } 7532 7533 var Interaction = /** @class */ (function () { 7534 function Interaction(settings) { 7535 this.component = settings.component; 7536 this.isHitComboAllowed = settings.isHitComboAllowed || null; 7537 } 7538 Interaction.prototype.destroy = function () { 7539 }; 7540 return Interaction; 7541 }()); 7542 function parseInteractionSettings(component, input) { 7543 return { 7544 component: component, 7545 el: input.el, 7546 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true, 7547 isHitComboAllowed: input.isHitComboAllowed || null, 7548 }; 7549 } 7550 function interactionSettingsToStore(settings) { 7551 var _a; 7552 return _a = {}, 7553 _a[settings.component.uid] = settings, 7554 _a; 7555 } 7556 // global state 7557 var interactionSettingsStore = {}; 7558 7559 /* 7560 An abstraction for a dragging interaction originating on an event. 7561 Does higher-level things than PointerDragger, such as possibly: 7562 - a "mirror" that moves with the pointer 7563 - a minimum number of pixels or other criteria for a true drag to begin 7564 7565 subclasses must emit: 7566 - pointerdown 7567 - dragstart 7568 - dragmove 7569 - pointerup 7570 - dragend 7571 */ 7572 var ElementDragging = /** @class */ (function () { 7573 function ElementDragging(el, selector) { 7574 this.emitter = new Emitter(); 7575 } 7576 ElementDragging.prototype.destroy = function () { 7577 }; 7578 ElementDragging.prototype.setMirrorIsVisible = function (bool) {
7579 // optional if subclass doesn't want to support a mirror 7580 }; 7581 ElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 7582 // optional if subclass doesn't want to support a mirror 7583 }; 7584 ElementDragging.prototype.setAutoScrollEnabled = function (bool) { 7585 // optional 7586 }; 7587 return ElementDragging; 7588 }()); 7589 7590 // TODO: get rid of this in favor of options system, 7591 // tho it's really easy to access this globally rather than pass thru options. 7592 var config = {}; 7593 7594 /* 7595 Information about what will happen when an external element is dragged-and-dropped 7596 onto a calendar. Contains information for creating an event. 7597 */ 7598 var DRAG_META_REFINERS = { 7599 startTime: createDuration, 7600 duration: createDuration, 7601 create: Boolean, 7602 sourceId: String, 7603 }; 7604 function parseDragMeta(raw) { 7605 var _a = refineProps(raw, DRAG_META_REFINERS), refined = _a.refined, extra = _a.extra; 7606 return { 7607 startTime: refined.startTime || null, 7608 duration: refined.duration || null, 7609 create: refined.create != null ? refined.create : true, 7610 sourceId: refined.sourceId, 7611 leftoverProps: extra, 7612 }; 7613 } 7614 7615 var ToolbarSection = /** @class */ (function (_super) { 7616 __extends(ToolbarSection, _super); 7617 function ToolbarSection() { 7618 return _super !== null && _super.apply(this, arguments) || this; 7619 } 7620 ToolbarSection.prototype.render = function () { 7621 var _this = this; 7622 var children = this.props.widgetGroups.map(function (widgetGroup) { return _this.renderWidgetGroup(widgetGroup); }); 7623 return createElement.apply(void 0, __spreadArray(['div', { className: 'fc-toolbar-chunk' }], children)); 7624 }; 7625 ToolbarSection.prototype.renderWidgetGroup = function (widgetGroup) { 7626 var props = this.props; 7627 var theme = this.context.theme; 7628 var children = []; 7629 var isOnlyButtons = true; 7630 for (var _i = 0, widgetGroup_1 = widgetGroup; _i < widgetGroup_1.length; _i++) { 7631 var widget = widgetGroup_1[_i]; 7632 var buttonName = widget.buttonName, buttonClick = widget.buttonClick, buttonText = widget.buttonText, buttonIcon = widget.buttonIcon; 7633 if (buttonName === 'title') { 7634 isOnlyButtons = false; 7635 children.push(createElement("h2", { className: "fc-toolbar-title" }, props.title)); 7636 } 7637 else { 7638 var ariaAttrs = buttonIcon ? { 'aria-label': buttonName } : {}; 7639 var buttonClasses = ["fc-" + buttonName + "-button", theme.getClass('button')]; 7640 if (buttonName === props.activeButton) { 7641 buttonClasses.push(theme.getClass('buttonActive')); 7642 } 7643 var isDisabled = (!props.isTodayEnabled && buttonName === 'today') || 7644 (!props.isPrevEnabled && buttonName === 'prev') || 7645 (!props.isNextEnabled && buttonName === 'next'); 7646 children.push(createElement("button", __assign({ disabled: isDisabled, className: buttonClasses.join(' '), onClick: buttonClick, type: "button" }, ariaAttrs), buttonText || (buttonIcon ? createElement("span", { className: buttonIcon }) : ''))); 7647 } 7648 } 7649 if (children.length > 1) { 7650 var groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || ''; 7651 return createElement.apply(void 0, __spreadArray(['div', { className: groupClassName }], children)); 7652 } 7653 return children[0]; 7654 }; 7655 return ToolbarSection; 7656 }(BaseComponent)); 7657 7658 var Toolbar = /** @class */ (function (_super) { 7659 __extends(Toolbar, _super); 7660 function Toolbar() { 7661 return _super !== null && _super.apply(this, arguments) || this; 7662 } 7663 Toolbar.prototype.render = function () { 7664 var _a = this.props, model = _a.model, extraClassName = _a.extraClassName; 7665 var forceLtr = false;
7666 var startContent; 7667 var endContent; 7668 var centerContent = model.center; 7669 if (model.left) { 7670 forceLtr = true; 7671 startContent = model.left; 7672 } 7673 else { 7674 startContent = model.start; 7675 } 7676 if (model.right) { 7677 forceLtr = true; 7678 endContent = model.right; 7679 } 7680 else { 7681 endContent = model.end; 7682 } 7683 var classNames = [ 7684 extraClassName || '', 7685 'fc-toolbar', 7686 forceLtr ? 'fc-toolbar-ltr' : '', 7687 ]; 7688 return (createElement("div", { className: classNames.join(' ') }, 7689 this.renderSection('start', startContent || []), 7690 this.renderSection('center', centerContent || []), 7691 this.renderSection('end', endContent || []))); 7692 }; 7693 Toolbar.prototype.renderSection = function (key, widgetGroups) { 7694 var props = this.props; 7695 return (createElement(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled })); 7696 }; 7697 return Toolbar; 7698 }(BaseComponent)); 7699 7700 // TODO: do function component? 7701 var ViewContainer = /** @class */ (function (_super) { 7702 __extends(ViewContainer, _super); 7703 function ViewContainer() { 7704 var _this = _super !== null && _super.apply(this, arguments) || this; 7705 _this.state = { 7706 availableWidth: null, 7707 }; 7708 _this.handleEl = function (el) { 7709 _this.el = el; 7710 setRef(_this.props.elRef, el); 7711 _this.updateAvailableWidth(); 7712 }; 7713 _this.handleResize = function () { 7714 _this.updateAvailableWidth(); 7715 }; 7716 return _this; 7717 } 7718 ViewContainer.prototype.render = function () { 7719 var _a = this, props = _a.props, state = _a.state; 7720 var aspectRatio = props.aspectRatio; 7721 var classNames = [ 7722 'fc-view-harness', 7723 (aspectRatio || props.liquid || props.height) 7724 ? 'fc-view-harness-active' // harness controls the height 7725 : 'fc-view-harness-passive', // let the view do the height 7726 ]; 7727 var height = ''; 7728 var paddingBottom = ''; 7729 if (aspectRatio) { 7730 if (state.availableWidth !== null) { 7731 height = state.availableWidth / aspectRatio; 7732 } 7733 else { 7734 // while waiting to know availableWidth, we can't set height to *zero* 7735 // because will cause lots of unnecessary scrollbars within scrollgrid. 7736 // BETTER: don't start rendering ANYTHING yet until we know container width 7737 // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606) 7738 paddingBottom = (1 / aspectRatio) * 100 + "%"; 7739 } 7740 } 7741 else { 7742 height = props.height || ''; 7743 } 7744 return (createElement("div", { ref: this.handleEl, onClick: props.onClick, className: classNames.join(' '), style: { height: height, paddingBottom: paddingBottom } }, props.children)); 7745 }; 7746 ViewContainer.prototype.componentDidMount = function () { 7747 this.context.addResizeHandler(this.handleResize); 7748 }; 7749 ViewContainer.prototype.componentWillUnmount = function () { 7750 this.context.removeResizeHandler(this.handleResize); 7751 }; 7752 ViewContainer.prototype.updateAvailableWidth = function () { 7753 if (this.el && // needed. but why? 7754 this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth 7755 ) { 7756 this.setState({ availableWidth: this.el.offsetWidth }); 7757 } 7758 }; 7759 return ViewContainer; 7760 }(BaseComponent)); 7761 7762 /* 7763 Detects when the user clicks on an event within a DateComponent 7764 */ 7765 var EventClicking = /** @class */ (function (_super) { 7766 __extends(EventClicking, _super);
7767 function EventClicking(settings) { 7768 var _this = _super.call(this, settings) || this; 7769 _this.handleSegClick = function (ev, segEl) { 7770 var component = _this.component; 7771 var context = component.context; 7772 var seg = getElSeg(segEl); 7773 if (seg && // might be the <div> surrounding the more link 7774 component.isValidSegDownEl(ev.target)) { 7775 // our way to simulate a link click for elements that can't be <a> tags 7776 // grab before trigger fired in case trigger trashes DOM thru rerendering 7777 var hasUrlContainer = elementClosest(ev.target, '.fc-event-forced-url'); 7778 var url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : ''; 7779 context.emitter.trigger('eventClick', { 7780 el: segEl, 7781 event: new EventApi(component.context, seg.eventRange.def, seg.eventRange.instance), 7782 jsEvent: ev, 7783 view: context.viewApi, 7784 }); 7785 if (url && !ev.defaultPrevented) { 7786 window.location.href = url; 7787 } 7788 } 7789 }; 7790 _this.destroy = listenBySelector(settings.el, 'click', '.fc-event', // on both fg and bg events 7791 _this.handleSegClick); 7792 return _this; 7793 } 7794 return EventClicking; 7795 }(Interaction)); 7796 7797 /* 7798 Triggers events and adds/removes core classNames when the user's pointer 7799 enters/leaves event-elements of a component. 7800 */ 7801 var EventHovering = /** @class */ (function (_super) { 7802 __extends(EventHovering, _super); 7803 function EventHovering(settings) { 7804 var _this = _super.call(this, settings) || this; 7805 // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it 7806 _this.handleEventElRemove = function (el) { 7807 if (el === _this.currentSegEl) { 7808 _this.handleSegLeave(null, _this.currentSegEl); 7809 } 7810 }; 7811 _this.handleSegEnter = function (ev, segEl) { 7812 if (getElSeg(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper 7813 _this.currentSegEl = segEl; 7814 _this.triggerEvent('eventMouseEnter', ev, segEl); 7815 } 7816 }; 7817 _this.handleSegLeave = function (ev, segEl) { 7818 if (_this.currentSegEl) { 7819 _this.currentSegEl = null; 7820 _this.triggerEvent('eventMouseLeave', ev, segEl); 7821 } 7822 }; 7823 _this.removeHoverListeners = listenToHoverBySelector(settings.el, '.fc-event', // on both fg and bg events 7824 _this.handleSegEnter, _this.handleSegLeave); 7825 return _this; 7826 } 7827 EventHovering.prototype.destroy = function () { 7828 this.removeHoverListeners(); 7829 }; 7830 EventHovering.prototype.triggerEvent = function (publicEvName, ev, segEl) { 7831 var component = this.component; 7832 var context = component.context; 7833 var seg = getElSeg(segEl); 7834 if (!ev || component.isValidSegDownEl(ev.target)) { 7835 context.emitter.trigger(publicEvName, { 7836 el: segEl, 7837 event: new EventApi(context, seg.eventRange.def, seg.eventRange.instance), 7838 jsEvent: ev, 7839 view: context.viewApi, 7840 }); 7841 } 7842 }; 7843 return EventHovering; 7844 }(Interaction)); 7845 7846 var CalendarContent = /** @class */ (function (_super) { 7847 __extends(CalendarContent, _super); 7848 function CalendarContent() { 7849 var _this = _super !== null && _super.apply(this, arguments) || this; 7850 _this.buildViewContext = memoize(buildViewContext); 7851 _this.buildViewPropTransformers = memoize(buildViewPropTransformers); 7852 _this.buildToolbarProps = memoize(buildToolbarProps); 7853 _this.handleNavLinkClick = buildDelegationHandler('a[data-navlink]', _this._handleNavLinkClick.bind(_this)); 7854 _this.headerRef = createRef(); 7855 _this.footerRef = createRef(); 7856 _this.interactionsStore = {}; 7857 // Component Registration 7858 // ----------------------------------------------------------------------------------------------------------------- 7859 _this.registerInteractiveComponent = function (component, settingsInput) { 7860 var settings = parseInteractionSettings(component, settingsInput); 7861 var DEFAULT_INTERACTIONS = [ 7862 EventClicking, 7863 EventHovering, 7864 ]; 7865 var interactionClasses = DEFAULT_INTERACTIONS.concat(_this.props.pluginHooks.componentInteractions); 7866 var interactions = interactionClasses.map(function (TheInteractionClass) { return new TheInteractionClass(settings); }); 7867 _this.interactionsStore[component.uid] = interactions; 7868 interactionSettingsStore[component.uid] = settings; 7869 }; 7870 _this.unregisterInteractiveComponent = function (component) { 7871 for (var _i = 0, _a = _this.interactionsStore[component.uid]; _i < _a.length; _i++) { 7872 var listener = _a[_i]; 7873 listener.destroy(); 7874 } 7875 delete _this.interactionsStore[component.uid]; 7876 delete interactionSettingsStore[component.uid]; 7877 }; 7878 // Resizing 7879 // ----------------------------------------------------------------------------------------------------------------- 7880 _this.resizeRunner = new DelayedRunner(function () { 7881 _this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ? 7882 _this.props.emitter.trigger('windowResize', { view: _this.props.viewApi }); 7883 }); 7884 _this.handleWindowResize = function (ev) { 7885 var options = _this.props.options; 7886 if (options.handleWindowResize && 7887 ev.target === window // avoid jqui events 7888 ) { 7889 _this.resizeRunner.request(options.windowResizeDelay); 7890 } 7891 }; 7892 return _this; 7893 } 7894 /* 7895 renders INSIDE of an outer div 7896 */ 7897 CalendarContent.prototype.render = function () { 7898 var props = this.props; 7899 var toolbarConfig = props.toolbarConfig, options = props.options; 7900 var toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, getNow(props.options.now, props.dateEnv), // TODO: use NowTimer???? 7901 props.viewTitle); 7902 var viewVGrow = false;
7903 var viewHeight = ''; 7904 var viewAspectRatio; 7905 if (props.isHeightAuto || props.forPrint) { 7906 viewHeight = ''; 7907 } 7908 else if (options.height != null) { 7909 viewVGrow = true; 7910 } 7911 else if (options.contentHeight != null) { 7912 viewHeight = options.contentHeight; 7913 } 7914 else { 7915 viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall 7916 } 7917 var viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent); 7918 return (createElement(ViewContextType.Provider, { value: viewContext }, 7919 toolbarConfig.headerToolbar && (createElement(Toolbar, __assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.headerToolbar }, toolbarProps))), 7920 createElement(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, onClick: this.handleNavLinkClick }, 7921 this.renderView(props), 7922 this.buildAppendContent()), 7923 toolbarConfig.footerToolbar && (createElement(Toolbar, __assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footerToolbar }, toolbarProps))))); 7924 }; 7925 CalendarContent.prototype.componentDidMount = function () { 7926 var props = this.props; 7927 this.calendarInteractions = props.pluginHooks.calendarInteractions 7928 .map(function (CalendarInteractionClass) { return new CalendarInteractionClass(props); }); 7929 window.addEventListener('resize', this.handleWindowResize); 7930 var propSetHandlers = props.pluginHooks.propSetHandlers; 7931 for (var propName in propSetHandlers) { 7932 propSetHandlers[propName](props[propName], props); 7933 } 7934 }; 7935 CalendarContent.prototype.componentDidUpdate = function (prevProps) { 7936 var props = this.props; 7937 var propSetHandlers = props.pluginHooks.propSetHandlers; 7938 for (var propName in propSetHandlers) { 7939 if (props[propName] !== prevProps[propName]) { 7940 propSetHandlers[propName](props[propName], props); 7941 } 7942 } 7943 }; 7944 CalendarContent.prototype.componentWillUnmount = function () { 7945 window.removeEventListener('resize', this.handleWindowResize); 7946 this.resizeRunner.clear(); 7947 for (var _i = 0, _a = this.calendarInteractions; _i < _a.length; _i++) { 7948 var interaction = _a[_i]; 7949 interaction.destroy(); 7950 } 7951 this.props.emitter.trigger('_unmount'); 7952 }; 7953 CalendarContent.prototype._handleNavLinkClick = function (ev, anchorEl) { 7954 var _a = this.props, dateEnv = _a.dateEnv, options = _a.options, calendarApi = _a.calendarApi; 7955 var navLinkOptions = anchorEl.getAttribute('data-navlink'); 7956 navLinkOptions = navLinkOptions ? JSON.parse(navLinkOptions) : {}; 7957 var dateMarker = dateEnv.createMarker(navLinkOptions.date); 7958 var viewType = navLinkOptions.type; 7959 var customAction = viewType === 'day' ? options.navLinkDayClick : 7960 viewType === 'week' ? options.navLinkWeekClick : null; 7961 if (typeof customAction === 'function') { 7962 customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev); 7963 } 7964 else { 7965 if (typeof customAction === 'string') { 7966 viewType = customAction; 7967 } 7968 calendarApi.zoomTo(dateMarker, viewType); 7969 } 7970 }; 7971 CalendarContent.prototype.buildAppendContent = function () { 7972 var props = this.props; 7973 var children = props.pluginHooks.viewContainerAppends.map(function (buildAppendContent) { return buildAppendContent(props); }); 7974 return createElement.apply(void 0, __spreadArray([Fragment, {}], children)); 7975 }; 7976 CalendarContent.prototype.renderView = function (props) { 7977 var pluginHooks = props.pluginHooks; 7978 var viewSpec = props.viewSpec; 7979 var viewProps = { 7980 dateProfile: props.dateProfile, 7981 businessHours: props.businessHours, 7982 eventStore: props.renderableEventStore, 7983 eventUiBases: props.eventUiBases, 7984 dateSelection: props.dateSelection, 7985 eventSelection: props.eventSelection, 7986 eventDrag: props.eventDrag, 7987 eventResize: props.eventResize, 7988 isHeightAuto: props.isHeightAuto, 7989 forPrint: props.forPrint, 7990 }; 7991 var transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers); 7992 for (var _i = 0, transformers_1 = transformers; _i < transformers_1.length; _i++) { 7993 var transformer = transformers_1[_i]; 7994 __assign(viewProps, transformer.transform(viewProps, props)); 7995 } 7996 var ViewComponent = viewSpec.component; 7997 return (createElement(ViewComponent, __assign({}, viewProps))); 7998 }; 7999 return CalendarContent; 8000 }(PureComponent)); 8001 function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) { 8002 // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid 8003 var todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason 8004 var prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false); 8005 var nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false); 8006 return { 8007 title: title, 8008 activeButton: viewSpec.type, 8009 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 8010 isPrevEnabled: prevInfo.isValid, 8011 isNextEnabled: nextInfo.isValid, 8012 }; 8013 } 8014 // Plugin 8015 // ----------------------------------------------------------------------------------------------------------------- 8016 function buildViewPropTransformers(theClasses) { 8017 return theClasses.map(function (TheClass) { return new TheClass(); }); 8018 } 8019 8020 var CalendarRoot = /** @class */ (function (_super) { 8021 __extends(CalendarRoot, _super); 8022 function CalendarRoot() { 8023 var _this = _super !== null && _super.apply(this, arguments) || this; 8024 _this.state = { 8025 forPrint: false, 8026 }; 8027 _this.handleBeforePrint = function () { 8028 _this.setState({ forPrint: true }); 8029 }; 8030 _this.handleAfterPrint = function () { 8031 _this.setState({ forPrint: false }); 8032 }; 8033 return _this; 8034 } 8035 CalendarRoot.prototype.render = function () { 8036 var props = this.props; 8037 var options = props.options; 8038 var forPrint = this.state.forPrint; 8039 var isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto'; 8040 var height = (!isHeightAuto && options.height != null) ? options.height : ''; 8041 var classNames = [ 8042 'fc', 8043 forPrint ? 'fc-media-print' : 'fc-media-screen', 8044 "fc-direction-" + options.direction, 8045 props.theme.getClass('root'), 8046 ]; 8047 if (!getCanVGrowWithinCell()) { 8048 classNames.push('fc-liquid-hack'); 8049 } 8050 return props.children(classNames, height, isHeightAuto, forPrint); 8051 }; 8052 CalendarRoot.prototype.componentDidMount = function () { 8053 var emitter = this.props.emitter; 8054 emitter.on('_beforeprint', this.handleBeforePrint); 8055 emitter.on('_afterprint', this.handleAfterPrint); 8056 }; 8057 CalendarRoot.prototype.componentWillUnmount = function () { 8058 var emitter = this.props.emitter; 8059 emitter.off('_beforeprint', this.handleBeforePrint); 8060 emitter.off('_afterprint', this.handleAfterPrint); 8061 }; 8062 return CalendarRoot; 8063 }(BaseComponent)); 8064 8065 // Computes a default column header formatting string if `colFormat` is not explicitly defined 8066 function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 8067 // if more than one week row, or if there are a lot of columns with not much space, 8068 // put just the day numbers will be in each cell 8069 if (!datesRepDistinctDays || dayCnt > 10) { 8070 return createFormatter({ weekday: 'short' }); // "Sat" 8071 } 8072 if (dayCnt > 1) { 8073 return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // "Sat 11/12" 8074 } 8075 return createFormatter({ weekday: 'long' }); // "Saturday" 8076 } 8077 8078 var CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no 8079 function renderInner$1(hookProps) { 8080 return hookProps.text; 8081 } 8082 8083 var TableDateCell = /** @class */ (function (_super) { 8084 __extends(TableDateCell, _super); 8085 function TableDateCell() { 8086 return _super !== null && _super.apply(this, arguments) || this; 8087 } 8088 TableDateCell.prototype.render = function () { 8089 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options, theme = _a.theme, viewApi = _a.viewApi; 8090 var props = this.props; 8091 var date = props.date, dateProfile = props.dateProfile;
8092 var dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 8093 var classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 8094 var text = dateEnv.format(date, props.dayHeaderFormat); 8095 // if colCnt is 1, we are already in a day-view and don't need a navlink 8096 var navLinkAttrs = (options.navLinks && !dayMeta.isDisabled && props.colCnt > 1) 8097 ? { 'data-navlink': buildNavLinkData(date), tabIndex: 0 } 8098 : {}; 8099 var hookProps = __assign(__assign(__assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraHookProps), { text: text }), dayMeta); 8100 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": !dayMeta.isDisabled ? formatDayString(date) : undefined, colSpan: props.colSpan }, props.extraDataAttrs), 8101 createElement("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && (createElement("a", __assign({ ref: innerElRef, className: [ 8102 'fc-col-header-cell-cushion', 8103 props.isSticky ? 'fc-sticky' : '', 8104 ].join(' ') }, navLinkAttrs), innerContent))))); })); 8105 }; 8106 return TableDateCell; 8107 }(BaseComponent)); 8108 8109 var TableDowCell = /** @class */ (function (_super) { 8110 __extends(TableDowCell, _super); 8111 function TableDowCell() { 8112 return _super !== null && _super.apply(this, arguments) || this; 8113 } 8114 TableDowCell.prototype.render = function () { 8115 var props = this.props; 8116 var _a = this.context, dateEnv = _a.dateEnv, theme = _a.theme, viewApi = _a.viewApi, options = _a.options; 8117 var date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT 8118 var dateMeta = { 8119 dow: props.dow, 8120 isDisabled: false, 8121 isFuture: false, 8122 isPast: false, 8123 isToday: false, 8124 isOther: false, 8125 }; 8126 var classNames = [CLASS_NAME].concat(getDayClassNames(dateMeta, theme), props.extraClassNames || []); 8127 var text = dateEnv.format(date, props.dayHeaderFormat); 8128 var hookProps = __assign(__assign(__assign(__assign({ // TODO: make this public? 8129 date: date }, dateMeta), { view: viewApi }), props.extraHookProps), { text: text }); 8130 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInner$1, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("th", __assign({ ref: rootElRef, className: classNames.concat(customClassNames).join(' '), colSpan: props.colSpan }, props.extraDataAttrs), 8131 createElement("div", { className: "fc-scrollgrid-sync-inner" }, 8132 createElement("a", { className: [ 8133 'fc-col-header-cell-cushion', 8134 props.isSticky ? 'fc-sticky' : '', 8135 ].join(' '), ref: innerElRef }, innerContent)))); })); 8136 }; 8137 return TableDowCell; 8138 }(BaseComponent)); 8139 8140 var NowTimer = /** @class */ (function (_super) { 8141 __extends(NowTimer, _super); 8142 function NowTimer(props, context) { 8143 var _this = _super.call(this, props, context) || this; 8144 _this.initialNowDate = getNow(context.options.now, context.dateEnv); 8145 _this.initialNowQueriedMs = new Date().valueOf(); 8146 _this.state = _this.computeTiming().currentState; 8147 return _this; 8148 } 8149 NowTimer.prototype.render = function () { 8150 var _a = this, props = _a.props, state = _a.state; 8151 return props.children(state.nowDate, state.todayRange); 8152 }; 8153 NowTimer.prototype.componentDidMount = function () { 8154 this.setTimeout(); 8155 }; 8156 NowTimer.prototype.componentDidUpdate = function (prevProps) { 8157 if (prevProps.unit !== this.props.unit) { 8158 this.clearTimeout(); 8159 this.setTimeout(); 8160 } 8161 }; 8162 NowTimer.prototype.componentWillUnmount = function () { 8163 this.clearTimeout(); 8164 }; 8165 NowTimer.prototype.computeTiming = function () { 8166 var _a = this, props = _a.props, context = _a.context; 8167 var unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs); 8168 var currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 8169 var nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit)); 8170 var waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 8171 // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342) 8172 // ensure no longer than a day 8173 waitMs = Math.min(1000 * 60 * 60 * 24, waitMs); 8174 return { 8175 currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) }, 8176 nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) }, 8177 waitMs: waitMs, 8178 }; 8179 }; 8180 NowTimer.prototype.setTimeout = function () { 8181 var _this = this; 8182 var _a = this.computeTiming(), nextState = _a.nextState, waitMs = _a.waitMs; 8183 this.timeoutId = setTimeout(function () { 8184 _this.setState(nextState, function () { 8185 _this.setTimeout(); 8186 }); 8187 }, waitMs); 8188 }; 8189 NowTimer.prototype.clearTimeout = function () { 8190 if (this.timeoutId) { 8191 clearTimeout(this.timeoutId); 8192 } 8193 }; 8194 NowTimer.contextType = ViewContextType; 8195 return NowTimer; 8196 }(Component)); 8197 function buildDayRange(date) { 8198 var start = startOfDay(date); 8199 var end = addDays(start, 1); 8200 return { start: start, end: end }; 8201 } 8202 8203 var DayHeader = /** @class */ (function (_super) { 8204 __extends(DayHeader, _super); 8205 function DayHeader() { 8206 var _this = _super !== null && _super.apply(this, arguments) || this; 8207 _this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 8208 return _this; 8209 } 8210 DayHeader.prototype.render = function () { 8211 var context = this.context; 8212 var _a = this.props, dates = _a.dates, dateProfile = _a.dateProfile, datesRepDistinctDays = _a.datesRepDistinctDays, renderIntro = _a.renderIntro; 8213 var dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length); 8214 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement("tr", null, 8215 renderIntro && renderIntro('day'), 8216 dates.map(function (date) { return (datesRepDistinctDays ? (createElement(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : (createElement(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))); }))); })); 8217 }; 8218 return DayHeader; 8219 }(BaseComponent)); 8220 function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) { 8221 return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt); 8222 } 8223
8224 var DaySeriesModel = /** @class */ (function () { 8225 function DaySeriesModel(range, dateProfileGenerator) { 8226 var date = range.start; 8227 var end = range.end; 8228 var indices = []; 8229 var dates = []; 8230 var dayIndex = -1; 8231 while (date < end) { // loop each day from start to end 8232 if (dateProfileGenerator.isHiddenDay(date)) { 8233 indices.push(dayIndex + 0.5); // mark that it's between indices 8234 } 8235 else { 8236 dayIndex += 1; 8237 indices.push(dayIndex); 8238 dates.push(date); 8239 } 8240 date = addDays(date, 1); 8241 } 8242 this.dates = dates; 8243 this.indices = indices; 8244 this.cnt = dates.length; 8245 } 8246 DaySeriesModel.prototype.sliceRange = function (range) { 8247 var firstIndex = this.getDateDayIndex(range.start); // inclusive first index 8248 var lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index 8249 var clippedFirstIndex = Math.max(0, firstIndex); 8250 var clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 8251 // deal with in-between indices 8252 clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell 8253 clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell 8254 if (clippedFirstIndex <= clippedLastIndex) { 8255 return { 8256 firstIndex: clippedFirstIndex, 8257 lastIndex: clippedLastIndex, 8258 isStart: firstIndex === clippedFirstIndex, 8259 isEnd: lastIndex === clippedLastIndex, 8260 }; 8261 } 8262 return null; 8263 }; 8264 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 8265 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 8266 // If before the first offset, returns a negative number. 8267 // If after the last offset, returns an offset past the last cell offset. 8268 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 8269 DaySeriesModel.prototype.getDateDayIndex = function (date) { 8270 var indices = this.indices; 8271 var dayOffset = Math.floor(diffDays(this.dates[0], date)); 8272 if (dayOffset < 0) { 8273 return indices[0] - 1; 8274 } 8275 if (dayOffset >= indices.length) { 8276 return indices[indices.length - 1] + 1; 8277 } 8278 return indices[dayOffset]; 8279 };
8280 return DaySeriesModel; 8281 }()); 8282 8283 var DayTableModel = /** @class */ (function () { 8284 function DayTableModel(daySeries, breakOnWeeks) { 8285 var dates = daySeries.dates; 8286 var daysPerRow; 8287 var firstDay; 8288 var rowCnt; 8289 if (breakOnWeeks) { 8290 // count columns until the day-of-week repeats 8291 firstDay = dates[0].getUTCDay(); 8292 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) { 8293 if (dates[daysPerRow].getUTCDay() === firstDay) { 8294 break; 8295 } 8296 } 8297 rowCnt = Math.ceil(dates.length / daysPerRow); 8298 } 8299 else { 8300 rowCnt = 1; 8301 daysPerRow = dates.length; 8302 } 8303 this.rowCnt = rowCnt; 8304 this.colCnt = daysPerRow; 8305 this.daySeries = daySeries; 8306 this.cells = this.buildCells(); 8307 this.headerDates = this.buildHeaderDates(); 8308 } 8309 DayTableModel.prototype.buildCells = function () { 8310 var rows = []; 8311 for (var row = 0; row < this.rowCnt; row += 1) { 8312 var cells = []; 8313 for (var col = 0; col < this.colCnt; col += 1) { 8314 cells.push(this.buildCell(row, col)); 8315 } 8316 rows.push(cells); 8317 } 8318 return rows; 8319 }; 8320 DayTableModel.prototype.buildCell = function (row, col) { 8321 var date = this.daySeries.dates[row * this.colCnt + col]; 8322 return { 8323 key: date.toISOString(), 8324 date: date, 8325 }; 8326 }; 8327 DayTableModel.prototype.buildHeaderDates = function () { 8328 var dates = []; 8329 for (var col = 0; col < this.colCnt; col += 1) { 8330 dates.push(this.cells[0][col].date); 8331 } 8332 return dates; 8333 }; 8334 DayTableModel.prototype.sliceRange = function (range) { 8335 var colCnt = this.colCnt; 8336 var seriesSeg = this.daySeries.sliceRange(range); 8337 var segs = []; 8338 if (seriesSeg) { 8339 var firstIndex = seriesSeg.firstIndex, lastIndex = seriesSeg.lastIndex; 8340 var index = firstIndex; 8341 while (index <= lastIndex) { 8342 var row = Math.floor(index / colCnt); 8343 var nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 8344 segs.push({ 8345 row: row, 8346 firstCol: index % colCnt, 8347 lastCol: (nextIndex - 1) % colCnt, 8348 isStart: seriesSeg.isStart && index === firstIndex, 8349 isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex, 8350 }); 8351 index = nextIndex; 8352 } 8353 } 8354 return segs; 8355 }; 8356 return DayTableModel; 8357 }()); 8358 8359 var Slicer = /** @class */ (function () { 8360 function Slicer() { 8361 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 8362 this.sliceDateSelection = memoize(this._sliceDateSpan); 8363 this.sliceEventStore = memoize(this._sliceEventStore); 8364 this.sliceEventDrag = memoize(this._sliceInteraction); 8365 this.sliceEventResize = memoize(this._sliceInteraction); 8366 this.forceDayIfListItem = false; // hack 8367 } 8368 Slicer.prototype.sliceProps = function (props, dateProfile, nextDayThreshold, context) { 8369 var extraArgs = []; 8370 for (var _i = 4; _i < arguments.length; _i++) { 8371 extraArgs[_i - 4] = arguments[_i]; 8372 } 8373 var eventUiBases = props.eventUiBases; 8374 var eventSegs = this.sliceEventStore.apply(this, __spreadArray([props.eventStore, eventUiBases, dateProfile, nextDayThreshold], extraArgs)); 8375 return { 8376 dateSelectionSegs: this.sliceDateSelection.apply(this, __spreadArray([props.dateSelection, eventUiBases, context], extraArgs)), 8377 businessHourSegs: this.sliceBusinessHours.apply(this, __spreadArray([props.businessHours, dateProfile, nextDayThreshold, context], extraArgs)), 8378 fgEventSegs: eventSegs.fg, 8379 bgEventSegs: eventSegs.bg, 8380 eventDrag: this.sliceEventDrag.apply(this, __spreadArray([props.eventDrag, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8381 eventResize: this.sliceEventResize.apply(this, __spreadArray([props.eventResize, eventUiBases, dateProfile, nextDayThreshold], extraArgs)), 8382 eventSelection: props.eventSelection, 8383 }; // TODO: give interactionSegs? 8384 }; 8385 Slicer.prototype.sliceNowDate = function (// does not memoize 8386 date, context) { 8387 var extraArgs = []; 8388 for (var _i = 2; _i < arguments.length; _i++) { 8389 extraArgs[_i - 2] = arguments[_i]; 8390 } 8391 return this._sliceDateSpan.apply(this, __spreadArray([{ range: { start: date, end: addMs(date, 1) }, allDay: false }, 8392 {}, 8393 context], extraArgs)); 8394 }; 8395 Slicer.prototype._sliceBusinessHours = function (businessHours, dateProfile, nextDayThreshold, context) { 8396 var extraArgs = []; 8397 for (var _i = 4; _i < arguments.length; _i++) { 8398 extraArgs[_i - 4] = arguments[_i]; 8399 } 8400 if (!businessHours) { 8401 return []; 8402 } 8403 return this._sliceEventStore.apply(this, __spreadArray([expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), 8404 {}, 8405 dateProfile, 8406 nextDayThreshold], extraArgs)).bg; 8407 }; 8408 Slicer.prototype._sliceEventStore = function (eventStore, eventUiBases, dateProfile, nextDayThreshold) { 8409 var extraArgs = []; 8410 for (var _i = 4; _i < arguments.length; _i++) { 8411 extraArgs[_i - 4] = arguments[_i]; 8412 } 8413 if (eventStore) { 8414 var rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8415 return { 8416 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 8417 fg: this.sliceEventRanges(rangeRes.fg, extraArgs), 8418 }; 8419 } 8420 return { bg: [], fg: [] }; 8421 }; 8422 Slicer.prototype._sliceInteraction = function (interaction, eventUiBases, dateProfile, nextDayThreshold) { 8423 var extraArgs = []; 8424 for (var _i = 4; _i < arguments.length; _i++) { 8425 extraArgs[_i - 4] = arguments[_i]; 8426 } 8427 if (!interaction) { 8428 return null; 8429 } 8430 var rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 8431 return { 8432 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 8433 affectedInstances: interaction.affectedEvents.instances, 8434 isEvent: interaction.isEvent, 8435 }; 8436 }; 8437 Slicer.prototype._sliceDateSpan = function (dateSpan, eventUiBases, context) { 8438 var extraArgs = []; 8439 for (var _i = 3; _i < arguments.length; _i++) { 8440 extraArgs[_i - 3] = arguments[_i]; 8441 } 8442 if (!dateSpan) { 8443 return []; 8444 } 8445 var eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 8446 var segs = this.sliceRange.apply(this, __spreadArray([dateSpan.range], extraArgs)); 8447 for (var _a = 0, segs_1 = segs; _a < segs_1.length; _a++) { 8448 var seg = segs_1[_a]; 8449 seg.eventRange = eventRange; 8450 } 8451 return segs; 8452 }; 8453 /* 8454 "complete" seg means it has component and eventRange 8455 */ 8456 Slicer.prototype.sliceEventRanges = function (eventRanges, extraArgs) { 8457 var segs = []; 8458 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 8459 var eventRange = eventRanges_1[_i]; 8460 segs.push.apply(segs, this.sliceEventRange(eventRange, extraArgs)); 8461 } 8462 return segs; 8463 }; 8464 /* 8465 "complete" seg means it has component and eventRange 8466 */ 8467 Slicer.prototype.sliceEventRange = function (eventRange, extraArgs) { 8468 var dateRange = eventRange.range; 8469 // hack to make multi-day events that are being force-displayed as list-items to take up only one day 8470 if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') { 8471 dateRange = { 8472 start: dateRange.start, 8473 end: addDays(dateRange.start, 1), 8474 }; 8475 } 8476 var segs = this.sliceRange.apply(this, __spreadArray([dateRange], extraArgs)); 8477 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 8478 var seg = segs_2[_i]; 8479 seg.eventRange = eventRange; 8480 seg.isStart = eventRange.isStart && seg.isStart; 8481 seg.isEnd = eventRange.isEnd && seg.isEnd; 8482 } 8483 return segs; 8484 }; 8485 return Slicer; 8486 }()); 8487 /* 8488 for incorporating slotMinTime/slotMaxTime if appropriate 8489 TODO: should be part of DateProfile! 8490 TimelineDateProfile already does this btw 8491 */ 8492 function computeActiveRange(dateProfile, isComponentAllDay) { 8493 var range = dateProfile.activeRange; 8494 if (isComponentAllDay) { 8495 return range; 8496 } 8497 return { 8498 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 8499 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day 8500 }; 8501 } 8502 8503 // high-level segmenting-aware tester functions 8504 // ------------------------------------------------------------------------------------------------------------------------ 8505 function isInteractionValid(interaction, dateProfile, context) { 8506 var instances = interaction.mutatedEvents.instances; 8507 for (var instanceId in instances) { 8508 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 8509 return false;
8510 } 8511 } 8512 return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions 8513 } 8514 function isDateSelectionValid(dateSelection, dateProfile, context) { 8515 if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) { 8516 return false; 8517 } 8518 return isNewPropsValid({ dateSelection: dateSelection }, context); 8519 } 8520 function isNewPropsValid(newProps, context) { 8521 var calendarState = context.getCurrentData(); 8522 var props = __assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps); 8523 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 8524 } 8525 function isPropsValid(state, context, dateSpanMeta, filterConfig) { 8526 if (dateSpanMeta === void 0) { dateSpanMeta = {}; } 8527 if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8528 return false; 8529 } 8530 if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) { 8531 return false; 8532 } 8533 return true; 8534 } 8535 // Moving Event Validation 8536 // ------------------------------------------------------------------------------------------------------------------------ 8537 function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 8538 var currentState = context.getCurrentData(); 8539 var interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions 8540 var subjectEventStore = interaction.mutatedEvents; 8541 var subjectDefs = subjectEventStore.defs; 8542 var subjectInstances = subjectEventStore.instances; 8543 var subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? 8544 state.eventUiBases : 8545 { '': currentState.selectionConfig }); 8546 if (filterConfig) { 8547 subjectConfigs = mapHash(subjectConfigs, filterConfig); 8548 } 8549 // exclude the subject events. TODO: exclude defs too? 8550 var otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); 8551 var otherDefs = otherEventStore.defs; 8552 var otherInstances = otherEventStore.instances; 8553 var otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 8554 for (var subjectInstanceId in subjectInstances) { 8555 var subjectInstance = subjectInstances[subjectInstanceId]; 8556 var subjectRange = subjectInstance.range; 8557 var subjectConfig = subjectConfigs[subjectInstance.defId]; 8558 var subjectDef = subjectDefs[subjectInstance.defId]; 8559 // constraint 8560 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) { 8561 return false; 8562 } 8563 // overlap 8564 var eventOverlap = context.options.eventOverlap; 8565 var eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null; 8566 for (var otherInstanceId in otherInstances) { 8567 var otherInstance = otherInstances[otherInstanceId]; 8568 // intersect! evaluate 8569 if (rangesIntersect(subjectRange, otherInstance.range)) { 8570 var otherOverlap = otherConfigs[otherInstance.defId].overlap; 8571 // consider the other event's overlap. only do this if the subject event is a "real" event 8572 if (otherOverlap === false && interaction.isEvent) { 8573 return false; 8574 } 8575 if (subjectConfig.overlap === false) { 8576 return false; 8577 } 8578 if (eventOverlapFunc && !eventOverlapFunc(new EventApi(context, otherDefs[otherInstance.defId], otherInstance), // still event 8579 new EventApi(context, subjectDef, subjectInstance))) { 8580 return false;
8581 } 8582 } 8583 } 8584 // allow (a function) 8585 var calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state 8586 for (var _i = 0, _a = subjectConfig.allows; _i < _a.length; _i++) { 8587 var subjectAllow = _a[_i]; 8588 var subjectDateSpan = __assign(__assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay }); 8589 var origDef = calendarEventStore.defs[subjectDef.defId]; 8590 var origInstance = calendarEventStore.instances[subjectInstanceId]; 8591 var eventApi = void 0; 8592 if (origDef) { // was previously in the calendar 8593 eventApi = new EventApi(context, origDef, origInstance); 8594 } 8595 else { // was an external event 8596 eventApi = new EventApi(context, subjectDef); // no instance, because had no dates 8597 } 8598 if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) { 8599 return false; 8600 } 8601 } 8602 } 8603 return true; 8604 } 8605 // Date Selection Validation 8606 // ------------------------------------------------------------------------------------------------------------------------ 8607 function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) { 8608 var relevantEventStore = state.eventStore; 8609 var relevantDefs = relevantEventStore.defs; 8610 var relevantInstances = relevantEventStore.instances; 8611 var selection = state.dateSelection; 8612 var selectionRange = selection.range; 8613 var selectionConfig = context.getCurrentData().selectionConfig; 8614 if (filterConfig) { 8615 selectionConfig = filterConfig(selectionConfig); 8616 } 8617 // constraint 8618 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) { 8619 return false; 8620 } 8621 // overlap 8622 var selectOverlap = context.options.selectOverlap; 8623 var selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null; 8624 for (var relevantInstanceId in relevantInstances) { 8625 var relevantInstance = relevantInstances[relevantInstanceId]; 8626 // intersect! evaluate 8627 if (rangesIntersect(selectionRange, relevantInstance.range)) { 8628 if (selectionConfig.overlap === false) { 8629 return false; 8630 } 8631 if (selectOverlapFunc && !selectOverlapFunc(new EventApi(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) { 8632 return false; 8633 } 8634 } 8635 } 8636 // allow (a function) 8637 for (var _i = 0, _a = selectionConfig.allows; _i < _a.length; _i++) { 8638 var selectionAllow = _a[_i]; 8639 var fullDateSpan = __assign(__assign({}, dateSpanMeta), selection); 8640 if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) { 8641 return false; 8642 } 8643 } 8644 return true; 8645 } 8646 // Constraint Utils 8647 // ------------------------------------------------------------------------------------------------------------------------ 8648 function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 8649 for (var _i = 0, constraints_1 = constraints; _i < constraints_1.length; _i++) { 8650 var constraint = constraints_1[_i]; 8651 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) { 8652 return false; 8653 } 8654 } 8655 return true; 8656 } 8657 function constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours 8658 otherEventStore, // for if constraint is an even group ID 8659 businessHoursUnexpanded, // for if constraint is 'businessHours' 8660 context) { 8661 if (constraint === 'businessHours') { 8662 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context)); 8663 } 8664 if (typeof constraint === 'string') { // an group ID 8665 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, function (eventDef) { return eventDef.groupId === constraint; })); 8666 } 8667 if (typeof constraint === 'object' && constraint) { // non-null object 8668 return eventStoreToRanges(expandRecurring(constraint, subjectRange, context)); 8669 } 8670 return []; // if it's false 8671 } 8672 // TODO: move to event-store file? 8673 function eventStoreToRanges(eventStore) { 8674 var instances = eventStore.instances; 8675 var ranges = []; 8676 for (var instanceId in instances) { 8677 ranges.push(instances[instanceId].range); 8678 } 8679 return ranges; 8680 } 8681 // TODO: move to geom file? 8682 function anyRangesContainRange(outerRanges, innerRange) { 8683 for (var _i = 0, outerRanges_1 = outerRanges; _i < outerRanges_1.length; _i++) { 8684 var outerRange = outerRanges_1[_i]; 8685 if (rangeContainsRange(outerRange, innerRange)) { 8686 return true; 8687 } 8688 } 8689 return false;
8690 } 8691 8692 var VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 8693 var Scroller = /** @class */ (function (_super) { 8694 __extends(Scroller, _super); 8695 function Scroller() { 8696 var _this = _super !== null && _super.apply(this, arguments) || this; 8697 _this.handleEl = function (el) { 8698 _this.el = el; 8699 setRef(_this.props.elRef, el); 8700 }; 8701 return _this; 8702 } 8703 Scroller.prototype.render = function () { 8704 var props = this.props; 8705 var liquid = props.liquid, liquidIsAbsolute = props.liquidIsAbsolute; 8706 var isAbsolute = liquid && liquidIsAbsolute; 8707 var className = ['fc-scroller']; 8708 if (liquid) { 8709 if (liquidIsAbsolute) { 8710 className.push('fc-scroller-liquid-absolute'); 8711 } 8712 else { 8713 className.push('fc-scroller-liquid'); 8714 } 8715 } 8716 return (createElement("div", { ref: this.handleEl, className: className.join(' '), style: { 8717 overflowX: props.overflowX, 8718 overflowY: props.overflowY, 8719 left: (isAbsolute && -(props.overcomeLeft || 0)) || '', 8720 right: (isAbsolute && -(props.overcomeRight || 0)) || '', 8721 bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '', 8722 marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '', 8723 marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '', 8724 marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '', 8725 maxHeight: props.maxHeight || '', 8726 } }, props.children)); 8727 }; 8728 Scroller.prototype.needsXScrolling = function () { 8729 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 8730 return false; 8731 } 8732 // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers. 8733 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 8734 // inner-child margins and absolute positioning 8735 var el = this.el; 8736 var realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 8737 var children = el.children; 8738 for (var i = 0; i < children.length; i += 1) { 8739 var childEl = children[i]; 8740 if (childEl.getBoundingClientRect().width > realClientWidth) { 8741 return true; 8742 } 8743 } 8744 return false; 8745 }; 8746 Scroller.prototype.needsYScrolling = function () { 8747 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 8748 return false; 8749 } 8750 // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers. 8751 // much more reliable to see if children are taller than the scroller, even tho doesn't account for 8752 // inner-child margins and absolute positioning 8753 var el = this.el; 8754 var realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 8755 var children = el.children; 8756 for (var i = 0; i < children.length; i += 1) { 8757 var childEl = children[i]; 8758 if (childEl.getBoundingClientRect().height > realClientHeight) { 8759 return true; 8760 } 8761 } 8762 return false; 8763 }; 8764 Scroller.prototype.getXScrollbarWidth = function () { 8765 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 8766 return 0; 8767 } 8768 return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important? 8769 }; 8770 Scroller.prototype.getYScrollbarWidth = function () { 8771 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 8772 return 0; 8773 } 8774 return this.el.offsetWidth - this.el.clientWidth;
8774 // only works because we guarantee no borders. TODO: add to CSS with important? 8775 }; 8776 return Scroller; 8777 }(BaseComponent)); 8778 8779 /* 8780 TODO: somehow infer OtherArgs from masterCallback? 8781 TODO: infer RefType from masterCallback if provided 8782 */ 8783 var RefMap = /** @class */ (function () { 8784 function RefMap(masterCallback) { 8785 var _this = this; 8786 this.masterCallback = masterCallback; 8787 this.currentMap = {}; 8788 this.depths = {}; 8789 this.callbackMap = {}; 8790 this.handleValue = function (val, key) { 8791 var _a = _this, depths = _a.depths, currentMap = _a.currentMap; 8792 var removed = false; 8793 var added = false; 8794 if (val !== null) { 8795 // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore 8796 removed = (key in currentMap); 8797 currentMap[key] = val; 8798 depths[key] = (depths[key] || 0) + 1; 8799 added = true; 8800 } 8801 else { 8802 depths[key] -= 1; 8803 if (!depths[key]) { 8804 delete currentMap[key]; 8805 delete _this.callbackMap[key]; 8806 removed = true; 8807 } 8808 } 8809 if (_this.masterCallback) { 8810 if (removed) { 8811 _this.masterCallback(null, String(key)); 8812 } 8813 if (added) { 8814 _this.masterCallback(val, String(key)); 8815 } 8816 } 8817 }; 8818 } 8819 RefMap.prototype.createRef = function (key) { 8820 var _this = this; 8821 var refCallback = this.callbackMap[key]; 8822 if (!refCallback) { 8823 refCallback = this.callbackMap[key] = function (val) { 8824 _this.handleValue(val, String(key)); 8825 }; 8826 } 8827 return refCallback; 8828 }; 8829 // TODO: check callers that don't care about order. should use getAll instead 8830 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 8831 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 8832 RefMap.prototype.collect = function (startIndex, endIndex, step) { 8833 return collectFromHash(this.currentMap, startIndex, endIndex, step); 8834 }; 8835 RefMap.prototype.getAll = function () { 8836 return hashValuesToArray(this.currentMap); 8837 }; 8838 return RefMap; 8839 }()); 8840 8841 function computeShrinkWidth(chunkEls) { 8842 var shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink'); 8843 var largestWidth = 0; 8844 for (var _i = 0, shrinkCells_1 = shrinkCells; _i < shrinkCells_1.length; _i++) { 8845 var shrinkCell = shrinkCells_1[_i]; 8846 largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell)); 8847 } 8848 return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits 8849 } 8850 function getSectionHasLiquidHeight(props, sectionConfig) { 8851 return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well) 8852 } 8853 function getAllowYScrolling(props, sectionConfig) { 8854 return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 8855 getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars 8856 } 8857 // TODO: ONLY use `arg`. force out internal function to use same API 8858 function renderChunkContent(sectionConfig, chunkConfig, arg) { 8859 var expandRows = arg.expandRows; 8860 var content = typeof chunkConfig.content === 'function' ? 8861 chunkConfig.content(arg) : 8862 createElement('table', { 8863 className: [ 8864 chunkConfig.tableClassName, 8865 sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '', 8866 ].join(' '), 8867 style: { 8868 minWidth: arg.tableMinWidth, 8869 width: arg.clientWidth, 8870 height: expandRows ? arg.clientHeight : '', // css `height` on a <table> serves as a min-height 8871 }, 8872 }, arg.tableColGroupNode, createElement('tbody', {}, typeof chunkConfig.rowContent === 'function' ? chunkConfig.rowContent(arg) : chunkConfig.rowContent)); 8873 return content; 8874 } 8875 function isColPropsEqual(cols0, cols1) { 8876 return isArraysEqual(cols0, cols1, isPropsEqual); 8877 } 8878 function renderMicroColGroup(cols, shrinkWidth) { 8879 var colNodes = []; 8880 /* 8881 for ColProps with spans, it would have been great to make a single <col span=""> 8882 HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans. 8883 SOLUTION: making individual <col> elements makes Chrome behave. 8884 */ 8885 for (var _i = 0, cols_1 = cols; _i < cols_1.length; _i++) { 8886 var colProps = cols_1[_i]; 8887 var span = colProps.span || 1; 8888 for (var i = 0; i < span; i += 1) {
8889 colNodes.push(createElement("col", { style: { 8890 width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''), 8891 minWidth: colProps.minWidth || '', 8892 } })); 8893 } 8894 } 8895 return createElement.apply(void 0, __spreadArray(['colgroup', {}], colNodes)); 8896 } 8897 function sanitizeShrinkWidth(shrinkWidth) { 8898 /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth 8899 4 accounts for 2 2-pixel borders. TODO: better solution? */ 8900 return shrinkWidth == null ? 4 : shrinkWidth; 8901 } 8902 function hasShrinkWidth(cols) { 8903 for (var _i = 0, cols_2 = cols; _i < cols_2.length; _i++) { 8904 var col = cols_2[_i]; 8905 if (col.width === 'shrink') { 8906 return true; 8907 } 8908 } 8909 return false; 8910 } 8911 function getScrollGridClassNames(liquid, context) { 8912 var classNames = [ 8913 'fc-scrollgrid', 8914 context.theme.getClass('table'), 8915 ]; 8916 if (liquid) { 8917 classNames.push('fc-scrollgrid-liquid'); 8918 } 8919 return classNames; 8920 } 8921 function getSectionClassNames(sectionConfig, wholeTableVGrow) { 8922 var classNames = [ 8923 'fc-scrollgrid-section', 8924 "fc-scrollgrid-section-" + sectionConfig.type, 8925 sectionConfig.className, // used? 8926 ]; 8927 if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) { 8928 classNames.push('fc-scrollgrid-section-liquid'); 8929 } 8930 if (sectionConfig.isSticky) { 8931 classNames.push('fc-scrollgrid-section-sticky'); 8932 } 8933 return classNames; 8934 }
8935 function renderScrollShim(arg) { 8936 return (createElement("div", { className: "fc-scrollgrid-sticky-shim", style: { 8937 width: arg.clientWidth, 8938 minWidth: arg.tableMinWidth, 8939 } })); 8940 } 8941 function getStickyHeaderDates(options) { 8942 var stickyHeaderDates = options.stickyHeaderDates; 8943 if (stickyHeaderDates == null || stickyHeaderDates === 'auto') { 8944 stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto'; 8945 } 8946 return stickyHeaderDates; 8947 } 8948 function getStickyFooterScrollbar(options) { 8949 var stickyFooterScrollbar = options.stickyFooterScrollbar; 8950 if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') { 8951 stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto'; 8952 } 8953 return stickyFooterScrollbar; 8954 } 8955 8956 var SimpleScrollGrid = /** @class */ (function (_super) { 8957 __extends(SimpleScrollGrid, _super); 8958 function SimpleScrollGrid() { 8959 var _this = _super !== null && _super.apply(this, arguments) || this; 8960 _this.processCols = memoize(function (a) { return a; }, isColPropsEqual); // so we get same `cols` props every time 8961 // yucky to memoize VNodes, but much more efficient for consumers 8962 _this.renderMicroColGroup = memoize(renderMicroColGroup); 8963 _this.scrollerRefs = new RefMap(); 8964 _this.scrollerElRefs = new RefMap(_this._handleScrollerEl.bind(_this)); 8965 _this.state = { 8966 shrinkWidth: null, 8967 forceYScrollbars: false, 8968 scrollerClientWidths: {}, 8969 scrollerClientHeights: {}, 8970 }; 8971 // TODO: can do a really simple print-view. dont need to join rows 8972 _this.handleSizing = function () { 8973 _this.setState(__assign({ shrinkWidth: _this.computeShrinkWidth() }, _this.computeScrollerDims())); 8974 }; 8975 return _this; 8976 } 8977 SimpleScrollGrid.prototype.render = function () { 8978 var _a = this, props = _a.props, state = _a.state, context = _a.context; 8979 var sectionConfigs = props.sections || []; 8980 var cols = this.processCols(props.cols); 8981 var microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 8982 var classNames = getScrollGridClassNames(props.liquid, context); 8983 if (props.collapsibleWidth) { 8984 classNames.push('fc-scrollgrid-collapsible'); 8985 } 8986 // TODO: make DRY 8987 var configCnt = sectionConfigs.length; 8988 var configI = 0; 8989 var currentConfig; 8990 var headSectionNodes = []; 8991 var bodySectionNodes = []; 8992 var footSectionNodes = []; 8993 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') { 8994 headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode)); 8995 configI += 1; 8996 } 8997 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') { 8998 bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode)); 8999 configI += 1; 9000 } 9001 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') { 9002 footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode)); 9003 configI += 1; 9004 } 9005 // firefox bug: when setting height on table and there is a thead or tfoot, 9006 // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524) 9007 // use getCanVGrowWithinCell as a way to detect table-stupid firefox. 9008 // if so, use a simpler dom structure, jam everything into a lone tbody. 9009 var isBuggy = !getCanVGrowWithinCell(); 9010 return createElement('table', { 9011 className: classNames.join(' '), 9012 style: { height: props.height }, 9013 }, Boolean(!isBuggy && headSectionNodes.length) && createElement.apply(void 0, __spreadArray(['thead', {}
9013], headSectionNodes)), Boolean(!isBuggy && bodySectionNodes.length) && createElement.apply(void 0, __spreadArray(['tbody', {}], bodySectionNodes)), Boolean(!isBuggy && footSectionNodes.length) && createElement.apply(void 0, __spreadArray(['tfoot', {}], footSectionNodes)), isBuggy && createElement.apply(void 0, __spreadArray(__spreadArray(__spreadArray(['tbody', {}], headSectionNodes), bodySectionNodes), footSectionNodes))); 9014 }; 9015 SimpleScrollGrid.prototype.renderSection = function (sectionConfig, microColGroupNode) { 9016 if ('outerContent' in sectionConfig) { 9017 return (createElement(Fragment, { key: sectionConfig.key }, sectionConfig.outerContent)); 9018 } 9019 return (createElement("tr", { key: sectionConfig.key, className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk))); 9020 }; 9021 SimpleScrollGrid.prototype.renderChunkTd = function (sectionConfig, microColGroupNode, chunkConfig) { 9022 if ('outerContent' in chunkConfig) { 9023 return chunkConfig.outerContent; 9024 } 9025 var props = this.props; 9026 var _a = this.state, forceYScrollbars = _a.forceYScrollbars, scrollerClientWidths = _a.scrollerClientWidths, scrollerClientHeights = _a.scrollerClientHeights; 9027 var needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config? 9028 var isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 9029 // for `!props.liquid` - is WHOLE scrollgrid natural height? 9030 // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars 9031 var overflowY = !props.liquid ? 'visible' : 9032 forceYScrollbars ? 'scroll' : 9033 !needsYScrolling ? 'hidden' : 9034 'auto'; 9035 var sectionKey = sectionConfig.key; 9036 var content = renderChunkContent(sectionConfig, chunkConfig, { 9037 tableColGroupNode: microColGroupNode, 9038 tableMinWidth: '', 9039 clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null, 9040 clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null, 9041 expandRows: sectionConfig.expandRows, 9042 syncRowHeights: false, 9043 rowSyncHeights: [], 9044 reportRowHeightChange: function () { }, 9045 }); 9046 return (createElement("td", { ref: chunkConfig.elRef }, 9047 createElement("div", { className: "fc-scroller-harness" + (isLiquid ? ' fc-scroller-harness-liquid' : '') }, 9048 createElement(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness 9049 : true }, content)))); 9050 }; 9051 SimpleScrollGrid.prototype._handleScrollerEl = function (scrollerEl, key) { 9052 var section = getSectionByKey(this.props.sections, key); 9053 if (section) { 9054 setRef(section.chunk.scrollerElRef, scrollerEl); 9055 } 9056 }; 9057 SimpleScrollGrid.prototype.componentDidMount = function () { 9058 this.handleSizing(); 9059 this.context.addResizeHandler(this.handleSizing); 9060 }; 9061 SimpleScrollGrid.prototype.componentDidUpdate = function () { 9062 // TODO: need better solution when state contains non-sizing things 9063 this.handleSizing(); 9064 }; 9065 SimpleScrollGrid.prototype.componentWillUnmount = function () { 9066 this.context.removeResizeHandler(this.handleSizing); 9067 }; 9068 SimpleScrollGrid.prototype.computeShrinkWidth = function () { 9069 return hasShrinkWidth(this.props.cols) 9070 ? computeShrinkWidth(this.scrollerElRefs.getAll()) 9071 : 0; 9072 }; 9073 SimpleScrollGrid.prototype.computeScrollerDims = function () { 9074 var scrollbarWidth = getScrollbarWidths(); 9075 var _a = this, scrollerRefs = _a.scrollerRefs, scrollerElRefs = _a.scrollerElRefs; 9076 var forceYScrollbars = false;
9077 var scrollerClientWidths = {}; 9078 var scrollerClientHeights = {}; 9079 for (var sectionKey in scrollerRefs.currentMap) { 9080 var scroller = scrollerRefs.currentMap[sectionKey]; 9081 if (scroller && scroller.needsYScrolling()) { 9082 forceYScrollbars = true; 9083 break; 9084 } 9085 } 9086 for (var _i = 0, _b = this.props.sections; _i < _b.length; _i++) { 9087 var section = _b[_i]; 9088 var sectionKey = section.key; 9089 var scrollerEl = scrollerElRefs.currentMap[sectionKey]; 9090 if (scrollerEl) { 9091 var harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders 9092 scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars 9093 ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future 9094 : 0)); 9095 scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height); 9096 } 9097 } 9098 return { forceYScrollbars: forceYScrollbars, scrollerClientWidths: scrollerClientWidths, scrollerClientHeights: scrollerClientHeights }; 9099 }; 9100 return SimpleScrollGrid; 9101 }(BaseComponent)); 9102 SimpleScrollGrid.addStateEquality({ 9103 scrollerClientWidths: isPropsEqual, 9104 scrollerClientHeights: isPropsEqual, 9105 }); 9106 function getSectionByKey(sections, key) { 9107 for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) { 9108 var section = sections_1[_i]; 9109 if (section.key === key) { 9110 return section; 9111 } 9112 } 9113 return null; 9114 } 9115 9116 var EventRoot = /** @class */ (function (_super) { 9117 __extends(EventRoot, _super); 9118 function EventRoot() { 9119 var _this = _super !== null && _super.apply(this, arguments) || this; 9120 _this.elRef = createRef(); 9121 return _this; 9122 } 9123 EventRoot.prototype.render = function () { 9124 var _a = this, props = _a.props, context = _a.context; 9125 var options = context.options; 9126 var seg = props.seg; 9127 var eventRange = seg.eventRange; 9128 var ui = eventRange.ui; 9129 var hookProps = { 9130 event: new EventApi(context, eventRange.def, eventRange.instance), 9131 view: context.viewApi, 9132 timeText: props.timeText, 9133 textColor: ui.textColor, 9134 backgroundColor: ui.backgroundColor, 9135 borderColor: ui.borderColor, 9136 isDraggable: !props.disableDragging && computeSegDraggable(seg, context), 9137 isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context), 9138 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 9139 isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting), 9140 isStart: Boolean(seg.isStart), 9141 isEnd: Boolean(seg.isEnd), 9142 isPast: Boolean(props.isPast), 9143 isFuture: Boolean(props.isFuture), 9144 isToday: Boolean(props.isToday), 9145 isSelected: Boolean(props.isSelected), 9146 isDragging: Boolean(props.isDragging), 9147 isResizing: Boolean(props.isResizing), 9148 }; 9149 var standardClassNames = getEventClassNames(hookProps).concat(ui.classNames); 9150 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.eventClassNames, content: options.eventContent, defaultContent: props.defaultContent, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount, elRef: this.elRef }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, standardClassNames.concat(customClassNames), innerElRef, innerContent, hookProps); })); 9151 }; 9152 EventRoot.prototype.componentDidMount = function () { 9153 setElSeg(this.elRef.current, this.props.seg); 9154 }; 9155 /* 9156 need to re-assign seg to the element if seg changes, even if the element is the same 9157 */ 9158 EventRoot.prototype.componentDidUpdate = function (prevProps) { 9159 var seg = this.props.seg; 9160 if (seg !== prevProps.seg) { 9161 setElSeg(this.elRef.current, seg); 9162 } 9163 }; 9164 return EventRoot; 9165 }(BaseComponent)); 9166 9167 // should not be a purecomponent 9168 var StandardEvent = /** @class */ (function (_super) { 9169 __extends(StandardEvent, _super); 9170 function StandardEvent() { 9171 return _super !== null && _super.apply(this, arguments) || this; 9172 } 9173 StandardEvent.prototype.render = function () { 9174 var _a = this, props = _a.props, context = _a.context; 9175 var seg = props.seg; 9176 var timeFormat = context.options.eventTimeFormat || props.defaultTimeFormat; 9177 var timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); 9178 return (createElement(EventRoot, { seg: seg, timeText: timeText, disableDragging: props.disableDragging, disableResizing: props.disableResizing, defaultContent: props.defaultContent || renderInnerContent$4, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("a", __assign({ className: props.extraClassNames.c
9178oncat(classNames).join(' '), style: { 9179 borderColor: hookProps.borderColor, 9180 backgroundColor: hookProps.backgroundColor, 9181 }, ref: rootElRef }, getSegAnchorAttrs$1(seg)), 9182 createElement("div", { className: "fc-event-main", ref: innerElRef, style: { color: hookProps.textColor } }, innerContent), 9183 hookProps.isStartResizable && 9184 createElement("div", { className: "fc-event-resizer fc-event-resizer-start" }), 9185 hookProps.isEndResizable && 9186 createElement("div", { className: "fc-event-resizer fc-event-resizer-end" }))); })); 9187 }; 9188 return StandardEvent; 9189 }(BaseComponent)); 9190 function renderInnerContent$4(innerProps) { 9191 return (createElement("div", { className: "fc-event-main-frame" }, 9192 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 9193 createElement("div", { className: "fc-event-title-container" }, 9194 createElement("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || createElement(Fragment, null, "\u00A0"))))); 9195 } 9196 function getSegAnchorAttrs$1(seg) { 9197 var url = seg.eventRange.def.url; 9198 return url ? { href: url } : {}; 9199 } 9200 9201 var NowIndicatorRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9202 var options = context.options; 9203 var hookProps = { 9204 isAxis: props.isAxis, 9205 date: context.dateEnv.toDate(props.date), 9206 view: context.viewApi, 9207 }; 9208 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.nowIndicatorClassNames, content: options.nowIndicatorContent, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount }, props.children)); 9209 })); }; 9210 9211 var DAY_NUM_FORMAT = createFormatter({ day: 'numeric' }); 9212 var DayCellContent = /** @class */ (function (_super) { 9213 __extends(DayCellContent, _super); 9214 function DayCellContent() { 9215 return _super !== null && _super.apply(this, arguments) || this; 9216 } 9217 DayCellContent.prototype.render = function () { 9218 var _a = this, props = _a.props, context = _a.context; 9219 var options = context.options; 9220 var hookProps = refineDayCellHookProps({ 9221 date: props.date, 9222 dateProfile: props.dateProfile, 9223 todayRange: props.todayRange, 9224 showDayNumber: props.showDayNumber, 9225 extraProps: props.extraHookProps, 9226 viewApi: context.viewApi, 9227 dateEnv: context.dateEnv, 9228 }); 9229 return (createElement(ContentHook, { hookProps: hookProps, content: options.dayCellContent, defaultContent: props.defaultContent }, props.children)); 9230 }; 9231 return DayCellContent; 9232 }(BaseComponent)); 9233 function refineDayCellHookProps(raw) { 9234 var date = raw.date, dateEnv = raw.dateEnv; 9235 var dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile); 9236 return __assign(__assign(__assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraProps); 9237 } 9238 9239 var DayCellRoot = /** @class */ (function (_super) { 9240 __extends(DayCellRoot, _super); 9241 function DayCellRoot() { 9242 var _this = _super !== null && _super.apply(this, arguments) || this; 9243 _this.refineHookProps = memoizeObjArg(refineDayCellHookProps); 9244 _this.normalizeClassNames = buildClassNameNormalizer(); 9245 return _this; 9246 } 9247 DayCellRoot.prototype.render = function () { 9248 var _a = this, props = _a.props, context = _a.context; 9249 var options = context.options; 9250 var hookProps = this.refineHookProps({ 9251 date: props.date, 9252 dateProfile: props.dateProfile, 9253 todayRange: props.todayRange, 9254 showDayNumber: props.showDayNumber, 9255 extraProps: props.extraHookProps, 9256 viewApi: context.viewApi, 9257 dateEnv: context.dateEnv, 9258 }); 9259 var classNames = getDayClassNames(hookProps, context.theme).concat(hookProps.isDisabled 9260 ? [] // don't use custom classNames if disabled 9261 : this.normalizeClassNames(options.dayCellClassNames, hookProps)); 9262 var dataAttrs = hookProps.isDisabled ? {} : { 9263 'data-date': formatDayString(props.date), 9264 }; 9265 return (createElement(MountHook, { hookProps: hookProps, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount, elRef: props.elRef }, function (rootElRef) { return props.children(rootElRef, classNames, dataAttrs, hookProps.isDisabled); })); 9266 }; 9267 return DayCellRoot; 9268 }(BaseComponent)); 9269 9270 function renderFill(fillType) { 9271 return (createElement("div", { className: "fc-" + fillType })); 9272 } 9273 var BgEvent = function (props) { return (createElement(EventRoot, { defaultContent: renderInnerContent$3, seg: props.seg /* uselesss i think */, timeText: "", disableDragging: true, disableResizing: true, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("div", { ref: rootElRef, className: ['fc-bg-event'].concat(classNames).join(' '), style: { 9274 backgroundColor: hookProps.backgroundColor, 9275 } }, innerContent)); })); }; 9276 function renderInnerContent$3(props) { 9277 var title = props.event.title; 9278 return title && (createElement("div", { className: "fc-event-title" }, props.event.title)); 9279 } 9280 9281 var WeekNumberRoot = function (props) { return (createElement(ViewContextType.Consumer, null, function (context) { 9282 var dateEnv = context.dateEnv, options = context.options; 9283 var date = props.date; 9284 var format = options.weekNumberFormat || props.defaultFormat; 9285 var num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well? 9286 var text = dateEnv.format(date, format); 9287 var hookProps = { num: num, text: text, date: date }; 9288 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.weekNumberClassNames, content: options.weekNumberContent, defaultContent: renderInner, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }, props.children)); 9289 })); }; 9290 function renderInner(innerProps) { 9291 return innerProps.text; 9292 } 9293 9294 var PADDING_FROM_VIEWPORT = 10; 9295 var Popover = /** @class */ (function (_super) { 9296 __extends(Popover, _super); 9297 function Popover() { 9298 var _this = _super !== null && _super.apply(this, arguments) || this; 9299 _this.handleRootEl = function (el) { 9300 _this.rootEl = el; 9301 if (_this.props.elRef) { 9302 setRef(_this.props.elRef, el); 9303 } 9304 }; 9305 // Triggered when the user clicks *anywhere* in the document, for the autoHide feature 9306 _this.handleDocumentMousedown = function (ev) { 9307 // only hide the popover if the click happened outside the popover 9308 var target = getEventTargetViaRoot(ev); 9309 if (!_this.rootEl.contains(target)) { 9310 _this.handleCloseClick(); 9311 } 9312 }; 9313 _this.handleCloseClick = function () { 9314 var onClose = _this.props.onClose; 9315 if (onClose) { 9316 onClose(); 9317 } 9318 }; 9319 return _this; 9320 } 9321 Popover.prototype.render = function () { 9322 var theme = this.context.theme; 9323 var props = this.props; 9324 var classNames = [ 9325 'fc-popover', 9326 theme.getClass('popover'), 9327 ].concat(props.extraClassNames || []); 9328 return createPortal(createElement("div", __assign({ className: classNames.join(' ') }, props.extraAttrs, { ref: this.handleRootEl }), 9329 createElement("div", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') }, 9330 createElement("span", { className: "fc-popover-title" }, props.title), 9331 createElement("span", { className: 'fc-popover-close ' + theme.getIconClass('close'), onClick: this.handleCloseClick })), 9332 createElement("div", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl); 9333 }; 9334 Popover.prototype.componentDidMount = function () { 9335 document.addEventListener('mousedown', this.handleDocumentMousedown); 9336 this.updateSize(); 9337 }; 9338 Popover.prototype.componentWillUnmount = function () { 9339 document.removeEventListener('mousedown', this.handleDocumentMousedown); 9340 }; 9341 Popover.prototype.updateSize = function () {
9342 var isRtl = this.context.isRtl; 9343 var _a = this.props, alignmentEl = _a.alignmentEl, alignGridTop = _a.alignGridTop; 9344 var rootEl = this.rootEl; 9345 var alignmentRect = computeClippedClientRect(alignmentEl); 9346 if (alignmentRect) { 9347 var popoverDims = rootEl.getBoundingClientRect(); 9348 // position relative to viewport 9349 var popoverTop = alignGridTop 9350 ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top 9351 : alignmentRect.top; 9352 var popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left; 9353 // constrain 9354 popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT); 9355 popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width); 9356 popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT); 9357 var origin_1 = rootEl.offsetParent.getBoundingClientRect(); 9358 applyStyle(rootEl, { 9359 top: popoverTop - origin_1.top, 9360 left: popoverLeft - origin_1.left, 9361 }); 9362 } 9363 }; 9364 return Popover; 9365 }(BaseComponent)); 9366 9367 var MorePopover = /** @class */ (function (_super) { 9368 __extends(MorePopover, _super); 9369 function MorePopover() { 9370 var _this = _super !== null && _super.apply(this, arguments) || this; 9371 _this.handleRootEl = function (rootEl) { 9372 _this.rootEl = rootEl; 9373 if (rootEl) { 9374 _this.context.registerInteractiveComponent(_this, { 9375 el: rootEl, 9376 useEventCenter: false, 9377 }); 9378 } 9379 else { 9380 _this.context.unregisterInteractiveComponent(_this); 9381 } 9382 }; 9383 return _this; 9384 } 9385 MorePopover.prototype.render = function () { 9386 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv; 9387 var props = this.props; 9388 var startDate = props.startDate, todayRange = props.todayRange, dateProfile = props.dateProfile; 9389 var title = dateEnv.format(startDate, options.dayPopoverFormat); 9390 return (createElement(DayCellRoot, { date: startDate, dateProfile: dateProfile, todayRange: todayRange, elRef: this.handleRootEl }, function (rootElRef, dayClassNames, dataAttrs) { return (createElement(Popover, { elRef: rootElRef, title: title, extraClassNames: ['fc-more-popover'].concat(dayClassNames), extraAttrs: dataAttrs /* TODO: make these time-based when not whole-day? */, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose }, 9391 createElement(DayCellContent, { date: startDate, dateProfile: dateProfile, todayRange: todayRange }, function (innerElRef, innerContent) { return (innerContent && 9392 createElement("div", { className: "fc-more-popover-misc", ref: innerElRef }, innerContent)); }), 9393 props.children)); })); 9394 }; 9395 MorePopover.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) { 9396 var _a = this, rootEl = _a.rootEl, props = _a.props; 9397 if (positionLeft >= 0 && positionLeft < elWidth && 9398 positionTop >= 0 && positionTop < elHeight) { 9399 return { 9400 dateProfile: props.dateProfile, 9401 dateSpan: __assign({ allDay: true, range: { 9402 start: props.startDate, 9403 end: props.endDate, 9404 } }, props.extraDateSpan), 9405 dayEl: rootEl, 9406 rect: { 9407 left: 0, 9408 top: 0, 9409 right: elWidth, 9410 bottom: elHeight, 9411 }, 9412 layer: 1, // important when comparing with hits from other components 9413 }; 9414 } 9415 return null; 9416 }; 9417 return MorePopover; 9418 }(DateComponent)); 9419 9420 var MoreLinkRoot = /** @class */ (function (_super) { 9421 __extends(MoreLinkRoot, _super); 9422 function MoreLinkRoot() { 9423 var _this = _super !== null && _super.apply(this, arguments) || this; 9424 _this.linkElRef = createRef(); 9425 _this.state = { 9426 isPopoverOpen: false, 9427 }; 9428 _this.handleClick = function (ev) { 9429 var _a = _this, props = _a.props, context = _a.context; 9430 var moreLinkClick = context.options.moreLinkClick; 9431 var date = computeRange(props).start; 9432 function buildPublicSeg(seg) { 9433 var _a = seg.eventRange, def = _a.def, instance = _a.instance, range = _a.range; 9434 return { 9435 event: new EventApi(context, def, instance), 9436 start: context.dateEnv.toDate(range.start), 9437 end: context.dateEnv.toDate(range.end), 9438 isStart: seg.isStart, 9439 isEnd: seg.isEnd, 9440 }; 9441 } 9442 if (typeof moreLinkClick === 'function') { 9443 moreLinkClick = moreLinkClick({ 9444 date: date, 9445 allDay: Boolean(props.allDayDate), 9446 allSegs: props.allSegs.map(buildPublicSeg), 9447 hiddenSegs: props.hiddenSegs.map(buildPublicSeg), 9448 jsEvent: ev, 9449 view: context.viewApi, 9450 }); 9451 } 9452 if (!moreLinkClick || moreLinkClick === 'popover') { 9453 _this.setState({ isPopoverOpen: true }); 9454 } 9455 else if (typeof moreLinkClick === 'string') { // a view n
9455ame 9456 context.calendarApi.zoomTo(date, moreLinkClick); 9457 } 9458 }; 9459 _this.handlePopoverClose = function () { 9460 _this.setState({ isPopoverOpen: false }); 9461 }; 9462 return _this; 9463 } 9464 MoreLinkRoot.prototype.render = function () { 9465 var _this = this; 9466 var props = this.props; 9467 return (createElement(ViewContextType.Consumer, null, function (context) { 9468 var viewApi = context.viewApi, options = context.options, calendarApi = context.calendarApi; 9469 var moreLinkText = options.moreLinkText; 9470 var moreCnt = props.moreCnt; 9471 var range = computeRange(props); 9472 var hookProps = { 9473 num: moreCnt, 9474 shortText: "+" + moreCnt, 9475 text: typeof moreLinkText === 'function' 9476 ? moreLinkText.call(calendarApi, moreCnt) 9477 : "+" + moreCnt + " " + moreLinkText, 9478 view: viewApi, 9479 }; 9480 return (createElement(Fragment, null, 9481 Boolean(props.moreCnt) && (createElement(RenderHook, { elRef: _this.linkElRef, hookProps: hookProps, classNames: options.moreLinkClassNames, content: options.moreLinkContent, defaultContent: props.defaultContent || renderMoreLinkInner$1, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return props.children(rootElRef, ['fc-more-link'].concat(customClassNames), innerElRef, innerContent, _this.handleClick); })), 9482 _this.state.isPopoverOpen && (createElement(MorePopover, { startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: _this.parentEl, alignmentEl: props.alignmentElRef.current, alignGridTop: props.alignGridTop, onClose: _this.handlePopoverClose }, props.popoverContent())))); 9483 })); 9484 }; 9485 MoreLinkRoot.prototype.componentDidMount = function () { 9486 this.updateParentEl(); 9487 }; 9488 MoreLinkRoot.prototype.componentDidUpdate = function () { 9489 this.updateParentEl(); 9490 }; 9491 MoreLinkRoot.prototype.updateParentEl = function () { 9492 if (this.linkElRef.current) { 9493 this.parentEl = elementClosest(this.linkElRef.current, '.fc-view-harness'); 9494 } 9495 }; 9496 return MoreLinkRoot; 9497 }(BaseComponent)); 9498 function renderMoreLinkInner$1(props) { 9499 return props.text; 9500 } 9501 function computeRange(props) { 9502 if (props.allDayDate) { 9503 return { 9504 start: props.allDayDate, 9505 end: addDays(props.allDayDate, 1), 9506 }; 9507 } 9508 var hiddenSegs = props.hiddenSegs; 9509 return { 9510 start: computeEarliestSegStart(hiddenSegs), 9511 end: computeLatestSegEnd(hiddenSegs), 9512 }; 9513 } 9514 function computeEarliestSegStart(segs) { 9515 return segs.reduce(pickEarliestStart).eventRange.range.start; 9516 } 9517 function pickEarliestStart(seg0, seg1) { 9518 return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1; 9519 } 9520 function computeLatestSegEnd(segs) { 9521 return segs.reduce(pickLatestEnd).eventRange.range.end; 9522 } 9523 function pickLatestEnd(seg0, seg1) { 9524 return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1; 9525 } 9526 9527 // exports 9528 // -------------------------------------------------------------------------------------------------- 9529 var version = '5.7.2'; // important to type it, so .d.ts has generic string 9530 9531 var Calendar = /** @class */ (function (_super) { 9532 __extends(Calendar, _super); 9533 function Calendar(el, optionOverrides) { 9534 if (optionOverrides === void 0) { optionOverrides = {}; } 9535 var _this = _super.call(this) || this; 9536 _this.isRendering = false; 9537 _this.isRendered = false;
9538 _this.currentClassNames = []; 9539 _this.customContentRenderId = 0; // will affect custom generated classNames? 9540 _this.handleAction = function (action) { 9541 // actions we know we want to render immediately 9542 switch (action.type) { 9543 case 'SET_EVENT_DRAG': 9544 case 'SET_EVENT_RESIZE': 9545 _this.renderRunner.tryDrain(); 9546 } 9547 }; 9548 _this.handleData = function (data) { 9549 _this.currentData = data; 9550 _this.renderRunner.request(data.calendarOptions.rerenderDelay); 9551 }; 9552 _this.handleRenderRequest = function () { 9553 if (_this.isRendering) { 9554 _this.isRendered = true; 9555 var currentData_1 = _this.currentData; 9556 render(createElement(CalendarRoot, { options: currentData_1.calendarOptions, theme: currentData_1.theme, emitter: currentData_1.emitter }, function (classNames, height, isHeightAuto, forPrint) { 9557 _this.setClassNames(classNames); 9558 _this.setHeight(height); 9559 return (createElement(CustomContentRenderContext.Provider, { value: _this.customContentRenderId }, 9560 createElement(CalendarContent, __assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData_1)))); 9561 }), _this.el); 9562 } 9563 else if (_this.isRendered) { 9564 _this.isRendered = false; 9565 unmountComponentAtNode(_this.el); 9566 _this.setClassNames([]); 9567 _this.setHeight(''); 9568 } 9569 flushToDom(); 9570 }; 9571 _this.el = el; 9572 _this.renderRunner = new DelayedRunner(_this.handleRenderRequest); 9573 new CalendarDataManager({ 9574 optionOverrides: optionOverrides, 9575 calendarApi: _this, 9576 onAction: _this.handleAction, 9577 onData: _this.handleData, 9578 }); 9579 return _this; 9580 } 9581 Object.defineProperty(Calendar.prototype, "view", { 9582 get: function () { return this.currentData.viewApi; } // for public API 9583 , 9584 enumerable: false, 9585 configurable: true 9586 }); 9587 Calendar.prototype.render = function () { 9588 var wasRendering = this.isRendering; 9589 if (!wasRendering) { 9590 this.isRendering = true; 9591 } 9592 else { 9593 this.customContentRenderId += 1; 9594 } 9595 this.renderRunner.request(); 9596 if (wasRendering) { 9597 this.updateSize(); 9598 } 9599 }; 9600 Calendar.prototype.destroy = function () { 9601 if (this.isRendering) { 9602 this.isRendering = false; 9603 this.renderRunner.request(); 9604 } 9605 }; 9606 Calendar.prototype.updateSize = function () { 9607 _super.prototype.updateSize.call(this); 9608 flushToDom(); 9609 }; 9610 Calendar.prototype.batchRendering = function (func) { 9611 this.renderRunner.pause('batchRendering'); 9612 func(); 9613 this.renderRunner.resume('batchRendering'); 9614 }; 9615 Calendar.prototype.pauseRendering = function () { 9616 this.renderRunner.pause('pauseRendering'); 9617 }; 9618 Calendar.prototype.resumeRendering = function () { 9619 this.renderRunner.resume('pauseRendering', true); 9620 }; 9621 Calendar.prototype.resetOptions = function (optionOverrides, append) { 9622 this.currentDataManager.resetOptions(optionOverrides, append); 9623 }; 9624 Calendar.prototype.setClassNames = function (classNames) { 9625 if (!isArraysEqual(classNames, this.currentClassNames)) { 9626 var classList = this.el.classList; 9627 for (var _i = 0, _a = this.currentClassNames; _i < _a.length; _i++) { 9628 var className = _a[_i]; 9629 classList.remove(className); 9630 } 9631 for (var _b = 0, classNames_1 = classNames; _b < classNames_1.length; _b++) { 9632 var className = classNames_1[_b]; 9633 classList.add(className); 9634 } 9635 this.currentClassNames = classNames; 9636 } 9637 }; 9638 Calendar.prototype.setHeight = function (height) { 9639 applyStyleProp(this.el, 'height', height); 9640 }; 9641 return Calendar; 9642 }(CalendarApi)); 9643 9644 config.touchMouseIgnoreWait = 500; 9645 var ignoreMouseDepth = 0; 9646 var listenerCnt = 0; 9647 var isWindowTouchMoveCancelled = false;
9648 /* 9649 Uses a "pointer" abstraction, which monitors UI events for both mouse and touch. 9650 Tracks when the pointer "drags" on a certain element, meaning down+move+up. 9651 9652 Also, tracks if there was touch-scrolling. 9653 Also, can prevent touch-scrolling from happening. 9654 Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement. 9655 9656 emits: 9657 - pointerdown 9658 - pointermove 9659 - pointerup 9660 */ 9661 var PointerDragging = /** @class */ (function () { 9662 function PointerDragging(containerEl) { 9663 var _this = this; 9664 this.subjectEl = null; 9665 // options that can be directly assigned by caller 9666 this.selector = ''; // will cause subjectEl in all emitted events to be this element 9667 this.handleSelector = ''; 9668 this.shouldIgnoreMove = false; 9669 this.shouldWatchScroll = true; // for simulating pointermove on scroll 9670 // internal states 9671 this.isDragging = false; 9672 this.isTouchDragging = false; 9673 this.wasTouchScroll = false; 9674 // Mouse 9675 // ---------------------------------------------------------------------------------------------------- 9676 this.handleMouseDown = function (ev) { 9677 if (!_this.shouldIgnoreMouse() && 9678 isPrimaryMouseButton(ev) && 9679 _this.tryStart(ev)) { 9680 var pev = _this.createEventFromMouse(ev, true); 9681 _this.emitter.trigger('pointerdown', pev); 9682 _this.initScrollWatch(pev); 9683 if (!_this.shouldIgnoreMove) { 9684 document.addEventListener('mousemove', _this.handleMouseMove); 9685 } 9686 document.addEventListener('mouseup', _this.handleMouseUp); 9687 } 9688 }; 9689 this.handleMouseMove = function (ev) { 9690 var pev = _this.createEventFromMouse(ev); 9691 _this.recordCoords(pev); 9692 _this.emitter.trigger('pointermove', pev); 9693 }; 9694 this.handleMouseUp = function (ev) { 9695 document.removeEventListener('mousemove', _this.handleMouseMove); 9696 document.removeEventListener('mouseup', _this.handleMouseUp); 9697 _this.emitter.trigger('pointerup', _this.createEventFromMouse(ev)); 9698 _this.cleanup(); // call last so that pointerup has access to props 9699 }; 9700 // Touch 9701 // ---------------------------------------------------------------------------------------------------- 9702 this.handleTouchStart = function (ev) { 9703 if (_this.tryStart(ev)) { 9704 _this.isTouchDragging = true; 9705 var pev = _this.createEventFromTouch(ev, true); 9706 _this.emitter.trigger('pointerdown', pev); 9707 _this.initScrollWatch(pev); 9708 // unlike mouse, need to attach to target, not document 9709 // https://stackoverflow.com/a/45760014 9710 var targetEl = ev.target; 9711 if (!_this.shouldIgnoreMove) { 9712 targetEl.addEventListener('touchmove', _this.handleTouchMove); 9713 } 9714 targetEl.addEventListener('touchend', _this.handleTouchEnd); 9715 targetEl.addEventListener('touchcancel', _this.handleTouchEnd); // treat it as a touch end 9716 // attach a handler to get called when ANY scroll action happens on the page. 9717 // this was impossible to do with normal on/off because 'scroll' doesn't bubble. 9718 // http://stackoverflow.com/a/32954565/96342 9719 window.addEventListener('scroll', _this.handleTouchScroll, true); 9720 } 9721 }; 9722 this.handleTouchMove = function (ev) { 9723 var pev = _this.createEventFromTouch(ev); 9724 _this.recordCoords(pev); 9725 _this.emitter.trigger('pointermove', pev); 9726 }; 9727 this.handleTouchEnd = function (ev) { 9728 if (_this.isDragging) { // done to guard against touchend followed by touchcancel 9729 var targetEl = ev.target; 9730 targetEl.removeEventListener('touchmove', _this.handleTouchMove); 9731 targetEl.removeEventListener('touchend', _this.handleTouchEnd); 9732 targetEl.removeEventListener('touchcancel', _this.handleTouchEnd); 9733 window.removeEventListener('scroll', _this.handleTouchScroll, true); // useCaptured=true 9734 _this.emitter.trigger('pointerup', _this.createEventFromTouch(ev)); 9735 _this.cleanup(); // call last so that pointerup has access to props 9736 _this.isTouchDragging = false;
9737 startIgnoringMouse(); 9738 } 9739 }; 9740 this.handleTouchScroll = function () { 9741 _this.wasTouchScroll = true; 9742 }; 9743 this.handleScroll = function (ev) { 9744 if (!_this.shouldIgnoreMove) { 9745 var pageX = (window.pageXOffset - _this.prevScrollX) + _this.prevPageX; 9746 var pageY = (window.pageYOffset - _this.prevScrollY) + _this.prevPageY; 9747 _this.emitter.trigger('pointermove', { 9748 origEvent: ev, 9749 isTouch: _this.isTouchDragging, 9750 subjectEl: _this.subjectEl, 9751 pageX: pageX, 9752 pageY: pageY, 9753 deltaX: pageX - _this.origPageX, 9754 deltaY: pageY - _this.origPageY, 9755 }); 9756 } 9757 }; 9758 this.containerEl = containerEl; 9759 this.emitter = new Emitter(); 9760 containerEl.addEventListener('mousedown', this.handleMouseDown); 9761 containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true }); 9762 listenerCreated(); 9763 } 9764 PointerDragging.prototype.destroy = function () { 9765 this.containerEl.removeEventListener('mousedown', this.handleMouseDown); 9766 this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true }); 9767 listenerDestroyed(); 9768 }; 9769 PointerDragging.prototype.tryStart = function (ev) { 9770 var subjectEl = this.querySubjectEl(ev); 9771 var downEl = ev.target; 9772 if (subjectEl && 9773 (!this.handleSelector || elementClosest(downEl, this.handleSelector))) { 9774 this.subjectEl = subjectEl; 9775 this.isDragging = true; // do this first so cancelTouchScroll will work 9776 this.wasTouchScroll = false; 9777 return true; 9778 } 9779 return false; 9780 }; 9781 PointerDragging.prototype.cleanup = function () { 9782 isWindowTouchMoveCancelled = false; 9783 this.isDragging = false; 9784 this.subjectEl = null; 9785 // keep wasTouchScroll around for later access 9786 this.destroyScrollWatch(); 9787 }; 9788 PointerDragging.prototype.querySubjectEl = function (ev) { 9789 if (this.selector) { 9790 return elementClosest(ev.target, this.selector); 9791 } 9792 return this.containerEl; 9793 }; 9794 PointerDragging.prototype.shouldIgnoreMouse = function () { 9795 return ignoreMouseDepth || this.isTouchDragging; 9796 }; 9797 // can be called by user of this class, to cancel touch-based scrolling for the current drag 9798 PointerDragging.prototype.cancelTouchScroll = function () { 9799 if (this.isDragging) { 9800 isWindowTouchMoveCancelled = true; 9801 } 9802 }; 9803 // Scrolling that simulates pointermoves 9804 // ---------------------------------------------------------------------------------------------------- 9805 PointerDragging.prototype.initScrollWatch = function (ev) { 9806 if (this.shouldWatchScroll) { 9807 this.recordCoords(ev); 9808 window.addEventListener('scroll', this.handleScroll, true); // useCapture=true 9809 } 9810 }; 9811 PointerDragging.prototype.recordCoords = function (ev) { 9812 if (this.shouldWatchScroll) { 9813 this.prevPageX = ev.pageX; 9814 this.prevPageY = ev.pageY; 9815 this.prevScrollX = window.pageXOffset; 9816 this.prevScrollY = window.pageYOffset; 9817 } 9818 }; 9819 PointerDragging.prototype.destroyScrollWatch = function () { 9820 if (this.shouldWatchScroll) { 9821 window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true 9822 } 9823 }; 9824 // Event Normalization 9825 // ---------------------------------------------------------------------------------------------------- 9826 PointerDragging.prototype.createEventFromMouse = function (ev, isFirst) { 9827 var deltaX = 0; 9828 var deltaY = 0; 9829 // TODO: repeat code 9830 if (isFirst) { 9831 this.origPageX = ev.pageX; 9832 this.origPageY = ev.pageY; 9833 } 9834 else { 9835 deltaX = ev.pageX - this.origPageX; 9836 deltaY = ev.pageY - this.origPageY; 9837 } 9838 return { 9839 origEvent: ev, 9840 isTouch: false, 9841 subjectEl: this.subjectEl, 9842 pageX: ev.pageX, 9843 pageY: ev.pageY, 9844 deltaX: deltaX, 9845 deltaY: deltaY, 9846 }; 9847 }; 9848 PointerDragging.prototype.createEventFromTouch = function (ev, isFirst) { 9849 var touches = ev.touches; 9850 var pageX; 9851 var pageY; 9852 var deltaX = 0; 9853 var deltaY = 0; 9854 // if touch coords available, prefer, 9855 // because FF would give bad ev.pageX ev.pageY 9856 if (touches && touches.length) { 9857 pageX = touches[0].pageX; 9858 pageY = touches[0].pageY; 9859 } 9860 else { 9861 pageX = ev.pageX; 9862 pageY = ev.pageY; 9863 } 9864 // TODO: repeat code 9865 if (isFirst) { 9866 this.origPageX = pageX; 9867 this.origPageY = pageY; 9868 } 9869 else { 9870 deltaX = pageX - this.origPageX; 9871 deltaY = pageY - this.origPageY; 9872 } 9873 return { 9874 origEvent: ev, 9875 isTouch: true, 9876 subjectEl: this.subjectEl, 9877 pageX: pageX, 9878 pageY: pageY, 9879 deltaX: deltaX, 9880 deltaY: deltaY, 9881 }; 9882 }; 9883 return PointerDragging; 9884 }());
9885 // Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac) 9886 function isPrimaryMouseButton(ev) { 9887 return ev.button === 0 && !ev.ctrlKey; 9888 } 9889 // Ignoring fake mouse events generated by touch 9890 // ---------------------------------------------------------------------------------------------------- 9891 function startIgnoringMouse() { 9892 ignoreMouseDepth += 1; 9893 setTimeout(function () { 9894 ignoreMouseDepth -= 1; 9895 }, config.touchMouseIgnoreWait); 9896 } 9897 // We want to attach touchmove as early as possible for Safari 9898 // ---------------------------------------------------------------------------------------------------- 9899 function listenerCreated() { 9900 listenerCnt += 1; 9901 if (listenerCnt === 1) { 9902 window.addEventListener('touchmove', onWindowTouchMove, { passive: false }); 9903 } 9904 } 9905 function listenerDestroyed() { 9906 listenerCnt -= 1; 9907 if (!listenerCnt) { 9908 window.removeEventListener('touchmove', onWindowTouchMove, { passive: false }); 9909 } 9910 } 9911 function onWindowTouchMove(ev) { 9912 if (isWindowTouchMoveCancelled) { 9913 ev.preventDefault(); 9914 } 9915 } 9916 9917 /* 9918 An effect in which an element follows the movement of a pointer across the screen. 9919 The moving element is a clone of some other element. 9920 Must call start + handleMove + stop. 9921 */ 9922 var ElementMirror = /** @class */ (function () { 9923 function ElementMirror() { 9924 this.isVisible = false; // must be explicitly enabled 9925 this.sourceEl = null; 9926 this.mirrorEl = null; 9927 this.sourceElRect = null; // screen coords relative to viewport 9928 // options that can be set directly by caller 9929 this.parentNode = document.body; 9930 this.zIndex = 9999; 9931 this.revertDuration = 0; 9932 } 9933 ElementMirror.prototype.start = function (sourceEl, pageX, pageY) { 9934 this.sourceEl = sourceEl; 9935 this.sourceElRect = this.sourceEl.getBoundingClientRect(); 9936 this.origScreenX = pageX - window.pageXOffset; 9937 this.origScreenY = pageY - window.pageYOffset; 9938 this.deltaX = 0; 9939 this.deltaY = 0; 9940 this.updateElPosition(); 9941 }; 9942 ElementMirror.prototype.handleMove = function (pageX, pageY) { 9943 this.deltaX = (pageX - window.pageXOffset) - this.origScreenX; 9944 this.deltaY = (pageY - window.pageYOffset) - this.origScreenY; 9945 this.updateElPosition(); 9946 }; 9947 // can be called before start 9948 ElementMirror.prototype.setIsVisible = function (bool) { 9949 if (bool) { 9950 if (!this.isVisible) { 9951 if (this.mirrorEl) { 9952 this.mirrorEl.style.display = ''; 9953 } 9954 this.isVisible = bool; // needs to happen before updateElPosition 9955 this.updateElPosition(); // because was not updating the position while invisible 9956 } 9957 } 9958 else if (this.isVisible) { 9959 if (this.mirrorEl) { 9960 this.mirrorEl.style.display = 'none'; 9961 } 9962 this.isVisible = bool; 9963 } 9964 }; 9965 // always async 9966 ElementMirror.prototype.stop = function (needsRevertAnimation, callback) { 9967 var _this = this; 9968 var done = function () { 9969 _this.cleanup(); 9970 callback(); 9971 }; 9972 if (needsRevertAnimation && 9973 this.mirrorEl && 9974 this.isVisible && 9975 this.revertDuration && // if 0, transition won't work 9976 (this.deltaX || this.deltaY) // if same coords, transition won't work 9977 ) { 9978 this.doRevertAnimation(done, this.revertDuration); 9979 } 9980 else { 9981 setTimeout(done, 0); 9982 } 9983 }; 9984 ElementMirror.prototype.doRevertAnimation = function (callback, revertDuration) { 9985 var mirrorEl = this.mirrorEl; 9986 var finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened 9987 mirrorEl.style.transition = 9988 'top ' + revertDuration + 'ms,' + 9989 'left ' + revertDuration + 'ms'; 9990 applyStyle(mirrorEl, { 9991 left: finalSourceElRect.left, 9992 top: finalSourceElRect.top, 9993 }); 9994 whenTransitionDone(mirrorEl, function () { 9995 mirrorEl.style.transition = ''; 9996 callback(); 9997 }); 9998 }; 9999 ElementMirror.prototype.cleanup = function () { 10000 if (this.mirrorEl) { 10001 removeElement(this.mirrorEl); 10002 this.mirrorEl = null; 10003 } 10004 this.sourceEl = null; 10005 }; 10006 ElementMirror.prototype.updateElPosition = function () { 10007 if (this.sourceEl && this.isVisible) { 10008 applyStyle(this.getMirrorEl(), { 10009 left: this.sourceElRect.left + this.deltaX,
10010 top: this.sourceElRect.top + this.deltaY, 10011 }); 10012 } 10013 }; 10014 ElementMirror.prototype.getMirrorEl = function () { 10015 var sourceElRect = this.sourceElRect; 10016 var mirrorEl = this.mirrorEl; 10017 if (!mirrorEl) { 10018 mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true 10019 // we don't want long taps or any mouse interaction causing selection/menus. 10020 // would use preventSelection(), but that prevents selectstart, causing problems. 10021 mirrorEl.classList.add('fc-unselectable'); 10022 mirrorEl.classList.add('fc-event-dragging'); 10023 applyStyle(mirrorEl, { 10024 position: 'fixed', 10025 zIndex: this.zIndex, 10026 visibility: '', 10027 boxSizing: 'border-box', 10028 width: sourceElRect.right - sourceElRect.left, 10029 height: sourceElRect.bottom - sourceElRect.top, 10030 right: 'auto', 10031 bottom: 'auto', 10032 margin: 0, 10033 }); 10034 this.parentNode.appendChild(mirrorEl); 10035 } 10036 return mirrorEl; 10037 }; 10038 return ElementMirror; 10039 }()); 10040 10041 /* 10042 Is a cache for a given element's scroll information (all the info that ScrollController stores) 10043 in addition the "client rectangle" of the element.. the area within the scrollbars. 10044 10045 The cache can be in one of two modes: 10046 - doesListening:false - ignores when the container is scrolled by someone else 10047 - doesListening:true - watch for scrolling and update the cache 10048 */ 10049 var ScrollGeomCache = /** @class */ (function (_super) { 10050 __extends(ScrollGeomCache, _super); 10051 function ScrollGeomCache(scrollController, doesListening) { 10052 var _this = _super.call(this) || this; 10053 _this.handleScroll = function () { 10054 _this.scrollTop = _this.scrollController.getScrollTop(); 10055 _this.scrollLeft = _this.scrollController.getScrollLeft(); 10056 _this.handleScrollChange(); 10057 }; 10058 _this.scrollController = scrollController; 10059 _this.doesListening = doesListening; 10060 _this.scrollTop = _this.origScrollTop = scrollController.getScrollTop(); 10061 _this.scrollLeft = _this.origScrollLeft = scrollController.getScrollLeft();
10062 _this.scrollWidth = scrollController.getScrollWidth(); 10063 _this.scrollHeight = scrollController.getScrollHeight(); 10064 _this.clientWidth = scrollController.getClientWidth(); 10065 _this.clientHeight = scrollController.getClientHeight(); 10066 _this.clientRect = _this.computeClientRect(); // do last in case it needs cached values 10067 if (_this.doesListening) { 10068 _this.getEventTarget().addEventListener('scroll', _this.handleScroll); 10069 } 10070 return _this; 10071 } 10072 ScrollGeomCache.prototype.destroy = function () { 10073 if (this.doesListening) { 10074 this.getEventTarget().removeEventListener('scroll', this.handleScroll); 10075 } 10076 }; 10077 ScrollGeomCache.prototype.getScrollTop = function () { 10078 return this.scrollTop; 10079 }; 10080 ScrollGeomCache.prototype.getScrollLeft = function () { 10081 return this.scrollLeft; 10082 }; 10083 ScrollGeomCache.prototype.setScrollTop = function (top) { 10084 this.scrollController.setScrollTop(top); 10085 if (!this.doesListening) { 10086 // we are not relying on the element to normalize out-of-bounds scroll values 10087 // so we need to sanitize ourselves 10088 this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0); 10089 this.handleScrollChange(); 10090 } 10091 }; 10092 ScrollGeomCache.prototype.setScrollLeft = function (top) { 10093 this.scrollController.setScrollLeft(top); 10094 if (!this.doesListening) { 10095 // we are not relying on the element to normalize out-of-bounds scroll values 10096 // so we need to sanitize ourselves 10097 this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0); 10098 this.handleScrollChange(); 10099 } 10100 }; 10101 ScrollGeomCache.prototype.getClientWidth = function () { 10102 return this.clientWidth; 10103 }; 10104 ScrollGeomCache.prototype.getClientHeight = function () { 10105 return this.clientHeight; 10106 }; 10107 ScrollGeomCache.prototype.getScrollWidth = function () { 10108 return this.scrollWidth; 10109 }; 10110 ScrollGeomCache.prototype.getScrollHeight = function () { 10111 return this.scrollHeight; 10112 }; 10113 ScrollGeomCache.prototype.handleScrollChange = function () { 10114 }; 10115 return ScrollGeomCache; 10116 }(ScrollController)); 10117 10118 var ElementScrollGeomCache = /** @class */ (function (_super) { 10119 __extends(ElementScrollGeomCache, _super); 10120 function ElementScrollGeomCache(el, doesListening) { 10121 return _super.call(this, new ElementScrollController(el), doesListening) || this; 10122 } 10123 ElementScrollGeomCache.prototype.getEventTarget = function () { 10124 return this.scrollController.el; 10125 }; 10126 ElementScrollGeomCache.prototype.computeClientRect = function () { 10127 return computeInnerRect(this.scrollController.el); 10128 }; 10129 return ElementScrollGeomCache; 10130 }(ScrollGeomCache)); 10131 10132 var WindowScrollGeomCache = /** @class */ (function (_super) { 10133 __extends(WindowScrollGeomCache, _super); 10134 function WindowScrollGeomCache(doesListening) { 10135 return _super.call(this, new WindowScrollController(), doesListening) || this; 10136 } 10137 WindowScrollGeomCache.prototype.getEventTarget = function () { 10138 return window; 10139 }; 10140 WindowScrollGeomCache.prototype.computeClientRect = function () { 10141 return { 10142 left: this.scrollLeft, 10143 right: this.scrollLeft + this.clientWidth, 10144 top: this.scrollTop, 10145 bottom: this.scrollTop + this.clientHeight, 10146 }; 10147 }; 10148 // the window is the only scroll object that changes it's rectangle relative 10149 // to the document's topleft as it scrolls 10150 WindowScrollGeomCache.prototype.handleScrollChange = function () { 10151 this.clientRect = this.computeClientRect(); 10152 }; 10153 return WindowScrollGeomCache; 10154 }(ScrollGeomCache)); 10155 10156 // If available we are using native "performance" API instead of "Date" 10157 // Read more about it on MDN: 10158 // https://developer.mozilla.org/en-US/docs/Web/API/Performance 10159 var getTime = typeof performance === 'function' ? performance.now : Date.now; 10160 /* 10161 For a pointer interaction, automatically scrolls certain scroll containers when the pointer 10162 approaches the edge. 10163 10164 The caller must call start + handleMove + stop. 10165 */ 10166 var AutoScroller = /** @class */ (function () { 10167 function AutoScroller() { 10168 var _this = this; 10169 // options that can be set by caller 10170 this.isEnabled = true; 10171 this.scrollQuery = [window, '.fc-scroller']; 10172 this.edgeThreshold = 50; // pixels 10173 this.maxVelocity = 300; // pixels per second 10174 // internal state 10175 this.pointerScreenX = null; 10176 this.pointerScreenY = null; 10177 this.isAnimating = false;
10178 this.scrollCaches = null; 10179 // protect against the initial pointerdown being too close to an edge and starting the scroll 10180 this.everMovedUp = false; 10181 this.everMovedDown = false; 10182 this.everMovedLeft = false; 10183 this.everMovedRight = false; 10184 this.animate = function () { 10185 if (_this.isAnimating) { // wasn't cancelled between animation calls 10186 var edge = _this.computeBestEdge(_this.pointerScreenX + window.pageXOffset, _this.pointerScreenY + window.pageYOffset); 10187 if (edge) { 10188 var now = getTime(); 10189 _this.handleSide(edge, (now - _this.msSinceRequest) / 1000); 10190 _this.requestAnimation(now); 10191 } 10192 else { 10193 _this.isAnimating = false; // will stop animation 10194 } 10195 } 10196 }; 10197 } 10198 AutoScroller.prototype.start = function (pageX, pageY) { 10199 if (this.isEnabled) { 10200 this.scrollCaches = this.buildCaches(); 10201 this.pointerScreenX = null; 10202 this.pointerScreenY = null; 10203 this.everMovedUp = false; 10204 this.everMovedDown = false; 10205 this.everMovedLeft = false; 10206 this.everMovedRight = false; 10207 this.handleMove(pageX, pageY); 10208 } 10209 }; 10210 AutoScroller.prototype.handleMove = function (pageX, pageY) { 10211 if (this.isEnabled) { 10212 var pointerScreenX = pageX - window.pageXOffset; 10213 var pointerScreenY = pageY - window.pageYOffset; 10214 var yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY; 10215 var xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX; 10216 if (yDelta < 0) { 10217 this.everMovedUp = true; 10218 } 10219 else if (yDelta > 0) { 10220 this.everMovedDown = true; 10221 } 10222 if (xDelta < 0) { 10223 this.everMovedLeft = true; 10224 } 10225 else if (xDelta > 0) { 10226 this.everMovedRight = true; 10227 } 10228 this.pointerScreenX = pointerScreenX; 10229 this.pointerScreenY = pointerScreenY; 10230 if (!this.isAnimating) { 10231 this.isAnimating = true; 10232 this.requestAnimation(getTime()); 10233 } 10234 } 10235 }; 10236 AutoScroller.prototype.stop = function () { 10237 if (this.isEnabled) { 10238 this.isAnimating = false; // will stop animation 10239 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10240 var scrollCache = _a[_i]; 10241 scrollCache.destroy(); 10242 } 10243 this.scrollCaches = null; 10244 } 10245 }; 10246 AutoScroller.prototype.requestAnimation = function (now) { 10247 this.msSinceRequest = now; 10248 requestAnimationFrame(this.animate); 10249 }; 10250 AutoScroller.prototype.handleSide = function (edge, seconds) { 10251 var scrollCache = edge.scrollCache; 10252 var edgeThreshold = this.edgeThreshold; 10253 var invDistance = edgeThreshold - edge.distance; 10254 var velocity = // the closer to the edge, the faster we scroll 10255 ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic 10256 this.maxVelocity * seconds; 10257 var sign = 1; 10258 switch (edge.name) { 10259 case 'left': 10260 sign = -1; 10261 // falls through 10262 case 'right': 10263 scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign); 10264 break; 10265 case 'top': 10266 sign = -1; 10267 // falls through 10268 case 'bottom': 10269 scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign); 10270 break; 10271 } 10272 }; 10273 // left/top are relative to document topleft 10274 AutoScroller.prototype.computeBestEdge = function (left, top) { 10275 var edgeThreshold = this.edgeThreshold; 10276 var bestSide = null; 10277 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10278 var scrollCache = _a[_i]; 10279 var rect = scrollCache.clientRect; 10280 var leftDist = left - rect.left; 10281 var rightDist = rect.right - left; 10282 var topDist = top - rect.top; 10283 var bottomDist = rect.bottom - top; 10284 // completely within the rect? 10285 if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) { 10286 if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && 10287 (!bestSide || bestSide.distance > topDist)) { 10288 bestSide = { scrollCache: scrollCache, name: 'top', distance: topDist }; 10289 } 10290 if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && 10291 (!bestSide || bestSide.distance > bottomDist)) { 10292 bestSide = { scrollCache: scrollCache, name: 'bottom', distance: bottomDist }; 10293 } 10294 if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && 10295 (!bestSide || bestSide.distance > leftDist)) { 10296 bestSide = { scrollCache: scrollCache, name: 'left', distance: leftDist }; 10297 } 10298 if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && 10299 (!bestSide || bestSide.distance > rightDist)) { 10300 bestSide = { scrollCache: scrollCache, name: 'right', distance: rightDist }; 10301 } 10302 } 10303 } 10304 return bestSide; 10305 }; 10306 AutoScroller.prototype.buildCaches = function () { 10307 return this.queryScrollEls().map(function (el) { 10308 if (el === window) { 10309 return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls 10310 } 10311 return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls 10312 }); 10313 }; 10314 AutoScroller.prototype.queryScrollEls = function () { 10315 var els = []; 10316 for (var _i = 0, _a = this.scrollQuery; _i < _a.length; _i++) { 10317 var query = _a[_i]; 10318 if (typeof query === 'object') { 10319 els.push(query); 10320 } 10321 else { 10322 els.push.apply(els, Array.prototype.slice.call(document.querySelectorAll(query))); 10323 } 10324 } 10325 return els; 10326 }; 10327 return AutoScroller; 10328 }()); 10329 10330 /* 10331 Monitors dragging on an element. Has a number of high-level features: 10332 - minimum distance required before dragging 10333 - minimum wait time ("delay") before dragging 10334 - a mirror element that follows the pointer 10335 */ 10336 var FeaturefulElementDragging = /** @class */ (function (_super) { 10337 __extends(FeaturefulElementDragging, _super); 10338 function FeaturefulElementDragging(containerEl, selector) { 10339 var _this = _super.call(this, containerEl) || this; 10340 // options that can be directly set by caller 10341 // the caller can also set the PointerDragging's options as well 10342 _this.delay = null; 10343 _this.minDistance = 0; 10344 _this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag 10345 _this.mirrorNeedsRevert = false;
10346 _this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup 10347 _this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation 10348 _this.isDelayEnded = false; 10349 _this.isDistanceSurpassed = false; 10350 _this.delayTimeoutId = null; 10351 _this.onPointerDown = function (ev) { 10352 if (!_this.isDragging) { // so new drag doesn't happen while revert animation is going 10353 _this.isInteracting = true; 10354 _this.isDelayEnded = false; 10355 _this.isDistanceSurpassed = false; 10356 preventSelection(document.body); 10357 preventContextMenu(document.body); 10358 // prevent links from being visited if there's an eventual drag. 10359 // also prevents selection in older browsers (maybe?). 10360 // not necessary for touch, besides, browser would complain about passiveness. 10361 if (!ev.isTouch) { 10362 ev.origEvent.preventDefault(); 10363 } 10364 _this.emitter.trigger('pointerdown', ev); 10365 if (_this.isInteracting && // not destroyed via pointerdown handler 10366 !_this.pointer.shouldIgnoreMove) { 10367 // actions related to initiating dragstart+dragmove+dragend... 10368 _this.mirror.setIsVisible(false); // reset. caller must set-visible 10369 _this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down 10370 _this.startDelay(ev); 10371 if (!_this.minDistance) { 10372 _this.handleDistanceSurpassed(ev); 10373 } 10374 } 10375 } 10376 }; 10377 _this.onPointerMove = function (ev) { 10378 if (_this.isInteracting) { 10379 _this.emitter.trigger('pointermove', ev); 10380 if (!_this.isDistanceSurpassed) { 10381 var minDistance = _this.minDistance; 10382 var distanceSq = void 0; // current distance from the origin, squared 10383 var deltaX = ev.deltaX, deltaY = ev.deltaY; 10384 distanceSq = deltaX * deltaX + deltaY * deltaY; 10385 if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem 10386 _this.handleDistanceSurpassed(ev); 10387 } 10388 } 10389 if (_this.isDragging) { 10390 // a real pointer move? (not one simulated by scrolling) 10391 if (ev.origEvent.type !== 'scroll') { 10392 _this.mirror.handleMove(ev.pageX, ev.pageY); 10393 _this.autoScroller.handleMove(ev.pageX, ev.pageY); 10394 } 10395 _this.emitter.trigger('dragmove', ev); 10396 } 10397 } 10398 }; 10399 _this.onPointerUp = function (ev) { 10400 if (_this.isInteracting) { 10401 _this.isInteracting = false; 10402 allowSelection(document.body); 10403 allowContextMenu(document.body); 10404 _this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert 10405 if (_this.isDragging) { 10406 _this.autoScroller.stop(); 10407 _this.tryStopDrag(ev); // which will stop the mirror 10408 } 10409 if (_this.delayTimeoutId) { 10410 clearTimeout(_this.delayTimeoutId); 10411 _this.delayTimeoutId = null; 10412 } 10413 } 10414 }; 10415 var pointer = _this.pointer = new PointerDragging(containerEl); 10416 pointer.emitter.on('pointerdown', _this.onPointerDown); 10417 pointer.emitter.on('pointermove', _this.onPointerMove); 10418 pointer.emitter.on('pointerup', _this.onPointerUp); 10419 if (selector) { 10420 pointer.selector = selector; 10421 } 10422 _this.mirror = new ElementMirror(); 10423 _this.autoScroller = new AutoScroller(); 10424 return _this; 10425 } 10426 FeaturefulElementDragging.prototype.destroy = function () { 10427 this.pointer.destroy(); 10428 // HACK: simulate a pointer-up to end the current drag
10429 // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire) 10430 this.onPointerUp({}); 10431 }; 10432 FeaturefulElementDragging.prototype.startDelay = function (ev) { 10433 var _this = this; 10434 if (typeof this.delay === 'number') { 10435 this.delayTimeoutId = setTimeout(function () { 10436 _this.delayTimeoutId = null; 10437 _this.handleDelayEnd(ev); 10438 }, this.delay); // not assignable to number! 10439 } 10440 else { 10441 this.handleDelayEnd(ev); 10442 } 10443 }; 10444 FeaturefulElementDragging.prototype.handleDelayEnd = function (ev) { 10445 this.isDelayEnded = true; 10446 this.tryStartDrag(ev); 10447 }; 10448 FeaturefulElementDragging.prototype.handleDistanceSurpassed = function (ev) { 10449 this.isDistanceSurpassed = true; 10450 this.tryStartDrag(ev); 10451 }; 10452 FeaturefulElementDragging.prototype.tryStartDrag = function (ev) { 10453 if (this.isDelayEnded && this.isDistanceSurpassed) { 10454 if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) { 10455 this.isDragging = true; 10456 this.mirrorNeedsRevert = false; 10457 this.autoScroller.start(ev.pageX, ev.pageY); 10458 this.emitter.trigger('dragstart', ev); 10459 if (this.touchScrollAllowed === false) { 10460 this.pointer.cancelTouchScroll(); 10461 } 10462 } 10463 } 10464 }; 10465 FeaturefulElementDragging.prototype.tryStopDrag = function (ev) { 10466 // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events 10467 // that come from the document to fire beforehand. much more convenient this way. 10468 this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev)); 10469 }; 10470 FeaturefulElementDragging.prototype.stopDrag = function (ev) { 10471 this.isDragging = false; 10472 this.emitter.trigger('dragend', ev); 10473 }; 10474 // fill in the implementations... 10475 FeaturefulElementDragging.prototype.setIgnoreMove = function (bool) { 10476 this.pointer.shouldIgnoreMove = bool; 10477 }; 10478 FeaturefulElementDragging.prototype.setMirrorIsVisible = function (bool) { 10479 this.mirror.setIsVisible(bool); 10480 }; 10481 FeaturefulElementDragging.prototype.setMirrorNeedsRevert = function (bool) { 10482 this.mirrorNeedsRevert = bool; 10483 }; 10484 FeaturefulElementDragging.prototype.setAutoScrollEnabled = function (bool) { 10485 this.autoScroller.isEnabled = bool; 10486 }; 10487 return FeaturefulElementDragging; 10488 }(ElementDragging)); 10489 10490 /* 10491 When this class is instantiated, it records the offset of an element (relative to the document topleft), 10492 and continues to monitor scrolling, updating the cached coordinates if it needs to. 10493 Does not access the DOM after instantiation, so highly performant. 10494 10495 Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element 10496 and an determine if a given point is inside the combined clipping rectangle. 10497 */ 10498 var OffsetTracker = /** @class */ (function () { 10499 function OffsetTracker(el) { 10500 this.origRect = computeRect(el); 10501 // will work fine for divs that have overflow:hidden 10502 this.scrollCaches = getClippingParents(el).map(function (scrollEl) { return new ElementScrollGeomCache(scrollEl, true); }); 10503 } 10504 OffsetTracker.prototype.destroy = function () { 10505 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10506 var scrollCache = _a[_i]; 10507 scrollCache.destroy(); 10508 } 10509 }; 10510 OffsetTracker.prototype.computeLeft = function () { 10511 var left = this.origRect.left; 10512 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10513 var scrollCache = _a[_i]; 10514 left += scrollCache.origScrollLeft - scrollCache.getScrollLeft(); 10515 } 10516 return left; 10517 }; 10518 OffsetTracker.prototype.computeTop = function () { 10519 var top = this.origRect.top; 10520 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10521 var scrollCache = _a[_i]; 10522 top += scrollCache.origScrollTop - scrollCache.getScrollTop(); 10523 } 10524 return top; 10525 }; 10526 OffsetTracker.prototype.isWithinClipping = function (pageX, pageY) { 10527 var point = { left: pageX, top: pageY }; 10528 for (var _i = 0, _a = this.scrollCaches; _i < _a.length; _i++) { 10529 var scrollCache = _a[_i];
10530 if (!isIgnoredClipping(scrollCache.getEventTarget()) && 10531 !pointInsideRect(point, scrollCache.clientRect)) { 10532 return false; 10533 } 10534 } 10535 return true; 10536 }; 10537 return OffsetTracker; 10538 }()); 10539 // certain clipping containers should never constrain interactions, like <html> and <body> 10540 // https://github.com/fullcalendar/fullcalendar/issues/3615 10541 function isIgnoredClipping(node) { 10542 var tagName = node.tagName; 10543 return tagName === 'HTML' || tagName === 'BODY'; 10544 } 10545 10546 /* 10547 Tracks movement over multiple droppable areas (aka "hits") 10548 that exist in one or more DateComponents. 10549 Relies on an existing draggable. 10550 10551 emits: 10552 - pointerdown 10553 - dragstart 10554 - hitchange - fires initially, even if not over a hit 10555 - pointerup 10556 - (hitchange - again, to null, if ended over a hit) 10557 - dragend 10558 */ 10559 var HitDragging = /** @class */ (function () { 10560 function HitDragging(dragging, droppableStore) { 10561 var _this = this; 10562 // options that can be set by caller 10563 this.useSubjectCenter = false; 10564 this.requireInitial = true; // if doesn't start out on a hit, won't emit any events 10565 this.initialHit = null; 10566 this.movingHit = null; 10567 this.finalHit = null; // won't ever be populated if shouldIgnoreMove 10568 this.handlePointerDown = function (ev) { 10569 var dragging = _this.dragging; 10570 _this.initialHit = null; 10571 _this.movingHit = null; 10572 _this.finalHit = null; 10573 _this.prepareHits(); 10574 _this.processFirstCoord(ev); 10575 if (_this.initialHit || !_this.requireInitial) { 10576 dragging.setIgnoreMove(false);
10577 // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :( 10578 _this.emitter.trigger('pointerdown', ev); 10579 } 10580 else { 10581 dragging.setIgnoreMove(true); 10582 } 10583 }; 10584 this.handleDragStart = function (ev) { 10585 _this.emitter.trigger('dragstart', ev); 10586 _this.handleMove(ev, true); // force = fire even if initially null 10587 }; 10588 this.handleDragMove = function (ev) { 10589 _this.emitter.trigger('dragmove', ev); 10590 _this.handleMove(ev); 10591 }; 10592 this.handlePointerUp = function (ev) { 10593 _this.releaseHits(); 10594 _this.emitter.trigger('pointerup', ev); 10595 }; 10596 this.handleDragEnd = function (ev) { 10597 if (_this.movingHit) { 10598 _this.emitter.trigger('hitupdate', null, true, ev); 10599 } 10600 _this.finalHit = _this.movingHit; 10601 _this.movingHit = null; 10602 _this.emitter.trigger('dragend', ev); 10603 }; 10604 this.droppableStore = droppableStore; 10605 dragging.emitter.on('pointerdown', this.handlePointerDown); 10606 dragging.emitter.on('dragstart', this.handleDragStart); 10607 dragging.emitter.on('dragmove', this.handleDragMove); 10608 dragging.emitter.on('pointerup', this.handlePointerUp); 10609 dragging.emitter.on('dragend', this.handleDragEnd); 10610 this.dragging = dragging; 10611 this.emitter = new Emitter(); 10612 } 10613 // sets initialHit 10614 // sets coordAdjust 10615 HitDragging.prototype.processFirstCoord = function (ev) { 10616 var origPoint = { left: ev.pageX, top: ev.pageY }; 10617 var adjustedPoint = origPoint; 10618 var subjectEl = ev.subjectEl; 10619 var subjectRect; 10620 if (subjectEl !== document) { 10621 subjectRect = computeRect(subjectEl); 10622 adjustedPoint = constrainPoint(adjustedPoint, subjectRect); 10623 } 10624 var initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top); 10625 if (initialHit) { 10626 if (this.useSubjectCenter && subjectRect) { 10627 var slicedSubjectRect = intersectRects(subjectRect, initialHit.rect); 10628 if (slicedSubjectRect) { 10629 adjustedPoint = getRectCenter(slicedSubjectRect); 10630 } 10631 } 10632 this.coordAdjust = diffPoints(adjustedPoint, origPoint); 10633 } 10634 else { 10635 this.coordAdjust = { left: 0, top: 0 }; 10636 } 10637 }; 10638 HitDragging.prototype.handleMove = function (ev, forceHandle) { 10639 var hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top); 10640 if (forceHandle || !isHitsEqual(this.movingHit, hit)) { 10641 this.movingHit = hit; 10642 this.emitter.trigger('hitupdate', hit, false, ev); 10643 } 10644 }; 10645 HitDragging.prototype.prepareHits = function () { 10646 this.offsetTrackers = mapHash(this.droppableStore, function (interactionSettings) { 10647 interactionSettings.component.prepareHits(); 10648 return new OffsetTracker(interactionSettings.el); 10649 }); 10650 }; 10651 HitDragging.prototype.releaseHits = function () { 10652 var offsetTrackers = this.offsetTrackers; 10653 for (var id in offsetTrackers) { 10654 offsetTrackers[id].destroy(); 10655 } 10656 this.offsetTrackers = {}; 10657 }; 10658 HitDragging.prototype.queryHitForOffset = function (offsetLeft, offsetTop) { 10659 var _a = this, droppableStore = _a.droppableStore, offsetTrackers = _a.offsetTrackers; 10660 var bestHit = null; 10661 for (var id in droppableStore) { 10662 var component = droppableStore[id].component; 10663 var offsetTracker = offsetTrackers[id]; 10664 if (offsetTracker && // wasn't destroyed mid-drag 10665 offsetTracker.isWithinClipping(offsetLeft, offsetTop)) { 10666 var originLeft = offsetTracker.computeLeft(); 10667 var originTop = offsetTracker.computeTop(); 10668 var positionLeft = offsetLeft - originLeft; 10669 var positionTop = offsetTop - originTop; 10670 var origRect = offsetTracker.origRect; 10671 var width = origRect.right - origRect.left; 10672 var height = origRect.bottom - origRect.top; 10673 if ( 10674 // must be within the element's bounds 10675 positionLeft >= 0 && positionLeft < width && 10676 positionTop >= 0 && positionTop < height) { 10677 var hit = component.queryHit(positionLeft, positionTop, width, height); 10678 if (hit && ( 10679 // make sure the hit is within activeRange, meaning it's not a dead cell 10680 rangeContainsRange(hit.dateProfile.activeRange, hit.dateSpan.range)) && 10681 (!bestHit || hit.layer > bestHit.layer)) { 10682 hit.componentId = id; 10683 hit.context = component.context; 10684 // TODO: better way to re-orient rectangle 10685 hit.rect.left += originLeft; 10686 hit.rect.right += originLeft; 10687 hit.rect.top += originTop; 10688 hit.rect.bottom += originTop; 10689 bestHit = hit; 10690 } 10691 } 10692 } 10693 } 10694 return bestHit; 10695 }; 10696 return HitDragging; 10697 }()); 10698 function isHitsEqual(hit0, hit1) { 10699 if (!hit0 && !hit1) { 10700 return true; 10701 } 10702 if (Boolean(hit0) !== Boolean(hit1)) { 10703 return false;
10704 } 10705 return isDateSpansEqual(hit0.dateSpan, hit1.dateSpan); 10706 } 10707 10708 function buildDatePointApiWithContext(dateSpan, context) { 10709 var props = {}; 10710 for (var _i = 0, _a = context.pluginHooks.datePointTransforms; _i < _a.length; _i++) { 10711 var transform = _a[_i]; 10712 __assign(props, transform(dateSpan, context)); 10713 } 10714 __assign(props, buildDatePointApi(dateSpan, context.dateEnv)); 10715 return props; 10716 } 10717 function buildDatePointApi(span, dateEnv) { 10718 return { 10719 date: dateEnv.toDate(span.range.start), 10720 dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }), 10721 allDay: span.allDay, 10722 }; 10723 } 10724 10725 /* 10726 Monitors when the user clicks on a specific date/time of a component. 10727 A pointerdown+pointerup on the same "hit" constitutes a click. 10728 */ 10729 var DateClicking = /** @class */ (function (_super) { 10730 __extends(DateClicking, _super); 10731 function DateClicking(settings) { 10732 var _this = _super.call(this, settings) || this; 10733 _this.handlePointerDown = function (pev) { 10734 var dragging = _this.dragging; 10735 var downEl = pev.origEvent.target; 10736 // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired 10737 dragging.setIgnoreMove(!_this.component.isValidDateDownEl(downEl)); 10738 }; 10739 // won't even fire if moving was ignored 10740 _this.handleDragEnd = function (ev) { 10741 var component = _this.component; 10742 var pointer = _this.dragging.pointer; 10743 if (!pointer.wasTouchScroll) { 10744 var _a = _this.hitDragging, initialHit = _a.initialHit, finalHit = _a.finalHit; 10745 if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) { 10746 var context = component.context; 10747 var arg = __assign(__assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view }); 10748 context.emitter.trigger('dateClick', arg); 10749 } 10750 } 10751 }; 10752 // we DO want to watch pointer moves because otherwise finalHit won't get populated 10753 _this.dragging = new FeaturefulElementDragging(settings.el); 10754 _this.dragging.autoScroller.isEnabled = false; 10755 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 10756 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 10757 hitDragging.emitter.on('dragend', _this.handleDragEnd); 10758 return _this; 10759 } 10760 DateClicking.prototype.destroy = function () { 10761 this.dragging.destroy(); 10762 }; 10763 return DateClicking; 10764 }(Interaction)); 10765 10766 /* 10767 Tracks when the user selects a portion of time of a component, 10768 constituted by a drag over date cells, with a possible delay at the beginning of the drag. 10769 */ 10770 var DateSelecting = /** @class */ (function (_super) { 10771 __extends(DateSelecting, _super); 10772 function DateSelecting(settings) { 10773 var _this = _super.call(this, settings) || this; 10774 _this.dragSelection = null; 10775 _this.handlePointerDown = function (ev) { 10776 var _a = _this, component = _a.component, dragging = _a.dragging; 10777 var options = component.context.options; 10778 var canSelect = options.selectable && 10779 component.isValidDateDownEl(ev.origEvent.target); 10780 // don't bother to watch expensive moves if component won't do selection 10781 dragging.setIgnoreMove(!canSelect); 10782 // if touch, require user to hold down 10783 dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null; 10784 }; 10785 _this.handleDragStart = function (ev) { 10786 _this.component.context.calendarApi.unselect(ev); // unselect previous selections 10787 }; 10788 _this.handleHitUpdate = function (hit, isFinal) { 10789 var context = _this.component.context; 10790 var dragSelection = null; 10791 var isInvalid = false;
10792 if (hit) { 10793 var initialHit = _this.hitDragging.initialHit; 10794 var disallowed = hit.componentId === initialHit.componentId 10795 && _this.isHitComboAllowed 10796 && !_this.isHitComboAllowed(initialHit, hit); 10797 if (!disallowed) { 10798 dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers); 10799 } 10800 if (!dragSelection || !isDateSelectionValid(dragSelection, hit.dateProfile, context)) { 10801 isInvalid = true; 10802 dragSelection = null; 10803 } 10804 } 10805 if (dragSelection) { 10806 context.dispatch({ type: 'SELECT_DATES', selection: dragSelection }); 10807 } 10808 else if (!isFinal) { // only unselect if moved away while dragging 10809 context.dispatch({ type: 'UNSELECT_DATES' }); 10810 } 10811 if (!isInvalid) { 10812 enableCursor(); 10813 } 10814 else { 10815 disableCursor(); 10816 } 10817 if (!isFinal) { 10818 _this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging 10819 } 10820 }; 10821 _this.handlePointerUp = function (pev) { 10822 if (_this.dragSelection) { 10823 // selection is already rendered, so just need to report selection 10824 triggerDateSelect(_this.dragSelection, pev, _this.component.context); 10825 _this.dragSelection = null; 10826 } 10827 }; 10828 var component = settings.component; 10829 var options = component.context.options; 10830 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 10831 dragging.touchScrollAllowed = false; 10832 dragging.minDistance = options.selectMinDistance || 0; 10833 dragging.autoScroller.isEnabled = options.dragScroll; 10834 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 10835 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 10836 hitDragging.emitter.on('dragstart', _this.handleDragStart); 10837 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 10838 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 10839 return _this; 10840 } 10841 DateSelecting.prototype.destroy = function () { 10842 this.dragging.destroy(); 10843 }; 10844 return DateSelecting; 10845 }(Interaction)); 10846 function getComponentTouchDelay$1(component) { 10847 var options = component.context.options; 10848 var delay = options.selectLongPressDelay; 10849 if (delay == null) { 10850 delay = options.longPressDelay; 10851 } 10852 return delay; 10853 } 10854 function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) { 10855 var dateSpan0 = hit0.dateSpan; 10856 var dateSpan1 = hit1.dateSpan; 10857 var ms = [ 10858 dateSpan0.range.start, 10859 dateSpan0.range.end, 10860 dateSpan1.range.start, 10861 dateSpan1.range.end, 10862 ]; 10863 ms.sort(compareNumbers); 10864 var props = {}; 10865 for (var _i = 0, dateSelectionTransformers_1 = dateSelectionTransformers; _i < dateSelectionTransformers_1.length; _i++) { 10866 var transformer = dateSelectionTransformers_1[_i]; 10867 var res = transformer(hit0, hit1); 10868 if (res === false) { 10869 return null; 10870 } 10871 if (res) { 10872 __assign(props, res); 10873 } 10874 } 10875 props.range = { start: ms[0], end: ms[3] }; 10876 props.allDay = dateSpan0.allDay; 10877 return props; 10878 } 10879 10880 var EventDragging = /** @class */ (function (_super) { 10881 __extends(EventDragging, _super); 10882 function EventDragging(settings) { 10883 var _this = _super.call(this, settings) || this; 10884 // internal state 10885 _this.subjectEl = null; 10886 _this.subjectSeg = null; // the seg being selected/dragged 10887 _this.isDragging = false;
10888 _this.eventRange = null; 10889 _this.relevantEvents = null; // the events being dragged 10890 _this.receivingContext = null; 10891 _this.validMutation = null; 10892 _this.mutatedRelevantEvents = null; 10893 _this.handlePointerDown = function (ev) { 10894 var origTarget = ev.origEvent.target; 10895 var _a = _this, component = _a.component, dragging = _a.dragging; 10896 var mirror = dragging.mirror; 10897 var options = component.context.options; 10898 var initialContext = component.context; 10899 _this.subjectEl = ev.subjectEl; 10900 var subjectSeg = _this.subjectSeg = getElSeg(ev.subjectEl); 10901 var eventRange = _this.eventRange = subjectSeg.eventRange; 10902 var eventInstanceId = eventRange.instance.instanceId; 10903 _this.relevantEvents = getRelevantEvents(initialContext.getCurrentData().eventStore, eventInstanceId); 10904 dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance; 10905 dragging.delay = 10906 // only do a touch delay if touch and this event hasn't been selected yet 10907 (ev.isTouch && eventInstanceId !== component.props.eventSelection) ? 10908 getComponentTouchDelay(component) : 10909 null; 10910 if (options.fixedMirrorParent) { 10911 mirror.parentNode = options.fixedMirrorParent; 10912 } 10913 else { 10914 mirror.parentNode = elementClosest(origTarget, '.fc'); 10915 } 10916 mirror.revertDuration = options.dragRevertDuration; 10917 var isValid = component.isValidSegDownEl(origTarget) && 10918 !elementClosest(origTarget, '.fc-event-resizer'); // NOT on a resizer 10919 dragging.setIgnoreMove(!isValid); 10920 // disable dragging for elements that are resizable (ie, selectable) 10921 // but are not draggable 10922 _this.isDragging = isValid && 10923 ev.subjectEl.classList.contains('fc-event-draggable'); 10924 }; 10925 _this.handleDragStart = function (ev) { 10926 var initialContext = _this.component.context; 10927 var eventRange = _this.eventRange; 10928 var eventInstanceId = eventRange.instance.instanceId; 10929 if (ev.isTouch) { 10930 // need to select a different event? 10931 if (eventInstanceId !== _this.component.props.eventSelection) { 10932 initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId: eventInstanceId }); 10933 } 10934 } 10935 else { 10936 // if now using mouse, but was previous touch interaction, clear selected event 10937 initialContext.dispatch({ type: 'UNSELECT_EVENT' }); 10938 } 10939 if (_this.isDragging) { 10940 initialContext.calendarApi.unselect(ev); // unselect *date* selection 10941 initialContext.emitter.trigger('eventDragStart', { 10942 el: _this.subjectEl, 10943 event: new EventApi(initialContext, eventRange.def, eventRange.instance), 10944 jsEvent: ev.origEvent, 10945 view: initialContext.viewApi, 10946 }); 10947 } 10948 }; 10949 _this.handleHitUpdate = function (hit, isFinal) { 10950 if (!_this.isDragging) { 10951 return; 10952 } 10953 var relevantEvents = _this.relevantEvents; 10954 var initialHit = _this.hitDragging.initialHit; 10955 var initialContext = _this.component.context; 10956 // states based on new hit 10957 var receivingContext = null; 10958 var mutation = null; 10959 var mutatedRelevantEvents = null; 10960 var isInvalid = false; 10961 var interaction = { 10962 affectedEvents: relevantEvents, 10963 mutatedEvents: createEmptyEventStore(), 10964 isEvent: true, 10965 }; 10966 if (hit) { 10967 receivingContext = hit.context; 10968 var receivingOptions = receivingContext.options; 10969 if (initialContext === receivingContext || 10970 (receivingOptions.editable && receivingOptions.droppable)) { 10971 mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers); 10972 if (mutation) { 10973 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext); 10974 interaction.mutatedEvents = mutatedRelevantEvents; 10975 if (!isInteractionValid(interaction, hit.dateProfile, receivingContext)) { 10976 isInvalid = true; 10977 mutation = null; 10978 mutatedRelevantEvents = null; 10979 interaction.mutatedEvents = createEmptyEventStore(); 10980 } 10981 } 10982 } 10983 else { 10984 receivingContext = null; 10985 } 10986 } 10987 _this.displayDrag(receivingContext, interaction); 10988 if (!isInvalid) {
10989 enableCursor(); 10990 } 10991 else { 10992 disableCursor(); 10993 } 10994 if (!isFinal) { 10995 if (initialContext === receivingContext && // TODO: write test for this 10996 isHitsEqual(initialHit, hit)) { 10997 mutation = null; 10998 } 10999 _this.dragging.setMirrorNeedsRevert(!mutation); 11000 // render the mirror if no already-rendered mirror 11001 // TODO: wish we could somehow wait for dispatch to guarantee render 11002 _this.dragging.setMirrorIsVisible(!hit || !document.querySelector('.fc-event-mirror')); 11003 // assign states based on new hit 11004 _this.receivingContext = receivingContext; 11005 _this.validMutation = mutation; 11006 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11007 } 11008 }; 11009 _this.handlePointerUp = function () { 11010 if (!_this.isDragging) { 11011 _this.cleanup(); // because handleDragEnd won't fire 11012 } 11013 }; 11014 _this.handleDragEnd = function (ev) { 11015 if (_this.isDragging) { 11016 var initialContext_1 = _this.component.context; 11017 var initialView = initialContext_1.viewApi; 11018 var _a = _this, receivingContext_1 = _a.receivingContext, validMutation = _a.validMutation; 11019 var eventDef = _this.eventRange.def; 11020 var eventInstance = _this.eventRange.instance; 11021 var eventApi = new EventApi(initialContext_1, eventDef, eventInstance); 11022 var relevantEvents_1 = _this.relevantEvents; 11023 var mutatedRelevantEvents_1 = _this.mutatedRelevantEvents; 11024 var finalHit = _this.hitDragging.finalHit; 11025 _this.clearDrag(); // must happen after revert animation 11026 initialContext_1.emitter.trigger('eventDragStop', { 11027 el: _this.subjectEl, 11028 event: eventApi, 11029 jsEvent: ev.origEvent, 11030 view: initialView, 11031 }); 11032 if (validMutation) { 11033 // dropped within same calendar 11034 if (receivingContext_1 === initialContext_1) { 11035 var updatedEventApi = new EventApi(initialContext_1, mutatedRelevantEvents_1.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents_1.instances[eventInstance.instanceId] : null); 11036 initialContext_1.dispatch({ 11037 type: 'MERGE_EVENTS', 11038 eventStore: mutatedRelevantEvents_1, 11039 }); 11040 var eventChangeArg = { 11041 oldEvent: eventApi, 11042 event: updatedEventApi, 11043 relatedEvents: buildEventApis(mutatedRelevantEvents_1, initialContext_1, eventInstance), 11044 revert: function () { 11045 initialContext_1.dispatch({ 11046 type: 'MERGE_EVENTS', 11047 eventStore: relevantEvents_1, // the pre-change data 11048 }); 11049 }, 11050 }; 11051 var transformed = {}; 11052 for (var _i = 0, _b = initialContext_1.getCurrentData().pluginHooks.eventDropTransformers; _i < _b.length; _i++) { 11053 var transformer = _b[_i]; 11054 __assign(transformed, transformer(validMutation, initialContext_1)); 11055 } 11056 initialContext_1.emitter.trigger('eventDrop', __assign(__assign(__assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView })); 11057 initialContext_1.emitter.trigger('eventChange', eventChangeArg); 11058 // dropped in different calendar 11059 } 11060 else if (receivingContext_1) { 11061 var eventRemoveArg = { 11062 event: eventApi, 11063 relatedEvents: buildEventApis(relevantEvents_1, initialContext_1, eventInstance), 11064 revert: function () { 11065 initialContext_1.dispatch({ 11066 type: 'MERGE_EVENTS', 11067 eventStore: relevantEvents_1, 11068 }); 11069 }, 11070 }; 11071 initialContext_1.emitter.trigger('eventLeave', __assign(__assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView })); 11072 initialContext_1.dispatch({
11073 type: 'REMOVE_EVENTS', 11074 eventStore: relevantEvents_1, 11075 }); 11076 initialContext_1.emitter.trigger('eventRemove', eventRemoveArg); 11077 var addedEventDef = mutatedRelevantEvents_1.defs[eventDef.defId]; 11078 var addedEventInstance = mutatedRelevantEvents_1.instances[eventInstance.instanceId]; 11079 var addedEventApi = new EventApi(receivingContext_1, addedEventDef, addedEventInstance); 11080 receivingContext_1.dispatch({ 11081 type: 'MERGE_EVENTS', 11082 eventStore: mutatedRelevantEvents_1, 11083 }); 11084 var eventAddArg = { 11085 event: addedEventApi, 11086 relatedEvents: buildEventApis(mutatedRelevantEvents_1, receivingContext_1, addedEventInstance), 11087 revert: function () { 11088 receivingContext_1.dispatch({ 11089 type: 'REMOVE_EVENTS', 11090 eventStore: mutatedRelevantEvents_1, 11091 }); 11092 }, 11093 }; 11094 receivingContext_1.emitter.trigger('eventAdd', eventAddArg); 11095 if (ev.isTouch) { 11096 receivingContext_1.dispatch({ 11097 type: 'SELECT_EVENT', 11098 eventInstanceId: eventInstance.instanceId, 11099 }); 11100 } 11101 receivingContext_1.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext_1)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi })); 11102 receivingContext_1.emitter.trigger('eventReceive', __assign(__assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi })); 11103 } 11104 } 11105 else { 11106 initialContext_1.emitter.trigger('_noEventDrop'); 11107 } 11108 } 11109 _this.cleanup(); 11110 }; 11111 var component = _this.component; 11112 var options = component.context.options; 11113 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11114 dragging.pointer.selector = EventDragging.SELECTOR; 11115 dragging.touchScrollAllowed = false; 11116 dragging.autoScroller.isEnabled = options.dragScroll; 11117 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsStore); 11118 hitDragging.useSubjectCenter = settings.useEventCenter; 11119 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11120 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11121 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11122 hitDragging.emitter.on('pointerup', _this.handlePointerUp); 11123 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11124 return _this; 11125 } 11126 EventDragging.prototype.destroy = function () { 11127 this.dragging.destroy(); 11128 }; 11129 // render a drag state on the next receivingCalendar 11130 EventDragging.prototype.displayDrag = function (nextContext, state) { 11131 var initialContext = this.component.context; 11132 var prevContext = this.receivingContext; 11133 // does the previous calendar need to be cleared? 11134 if (prevContext && prevContext !== nextContext) { 11135 // does the initial calendar need to be cleared? 11136 // if so, don't clear all the way. we still need to to hide the affectedEvents 11137 if (prevContext === initialContext) { 11138 prevContext.dispatch({ 11139 type: 'SET_EVENT_DRAG', 11140 state: { 11141 affectedEvents: state.affectedEvents, 11142 mutatedEvents: createEmptyEventStore(), 11143 isEvent: true, 11144 }, 11145 }); 11146 // completely clear the old calendar if it wasn't the initial 11147 } 11148 else { 11149 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11150 } 11151 } 11152 if (nextContext) { 11153 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11154 } 11155 }; 11156 EventDragging.prototype.clearDrag = function () { 11157 var initialCalendar = this.component.context; 11158 var receivingContext = this.receivingContext; 11159 if (receivingContext) { 11160 receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11161 } 11162 // the initial calendar might have an dummy drag state from displayDrag 11163 if (initialCalendar !== receivingContext) { 11164 initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11165 } 11166 }; 11167 EventDragging.prototype.cleanup = function () { 11168 this.subjectSeg = null; 11169 this.isDragging = false;
11170 this.eventRange = null; 11171 this.relevantEvents = null; 11172 this.receivingContext = null; 11173 this.validMutation = null; 11174 this.mutatedRelevantEvents = null; 11175 }; 11176 // TODO: test this in IE11 11177 // QUESTION: why do we need it on the resizable??? 11178 EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable'; 11179 return EventDragging; 11180 }(Interaction)); 11181 function computeEventMutation(hit0, hit1, massagers) { 11182 var dateSpan0 = hit0.dateSpan; 11183 var dateSpan1 = hit1.dateSpan; 11184 var date0 = dateSpan0.range.start; 11185 var date1 = dateSpan1.range.start; 11186 var standardProps = {}; 11187 if (dateSpan0.allDay !== dateSpan1.allDay) { 11188 standardProps.allDay = dateSpan1.allDay; 11189 standardProps.hasEnd = hit1.context.options.allDayMaintainDuration; 11190 if (dateSpan1.allDay) { 11191 // means date1 is already start-of-day, 11192 // but date0 needs to be converted 11193 date0 = startOfDay(date0); 11194 } 11195 } 11196 var delta = diffDates(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? 11197 hit0.largeUnit : 11198 null); 11199 if (delta.milliseconds) { // has hours/minutes/seconds 11200 standardProps.allDay = false; 11201 } 11202 var mutation = { 11203 datesDelta: delta, 11204 standardProps: standardProps, 11205 }; 11206 for (var _i = 0, massagers_1 = massagers; _i < massagers_1.length; _i++) { 11207 var massager = massagers_1[_i]; 11208 massager(mutation, hit0, hit1); 11209 } 11210 return mutation; 11211 } 11212 function getComponentTouchDelay(component) { 11213 var options = component.context.options; 11214 var delay = options.eventLongPressDelay; 11215 if (delay == null) { 11216 delay = options.longPressDelay; 11217 } 11218 return delay; 11219 } 11220 11221 var EventResizing = /** @class */ (function (_super) { 11222 __extends(EventResizing, _super); 11223 function EventResizing(settings) { 11224 var _this = _super.call(this, settings) || this; 11225 // internal state 11226 _this.draggingSegEl = null; 11227 _this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg? 11228 _this.eventRange = null; 11229 _this.relevantEvents = null; 11230 _this.validMutation = null; 11231 _this.mutatedRelevantEvents = null; 11232 _this.handlePointerDown = function (ev) { 11233 var component = _this.component; 11234 var segEl = _this.querySegEl(ev); 11235 var seg = getElSeg(segEl); 11236 var eventRange = _this.eventRange = seg.eventRange; 11237 _this.dragging.minDistance = component.context.options.eventDragMinDistance; 11238 // if touch, need to be working with a selected event 11239 _this.dragging.setIgnoreMove(!_this.component.isValidSegDownEl(ev.origEvent.target) || 11240 (ev.isTouch && _this.component.props.eventSelection !== eventRange.instance.instanceId)); 11241 }; 11242 _this.handleDragStart = function (ev) { 11243 var context = _this.component.context; 11244 var eventRange = _this.eventRange; 11245 _this.relevantEvents = getRelevantEvents(context.getCurrentData().eventStore, _this.eventRange.instance.instanceId); 11246 var segEl = _this.querySegEl(ev); 11247 _this.draggingSegEl = segEl; 11248 _this.draggingSeg = getElSeg(segEl); 11249 context.calendarApi.unselect(); 11250 context.emitter.trigger('eventResizeStart', { 11251 el: segEl, 11252 event: new EventApi(context, eventRange.def, eventRange.instance), 11253 jsEvent: ev.origEvent, 11254 view: context.viewApi, 11255 }); 11256 }; 11257 _this.handleHitUpdate = function (hit, isFinal, ev) { 11258 var context = _this.component.context; 11259 var relevantEvents = _this.relevantEvents; 11260 var initialHit = _this.hitDragging.initialHit; 11261 var eventInstance = _this.eventRange.instance; 11262 var mutation = null; 11263 var mutatedRelevantEvents = null; 11264 var isInvalid = false;
11265 var interaction = { 11266 affectedEvents: relevantEvents, 11267 mutatedEvents: createEmptyEventStore(), 11268 isEvent: true, 11269 }; 11270 if (hit) { 11271 var disallowed = hit.componentId === initialHit.componentId 11272 && _this.isHitComboAllowed 11273 && !_this.isHitComboAllowed(initialHit, hit); 11274 if (!disallowed) { 11275 mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range); 11276 } 11277 } 11278 if (mutation) { 11279 mutatedRelevantEvents = applyMutationToEventStore(relevantEvents, context.getCurrentData().eventUiBases, mutation, context); 11280 interaction.mutatedEvents = mutatedRelevantEvents; 11281 if (!isInteractionValid(interaction, hit.dateProfile, context)) { 11282 isInvalid = true; 11283 mutation = null; 11284 mutatedRelevantEvents = null; 11285 interaction.mutatedEvents = null; 11286 } 11287 } 11288 if (mutatedRelevantEvents) { 11289 context.dispatch({ 11290 type: 'SET_EVENT_RESIZE', 11291 state: interaction, 11292 }); 11293 } 11294 else { 11295 context.dispatch({ type: 'UNSET_EVENT_RESIZE' }); 11296 } 11297 if (!isInvalid) { 11298 enableCursor(); 11299 } 11300 else { 11301 disableCursor(); 11302 } 11303 if (!isFinal) { 11304 if (mutation && isHitsEqual(initialHit, hit)) { 11305 mutation = null; 11306 } 11307 _this.validMutation = mutation; 11308 _this.mutatedRelevantEvents = mutatedRelevantEvents; 11309 } 11310 }; 11311 _this.handleDragEnd = function (ev) { 11312 var context = _this.component.context; 11313 var eventDef = _this.eventRange.def; 11314 var eventInstance = _this.eventRange.instance; 11315 var eventApi = new EventApi(context, eventDef, eventInstance); 11316 var relevantEvents = _this.relevantEvents; 11317 var mutatedRelevantEvents = _this.mutatedRelevantEvents; 11318 context.emitter.trigger('eventResizeStop', { 11319 el: _this.draggingSegEl, 11320 event: eventApi, 11321 jsEvent: ev.origEvent, 11322 view: context.viewApi, 11323 }); 11324 if (_this.validMutation) { 11325 var updatedEventApi = new EventApi(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null); 11326 context.dispatch({ 11327 type: 'MERGE_EVENTS', 11328 eventStore: mutatedRelevantEvents, 11329 }); 11330 var eventChangeArg = { 11331 oldEvent: eventApi, 11332 event: updatedEventApi, 11333 relatedEvents: buildEventApis(mutatedRelevantEvents, context, eventInstance), 11334 revert: function () { 11335 context.dispatch({ 11336 type: 'MERGE_EVENTS', 11337 eventStore: relevantEvents, // the pre-change events 11338 }); 11339 }, 11340 }; 11341 context.emitter.trigger('eventResize', __assign(__assign({}, eventChangeArg), { el: _this.draggingSegEl, startDelta: _this.validMutation.startDelta || createDuration(0), endDelta: _this.validMutation.endDelta || createDuration(0), jsEvent: ev.origEvent, view: context.viewApi })); 11342 context.emitter.trigger('eventChange', eventChangeArg); 11343 } 11344 else { 11345 context.emitter.trigger('_noEventResize'); 11346 } 11347 // reset all internal state 11348 _this.draggingSeg = null; 11349 _this.relevantEvents = null; 11350 _this.validMutation = null; 11351 // okay to keep eventInstance around. useful to set it in handlePointerDown 11352 }; 11353 var component = settings.component; 11354 var dragging = _this.dragging = new FeaturefulElementDragging(settings.el); 11355 dragging.pointer.selector = '.fc-event-resizer'; 11356 dragging.touchScrollAllowed = false;
11357 dragging.autoScroller.isEnabled = component.context.options.dragScroll; 11358 var hitDragging = _this.hitDragging = new HitDragging(_this.dragging, interactionSettingsToStore(settings)); 11359 hitDragging.emitter.on('pointerdown', _this.handlePointerDown); 11360 hitDragging.emitter.on('dragstart', _this.handleDragStart); 11361 hitDragging.emitter.on('hitupdate', _this.handleHitUpdate); 11362 hitDragging.emitter.on('dragend', _this.handleDragEnd); 11363 return _this; 11364 } 11365 EventResizing.prototype.destroy = function () { 11366 this.dragging.destroy(); 11367 }; 11368 EventResizing.prototype.querySegEl = function (ev) { 11369 return elementClosest(ev.subjectEl, '.fc-event'); 11370 }; 11371 return EventResizing; 11372 }(Interaction)); 11373 function computeMutation(hit0, hit1, isFromStart, instanceRange) { 11374 var dateEnv = hit0.context.dateEnv; 11375 var date0 = hit0.dateSpan.range.start; 11376 var date1 = hit1.dateSpan.range.start; 11377 var delta = diffDates(date0, date1, dateEnv, hit0.largeUnit); 11378 if (isFromStart) { 11379 if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) { 11380 return { startDelta: delta }; 11381 } 11382 } 11383 else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) { 11384 return { endDelta: delta }; 11385 } 11386 return null; 11387 } 11388 11389 var UnselectAuto = /** @class */ (function () { 11390 function UnselectAuto(context) { 11391 var _this = this; 11392 this.context = context; 11393 this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system 11394 this.matchesCancel = false; 11395 this.matchesEvent = false; 11396 this.onSelect = function (selectInfo) { 11397 if (selectInfo.jsEvent) { 11398 _this.isRecentPointerDateSelect = true; 11399 } 11400 }; 11401 this.onDocumentPointerDown = function (pev) { 11402 var unselectCancel = _this.context.options.unselectCancel; 11403 var downEl = pev.origEvent.target; 11404 _this.matchesCancel = !!elementClosest(downEl, unselectCancel); 11405 _this.matchesEvent = !!elementClosest(downEl, EventDragging.SELECTOR); // interaction started on an event? 11406 }; 11407 this.onDocumentPointerUp = function (pev) { 11408 var context = _this.context; 11409 var documentPointer = _this.documentPointer; 11410 var calendarState = context.getCurrentData(); 11411 // touch-scrolling should never unfocus any type of selection 11412 if (!documentPointer.wasTouchScroll) { 11413 if (calendarState.dateSelection && // an existing date selection? 11414 !_this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp? 11415 ) { 11416 var unselectAuto = context.options.unselectAuto; 11417 if (unselectAuto && (!unselectAuto || !_this.matchesCancel)) { 11418 context.calendarApi.unselect(pev); 11419 } 11420 } 11421 if (calendarState.eventSelection && // an existing event selected? 11422 !_this.matchesEvent // interaction DIDN'T start on an event 11423 ) { 11424 context.dispatch({ type: 'UNSELECT_EVENT' }); 11425 } 11426 } 11427 _this.isRecentPointerDateSelect = false; 11428 }; 11429 var documentPointer = this.documentPointer = new PointerDragging(document); 11430 documentPointer.shouldIgnoreMove = true; 11431 documentPointer.shouldWatchScroll = false; 11432 documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown); 11433 documentPointer.emitter.on('pointerup', this.onDocumentPointerUp); 11434 /* 11435 TODO: better way to know about whether there was a selection with the pointer 11436 */ 11437 context.emitter.on('select', this.onSelect); 11438 } 11439 UnselectAuto.prototype.destroy = function () { 11440 this.context.emitter.off('select', this.onSelect); 11441 this.documentPointer.destroy(); 11442 }; 11443 return UnselectAuto; 11444 }()); 11445 11446 var OPTION_REFINERS$3 = { 11447 fixedMirrorParent: identity, 11448 }; 11449 var LISTENER_REFINERS = { 11450 dateClick: identity, 11451 eventDragStart: identity, 11452 eventDragStop: identity, 11453 eventDrop: identity, 11454 eventResizeStart: identity, 11455 eventResizeStop: identity, 11456 eventResize: identity, 11457 drop: identity, 11458 eventReceive: identity, 11459 eventLeave: identity, 11460 }; 11461 11462 /* 11463 Given an already instantiated draggable object for one-or-more elements, 11464 Interprets any dragging as an attempt to drag an events that lives outside 11465 of a calendar onto a calendar. 11466 */
11467 var ExternalElementDragging = /** @class */ (function () { 11468 function ExternalElementDragging(dragging, suppliedDragMeta) { 11469 var _this = this; 11470 this.receivingContext = null; 11471 this.droppableEvent = null; // will exist for all drags, even if create:false 11472 this.suppliedDragMeta = null; 11473 this.dragMeta = null; 11474 this.handleDragStart = function (ev) { 11475 _this.dragMeta = _this.buildDragMeta(ev.subjectEl); 11476 }; 11477 this.handleHitUpdate = function (hit, isFinal, ev) { 11478 var dragging = _this.hitDragging.dragging; 11479 var receivingContext = null; 11480 var droppableEvent = null; 11481 var isInvalid = false; 11482 var interaction = { 11483 affectedEvents: createEmptyEventStore(), 11484 mutatedEvents: createEmptyEventStore(), 11485 isEvent: _this.dragMeta.create, 11486 }; 11487 if (hit) { 11488 receivingContext = hit.context; 11489 if (_this.canDropElOnCalendar(ev.subjectEl, receivingContext)) { 11490 droppableEvent = computeEventForDateSpan(hit.dateSpan, _this.dragMeta, receivingContext); 11491 interaction.mutatedEvents = eventTupleToStore(droppableEvent); 11492 isInvalid = !isInteractionValid(interaction, hit.dateProfile, receivingContext); 11493 if (isInvalid) { 11494 interaction.mutatedEvents = createEmptyEventStore(); 11495 droppableEvent = null; 11496 } 11497 } 11498 } 11499 _this.displayDrag(receivingContext, interaction); 11500 // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?) 11501 // TODO: wish we could somehow wait for dispatch to guarantee render 11502 dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror')); 11503 if (!isInvalid) { 11504 enableCursor(); 11505 } 11506 else { 11507 disableCursor(); 11508 } 11509 if (!isFinal) { 11510 dragging.setMirrorNeedsRevert(!droppableEvent); 11511 _this.receivingContext = receivingContext; 11512 _this.droppableEvent = droppableEvent; 11513 } 11514 }; 11515 this.handleDragEnd = function (pev) { 11516 var _a = _this, receivingContext = _a.receivingContext, droppableEvent = _a.droppableEvent; 11517 _this.clearDrag(); 11518 if (receivingContext && droppableEvent) { 11519 var finalHit = _this.hitDragging.finalHit; 11520 var finalView = finalHit.context.viewApi; 11521 var dragMeta = _this.dragMeta; 11522 receivingContext.emitter.trigger('drop', __assign(__assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView })); 11523 if (dragMeta.create) { 11524 var addingEvents_1 = eventTupleToStore(droppableEvent); 11525 receivingContext.dispatch({ 11526 type: 'MERGE_EVENTS', 11527 eventStore: addingEvents_1, 11528 }); 11529 if (pev.isTouch) { 11530 receivingContext.dispatch({ 11531 type: 'SELECT_EVENT', 11532 eventInstanceId: droppableEvent.instance.instanceId, 11533 }); 11534 } 11535 // signal that an external event landed 11536 receivingContext.emitter.trigger('eventReceive', { 11537 event: new EventApi(receivingContext, droppableEvent.def, droppableEvent.instance), 11538 relatedEvents: [], 11539 revert: function () { 11540 receivingContext.dispatch({
11541 type: 'REMOVE_EVENTS', 11542 eventStore: addingEvents_1, 11543 }); 11544 }, 11545 draggedEl: pev.subjectEl, 11546 view: finalView, 11547 }); 11548 } 11549 } 11550 _this.receivingContext = null; 11551 _this.droppableEvent = null; 11552 }; 11553 var hitDragging = this.hitDragging = new HitDragging(dragging, interactionSettingsStore); 11554 hitDragging.requireInitial = false; // will start outside of a component 11555 hitDragging.emitter.on('dragstart', this.handleDragStart); 11556 hitDragging.emitter.on('hitupdate', this.handleHitUpdate); 11557 hitDragging.emitter.on('dragend', this.handleDragEnd); 11558 this.suppliedDragMeta = suppliedDragMeta; 11559 } 11560 ExternalElementDragging.prototype.buildDragMeta = function (subjectEl) { 11561 if (typeof this.suppliedDragMeta === 'object') { 11562 return parseDragMeta(this.suppliedDragMeta); 11563 } 11564 if (typeof this.suppliedDragMeta === 'function') { 11565 return parseDragMeta(this.suppliedDragMeta(subjectEl)); 11566 } 11567 return getDragMetaFromEl(subjectEl); 11568 }; 11569 ExternalElementDragging.prototype.displayDrag = function (nextContext, state) { 11570 var prevContext = this.receivingContext; 11571 if (prevContext && prevContext !== nextContext) { 11572 prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11573 } 11574 if (nextContext) { 11575 nextContext.dispatch({ type: 'SET_EVENT_DRAG', state: state }); 11576 } 11577 }; 11578 ExternalElementDragging.prototype.clearDrag = function () { 11579 if (this.receivingContext) { 11580 this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' }); 11581 } 11582 }; 11583 ExternalElementDragging.prototype.canDropElOnCalendar = function (el, receivingContext) { 11584 var dropAccept = receivingContext.options.dropAccept; 11585 if (typeof dropAccept === 'function') { 11586 return dropAccept.call(receivingContext.calendarApi, el); 11587 } 11588 if (typeof dropAccept === 'string' && dropAccept) { 11589 return Boolean(elementMatches(el, dropAccept)); 11590 } 11591 return true; 11592 }; 11593 return ExternalElementDragging; 11594 }()); 11595 // Utils for computing event store from the DragMeta 11596 // ---------------------------------------------------------------------------------------------------- 11597 function computeEventForDateSpan(dateSpan, dragMeta, context) { 11598 var defProps = __assign({}, dragMeta.leftoverProps); 11599 for (var _i = 0, _a = context.pluginHooks.externalDefTransforms; _i < _a.length; _i++) { 11600 var transform = _a[_i]; 11601 __assign(defProps, transform(dateSpan, dragMeta)); 11602 } 11603 var _b = refineEventDef(defProps, context), refined = _b.refined, extra = _b.extra; 11604 var def = parseEventDef(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd 11605 context); 11606 var start = dateSpan.range.start; 11607 // only rely on time info if drop zone is all-day, 11608 // otherwise, we already know the time 11609 if (dateSpan.allDay && dragMeta.startTime) { 11610 start = context.dateEnv.add(start, dragMeta.startTime); 11611 } 11612 var end = dragMeta.duration ? 11613 context.dateEnv.add(start, dragMeta.duration) : 11614 getDefaultEventEnd(dateSpan.allDay, start, context); 11615 var instance = createEventInstance(def.defId, { start: start, end: end }); 11616 return { def: def, instance: instance }; 11617 } 11618 // Utils for extracting data from element 11619 // ---------------------------------------------------------------------------------------------------- 11620 function getDragMetaFromEl(el) { 11621 var str = getEmbeddedElData(el, 'event'); 11622 var obj = str ? 11623 JSON.parse(str) : 11624 { create: false }; // if no embedded data, assume no event creation 11625 return parseDragMeta(obj); 11626 } 11627 config.dataAttrPrefix = ''; 11628 function getEmbeddedElData(el, name) { 11629 var prefix = config.dataAttrPrefix; 11630 var prefixedName = (prefix ? prefix + '-' : '') + name; 11631 return el.getAttribute('data-' + prefixedName) || ''; 11632 } 11633 11634 /* 11635 Makes an element (that is *external* to any calendar) draggable. 11636 Can pass in data that determines how an event will be created when dropped onto a calendar. 11637 Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system. 11638 */
11639 var ExternalDraggable = /** @class */ (function () { 11640 function ExternalDraggable(el, settings) { 11641 var _this = this; 11642 if (settings === void 0) { settings = {}; } 11643 this.handlePointerDown = function (ev) { 11644 var dragging = _this.dragging; 11645 var _a = _this.settings, minDistance = _a.minDistance, longPressDelay = _a.longPressDelay; 11646 dragging.minDistance = 11647 minDistance != null ? 11648 minDistance : 11649 (ev.isTouch ? 0 : BASE_OPTION_DEFAULTS.eventDragMinDistance); 11650 dragging.delay = 11651 ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv 11652 (longPressDelay != null ? longPressDelay : BASE_OPTION_DEFAULTS.longPressDelay) : 11653 0; 11654 }; 11655 this.handleDragStart = function (ev) { 11656 if (ev.isTouch && 11657 _this.dragging.delay && 11658 ev.subjectEl.classList.contains('fc-event')) { 11659 _this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected'); 11660 } 11661 }; 11662 this.settings = settings; 11663 var dragging = this.dragging = new FeaturefulElementDragging(el); 11664 dragging.touchScrollAllowed = false; 11665 if (settings.itemSelector != null) { 11666 dragging.pointer.selector = settings.itemSelector; 11667 } 11668 if (settings.appendTo != null) { 11669 dragging.mirror.parentNode = settings.appendTo; // TODO: write tests 11670 } 11671 dragging.emitter.on('pointerdown', this.handlePointerDown); 11672 dragging.emitter.on('dragstart', this.handleDragStart); 11673 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 11674 } 11675 ExternalDraggable.prototype.destroy = function () { 11676 this.dragging.destroy(); 11677 }; 11678 return ExternalDraggable; 11679 }()); 11680 11681 /* 11682 Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements. 11683 The third-party system is responsible for drawing the visuals effects of the drag. 11684 This class simply monitors for pointer movements and fires events. 11685 It also has the ability to hide the moving element (the "mirror") during the drag. 11686 */ 11687 var InferredElementDragging = /** @class */ (function (_super) { 11688 __extends(InferredElementDragging, _super); 11689 function InferredElementDragging(containerEl) { 11690 var _this = _super.call(this, containerEl) || this; 11691 _this.shouldIgnoreMove = false; 11692 _this.mirrorSelector = ''; 11693 _this.currentMirrorEl = null; 11694 _this.handlePointerDown = function (ev) { 11695 _this.emitter.trigger('pointerdown', ev); 11696 if (!_this.shouldIgnoreMove) { 11697 // fire dragstart right away. does not support delay or min-distance 11698 _this.emitter.trigger('dragstart', ev); 11699 } 11700 }; 11701 _this.handlePointerMove = function (ev) { 11702 if (!_this.shouldIgnoreMove) { 11703 _this.emitter.trigger('dragmove', ev); 11704 } 11705 }; 11706 _this.handlePointerUp = function (ev) { 11707 _this.emitter.trigger('pointerup', ev); 11708 if (!_this.shouldIgnoreMove) { 11709 // fire dragend right away. does not support a revert animation 11710 _this.emitter.trigger('dragend', ev); 11711 } 11712 }; 11713 var pointer = _this.pointer = new PointerDragging(containerEl); 11714 pointer.emitter.on('pointerdown', _this.handlePointerDown); 11715 pointer.emitter.on('pointermove', _this.handlePointerMove); 11716 pointer.emitter.on('pointerup', _this.handlePointerUp); 11717 return _this; 11718 } 11719 InferredElementDragging.prototype.destroy = function () { 11720 this.pointer.destroy(); 11721 }; 11722 InferredElementDragging.prototype.setIgnoreMove = function (bool) { 11723 this.shouldIgnoreMove = bool; 11724 }; 11725 InferredElementDragging.prototype.setMirrorIsVisible = function (bool) { 11726 if (bool) { 11727 // restore a previously hidden element. 11728 // use the reference in case the selector class has already been removed. 11729 if (this.currentMirrorEl) { 11730 this.currentMirrorEl.style.visibility = ''; 11731 this.currentMirrorEl = null; 11732 } 11733 } 11734 else { 11735 var mirrorEl = this.mirrorSelector ? 11736 document.querySelector(this.mirrorSelector) : 11737 null; 11738 if (mirrorEl) { 11739 this.currentMirrorEl = mirrorEl; 11740 mirrorEl.style.visibility = 'hidden'; 11741 } 11742 } 11743 }; 11744 return InferredElementDragging; 11745 }(ElementDragging)); 11746 11747 /* 11748 Bridges third-party drag-n-drop systems with FullCalendar. 11749 Must be instantiated and destroyed by caller. 11750 */ 11751 var ThirdPartyDraggable = /** @class */ (function () { 11752 function ThirdPartyDraggable(containerOrSettings, settings) { 11753 var containerEl = document; 11754 if ( 11755 // wish we could just test instanceof EventTarget, but doesn't work in IE11 11756 containerOrSettings === document || 11757 containerOrSettings instanceof Element) { 11758 containerEl = containerOrSettings; 11759 settings = settings || {}; 11760 } 11761 else { 11762 settings = (containerOrSettings || {}); 11763 } 11764 var dragging = this.dragging = new InferredElementDragging(containerEl); 11765 if (typeof settings.itemSelector === 'string') { 11766 dragging.pointer.selector = settings.itemSelector; 11767 } 11768 else if (containerEl === document) { 11769 dragging.pointer.selector = '[data-event]'; 11770 } 11771 if (typeof settings.mirrorSelector === 'string') { 11772 dragging.mirrorSelector = settings.mirrorSelector; 11773 } 11774 new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new 11775 } 11776 ThirdPartyDraggable.prototype.destroy = function () { 11777 this.dragging.destroy(); 11778 }; 11779 return ThirdPartyDraggable; 11780 }()); 11781 11782 var interactionPlugin = createPlugin({ 11783 componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing], 11784 calendarInteractions: [UnselectAuto], 11785 elementDraggingImpl: FeaturefulElementDragging, 11786 optionRefiners: OPTION_REFINERS$3, 11787 listenerRefiners: LISTENER_REFINERS, 11788 }); 11789 11790 /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells. 11791 ----------------------------------------------------------------------------------------------------------------------*/ 11792 // It is a manager for a Table subcomponent, which does most of the heavy lifting. 11793 // It is responsible for managing width/height. 11794 var TableView = /** @class */ (function (_super) { 11795 __extends(TableView, _super); 11796 function TableView() { 11797 var _this = _super !== null && _super.apply(this, arguments) || this; 11798 _this.headerElRef = createRef(); 11799 return _this; 11800 } 11801 TableView.prototype.renderSimpleLayout = function (headerRowContent, bodyContent) { 11802 var _a = this, props = _a.props, context = _a.context; 11803 var sections = []; 11804 var stickyHeaderDates = getStickyHeaderDates(context.options); 11805 if (headerRowContent) { 11806 sections.push({ 11807 type: 'header', 11808 key: 'header', 11809 isSticky: stickyHeaderDates, 11810 chunk: { 11811 elRef: this.headerElRef, 11812 tableClassName: 'fc-col-header', 11813 rowContent: headerRowContent, 11814 }, 11815 }); 11816 } 11817 sections.push({ 11818 type: 'body', 11819 key: 'body', 11820 liquid: true, 11821 chunk: { content: bodyContent }, 11822 }); 11823 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygri
11823d'].concat(classNames).join(' ') }, 11824 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections }))); })); 11825 }; 11826 TableView.prototype.renderHScrollLayout = function (headerRowContent, bodyContent, colCnt, dayMinWidth) { 11827 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 11828 if (!ScrollGrid) { 11829 throw new Error('No ScrollGrid implementation'); 11830 } 11831 var _a = this, props = _a.props, context = _a.context; 11832 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 11833 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 11834 var sections = []; 11835 if (headerRowContent) { 11836 sections.push({ 11837 type: 'header', 11838 key: 'header', 11839 isSticky: stickyHeaderDates, 11840 chunks: [{ 11841 key: 'main', 11842 elRef: this.headerElRef, 11843 tableClassName: 'fc-col-header', 11844 rowContent: headerRowContent, 11845 }], 11846 }); 11847 } 11848 sections.push({ 11849 type: 'body', 11850 key: 'body', 11851 liquid: true, 11852 chunks: [{ 11853 key: 'main', 11854 content: bodyContent, 11855 }], 11856 }); 11857 if (stickyFooterScrollbar) { 11858 sections.push({ 11859 type: 'footer', 11860 key: 'footer', 11861 isSticky: true, 11862 chunks: [{ 11863 key: 'main', 11864 content: renderScrollShim, 11865 }], 11866 }); 11867 } 11868 return (createElement(ViewRoot, { viewSpec: context.viewSpec }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: ['fc-daygrid'].concat(classNames).join(' ') }, 11869 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections }))); })); 11870 }; 11871 return TableView; 11872 }(DateComponent)); 11873 11874 function splitSegsByRow(segs, rowCnt) { 11875 var byRow = []; 11876 for (var i = 0; i < rowCnt; i += 1) { 11877 byRow[i] = []; 11878 } 11879 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 11880 var seg = segs_1[_i]; 11881 byRow[seg.row].push(seg); 11882 } 11883 return byRow; 11884 } 11885 function splitSegsByFirstCol(segs, colCnt) { 11886 var byCol = []; 11887 for (var i = 0; i < colCnt; i += 1) { 11888 byCol[i] = []; 11889 } 11890 for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) { 11891 var seg = segs_2[_i]; 11892 byCol[seg.firstCol].push(seg); 11893 } 11894 return byCol; 11895 } 11896 function splitInteractionByRow(ui, rowCnt) { 11897 var byRow = []; 11898 if (!ui) { 11899 for (var i = 0; i < rowCnt; i += 1) { 11900 byRow[i] = null; 11901 } 11902 } 11903 else { 11904 for (var i = 0; i < rowCnt; i += 1) { 11905 byRow[i] = { 11906 affectedInstances: ui.affectedInstances, 11907 isEvent: ui.isEvent, 11908 segs: [], 11909 }; 11910 } 11911 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 11912 var seg = _a[_i]; 11913 byRow[seg.row].segs.push(seg); 11914 } 11915 } 11916 return byRow; 11917 } 11918 11919 var TableCellTop = /** @class */ (function (_super) { 11920 __extends(TableCellTop, _super); 11921 function TableCellTop() { 11922 return _super !== null && _super.apply(this, arguments) || this; 11923 } 11924 TableCellTop.prototype.render = function () { 11925 var props = this.props; 11926 var navLinkAttrs = this.context.options.navLinks 11927 ? { 'data-navlink': buildNavLinkData(props.date), tabIndex: 0 } 11928 : {}; 11929 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, defaultContent: renderTopInner }, function (innerElRef, innerContent) { return ((innerContent || props.forceDayTop) && (createElement("div", { className: "fc-daygri
11929d-day-top", ref: innerElRef }, 11930 createElement("a", __assign({ className: "fc-daygrid-day-number" }, navLinkAttrs), innerContent || createElement(Fragment, null, "\u00A0"))))); })); 11931 }; 11932 return TableCellTop; 11933 }(BaseComponent)); 11934 function renderTopInner(props) { 11935 return props.dayNumberText; 11936 } 11937 11938 var DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 11939 hour: 'numeric', 11940 minute: '2-digit', 11941 omitZeroMinute: true, 11942 meridiem: 'narrow', 11943 }); 11944 function hasListItemDisplay(seg) { 11945 var display = seg.eventRange.ui.display; 11946 return display === 'list-item' || (display === 'auto' && 11947 !seg.eventRange.def.allDay && 11948 seg.firstCol === seg.lastCol && // can't be multi-day 11949 seg.isStart && // " 11950 seg.isEnd // " 11951 ); 11952 } 11953 11954 var TableBlockEvent = /** @class */ (function (_super) { 11955 __extends(TableBlockEvent, _super); 11956 function TableBlockEvent() { 11957 return _super !== null && _super.apply(this, arguments) || this; 11958 } 11959 TableBlockEvent.prototype.render = function () { 11960 var props = this.props; 11961 return (createElement(StandardEvent, __assign({}
11961, props, { extraClassNames: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay }))); 11962 }; 11963 return TableBlockEvent; 11964 }(BaseComponent)); 11965 11966 var TableListItemEvent = /** @class */ (function (_super) { 11967 __extends(TableListItemEvent, _super); 11968 function TableListItemEvent() { 11969 return _super !== null && _super.apply(this, arguments) || this; 11970 } 11971 TableListItemEvent.prototype.render = function () { 11972 var _a = this, props = _a.props, context = _a.context; 11973 var timeFormat = context.options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 11974 var timeText = buildSegTimeText(props.seg, timeFormat, context, true, props.defaultDisplayEventEnd); 11975 return (createElement(EventRoot, { seg: props.seg, timeText: timeText, defaultContent: renderInnerContent$2, isDragging: props.isDragging, isResizing: false, isDateSelecting: false, isSelected: props.isSelected, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday }, function (rootElRef, classNames, innerElRef, innerContent) { return ( // we don't use styles! 11976 createElement("a", __assign({ className: ['fc-daygrid-event', 'fc-daygri
11976d-dot-event'].concat(classNames).join(' '), ref: rootElRef }, getSegAnchorAttrs(props.seg)), innerContent)); })); 11977 }; 11978 return TableListItemEvent; 11979 }(BaseComponent)); 11980 function renderInnerContent$2(innerProps) { 11981 return (createElement(Fragment, null, 11982 createElement("div", { className: "fc-daygrid-event-dot", style: { borderColor: innerProps.borderColor || innerProps.backgroundColor } }), 11983 innerProps.timeText && (createElement("div", { className: "fc-event-time" }, innerProps.timeText)), 11984 createElement("div", { className: "fc-event-title" }, innerProps.event.title || createElement(Fragment, null, "\u00A0")))); 11985 } 11986 function getSegAnchorAttrs(seg) { 11987 var url = seg.eventRange.def.url; 11988 return url ? { href: url } : {}; 11989 } 11990 11991 var TableCellMoreLink = /** @class */ (function (_super) { 11992 __extends(TableCellMoreLink, _super); 11993 function TableCellMoreLink() { 11994 var _this = _super !== null && _super.apply(this, arguments) || this; 11995 _this.compileSegs = memoize(compileSegs); 11996 return _this; 11997 } 11998 TableCellMoreLink.prototype.render = function () { 11999 var props = this.props; 12000 var _a = this.compileSegs(props.singlePlacements), allSegs = _a.allSegs, invisibleSegs = _a.invisibleSegs; 12001 return (createElement(MoreLinkRoot, { dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: function () { 12002 var isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || 12003 (props.eventResize ? props.eventResize.affectedInstances : null) || 12004 {}; 12005 return (createElement(Fragment, null, allSegs.map(function (seg) { 12006 var instanceId = seg.eventRange.instance.instanceId; 12007 return (createElement("div", { className: "fc-daygrid-event-harness", key: instanceId, style: { 12008 visibility: isForcedInvisible[instanceId] ? 'hidden' : '', 12009 } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))))); 12010 }))); 12011 } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick) { return (createElement("a", { ref: rootElRef, className: ['fc-daygrid-more-link'].concat(classNames).join(' '), onClick: handleClick }, innerContent)); })); 12012 }; 12013 return TableCellMoreLink; 12014 }(BaseComponent)); 12015 function compileSegs(singlePlacements) { 12016 var allSegs = []; 12017 var invisibleSegs = []; 12018 for (var _i = 0, singlePlacements_1 = singlePlacements; _i < singlePlacements_1.length; _i++) { 12019 var placement = singlePlacements_1[_i]; 12020 allSegs.push(placement.seg); 12021 if (!placement.isVisible) { 12022 invisibleSegs.push(placement.seg); 12023 } 12024 } 12025 return { allSegs: allSegs, invisibleSegs: invisibleSegs }; 12026 } 12027 12028 var DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: 'narrow' }); 12029 var TableCell = /** @class */ (function (_super) { 12030 __extends(TableCell, _super); 12031 function TableCell() { 12032 var _this = _super !== null && _super.apply(this, arguments) || this; 12033 _this.rootElRef = createRef(); 12034 _this.handleRootEl = function (el) { 12035 setRef(_this.rootElRef, el); 12036 setRef(_this.props.elRef, el); 12037 }; 12038 return _this; 12039 } 12040 TableCell.prototype.render = function () { 12041 var _a = this, props = _a.props, context = _a.context, rootElRef = _a.rootElRef; 12042 var options = context.options; 12043 var date = props.date, dateProfile = props.dateProfile; 12044 var navLinkAttrs = options.navLinks 12045 ? { 'data-navlink': buildNavLinkData(date, 'week'), tabIndex: 0 } 12046 : {}; 12047 return (createElement(DayCellRoot, { date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraHookProps: props.extraHookProps, elRef: this.handleRootEl }, function (dayElRef, dayClassNames, rootDataAttrs, isDisabled) { return (createElement("td", __assign({ ref: dayElRef, className: ['fc-daygri
12047d-day'].concat(dayClassNames, props.extraClassNames || []).join(' ') }, rootDataAttrs, props.extraDataAttrs), 12048 createElement("div", { className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", ref: props.innerElRef /* different from hook system! RENAME */ }, 12049 props.showWeekNumber && (createElement(WeekNumberRoot, { date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }, function (weekElRef, weekClassNames, innerElRef, innerContent) { return (createElement("a", __assign({ ref: weekElRef, className: ['fc-daygrid-week-number'].concat(weekClassNames).join(' ') }, navLinkAttrs), innerContent)); })), 12050 !isDisabled && (createElement(TableCellTop, { date: date, dateProfile: dateProfile, showDayNumber: props.showDayNumber, forceDayTop: props.forceDayTop, todayRange: props.todayRange, extraHookProps: props.extraHookProps })), 12051 createElement("div", { className: "fc-daygrid-day-events", ref: props.fgContentElRef }, 12052 props.fgContent, 12053 createElement("div", { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } }, 12054 createElement(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))), 12055 createElement("div", { className: "fc-daygrid-day-bg" }, props.bgContent)))); })); 12056 }; 12057 return TableCell; 12058 }(DateComponent)); 12059 12060 function computeFgSegPlacement(segs, // assumed already sorted 12061 dayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) { 12062 var hierarchy = new DayGridSegHierarchy(); 12063 hierarchy.allowReslicing = true; 12064 hierarchy.strictOrder = strictOrder; 12065 if (dayMaxEvents === true || dayMaxEventRows === true) { 12066 hierarchy.maxCoord = maxContentHeight; 12067 hierarchy.hiddenConsumes = true; 12068 } 12069 else if (typeof dayMaxEvents === 'number') { 12070 hierarchy.maxStackCnt = dayMaxEvents; 12071 } 12072 else if (typeof dayMaxEventRows === 'number') { 12073 hierarchy.maxStackCnt = dayMaxEventRows; 12074 hierarchy.hiddenConsumes = true; 12075 } 12076 // create segInputs only for segs with known heights 12077 var segInputs = []; 12078 var unknownHeightSegs = []; 12079 for (var i = 0; i < segs.length; i += 1) { 12080 var seg = segs[i]; 12081 var instanceId = seg.eventRange.instance.instanceId; 12082 var eventHeight = eventInstanceHeights[instanceId]; 12083 if (eventHeight != null) { 12084 segInputs.push({ 12085 index: i, 12086 spanStart: seg.firstCol, 12087 spanEnd: seg.lastCol + 1, 12088 thickness: eventHeight, 12089 }); 12090 } 12091 else { 12092 unknownHeightSegs.push(seg); 12093 } 12094 } 12095 var hiddenEntries = hierarchy.addSegs(segInputs); 12096 var segRects = hierarchy.toRects(); 12097 var _a = placeRects(segRects, segs, cells), singleColPlacements = _a.singleColPlacements, multiColPlacements = _a.multiColPlacements, leftoverMargins = _a.leftoverMargins; 12098 var moreCnts = []; 12099 var moreMarginTops = []; 12100 // add segs with unknown heights 12101 for (var _i = 0, unknownHeightSegs_1 = unknownHeightSegs; _i < unknownHeightSegs_1.length; _i++) { 12102 var seg = unknownHeightSegs_1[_i]; 12103 multiColPlacements[seg.firstCol].push({ 12104 seg: seg, 12105 isVisible: false, 12106 isAbsolute: true, 12107 absoluteTop: 0, 12108 marginTop: 0, 12109 }); 12110 for (var col = seg.firstCol; col <= seg.lastCol; col += 1) { 12111 singleColPlacements[col].push({ 12112 seg: resliceSeg(seg, col, col + 1, cells), 12113 isVisible: false, 12114 isAbsolute: false, 12115 absoluteTop: 0, 12116 marginTop: 0, 12117 }); 12118 } 12119 } 12120 // add the hidden entries 12121 for (var col = 0; col < cells.length; col += 1) { 12122 moreCnts.push(0); 12123 } 12124 for (var _b = 0, hiddenEntries_1 = hiddenEntries; _b < hiddenEntries_1.length; _b++) { 12125 var hiddenEntry = hiddenEntries_1[_b]; 12126 var seg = segs[hiddenEntry.segInput.index]; 12127 multiColPlacements[hiddenEntry.spanStart].push({ 12128 seg: seg, 12129 isVisible: false, 12130 isAbsolute: true, 12131 absoluteTop: 0, 12132 marginTop: 0, 12133 }); 12134 for (var col = hiddenEntry.spanStart; col < hiddenEntry.spanEnd; col += 1) { 12135 moreCnts[col] += 1; 12136 singleColPlacements[col].push({ 12137 seg: resliceSeg(seg, col, col + 1, cells), 12138 isVisible: false, 12139 isAbsolute: false, 12140 absoluteTop: 0, 12141 marginTop: 0, 12142 }); 12143 } 12144 } 12145 // deal with leftover margins 12146 for (var col = 0; col < cells.length; col += 1) { 12147 moreMarginTops.push(leftoverMargins[col]); 12148 } 12149 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, moreCnts: moreCnts, moreMarginTops: moreMarginTops }; 12150 } 12151 // rects ordered by top coord, then left 12152 function placeRects(allRects, segs, cells) { 12153 var rectsByEachCol = groupRectsByEachCol(allRects, cells.length); 12154 var singleColPlacements = []; 12155 var multiColPlacements = []; 12156 var leftoverMargins = []; 12157 for (var col = 0; col < cells.length; col += 1) { 12158 var rects = rectsByEachCol[col]; 12159 // compute all static segs in singlePlacements 12160 var singlePlacements = []; 12161 var currentHeight = 0; 12162 var currentMarginTop = 0; 12163 for (var _i = 0, rects_1 = rects; _i < rects_1.length; _i++) { 12164 var rect = rects_1[_i]; 12165 var seg = segs[rect.segInput.index]; 12166 singlePlacements.push({ 12167 seg: resliceSeg(seg, col, col + 1, cells), 12168 isVisible: true, 12169 isAbsolute: false, 12170 absoluteTop: 0, 12171 marginTop: rect.levelCoord - currentHeight, 12172 }); 12173 currentHeight = rect.levelCoord + rect.thickness; 12174 } 12175 // compute mixed static/absolute segs in multiPlacements 12176 var multiPlacements = []; 12177 currentHeight = 0; 12178 currentMarginTop = 0; 12179 for (var _a = 0, rects_2 = rects; _a < rects_2.length; _a++) { 12180 var rect = rects_2[_a]; 12181 var seg = segs[rect.segInput.index]; 12182 var isAbsolute = rect.spanEnd - rect.spanStart > 1; // multi-column? 12183 var isFirstCol = rect.spanStart === col; 12184 currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg 12185 currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg 12186 if (isAbsolute) { 12187 currentMarginTop += rect.thickness; 12188 if (isFirstCol) { 12189 multiPlacements.push({ 12190 seg: resliceSeg(seg, rect.spanStart, rect.spanEnd, cells), 12191 isVisible: true, 12192 isAbsolute: true, 12193 absoluteTop: rect.levelCoord, 12194 marginTop: 0, 12195 }); 12196 } 12197 } 12198 else if (isFirstCol) { 12199 multiPlacements.push({ 12200 seg: resliceSeg(seg, rect.spanStart, rect.spanEnd, cells), 12201 isVisible: true, 12202 isAbsolute: false, 12203 absoluteTop: 0, 12204 marginTop: currentMarginTop, // claim the margin 12205 }); 12206 currentMarginTop = 0; 12207 } 12208 } 12209 singleColPlacements.push(singlePlacements); 12210 multiColPlacements.push(multiPlacements); 12211 leftoverMargins.push(currentMarginTop); 12212 } 12213 return { singleColPlacements: singleColPlacements, multiColPlacements: multiColPlacements, leftoverMargins: leftoverMargins }; 12214 } 12215 function groupRectsByEachCol(rects, colCnt) { 12216 var rectsByEachCol = []; 12217 for (var col = 0; col < colCnt; col += 1) { 12218 rectsByEachCol.push([]); 12219 } 12220 for (var _i = 0, rects_3 = rects; _i < rects_3.length; _i++) { 12221 var rect = rects_3[_i]; 12222 for (var col = rect.spanStart; col < rect.spanEnd; col += 1) { 12223 rectsByEachCol[col].push(rect); 12224 } 12225 } 12226 return rectsByEachCol; 12227 } 12228 function resliceSeg(seg, spanStart, spanEnd, cells) { 12229 if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) { 12230 return seg; 12231 } 12232 var eventRange = seg.eventRange; 12233 var origRange = eventRange.range; 12234 var slicedRange = intersectRanges(origRange, { 12235 start: cells[spanStart].date, 12236 end: addDays(cells[spanEnd - 1].date, 1), 12237 }); 12238 return __assign(__assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: { 12239 def: eventRange.def, 12240 ui: __assign(__assign({}, eventRange.ui), { durationEditable: false }), 12241 instance: eventRange.instance, 12242 range: slicedRange, 12243 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }); 12244 } 12245 var DayGridSegHierarchy = /** @class */ (function (_super) { 12246 __extends(DayGridSegHierarchy, _super); 12247 function DayGridSegHierarchy() { 12248 var _this = _super !== null && _super.apply(this, arguments) || this; 12249 // config 12250 _this.hiddenConsumes = false;
12251 // allows us to keep hidden entries in the hierarchy so they take up space 12252 _this.forceHidden = {}; 12253 return _this; 12254 } 12255 DayGridSegHierarchy.prototype.addSegs = function (segInputs) { 12256 var _this = this; 12257 var hiddenSegs = _super.prototype.addSegs.call(this, segInputs); 12258 var entriesByLevel = this.entriesByLevel; 12259 var excludeHidden = function (entry) { return !_this.forceHidden[buildEntryKey(entry)]; }; 12260 // remove the forced-hidden segs 12261 for (var level = 0; level < entriesByLevel.length; level += 1) { 12262 entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden); 12263 } 12264 return hiddenSegs; 12265 }; 12266 DayGridSegHierarchy.prototype.handleInvalidInsertion = function (insertion, entry, hiddenEntries) { 12267 var _a = this, entriesByLevel = _a.entriesByLevel, forceHidden = _a.forceHidden; 12268 var level = insertion.nextLevel - 1; 12269 if (this.hiddenConsumes && level >= 0) { 12270 for (var lateral = insertion.lateralStart; lateral < insertion.lateralEnd; lateral += 1) { 12271 var leadingEntry = entriesByLevel[level][lateral]; 12272 if (this.allowReslicing) { 12273 var placeholderEntry = __assign(__assign({}, leadingEntry), { spanStart: Math.max(leadingEntry.spanStart, entry.spanStart), spanEnd: Math.min(leadingEntry.spanEnd, entry.spanEnd) }); 12274 var placeholderEntryId = buildEntryKey(placeholderEntry); 12275 if (!forceHidden[placeholderEntryId]) { 12276 forceHidden[placeholderEntryId] = true; 12277 entriesByLevel[level][lateral] = placeholderEntry; 12278 this.splitEntry(leadingEntry, entry, hiddenEntries); // split up the leadingEntry 12279 } 12280 } 12281 else { 12282 var placeholderEntryId = buildEntryKey(leadingEntry); 12283 if (!forceHidden[placeholderEntryId]) { 12284 forceHidden[placeholderEntryId] = true; 12285 hiddenEntries.push(leadingEntry); 12286 } 12287 } 12288 } 12289 } 12290 return _super.prototype.handleInvalidInsertion.call(this, insertion, entry, hiddenEntries); 12291 }; 12292 return DayGridSegHierarchy; 12293 }(SegHierarchy)); 12294 12295 var TableRow = /** @class */ (function (_super) { 12296 __extends(TableRow, _super); 12297 function TableRow() { 12298 var _this = _super !== null && _super.apply(this, arguments) || this; 12299 _this.cellElRefs = new RefMap(); // the <td> 12300 _this.frameElRefs = new RefMap(); // the fc-daygrid-day-frame 12301 _this.fgElRefs = new RefMap(); // the fc-daygrid-day-events 12302 _this.segHarnessRefs = new RefMap(); // indexed by "instanceId:firstCol" 12303 _this.rootElRef = createRef(); 12304 _this.state = { 12305 framePositions: null, 12306 maxContentHeight: null, 12307 eventInstanceHeights: {}, 12308 }; 12309 return _this; 12310 } 12311 TableRow.prototype.render = function () { 12312 var _this = this; 12313 var _a = this, props = _a.props, state = _a.state, context = _a.context; 12314 var options = context.options; 12315 var colCnt = props.cells.length; 12316 var businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt); 12317 var bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 12318 var highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt); 12319 var mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 12320 var _b = computeFgSegPlacement(sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.eventInstanceHeights, state.maxContentHeight, props.cells), singleColPlacements = _b.singleColPlacements, multiColPlacements = _b.multiColPlacements, moreCnts = _b.moreCnts, moreMarginTops = _b.moreMarginTops; 12321 var isForcedInvisible = // TODO: messy way to compute this 12322 (props.eventDrag && props.eventDrag.affectedInstances) || 12323 (props.eventResize && props.eventResize.affectedInstances) || 12324 {}; 12325 return (createElement("tr", { ref: this.rootElRef }, 12326 props.renderIntro && props.renderIntro(), 12327 props.cells.map(function (cell, col) { 12328 var normalFgNodes = _this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible); 12329 var mirrorFgNodes = _this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false); 12330 return (createElement(TableCell, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), innerElRef: _this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: _this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys 12331 createElement(Fragment, null, 12332 createElement(Fragment, null, normalFgNodes), 12333 createElement(Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys 12334 createElement(Fragment, null, 12335 _this.renderFillSegs(highlightSegsByCol[col], 'highlight'), 12336 _this.renderFillSegs(businessHoursByCol[col], 'non-business'), 12337 _this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) })); 12338 }))); 12339 }; 12340 TableRow.prototype.componentDidMount = function () { 12341 this.updateSizing(true); 12342 }; 12343 TableRow.prototype.componentDidUpdate = function (prevProps, prevState) { 12344 var currentProps = this.props; 12345 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 12346 }; 12347 TableRow.prototype.getHighlightSegs = function () { 12348 var props = this.props; 12349 if (props.eventDrag && props.eventDrag.segs.length) { // messy check 12350 return props.eventDrag.segs; 12351 } 12352 if (props.eventResize && props.eventResize.segs.length) { // messy check 12353 return props.eventResize.segs; 12354 } 12355 return props.dateSelectionSegs; 12356 }; 12357 TableRow.prototype.getMirrorSegs = function () { 12358 var props = this.props; 12359 if (props.eventResize && props.eventResize.segs.length) { // messy check 12360 return props.eventResize.segs; 12361 } 12362 return []; 12363 }; 12364 TableRow.prototype.renderFgSegs = function (col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) { 12365 var context = this.context; 12366 var eventSelection = this.props.eventSelection; 12367 var framePositions = this.state.framePositions; 12368 var defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1 12369 var isMirror = isDragging || isResizing || isDateSelecting; 12370 var nodes = []; 12371 if (framePositions) { 12372 for (var _i = 0, segPlacements_1 = segPlacements; _i < segPlacements_1.length; _i++) { 12373 var placement = segPlacements_1[_i]; 12374 var seg = placement.seg; 12375 var instanceId = seg.eventRange.instance.instanceId; 12376 var key = instanceId + ':' + col; 12377 var isVisible = placement.isVisible && !isForcedInvisible[instanceId];
12378 var isAbsolute = placement.isAbsolute; 12379 var left = ''; 12380 var right = ''; 12381 if (isAbsolute) { 12382 if (context.isRtl) { 12383 right = 0; 12384 left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]; 12385 } 12386 else { 12387 left = 0; 12388 right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]; 12389 } 12390 } 12391 /* 12392 known bug: events that are force to be list-item but span multiple days still take up space in later columns 12393 todo: in print view, for multi-day events, don't display title within non-start/end segs 12394 */ 12395 nodes.push(createElement("div", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: key, ref: isMirror ? null : this.segHarnessRefs.createRef(key), style: { 12396 visibility: isVisible ? '' : 'hidden', 12397 marginTop: isAbsolute ? '' : placement.marginTop, 12398 top: isAbsolute ? placement.absoluteTop : '', 12399 left: left, 12400 right: right, 12401 } }, hasListItemDisplay(seg) ? (createElement(TableListItemEvent, __assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))) : (createElement(TableBlockEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, getSegMeta(seg, todayRange)))))); 12402 } 12403 } 12404 return nodes; 12405 }; 12406 TableRow.prototype.renderFillSegs = function (segs, fillType) { 12407 var isRtl = this.context.isRtl; 12408 var todayRange = this.props.todayRange; 12409 var framePositions = this.state.framePositions; 12410 var nodes = []; 12411 if (framePositions) { 12412 for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) { 12413 var seg = segs_1[_i]; 12414 var leftRightCss = isRtl ? { 12415 right: 0, 12416 left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol], 12417 } : { 12418 left: 0, 12419 right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol], 12420 }; 12421 nodes.push(createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === 'bg-event' ? 12422 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, todayRange))) : 12423 renderFill(fillType))); 12424 } 12425 } 12426 return createElement.apply(void 0, __spreadArray([Fragment, {}], nodes)); 12427 }; 12428 TableRow.prototype.updateSizing = function (isExternalSizingChange) { 12429 var _a = this, props = _a.props, frameElRefs = _a.frameElRefs; 12430 if (!props.forPrint && 12431 props.clientWidth !== null // positioning ready? 12432 ) { 12433 if (isExternalSizingChange) { 12434 var frameEls = props.cells.map(function (cell) { return frameElRefs.currentMap[cell.key]; }); 12435 if (frameEls.length) { 12436 var originEl = this.rootElRef.current; 12437 this.setState({ 12438 framePositions: new PositionCache(originEl, frameEls, true, // isHorizontal 12439 false), 12440 }); 12441 } 12442 } 12443 var limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true; 12444 this.setState({ 12445 eventInstanceHeights: this.queryEventInstanceHeights(), 12446 maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null, 12447 }); 12448 } 12449 }; 12450 TableRow.prototype.queryEventInstanceHeights = function () { 12451 var segElMap = this.segHarnessRefs.currentMap; 12452 var eventInstanceHeights = {}; 12453 // get the max height amongst instance segs 12454 for (var key in segElMap) { 12455 var height = Math.round(segElMap[key].getBoundingClientRect().height); 12456 var instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key 12457 eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height); 12458 } 12459 return eventInstanceHeights; 12460 }; 12461 TableRow.prototype.computeMaxContentHeight = function () { 12462 var firstKey = this.props.cells[0].key; 12463 var cellEl = this.cellElRefs.currentMap[firstKey]; 12464 var fcContainerEl = this.fgElRefs.currentMap[firstKey]; 12465 return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top; 12466 }; 12467 TableRow.prototype.getCellEls = function () { 12468 var elMap = this.cellElRefs.currentMap; 12469 return this.props.cells.map(function (cell) { return elMap[cell.key]; }); 12470 }; 12471 return TableRow; 12472 }(DateComponent)); 12473 TableRow.addStateEquality({ 12474 eventInstanceHeights: isPropsEqual, 12475 }); 12476 function buildMirrorPlacements(mirrorSegs, colPlacements) { 12477 if (!mirrorSegs.length) { 12478 return []; 12479 } 12480 var topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render? 12481 return mirrorSegs.map(function (seg) { return ({ 12482 seg: seg, 12483 isVisible: true, 12484 isAbsolute: true, 12485 absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId], 12486 marginTop: 0, 12487 }); }); 12488 } 12489 function buildAbsoluteTopHash(colPlacements) { 12490 var topsByInstanceId = {}; 12491 for (var _i = 0, colPlacements_1 = colPlacements; _i < colPlacements_1.length; _i++) { 12492 var placements = colPlacements_1[_i]; 12493 for (var _a = 0, placements_1 = placements; _a < placements_1.length; _a++) { 12494 var placement = placements_1[_a]; 12495 topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop; 12496 } 12497 } 12498 return colPlacements; 12499 } 12500 12501 var Table = /** @class */ (function (_super) { 12502 __extends(Table, _super); 12503 function Table() { 12504 var _this = _super !== null && _super.apply(this, arguments) || this; 12505 _this.splitBusinessHourSegs = memoize(splitSegsByRow); 12506 _this.splitBgEventSegs = memoize(splitSegsByRow); 12507 _this.splitFgEventSegs = memoize(splitSegsByRow); 12508 _this.splitDateSelectionSegs = memoize(splitSegsByRow); 12509 _this.splitEventDrag = memoize(splitInteractionByRow); 12510 _this.splitEventResize = memoize(splitInteractionByRow); 12511 _this.rowRefs = new RefMap(); 12512 _this.handleRootEl = function (rootEl) { 12513 _this.rootEl = rootEl; 12514 if (rootEl) { 12515 _this.context.registerInteractiveComponent(_this, { 12516 el: rootEl, 12517 isHitComboAllowed: _this.props.isHitComboAllowed, 12518 }); 12519 } 12520 else { 12521 _this.context.unregisterInteractiveComponent(_this); 12522 } 12523 }; 12524 return _this; 12525 } 12526 Table.prototype.render = function () { 12527 var _this = this; 12528 var props = this.props; 12529 var dateProfile = props.dateProfile, dayMaxEventRows = props.dayMaxEventRows, dayMaxEvents = props.dayMaxEvents, expandRows = props.expandRows; 12530 var rowCnt = props.cells.length; 12531 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt); 12532 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 12533 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 12534 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt); 12535 var eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 12536 var eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt); 12537 var limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 12538 // if rows can't expand to fill fixed height, can't do balanced-height event limit 12539 // TODO: best place to normalize these options? 12540 if (limitViaBalanced && !expandRows) { 12541 limitViaBalanced = false;
12542 dayMaxEventRows = null; 12543 dayMaxEvents = null; 12544 } 12545 var classNames = [ 12546 'fc-daygrid-body', 12547 limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced', 12548 expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others? 12549 ]; 12550 return (createElement("div", { className: classNames.join(' '), ref: this.handleRootEl, style: { 12551 // these props are important to give this wrapper correct dimensions for interactions 12552 // TODO: if we set it here, can we avoid giving to inner tables? 12553 width: props.clientWidth, 12554 minWidth: props.tableMinWidth, 12555 } }, 12556 createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { return (createElement(Fragment, null, 12557 createElement("table", { className: "fc-scrollgrid-sync-table", style: { 12558 width: props.clientWidth, 12559 minWidth: props.tableMinWidth, 12560 height: expandRows ? props.clientHeight : '', 12561 } }, 12562 props.colGroupNode, 12563 createElement("tbody", null, props.cells.map(function (cells, row) { return (createElement(TableRow, { ref: _this.rowRefs.createRef(row), key: cells.length 12564 ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ 12565 : row // in case there are no cells (like when resource view is loading) 12566 , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })); }))))); }))); 12567 }; 12568 // Hit System 12569 // ---------------------------------------------------------------------------------------------------- 12570 Table.prototype.prepareHits = function () { 12571 this.rowPositions = new PositionCache(this.rootEl, this.rowRefs.collect().map(function (rowObj) { return rowObj.getCellEls()[0]; }), // first cell el in each row. TODO: not optimal 12572 false, true); 12573 this.colPositions = new PositionCache(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row 12574 true, // horizontal 12575 false); 12576 }; 12577 Table.prototype.queryHit = function (positionLeft, positionTop) { 12578 var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions; 12579 var col = colPositions.leftToIndex(positionLeft); 12580 var row = rowPositions.topToIndex(positionTop); 12581 if (row != null && col != null) { 12582 var cell = this.props.cells[row][col]; 12583 return { 12584 dateProfile: this.props.dateProfile, 12585 dateSpan: __assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan), 12586 dayEl: this.getCellEl(row, col), 12587 rect: { 12588 left: colPositions.lefts[col], 12589 right: colPositions.rights[col], 12590 top: rowPositions.tops[row], 12591 bottom: rowPositions.bottoms[row], 12592 }, 12593 layer: 0, 12594 }; 12595 } 12596 return null; 12597 }; 12598 Table.prototype.getCellEl = function (row, col) { 12599 return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal 12600 }; 12601 Table.prototype.getCellRange = function (row, col) { 12602 var start = this.props.cells[row][col].date; 12603 var end = addDays(start, 1); 12604 return { start: start, end: end }; 12605 }; 12606 return Table; 12607 }(DateComponent)); 12608 function isSegAllDay(seg) { 12609 return seg.eventRange.def.allDay; 12610 } 12611 12612 var DayTableSlicer = /** @class */ (function (_super) { 12613 __extends(DayTableSlicer, _super); 12614 function DayTableSlicer() { 12615 var _this = _super !== null && _super.apply(this, arguments) || this; 12616 _this.forceDayIfListItem = true; 12617 return _this; 12618 } 12619 DayTableSlicer.prototype.sliceRange = function (dateRange, dayTableModel) { 12620 return dayTableModel.sliceRange(dateRange); 12621 }; 12622 return DayTableSlicer; 12623 }(Slicer)); 12624 12625 var DayTable = /** @class */ (function (_super) { 12626 __extends(DayTable, _super); 12627 function DayTable() { 12628 var _this = _super !== null && _super.apply(this, arguments) || this; 12629 _this.slicer = new DayTableSlicer(); 12630 _this.tableRef = createRef(); 12631 return _this; 12632 } 12633 DayTable.prototype.render = function () { 12634 var _a = this, props = _a.props, context = _a.context; 12635 return (createElement(Table, __assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint }))); 12636 }; 12637 return DayTable; 12638 }(DateComponent)); 12639 12640 var DayTableView = /** @class */ (function (_super) { 12641 __extends(DayTableView, _super); 12642 function DayTableView() { 12643 var _this = _super !== null && _super.apply(this, arguments) || this; 12644 _this.buildDayTableModel = memoize(buildDayTableModel); 12645 _this.headerRef = createRef(); 12646 _this.tableRef = createRef(); 12647 return _this; 12648 } 12649 DayTableView.prototype.render = function () { 12650 var _this = this; 12651 var _a = this.context, options = _a.options, dateProfileGenerator = _a.dateProfileGenerator; 12652 var props = this.props; 12653 var dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator); 12654 var headerContent = options.dayHeaders && (createElement(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 })); 12655 var bodyContent = function (contentArg) { return (createElement(DayTable, { ref: _this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint })); }; 12656 return options.dayMinWidth 12657 ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) 12658 : this.renderSimpleLayout(headerContent, bodyContent); 12659 }; 12660 return DayTableView; 12661 }(TableView)); 12662 function buildDayTableModel(dateProfile, dateProfileGenerator) {
12663 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 12664 return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 12665 } 12666 12667 var TableDateProfileGenerator = /** @class */ (function (_super) { 12668 __extends(TableDateProfileGenerator, _super); 12669 function TableDateProfileGenerator() { 12670 return _super !== null && _super.apply(this, arguments) || this; 12671 } 12672 // Computes the date range that will be rendered. 12673 TableDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) { 12674 var dateEnv = this.props.dateEnv; 12675 var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay); 12676 var start = renderRange.start; 12677 var end = renderRange.end; 12678 var endOfWeek; 12679 // year and month views should be aligned with weeks. this is already done for week 12680 if (/^(year|month)$/.test(currentRangeUnit)) { 12681 start = dateEnv.startOfWeek(start); 12682 // make end-of-week if not already 12683 endOfWeek = dateEnv.startOfWeek(end); 12684 if (endOfWeek.valueOf() !== end.valueOf()) { 12685 end = addWeeks(endOfWeek, 1); 12686 } 12687 } 12688 // ensure 6 weeks 12689 if (this.props.monthMode && 12690 this.props.fixedWeekCount) { 12691 var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays 12692 diffWeeks(start, end)); 12693 end = addWeeks(end, 6 - rowCnt); 12694 } 12695 return { start: start, end: end }; 12696 }; 12697 return TableDateProfileGenerator; 12698 }(DateProfileGenerator)); 12699 12700 var dayGridPlugin = createPlugin({ 12701 initialView: 'dayGridMonth', 12702 views: { 12703 dayGrid: { 12704 component: DayTableView, 12705 dateProfileGeneratorClass: TableDateProfileGenerator, 12706 }, 12707 dayGridDay: { 12708 type: 'dayGrid', 12709 duration: { days: 1 }, 12710 }, 12711 dayGridWeek: { 12712 type: 'dayGrid', 12713 duration: { weeks: 1 }, 12714 }, 12715 dayGridMonth: { 12716 type: 'dayGrid', 12717 duration: { months: 1 }, 12718 monthMode: true, 12719 fixedWeekCount: true, 12720 }, 12721 }, 12722 }); 12723 12724 var AllDaySplitter = /** @class */ (function (_super) { 12725 __extends(AllDaySplitter, _super); 12726 function AllDaySplitter() { 12727 return _super !== null && _super.apply(this, arguments) || this; 12728 } 12729 AllDaySplitter.prototype.getKeyInfo = function () { 12730 return { 12731 allDay: {}, 12732 timed: {}, 12733 }; 12734 }; 12735 AllDaySplitter.prototype.getKeysForDateSpan = function (dateSpan) { 12736 if (dateSpan.allDay) { 12737 return ['allDay']; 12738 } 12739 return ['timed']; 12740 }; 12741 AllDaySplitter.prototype.getKeysForEventDef = function (eventDef) { 12742 if (!eventDef.allDay) { 12743 return ['timed']; 12744 } 12745 if (hasBgRendering(eventDef)) { 12746 return ['timed', 'allDay']; 12747 } 12748 return ['allDay']; 12749 }; 12750 return AllDaySplitter; 12751 }(Splitter)); 12752 12753 var DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 12754 hour: 'numeric', 12755 minute: '2-digit', 12756 omitZeroMinute: true, 12757 meridiem: 'short', 12758 }); 12759 function TimeColsAxisCell(props) { 12760 var classNames = [ 12761 'fc-timegrid-slot', 12762 'fc-timegrid-slot-label', 12763 props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor', 12764 ]; 12765 return (createElement(ViewContextType.Consumer, null, function (context) { 12766 if (!props.isLabeled) { 12767 return (createElement("td", { className: classNames.join(' '), "data-time": props.isoTimeStr })); 12768 } 12769 var dateEnv = context.dateEnv, options = context.options, viewApi = context.viewApi; 12770 var labelFormat = // TODO: fully pre-parse 12771 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : 12772 Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) : 12773 createFormatter(options.slotLabelFormat); 12774 var hookProps = { 12775 level: 0, 12776 time: props.time, 12777 date: dateEnv.toDate(props.date), 12778 view: viewApi, 12779 text: dateEnv.format(props.date, labelFormat), 12780 }; 12781 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLabelClassNames, content: options.slotLabelContent, defaultContent: renderInnerContent$1, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
12781oncat(customClassNames).join(' '), "data-time": props.isoTimeStr }, 12782 createElement("div", { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" }, 12783 createElement("div", { className: "fc-timegrid-slot-label-cushion fc-scrollgrid-shrink-cushion", ref: innerElRef }, innerContent)))); })); 12784 })); 12785 } 12786 function renderInnerContent$1(props) { 12787 return props.text; 12788 } 12789 12790 var TimeBodyAxis = /** @class */ (function (_super) { 12791 __extends(TimeBodyAxis, _super); 12792 function TimeBodyAxis() { 12793 return _super !== null && _super.apply(this, arguments) || this; 12794 } 12795 TimeBodyAxis.prototype.render = function () { 12796 return this.props.slatMetas.map(function (slatMeta) { return (createElement("tr", { key: slatMeta.key }, 12797 createElement(TimeColsAxisCell, __assign({}, slatMeta)))); }); 12798 }; 12799 return TimeBodyAxis; 12800 }(BaseComponent)); 12801 12802 var DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: 'short' }); 12803 var AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 12804 var TimeColsView = /** @class */ (function (_super) { 12805 __extends(TimeColsView, _super); 12806 function TimeColsView() { 12807 var _this = _super !== null && _super.apply(this, arguments) || this; 12808 _this.allDaySplitter = new AllDaySplitter(); // for use by subclasses 12809 _this.headerElRef = createRef(); 12810 _this.rootElRef = createRef(); 12811 _this.scrollerElRef = createRef(); 12812 _this.state = { 12813 slatCoords: null, 12814 }; 12815 _this.handleScrollTopRequest = function (scrollTop) { 12816 var scrollerEl = _this.scrollerElRef.current; 12817 if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer 12818 scrollerEl.scrollTop = scrollTop; 12819 } 12820 }; 12821 /* Header Render Methods 12822 ------------------------------------------------------------------------------------------------------------------*/ 12823 _this.renderHeadAxis = function (rowKey, frameHeight) { 12824 if (frameHeight === void 0) { frameHeight = ''; } 12825 var options = _this.context.options; 12826 var dateProfile = _this.props.dateProfile; 12827 var range = dateProfile.renderRange; 12828 var dayCnt = diffDays(range.start, range.end); 12829 var navLinkAttrs = (options.navLinks && dayCnt === 1) // only do in day views (to avoid doing in week views that dont need it) 12830 ? { 'data-navlink': buildNavLinkData(range.start, 'week'), tabIndex: 0 } 12831 : {}; 12832 if (options.weekNumbers && rowKey === 'day') { 12833 return (createElement(WeekNumberRoot, { date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("th", { ref: rootElRef, className: [ 12834 'fc-timegrid-axis', 12835 'fc-scrollgrid-shrink', 12836 ].concat(classNames).join(' ') }, 12837 createElement("div", { className: "fc-timegrid-axis-frame fc-scrollgrid-shrink-frame fc-timegrid-axis-frame-liquid", style: { height: frameHeight } }, 12838 createElement("a", __assign({ ref: innerElRef, className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner" }, navLinkAttrs), innerContent)))); })); 12839 } 12840 return (createElement("th", { className: "fc-timegrid-axis" }, 12841 createElement("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } }))); 12842 }; 12843 /* Table Component Render Methods 12844 ------------------------------------------------------------------------------------------------------------------*/ 12845 // only a one-way height sync. we don't send the axis inner-content height to the DayGrid, 12846 // but DayGrid still needs to have classNames on inner elements in order to measure. 12847 _this.renderTableRowAxis = function (rowHeight) { 12848 var _a = _this.context, options = _a.options, viewApi = _a.viewApi; 12849 var hookProps = { 12850 text: options.allDayText, 12851 view: viewApi, 12852 }; 12853 return ( 12854 // TODO: make reusable hook. used in list view too 12855 createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner$1, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: [ 12856 'fc-timegrid-axis', 12857 'fc-scrollgrid-shrink', 12858 ].concat(classNames).join(' ') }, 12859 createElement("div", { className: 'fc-timegrid-axis-frame fc-scrollgrid-shrink-frame' + (rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''), style: { height: rowHeight } }, 12860 createElement("span", { className: "fc-timegrid-axis-cushion fc-scrollgrid-shrink-cushion fc-scrollgrid-sync-inner", ref: innerElRef }, innerContent)))); })); 12861 }; 12862 _this.handleSlatCoords = function (slatCoords) {
12863 _this.setState({ slatCoords: slatCoords }); 12864 }; 12865 return _this; 12866 } 12867 // rendering 12868 // ---------------------------------------------------------------------------------------------------- 12869 TimeColsView.prototype.renderSimpleLayout = function (headerRowContent, allDayContent, timeContent) { 12870 var _a = this, context = _a.context, props = _a.props; 12871 var sections = []; 12872 var stickyHeaderDates = getStickyHeaderDates(context.options); 12873 if (headerRowContent) { 12874 sections.push({ 12875 type: 'header', 12876 key: 'header', 12877 isSticky: stickyHeaderDates, 12878 chunk: { 12879 elRef: this.headerElRef, 12880 tableClassName: 'fc-col-header', 12881 rowContent: headerRowContent, 12882 }, 12883 }); 12884 } 12885 if (allDayContent) { 12886 sections.push({ 12887 type: 'body', 12888 key: 'all-day', 12889 chunk: { content: allDayContent }, 12890 }); 12891 sections.push({ 12892 type: 'body', 12893 key: 'all-day-divider', 12894 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 12895 createElement("tr", { className: "fc-scrollgrid-section" }, 12896 createElement("td", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 12897 }); 12898 } 12899 sections.push({ 12900 type: 'body', 12901 key: 'body', 12902 liquid: true, 12903 expandRows: Boolean(context.options.expandRows), 12904 chunk: { 12905 scrollerElRef: this.scrollerElRef, 12906 content: timeContent, 12907 }, 12908 }); 12909 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].concat(classNames).join(' '), ref: rootElRef }, 12910 createElement(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections }))); })); 12911 }; 12912 TimeColsView.prototype.renderHScrollLayout = function (headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) { 12913 var _this = this; 12914 var ScrollGrid = this.context.pluginHooks.scrollGridImpl; 12915 if (!ScrollGrid) { 12916 throw new Error('No ScrollGrid implementation'); 12917 } 12918 var _a = this, context = _a.context, props = _a.props; 12919 var stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 12920 var stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 12921 var sections = []; 12922 if (headerRowContent) { 12923 sections.push({ 12924 type: 'header', 12925 key: 'header', 12926 isSticky: stickyHeaderDates, 12927 syncRowHeights: true, 12928 chunks: [ 12929 { 12930 key: 'axis', 12931 rowContent: function (arg) { return (createElement("tr", null, _this.renderHeadAxis('day', arg.rowSyncHeights[0]))); }, 12932 }, 12933 { 12934 key: 'cols', 12935 elRef: this.headerElRef, 12936 tableClassName: 'fc-col-header', 12937 rowContent: headerRowContent, 12938 }, 12939 ], 12940 }); 12941 } 12942 if (allDayContent) { 12943 sections.push({ 12944 type: 'body', 12945 key: 'all-day', 12946 syncRowHeights: true, 12947 chunks: [ 12948 { 12949 key: 'axis', 12950 rowContent: function (contentArg) { return (createElement("tr", null, _this.renderTableRowAxis(contentArg.rowSyncHeights[0]))); }, 12951 }, 12952 { 12953 key: 'cols', 12954 content: allDayContent, 12955 }, 12956 ], 12957 }); 12958 sections.push({ 12959 key: 'all-day-divider', 12960 type: 'body', 12961 outerContent: ( // TODO: rename to cellContent so don't need to define <tr>? 12962 createElement("tr", { className: "fc-scrollgrid-section" }, 12963 createElement("td", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))), 12964 }); 12965 } 12966 var isNowIndicator = context.options.nowIndicator; 12967 sections.push({ 12968 type: 'body', 12969 key: 'body', 12970 liquid: true, 12971 expandRows: Boolean(context.options.expandRows), 12972 chunks: [ 12973 { 12974 key: 'axis', 12975 content: function (arg) { return ( 12976 // TODO: make this now-indicator arrow more DRY with TimeColsContent 12977 createElement("div", { className: "fc-timegrid-axis-chunk" }, 12978 createElement("table", { style: { height: arg.expandRows ? arg.clientHeight : '' } }, 12979 arg.tableColGroupNode, 12980 createElement("tbody", null, 12981 createElement(TimeBodyAxis, { slatMetas: slatMetas }))), 12982 createElement("div", { className: "fc-timegrid-now-indicator-container" }, 12983 createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, function (nowDate) { 12984 var nowIndicatorTop = isNowIndicator && 12985 slatCoords && 12986 slatCoords.safeComputeTop(nowDate); // might return void 12987 if (typeof nowIndicatorTop === 'number') { 12988 return (createElement(NowIndicatorRoot, { isAxis: true, date: nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })); 12989 } 12990 return null; 12991 })))); }, 12992 }, 12993 { 12994 key: 'cols', 12995 scrollerElRef: this.scrollerElRef, 12996 content: timeContent, 12997 }, 12998 ], 12999 }); 13000 if (stickyFooterScrollbar) { 13001 sections.push({ 13002 key: 'footer', 13003 type: 'footer', 13004 isSticky: true, 13005 chunks: [ 13006 { 13007 key: 'axis', 13008 content: renderScrollShim, 13009 }, 13010 { 13011 key: 'cols', 13012 content: renderScrollShim, 13013 }, 13014 ], 13015 }); 13016 } 13017 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.rootElRef }, function (rootElRef, classNames) { return (createElement("div", { className: ['fc-timegrid'].
13017concat(classNames).join(' '), ref: rootElRef }, 13018 createElement(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [ 13019 { width: 'shrink', cols: [{ width: 'shrink' }] }, 13020 { cols: [{ span: colCnt, minWidth: dayMinWidth }] }, 13021 ], sections: sections }))); })); 13022 }; 13023 /* Dimensions 13024 ------------------------------------------------------------------------------------------------------------------*/ 13025 TimeColsView.prototype.getAllDayMaxEventProps = function () { 13026 var _a = this.context.options, dayMaxEvents = _a.dayMaxEvents, dayMaxEventRows = _a.dayMaxEventRows; 13027 if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto? 13028 dayMaxEvents = undefined; 13029 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number 13030 } 13031 return { dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows }; 13032 }; 13033 return TimeColsView; 13034 }(DateComponent)); 13035 function renderAllDayInner$1(hookProps) { 13036 return hookProps.text; 13037 } 13038 13039 var TimeColsSlatsCoords = /** @class */ (function () { 13040 function TimeColsSlatsCoords(positions, dateProfile, slotDuration) { 13041 this.positions = positions; 13042 this.dateProfile = dateProfile; 13043 this.slotDuration = slotDuration; 13044 } 13045 TimeColsSlatsCoords.prototype.safeComputeTop = function (date) { 13046 var dateProfile = this.dateProfile; 13047 if (rangeContainsMarker(dateProfile.currentRange, date)) { 13048 var startOfDayDate = startOfDay(date); 13049 var timeMs = date.valueOf() - startOfDayDate.valueOf(); 13050 if (timeMs >= asRoughMs(dateProfile.slotMinTime) && 13051 timeMs < asRoughMs(dateProfile.slotMaxTime)) { 13052 return this.computeTimeTop(createDuration(timeMs)); 13053 } 13054 } 13055 return null; 13056 }; 13057 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 13058 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 13059 TimeColsSlatsCoords.prototype.computeDateTop = function (when, startOfDayDate) { 13060 if (!startOfDayDate) { 13061 startOfDayDate = startOfDay(when); 13062 } 13063 return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())); 13064 }; 13065 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 13066 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 13067 // Eventually allow computation with arbirary slat dates. 13068 TimeColsSlatsCoords.prototype.computeTimeTop = function (duration) { 13069 var _a = this, positions = _a.positions, dateProfile = _a.dateProfile; 13070 var len = positions.els.length; 13071 // floating-point value of # of slots covered 13072 var slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration); 13073 var slatIndex; 13074 var slatRemainder; 13075 // compute a floating-point number for how many slats should be progressed through. 13076 // from 0 to number of slats (inclusive) 13077 // constrained because slotMinTime/slotMaxTime might be customized. 13078 slatCoverage = Math.max(0, slatCoverage); 13079 slatCoverage = Math.min(len, slatCoverage); 13080 // an integer index of the furthest whole slat 13081 // from 0 to number slats (*exclusive*, so len-1) 13082 slatIndex = Math.floor(slatCoverage); 13083 slatIndex = Math.min(slatIndex, len - 1); 13084 // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition. 13085 // could be 1.0 if slatCoverage is covering *all* the slots 13086 slatRemainder = slatCoverage - slatIndex; 13087 return positions.tops[slatIndex] + 13088 positions.getHeight(slatIndex) * slatRemainder; 13089 }; 13090 return TimeColsSlatsCoords; 13091 }()); 13092 13093 var TimeColsSlatsBody = /** @class */ (function (_super) { 13094 __extends(TimeColsSlatsBody, _super); 13095 function TimeColsSlatsBody() { 13096 return _super !== null && _super.apply(this, arguments) || this; 13097 } 13098 TimeColsSlatsBody.prototype.render = function () { 13099 var _a = this, props = _a.props, context = _a.context; 13100 var options = context.options; 13101 var slatElRefs = props.slatElRefs; 13102 return (createElement("tbody", null, props.slatMetas.map(function (slatMeta, i) { 13103 var hookProps = { 13104 time: slatMeta.time, 13105 date: context.dateEnv.toDate(slatMeta.date), 13106 view: context.viewApi, 13107 }; 13108 var classNames = [ 13109 'fc-timegrid-slot', 13110 'fc-timegrid-slot-lane', 13111 slatMeta.isLabeled ? '' : 'fc-timegrid-slot-minor', 13112 ]; 13113 return (createElement("tr", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) }, 13114 props.axis && (createElement(TimeColsAxisCell, __assign({}, slatMeta))), 13115 createElement(RenderHook, { hookProps: hookProps, classNames: options.slotLaneClassNames, content: options.slotLaneContent, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("td", { ref: rootElRef, className: classNames.c
13115oncat(customClassNames).join(' '), "data-time": slatMeta.isoTimeStr }, innerContent)); }))); 13116 }))); 13117 }; 13118 return TimeColsSlatsBody; 13119 }(BaseComponent)); 13120 13121 /* 13122 for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL. 13123 */ 13124 var TimeColsSlats = /** @class */ (function (_super) { 13125 __extends(TimeColsSlats, _super); 13126 function TimeColsSlats() { 13127 var _this = _super !== null && _super.apply(this, arguments) || this; 13128 _this.rootElRef = createRef(); 13129 _this.slatElRefs = new RefMap(); 13130 return _this; 13131 } 13132 TimeColsSlats.prototype.render = function () { 13133 var _a = this, props = _a.props, context = _a.context; 13134 return (createElement("div", { className: "fc-timegrid-slots", ref: this.rootElRef }, 13135 createElement("table", { className: context.theme.getClass('table'), style: { 13136 minWidth: props.tableMinWidth, 13137 width: props.clientWidth, 13138 height: props.minHeight, 13139 } }, 13140 props.tableColGroupNode /* relies on there only being a single <col> for the axis */, 13141 createElement(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas })))); 13142 }; 13143 TimeColsSlats.prototype.componentDidMount = function () { 13144 this.updateSizing(); 13145 }; 13146 TimeColsSlats.prototype.componentDidUpdate = function () { 13147 this.updateSizing(); 13148 }; 13149 TimeColsSlats.prototype.componentWillUnmount = function () { 13150 if (this.props.onCoords) { 13151 this.props.onCoords(null); 13152 } 13153 }; 13154 TimeColsSlats.prototype.updateSizing = function () { 13155 var _a = this, context = _a.context, props = _a.props; 13156 if (props.onCoords && 13157 props.clientWidth !== null // means sizing has stabilized 13158 ) { 13159 var rootEl = this.rootElRef.current; 13160 if (rootEl.offsetHeight) { // not hidden by css 13161 props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration)); 13162 } 13163 } 13164 }; 13165 return TimeColsSlats; 13166 }(BaseComponent)); 13167 function collectSlatEls(elMap, slatMetas) { 13168 return slatMetas.map(function (slatMeta) { return elMap[slatMeta.key]; }); 13169 } 13170 13171 function splitSegsByCol(segs, colCnt) { 13172 var segsByCol = []; 13173 var i; 13174 for (i = 0; i < colCnt; i += 1) { 13175 segsByCol.push([]); 13176 } 13177 if (segs) { 13178 for (i = 0; i < segs.length; i += 1) { 13179 segsByCol[segs[i].col].push(segs[i]); 13180 } 13181 } 13182 return segsByCol; 13183 } 13184 function splitInteractionByCol(ui, colCnt) { 13185 var byRow = []; 13186 if (!ui) { 13187 for (var i = 0; i < colCnt; i += 1) { 13188 byRow[i] = null; 13189 } 13190 } 13191 else { 13192 for (var i = 0; i < colCnt; i += 1) { 13193 byRow[i] = { 13194 affectedInstances: ui.affectedInstances, 13195 isEvent: ui.isEvent, 13196 segs: [], 13197 }; 13198 } 13199 for (var _i = 0, _a = ui.segs; _i < _a.length; _i++) { 13200 var seg = _a[_i]; 13201 byRow[seg.col].segs.push(seg); 13202 } 13203 } 13204 return byRow; 13205 } 13206 13207 var TimeColMoreLink = /** @class */ (function (_super) { 13208 __extends(TimeColMoreLink, _super); 13209 function TimeColMoreLink() { 13210 var _this = _super !== null && _super.apply(this, arguments) || this; 13211 _this.rootElRef = createRef(); 13212 return _this; 13213 } 13214 TimeColMoreLink.prototype.render = function () { 13215 var _this = this; 13216 var props = this.props; 13217 return (createElement(MoreLinkRoot, { allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, al
13217ignmentElRef: this.rootElRef, defaultContent: renderMoreLinkInner, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: function () { return renderPlainFgSegs(props.hiddenSegs, props); } }, function (rootElRef, classNames, innerElRef, innerContent, handleClick) { return (createElement("a", { ref: function (el) { 13218 setRef(rootElRef, el); 13219 setRef(_this.rootElRef, el); 13220 }, className: ['fc-timegrid-more-link'].concat(classNames).join(' '), style: { top: props.top, bottom: props.bottom }, onClick: handleClick }, 13221 createElement("div", { ref: innerElRef, className: "fc-timegrid-more-link-inner fc-sticky" }, innerContent))); })); 13222 }; 13223 return TimeColMoreLink; 13224 }(BaseComponent)); 13225 function renderMoreLinkInner(props) { 13226 return props.shortText; 13227 } 13228 13229 // segInputs assumed sorted 13230 function computeFgSegPlacements(segInputs, strictOrder, maxStackCnt) { 13231 var hierarchy = new SegHierarchy(); 13232 if (strictOrder != null) { 13233 hierarchy.strictOrder = strictOrder; 13234 } 13235 if (maxStackCnt != null) { 13236 hierarchy.maxStackCnt = maxStackCnt; 13237 } 13238 var hiddenEntries = hierarchy.addSegs(segInputs); 13239 var hiddenGroups = groupIntersectingEntries(hiddenEntries); 13240 var web = buildWeb(hierarchy); 13241 web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0 13242 var segRects = webToRects(web); 13243 return { segRects: segRects, hiddenGroups: hiddenGroups }; 13244 } 13245 function buildWeb(hierarchy) { 13246 var entriesByLevel = hierarchy.entriesByLevel; 13247 var buildNode = cacheable(function (level, lateral) { return level + ':' + lateral; }, function (level, lateral) { 13248 var siblingRange = findNextLevelSegs(hierarchy, level, lateral); 13249 var nextLevelRes = buildNodes(siblingRange, buildNode); 13250 var entry = entriesByLevel[level][lateral]; 13251 return [ 13252 __assign(__assign({}, entry), { nextLevelNodes: nextLevelRes[0] }), 13253 entry.thickness + nextLevelRes[1], // the pressure builds 13254 ]; 13255 }); 13256 return buildNodes(entriesByLevel.length 13257 ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length } 13258 : null, buildNode)[0]; 13259 } 13260 function buildNodes(siblingRange, buildNode) { 13261 if (!siblingRange) { 13262 return [[], 0]; 13263 } 13264 var level = siblingRange.level, lateralStart = siblingRange.lateralStart, lateralEnd = siblingRange.lateralEnd; 13265 var lateral = lateralStart; 13266 var pairs = []; 13267 while (lateral < lateralEnd) { 13268 pairs.push(buildNode(level, lateral)); 13269 lateral += 1; 13270 } 13271 pairs.sort(cmpDescPressures); 13272 return [ 13273 pairs.map(extractNode), 13274 pairs[0][1], // first item's pressure 13275 ]; 13276 } 13277 function cmpDescPressures(a, b) { 13278 return b[1] - a[1]; 13279 } 13280 function extractNode(a) { 13281 return a[0]; 13282 } 13283 function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) { 13284 var levelCoords = hierarchy.levelCoords, entriesByLevel = hierarchy.entriesByLevel; 13285 var subjectEntry = entriesByLevel[subjectLevel][subjectLateral]; 13286 var afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness; 13287 var levelCnt = levelCoords.length; 13288 var level = subjectLevel; 13289 // skip past levels that are too high up 13290 for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1) 13291 ; // do nothing 13292 for (; level < levelCnt; level += 1) { 13293 var entries = entriesByLevel[level]; 13294 var entry = void 0; 13295 var searchIndex = binarySearch(entries, subjectEntry.spanStart, getEntrySpanEnd); 13296 var lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one 13297 var lateralEnd = lateralStart; 13298 while ( // loop through entries that horizontally intersect 13299 (entry = entries[lateralEnd]) && // but not past the whole seg list 13300 entry.spanStart < subjectEntry.spanEnd) { 13301 lateralEnd += 1; 13302 } 13303 if (lateralStart < lateralEnd) { 13304 return { level: level, lateralStart: lateralStart, lateralEnd: lateralEnd }; 13305 } 13306 } 13307 return null; 13308 } 13309 function stretchWeb(topLevelNodes, totalThickness) { 13310 var stretchNode = cacheable(function (node, startCoord, prevThickness) { return buildEntryKey(node); }, function (node, startCoord, prevThickness) { 13311 var nextLevelNodes = node.nextLevelNodes, thickness = node.thickness; 13312 var allThickness = thickness + prevThickness; 13313 var thicknessFraction = thickness / allThickness; 13314 var endCoord; 13315 var newChildren = []; 13316 if (!nextLevelNodes.length) { 13317 endCoord = totalThickness; 13318 } 13319 else { 13320 for (var _i = 0, nextLevelNodes_1 = nextLevelNodes; _i < nextLevelNodes_1.length; _i++) { 13321 var childNode = nextLevelNodes_1[_i]; 13322 if (endCoord === undefined) { 13323 var res = stretchNode(childNode, startCoord, allThickness); 13324 endCoord = res[0]; 13325 newChildren.push(res[1]); 13326 } 13327 else { 13328 var res = stretchNode(childNode, endCoord, 0); 13329 newChildren.push(res[1]); 13330 } 13331 } 13332 } 13333 var newThickness = (endCoord - startCoord) * thicknessFraction; 13334 return [endCoord - newThickness, __assign(__assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })]; 13335 }); 13336 return topLevelNodes.map(function (node) { return stretchNode(node,
133360, 0)[1]; }); 13337 } 13338 // not sorted in any particular order 13339 function webToRects(topLevelNodes) { 13340 var rects = []; 13341 var processNode = cacheable(function (node, levelCoord, stackDepth) { return buildEntryKey(node); }, function (node, levelCoord, stackDepth) { 13342 var rect = __assign(__assign({}, node), { levelCoord: levelCoord, 13343 stackDepth: stackDepth, stackForward: 0 }); 13344 rects.push(rect); 13345 return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1); 13346 }); 13347 function processNodes(nodes, levelCoord, stackDepth) { 13348 var stackForward = 0; 13349 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { 13350 var node = nodes_1[_i]; 13351 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward); 13352 } 13353 return stackForward; 13354 } 13355 processNodes(topLevelNodes, 0, 0); 13356 return rects; // TODO: sort rects by levelCoord to be consistent with toRects? 13357 } 13358 // TODO: move to general util 13359 function cacheable(keyFunc, workFunc) { 13360 var cache = {}; 13361 return function () { 13362 var args = []; 13363 for (var _i = 0; _i < arguments.length; _i++) { 13364 args[_i] = arguments[_i]; 13365 } 13366 var key = keyFunc.apply(void 0, args); 13367 return (key in cache) 13368 ? cache[key] 13369 : (cache[key] = workFunc.apply(void 0, args)); 13370 }; 13371 } 13372 13373 var DEFAULT_TIME_FORMAT$1 = createFormatter({ 13374 hour: 'numeric', 13375 minute: '2-digit', 13376 meridiem: false, 13377 }); 13378 var TimeColEvent = /** @class */ (function (_super) { 13379 __extends(TimeColEvent, _super); 13380 function TimeColEvent() { 13381 return _super !== null && _super.apply(this, arguments) || this; 13382 } 13383 TimeColEvent.prototype.render = function () { 13384 var classNames = [ 13385 'fc-timegrid-event', 13386 'fc-v-event', 13387 ]; 13388 if (this.props.isShort) { 13389 classNames.push('fc-timegrid-event-short'); 13390 } 13391 return (createElement(StandardEvent, __assign({}, this.props, { defaultTimeFormat: DEFAULT_TIME_FORMAT$1, extraClassNames: classNames }))); 13392 }; 13393 return TimeColEvent; 13394 }(BaseComponent)); 13395 13396 var TimeColMisc = /** @class */ (function (_super) { 13397 __extends(TimeColMisc, _super); 13398 function TimeColMisc() { 13399 return _super !== null && _super.apply(this, arguments) || this; 13400 } 13401 TimeColMisc.prototype.render = function () { 13402 var props = this.props; 13403 return (createElement(DayCellContent, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (innerElRef, innerContent) { return (innerContent && 13404 createElement("div", { className: "fc-timegrid-col-misc", ref: innerElRef }, innerContent)); })); 13405 }; 13406 return TimeColMisc; 13407 }(BaseComponent)); 13408 13409 var TimeCol = /** @class */ (function (_super) { 13410 __extends(TimeCol, _super); 13411 function TimeCol() { 13412 var _this = _super !== null && _super.apply(this, arguments) || this; 13413 _this.sortEventSegs = memoize(sortEventSegs); 13414 _this.computeFgSegPlacements = memoize(computeFgSegPlacements); // only for non-print, non-mirror 13415 return _this; 13416 } 13417 TimeCol.prototype.render = function () { 13418 var _this = this; 13419 var _a = this, props = _a.props, context = _a.context; 13420 var isSelectMirror = context.options.selectMirror; 13421 var mirrorSegs = (props.eventDrag && props.eventDrag.segs) || 13422 (props.eventResize && props.eventResize.segs) || 13423 (isSelectMirror && props.dateSelectionSegs) || 13424 []; 13425 var interactionAffectedInstances = // TODO: messy way to compute this 13426 (props.eventDrag && props.eventDrag.affectedInstances) || 13427 (props.eventResize && props.eventResize.affectedInstances) || 13428 {}; 13429 var sortedFgSegs = this.sortEventSegs(props.fgEventSegs, context.options.eventOrder); 13430 return (createElement(DayCellRoot, { elRef: props.elRef, date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps }, function (rootElRef, classNames, dataAttrs) { return (createElement("td", __assign({ ref: rootElRef, className: ['fc-timegrid-col'].concat(classNames, props.extraClassNames || []).join(' ') }, dataAttrs, props.extraDataAttrs), 13431 createElement("div", { className: "fc-timegrid-col-frame" }, 13432 createElement("div", { className: "fc-timegrid-col-bg" }, 13433 _this.renderFillSegs(props.businessHourSegs, 'non-business'), 13434 _this.renderFillSegs(props.bgEventSegs, 'bg-event'), 13435 _this.renderFillSegs(props.dateSelectionSegs, 'highlight')), 13436 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(sortedFgSegs, interactionAffectedInstances)), 13437 createElement("div", { className: "fc-timegrid-col-events" }, _this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))), 13438 createElement("div", { className: "fc-timegrid-now-indicator-container" }, _this.renderNowIndicator(props.nowIndicatorSegs)), 13439 createElement(TimeColMisc, { date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraHookProps: props.extraHookProps })))); })); 13440 }; 13441 TimeCol.prototype.renderFgSegs = function (sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) { 13442 var props = this.props; 13443 if (props.forPrint) { 13444 return renderPlainFgSegs(sortedFgSegs, props); 13445 } 13446 if (props.slatCoords) { 13447 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting); 13448 } 13449 return null; 13450 }; 13451 TimeCol.prototype.renderPositionedFgSegs = function (segs, // if not mirror, needs to be sorted 13452 segIsInvisible, isDragging, isResizing, isDateSelecting) { 13453 var _this = this; 13454 var _a = this.context.options, eventMaxStack = _a.eventMaxStack, eventShortHeight = _a.eventShortHeight, eventOrderStrict = _a.eventOrderStrict; 13455 var _b = this.props, eventSelection = _b.eventSelection, todayRange = _b.todayRange, nowDate = _b.nowDate; 13456 var isMirror = isDragging || isResizing || isDateSelecting; 13457 var segInputs = this.buildSegInputs(segs); 13458 var _c = isMirror ? computeFgSegPlacements(segInputs) : // don't use memoized 13459 this.computeFgSegPlacements(segInputs, eventOrderStrict, eventMaxStack), segRects = _c.segRects, hiddenGroups = _c.hiddenGroups; 13460 return (createElement(Fragment, null, 13461 this.renderHiddenGroups(hiddenGroups, segs), 13462 segRects.map(function (segRect) { 13463 var seg = segs[segRect.segInput.index]; 13464 var instanceId = seg.eventRange.instance.instanceId; 13465 var positionCss = __assign(__assign({}
13465, _this.computeSegTopBottomCss(segRect.segInput)), (isMirror ? { left: 0, right: 0 } : _this.computeSegLeftRightCss(segRect))); 13466 return (createElement("div", { className: 'fc-timegrid-event-harness' + (segRect.stackForward > 0 ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: __assign({ visibility: segIsInvisible[instanceId] ? 'hidden' : '' }, positionCss) }, 13467 createElement(TimeColEvent, __assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: (segRect.spanEnd - segRect.spanStart) < eventShortHeight }, getSegMeta(seg, todayRange, nowDate))))); 13468 }))); 13469 }; 13470 // will already have eventMinHeight applied because segInputs already had it 13471 TimeCol.prototype.renderHiddenGroups = function (hiddenGroups, segs) { 13472 var _this = this; 13473 var _a = this.props, extraDateSpan = _a.extraDateSpan, dateProfile = _a.dateProfile, todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13474 return (createElement(Fragment, null, hiddenGroups.map(function (hiddenGroup) { 13475 var positionCss = _this.computeSegTopBottomCss(hiddenGroup); 13476 var hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs); 13477 return (createElement(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize })); 13478 }))); 13479 }; 13480 TimeCol.prototype.buildSegInputs = function (segs) { 13481 var _a = this.props, date = _a.date, slatCoords = _a.slatCoords; 13482 var eventMinHeight = this.context.options.eventMinHeight; 13483 var segInputs = []; 13484 for (var i = 0; i < segs.length; i += 1) { 13485 var seg = segs[i]; 13486 var spanStart = slatCoords.computeDateTop(seg.start, date); 13487 var spanEnd = Math.max(spanStart + (eventMinHeight || 0), // yuck 13488 slatCoords.computeDateTop(seg.end, date)); 13489 segInputs.push({ 13490 index: i, 13491 spanStart: Math.round(spanStart), 13492 spanEnd: Math.round(spanEnd), 13493 thickness: 1, 13494 }); 13495 } 13496 return segInputs; 13497 }; 13498 TimeCol.prototype.renderFillSegs = function (segs, fillType) { 13499 var _this = this; 13500 var props = this.props; 13501 if (!props.slatCoords) { 13502 return null; 13503 } 13504 var segInputs = this.buildSegInputs(segs); 13505 var children = segInputs.map(function (segInput) { 13506 var seg = segs[segInput.index]; 13507 return (createElement("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: _this.computeSegTopBottomCss(segInput) }, fillType === 'bg-event' ? 13508 createElement(BgEvent, __assign({ seg: seg }, getSegMeta(seg, props.todayRange, props.nowDate))) : 13509 renderFill(fillType))); 13510 }); 13511 return createElement(Fragment, null, children); 13512 }; 13513 TimeCol.prototype.renderNowIndicator = function (segs) { 13514 var _a = this.props, slatCoords = _a.slatCoords, date = _a.date; 13515 if (!slatCoords) { 13516 return null; 13517 } 13518 return segs.map(function (seg, i) { return (createElement(NowIndicatorRoot, { isAxis: false, date: date, 13519 // key doesn't matter. will only ever be one 13520 key: i }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-line'].concat(classNames).join(' '), style: { top: slatCoords.computeDateTop(seg.start, date) } }, innerContent)); })); }); 13521 };
13522 TimeCol.prototype.computeSegTopBottomCss = function (segLike) { 13523 return { 13524 top: segLike.spanStart, 13525 bottom: -segLike.spanEnd, 13526 }; 13527 }; 13528 TimeCol.prototype.computeSegLeftRightCss = function (segRect) { 13529 var _a = this.context, isRtl = _a.isRtl, options = _a.options; 13530 var shouldOverlap = options.slotEventOverlap; 13531 var nearCoord = segRect.levelCoord; // the left side if LTR. the right side if RTL. floating-point 13532 var farCoord = segRect.levelCoord + segRect.thickness; // the right side if LTR. the left side if RTL. floating-point 13533 var left; // amount of space from left edge, a fraction of the total width 13534 var right; // amount of space from right edge, a fraction of the total width 13535 if (shouldOverlap) { 13536 // double the width, but don't go beyond the maximum forward coordinate (1.0) 13537 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2); 13538 } 13539 if (isRtl) { 13540 left = 1 - farCoord; 13541 right = nearCoord; 13542 } 13543 else { 13544 left = nearCoord; 13545 right = 1 - farCoord; 13546 } 13547 var props = { 13548 zIndex: segRect.stackDepth + 1, 13549 left: left * 100 + '%', 13550 right: right * 100 + '%', 13551 }; 13552 if (shouldOverlap && !segRect.stackForward) { 13553 // add padding to the edge so that forward stacked events don't cover the resizer's icon 13554 props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width 13555 } 13556 return props; 13557 }; 13558 return TimeCol; 13559 }(BaseComponent)); 13560 function renderPlainFgSegs(sortedFgSegs, _a) { 13561 var todayRange = _a.todayRange, nowDate = _a.nowDate, eventSelection = _a.eventSelection, eventDrag = _a.eventDrag, eventResize = _a.eventResize; 13562 var hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || 13563 (eventResize ? eventResize.affectedInstances : null) || 13564 {}; 13565 return (createElement(Fragment, null, sortedFgSegs.map(function (seg) { 13566 var instanceId = seg.eventRange.instance.instanceId; 13567 return (createElement("div", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } }, 13568 createElement(TimeColEvent, __assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate))))); 13569 }))); 13570 } 13571 function compileSegsFromEntries(segEntries, allSegs) { 13572 return segEntries.map(function (segEntry) { return allSegs[segEntry.segInput.index]; }); 13573 } 13574 13575 var TimeColsContent = /** @class */ (function (_super) { 13576 __extends(TimeColsContent, _super); 13577 function TimeColsContent() { 13578 var _this = _super !== null && _super.apply(this, arguments) || this; 13579 _this.splitFgEventSegs = memoize(splitSegsByCol); 13580 _this.splitBgEventSegs = memoize(splitSegsByCol); 13581 _this.splitBusinessHourSegs = memoize(splitSegsByCol); 13582 _this.splitNowIndicatorSegs = memoize(splitSegsByCol); 13583 _this.splitDateSelectionSegs = memoize(splitSegsByCol); 13584 _this.splitEventDrag = memoize(splitInteractionByCol); 13585 _this.splitEventResize = memoize(splitInteractionByCol); 13586 _this.rootElRef = createRef(); 13587 _this.cellElRefs = new RefMap(); 13588 return _this; 13589 } 13590 TimeColsContent.prototype.render = function () { 13591 var _this = this; 13592 var _a = this, props = _a.props, context = _a.context; 13593 var nowIndicatorTop = context.options.nowIndicator && 13594 props.slatCoords && 13595 props.slatCoords.safeComputeTop(props.nowDate); // might return void 13596 var colCnt = props.cells.length; 13597 var fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 13598 var bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 13599 var businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt); 13600 var nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt); 13601 var dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt); 13602 var eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 13603 var eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 13604 return (createElement("div", { className: "fc-timegrid-cols", ref: this.rootElRef }, 13605 createElement("table", { style: { 13606 minWidth: props.tableMinWidth, 13607 width: props.clientWidth, 13608 } },
13609 props.tableColGroupNode, 13610 createElement("tbody", null, 13611 createElement("tr", null, 13612 props.axis && (createElement("td", { className: "fc-timegrid-col fc-timegrid-axis" }, 13613 createElement("div", { className: "fc-timegrid-col-frame" }, 13614 createElement("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === 'number' && (createElement(NowIndicatorRoot, { isAxis: true, date: props.nowDate }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { ref: rootElRef, className: ['fc-timegrid-now-indicator-arrow'].concat(classNames).join(' '), style: { top: nowIndicatorTop } }, innerContent)); })))))), 13615 props.cells.map(function (cell, i) { return (createElement(TimeCol, { key: cell.key, elRef: _this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraHookProps: cell.extraHookProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })); })))))); 13616 }; 13617 TimeColsContent.prototype.componentDidMount = function () { 13618 this.updateCoords(); 13619 }; 13620 TimeColsContent.prototype.componentDidUpdate = function () { 13621 this.updateCoords(); 13622 }; 13623 TimeColsContent.prototype.updateCoords = function () { 13624 var props = this.props; 13625 if (props.onColCoords && 13626 props.clientWidth !== null // means sizing has stabilized 13627 ) { 13628 props.onColCoords(new PositionCache(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal 13629 false)); 13630 } 13631 }; 13632 return TimeColsContent; 13633 }(BaseComponent)); 13634 function collectCellEls(elMap, cells) { 13635 return cells.map(function (cell) { return elMap[cell.key]; }); 13636 } 13637 13638 /* A component that renders one or more columns of vertical time slots 13639 ----------------------------------------------------------------------------------------------------------------------*/ 13640 var TimeCols = /** @class */ (function (_super) { 13641 __extends(TimeCols, _super); 13642 function TimeCols() { 13643 var _this = _super !== null && _super.apply(this, arguments) || this; 13644 _this.processSlotOptions = memoize(processSlotOptions); 13645 _this.state = { 13646 slatCoords: null, 13647 }; 13648 _this.handleRootEl = function (el) { 13649 if (el) { 13650 _this.context.registerInteractiveComponent(_this, { 13651 el: el, 13652 isHitComboAllowed: _this.props.isHitComboAllowed, 13653 }); 13654 } 13655 else { 13656 _this.context.unregisterInteractiveComponent(_this); 13657 } 13658 }; 13659 _this.handleScrollRequest = function (request) { 13660 var onScrollTopRequest = _this.props.onScrollTopRequest; 13661 var slatCoords = _this.state.slatCoords; 13662 if (onScrollTopRequest && slatCoords) { 13663 if (request.time) { 13664 var top_1 = slatCoords.computeTimeTop(request.time); 13665 top_1 = Math.ceil(top_1); // zoom can give weird floating-point values. rather scroll a little bit further 13666 if (top_1) { 13667 top_1 += 1; // to overcome top border that slots beyond the first have. looks better 13668 } 13669 onScrollTopRequest(top_1); 13670 } 13671 return true; 13672 } 13673 return false;
13674 }; 13675 _this.handleColCoords = function (colCoords) { 13676 _this.colCoords = colCoords; 13677 }; 13678 _this.handleSlatCoords = function (slatCoords) { 13679 _this.setState({ slatCoords: slatCoords }); 13680 if (_this.props.onSlatCoords) { 13681 _this.props.onSlatCoords(slatCoords); 13682 } 13683 }; 13684 return _this; 13685 } 13686 TimeCols.prototype.render = function () { 13687 var _a = this, props = _a.props, state = _a.state; 13688 return (createElement("div", { className: "fc-timegrid-body", ref: this.handleRootEl, style: { 13689 // these props are important to give this wrapper correct dimensions for interactions 13690 // TODO: if we set it here, can we avoid giving to inner tables? 13691 width: props.clientWidth, 13692 minWidth: props.tableMinWidth, 13693 } }, 13694 createElement(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }), 13695 createElement(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
13695EventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint }))); 13696 }; 13697 TimeCols.prototype.componentDidMount = function () { 13698 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest); 13699 }; 13700 TimeCols.prototype.componentDidUpdate = function (prevProps) { 13701 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile); 13702 }; 13703 TimeCols.prototype.componentWillUnmount = function () { 13704 this.scrollResponder.detach(); 13705 }; 13706 TimeCols.prototype.queryHit = function (positionLeft, positionTop) { 13707 var _a = this.context, dateEnv = _a.dateEnv, options = _a.options; 13708 var colCoords = this.colCoords; 13709 var dateProfile = this.props.dateProfile; 13710 var slatCoords = this.state.slatCoords; 13711 var _b = this.processSlotOptions(this.props.slotDuration, options.snapDuration), snapDuration = _b.snapDuration, snapsPerSlot = _b.snapsPerSlot; 13712 var colIndex = colCoords.leftToIndex(positionLeft); 13713 var slatIndex = slatCoords.positions.topToIndex(positionTop); 13714 if (colIndex != null && slatIndex != null) { 13715 var cell = this.props.cells[colIndex]; 13716 var slatTop = slatCoords.positions.tops[slatIndex]; 13717 var slatHeight = slatCoords.positions.getHeight(slatIndex); 13718 var partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1 13719 var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat 13720 var snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 13721 var dayDate = this.props.cells[colIndex].date; 13722 var time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex)); 13723 var start = dateEnv.add(dayDate, time); 13724 var end = dateEnv.add(start, snapDuration); 13725 return { 13726 dateProfile: dateProfile, 13727 dateSpan: __assign({ range: { start: start, end: end }, allDay: false }, cell.extraDateSpan), 13728 dayEl: colCoords.els[colIndex], 13729 rect: { 13730 left: colCoords.lefts[colIndex], 13731 right: colCoords.rights[colIndex], 13732 top: slatTop, 13733 bottom: slatTop + slatHeight, 13734 }, 13735 layer: 0, 13736 }; 13737 } 13738 return null; 13739 }; 13740 return TimeCols; 13741 }(DateComponent)); 13742 function processSlotOptions(slotDuration, snapDurationOverride) { 13743 var snapDuration = snapDurationOverride || slotDuration; 13744 var snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 13745 if (snapsPerSlot === null) { 13746 snapDuration = slotDuration; 13747 snapsPerSlot = 1; 13748 // TODO: say warning? 13749 } 13750 return { snapDuration: snapDuration, snapsPerSlot: snapsPerSlot }; 13751 } 13752 13753 var DayTimeColsSlicer = /** @class */ (function (_super) { 13754 __extends(DayTimeColsSlicer, _super); 13755 function DayTimeColsSlicer() { 13756 return _super !== null && _super.apply(this, arguments) || this; 13757 } 13758 DayTimeColsSlicer.prototype.sliceRange = function (range, dayRanges) { 13759 var segs = []; 13760 for (var col = 0; col < dayRanges.length; col += 1) { 13761 var segRange = intersectRanges(range, dayRanges[col]); 13762 if (segRange) { 13763 segs.push({ 13764 start: segRange.start, 13765 end: segRange.end, 13766 isStart: segRange.start.valueOf() === range.start.valueOf(), 13767 isEnd: segRange.end.valueOf() === range.end.valueOf(), 13768 col: col, 13769 }); 13770 } 13771 } 13772 return segs; 13773 }; 13774 return DayTimeColsSlicer; 13775 }(Slicer)); 13776 13777 var DayTimeCols = /** @class */ (function (_super) { 13778 __extends(DayTimeCols, _super); 13779 function DayTimeCols() { 13780 var _this = _super !== null && _super.apply(this, arguments) || this; 13781 _this.buildDayRanges = memoize(buildDayRanges); 13782 _this.slicer = new DayTimeColsSlicer(); 13783 _this.timeColsRef = createRef(); 13784 return _this; 13785 } 13786 DayTimeCols.prototype.render = function () { 13787 var _this = this; 13788 var _a = this, props = _a.props, context = _a.context; 13789 var dateProfile = props.dateProfile, dayTableModel = props.dayTableModel; 13790 var isNowIndicator = context.options.nowIndicator; 13791 var dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv); 13792 // give it the first row of cells 13793 // TODO: would move this further down hierarchy, but sliceNowDate needs it 13794 return (createElement(NowTimer, { unit: isNowIndicator ? 'minute' : 'day' }, function (nowDate, todayRange) { return (createElement(TimeCols, __assign({ ref: _this.timeColsRef }, _this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: n
13794owDate, nowIndicatorSegs: isNowIndicator && _this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); })); 13795 }; 13796 return DayTimeCols; 13797 }(DateComponent)); 13798 function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 13799 var ranges = []; 13800 for (var _i = 0, _a = dayTableModel.headerDates; _i < _a.length; _i++) { 13801 var date = _a[_i]; 13802 ranges.push({ 13803 start: dateEnv.add(date, dateProfile.slotMinTime), 13804 end: dateEnv.add(date, dateProfile.slotMaxTime), 13805 }); 13806 } 13807 return ranges; 13808 } 13809 13810 // potential nice values for the slot-duration and interval-duration 13811 // from largest to smallest 13812 var STOCK_SUB_DURATIONS = [ 13813 { hours: 1 }, 13814 { minutes: 30 }, 13815 { minutes: 15 }, 13816 { seconds: 30 }, 13817 { seconds: 15 }, 13818 ]; 13819 function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) { 13820 var dayStart = new Date(0); 13821 var slatTime = slotMinTime; 13822 var slatIterator = createDuration(0); 13823 var labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration); 13824 var metas = []; 13825 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 13826 var date = dateEnv.add(dayStart, slatTime); 13827 var isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null; 13828 metas.push({ 13829 date: date, 13830 time: slatTime, 13831 key: date.toISOString(), 13832 isoTimeStr: formatIsoTimeString(date), 13833 isLabeled: isLabeled, 13834 }); 13835 slatTime = addDurations(slatTime, slotDuration); 13836 slatIterator = addDurations(slatIterator, slotDuration); 13837 } 13838 return metas; 13839 } 13840 // Computes an automatic value for slotLabelInterval 13841 function computeLabelInterval(slotDuration) { 13842 var i; 13843 var labelInterval; 13844 var slotsPerLabel; 13845 // find the smallest stock label interval that results in more than one slots-per-label 13846 for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) { 13847 labelInterval = createDuration(STOCK_SUB_DURATIONS[i]); 13848 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration);
13849 if (slotsPerLabel !== null && slotsPerLabel > 1) { 13850 return labelInterval; 13851 } 13852 } 13853 return slotDuration; // fall back 13854 } 13855 13856 var DayTimeColsView = /** @class */ (function (_super) { 13857 __extends(DayTimeColsView, _super); 13858 function DayTimeColsView() { 13859 var _this = _super !== null && _super.apply(this, arguments) || this; 13860 _this.buildTimeColsModel = memoize(buildTimeColsModel); 13861 _this.buildSlatMetas = memoize(buildSlatMetas); 13862 return _this; 13863 } 13864 DayTimeColsView.prototype.render = function () { 13865 var _this = this; 13866 var _a = this.context, options = _a.options, dateEnv = _a.dateEnv, dateProfileGenerator = _a.dateProfileGenerator; 13867 var props = this.props; 13868 var dateProfile = props.dateProfile; 13869 var dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator); 13870 var splitProps = this.allDaySplitter.splitProps(props); 13871 var slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv); 13872 var dayMinWidth = options.dayMinWidth; 13873 var hasAttachedAxis = !dayMinWidth; 13874 var hasDetachedAxis = dayMinWidth; 13875 var headerContent = options.dayHeaders && (createElement(DayHeader, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null })); 13876 var allDayContent = (options.allDaySlot !== false) && (function (contentArg) { return (createElement(DayTable, __assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? _this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: _this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, _this.getAllDayMaxEventProps()))); }); 13877 var timeGridContent = function (contentArg) { return (createElement(DayTimeCols, __assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: _this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: _this.handleScrollTopRequest }))); }; 13878 return hasDetachedAxis 13879 ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) 13880 : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent); 13881 }; 13882 return DayTimeColsView; 13883 }(TimeColsView));
13884 function buildTimeColsModel(dateProfile, dateProfileGenerator) { 13885 var daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 13886 return new DayTableModel(daySeries, false); 13887 } 13888 13889 var OPTION_REFINERS$2 = { 13890 allDaySlot: Boolean, 13891 }; 13892 13893 var timeGridPlugin = createPlugin({ 13894 initialView: 'timeGridWeek', 13895 optionRefiners: OPTION_REFINERS$2, 13896 views: { 13897 timeGrid: { 13898 component: DayTimeColsView, 13899 usesMinMaxTime: true, 13900 allDaySlot: true, 13901 slotDuration: '00:30:00', 13902 slotEventOverlap: true, // a bad name. confused with overlap/constraint system 13903 }, 13904 timeGridDay: { 13905 type: 'timeGrid', 13906 duration: { days: 1 }, 13907 }, 13908 timeGridWeek: { 13909 type: 'timeGrid', 13910 duration: { weeks: 1 }, 13911 }, 13912 }, 13913 }); 13914 13915 var ListViewHeaderRow = /** @class */ (function (_super) { 13916 __extends(ListViewHeaderRow, _super); 13917 function ListViewHeaderRow() { 13918 return _super !== null && _super.apply(this, arguments) || this; 13919 } 13920 ListViewHeaderRow.prototype.render = function () { 13921 var _a = this.props, dayDate = _a.dayDate, todayRange = _a.todayRange; 13922 var _b = this.context, theme = _b.theme, dateEnv = _b.dateEnv, options = _b.options, viewApi = _b.viewApi; 13923 var dayMeta = getDateMeta(dayDate, todayRange); 13924 // will ever be falsy? 13925 var text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : ''; 13926 // will ever be falsy? also, BAD NAME "alt" 13927 var sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : ''; 13928 var navLinkData = options.navLinks 13929 ? buildNavLinkData(dayDate) 13930 : null; 13931 var hookProps = __assign({ date: dateEnv.toDate(dayDate), view: viewApi, text: text, 13932 sideText: sideText, 13933 navLinkData: navLinkData }, dayMeta); 13934 var classNames = ['fc-list-day'].concat(getDayClassNames(dayMeta, theme)); 13935 // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too) 13936 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.dayHeaderClassNames, content: options.dayHeaderContent, defaultContent: renderInnerContent, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, function (rootElRef, customClassNames, innerElRef, innerContent) { return (createElement("tr", { ref: rootElRef, className: classNames.concat(customClassNames).join(' '), "data-date": formatDayString(dayDate) }, 13937 createElement("th", { colSpan: 3 }, 13938 createElement("div", { className: 'fc-list-day-cushion ' + theme.getClass('tableCellShaded'), ref: innerElRef }, innerContent)))); })); 13939 }; 13940 return ListViewHeaderRow; 13941 }(BaseComponent)); 13942 function renderInnerContent(props) { 13943 var navLinkAttrs = props.navLinkData // is there a type for this? 13944 ? { 'data-navlink': props.navLinkData, tabIndex: 0 } 13945 : {}; 13946 return (createElement(Fragment, null, 13947 props.text && (createElement("a", __assign({ className: "fc-list-day-text" }, navLinkAttrs), props.text)), 13948 props.sideText && (createElement("a", __assign({ className: "fc-list-day-side-text" }, navLinkAttrs), props.sideText)))); 13949 } 13950 13951 var DEFAULT_TIME_FORMAT = createFormatter({ 13952 hour: 'numeric', 13953 minute: '2-digit', 13954 meridiem: 'short', 13955 }); 13956 var ListViewEventRow = /** @class */ (function (_super) { 13957 __extends(ListViewEventRow, _super); 13958 function ListViewEventRow() { 13959 return _super !== null && _super.apply(this, arguments) || this; 13960 } 13961 ListViewEventRow.prototype.render = function () { 13962 var _a = this, props = _a.props, context = _a.context; 13963 var seg = props.seg; 13964 var timeFormat = context.options.eventTimeFormat || DEFAULT_TIME_FORMAT; 13965 return (createElement(EventRoot, { seg: seg, timeText: "" // BAD. because of all-day content 13966 , disableDragging: true, disableResizing: true, defaultContent: renderEventInnerContent, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, isSelected: props.isSelected, isDragging: props.isDragging, isResizing: props.isResizing, isDateSelecting: props.isDateSelecting }, function (rootElRef, classNames, innerElRef, innerContent, hookProps) { return (createElement("tr", { className: ['fc-list-event', hookProps.event.url ? 'fc-event-forced-url' : ''].concat(classNames).join(' '), ref: rootElRef }, 13967 buildTimeContent(seg, timeFormat, context), 13968 createElement("td", { className: "fc-list-event-graphic" }, 13969 createElement("span", { className: "fc-list-event-dot", style: { borderColor: hookProps.borderColor || hookProps.backgroundColor } })), 13970 createElement("td", { className: "fc-list-event-title", ref: innerElRef }, innerContent))); })); 13971 }; 13972 return ListViewEventRow; 13973 }(BaseComponent)); 13974 function renderEventInnerContent(props) { 13975 var event = props.event; 13976 var url = event.url; 13977 var anchorAttrs = url ? { href: url } : {}; 13978 return (createElement("a", __assign({}, anchorAttrs), event.title)); 13979 } 13980 function buildTimeContent(seg, timeFormat, context) { 13981 var options = context.options; 13982 if (options.displayEventTime !== false) { 13983 var eventDef = seg.eventRange.def; 13984 var eventInstance = seg.eventRange.instance; 13985 var doAllDay = false;
13986 var timeText = void 0; 13987 if (eventDef.allDay) { 13988 doAllDay = true; 13989 } 13990 else if (isMultiDayRange(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead? 13991 if (seg.isStart) { 13992 timeText = buildSegTimeText(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end); 13993 } 13994 else if (seg.isEnd) { 13995 timeText = buildSegTimeText(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end); 13996 } 13997 else { 13998 doAllDay = true; 13999 } 14000 } 14001 else { 14002 timeText = buildSegTimeText(seg, timeFormat, context); 14003 } 14004 if (doAllDay) { 14005 var hookProps = { 14006 text: context.options.allDayText, 14007 view: context.viewApi, 14008 }; 14009 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.allDayClassNames, content: options.allDayContent, defaultContent: renderAllDayInner, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("td", { className: ['fc-list-event-time'].concat(classNames).join(' '), ref: rootElRef }, innerContent)); })); 14010 } 14011 return (createElement("td", { className: "fc-list-event-time" }, timeText)); 14012 } 14013 return null; 14014 } 14015 function renderAllDayInner(hookProps) { 14016 return hookProps.text; 14017 } 14018 14019 /* 14020 Responsible for the scroller, and forwarding event-related actions into the "grid". 14021 */ 14022 var ListView = /** @class */ (function (_super) { 14023 __extends(ListView, _super); 14024 function ListView() { 14025 var _this = _super !== null && _super.apply(this, arguments) || this; 14026 _this.computeDateVars = memoize(computeDateVars); 14027 _this.eventStoreToSegs = memoize(_this._eventStoreToSegs); 14028 _this.setRootEl = function (rootEl) { 14029 if (rootEl) { 14030 _this.context.registerInteractiveComponent(_this, { 14031 el: rootEl, 14032 }); 14033 } 14034 else { 14035 _this.context.unregisterInteractiveComponent(_this); 14036 } 14037 }; 14038 return _this; 14039 } 14040 ListView.prototype.render = function () { 14041 var _this = this; 14042 var _a = this, props = _a.props, context = _a.context; 14043 var extraClassNames = [ 14044 'fc-list', 14045 context.theme.getClass('table'), 14046 context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : '', 14047 ]; 14048 var _b = this.computeDateVars(props.dateProfile), dayDates = _b.dayDates, dayRanges = _b.dayRanges; 14049 var eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges); 14050 return (createElement(ViewRoot, { viewSpec: context.viewSpec, elRef: this.setRootEl }, function (rootElRef, classNames) { return (createElement("div", { ref: rootElRef, className: extraClassNames.concat(classNames).join(' ') }, 14051 createElement(Scroller, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ? 14052 _this.renderSegList(eventSegs, dayDates) : 14053 _this.renderEmptyMessage()))); })); 14054 }; 14055 ListView.prototype.renderEmptyMessage = function () { 14056 var _a = this.context, options = _a.options, viewApi = _a.viewApi; 14057 var hookProps = { 14058 text: options.noEventsText, 14059 view: viewApi, 14060 }; 14061 return (createElement(RenderHook, { hookProps: hookProps, classNames: options.noEventsClassNames, content: options.noEventsContent, defaultContent: renderNoEventsInner, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, function (rootElRef, classNames, innerElRef, innerContent) { return (createElement("div", { className: ['fc-list-empty'].concat(classNames).join(' '), ref: rootElRef }, 14062 createElement("div", { className: "fc-list-empty-cushion", ref: innerElRef }, innerContent))); })); 14063 }; 14064 ListView.prototype.renderSegList = function (allSegs, dayDates) { 14065 var _a = this.context, theme = _a.theme, options = _a.options; 14066 var segsByDay = groupSegsByDay(allSegs); // sparse array 14067 return (createElement(NowTimer, { unit: "day" }, function (nowDate, todayRange) { 14068 var innerNodes = []; 14069 for (var dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) { 14070 var daySegs = segsByDay[dayIndex]; 14071 if (daySegs) { // sparse array, so might be undefined 14072 var dayStr = dayDates[dayIndex].toISOString(); 14073 // append a day header 14074 innerNodes.push(createElement(ListViewHeaderRow, { key: dayStr, dayDate: dayDates[dayIndex], todayRange: todayRange })); 14075 daySegs = sortEventSegs(daySegs, options.eventOrder);
14076 for (var _i = 0, daySegs_1 = daySegs; _i < daySegs_1.length; _i++) { 14077 var seg = daySegs_1[_i]; 14078 innerNodes.push(createElement(ListViewEventRow, __assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false }, getSegMeta(seg, todayRange, nowDate)))); 14079 } 14080 } 14081 } 14082 return (createElement("table", { className: 'fc-list-table ' + theme.getClass('table') }, 14083 createElement("tbody", null, innerNodes))); 14084 })); 14085 }; 14086 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 14087 return this.eventRangesToSegs(sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges); 14088 }; 14089 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 14090 var segs = []; 14091 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 14092 var eventRange = eventRanges_1[_i]; 14093 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 14094 } 14095 return segs; 14096 }; 14097 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 14098 var dateEnv = this.context.dateEnv; 14099 var nextDayThreshold = this.context.options.nextDayThreshold; 14100 var range = eventRange.range; 14101 var allDay = eventRange.def.allDay; 14102 var dayIndex; 14103 var segRange; 14104 var seg; 14105 var segs = []; 14106 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) { 14107 segRange = intersectRanges(range, dayRanges[dayIndex]); 14108 if (segRange) { 14109 seg = { 14110 component: this, 14111 eventRange: eventRange, 14112 start: segRange.start, 14113 end: segRange.end, 14114 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 14115 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 14116 dayIndex: dayIndex, 14117 }; 14118 segs.push(seg); 14119 // detect when range won't go fully into the next day, 14120 // and mutate the latest seg to the be the end. 14121 if (!seg.isEnd && !allDay && 14122 dayIndex + 1 < dayRanges.length && 14123 range.end < 14124 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 14125 seg.end = range.end; 14126 seg.isEnd = true; 14127 break; 14128 } 14129 } 14130 } 14131 return segs; 14132 }; 14133 return ListView; 14134 }(DateComponent)); 14135 function renderNoEventsInner(hookProps) { 14136 return hookProps.text; 14137 } 14138 function computeDateVars(dateProfile) { 14139 var dayStart = startOfDay(dateProfile.renderRange.start); 14140 var viewEnd = dateProfile.renderRange.end; 14141 var dayDates = []; 14142 var dayRanges = []; 14143 while (dayStart < viewEnd) { 14144 dayDates.push(dayStart); 14145 dayRanges.push({ 14146 start: dayStart, 14147 end: addDays(dayStart, 1), 14148 }); 14149 dayStart = addDays(dayStart, 1); 14150 } 14151 return { dayDates: dayDates, dayRanges: dayRanges }; 14152 } 14153 // Returns a sparse array of arrays, segs grouped by their dayIndex 14154 function groupSegsByDay(segs) { 14155 var segsByDay = []; // sparse array 14156 var i; 14157 var seg; 14158 for (i = 0; i < segs.length; i += 1) { 14159 seg = segs[i]; 14160 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 14161 .push(seg); 14162 } 14163 return segsByDay; 14164 } 14165 14166 var OPTION_REFINERS$1 = { 14167 listDayFormat: createFalsableFormatter, 14168 listDaySideFormat: createFalsableFormatter, 14169 noEventsClassNames: identity, 14170 noEventsContent: identity, 14171 noEventsDidMount: identity, 14172 noEventsWillUnmount: identity, 14173 // noEventsText is defined in base options 14174 }; 14175 function createFalsableFormatter(input) { 14176 return input === false ? null : createFormatter(input); 14177 } 14178 14179 var listPlugin = createPlugin({ 14180 optionRefiners: OPTION_REFINERS$1, 14181 views: { 14182 list: { 14183 component: ListView, 14184 buttonTextKey: 'list', 14185 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like "January 1, 2016" 14186 }, 14187 listDay: { 14188 type: 'list', 14189 duration: { days: 1 }, 14190 listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar 14191 }, 14192 listWeek: { 14193 type: 'list', 14194 duration: { weeks: 1 }, 14195 listDayFormat: { weekday: 'long' }, 14196 listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' }, 14197 }, 14198 listMonth: { 14199 type: 'list', 14200 duration: { month: 1 }, 14201 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14202 }, 14203 listYear: { 14204 type: 'list', 14205 duration: { year: 1 }, 14206 listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have 14207 }, 14208 }, 14209 }); 14210 14211 var BootstrapTheme = /** @class */ (function (_super) { 14212 __extends(BootstrapTheme, _super); 14213 function BootstrapTheme() { 14214 return _super !== null && _super.apply(this, arguments) || this; 14215 } 14216 return BootstrapTheme; 14217 }(Theme)); 14218 BootstrapTheme.prototype.classes = { 14219 root: 'fc-theme-bootstrap', 14220 table: 'table-bordered', 14221 tableCellShaded: 'table-active', 14222 buttonGroup: 'btn-group', 14223 button: 'btn btn-primary', 14224 buttonActive: 'active', 14225 popover: 'popover', 14226 popoverHeader: 'popover-header', 14227 popoverContent: 'popover-body', 14228 }; 14229 BootstrapTheme.prototype.baseIconClass = 'fa'; 14230 BootstrapTheme.prototype.iconClasses = { 14231 close: 'fa-times', 14232 prev: 'fa-chevron-left', 14233 next: 'fa-chevron-right', 14234 prevYear: 'fa-angle-double-left', 14235 nextYear: 'fa-angle-double-right', 14236 }; 14237 BootstrapTheme.prototype.rtlIconClasses = { 14238 prev: 'fa-chevron-right', 14239 next: 'fa-chevron-left', 14240 prevYear: 'fa-angle-double-right', 14241 nextYear: 'fa-angle-double-left', 14242 }; 14243 BootstrapTheme.prototype.iconOverrideOption = 'bootstrapFontAwesome';
14243 // TODO: make TS-friendly. move the option-processing into this plugin 14244 BootstrapTheme.prototype.iconOverrideCustomButtonOption = 'bootstrapFontAwesome'; 14245 BootstrapTheme.prototype.iconOverridePrefix = 'fa-'; 14246 var plugin = createPlugin({ 14247 themeClasses: { 14248 bootstrap: BootstrapTheme, 14249 }, 14250 }); 14251 14252 // rename this file to options.ts like other packages? 14253 var OPTION_REFINERS = { 14254 googleCalendarApiKey: String, 14255 }; 14256 14257 var EVENT_SOURCE_REFINERS = { 14258 googleCalendarApiKey: String, 14259 googleCalendarId: String, 14260 googleCalendarApiBase: String, 14261 extraParams: identity, 14262 }; 14263 14264 // TODO: expose somehow 14265 var API_BASE = 'https://www.googleapis.com/calendar/v3/calendars'; 14266 var eventSourceDef = { 14267 parseMeta: function (refined) { 14268 var googleCalendarId = refined.googleCalendarId; 14269 if (!googleCalendarId && refined.url) { 14270 googleCalendarId = parseGoogleCalendarId(refined.url); 14271 } 14272 if (googleCalendarId) { 14273 return { 14274 googleCalendarId: googleCalendarId, 14275 googleCalendarApiKey: refined.googleCalendarApiKey, 14276 googleCalendarApiBase: refined.googleCalendarApiBase, 14277 extraParams: refined.extraParams, 14278 }; 14279 } 14280 return null; 14281 }, 14282 fetch: function (arg, onSuccess, onFailure) { 14283 var _a = arg.context, dateEnv = _a.dateEnv, options = _a.options; 14284 var meta = arg.eventSource.meta; 14285 var apiKey = meta.googleCalendarApiKey || options.googleCalendarApiKey; 14286 if (!apiKey) { 14287 onFailure({ 14288 message: 'Specify a googleCalendarApiKey. See http://fullcalendar.io/docs/google_calendar/', 14289 }); 14290 } 14291 else { 14292 var url = buildUrl(meta); 14293 // TODO: make DRY with json-feed-event-source 14294 var extraParams = meta.extraParams; 14295 var extraParamsObj = typeof extraParams === 'function' ? extraParams() : extraParams; 14296 var requestParams_1 = buildRequestParams(arg.range, apiKey, extraParamsObj, dateEnv); 14297 requestJson('GET', url, requestParams_1, function (body, xhr) { 14298 if (body.error) { 14299 onFailure({ 14300 message: 'Google Calendar API: ' + body.error.message, 14301 errors: body.error.errors, 14302 xhr: xhr, 14303 }); 14304 } 14305 else { 14306 onSuccess({ 14307 rawEvents: gcalItemsToRawEventDefs(body.items, requestParams_1.timeZone), 14308 xhr: xhr, 14309 }); 14310 } 14311 }, function (message, xhr) { 14312 onFailure({ message: message, xhr: xhr }); 14313 }); 14314 } 14315 }, 14316 }; 14317 function parseGoogleCalendarId(url) { 14318 var match; 14319 // detect if the ID was specified as a single string. 14320 // will match calendars like "[email protected]" in addition to person email calendars. 14321 if (/^[^/]+@([^/.]+\.)*(google|googlemail|gmail)\.com$/.test(url)) { 14322 return url; 14323 } 14324 if ((match = /^https:\/\/www.googleapis.com\/calendar\/v3\/calendars\/([^/]*)/.exec(url)) || 14325 (match = /^https?:\/\/www.google.com\/calendar\/feeds\/([^/]*)/.exec(url))) { 14326 return decodeURIComponent(match[1]); 14327 } 14328 return null; 14329 } 14330 function buildUrl(meta) { 14331 var apiBase = meta.googleCalendarApiBase; 14332 if (!apiBase) { 14333 apiBase = API_BASE; 14334 } 14335 return apiBase + '/' + encodeURIComponent(meta.googleCalendarId) + '/events'; 14336 } 14337 function buildRequestParams(range, apiKey, extraParams, dateEnv) { 14338 var params; 14339 var startStr; 14340 var endStr; 14341 if (dateEnv.canComputeOffset) { 14342 // strings will naturally have offsets, which GCal needs 14343 startStr = dateEnv.formatIso(range.start); 14344 endStr = dateEnv.formatIso(range.end); 14345 } 14346 else {
14347 // when timezone isn't known, we don't know what the UTC offset should be, so ask for +/- 1 day 14348 // from the UTC day-start to guarantee we're getting all the events 14349 // (start/end will be UTC-coerced dates, so toISOString is okay) 14350 startStr = addDays(range.start, -1).toISOString(); 14351 endStr = addDays(range.end, 1).toISOString(); 14352 } 14353 params = __assign(__assign({}, (extraParams || {})), { key: apiKey, timeMin: startStr, timeMax: endStr, singleEvents: true, maxResults: 9999 }); 14354 if (dateEnv.timeZone !== 'local') { 14355 params.timeZone = dateEnv.timeZone; 14356 } 14357 return params; 14358 } 14359 function gcalItemsToRawEventDefs(items, gcalTimezone) { 14360 return items.map(function (item) { return gcalItemToRawEventDef(item, gcalTimezone); }); 14361 } 14362 function gcalItemToRawEventDef(item, gcalTimezone) { 14363 var url = item.htmlLink || null; 14364 // make the URLs for each event show times in the correct timezone 14365 if (url && gcalTimezone) { 14366 url = injectQsComponent(url, 'ctz=' + gcalTimezone); 14367 } 14368 return { 14369 id: item.id, 14370 title: item.summary, 14371 start: item.start.dateTime || item.start.date, 14372 end: item.end.dateTime || item.end.date, 14373 url: url, 14374 location: item.location, 14375 description: item.description, 14376 attachments: item.attachments || [], 14377 extendedProps: (item.extendedProperties || {}).shared || {}, 14378 }; 14379 } 14380 // Injects a string like "arg=value" into the querystring of a URL 14381 // TODO: move to a general util file? 14382 function injectQsComponent(url, component) { 14383 // inject it after the querystring but before the fragment 14384 return url.replace(/(\?.*?)?(#|$)/, function (whole, qs, hash) { return (qs ? qs + '&' : '?') + component + hash; }); 14385 } 14386 var googleCalendarPlugin = createPlugin({ 14387 eventSourceDefs: [eventSourceDef], 14388 optionRefiners: OPTION_REFINERS, 14389 eventSourceRefiners: EVENT_SOURCE_REFINERS, 14390 }); 14391 14392 globalPlugins.push(interactionPlugin, dayGridPlugin, timeGridPlugin, listPlugin, plugin, googleCalendarPlugin); 14393 14394 exports.BASE_OPTION_DEFAULTS = BASE_OPTION_DEFAULTS; 14395 exports.BASE_OPTION_REFINERS = BASE_OPTION_REFINERS; 14396 exports.BaseComponent = BaseComponent; 14397 exports.BgEvent = BgEvent; 14398 exports.BootstrapTheme = BootstrapTheme; 14399 exports.Calendar = Calendar; 14400 exports.CalendarApi = CalendarApi; 14401 exports.CalendarContent = CalendarContent; 14402 exports.CalendarDataManager = CalendarDataManager; 14403 exports.CalendarDataProvider = CalendarDataProvider; 14404 exports.CalendarRoot = CalendarRoot; 14405 exports.Component = Component; 14406 exports.ContentHook = ContentHook; 14407 exports.CustomContentRenderContext = CustomContentRenderContext; 14408 exports.DateComponent = DateComponent; 14409 exports.DateEnv = DateEnv; 14410 exports.DateProfileGenerator = DateProfileGenerator; 14411 exports.DayCellContent = DayCellContent; 14412 exports.DayCellRoot = DayCellRoot; 14413 exports.DayGridView = DayTableView; 14414 exports.DayHeader = DayHeader;
14415 exports.DaySeriesModel = DaySeriesModel; 14416 exports.DayTable = DayTable; 14417 exports.DayTableModel = DayTableModel; 14418 exports.DayTableSlicer = DayTableSlicer; 14419 exports.DayTimeCols = DayTimeCols; 14420 exports.DayTimeColsSlicer = DayTimeColsSlicer; 14421 exports.DayTimeColsView = DayTimeColsView; 14422 exports.DelayedRunner = DelayedRunner; 14423 exports.Draggable = ExternalDraggable; 14424 exports.ElementDragging = ElementDragging; 14425 exports.ElementScrollController = ElementScrollController; 14426 exports.Emitter = Emitter; 14427 exports.EventApi = EventApi; 14428 exports.EventRoot = EventRoot; 14429 exports.EventSourceApi = EventSourceApi; 14430 exports.FeaturefulElementDragging = FeaturefulElementDragging; 14431 exports.Fragment = Fragment; 14432 exports.Interaction = Interaction; 14433 exports.ListView = ListView; 14434 exports.MoreLinkRoot = MoreLinkRoot; 14435 exports.MountHook = MountHook; 14436 exports.NamedTimeZoneImpl = NamedTimeZoneImpl; 14437 exports.NowIndicatorRoot = NowIndicatorRoot; 14438 exports.NowTimer = NowTimer; 14439 exports.PointerDragging = PointerDragging; 14440 exports.PositionCache = PositionCache; 14441 exports.RefMap = RefMap; 14442 exports.RenderHook = RenderHook; 14443 exports.ScrollController = ScrollController; 14444 exports.ScrollResponder = ScrollResponder; 14445 exports.Scroller = Scroller; 14446 exports.SegHierarchy = SegHierarchy; 14447 exports.SimpleScrollGrid = SimpleScrollGrid; 14448 exports.Slicer = Slicer; 14449 exports.Splitter = Splitter; 14450 exports.StandardEvent = StandardEvent; 14451 exports.Table = Table; 14452 exports.TableDateCell = TableDateCell; 14453 exports.TableDowCell = TableDowCell; 14454 exports.TableView = TableView; 14455 exports.Theme = Theme; 14456 exports.ThirdPartyDraggable = ThirdPartyDraggable; 14457 exports.TimeCols = TimeCols; 14458 exports.TimeColsSlatsCoords = TimeColsSlatsCoords; 14459 exports.TimeColsView = TimeColsView; 14460 exports.ViewApi = ViewApi; 14461 exports.ViewContextType = ViewContextType; 14462 exports.ViewRoot = ViewRoot; 14463 exports.WeekNumberRoot = WeekNumberRoot; 14464 exports.WindowScrollController = WindowScrollController; 14465 exports.addDays = addDays; 14466 exports.addDurations = addDurations; 14467 exports.addMs = addMs; 14468 exports.addWeeks = addWeeks; 14469 exports.allowContextMenu = allowContextMenu; 14470 exports.allowSelection = allowSelection; 14471 exports.applyMutationToEventStore = applyMutationToEventStore; 14472 exports.applyStyle = applyStyle; 14473 exports.applyStyleProp = applyStyleProp; 14474 exports.asCleanDays = asCleanDays; 14475 exports.asRoughMinutes = asRoughMinutes; 14476 exports.asRoughMs = asRoughMs; 14477 exports.asRoughSeconds = asRoughSeconds; 14478 exports.binarySearch = binarySearch; 14479 exports.buildClassNameNormalizer = buildClassNameNormalizer; 14480 exports.buildDayRanges = buildDayRanges; 14481 exports.buildDayTableModel = buildDayTableModel; 14482 exports.buildEntryKey = buildEntryKey; 14483 exports.buildEventApis = buildEventApis; 14484 exports.buildEventRangeKey = buildEventRangeKey; 14485 exports.buildHashFromArray = buildHashFromArray; 14486 exports.buildIsoString = buildIsoString; 14487 exports.buildNavLinkData = buildNavLinkData; 14488 exports.buildSegCompareObj = buildSegCompareObj; 14489 exports.buildSegTimeText = buildSegTimeText; 14490 exports.buildSlatMetas = buildSlatMetas; 14491 exports.buildTimeColsModel = buildTimeColsModel; 14492 exports.collectFromHash = collectFromHash; 14493 exports.combineEventUis = combineEventUis; 14494 exports.compareByFieldSpec = compareByFieldSpec; 14495 exports.compareByFieldSpecs = compareByFieldSpecs; 14496 exports.compareNumbers = compareNumbers; 14497 exports.compareObjs = compareObjs; 14498 exports.computeEarliestSegStart = computeEarliestSegStart; 14499 exports.computeEdges = computeEdges; 14500 exports.computeFallbackHeaderFormat = computeFallbackHeaderFormat; 14501 exports.computeHeightAndMargins = computeHeightAndMargins; 14502 exports.computeInnerRect = computeInnerRect; 14503 exports.computeRect = computeRect; 14504 exports.computeSegDraggable = computeSegDraggable; 14505 exports.computeSegEndResizable = computeSegEndResizable; 14506 exports.computeSegStartResizable = computeSegStartResizable; 14507 exports.computeShrinkWidth = computeShrinkWidth; 14508 exports.computeSmallestCellWidth = computeSmallestCellWidth; 14509 exports.computeVisibleDayRange = computeVisibleDayRange; 14510 exports.config = config; 14511 exports.constrainPoint = constrainPoint; 14512 exports.createContext = createContext; 14513 exports.createDuration = createDuration; 14514 exports.createElement = createElement; 14515 exports.createEmptyEventStore = createEmptyEventStore; 14516 exports.createEventInstance = createEventInstance; 14517 exports.createEventUi = createEventUi; 14518 exports.createFormatter = createFormatter; 14519 exports.createPlugin = createPlugin; 14520 exports.createPortal = createPortal; 14521 exports.createRef = createRef; 14522 exports.diffDates = diffDates; 14523 exports.diffDayAndTime = diffDayAndTime; 14524 exports.diffDays = diffDays; 14525 exports.diffPoints = diffPoints; 14526 exports.diffWeeks = diffWeeks; 14527 exports.diffWholeDays = diffWholeDays; 14528 exports.diffWholeWeeks = diffWholeWeeks; 14529 exports.disableCursor = disableCursor; 14530 exports.elementClosest = elementClosest; 14531 exports.elementMatches = elementMatches; 14532 exports.enableCursor = enableCursor; 14533 exports.eventTupleToStore = eventTupleToStore; 14534 exports.filterEventStoreDefs = filterEventStoreDefs; 14535 exports.filterHash = filterHash; 14536 exports.findDirectChildren = findDirectChildren; 14537 exports.findElements = findElements; 14538 exports.flexibleCompare = flexibleCompare; 14539 exports.flushToDom = flushToDom; 14540 exports.formatDate = formatDate; 14541 exports.formatDayString = formatDayString; 14542 exports.formatIsoTimeString = formatIsoTimeString; 14543 exports.formatRange = formatRange; 14544 exports.getAllowYScrolling = getAllowYScrolling; 14545 exports.getCanVGrowWithinCell = getCanVGrowWithinCell; 14546 exports.getClippingParents = getClippingParents; 14547 exports.getDateMeta = getDateMeta; 14548 exports.getDayClassNames = getDayClassNames; 14549 exports.getDefaultEventEnd = getDefaultEventEnd; 14550 exports.getElSeg = getElSeg; 14551 exports.getEntrySpanEnd = getEntrySpanEnd; 14552 exports.getEventClassNames = getEventClassNames; 14553 exports.getIsRtlScrollbarOnLeft = getIsRtlScrollbarOnLeft; 14554 exports.getRectCenter = getRectCenter; 14555 exports.getRelevantEvents = getRelevantEvents; 14556 exports.getScrollGridClassNames = getScrollGridClassNames;
14557 exports.getScrollbarWidths = getScrollbarWidths; 14558 exports.getSectionClassNames = getSectionClassNames; 14559 exports.getSectionHasLiquidHeight = getSectionHasLiquidHeight; 14560 exports.getSegMeta = getSegMeta; 14561 exports.getSlotClassNames = getSlotClassNames; 14562 exports.getStickyFooterScrollbar = getStickyFooterScrollbar; 14563 exports.getStickyHeaderDates = getStickyHeaderDates; 14564 exports.getUnequalProps = getUnequalProps; 14565 exports.globalLocales = globalLocales; 14566 exports.globalPlugins = globalPlugins; 14567 exports.greatestDurationDenominator = greatestDurationDenominator; 14568 exports.groupIntersectingEntries = groupIntersectingEntries; 14569 exports.guid = guid; 14570 exports.hasBgRendering = hasBgRendering; 14571 exports.hasShrinkWidth = hasShrinkWidth; 14572 exports.identity = identity; 14573 exports.interactionSettingsStore = interactionSettingsStore; 14574 exports.interactionSettingsToStore = interactionSettingsToStore; 14575 exports.intersectRanges = intersectRanges; 14576 exports.intersectRects = intersectRects; 14577 exports.isArraysEqual = isArraysEqual; 14578 exports.isColPropsEqual = isColPropsEqual; 14579 exports.isDateSelectionValid = isDateSelectionValid; 14580 exports.isDateSpansEqual = isDateSpansEqual; 14581 exports.isInt = isInt; 14582 exports.isInteractionValid = isInteractionValid; 14583 exports.isMultiDayRange = isMultiDayRange; 14584 exports.isPropsEqual = isPropsEqual; 14585 exports.isPropsValid = isPropsValid; 14586 exports.isValidDate = isValidDate; 14587 exports.listenBySelector = listenBySelector; 14588 exports.mapHash = mapHash; 14589 exports.memoize = memoize; 14590 exports.memoizeArraylike = memoizeArraylike; 14591 exports.memoizeHashlike = memoizeHashlike; 14592 exports.memoizeObjArg = memoizeObjArg; 14593 exports.mergeEventStores = mergeEventStores; 14594 exports.multiplyDuration = multiplyDuration; 14595 exports.padStart = padStart; 14596 exports.parseBusinessHours = parseBusinessHours; 14597 exports.parseClassNames = parseClassNames; 14598 exports.parseDragMeta = parseDragMeta; 14599 exports.parseEventDef = parseEventDef; 14600 exports.parseFieldSpecs = parseFieldSpecs; 14601 exports.parseMarker = parse; 14602 exports.pointInsideRect = pointInsideRect; 14603 exports.preventContextMenu = preventContextMenu; 14604 exports.preventDefault = preventDefault; 14605 exports.preventSelection = preventSelection; 14606 exports.rangeContainsMarker = rangeContainsMarker; 14607 exports.rangeContainsRange = rangeContainsRange; 14608 exports.rangesEqual = rangesEqual; 14609 exports.rangesIntersect = rangesIntersect; 14610 exports.refineEventDef = refineEventDef; 14611 exports.refineProps = refineProps; 14612 exports.removeElement = removeElement; 14613 exports.removeExact = removeExact; 14614 exports.render = render; 14615 exports.renderChunkContent = renderChunkContent; 14616 exports.renderFill = renderFill; 14617 exports.renderMicroColGroup = renderMicroColGroup; 14618 exports.renderScrollShim = renderScrollShim; 14619 exports.requestJson = requestJson; 14620 exports.sanitizeShrinkWidth = sanitizeShrinkWidth; 14621 exports.setElSeg = setElSeg; 14622 exports.setRef = setRef; 14623 exports.sliceEventStore = sliceEventStore; 14624 exports.sliceEvents = sliceEvents; 14625 exports.sortEventSegs = sortEventSegs; 14626 exports.startOfDay = startOfDay; 14627 exports.translateRect = translateRect; 14628 exports.triggerDateSelect = triggerDateSelect; 14629 exports.unmountComponentAtNode = unmountComponentAtNode; 14630 exports.unpromisify = unpromisify; 14631 exports.version = version; 14632 exports.whenTransitionDone = whenTransitionDone; 14633 exports.wholeDivideDurations = wholeDivideDurations; 14634 14635 Object.defineProperty(exports, '__esModule', { value: true }); 14636 14637 return exports; 14638 14639}({}));
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.