main.js 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
  1. /*!
  2. FullCalendar Day Grid Plugin v4.3.0
  3. Docs & License: https://fullcalendar.io/
  4. (c) 2019 Adam Shaw
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@fullcalendar/core')) :
  8. typeof define === 'function' && define.amd ? define(['exports', '@fullcalendar/core'], factory) :
  9. (global = global || self, factory(global.FullCalendarDayGrid = {}, global.FullCalendar));
  10. }(this, function (exports, core) {
  11. 'use strict';
  12. /*! *****************************************************************************
  13. Copyright (c) Microsoft Corporation. All rights reserved.
  14. Licensed under the Apache License, Version 2.0 (the "License"); you may not use
  15. this file except in compliance with the License. You may obtain a copy of the
  16. License at http://www.apache.org/licenses/LICENSE-2.0
  17. THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18. KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
  19. WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
  20. MERCHANTABLITY OR NON-INFRINGEMENT.
  21. See the Apache Version 2.0 License for specific language governing permissions
  22. and limitations under the License.
  23. ***************************************************************************** */
  24. /* global Reflect, Promise */
  25. var extendStatics = function (d, b) {
  26. extendStatics = Object.setPrototypeOf ||
  27. ({__proto__: []} instanceof Array && function (d, b) {
  28. d.__proto__ = b;
  29. }) ||
  30. function (d, b) {
  31. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  32. };
  33. return extendStatics(d, b);
  34. };
  35. function __extends(d, b) {
  36. extendStatics(d, b);
  37. function __() {
  38. this.constructor = d;
  39. }
  40. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  41. }
  42. var __assign = function () {
  43. __assign = Object.assign || function __assign(t) {
  44. for (var s, i = 1, n = arguments.length; i < n; i++) {
  45. s = arguments[i];
  46. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
  47. }
  48. return t;
  49. };
  50. return __assign.apply(this, arguments);
  51. };
  52. var DayGridDateProfileGenerator = /** @class */ (function (_super) {
  53. __extends(DayGridDateProfileGenerator, _super);
  54. function DayGridDateProfileGenerator() {
  55. return _super !== null && _super.apply(this, arguments) || this;
  56. }
  57. // Computes the date range that will be rendered.
  58. DayGridDateProfileGenerator.prototype.buildRenderRange = function (currentRange, currentRangeUnit, isRangeAllDay) {
  59. var dateEnv = this.dateEnv;
  60. var renderRange = _super.prototype.buildRenderRange.call(this, currentRange, currentRangeUnit, isRangeAllDay);
  61. var start = renderRange.start;
  62. var end = renderRange.end;
  63. var endOfWeek;
  64. // year and month views should be aligned with weeks. this is already done for week
  65. if (/^(year|month)$/.test(currentRangeUnit)) {
  66. start = dateEnv.startOfWeek(start);
  67. // make end-of-week if not already
  68. endOfWeek = dateEnv.startOfWeek(end);
  69. if (endOfWeek.valueOf() !== end.valueOf()) {
  70. end = core.addWeeks(endOfWeek, 1);
  71. }
  72. }
  73. // ensure 6 weeks
  74. if (this.options.monthMode &&
  75. this.options.fixedWeekCount) {
  76. var rowCnt = Math.ceil(// could be partial weeks due to hiddenDays
  77. core.diffWeeks(start, end));
  78. end = core.addWeeks(end, 6 - rowCnt);
  79. }
  80. return {start: start, end: end};
  81. };
  82. return DayGridDateProfileGenerator;
  83. }(core.DateProfileGenerator));
  84. /* A rectangular panel that is absolutely positioned over other content
  85. ------------------------------------------------------------------------------------------------------------------------
  86. Options:
  87. - className (string)
  88. - content (HTML string, element, or element array)
  89. - parentEl
  90. - top
  91. - left
  92. - right (the x coord of where the right edge should be. not a "CSS" right)
  93. - autoHide (boolean)
  94. - show (callback)
  95. - hide (callback)
  96. */
  97. var Popover = /** @class */ (function () {
  98. function Popover(options) {
  99. var _this = this;
  100. this.isHidden = true;
  101. this.margin = 10; // the space required between the popover and the edges of the scroll container
  102. // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
  103. this.documentMousedown = function (ev) {
  104. // only hide the popover if the click happened outside the popover
  105. if (_this.el && !_this.el.contains(ev.target)) {
  106. _this.hide();
  107. }
  108. };
  109. this.options = options;
  110. }
  111. // Shows the popover on the specified position. Renders it if not already
  112. Popover.prototype.show = function () {
  113. if (this.isHidden) {
  114. if (!this.el) {
  115. this.render();
  116. }
  117. this.el.style.display = '';
  118. this.position();
  119. this.isHidden = false;
  120. this.trigger('show');
  121. }
  122. };
  123. // Hides the popover, through CSS, but does not remove it from the DOM
  124. Popover.prototype.hide = function () {
  125. if (!this.isHidden) {
  126. this.el.style.display = 'none';
  127. this.isHidden = true;
  128. this.trigger('hide');
  129. }
  130. };
  131. // Creates `this.el` and renders content inside of it
  132. Popover.prototype.render = function () {
  133. var _this = this;
  134. var options = this.options;
  135. var el = this.el = core.createElement('div', {
  136. className: 'fc-popover ' + (options.className || ''),
  137. style: {
  138. top: '0',
  139. left: '0'
  140. }
  141. });
  142. if (typeof options.content === 'function') {
  143. options.content(el);
  144. }
  145. options.parentEl.appendChild(el);
  146. // when a click happens on anything inside with a 'fc-close' className, hide the popover
  147. core.listenBySelector(el, 'click', '.fc-close', function (ev) {
  148. _this.hide();
  149. });
  150. if (options.autoHide) {
  151. document.addEventListener('mousedown', this.documentMousedown);
  152. }
  153. };
  154. // Hides and unregisters any handlers
  155. Popover.prototype.destroy = function () {
  156. this.hide();
  157. if (this.el) {
  158. core.removeElement(this.el);
  159. this.el = null;
  160. }
  161. document.removeEventListener('mousedown', this.documentMousedown);
  162. };
  163. // Positions the popover optimally, using the top/left/right options
  164. Popover.prototype.position = function () {
  165. var options = this.options;
  166. var el = this.el;
  167. var elDims = el.getBoundingClientRect(); // only used for width,height
  168. var origin = core.computeRect(el.offsetParent);
  169. var clippingRect = core.computeClippingRect(options.parentEl);
  170. var top; // the "position" (not "offset") values for the popover
  171. var left; //
  172. // compute top and left
  173. top = options.top || 0;
  174. if (options.left !== undefined) {
  175. left = options.left;
  176. } else if (options.right !== undefined) {
  177. left = options.right - elDims.width; // derive the left value from the right value
  178. } else {
  179. left = 0;
  180. }
  181. // constrain to the view port. if constrained by two edges, give precedence to top/left
  182. top = Math.min(top, clippingRect.bottom - elDims.height - this.margin);
  183. top = Math.max(top, clippingRect.top + this.margin);
  184. left = Math.min(left, clippingRect.right - elDims.width - this.margin);
  185. left = Math.max(left, clippingRect.left + this.margin);
  186. core.applyStyle(el, {
  187. top: top - origin.top,
  188. left: left - origin.left
  189. });
  190. };
  191. // Triggers a callback. Calls a function in the option hash of the same name.
  192. // Arguments beyond the first `name` are forwarded on.
  193. // TODO: better code reuse for this. Repeat code
  194. // can kill this???
  195. Popover.prototype.trigger = function (name) {
  196. if (this.options[name]) {
  197. this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
  198. }
  199. };
  200. return Popover;
  201. }());
  202. /* Event-rendering methods for the DayGrid class
  203. ----------------------------------------------------------------------------------------------------------------------*/
  204. // "Simple" is bad a name. has nothing to do with SimpleDayGrid
  205. var SimpleDayGridEventRenderer = /** @class */ (function (_super) {
  206. __extends(SimpleDayGridEventRenderer, _super);
  207. function SimpleDayGridEventRenderer() {
  208. return _super !== null && _super.apply(this, arguments) || this;
  209. }
  210. // Builds the HTML to be used for the default element for an individual segment
  211. SimpleDayGridEventRenderer.prototype.renderSegHtml = function (seg, mirrorInfo) {
  212. var _a = this.context, view = _a.view, options = _a.options;
  213. var eventRange = seg.eventRange;
  214. var eventDef = eventRange.def;
  215. var eventUi = eventRange.ui;
  216. var allDay = eventDef.allDay;
  217. var isDraggable = view.computeEventDraggable(eventDef, eventUi);
  218. var isResizableFromStart = allDay && seg.isStart && view.computeEventStartResizable(eventDef, eventUi);
  219. var isResizableFromEnd = allDay && seg.isEnd && view.computeEventEndResizable(eventDef, eventUi);
  220. var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd, mirrorInfo);
  221. var skinCss = core.cssToStr(this.getSkinCss(eventUi));
  222. var timeHtml = '';
  223. var timeText;
  224. var titleHtml;
  225. classes.unshift('fc-day-grid-event', 'fc-h-event');
  226. // Only display a timed events time if it is the starting segment
  227. if (seg.isStart) {
  228. timeText = this.getTimeText(eventRange);
  229. if (timeText) {
  230. timeHtml = '<span class="fc-time">' + core.htmlEscape(timeText) + '</span>';
  231. }
  232. }
  233. titleHtml =
  234. '<span class="fc-title">' +
  235. (core.htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
  236. '</span>';
  237. return '<a class="' + classes.join(' ') + '"' +
  238. (eventDef.url ?
  239. ' href="' + core.htmlEscape(eventDef.url) + '"' :
  240. '') +
  241. (skinCss ?
  242. ' style="' + skinCss + '"' :
  243. '') +
  244. '>' +
  245. '<div class="fc-content">' +
  246. (options.dir === 'rtl' ?
  247. titleHtml + ' ' + timeHtml : // put a natural space in between
  248. timeHtml + ' ' + titleHtml //
  249. ) +
  250. '</div>' +
  251. (isResizableFromStart ?
  252. '<div class="fc-resizer fc-start-resizer"></div>' :
  253. '') +
  254. (isResizableFromEnd ?
  255. '<div class="fc-resizer fc-end-resizer"></div>' :
  256. '') +
  257. '</a>';
  258. };
  259. // Computes a default event time formatting string if `eventTimeFormat` is not explicitly defined
  260. SimpleDayGridEventRenderer.prototype.computeEventTimeFormat = function () {
  261. return {
  262. hour: 'numeric',
  263. minute: '2-digit',
  264. omitZeroMinute: true,
  265. meridiem: 'narrow'
  266. };
  267. };
  268. SimpleDayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
  269. return false; // TODO: somehow consider the originating DayGrid's column count
  270. };
  271. return SimpleDayGridEventRenderer;
  272. }(core.FgEventRenderer));
  273. /* Event-rendering methods for the DayGrid class
  274. ----------------------------------------------------------------------------------------------------------------------*/
  275. var DayGridEventRenderer = /** @class */ (function (_super) {
  276. __extends(DayGridEventRenderer, _super);
  277. function DayGridEventRenderer(dayGrid) {
  278. var _this = _super.call(this, dayGrid.context) || this;
  279. _this.dayGrid = dayGrid;
  280. return _this;
  281. }
  282. // Renders the given foreground event segments onto the grid
  283. DayGridEventRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
  284. var rowStructs = this.rowStructs = this.renderSegRows(segs);
  285. // append to each row's content skeleton
  286. this.dayGrid.rowEls.forEach(function (rowNode, i) {
  287. rowNode.querySelector('.fc-content-skeleton > table').appendChild(rowStructs[i].tbodyEl);
  288. });
  289. // removes the "more.." events popover
  290. if (!mirrorInfo) {
  291. this.dayGrid.removeSegPopover();
  292. }
  293. };
  294. // Unrenders all currently rendered foreground event segments
  295. DayGridEventRenderer.prototype.detachSegs = function () {
  296. var rowStructs = this.rowStructs || [];
  297. var rowStruct;
  298. while ((rowStruct = rowStructs.pop())) {
  299. core.removeElement(rowStruct.tbodyEl);
  300. }
  301. this.rowStructs = null;
  302. };
  303. // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
  304. // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
  305. // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
  306. DayGridEventRenderer.prototype.renderSegRows = function (segs) {
  307. var rowStructs = [];
  308. var segRows;
  309. var row;
  310. segRows = this.groupSegRows(segs); // group into nested arrays
  311. // iterate each row of segment groupings
  312. for (row = 0; row < segRows.length; row++) {
  313. rowStructs.push(this.renderSegRow(row, segRows[row]));
  314. }
  315. return rowStructs;
  316. };
  317. // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
  318. // the segments. Returns object with a bunch of internal data about how the render was calculated.
  319. // NOTE: modifies rowSegs
  320. DayGridEventRenderer.prototype.renderSegRow = function (row, rowSegs) {
  321. var dayGrid = this.dayGrid;
  322. var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
  323. var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
  324. var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
  325. var tbody = document.createElement('tbody');
  326. var segMatrix = []; // lookup for which segments are rendered into which level+col cells
  327. var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
  328. var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
  329. var i;
  330. var levelSegs;
  331. var col;
  332. var tr;
  333. var j;
  334. var seg;
  335. var td;
  336. // populates empty cells from the current column (`col`) to `endCol`
  337. function emptyCellsUntil(endCol) {
  338. while (col < endCol) {
  339. // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
  340. td = (loneCellMatrix[i - 1] || [])[col];
  341. if (td) {
  342. td.rowSpan = (td.rowSpan || 1) + 1;
  343. } else {
  344. td = document.createElement('td');
  345. tr.appendChild(td);
  346. }
  347. cellMatrix[i][col] = td;
  348. loneCellMatrix[i][col] = td;
  349. col++;
  350. }
  351. }
  352. for (i = 0; i < levelCnt; i++) { // iterate through all levels
  353. levelSegs = segLevels[i];
  354. col = 0;
  355. tr = document.createElement('tr');
  356. segMatrix.push([]);
  357. cellMatrix.push([]);
  358. loneCellMatrix.push([]);
  359. // levelCnt might be 1 even though there are no actual levels. protect against this.
  360. // this single empty row is useful for styling.
  361. if (levelSegs) {
  362. for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
  363. seg = levelSegs[j];
  364. var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
  365. var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
  366. emptyCellsUntil(leftCol);
  367. // create a container that occupies or more columns. append the event element.
  368. td = core.createElement('td', {className: 'fc-event-container'}, seg.el);
  369. if (leftCol !== rightCol) {
  370. td.colSpan = rightCol - leftCol + 1;
  371. } else { // a single-column segment
  372. loneCellMatrix[i][col] = td;
  373. }
  374. while (col <= rightCol) {
  375. cellMatrix[i][col] = td;
  376. segMatrix[i][col] = seg;
  377. col++;
  378. }
  379. tr.appendChild(td);
  380. }
  381. }
  382. emptyCellsUntil(colCnt); // finish off the row
  383. var introHtml = dayGrid.renderProps.renderIntroHtml();
  384. if (introHtml) {
  385. if (dayGrid.isRtl) {
  386. core.appendToElement(tr, introHtml);
  387. } else {
  388. core.prependToElement(tr, introHtml);
  389. }
  390. }
  391. tbody.appendChild(tr);
  392. }
  393. return {
  394. row: row,
  395. tbodyEl: tbody,
  396. cellMatrix: cellMatrix,
  397. segMatrix: segMatrix,
  398. segLevels: segLevels,
  399. segs: rowSegs
  400. };
  401. };
  402. // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
  403. // NOTE: modifies segs
  404. DayGridEventRenderer.prototype.buildSegLevels = function (segs) {
  405. var _a = this.dayGrid, isRtl = _a.isRtl, colCnt = _a.colCnt;
  406. var levels = [];
  407. var i;
  408. var seg;
  409. var j;
  410. // Give preference to elements with certain criteria, so they have
  411. // a chance to be closer to the top.
  412. segs = this.sortEventSegs(segs);
  413. for (i = 0; i < segs.length; i++) {
  414. seg = segs[i];
  415. // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
  416. for (j = 0; j < levels.length; j++) {
  417. if (!isDaySegCollision(seg, levels[j])) {
  418. break;
  419. }
  420. }
  421. // `j` now holds the desired subrow index
  422. seg.level = j;
  423. seg.leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol; // for sorting only
  424. seg.rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol // for sorting only
  425. ;
  426. (levels[j] || (levels[j] = [])).push(seg);
  427. }
  428. // order segments left-to-right. very important if calendar is RTL
  429. for (j = 0; j < levels.length; j++) {
  430. levels[j].sort(compareDaySegCols);
  431. }
  432. return levels;
  433. };
  434. // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
  435. DayGridEventRenderer.prototype.groupSegRows = function (segs) {
  436. var segRows = [];
  437. var i;
  438. for (i = 0; i < this.dayGrid.rowCnt; i++) {
  439. segRows.push([]);
  440. }
  441. for (i = 0; i < segs.length; i++) {
  442. segRows[segs[i].row].push(segs[i]);
  443. }
  444. return segRows;
  445. };
  446. // Computes a default `displayEventEnd` value if one is not expliclty defined
  447. DayGridEventRenderer.prototype.computeDisplayEventEnd = function () {
  448. return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
  449. };
  450. return DayGridEventRenderer;
  451. }(SimpleDayGridEventRenderer));
  452. // Computes whether two segments' columns collide. They are assumed to be in the same row.
  453. function isDaySegCollision(seg, otherSegs) {
  454. var i;
  455. var otherSeg;
  456. for (i = 0; i < otherSegs.length; i++) {
  457. otherSeg = otherSegs[i];
  458. if (otherSeg.firstCol <= seg.lastCol &&
  459. otherSeg.lastCol >= seg.firstCol) {
  460. return true;
  461. }
  462. }
  463. return false;
  464. }
  465. // A cmp function for determining the leftmost event
  466. function compareDaySegCols(a, b) {
  467. return a.leftCol - b.leftCol;
  468. }
  469. var DayGridMirrorRenderer = /** @class */ (function (_super) {
  470. __extends(DayGridMirrorRenderer, _super);
  471. function DayGridMirrorRenderer() {
  472. return _super !== null && _super.apply(this, arguments) || this;
  473. }
  474. DayGridMirrorRenderer.prototype.attachSegs = function (segs, mirrorInfo) {
  475. var sourceSeg = mirrorInfo.sourceSeg;
  476. var rowStructs = this.rowStructs = this.renderSegRows(segs);
  477. // inject each new event skeleton into each associated row
  478. this.dayGrid.rowEls.forEach(function (rowNode, row) {
  479. var skeletonEl = core.htmlToElement('<div class="fc-mirror-skeleton"><table></table></div>'); // will be absolutely positioned
  480. var skeletonTopEl;
  481. var skeletonTop;
  482. // If there is an original segment, match the top position. Otherwise, put it at the row's top level
  483. if (sourceSeg && sourceSeg.row === row) {
  484. skeletonTopEl = sourceSeg.el;
  485. } else {
  486. skeletonTopEl = rowNode.querySelector('.fc-content-skeleton tbody');
  487. if (!skeletonTopEl) { // when no events
  488. skeletonTopEl = rowNode.querySelector('.fc-content-skeleton table');
  489. }
  490. }
  491. skeletonTop = skeletonTopEl.getBoundingClientRect().top -
  492. rowNode.getBoundingClientRect().top; // the offsetParent origin
  493. skeletonEl.style.top = skeletonTop + 'px';
  494. skeletonEl.querySelector('table').appendChild(rowStructs[row].tbodyEl);
  495. rowNode.appendChild(skeletonEl);
  496. });
  497. };
  498. return DayGridMirrorRenderer;
  499. }(DayGridEventRenderer));
  500. var EMPTY_CELL_HTML = '<td style="pointer-events:none"></td>';
  501. var DayGridFillRenderer = /** @class */ (function (_super) {
  502. __extends(DayGridFillRenderer, _super);
  503. function DayGridFillRenderer(dayGrid) {
  504. var _this = _super.call(this, dayGrid.context) || this;
  505. _this.fillSegTag = 'td'; // override the default tag name
  506. _this.dayGrid = dayGrid;
  507. return _this;
  508. }
  509. DayGridFillRenderer.prototype.renderSegs = function (type, segs) {
  510. // don't render timed background events
  511. if (type === 'bgEvent') {
  512. segs = segs.filter(function (seg) {
  513. return seg.eventRange.def.allDay;
  514. });
  515. }
  516. _super.prototype.renderSegs.call(this, type, segs);
  517. };
  518. DayGridFillRenderer.prototype.attachSegs = function (type, segs) {
  519. var els = [];
  520. var i;
  521. var seg;
  522. var skeletonEl;
  523. for (i = 0; i < segs.length; i++) {
  524. seg = segs[i];
  525. skeletonEl = this.renderFillRow(type, seg);
  526. this.dayGrid.rowEls[seg.row].appendChild(skeletonEl);
  527. els.push(skeletonEl);
  528. }
  529. return els;
  530. };
  531. // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
  532. DayGridFillRenderer.prototype.renderFillRow = function (type, seg) {
  533. var dayGrid = this.dayGrid;
  534. var colCnt = dayGrid.colCnt, isRtl = dayGrid.isRtl;
  535. var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
  536. var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
  537. var startCol = leftCol;
  538. var endCol = rightCol + 1;
  539. var className;
  540. var skeletonEl;
  541. var trEl;
  542. if (type === 'businessHours') {
  543. className = 'bgevent';
  544. } else {
  545. className = type.toLowerCase();
  546. }
  547. skeletonEl = core.htmlToElement('<div class="fc-' + className + '-skeleton">' +
  548. '<table><tr></tr></table>' +
  549. '</div>');
  550. trEl = skeletonEl.getElementsByTagName('tr')[0];
  551. if (startCol > 0) {
  552. core.appendToElement(trEl,
  553. // will create (startCol + 1) td's
  554. new Array(startCol + 1).join(EMPTY_CELL_HTML));
  555. }
  556. seg.el.colSpan = endCol - startCol;
  557. trEl.appendChild(seg.el);
  558. if (endCol < colCnt) {
  559. core.appendToElement(trEl,
  560. // will create (colCnt - endCol) td's
  561. new Array(colCnt - endCol + 1).join(EMPTY_CELL_HTML));
  562. }
  563. var introHtml = dayGrid.renderProps.renderIntroHtml();
  564. if (introHtml) {
  565. if (dayGrid.isRtl) {
  566. core.appendToElement(trEl, introHtml);
  567. } else {
  568. core.prependToElement(trEl, introHtml);
  569. }
  570. }
  571. return skeletonEl;
  572. };
  573. return DayGridFillRenderer;
  574. }(core.FillRenderer));
  575. var DayTile = /** @class */ (function (_super) {
  576. __extends(DayTile, _super);
  577. function DayTile(context, el) {
  578. var _this = _super.call(this, context, el) || this;
  579. var eventRenderer = _this.eventRenderer = new DayTileEventRenderer(_this);
  580. var renderFrame = _this.renderFrame = core.memoizeRendering(_this._renderFrame);
  581. _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderFrame]);
  582. _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
  583. _this.renderEventDrag = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
  584. _this.renderEventResize = core.memoizeRendering(eventRenderer.hideByHash.bind(eventRenderer), eventRenderer.showByHash.bind(eventRenderer), [renderFrame]);
  585. context.calendar.registerInteractiveComponent(_this, {
  586. el: _this.el,
  587. useEventCenter: false
  588. });
  589. return _this;
  590. }
  591. DayTile.prototype.render = function (props) {
  592. this.renderFrame(props.date);
  593. this.renderFgEvents(props.fgSegs);
  594. this.renderEventSelection(props.eventSelection);
  595. this.renderEventDrag(props.eventDragInstances);
  596. this.renderEventResize(props.eventResizeInstances);
  597. };
  598. DayTile.prototype.destroy = function () {
  599. _super.prototype.destroy.call(this);
  600. this.renderFrame.unrender(); // should unrender everything else
  601. this.calendar.unregisterInteractiveComponent(this);
  602. };
  603. DayTile.prototype._renderFrame = function (date) {
  604. var _a = this, theme = _a.theme, dateEnv = _a.dateEnv;
  605. var title = dateEnv.format(date, core.createFormatter(this.opt('dayPopoverFormat')) // TODO: cache
  606. );
  607. this.el.innerHTML =
  608. '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
  609. '<span class="fc-title">' +
  610. core.htmlEscape(title) +
  611. '</span>' +
  612. '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
  613. '</div>' +
  614. '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
  615. '<div class="fc-event-container"></div>' +
  616. '</div>';
  617. this.segContainerEl = this.el.querySelector('.fc-event-container');
  618. };
  619. DayTile.prototype.queryHit = function (positionLeft, positionTop, elWidth, elHeight) {
  620. var date = this.props.date; // HACK
  621. if (positionLeft < elWidth && positionTop < elHeight) {
  622. return {
  623. component: this,
  624. dateSpan: {
  625. allDay: true,
  626. range: {start: date, end: core.addDays(date, 1)}
  627. },
  628. dayEl: this.el,
  629. rect: {
  630. left: 0,
  631. top: 0,
  632. right: elWidth,
  633. bottom: elHeight
  634. },
  635. layer: 1
  636. };
  637. }
  638. };
  639. return DayTile;
  640. }(core.DateComponent));
  641. var DayTileEventRenderer = /** @class */ (function (_super) {
  642. __extends(DayTileEventRenderer, _super);
  643. function DayTileEventRenderer(dayTile) {
  644. var _this = _super.call(this, dayTile.context) || this;
  645. _this.dayTile = dayTile;
  646. return _this;
  647. }
  648. DayTileEventRenderer.prototype.attachSegs = function (segs) {
  649. for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
  650. var seg = segs_1[_i];
  651. this.dayTile.segContainerEl.appendChild(seg.el);
  652. }
  653. };
  654. DayTileEventRenderer.prototype.detachSegs = function (segs) {
  655. for (var _i = 0, segs_2 = segs; _i < segs_2.length; _i++) {
  656. var seg = segs_2[_i];
  657. core.removeElement(seg.el);
  658. }
  659. };
  660. return DayTileEventRenderer;
  661. }(SimpleDayGridEventRenderer));
  662. var DayBgRow = /** @class */ (function () {
  663. function DayBgRow(context) {
  664. this.context = context;
  665. }
  666. DayBgRow.prototype.renderHtml = function (props) {
  667. var parts = [];
  668. if (props.renderIntroHtml) {
  669. parts.push(props.renderIntroHtml());
  670. }
  671. for (var _i = 0, _a = props.cells; _i < _a.length; _i++) {
  672. var cell = _a[_i];
  673. parts.push(renderCellHtml(cell.date, props.dateProfile, this.context, cell.htmlAttrs));
  674. }
  675. if (!props.cells.length) {
  676. parts.push('<td class="fc-day ' + this.context.theme.getClass('widgetContent') + '"></td>');
  677. }
  678. if (this.context.options.dir === 'rtl') {
  679. parts.reverse();
  680. }
  681. return '<tr>' + parts.join('') + '</tr>';
  682. };
  683. return DayBgRow;
  684. }());
  685. function renderCellHtml(date, dateProfile, context, otherAttrs) {
  686. var dateEnv = context.dateEnv, theme = context.theme;
  687. var isDateValid = core.rangeContainsMarker(dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
  688. var classes = core.getDayClasses(date, dateProfile, context);
  689. classes.unshift('fc-day', theme.getClass('widgetContent'));
  690. return '<td class="' + classes.join(' ') + '"' +
  691. (isDateValid ?
  692. ' data-date="' + dateEnv.formatIso(date, {omitTime: true}) + '"' :
  693. '') +
  694. (otherAttrs ?
  695. ' ' + otherAttrs :
  696. '') +
  697. '></td>';
  698. }
  699. var DAY_NUM_FORMAT = core.createFormatter({day: 'numeric'});
  700. var WEEK_NUM_FORMAT = core.createFormatter({week: 'numeric'});
  701. var DayGrid = /** @class */ (function (_super) {
  702. __extends(DayGrid, _super);
  703. function DayGrid(context, el, renderProps) {
  704. var _this = _super.call(this, context, el) || this;
  705. _this.bottomCoordPadding = 0; // hack for extending the hit area for the last row of the coordinate grid
  706. _this.isCellSizesDirty = false;
  707. var eventRenderer = _this.eventRenderer = new DayGridEventRenderer(_this);
  708. var fillRenderer = _this.fillRenderer = new DayGridFillRenderer(_this);
  709. _this.mirrorRenderer = new DayGridMirrorRenderer(_this);
  710. var renderCells = _this.renderCells = core.memoizeRendering(_this._renderCells, _this._unrenderCells);
  711. _this.renderBusinessHours = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'), fillRenderer.unrender.bind(fillRenderer, 'businessHours'), [renderCells]);
  712. _this.renderDateSelection = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'highlight'), fillRenderer.unrender.bind(fillRenderer, 'highlight'), [renderCells]);
  713. _this.renderBgEvents = core.memoizeRendering(fillRenderer.renderSegs.bind(fillRenderer, 'bgEvent'), fillRenderer.unrender.bind(fillRenderer, 'bgEvent'), [renderCells]);
  714. _this.renderFgEvents = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer), [renderCells]);
  715. _this.renderEventSelection = core.memoizeRendering(eventRenderer.selectByInstanceId.bind(eventRenderer), eventRenderer.unselectByInstanceId.bind(eventRenderer), [_this.renderFgEvents]);
  716. _this.renderEventDrag = core.memoizeRendering(_this._renderEventDrag, _this._unrenderEventDrag, [renderCells]);
  717. _this.renderEventResize = core.memoizeRendering(_this._renderEventResize, _this._unrenderEventResize, [renderCells]);
  718. _this.renderProps = renderProps;
  719. return _this;
  720. }
  721. DayGrid.prototype.render = function (props) {
  722. var cells = props.cells;
  723. this.rowCnt = cells.length;
  724. this.colCnt = cells[0].length;
  725. this.renderCells(cells, props.isRigid);
  726. this.renderBusinessHours(props.businessHourSegs);
  727. this.renderDateSelection(props.dateSelectionSegs);
  728. this.renderBgEvents(props.bgEventSegs);
  729. this.renderFgEvents(props.fgEventSegs);
  730. this.renderEventSelection(props.eventSelection);
  731. this.renderEventDrag(props.eventDrag);
  732. this.renderEventResize(props.eventResize);
  733. if (this.segPopoverTile) {
  734. this.updateSegPopoverTile();
  735. }
  736. };
  737. DayGrid.prototype.destroy = function () {
  738. _super.prototype.destroy.call(this);
  739. this.renderCells.unrender(); // will unrender everything else
  740. };
  741. DayGrid.prototype.getCellRange = function (row, col) {
  742. var start = this.props.cells[row][col].date;
  743. var end = core.addDays(start, 1);
  744. return {start: start, end: end};
  745. };
  746. DayGrid.prototype.updateSegPopoverTile = function (date, segs) {
  747. var ownProps = this.props;
  748. this.segPopoverTile.receiveProps({
  749. date: date || this.segPopoverTile.props.date,
  750. fgSegs: segs || this.segPopoverTile.props.fgSegs,
  751. eventSelection: ownProps.eventSelection,
  752. eventDragInstances: ownProps.eventDrag ? ownProps.eventDrag.affectedInstances : null,
  753. eventResizeInstances: ownProps.eventResize ? ownProps.eventResize.affectedInstances : null
  754. });
  755. };
  756. /* Date Rendering
  757. ------------------------------------------------------------------------------------------------------------------*/
  758. DayGrid.prototype._renderCells = function (cells, isRigid) {
  759. var _a = this, view = _a.view, dateEnv = _a.dateEnv;
  760. var _b = this, rowCnt = _b.rowCnt, colCnt = _b.colCnt;
  761. var html = '';
  762. var row;
  763. var col;
  764. for (row = 0; row < rowCnt; row++) {
  765. html += this.renderDayRowHtml(row, isRigid);
  766. }
  767. this.el.innerHTML = html;
  768. this.rowEls = core.findElements(this.el, '.fc-row');
  769. this.cellEls = core.findElements(this.el, '.fc-day, .fc-disabled-day');
  770. if (this.isRtl) {
  771. this.cellEls.reverse();
  772. }
  773. this.rowPositions = new core.PositionCache(this.el, this.rowEls, false, true // vertical
  774. );
  775. this.colPositions = new core.PositionCache(this.el, this.cellEls.slice(0, colCnt), // only the first row
  776. true, false // horizontal
  777. );
  778. // trigger dayRender with each cell's element
  779. for (row = 0; row < rowCnt; row++) {
  780. for (col = 0; col < colCnt; col++) {
  781. this.publiclyTrigger('dayRender', [
  782. {
  783. date: dateEnv.toDate(cells[row][col].date),
  784. el: this.getCellEl(row, col),
  785. view: view
  786. }
  787. ]);
  788. }
  789. }
  790. this.isCellSizesDirty = true;
  791. };
  792. DayGrid.prototype._unrenderCells = function () {
  793. this.removeSegPopover();
  794. };
  795. // Generates the HTML for a single row, which is a div that wraps a table.
  796. // `row` is the row number.
  797. DayGrid.prototype.renderDayRowHtml = function (row, isRigid) {
  798. var theme = this.theme;
  799. var classes = ['fc-row', 'fc-week', theme.getClass('dayRow')];
  800. if (isRigid) {
  801. classes.push('fc-rigid');
  802. }
  803. var bgRow = new DayBgRow(this.context);
  804. return '' +
  805. '<div class="' + classes.join(' ') + '">' +
  806. '<div class="fc-bg">' +
  807. '<table class="' + theme.getClass('tableGrid') + '">' +
  808. bgRow.renderHtml({
  809. cells: this.props.cells[row],
  810. dateProfile: this.props.dateProfile,
  811. renderIntroHtml: this.renderProps.renderBgIntroHtml
  812. }) +
  813. '</table>' +
  814. '</div>' +
  815. '<div class="fc-content-skeleton">' +
  816. '<table>' +
  817. (this.getIsNumbersVisible() ?
  818. '<thead>' +
  819. this.renderNumberTrHtml(row) +
  820. '</thead>' :
  821. '') +
  822. '</table>' +
  823. '</div>' +
  824. '</div>';
  825. };
  826. DayGrid.prototype.getIsNumbersVisible = function () {
  827. return this.getIsDayNumbersVisible() ||
  828. this.renderProps.cellWeekNumbersVisible ||
  829. this.renderProps.colWeekNumbersVisible;
  830. };
  831. DayGrid.prototype.getIsDayNumbersVisible = function () {
  832. return this.rowCnt > 1;
  833. };
  834. /* Grid Number Rendering
  835. ------------------------------------------------------------------------------------------------------------------*/
  836. DayGrid.prototype.renderNumberTrHtml = function (row) {
  837. var intro = this.renderProps.renderNumberIntroHtml(row, this);
  838. return '' +
  839. '<tr>' +
  840. (this.isRtl ? '' : intro) +
  841. this.renderNumberCellsHtml(row) +
  842. (this.isRtl ? intro : '') +
  843. '</tr>';
  844. };
  845. DayGrid.prototype.renderNumberCellsHtml = function (row) {
  846. var htmls = [];
  847. var col;
  848. var date;
  849. for (col = 0; col < this.colCnt; col++) {
  850. date = this.props.cells[row][col].date;
  851. htmls.push(this.renderNumberCellHtml(date));
  852. }
  853. if (this.isRtl) {
  854. htmls.reverse();
  855. }
  856. return htmls.join('');
  857. };
  858. // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
  859. // The number row will only exist if either day numbers or week numbers are turned on.
  860. DayGrid.prototype.renderNumberCellHtml = function (date) {
  861. var _a = this, view = _a.view, dateEnv = _a.dateEnv;
  862. var html = '';
  863. var isDateValid = core.rangeContainsMarker(this.props.dateProfile.activeRange, date); // TODO: called too frequently. cache somehow.
  864. var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
  865. var classes;
  866. var weekCalcFirstDow;
  867. if (!isDayNumberVisible && !this.renderProps.cellWeekNumbersVisible) {
  868. // no numbers in day cell (week number must be along the side)
  869. return '<td></td>'; // will create an empty space above events :(
  870. }
  871. classes = core.getDayClasses(date, this.props.dateProfile, this.context);
  872. classes.unshift('fc-day-top');
  873. if (this.renderProps.cellWeekNumbersVisible) {
  874. weekCalcFirstDow = dateEnv.weekDow;
  875. }
  876. html += '<td class="' + classes.join(' ') + '"' +
  877. (isDateValid ?
  878. ' data-date="' + dateEnv.formatIso(date, {omitTime: true}) + '"' :
  879. '') +
  880. '>';
  881. if (this.renderProps.cellWeekNumbersVisible && (date.getUTCDay() === weekCalcFirstDow)) {
  882. html += core.buildGotoAnchorHtml(view, {
  883. date: date,
  884. type: 'week'
  885. }, {'class': 'fc-week-number'}, dateEnv.format(date, WEEK_NUM_FORMAT) // inner HTML
  886. );
  887. }
  888. if (isDayNumberVisible) {
  889. html += core.buildGotoAnchorHtml(view, date, {'class': 'fc-day-number'}, dateEnv.format(date, DAY_NUM_FORMAT) // inner HTML
  890. );
  891. }
  892. html += '</td>';
  893. return html;
  894. };
  895. /* Sizing
  896. ------------------------------------------------------------------------------------------------------------------*/
  897. DayGrid.prototype.updateSize = function (isResize) {
  898. var _a = this, fillRenderer = _a.fillRenderer, eventRenderer = _a.eventRenderer,
  899. mirrorRenderer = _a.mirrorRenderer;
  900. if (isResize ||
  901. this.isCellSizesDirty ||
  902. this.view.calendar.isEventsUpdated // hack
  903. ) {
  904. this.buildPositionCaches();
  905. this.isCellSizesDirty = false;
  906. }
  907. fillRenderer.computeSizes(isResize);
  908. eventRenderer.computeSizes(isResize);
  909. mirrorRenderer.computeSizes(isResize);
  910. fillRenderer.assignSizes(isResize);
  911. eventRenderer.assignSizes(isResize);
  912. mirrorRenderer.assignSizes(isResize);
  913. };
  914. DayGrid.prototype.buildPositionCaches = function () {
  915. this.buildColPositions();
  916. this.buildRowPositions();
  917. };
  918. DayGrid.prototype.buildColPositions = function () {
  919. this.colPositions.build();
  920. };
  921. DayGrid.prototype.buildRowPositions = function () {
  922. this.rowPositions.build();
  923. this.rowPositions.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
  924. };
  925. /* Hit System
  926. ------------------------------------------------------------------------------------------------------------------*/
  927. DayGrid.prototype.positionToHit = function (leftPosition, topPosition) {
  928. var _a = this, colPositions = _a.colPositions, rowPositions = _a.rowPositions;
  929. var col = colPositions.leftToIndex(leftPosition);
  930. var row = rowPositions.topToIndex(topPosition);
  931. if (row != null && col != null) {
  932. return {
  933. row: row,
  934. col: col,
  935. dateSpan: {
  936. range: this.getCellRange(row, col),
  937. allDay: true
  938. },
  939. dayEl: this.getCellEl(row, col),
  940. relativeRect: {
  941. left: colPositions.lefts[col],
  942. right: colPositions.rights[col],
  943. top: rowPositions.tops[row],
  944. bottom: rowPositions.bottoms[row]
  945. }
  946. };
  947. }
  948. };
  949. /* Cell System
  950. ------------------------------------------------------------------------------------------------------------------*/
  951. // FYI: the first column is the leftmost column, regardless of date
  952. DayGrid.prototype.getCellEl = function (row, col) {
  953. return this.cellEls[row * this.colCnt + col];
  954. };
  955. /* Event Drag Visualization
  956. ------------------------------------------------------------------------------------------------------------------*/
  957. DayGrid.prototype._renderEventDrag = function (state) {
  958. if (state) {
  959. this.eventRenderer.hideByHash(state.affectedInstances);
  960. this.fillRenderer.renderSegs('highlight', state.segs);
  961. }
  962. };
  963. DayGrid.prototype._unrenderEventDrag = function (state) {
  964. if (state) {
  965. this.eventRenderer.showByHash(state.affectedInstances);
  966. this.fillRenderer.unrender('highlight');
  967. }
  968. };
  969. /* Event Resize Visualization
  970. ------------------------------------------------------------------------------------------------------------------*/
  971. DayGrid.prototype._renderEventResize = function (state) {
  972. if (state) {
  973. this.eventRenderer.hideByHash(state.affectedInstances);
  974. this.fillRenderer.renderSegs('highlight', state.segs);
  975. this.mirrorRenderer.renderSegs(state.segs, {isResizing: true, sourceSeg: state.sourceSeg});
  976. }
  977. };
  978. DayGrid.prototype._unrenderEventResize = function (state) {
  979. if (state) {
  980. this.eventRenderer.showByHash(state.affectedInstances);
  981. this.fillRenderer.unrender('highlight');
  982. this.mirrorRenderer.unrender(state.segs, {isResizing: true, sourceSeg: state.sourceSeg});
  983. }
  984. };
  985. /* More+ Link Popover
  986. ------------------------------------------------------------------------------------------------------------------*/
  987. DayGrid.prototype.removeSegPopover = function () {
  988. if (this.segPopover) {
  989. this.segPopover.hide(); // in handler, will call segPopover's removeElement
  990. }
  991. };
  992. // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
  993. // `levelLimit` can be false (don't limit), a number, or true (should be computed).
  994. DayGrid.prototype.limitRows = function (levelLimit) {
  995. var rowStructs = this.eventRenderer.rowStructs || [];
  996. var row; // row #
  997. var rowLevelLimit;
  998. for (row = 0; row < rowStructs.length; row++) {
  999. this.unlimitRow(row);
  1000. if (!levelLimit) {
  1001. rowLevelLimit = false;
  1002. } else if (typeof levelLimit === 'number') {
  1003. rowLevelLimit = levelLimit;
  1004. } else {
  1005. rowLevelLimit = this.computeRowLevelLimit(row);
  1006. }
  1007. if (rowLevelLimit !== false) {
  1008. this.limitRow(row, rowLevelLimit);
  1009. }
  1010. }
  1011. };
  1012. // Computes the number of levels a row will accomodate without going outside its bounds.
  1013. // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
  1014. // `row` is the row number.
  1015. DayGrid.prototype.computeRowLevelLimit = function (row) {
  1016. var rowEl = this.rowEls[row]; // the containing "fake" row div
  1017. var rowBottom = rowEl.getBoundingClientRect().bottom; // relative to viewport!
  1018. var trEls = core.findChildren(this.eventRenderer.rowStructs[row].tbodyEl);
  1019. var i;
  1020. var trEl;
  1021. // Reveal one level <tr> at a time and stop when we find one out of bounds
  1022. for (i = 0; i < trEls.length; i++) {
  1023. trEl = trEls[i];
  1024. trEl.classList.remove('fc-limited'); // reset to original state (reveal)
  1025. if (trEl.getBoundingClientRect().bottom > rowBottom) {
  1026. return i;
  1027. }
  1028. }
  1029. return false; // should not limit at all
  1030. };
  1031. // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
  1032. // `row` is the row number.
  1033. // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
  1034. DayGrid.prototype.limitRow = function (row, levelLimit) {
  1035. var _this = this;
  1036. var _a = this, colCnt = _a.colCnt, isRtl = _a.isRtl;
  1037. var rowStruct = this.eventRenderer.rowStructs[row];
  1038. var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
  1039. var col = 0; // col #, left-to-right (not chronologically)
  1040. var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
  1041. var cellMatrix; // a matrix (by level, then column) of all <td> elements in the row
  1042. var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
  1043. var i;
  1044. var seg;
  1045. var segsBelow; // array of segment objects below `seg` in the current `col`
  1046. var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
  1047. var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
  1048. var td;
  1049. var rowSpan;
  1050. var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
  1051. var j;
  1052. var moreTd;
  1053. var moreWrap;
  1054. var moreLink;
  1055. // Iterates through empty level cells and places "more" links inside if need be
  1056. var emptyCellsUntil = function (endCol) {
  1057. while (col < endCol) {
  1058. segsBelow = _this.getCellSegs(row, col, levelLimit);
  1059. if (segsBelow.length) {
  1060. td = cellMatrix[levelLimit - 1][col];
  1061. moreLink = _this.renderMoreLink(row, col, segsBelow);
  1062. moreWrap = core.createElement('div', null, moreLink);
  1063. td.appendChild(moreWrap);
  1064. moreNodes.push(moreWrap);
  1065. }
  1066. col++;
  1067. }
  1068. };
  1069. if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
  1070. levelSegs = rowStruct.segLevels[levelLimit - 1];
  1071. cellMatrix = rowStruct.cellMatrix;
  1072. limitedNodes = core.findChildren(rowStruct.tbodyEl).slice(levelLimit); // get level <tr> elements past the limit
  1073. limitedNodes.forEach(function (node) {
  1074. node.classList.add('fc-limited'); // hide elements and get a simple DOM-nodes array
  1075. });
  1076. // iterate though segments in the last allowable level
  1077. for (i = 0; i < levelSegs.length; i++) {
  1078. seg = levelSegs[i];
  1079. var leftCol = isRtl ? (colCnt - 1 - seg.lastCol) : seg.firstCol;
  1080. var rightCol = isRtl ? (colCnt - 1 - seg.firstCol) : seg.lastCol;
  1081. emptyCellsUntil(leftCol); // process empty cells before the segment
  1082. // determine *all* segments below `seg` that occupy the same columns
  1083. colSegsBelow = [];
  1084. totalSegsBelow = 0;
  1085. while (col <= rightCol) {
  1086. segsBelow = this.getCellSegs(row, col, levelLimit);
  1087. colSegsBelow.push(segsBelow);
  1088. totalSegsBelow += segsBelow.length;
  1089. col++;
  1090. }
  1091. if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
  1092. td = cellMatrix[levelLimit - 1][leftCol]; // the segment's parent cell
  1093. rowSpan = td.rowSpan || 1;
  1094. segMoreNodes = [];
  1095. // make a replacement <td> for each column the segment occupies. will be one for each colspan
  1096. for (j = 0; j < colSegsBelow.length; j++) {
  1097. moreTd = core.createElement('td', {className: 'fc-more-cell', rowSpan: rowSpan});
  1098. segsBelow = colSegsBelow[j];
  1099. moreLink = this.renderMoreLink(row, leftCol + j, [seg].concat(segsBelow) // count seg as hidden too
  1100. );
  1101. moreWrap = core.createElement('div', null, moreLink);
  1102. moreTd.appendChild(moreWrap);
  1103. segMoreNodes.push(moreTd);
  1104. moreNodes.push(moreTd);
  1105. }
  1106. td.classList.add('fc-limited');
  1107. core.insertAfterElement(td, segMoreNodes);
  1108. limitedNodes.push(td);
  1109. }
  1110. }
  1111. emptyCellsUntil(this.colCnt); // finish off the level
  1112. rowStruct.moreEls = moreNodes; // for easy undoing later
  1113. rowStruct.limitedEls = limitedNodes; // for easy undoing later
  1114. }
  1115. };
  1116. // Reveals all levels and removes all "more"-related elements for a grid's row.
  1117. // `row` is a row number.
  1118. DayGrid.prototype.unlimitRow = function (row) {
  1119. var rowStruct = this.eventRenderer.rowStructs[row];
  1120. if (rowStruct.moreEls) {
  1121. rowStruct.moreEls.forEach(core.removeElement);
  1122. rowStruct.moreEls = null;
  1123. }
  1124. if (rowStruct.limitedEls) {
  1125. rowStruct.limitedEls.forEach(function (limitedEl) {
  1126. limitedEl.classList.remove('fc-limited');
  1127. });
  1128. rowStruct.limitedEls = null;
  1129. }
  1130. };
  1131. // Renders an <a> element that represents hidden event element for a cell.
  1132. // Responsible for attaching click handler as well.
  1133. DayGrid.prototype.renderMoreLink = function (row, col, hiddenSegs) {
  1134. var _this = this;
  1135. var _a = this, view = _a.view, dateEnv = _a.dateEnv;
  1136. var a = core.createElement('a', {className: 'fc-more'});
  1137. a.innerText = this.getMoreLinkText(hiddenSegs.length);
  1138. a.addEventListener('click', function (ev) {
  1139. var clickOption = _this.opt('eventLimitClick');
  1140. var _col = _this.isRtl ? _this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
  1141. var date = _this.props.cells[row][_col].date;
  1142. var moreEl = ev.currentTarget;
  1143. var dayEl = _this.getCellEl(row, col);
  1144. var allSegs = _this.getCellSegs(row, col);
  1145. // rescope the segments to be within the cell's date
  1146. var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
  1147. var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
  1148. if (typeof clickOption === 'function') {
  1149. // the returned value can be an atomic option
  1150. clickOption = _this.publiclyTrigger('eventLimitClick', [
  1151. {
  1152. date: dateEnv.toDate(date),
  1153. allDay: true,
  1154. dayEl: dayEl,
  1155. moreEl: moreEl,
  1156. segs: reslicedAllSegs,
  1157. hiddenSegs: reslicedHiddenSegs,
  1158. jsEvent: ev,
  1159. view: view
  1160. }
  1161. ]);
  1162. }
  1163. if (clickOption === 'popover') {
  1164. _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
  1165. } else if (typeof clickOption === 'string') { // a view name
  1166. view.calendar.zoomTo(date, clickOption);
  1167. }
  1168. });
  1169. return a;
  1170. };
  1171. // Reveals the popover that displays all events within a cell
  1172. DayGrid.prototype.showSegPopover = function (row, col, moreLink, segs) {
  1173. var _this = this;
  1174. var _a = this, calendar = _a.calendar, view = _a.view, theme = _a.theme;
  1175. var _col = this.isRtl ? this.colCnt - col - 1 : col; // HACK: props.cells has different dir system?
  1176. var moreWrap = moreLink.parentNode; // the <div> wrapper around the <a>
  1177. var topEl; // the element we want to match the top coordinate of
  1178. var options;
  1179. if (this.rowCnt === 1) {
  1180. topEl = view.el; // will cause the popover to cover any sort of header
  1181. } else {
  1182. topEl = this.rowEls[row]; // will align with top of row
  1183. }
  1184. options = {
  1185. className: 'fc-more-popover ' + theme.getClass('popover'),
  1186. parentEl: view.el,
  1187. top: core.computeRect(topEl).top,
  1188. autoHide: true,
  1189. content: function (el) {
  1190. _this.segPopoverTile = new DayTile(_this.context, el);
  1191. _this.updateSegPopoverTile(_this.props.cells[row][_col].date, segs);
  1192. },
  1193. hide: function () {
  1194. _this.segPopoverTile.destroy();
  1195. _this.segPopoverTile = null;
  1196. _this.segPopover.destroy();
  1197. _this.segPopover = null;
  1198. }
  1199. };
  1200. // Determine horizontal coordinate.
  1201. // We use the moreWrap instead of the <td> to avoid border confusion.
  1202. if (this.isRtl) {
  1203. options.right = core.computeRect(moreWrap).right + 1; // +1 to be over cell border
  1204. } else {
  1205. options.left = core.computeRect(moreWrap).left - 1; // -1 to be over cell border
  1206. }
  1207. this.segPopover = new Popover(options);
  1208. this.segPopover.show();
  1209. calendar.releaseAfterSizingTriggers(); // hack for eventPositioned
  1210. };
  1211. // Given the events within an array of segment objects, reslice them to be in a single day
  1212. DayGrid.prototype.resliceDaySegs = function (segs, dayDate) {
  1213. var dayStart = dayDate;
  1214. var dayEnd = core.addDays(dayStart, 1);
  1215. var dayRange = {start: dayStart, end: dayEnd};
  1216. var newSegs = [];
  1217. for (var _i = 0, segs_1 = segs; _i < segs_1.length; _i++) {
  1218. var seg = segs_1[_i];
  1219. var eventRange = seg.eventRange;
  1220. var origRange = eventRange.range;
  1221. var slicedRange = core.intersectRanges(origRange, dayRange);
  1222. if (slicedRange) {
  1223. newSegs.push(__assign({}, seg, {
  1224. eventRange: {
  1225. def: eventRange.def,
  1226. ui: __assign({}, eventRange.ui, {durationEditable: false}),
  1227. instance: eventRange.instance,
  1228. range: slicedRange
  1229. },
  1230. isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(),
  1231. isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf()
  1232. }));
  1233. }
  1234. }
  1235. return newSegs;
  1236. };
  1237. // Generates the text that should be inside a "more" link, given the number of events it represents
  1238. DayGrid.prototype.getMoreLinkText = function (num) {
  1239. var opt = this.opt('eventLimitText');
  1240. if (typeof opt === 'function') {
  1241. return opt(num);
  1242. } else {
  1243. return '+' + num + ' ' + opt;
  1244. }
  1245. };
  1246. // Returns segments within a given cell.
  1247. // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
  1248. DayGrid.prototype.getCellSegs = function (row, col, startLevel) {
  1249. var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
  1250. var level = startLevel || 0;
  1251. var segs = [];
  1252. var seg;
  1253. while (level < segMatrix.length) {
  1254. seg = segMatrix[level][col];
  1255. if (seg) {
  1256. segs.push(seg);
  1257. }
  1258. level++;
  1259. }
  1260. return segs;
  1261. };
  1262. return DayGrid;
  1263. }(core.DateComponent));
  1264. var WEEK_NUM_FORMAT$1 = core.createFormatter({week: 'numeric'});
  1265. /* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
  1266. ----------------------------------------------------------------------------------------------------------------------*/
  1267. // It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
  1268. // It is responsible for managing width/height.
  1269. var DayGridView = /** @class */ (function (_super) {
  1270. __extends(DayGridView, _super);
  1271. function DayGridView(context, viewSpec, dateProfileGenerator, parentEl) {
  1272. var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this;
  1273. /* Header Rendering
  1274. ------------------------------------------------------------------------------------------------------------------*/
  1275. // Generates the HTML that will go before the day-of week header cells
  1276. _this.renderHeadIntroHtml = function () {
  1277. var theme = _this.theme;
  1278. if (_this.colWeekNumbersVisible) {
  1279. return '' +
  1280. '<th class="fc-week-number ' + theme.getClass('widgetHeader') + '" ' + _this.weekNumberStyleAttr() + '>' +
  1281. '<span>' + // needed for matchCellWidths
  1282. core.htmlEscape(_this.opt('weekLabel')) +
  1283. '</span>' +
  1284. '</th>';
  1285. }
  1286. return '';
  1287. };
  1288. /* Day Grid Rendering
  1289. ------------------------------------------------------------------------------------------------------------------*/
  1290. // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
  1291. _this.renderDayGridNumberIntroHtml = function (row, dayGrid) {
  1292. var dateEnv = _this.dateEnv;
  1293. var weekStart = dayGrid.props.cells[row][0].date;
  1294. if (_this.colWeekNumbersVisible) {
  1295. return '' +
  1296. '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '>' +
  1297. core.buildGotoAnchorHtml(// aside from link, important for matchCellWidths
  1298. _this, {
  1299. date: weekStart,
  1300. type: 'week',
  1301. forceOff: dayGrid.colCnt === 1
  1302. }, dateEnv.format(weekStart, WEEK_NUM_FORMAT$1) // inner HTML
  1303. ) +
  1304. '</td>';
  1305. }
  1306. return '';
  1307. };
  1308. // Generates the HTML that goes before the day bg cells for each day-row
  1309. _this.renderDayGridBgIntroHtml = function () {
  1310. var theme = _this.theme;
  1311. if (_this.colWeekNumbersVisible) {
  1312. return '<td class="fc-week-number ' + theme.getClass('widgetContent') + '" ' + _this.weekNumberStyleAttr() + '></td>';
  1313. }
  1314. return '';
  1315. };
  1316. // Generates the HTML that goes before every other type of row generated by DayGrid.
  1317. // Affects mirror-skeleton and highlight-skeleton rows.
  1318. _this.renderDayGridIntroHtml = function () {
  1319. if (_this.colWeekNumbersVisible) {
  1320. return '<td class="fc-week-number" ' + _this.weekNumberStyleAttr() + '></td>';
  1321. }
  1322. return '';
  1323. };
  1324. _this.el.classList.add('fc-dayGrid-view');
  1325. _this.el.innerHTML = _this.renderSkeletonHtml();
  1326. _this.scroller = new core.ScrollComponent('hidden', // overflow x
  1327. 'auto' // overflow y
  1328. );
  1329. var dayGridContainerEl = _this.scroller.el;
  1330. _this.el.querySelector('.fc-body > tr > td').appendChild(dayGridContainerEl);
  1331. dayGridContainerEl.classList.add('fc-day-grid-container');
  1332. var dayGridEl = core.createElement('div', {className: 'fc-day-grid'});
  1333. dayGridContainerEl.appendChild(dayGridEl);
  1334. var cellWeekNumbersVisible;
  1335. if (_this.opt('weekNumbers')) {
  1336. if (_this.opt('weekNumbersWithinDays')) {
  1337. cellWeekNumbersVisible = true;
  1338. _this.colWeekNumbersVisible = false;
  1339. } else {
  1340. cellWeekNumbersVisible = false;
  1341. _this.colWeekNumbersVisible = true;
  1342. }
  1343. } else {
  1344. _this.colWeekNumbersVisible = false;
  1345. cellWeekNumbersVisible = false;
  1346. }
  1347. _this.dayGrid = new DayGrid(_this.context, dayGridEl, {
  1348. renderNumberIntroHtml: _this.renderDayGridNumberIntroHtml,
  1349. renderBgIntroHtml: _this.renderDayGridBgIntroHtml,
  1350. renderIntroHtml: _this.renderDayGridIntroHtml,
  1351. colWeekNumbersVisible: _this.colWeekNumbersVisible,
  1352. cellWeekNumbersVisible: cellWeekNumbersVisible
  1353. });
  1354. return _this;
  1355. }
  1356. DayGridView.prototype.destroy = function () {
  1357. _super.prototype.destroy.call(this);
  1358. this.dayGrid.destroy();
  1359. this.scroller.destroy();
  1360. };
  1361. // Builds the HTML skeleton for the view.
  1362. // The day-grid component will render inside of a container defined by this HTML.
  1363. DayGridView.prototype.renderSkeletonHtml = function () {
  1364. var theme = this.theme;
  1365. return '' +
  1366. '<table class="' + theme.getClass('tableGrid') + '">' +
  1367. (this.opt('columnHeader') ?
  1368. '<thead class="fc-head">' +
  1369. '<tr>' +
  1370. '<td class="fc-head-container ' + theme.getClass('widgetHeader') + '">&nbsp;</td>' +
  1371. '</tr>' +
  1372. '</thead>' :
  1373. '') +
  1374. '<tbody class="fc-body">' +
  1375. '<tr>' +
  1376. '<td class="' + theme.getClass('widgetContent') + '"></td>' +
  1377. '</tr>' +
  1378. '</tbody>' +
  1379. '</table>';
  1380. };
  1381. // Generates an HTML attribute string for setting the width of the week number column, if it is known
  1382. DayGridView.prototype.weekNumberStyleAttr = function () {
  1383. if (this.weekNumberWidth != null) {
  1384. return 'style="width:' + this.weekNumberWidth + 'px"';
  1385. }
  1386. return '';
  1387. };
  1388. // Determines whether each row should have a constant height
  1389. DayGridView.prototype.hasRigidRows = function () {
  1390. var eventLimit = this.opt('eventLimit');
  1391. return eventLimit && typeof eventLimit !== 'number';
  1392. };
  1393. /* Dimensions
  1394. ------------------------------------------------------------------------------------------------------------------*/
  1395. DayGridView.prototype.updateSize = function (isResize, viewHeight, isAuto) {
  1396. _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); // will call updateBaseSize. important that executes first
  1397. this.dayGrid.updateSize(isResize);
  1398. };
  1399. // Refreshes the horizontal dimensions of the view
  1400. DayGridView.prototype.updateBaseSize = function (isResize, viewHeight, isAuto) {
  1401. var dayGrid = this.dayGrid;
  1402. var eventLimit = this.opt('eventLimit');
  1403. var headRowEl = this.header ? this.header.el : null; // HACK
  1404. var scrollerHeight;
  1405. var scrollbarWidths;
  1406. // hack to give the view some height prior to dayGrid's columns being rendered
  1407. // TODO: separate setting height from scroller VS dayGrid.
  1408. if (!dayGrid.rowEls) {
  1409. if (!isAuto) {
  1410. scrollerHeight = this.computeScrollerHeight(viewHeight);
  1411. this.scroller.setHeight(scrollerHeight);
  1412. }
  1413. return;
  1414. }
  1415. if (this.colWeekNumbersVisible) {
  1416. // Make sure all week number cells running down the side have the same width.
  1417. this.weekNumberWidth = core.matchCellWidths(core.findElements(this.el, '.fc-week-number'));
  1418. }
  1419. // reset all heights to be natural
  1420. this.scroller.clear();
  1421. if (headRowEl) {
  1422. core.uncompensateScroll(headRowEl);
  1423. }
  1424. dayGrid.removeSegPopover(); // kill the "more" popover if displayed
  1425. // is the event limit a constant level number?
  1426. if (eventLimit && typeof eventLimit === 'number') {
  1427. dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
  1428. }
  1429. // distribute the height to the rows
  1430. // (viewHeight is a "recommended" value if isAuto)
  1431. scrollerHeight = this.computeScrollerHeight(viewHeight);
  1432. this.setGridHeight(scrollerHeight, isAuto);
  1433. // is the event limit dynamically calculated?
  1434. if (eventLimit && typeof eventLimit !== 'number') {
  1435. dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
  1436. }
  1437. if (!isAuto) { // should we force dimensions of the scroll container?
  1438. this.scroller.setHeight(scrollerHeight);
  1439. scrollbarWidths = this.scroller.getScrollbarWidths();
  1440. if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
  1441. if (headRowEl) {
  1442. core.compensateScroll(headRowEl, scrollbarWidths);
  1443. }
  1444. // doing the scrollbar compensation might have created text overflow which created more height. redo
  1445. scrollerHeight = this.computeScrollerHeight(viewHeight);
  1446. this.scroller.setHeight(scrollerHeight);
  1447. }
  1448. // guarantees the same scrollbar widths
  1449. this.scroller.lockOverflow(scrollbarWidths);
  1450. }
  1451. };
  1452. // given a desired total height of the view, returns what the height of the scroller should be
  1453. DayGridView.prototype.computeScrollerHeight = function (viewHeight) {
  1454. return viewHeight -
  1455. core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
  1456. };
  1457. // Sets the height of just the DayGrid component in this view
  1458. DayGridView.prototype.setGridHeight = function (height, isAuto) {
  1459. if (this.opt('monthMode')) {
  1460. // if auto, make the height of each row the height that it would be if there were 6 weeks
  1461. if (isAuto) {
  1462. height *= this.dayGrid.rowCnt / 6;
  1463. }
  1464. core.distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
  1465. } else {
  1466. if (isAuto) {
  1467. core.undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
  1468. } else {
  1469. core.distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
  1470. }
  1471. }
  1472. };
  1473. /* Scroll
  1474. ------------------------------------------------------------------------------------------------------------------*/
  1475. DayGridView.prototype.computeDateScroll = function (duration) {
  1476. return {top: 0};
  1477. };
  1478. DayGridView.prototype.queryDateScroll = function () {
  1479. return {top: this.scroller.getScrollTop()};
  1480. };
  1481. DayGridView.prototype.applyDateScroll = function (scroll) {
  1482. if (scroll.top !== undefined) {
  1483. this.scroller.setScrollTop(scroll.top);
  1484. }
  1485. };
  1486. return DayGridView;
  1487. }(core.View));
  1488. DayGridView.prototype.dateProfileGeneratorClass = DayGridDateProfileGenerator;
  1489. var SimpleDayGrid = /** @class */ (function (_super) {
  1490. __extends(SimpleDayGrid, _super);
  1491. function SimpleDayGrid(context, dayGrid) {
  1492. var _this = _super.call(this, context, dayGrid.el) || this;
  1493. _this.slicer = new DayGridSlicer();
  1494. _this.dayGrid = dayGrid;
  1495. context.calendar.registerInteractiveComponent(_this, {el: _this.dayGrid.el});
  1496. return _this;
  1497. }
  1498. SimpleDayGrid.prototype.destroy = function () {
  1499. _super.prototype.destroy.call(this);
  1500. this.calendar.unregisterInteractiveComponent(this);
  1501. };
  1502. SimpleDayGrid.prototype.render = function (props) {
  1503. var dayGrid = this.dayGrid;
  1504. var dateProfile = props.dateProfile, dayTable = props.dayTable;
  1505. dayGrid.receiveProps(__assign({}, this.slicer.sliceProps(props, dateProfile, props.nextDayThreshold, dayGrid, dayTable), {
  1506. dateProfile: dateProfile,
  1507. cells: dayTable.cells,
  1508. isRigid: props.isRigid
  1509. }));
  1510. };
  1511. SimpleDayGrid.prototype.buildPositionCaches = function () {
  1512. this.dayGrid.buildPositionCaches();
  1513. };
  1514. SimpleDayGrid.prototype.queryHit = function (positionLeft, positionTop) {
  1515. var rawHit = this.dayGrid.positionToHit(positionLeft, positionTop);
  1516. if (rawHit) {
  1517. return {
  1518. component: this.dayGrid,
  1519. dateSpan: rawHit.dateSpan,
  1520. dayEl: rawHit.dayEl,
  1521. rect: {
  1522. left: rawHit.relativeRect.left,
  1523. right: rawHit.relativeRect.right,
  1524. top: rawHit.relativeRect.top,
  1525. bottom: rawHit.relativeRect.bottom
  1526. },
  1527. layer: 0
  1528. };
  1529. }
  1530. };
  1531. return SimpleDayGrid;
  1532. }(core.DateComponent));
  1533. var DayGridSlicer = /** @class */ (function (_super) {
  1534. __extends(DayGridSlicer, _super);
  1535. function DayGridSlicer() {
  1536. return _super !== null && _super.apply(this, arguments) || this;
  1537. }
  1538. DayGridSlicer.prototype.sliceRange = function (dateRange, dayTable) {
  1539. return dayTable.sliceRange(dateRange);
  1540. };
  1541. return DayGridSlicer;
  1542. }(core.Slicer));
  1543. var DayGridView$1 = /** @class */ (function (_super) {
  1544. __extends(DayGridView, _super);
  1545. function DayGridView(_context, viewSpec, dateProfileGenerator, parentEl) {
  1546. var _this = _super.call(this, _context, viewSpec, dateProfileGenerator, parentEl) || this;
  1547. _this.buildDayTable = core.memoize(buildDayTable);
  1548. if (_this.opt('columnHeader')) {
  1549. _this.header = new core.DayHeader(_this.context, _this.el.querySelector('.fc-head-container'));
  1550. }
  1551. _this.simpleDayGrid = new SimpleDayGrid(_this.context, _this.dayGrid);
  1552. return _this;
  1553. }
  1554. DayGridView.prototype.destroy = function () {
  1555. _super.prototype.destroy.call(this);
  1556. if (this.header) {
  1557. this.header.destroy();
  1558. }
  1559. this.simpleDayGrid.destroy();
  1560. };
  1561. DayGridView.prototype.render = function (props) {
  1562. _super.prototype.render.call(this, props);
  1563. var dateProfile = this.props.dateProfile;
  1564. var dayTable = this.dayTable =
  1565. this.buildDayTable(dateProfile, this.dateProfileGenerator);
  1566. if (this.header) {
  1567. this.header.receiveProps({
  1568. dateProfile: dateProfile,
  1569. dates: dayTable.headerDates,
  1570. datesRepDistinctDays: dayTable.rowCnt === 1,
  1571. renderIntroHtml: this.renderHeadIntroHtml
  1572. });
  1573. }
  1574. this.simpleDayGrid.receiveProps({
  1575. dateProfile: dateProfile,
  1576. dayTable: dayTable,
  1577. businessHours: props.businessHours,
  1578. dateSelection: props.dateSelection,
  1579. eventStore: props.eventStore,
  1580. eventUiBases: props.eventUiBases,
  1581. eventSelection: props.eventSelection,
  1582. eventDrag: props.eventDrag,
  1583. eventResize: props.eventResize,
  1584. isRigid: this.hasRigidRows(),
  1585. nextDayThreshold: this.nextDayThreshold
  1586. });
  1587. };
  1588. return DayGridView;
  1589. }(DayGridView));
  1590. function buildDayTable(dateProfile, dateProfileGenerator) {
  1591. var daySeries = new core.DaySeries(dateProfile.renderRange, dateProfileGenerator);
  1592. return new core.DayTable(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
  1593. }
  1594. var main = core.createPlugin({
  1595. defaultView: 'dayGridMonth',
  1596. views: {
  1597. dayGrid: DayGridView$1,
  1598. dayGridDay: {
  1599. type: 'dayGrid',
  1600. duration: {days: 1}
  1601. },
  1602. dayGridWeek: {
  1603. type: 'dayGrid',
  1604. duration: {weeks: 1}
  1605. },
  1606. dayGridMonth: {
  1607. type: 'dayGrid',
  1608. duration: {months: 1},
  1609. monthMode: true,
  1610. fixedWeekCount: true
  1611. }
  1612. }
  1613. });
  1614. exports.AbstractDayGridView = DayGridView;
  1615. exports.DayBgRow = DayBgRow;
  1616. exports.DayGrid = DayGrid;
  1617. exports.DayGridSlicer = DayGridSlicer;
  1618. exports.DayGridView = DayGridView$1;
  1619. exports.SimpleDayGrid = SimpleDayGrid;
  1620. exports.buildBasicDayTable = buildDayTable;
  1621. exports.default = main;
  1622. Object.defineProperty(exports, '__esModule', {value: true});
  1623. }));