1/*! 2FullCalendar List View Plugin v4.0.2 3Docs & 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.FullCalendarList = {}, global.FullCalendar)); 10}(this, function (exports, core) { 'use strict'; 11 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 18 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 20 WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 21 MERCHANTABLITY OR NON-INFRINGEMENT. 22 23 See the Apache Version 2.0 License for specific language governing permissions 24 and limitations under the License. 25 ***************************************************************************** */ 26 /* global Reflect, Promise */ 27 28 var extendStatics = function(d, b) { 29 extendStatics = Object.setPrototypeOf || 30 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 31 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; 32 return extendStatics(d, b); 33 }; 34 35 function __extends(d, b) { 36 extendStatics(d, b); 37 function __() { this.constructor = d; } 38 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 39 } 40 41 var ListEventRenderer = /** @class */ (function (_super) { 42 __extends(ListEventRenderer, _super); 43 function ListEventRenderer(listView) { 44 var _this = _super.call(this, listView.context) || this; 45 _this.listView = listView; 46 return _this; 47 } 48 ListEventRenderer.prototype.attachSegs = function (segs) { 49 if (!segs.length) { 50 this.listView.renderEmptyMessage(); 51 } 52 else { 53 this.listView.renderSegList(segs); 54 } 55 }; 56 ListEventRenderer.prototype.detachSegs = function () { 57 }; 58 // generates the HTML for a single event row 59 ListEventRenderer.prototype.renderSegHtml = function (seg) { 60 var _a = this.context, view = _a.view, theme = _a.theme; 61 var eventRange = seg.eventRange; 62 var eventDef = eventRange.def; 63 var eventInstance = eventRange.instance; 64 var eventUi = eventRange.ui; 65 var url = eventDef.url; 66 var classes = ['fc-list-item'].concat(eventUi.classNames); 67 var bgColor = eventUi.backgroundColor; 68 var timeHtml; 69 if (eventDef.allDay) { 70 timeHtml = core.getAllDayHtml(view); 71 } 72 else if (core.isMultiDayRange(eventRange.range)) { 73 if (seg.isStart) { 74 timeHtml = core.htmlEscape(this._getTimeText(eventInstance.range.start, seg.end, false // allDay 75 )); 76 } 77 else if (seg.isEnd) { 78 timeHtml = core.htmlEscape(this._getTimeText(seg.start, eventInstance.range.end, false // allDay 79 )); 80 } 81 else { // inner segment that lasts the whole day 82 timeHtml = core.getAllDayHtml(view); 83 } 84 } 85 else { 86 // Display the normal time text for the *event's* times 87 timeHtml = core.htmlEscape(this.getTimeText(eventRange)); 88 } 89 if (url) { 90 classes.push('fc-has-url'); 91 } 92 return '<tr class="' + classes.join(' ') + '">' + 93 (this.displayEventTime ? 94 '<td class="fc-list-item-time ' + theme.getClass('widgetContent') + '">' + 95 (timeHtml || '') + 96 '</td>' : 97 '') + 98 '<td class="fc-list-item-marker ' + theme.getClass('widgetContent') + '">' + 99 '<span class="fc-event-dot"' + 100 (bgColor ? 101 ' style="background-color:' + bgColor + '"' : 102 '') + 103 '></span>' + 104 '</td>' + 105 '<td class="fc-list-item-title ' + theme.getClass('widgetContent') + '">' + 106 '<a' + (url ? ' href="' + core.htmlEscape(url) + '"' : '') + '>
106' + 107 core.htmlEscape(eventDef.title || '') + 108 '</a>' + 109 '</td>' + 110 '</tr>'; 111 }; 112 // like "4:00am" 113 ListEventRenderer.prototype.computeEventTimeFormat = function () { 114 return { 115 hour: 'numeric', 116 minute: '2-digit', 117 meridiem: 'short' 118 }; 119 }; 120 return ListEventRenderer; 121 }(core.FgEventRenderer)); 122 123 /* 124 Responsible for the scroller, and forwarding event-related actions into the "grid". 125 */ 126 var ListView = /** @class */ (function (_super) { 127 __extends(ListView, _super); 128 function ListView(context, viewSpec, dateProfileGenerator, parentEl) { 129 var _this = _super.call(this, context, viewSpec, dateProfileGenerator, parentEl) || this; 130 _this.computeDateVars = core.memoize(computeDateVars); 131 _this.eventStoreToSegs = core.memoize(_this._eventStoreToSegs); 132 var eventRenderer = _this.eventRenderer = new ListEventRenderer(_this); 133 _this.renderContent = core.memoizeRendering(eventRenderer.renderSegs.bind(eventRenderer), eventRenderer.unrender.bind(eventRenderer)); 134 _this.el.classList.add('fc-list-view'); 135 var listViewClassNames = (_this.theme.getClass('listView') || '').split(' '); // wish we didn't have to do this 136 for (var _i = 0, listViewClassNames_1 = listViewClassNames; _i < listViewClassNames_1.length; _i++) { 137 var listViewClassName = listViewClassNames_1[_i]; 138 if (listViewClassName) { // in case input was empty string 139 _this.el.classList.add(listViewClassName); 140 } 141 } 142 _this.scroller = new core.ScrollComponent('hidden', // overflow x 143 'auto' // overflow y 144 ); 145 _this.el.appendChild(_this.scroller.el); 146 _this.contentEl = _this.scroller.el; // shortcut 147 context.calendar.registerInteractiveComponent(_this, { 148 el: _this.el 149 // TODO: make aware that it doesn't do Hits 150 }); 151 return _this; 152 } 153 ListView.prototype.render = function (props) { 154 var _a = this.computeDateVars(props.dateProfile), dayDates = _a.dayDates, dayRanges = _a.dayRanges; 155 this.dayDates = dayDates; 156 this.renderContent(this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges)); 157 }; 158 ListView.prototype.destroy = function () { 159 _super.prototype.destroy.call(this); 160 this.scroller.destroy(); // will remove the Grid too 161 this.calendar.unregisterInteractiveComponent(this); 162 }; 163 ListView.prototype.updateSize = function (isResize, viewHeight, isAuto) { 164 _super.prototype.updateSize.call(this, isResize, viewHeight, isAuto); 165 this.eventRenderer.computeSizes(isResize); 166 this.eventRenderer.assignSizes(isResize); 167 this.scroller.clear(); // sets height to 'auto' and clears overflow 168 if (!isAuto) { 169 this.scroller.setHeight(this.computeScrollerHeight(viewHeight)); 170 } 171 }; 172 ListView.prototype.computeScrollerHeight = function (viewHeight) { 173 return viewHeight - 174 core.subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller 175 }; 176 ListView.prototype._eventStoreToSegs = function (eventStore, eventUiBases, dayRanges) { 177 return this.eventRangesToSegs(core.sliceEventStore(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.nextDayThreshold).fg, dayRanges); 178 }; 179 ListView.prototype.eventRangesToSegs = function (eventRanges, dayRanges) { 180 var segs = []; 181 for (var _i = 0, eventRanges_1 = eventRanges; _i < eventRanges_1.length; _i++) { 182 var eventRange = eventRanges_1[_i]; 183 segs.push.apply(segs, this.eventRangeToSegs(eventRange, dayRanges)); 184 } 185 return segs; 186 }; 187 ListView.prototype.eventRangeToSegs = function (eventRange, dayRanges) { 188 var _a = this, dateEnv = _a.dateEnv, nextDayThreshold = _a.nextDayThreshold; 189 var range = eventRange.range; 190 var allDay = eventRange.def.allDay; 191 var dayIndex; 192 var segRange; 193 var seg; 194 var segs = []; 195 for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) { 196 segRange = core.intersectRanges(range, dayRanges[dayIndex]); 197 if (segRange) { 198 seg = { 199 component: this, 200 eventRange: eventRange, 201 start: segRange.start, 202 end: segRange.end, 203 isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(), 204 isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(), 205 dayIndex: dayIndex 206 }; 207 segs.push(seg); 208 // detect when range won't go fully into the next day, 209 // and mutate the latest seg to the be the end. 210 if (!seg.isEnd && !allDay && 211 dayIndex + 1 < dayRanges.length && 212 range.end < 213 dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) { 214 seg.end = range.end; 215 seg.isEnd = true; 216 break; 217 } 218 } 219 } 220 return segs; 221 }; 222 ListView.prototype.renderEmptyMessage = function () { 223 this.contentEl.innerHTML = 224 '<div class="fc-list-empty-wrap2">' + // TODO: try less wraps 225 '<div class="fc-list-empty-wrap1">' + 226 '<div class="fc-list-empty">' + 227 core.htmlEscape(this.opt('noEventsMessage')) + 228 '</div>' + 229 '</div>' + 230 '</div>'; 231 }; 232 // called by ListEventRenderer 233 ListView.prototype.renderSegList = function (allSegs) { 234 var segsByDay = this.groupSegsByDay(allSegs); // sparse array 235 var dayIndex; 236 var daySegs; 237 var i; 238 var tableEl = core.htmlToElement('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody></tbody></table>'); 239 var tbodyEl = tableEl.querySelector('tbody'); 240 for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) { 241 daySegs = segsByDay[dayIndex]; 242 if (daySegs) { // sparse array, so might be undefined 243 // append a day header 244 tbodyEl.appendChild(this.buildDayHeaderRow(this.dayDates[dayIndex])); 245 daySegs = this.eventRenderer.sortEventSegs(daySegs); 246 for (i = 0;
246 i < daySegs.length; i++) { 247 tbodyEl.appendChild(daySegs[i].el); // append event row 248 } 249 } 250 } 251 this.contentEl.innerHTML = ''; 252 this.contentEl.appendChild(tableEl); 253 }; 254 // Returns a sparse array of arrays, segs grouped by their dayIndex 255 ListView.prototype.groupSegsByDay = function (segs) { 256 var segsByDay = []; // sparse array 257 var i; 258 var seg; 259 for (i = 0; i < segs.length; i++) { 260 seg = segs[i]; 261 (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])) 262 .push(seg); 263 } 264 return segsByDay; 265 }; 266 // generates the HTML for the day headers that live amongst the event rows 267 ListView.prototype.buildDayHeaderRow = function (dayDate) { 268 var dateEnv = this.dateEnv; 269 var mainFormat = core.createFormatter(this.opt('listDayFormat')); // TODO: cache 270 var altFormat = core.createFormatter(this.opt('listDayAltFormat')); // TODO: cache 271 return core.createElement('tr', { 272 className: 'fc-list-heading', 273 'data-date': dateEnv.formatIso(dayDate, { omitTime: true }) 274 }, '<td class="' + (this.calendar.theme.getClass('tableListHeading') || 275 this.calendar.theme.getClass('widgetHeader')) + '" colspan="3">' + 276 (mainFormat ? 277 core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-main' }, core.htmlEscape(dateEnv.format(dayDate, mainFormat)) // inner HTML 278 ) : 279 '') + 280 (altFormat ? 281 core.buildGotoAnchorHtml(this, dayDate, { 'class': 'fc-list-heading-alt' }, core.htmlEscape(dateEnv.format(dayDate, altFormat)) // inner HTML 282 ) : 283 '') + 284 '</td>'); 285 }; 286 return ListView; 287 }(core.View)); 288 ListView.prototype.fgSegSelector = '.fc-list-item'; // which elements accept event actions 289 function computeDateVars(dateProfile) { 290 var dayStart = core.startOfDay(dateProfile.renderRange.start); 291 var viewEnd = dateProfile.renderRange.end; 292 var dayDates = []; 293 var dayRanges = []; 294 while (dayStart < viewEnd) { 295 dayDates.push(dayStart); 296 dayRanges.push({ 297 start: dayStart, 298 end: core.addDays(dayStart, 1) 299 }); 300 dayStart = core.addDays(dayStart, 1); 301 } 302 return { dayDates: dayDates, dayRanges: dayRanges }; 303 } 304 305 var main = core.createPlugin({ 306 views: { 307 list: { 308 class: ListView, 309 buttonTextKey: 'list', 310 listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' } // like "January 1, 2016" 311 }, 312 listDay: { 313 type: 'list', 314 duration: { days: 1 }, 315 listDayFormat: { weekday: 'long' } // day-of-week is all we need. full date is probably in header 316 }, 317 listWeek: { 318 type: 'list', 319 duration: { weeks: 1 }, 320 listDayFormat: { weekday: 'long' }, 321 listDayAltFormat: { month: 'long', day: 'numeric', year: 'numeric' } 322 }, 323 listMonth: { 324 type: 'list', 325 duration: { month: 1 }, 326 listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have 327 }, 328 listYear: { 329 type: 'list', 330 duration: { year: 1 }, 331 listDayAltFormat: { weekday: 'long' } // day-of-week is nice-to-have 332 } 333 } 334 }); 335 336 exports.ListView = ListView; 337 exports.default = main; 338 339 Object.defineProperty(exports, '__esModule', { value: true }); 340 341}));
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.