Procházet zdrojové kódy

fixes, remove DateComponent methods

Adam Shaw před 7 roky
rodič
revize
a9447e55e6

+ 99 - 49
src/View.ts

@@ -58,13 +58,13 @@ export default abstract class View extends DateComponent<ViewProps> {
   nowIndicatorTimeoutID: any // for refresh timing of now indicator
   nowIndicatorIntervalID: any // "
 
-  private _renderDates = memoizeRendering(this.__renderDates, this.__unrenderDates)
-  private _renderBusinessHours = memoizeRendering(this.renderBusinessHours, this.unrenderBusinessHours, [ this._renderDates ])
-  private _renderDateSelectionState = memoizeRendering(this.renderDateSelectionState, this.unrenderDateSelection, [ this._renderDates ])
-  private _renderEvents = memoizeRendering(this.__renderEvents, this.unrenderEvents, [ this._renderDates ])
-  private _renderEventSelection = memoizeRendering(this.renderEventSelection, this.unrenderEventSelection, [ this._renderEvents ])
-  private _renderEventDragState = memoizeRendering(this.renderEventDragState, this.unrenderEventDragState, [ this._renderDates ])
-  private _renderEventResizeState = memoizeRendering(this.renderEventResizeState, this.unrenderEventResizeState, [ this._renderDates ])
+  private renderDatesMem = memoizeRendering(this.renderDatesWrap, this.unrenderDatesWrap)
+  private renderBusinessHoursMem = memoizeRendering(this.renderBusinessHours, this.unrenderBusinessHours, [ this.renderDatesMem ])
+  private renderDateSelectionMem = memoizeRendering(this.renderDateSelectionWrap, this.unrenderDateSelectionWrap, [ this.renderDatesMem ])
+  private renderEventsMem = memoizeRendering(this.renderEventsWrap, this.unrenderEvents, [ this.renderDatesMem ])
+  private renderEventSelectionMem = memoizeRendering(this.renderEventSelectionWrap, this.unrenderEventSelectionWrap, [ this.renderEventsMem ])
+  private renderEventDragMem = memoizeRendering(this.renderEventDragWrap, this.unrenderEventDragWrap, [ this.renderDatesMem ])
+  private renderEventResizeMem = memoizeRendering(this.renderEventResizeWrap, this.unrenderEventResizeWrap, [ this.renderDatesMem ])
 
 
   constructor(context: ComponentContext, viewSpec: ViewSpec, dateProfileGenerator: DateProfileGenerator, parentEl: HTMLElement) {
@@ -121,31 +121,20 @@ export default abstract class View extends DateComponent<ViewProps> {
 
 
   render(props: ViewProps) {
-    this._renderDates(props.dateProfile)
-    this._renderBusinessHours(props.businessHours)
-    this._renderDateSelectionState(props.dateSelection)
-    this._renderEvents(props.eventStore, props.eventUis)
-    this._renderEventSelection(props.eventSelection)
-    this._renderEventDragState(props.eventDrag)
-    this._renderEventResizeState(props.eventResize)
+    this.renderDatesMem(props.dateProfile)
+    this.renderBusinessHoursMem(props.businessHours)
+    this.renderDateSelectionMem(props.dateSelection)
+    this.renderEventsMem(props.eventStore, props.eventUis)
+    this.renderEventSelectionMem(props.eventSelection)
+    this.renderEventDragMem(props.eventDrag)
+    this.renderEventResizeMem(props.eventResize)
   }
 
 
   destroy() {
     super.destroy()
 
-    this._renderDates.unrender() // should unrender everything else
-  }
-
-
-  // util for subclasses
-  sliceEvents(eventStore: EventStore, eventUis: EventUiHash, allDay: boolean): EventRenderRange[] {
-    return sliceEventStore(
-      eventStore,
-      eventUis,
-      this.props.dateProfile.activeRange,
-      allDay ? this.nextDayThreshold : null
-    )
+    this.renderDatesMem.unrender() // should unrender everything else
   }
 
 
@@ -154,7 +143,6 @@ export default abstract class View extends DateComponent<ViewProps> {
 
 
   updateSize(viewHeight: number, isAuto: boolean, isResize: boolean) {
-    let { fillRenderer, eventRenderer, mirrorRenderer } = this
 
     if (isResize || this.isDateSizeDirty || this.isEventSizeDirty) {
       // sort of the catch-all sizing
@@ -164,14 +152,6 @@ export default abstract class View extends DateComponent<ViewProps> {
 
     this.isDateSizeDirty = false
     this.isEventSizeDirty = false
-
-    fillRenderer && fillRenderer.computeSizes(isResize)
-    eventRenderer && eventRenderer.computeSizes(isResize)
-    mirrorRenderer && mirrorRenderer.computeSizes(isResize)
-
-    fillRenderer && fillRenderer.assignSizes(isResize)
-    eventRenderer && eventRenderer.assignSizes(isResize)
-    mirrorRenderer && mirrorRenderer.assignSizes(isResize)
   }
 
 
@@ -182,15 +162,14 @@ export default abstract class View extends DateComponent<ViewProps> {
   // Date Rendering
   // -----------------------------------------------------------------------------------------------------------------
 
-
-  __renderDates(dateProfile: DateProfile) {
+  renderDatesWrap(dateProfile: DateProfile) {
     this.renderDates(dateProfile)
     this.addScroll({ isDateInit: true })
     this.startNowIndicator() // shouldn't render yet because updateSize will be called soon
     this.isDateSizeDirty = true
   }
 
-  __unrenderDates() {
+  unrenderDatesWrap() {
     this.stopNowIndicator()
     this.unrenderDates()
   }
@@ -199,39 +178,110 @@ export default abstract class View extends DateComponent<ViewProps> {
   unrenderDates() {}
 
 
+  // Business Hours
+  // -----------------------------------------------------------------------------------------------------------------
+
+  renderBusinessHours(businessHours: EventStore) {}
+  unrenderBusinessHours() {}
+
+
+  // Date Selection
+  // -----------------------------------------------------------------------------------------------------------------
+
+  renderDateSelectionWrap(selection: DateSpan) {
+    if (selection) {
+      this.renderDateSelection(selection)
+    }
+  }
+
+  unrenderDateSelectionWrap(selection: DateSpan) {
+    if (selection) {
+      this.unrenderDateSelection(selection)
+    }
+  }
+
+  renderDateSelection(selection: DateSpan) {}
+  unrenderDateSelection(selection: DateSpan) {}
+
+
   // Event Rendering
   // -----------------------------------------------------------------------------------------------------------------
 
-  __renderEvents(eventStore: EventStore, eventUis: EventUiHash) {
+  renderEventsWrap(eventStore: EventStore, eventUis: EventUiHash) {
     this.isEventSizeDirty = true
     this.renderEvents(eventStore, eventUis)
   }
 
   renderEvents(eventStore: EventStore, eventUis: EventUiHash) {}
+  unrenderEvents() {}
+
+  // util for subclasses
+  sliceEvents(eventStore: EventStore, eventUis: EventUiHash, allDay: boolean): EventRenderRange[] {
+    return sliceEventStore(
+      eventStore,
+      eventUis,
+      this.props.dateProfile.activeRange,
+      allDay ? this.nextDayThreshold : null
+    )
+  }
 
 
-  // Other Rendering (uses eventRenderer and fillRenderer)
+  // Event Selection
   // -----------------------------------------------------------------------------------------------------------------
 
+  renderEventSelectionWrap(instanceId: string) {
+    if (instanceId) {
+      this.renderEventSelection(instanceId)
+    }
+  }
+
+  unrenderEventSelectionWrap(instanceId: string) {
+    if (instanceId) {
+      this.unrenderEventSelection(instanceId)
+    }
+  }
 
-  renderBusinessHours(businessHours: EventStore) {}
   renderEventSelection(instanceId: string) {}
+  unrenderEventSelection(instanceId: string) {}
 
-  renderEventDragState(state: EventInteractionUiState) {}
-  unrenderEventDragState() {}
 
-  renderEventResizeState(state: EventInteractionUiState) {}
-  unrenderEventResizeState() {}
+  // Event Drag
+  // -----------------------------------------------------------------------------------------------------------------
 
-  renderDateSelectionState(selection: DateSpan) {
-    if (selection) {
-      this.renderDateSelection(selection)
+  renderEventDragWrap(state: EventInteractionUiState) {
+    if (state) {
+      this.renderEventDrag(state)
     }
   }
 
-  renderDateSelection(selection: DateSpan) {
+  unrenderEventDragWrap(state: EventInteractionUiState) {
+    if (state) {
+      this.unrenderEventDrag(state)
+    }
   }
 
+  renderEventDrag(state: EventInteractionUiState) {}
+  unrenderEventDrag(state: EventInteractionUiState) {}
+
+
+  // Event Resize
+  // -----------------------------------------------------------------------------------------------------------------
+
+  renderEventResizeWrap(state: EventInteractionUiState) {
+    if (state) {
+      this.renderEventResize(state)
+    }
+  }
+
+  unrenderEventResizeWrap(state: EventInteractionUiState) {
+    if (state) {
+      this.unrenderEventResize(state)
+    }
+  }
+
+  renderEventResize(state: EventInteractionUiState) {}
+  unrenderEventResize(state: EventInteractionUiState) {}
+
 
   /* Now Indicator
   ------------------------------------------------------------------------------------------------------------------*/

+ 106 - 29
src/agenda/TimeGrid.ts

@@ -11,7 +11,7 @@ import { ComponentContext } from '../component/Component'
 import DateComponent, { Seg, EventSegUiInteractionState } from '../component/DateComponent'
 import DayBgRow from '../basic/DayBgRow'
 import { DateProfile } from '../DateProfileGenerator'
-import { memoizeRendering } from '../component/memoized-rendering'
+import { memoizeRendering, MemoizedRendering } from '../component/memoized-rendering'
 
 
 /* A component that renders one or more columns of vertical time slots
@@ -87,22 +87,63 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   highlightContainerEls: HTMLElement[]
   businessContainerEls: HTMLElement[]
 
-  private _renderSlats = memoizeRendering(this.renderSlats)
-  private _renderColumns = memoizeRendering(this.renderColumns, this.unrenderColumns)
-  private _renderBusinessHourSegs = memoizeRendering(this.renderBusinessHourSegs, this.unrenderBusinessHours, [ this._renderColumns ])
-  private _renderDateSelectionSegs = memoizeRendering(this.renderDateSelectionSegs, this.unrenderDateSelection, [ this._renderColumns ])
-  private _renderEventSegs = memoizeRendering(this.renderEventSegs, this.unrenderEvents, [ this._renderColumns ])
-  private _renderEventSelection = memoizeRendering(this.renderEventSelection, this.unrenderEventSelection, [ this._renderEventSegs ])
-  private _renderEventDragSegs = memoizeRendering(this.renderEventDragSegs, this.unrenderEventDragSegs, [ this._renderColumns ])
-  private _renderEventResizeSegs = memoizeRendering(this.renderEventResizeSegs, this.unrenderEventResizeSegs, [ this._renderColumns ])
+  private renderSlats = memoizeRendering(this._renderSlats)
+  private renderColumns: MemoizedRendering<[TimeGridCell[], DateProfile]>
+  private renderBusinessHours: MemoizedRendering<[TimeGridSeg[]]>
+  private renderDateSelection: MemoizedRendering<[TimeGridSeg[]]>
+  private renderEvents: MemoizedRendering<[TimeGridSeg[]]>
+  private renderEventSelection: MemoizedRendering<[string]>
+  private renderEventDrag: MemoizedRendering<[EventSegUiInteractionState]>
+  private renderEventResize: MemoizedRendering<[EventSegUiInteractionState]>
 
 
   constructor(context: ComponentContext, el: HTMLElement, renderProps: RenderProps) {
     super(context, el)
 
-    this.eventRenderer = new TimeGridEventRenderer(this)
+    let eventRenderer = this.eventRenderer = new TimeGridEventRenderer(this)
+    let fillRenderer = this.fillRenderer = new TimeGridFillRenderer(this)
     this.mirrorRenderer = new TimeGridMirrorRenderer(this)
-    this.fillRenderer = new TimeGridFillRenderer(this)
+
+    let renderColumns = this.renderColumns = memoizeRendering(
+      this._renderColumns,
+      this._unrenderColumns
+    )
+
+    this.renderBusinessHours = memoizeRendering(
+      fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'),
+      fillRenderer.unrender.bind(fillRenderer, 'businessHours'),
+      [ renderColumns ]
+    )
+
+    this.renderDateSelection = memoizeRendering(
+      this._renderDateSelection,
+      this._unrenderDateSelection,
+      [ renderColumns ]
+    )
+
+    this.renderEvents = memoizeRendering(
+      this._renderEventSegs,
+      this._unrenderEventSegs,
+      [ renderColumns ]
+    )
+
+    this.renderEventSelection = memoizeRendering(
+      eventRenderer.selectByInstanceId.bind(eventRenderer),
+      eventRenderer.unselectByInstanceId.bind(eventRenderer),
+      [ this.renderEvents ]
+    )
+
+    this.renderEventDrag = memoizeRendering(
+      this._renderEventDrag,
+      this._unrenderEventDrag,
+      [ renderColumns ]
+    )
+
+    this.renderEventResize = memoizeRendering(
+      this._renderEventResize,
+      this._unrenderEventResize,
+      [ renderColumns ]
+    )
 
     this.processOptions()
 
@@ -192,14 +233,14 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
     let cells = props.cells
     this.colCnt = cells.length
 
-    this._renderSlats(props.dateProfile)
-    this._renderColumns(props.cells, props.dateProfile)
-    this._renderBusinessHourSegs(props.businessHourSegs)
-    this._renderDateSelectionSegs(props.dateSelectionSegs)
-    this._renderEventSegs(props.eventSegs)
-    this._renderEventSelection(props.eventSelection)
-    this._renderEventDragSegs(props.eventDrag)
-    this._renderEventResizeSegs(props.eventResize)
+    this.renderSlats(props.dateProfile)
+    this.renderColumns(props.cells, props.dateProfile)
+    this.renderBusinessHours(props.businessHourSegs)
+    this.renderDateSelection(props.dateSelectionSegs)
+    this.renderEvents(props.eventSegs)
+    this.renderEventSelection(props.eventSelection)
+    this.renderEventDrag(props.eventDrag)
+    this.renderEventResize(props.eventResize)
   }
 
 
@@ -207,8 +248,8 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
     super.destroy()
 
     // should unrender everything else too
-    this._renderSlats.unrender()
-    this._renderColumns.unrender()
+    this.renderSlats.unrender()
+    this.renderColumns.unrender()
   }
 
 
@@ -235,7 +276,7 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
-  renderSlats(dateProfile: DateProfile) {
+  _renderSlats(dateProfile: DateProfile) {
     let { theme } = this
 
     this.slatContainerEl.innerHTML =
@@ -299,7 +340,7 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
-  renderColumns(cells: TimeGridCell[], dateProfile: DateProfile) {
+  _renderColumns(cells: TimeGridCell[], dateProfile: DateProfile) {
     let { theme } = this
 
     let bgRow = new DayBgRow(this.context)
@@ -330,7 +371,7 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
-  unrenderColumns() {
+  _unrenderColumns() {
     this.unrenderContentSkeleton()
   }
 
@@ -627,11 +668,37 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
+  /* Event Drag Visualization
+  ------------------------------------------------------------------------------------------------------------------*/
+
+
+  _renderEventDrag(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.hideByHash(state.affectedInstances)
+
+      if (state.isEvent) {
+        this.mirrorRenderer.renderSegs(state.segs, { isDragging: true, sourceSeg: state.sourceSeg })
+      } else {
+        this.fillRenderer.renderSegs('highlight', state.segs)
+      }
+    }
+  }
+
+
+  _unrenderEventDrag(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.showByHash(state.affectedInstances)
+      this.mirrorRenderer.unrender()
+      this.fillRenderer.unrender('highlight')
+    }
+  }
+
+
   /* Event Resize Visualization
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  renderEventResizeSegs(state: EventSegUiInteractionState) {
+  _renderEventResize(state: EventSegUiInteractionState) {
     if (state) {
       this.eventRenderer.hideByHash(state.affectedInstances)
       this.mirrorRenderer.renderSegs(state.segs, { isResizing: true, sourceSeg: state.sourceSeg })
@@ -639,12 +706,20 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
+  _unrenderEventResize(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.showByHash(state.affectedInstances)
+      this.mirrorRenderer.unrender()
+    }
+  }
+
+
   /* Selection
   ------------------------------------------------------------------------------------------------------------------*/
 
 
   // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
-  renderDateSelectionSegs(segs: Seg[]) {
+  _renderDateSelection(segs: Seg[]) {
     if (segs) {
       if (this.opt('selectMirror')) {
         this.mirrorRenderer.renderSegs(segs, { isSelecting: true })
@@ -655,7 +730,9 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   }
 
 
-}
+  _unrenderDateSelection() {
+    this.mirrorRenderer.unrender()
+    this.fillRenderer.unrender('highlight')
+  }
 
-TimeGrid.prototype.doesDragMirror = true
-TimeGrid.prototype.doesDragHighlight = false
+}

+ 96 - 28
src/basic/DayGrid.ts

@@ -22,7 +22,7 @@ import { EventRenderRange } from '../component/event-rendering'
 import { buildGotoAnchorHtml, getDayClasses } from '../component/date-rendering'
 import DayBgRow from './DayBgRow'
 import { DateProfile } from '../DateProfileGenerator'
-import { memoizeRendering } from '../component/memoized-rendering'
+import { memoizeRendering, MemoizedRendering } from '../component/memoized-rendering'
 
 const DAY_NUM_FORMAT = createFormatter({ day: 'numeric' })
 const WEEK_NUM_FORMAT = createFormatter({ week: 'numeric' })
@@ -85,21 +85,62 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   segPopover: Popover // the Popover that holds events that can't fit in a cell. null when not visible
   segPopoverTile: DayTile
 
-  private _renderCells = memoizeRendering(this.renderCells, this.unrenderCells)
-  private _renderBusinessHourSegs = memoizeRendering(this.renderBusinessHourSegs, this.unrenderBusinessHours, [ this._renderCells ])
-  private _renderDateSelectionSegs = memoizeRendering(this.renderDateSelectionSegs, this.unrenderDateSelection, [ this._renderCells ])
-  private _renderEventSegs = memoizeRendering(this.renderEventSegs, this.unrenderEvents, [ this._renderCells ])
-  private _renderEventSelection = memoizeRendering(this.renderEventSelection, this.unrenderEventSelection, [ this._renderCells ])
-  private _renderEventDragSegs = memoizeRendering(this.renderEventDragSegs, this.unrenderEventDragSegs, [ this._renderCells ])
-  private _renderEventResizeSegs = memoizeRendering(this.renderEventResizeSegs, this.unrenderEventResizeSegs, [ this._renderCells ])
+  private renderCells: MemoizedRendering<[DayGridCell[][], boolean]>
+  private renderBusinessHours: MemoizedRendering<[DayGridSeg[]]>
+  private renderDateSelection: MemoizedRendering<[DayGridSeg[]]>
+  private renderEvents: MemoizedRendering<[DayGridSeg[]]>
+  private renderEventSelection: MemoizedRendering<[string]>
+  private renderEventDrag: MemoizedRendering<[EventSegUiInteractionState]>
+  private renderEventResize: MemoizedRendering<[EventSegUiInteractionState]>
 
 
   constructor(context, el, renderProps: RenderProps) {
     super(context, el)
 
-    this.eventRenderer = new DayGridEventRenderer(this)
+    let eventRenderer = this.eventRenderer = new DayGridEventRenderer(this)
+    let fillRenderer = this.fillRenderer = new DayGridFillRenderer(this)
     this.mirrorRenderer = new DayGridMirrorRenderer(this)
-    this.fillRenderer = new DayGridFillRenderer(this)
+
+    let renderCells = this.renderCells = memoizeRendering(
+      this._renderCells,
+      this._unrenderCells
+    )
+
+    this.renderBusinessHours = memoizeRendering(
+      fillRenderer.renderSegs.bind(fillRenderer, 'businessHours'),
+      fillRenderer.unrender.bind(fillRenderer, 'businessHours'),
+      [ renderCells ]
+    )
+
+    this.renderDateSelection = memoizeRendering(
+      fillRenderer.renderSegs.bind(fillRenderer, 'highlight'),
+      fillRenderer.unrender.bind(fillRenderer, 'highlight'),
+      [ renderCells ]
+    )
+
+    this.renderEvents = memoizeRendering(
+      this._renderEventSegs,
+      this._unrenderEventSegs,
+      [ renderCells ]
+    )
+
+    this.renderEventSelection = memoizeRendering(
+      eventRenderer.selectByInstanceId.bind(eventRenderer),
+      eventRenderer.unselectByInstanceId.bind(eventRenderer),
+      [ this.renderEvents ]
+    )
+
+    this.renderEventDrag = memoizeRendering(
+      this._renderEventDrag,
+      this._unrenderEventDrag,
+      [ renderCells ]
+    )
+
+    this.renderEventResize = memoizeRendering(
+      this._renderEventResize,
+      this._unrenderEventResize,
+      [ renderCells ]
+    )
 
     this.renderProps = renderProps
   }
@@ -110,13 +151,13 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
     this.rowCnt = cells.length
     this.colCnt = cells[0].length
 
-    this._renderCells(cells, props.isRigid)
-    this._renderBusinessHourSegs(props.businessHourSegs)
-    this._renderDateSelectionSegs(props.dateSelectionSegs)
-    this._renderEventSegs(props.eventSegs)
-    this._renderEventSelection(props.eventSelection)
-    this._renderEventDragSegs(props.eventDrag)
-    this._renderEventResizeSegs(props.eventResize)
+    this.renderCells(cells, props.isRigid)
+    this.renderBusinessHours(props.businessHourSegs)
+    this.renderDateSelection(props.dateSelectionSegs)
+    this.renderEvents(props.eventSegs)
+    this.renderEventSelection(props.eventSelection)
+    this.renderEventDrag(props.eventDrag)
+    this.renderEventResize(props.eventResize)
 
     if (this.segPopoverTile) {
       this.updateSegPopoverTile()
@@ -127,7 +168,7 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   destroy() {
     super.destroy()
 
-    this._renderCells.unrender() // will unrender everything else
+    this.renderCells.unrender() // will unrender everything else
   }
 
 
@@ -156,7 +197,7 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  renderCells(cells: DayGridCell[][], isRigid: boolean) {
+  _renderCells(cells: DayGridCell[][], isRigid: boolean) {
     let { view, dateEnv } = this
     let { rowCnt, colCnt } = this
     let html = ''
@@ -206,7 +247,7 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   }
 
 
-  unrenderCells() {
+  _unrenderCells() {
     this.removeSegPopover()
   }
 
@@ -424,8 +465,8 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  renderBgEventSegs(segs: Seg[]) {
-    super.renderBgEventSegs(
+  _renderBgEventSegs(segs: Seg[]) {
+    super._renderBgEventSegs(
       // don't render timed background events
       segs.filter(function(seg) {
         return seg.eventRange.def.allDay
@@ -435,9 +476,30 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
 
 
   // Unrenders all events currently rendered on the grid
-  unrenderEvents() {
+  _unrenderEventSegs() {
+    super._unrenderEventSegs()
+
     this.removeSegPopover() // removes the "more.." events popover
-    super.unrenderEvents()
+  }
+
+
+  /* Event Drag Visualization
+  ------------------------------------------------------------------------------------------------------------------*/
+
+
+  _renderEventDrag(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.hideByHash(state.affectedInstances)
+      this.fillRenderer.renderSegs('highlight', state.segs)
+    }
+  }
+
+
+  _unrenderEventDrag(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.showByHash(state.affectedInstances)
+      this.fillRenderer.unrender('highlight')
+    }
   }
 
 
@@ -445,7 +507,7 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   ------------------------------------------------------------------------------------------------------------------*/
 
 
-  renderEventResizeSegs(state: EventSegUiInteractionState) {
+  _renderEventResize(state: EventSegUiInteractionState) {
     if (state) {
       this.eventRenderer.hideByHash(state.affectedInstances)
       this.fillRenderer.renderSegs('highlight', state.segs)
@@ -454,6 +516,15 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   }
 
 
+  _unrenderEventResize(state: EventSegUiInteractionState) {
+    if (state) {
+      this.eventRenderer.showByHash(state.affectedInstances)
+      this.fillRenderer.unrender('highlight')
+      this.mirrorRenderer.unrender()
+    }
+  }
+
+
   /* More+ Link Popover
   ------------------------------------------------------------------------------------------------------------------*/
 
@@ -788,6 +859,3 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   }
 
 }
-
-DayGrid.prototype.doesDragMirror = false
-DayGrid.prototype.doesDragHighlight = true

+ 46 - 41
src/basic/DayTile.ts

@@ -10,7 +10,7 @@ import { addDays, DateMarker } from '../datelib/marker'
 import { removeElement } from '../util/dom-manip'
 import { ComponentContext } from '../component/Component'
 import { EventInstanceHash } from '../structs/event'
-import { memoizeRendering } from '../component/memoized-rendering'
+import { memoizeRendering, MemoizedRendering } from '../component/memoized-rendering'
 
 export interface DayTileProps {
   date: DateMarker
@@ -27,33 +27,61 @@ export default class DayTile extends DateComponent<DayTileProps> {
   height: number
   offsetTracker: OffsetTracker // TODO: abstraction for tracking dims of whole element rect
 
-  private _renderFrame = memoizeRendering(this.renderFrame)
-  private _renderEventSegs = memoizeRendering(this.renderEventSegs, this.unrenderEvents, [ this._renderFrame ])
-  private _renderEventSelection = memoizeRendering(this.renderEventSelection, this.unrenderEventSelection, [ this._renderEventSegs ])
-  private _renderEventDrag = memoizeRendering(this.renderEventDrag, this.unrenderEventDrag, [ this._renderFrame ])
-  private _renderEventResize = memoizeRendering(this.renderEventResize, this.unrenderEventResize, [ this._renderFrame ])
+  private renderFrame: MemoizedRendering<[DateMarker]>
+  private renderEvents: MemoizedRendering<[Seg[]]>
+  private renderEventSelection: MemoizedRendering<[string]>
+  private renderEventDrag: MemoizedRendering<[EventInstanceHash]>
+  private renderEventResize: MemoizedRendering<[EventInstanceHash]>
 
   constructor(context: ComponentContext, el: HTMLElement) {
     super(context, el)
 
-    this.eventRenderer = new DayTileEventRenderer(this)
+    let eventRenderer = this.eventRenderer = new DayTileEventRenderer(this)
+
+    let renderFrame = this.renderFrame = memoizeRendering(
+      this._renderFrame
+    )
+
+    let renderEvents = this.renderEvents = memoizeRendering(
+      this._renderEventSegs,
+      this._unrenderEventSegs,
+      [ renderFrame ]
+    )
+
+    this.renderEventSelection = memoizeRendering(
+      eventRenderer.selectByInstanceId.bind(eventRenderer),
+      eventRenderer.unselectByInstanceId.bind(eventRenderer),
+      [ renderEvents ]
+    )
+
+    this.renderEventDrag = memoizeRendering(
+      eventRenderer.hideByHash.bind(eventRenderer),
+      eventRenderer.showByHash.bind(eventRenderer),
+      [ renderFrame ]
+    )
+
+    this.renderEventResize = memoizeRendering(
+      eventRenderer.hideByHash.bind(eventRenderer),
+      eventRenderer.showByHash.bind(eventRenderer),
+      [ renderFrame ]
+    )
   }
 
   render(props: DayTileProps) {
-    this._renderFrame(props.date)
-    this._renderEventSegs(props.segs)
-    this._renderEventSelection(props.eventSelection)
-    this._renderEventDrag(props.eventDragInstances)
-    this._renderEventResize(props.eventResizeInstances)
+    this.renderFrame(props.date)
+    this.renderEvents(props.segs)
+    this.renderEventSelection(props.eventSelection)
+    this.renderEventDrag(props.eventDragInstances)
+    this.renderEventResize(props.eventResizeInstances)
   }
 
   destroy() {
     super.destroy()
 
-    this._renderFrame.unrender() // should unrender everything else
+    this.renderFrame.unrender() // should unrender everything else
   }
 
-  renderFrame(date: DateMarker) {
+  _renderFrame(date: DateMarker) {
     let { theme, dateEnv } = this
 
     let title = dateEnv.format(
@@ -76,30 +104,6 @@ export default class DayTile extends DateComponent<DayTileProps> {
     this.segContainerEl = this.el.querySelector('.fc-event-container')
   }
 
-  renderEventDrag(affectedInstances: EventInstanceHash) {
-    if (affectedInstances) {
-      this.eventRenderer.hideByHash(affectedInstances)
-    }
-  }
-
-  unrenderEventDrag(affectedInstances: EventInstanceHash) {
-    if (affectedInstances) {
-      this.eventRenderer.showByHash(affectedInstances)
-    }
-  }
-
-  renderEventResize(affectedInstances: EventInstanceHash) {
-    if (affectedInstances) {
-      this.eventRenderer.hideByHash(affectedInstances)
-    }
-  }
-
-  unrenderEventResize(affectedInstances: EventInstanceHash) {
-    if (affectedInstances) {
-      this.eventRenderer.showByHash(affectedInstances)
-    }
-  }
-
   prepareHits() {
     let rect = computeRect(this.el)
     this.width = rect.right - rect.left
@@ -141,6 +145,10 @@ export default class DayTile extends DateComponent<DayTileProps> {
 
 }
 
+DayTile.prototype.isInteractable = true
+DayTile.prototype.useEventCenter = false
+
+
 export class DayTileEventRenderer extends SimpleDayGridEventRenderer {
 
   dayTile: DayTile
@@ -164,6 +172,3 @@ export class DayTileEventRenderer extends SimpleDayGridEventRenderer {
   }
 
 }
-
-DayTile.prototype.isInteractable = true
-DayTile.prototype.useEventCenter = false

+ 14 - 122
src/component/DateComponent.ts

@@ -42,8 +42,6 @@ export default class DateComponent<PropsType> extends Component<PropsType> {
   // self-config, overridable by subclasses. must set on prototype
   isInteractable: boolean
   useEventCenter: boolean // for dragging geometry
-  doesDragMirror: boolean // for events that ORIGINATE from this component
-  doesDragHighlight: boolean // for events that ORIGINATE from this component
   fgSegSelector: string // lets eventRender produce elements without fc-event class
   bgSegSelector: string
 
@@ -81,48 +79,10 @@ export default class DateComponent<PropsType> extends Component<PropsType> {
   }
 
 
-  // Business Hours
-  // ---------------------------------------------------------------------------------------------------------------
-
-  renderBusinessHourSegs(segs: Seg[]) {
-    if (this.fillRenderer) {
-      this.fillRenderer.renderSegs('businessHours', segs)
-    }
-  }
-
-  unrenderBusinessHours() {
-    if (this.fillRenderer) {
-      this.fillRenderer.unrender('businessHours')
-    }
-  }
-
-
-  // Date Selection
-  // ---------------------------------------------------------------------------------------------------------------
-
-  renderDateSelectionSegs(segs: Seg[]) {
-    if (segs) {
-      if (this.fillRenderer) {
-        this.fillRenderer.renderSegs('highlight', segs)
-      }
-    }
-  }
-
-  unrenderDateSelection() {
-    if (this.mirrorRenderer) {
-      this.mirrorRenderer.unrender()
-    }
-
-    if (this.fillRenderer) {
-      this.fillRenderer.unrender('highlight')
-    }
-  }
-
-
   // Events
   // -----------------------------------------------------------------------------------------------------------------
 
-  renderEventSegs(segs: Seg[]) {
+  _renderEventSegs(segs: Seg[]) {
     let bgSegs = []
     let fgSegs = []
 
@@ -134,60 +94,45 @@ export default class DateComponent<PropsType> extends Component<PropsType> {
       }
     }
 
-    this.renderFgEventSegs(fgSegs)
-    this.renderBgEventSegs(bgSegs)
+    this._renderFgEventSegs(fgSegs)
+    this._renderBgEventSegs(bgSegs)
   }
 
-  renderFgEventSegs(segs: Seg[]) {
+  _renderFgEventSegs(segs: Seg[]) {
     if (this.eventRenderer) {
       this.eventRenderer.renderSegs(segs)
     }
   }
 
-  renderBgEventSegs(segs: Seg[]) {
+  _renderBgEventSegs(segs: Seg[]) {
     if (this.fillRenderer) {
       this.fillRenderer.renderSegs('bgEvent', segs)
     }
   }
 
-  unrenderEvents() {
-    this.unrenderFgEventSegs()
-    this.unrenderBgEventSegs()
+  _unrenderEventSegs() {
+    this._unrenderFgEventSegs()
+    this._unrenderBgEventSegs()
   }
 
-  unrenderFgEventSegs() {
+  _unrenderFgEventSegs() {
     if (this.eventRenderer) {
       this.eventRenderer.unrender()
     }
   }
 
-  unrenderBgEventSegs() {
+  _unrenderBgEventSegs() {
     if (this.fillRenderer) {
       this.fillRenderer.unrender('bgEvent')
     }
   }
 
 
-  // Event Instance Selection (aka long-touch focus)
-  // -----------------------------------------------------------------------------------------------------------------
-  // TODO: show/hide according to groupId?
-
-  renderEventSelection(instanceId) {
-    if (instanceId && this.eventRenderer) {
-      this.eventRenderer.selectByInstanceId(instanceId)
-    }
-  }
-
-  unrenderEventSelection(instanceId) {
-    if (instanceId && this.eventRenderer) {
-      this.eventRenderer.unselectByInstanceId(instanceId)
-    }
-  }
-
-
+  // TODO: WHAT ABOUT (sourceSeg && sourceSeg.component.doesDragMirror)
+  //
   // Event Drag-n-Drop Rendering (for both events and external elements)
   // ---------------------------------------------------------------------------------------------------------------
-
+  /*
   renderEventDragSegs(state: EventSegUiInteractionState) {
     if (state) {
       let { isEvent, segs, sourceSeg } = state
@@ -214,58 +159,7 @@ export default class DateComponent<PropsType> extends Component<PropsType> {
       }
     }
   }
-
-  unrenderEventDragSegs(state: EventSegUiInteractionState) {
-    if (state) {
-      this.unrenderEventDrag(state.affectedInstances)
-    }
-  }
-
-  unrenderEventDrag(affectedInstances: EventInstanceHash) {
-    if (this.eventRenderer) {
-      this.eventRenderer.showByHash(affectedInstances)
-    }
-
-    if (this.mirrorRenderer) {
-      this.mirrorRenderer.unrender()
-    }
-
-    if (this.fillRenderer) {
-      this.fillRenderer.unrender('highlight')
-    }
-  }
-
-
-  // Event Resizing
-  // ---------------------------------------------------------------------------------------------------------------
-
-  renderEventResizeSegs(state: EventSegUiInteractionState) {
-    if (this.eventRenderer) {
-      this.eventRenderer.hideByHash(state.affectedInstances)
-    }
-
-    // subclasses can override and do something with segs
-  }
-
-  unrenderEventResizeSegs(state: EventSegUiInteractionState) {
-    if (state) {
-      this.unrenderEventResize(state.affectedInstances)
-    }
-  }
-
-  unrenderEventResize(affectedInstances: EventInstanceHash) {
-    if (this.eventRenderer) {
-      this.eventRenderer.showByHash(affectedInstances)
-    }
-
-    if (this.mirrorRenderer) {
-      this.mirrorRenderer.unrender()
-    }
-
-    if (this.fillRenderer) {
-      this.fillRenderer.unrender('highlight')
-    }
-  }
+  */
 
 
   // Hit System
@@ -437,7 +331,5 @@ export default class DateComponent<PropsType> extends Component<PropsType> {
 
 DateComponent.prototype.isInteractable = false
 DateComponent.prototype.useEventCenter = true
-DateComponent.prototype.doesDragMirror = false
-DateComponent.prototype.doesDragHighlight = false
 DateComponent.prototype.fgSegSelector = '.fc-event-container > *'
 DateComponent.prototype.bgSegSelector = '.fc-bgevent:not(.fc-nonbusiness)'

+ 26 - 18
src/component/renderers/FgEventRenderer.ts

@@ -267,40 +267,48 @@ export default abstract class FgEventRenderer {
 
 
   hideByHash(hash) {
-    for (let seg of this.segs) {
-      if (hash[seg.eventRange.instance.instanceId]) {
-        seg.el.style.visibility = 'hidden'
+    if (hash) {
+      for (let seg of this.segs) {
+        if (hash[seg.eventRange.instance.instanceId]) {
+          seg.el.style.visibility = 'hidden'
+        }
       }
     }
   }
 
 
   showByHash(hash) {
-    for (let seg of this.segs) {
-      if (hash[seg.eventRange.instance.instanceId]) {
-        seg.el.style.visibility = ''
+    if (hash) {
+      for (let seg of this.segs) {
+        if (hash[seg.eventRange.instance.instanceId]) {
+          seg.el.style.visibility = ''
+        }
       }
     }
   }
 
 
-  selectByInstanceId(instanceId) {
-    for (let seg of this.segs) {
-      let eventInstance = seg.eventRange.instance
-      if (
-        eventInstance && eventInstance.instanceId === instanceId &&
-        seg.el // necessary?
-      ) {
-        seg.el.classList.add('fc-selected')
+  selectByInstanceId(instanceId: string) {
+    if (instanceId) {
+      for (let seg of this.segs) {
+        let eventInstance = seg.eventRange.instance
+        if (
+          eventInstance && eventInstance.instanceId === instanceId &&
+          seg.el // necessary?
+        ) {
+          seg.el.classList.add('fc-selected')
+        }
       }
     }
   }
 
 
-  unselectByInstanceId(instanceId) {
-    for (let seg of this.segs) {
-      if (seg.el) { // necessary?
-        seg.el.classList.remove('fc-selected')
+  unselectByInstanceId(instanceId: string) {
+    if (instanceId) {
+      for (let seg of this.segs) {
+        if (seg.el) { // necessary?
+          seg.el.classList.remove('fc-selected')
+        }
       }
     }
   }

+ 4 - 1
src/list/ListView.ts

@@ -58,6 +58,9 @@ export default class ListView extends View {
   updateSize(totalHeight, isAuto, isResize) {
     super.updateSize(totalHeight, isAuto, isResize)
 
+    this.eventRenderer.computeSizes(isResize)
+    this.eventRenderer.assignSizes(isResize)
+
     this.scroller.clear() // sets height to 'auto' and clears overflow
 
     if (!isAuto) {
@@ -98,7 +101,7 @@ export default class ListView extends View {
 
 
   renderEvents(eventStore: EventStore, eventUis: EventUiHash) {
-    this.renderEventSegs(
+    this._renderEventSegs(
       this.eventRangesToSegs(
         sliceEventStore(
           eventStore,