Adam Shaw 7 лет назад
Родитель
Сommit
c1a07d3dc2

+ 22 - 22
src/agenda/TimeGridEventRenderer.ts

@@ -2,7 +2,7 @@ import { htmlEscape, cssToStr } from '../util/html'
 import { removeElement, applyStyle } from '../util/dom-manip'
 import { createFormatter } from '../datelib/formatting'
 import EventRenderer from '../component/renderers/EventRenderer'
-import EventDef from '../models/event/EventDef'
+import { Seg } from '../reducers/seg'
 
 const FULL_TIME_FORMAT = createFormatter({ hour: 'numeric', minute: '2-digit' })
 
@@ -21,14 +21,14 @@ export default class TimeGridEventRenderer extends EventRenderer {
   }
 
 
-  renderFgSegs(segs) {
+  renderFgSegs(segs: Seg[]) {
     this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls)
   }
 
 
   // Given an array of foreground segments, render a DOM element for each, computes position,
   // and attaches to the column inner-container elements.
-  renderFgSegsIntoContainers(segs, containerEls) {
+  renderFgSegsIntoContainers(segs: Seg[], containerEls) {
     let segsByCol
     let col
 
@@ -68,11 +68,11 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
 
   // Renders the HTML for a single event segment's default rendering
-  fgSegHtml(seg, disableResizing) {
+  fgSegHtml(seg: Seg, disableResizing) {
     let view = this.view
-    let componentFootprint = seg.footprint.componentFootprint
-    let isAllDay = componentFootprint.isAllDay
-    let eventDef: EventDef = seg.footprint.eventDef
+    let eventRange = seg.eventRange
+    let eventDef = eventRange.eventDef
+    let isAllDay = eventDef.isAllDay
     let isDraggable = view.isEventDefDraggable(eventDef)
     let isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef)
     let isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef)
@@ -85,7 +85,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
     classes.unshift('fc-time-grid-event', 'fc-v-event')
 
     // if the event appears to span more than one day...
-    if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
+    if (view.isMultiDayRange(eventRange.range)) {
       // Don't display time text on segments that run entirely through a day.
       // That would appear as midnight-midnight and would look dumb.
       // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
@@ -98,9 +98,9 @@ export default class TimeGridEventRenderer extends EventRenderer {
       }
     } else {
       // Display the normal time text for the *event's* times
-      timeText = this.getTimeText(seg.footprint)
-      fullTimeText = this.getTimeText(seg.footprint, FULL_TIME_FORMAT)
-      startTimeText = this.getTimeText(seg.footprint, null, false) // displayEnd=false
+      timeText = this.getTimeText(eventRange)
+      fullTimeText = this.getTimeText(eventRange, FULL_TIME_FORMAT)
+      startTimeText = this.getTimeText(eventRange, null, false) // displayEnd=false
     }
 
     return '<a class="' + classes.join(' ') + '"' +
@@ -147,7 +147,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
   // Given segments that are assumed to all live in the *same column*,
   // compute their verical/horizontal coordinates and assign to their elements.
-  updateFgSegCoords(segs) {
+  updateFgSegCoords(segs: Seg[]) {
     this.timeGrid.computeSegVerticals(segs) // horizontals relies on this
     this.computeFgSegHorizontals(segs) // compute horizontal coordinates, z-index's, and reorder the array
     this.timeGrid.assignSegVerticals(segs)
@@ -157,7 +157,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
   // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
   // NOTE: Also reorders the given array by date!
-  computeFgSegHorizontals(segs) {
+  computeFgSegHorizontals(segs: Seg[]) {
     let levels
     let level0
     let i
@@ -187,7 +187,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
   // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
   // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
   // coordinate of the first segment in the series.
-  computeFgSegForwardBack(seg, seriesBackwardPressure, seriesBackwardCoord) {
+  computeFgSegForwardBack(seg: Seg, seriesBackwardPressure, seriesBackwardCoord) {
     let forwardSegs = seg.forwardSegs
     let i
 
@@ -222,13 +222,13 @@ export default class TimeGridEventRenderer extends EventRenderer {
   }
 
 
-  sortForwardSegs(forwardSegs) {
+  sortForwardSegs(forwardSegs: Seg[]) {
     forwardSegs.sort(this.compareForwardSegs.bind(this))
   }
 
 
   // A cmp function for determining which forward segment to rely on more when computing coordinates.
-  compareForwardSegs(seg1, seg2) {
+  compareForwardSegs(seg1: Seg, seg2: Seg) {
     // put higher-pressure first
     return seg2.forwardPressure - seg1.forwardPressure ||
       // put segments that are closer to initial edge first (and favor ones with no coords yet)
@@ -240,7 +240,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
   // Given foreground event segments that have already had their position coordinates computed,
   // assigns position-related CSS values to their elements.
-  assignFgSegHorizontals(segs) {
+  assignFgSegHorizontals(segs: Seg[]) {
     let i
     let seg
 
@@ -258,7 +258,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
   // Generates an object with CSS properties/values that should be applied to an event segment element.
   // Contains important positioning-related properties that should be applied to any event element, customized or not.
-  generateFgSegHorizontalCss(seg) {
+  generateFgSegHorizontalCss(seg: Seg) {
     let shouldOverlap = this.opt('slotEventOverlap')
     let backwardCoord = seg.backwardCoord // the left side if LTR. the right side if RTL. floating-point
     let forwardCoord = seg.forwardCoord // the right side if LTR. the left side if RTL. floating-point
@@ -297,7 +297,7 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
-function buildSlotSegLevels(segs) {
+function buildSlotSegLevels(segs: Seg[]) {
   let levels = []
   let i
   let seg
@@ -348,7 +348,7 @@ function computeForwardSlotSegs(levels) {
 
 // Figure out which path forward (via seg.forwardSegs) results in the longest path until
 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
-function computeSlotSegPressures(seg) {
+function computeSlotSegPressures(seg: Seg) {
   let forwardSegs = seg.forwardSegs
   let forwardPressure = 0
   let i
@@ -377,7 +377,7 @@ function computeSlotSegPressures(seg) {
 
 // Find all the segments in `otherSegs` that vertically collide with `seg`.
 // Append into an optionally-supplied `results` array and return.
-function computeSlotSegCollisions(seg, otherSegs, results= []) {
+function computeSlotSegCollisions(seg: Seg, otherSegs: Seg[], results= []) {
 
   for (let i = 0; i < otherSegs.length; i++) {
     if (isSlotSegCollision(seg, otherSegs[i])) {
@@ -390,6 +390,6 @@ function computeSlotSegCollisions(seg, otherSegs, results= []) {
 
 
 // Do these segments occupy the same vertical space?
-function isSlotSegCollision(seg1, seg2) {
+function isSlotSegCollision(seg1: Seg, seg2: Seg) {
   return seg1.bottom > seg2.top && seg1.top < seg2.bottom
 }

+ 16 - 14
src/basic/DayGridEventRenderer.ts

@@ -2,6 +2,7 @@ import { htmlEscape, cssToStr } from '../util/html'
 import { createElement, removeElement } from '../util/dom-manip'
 import EventRenderer from '../component/renderers/EventRenderer'
 import DayGrid from './DayGrid'
+import { Seg } from '../reducers/seg'
 
 
 /* Event-rendering methods for the DayGrid class
@@ -19,18 +20,18 @@ export default class DayGridEventRenderer extends EventRenderer {
   }
 
 
-  renderBgRanges(eventRanges) {
+  renderSegs(segs: Seg[]) {
     // don't render timed background events
-    eventRanges = eventRanges.filter(function(eventRange: any) {
-      return eventRange.eventDef.isAllDay()
+    segs = segs.filter(function(seg) {
+      return seg.eventRange.eventDef.isAllDay
     })
 
-    super.renderBgRanges(eventRanges)
+    super.renderSegs(segs)
   }
 
 
   // Renders the given foreground event segments onto the grid
-  renderFgSegs(segs) {
+  renderFgSegs(segs: Seg[]) {
     let rowStructs = this.rowStructs = this.renderSegRows(segs)
 
     // append to each row's content skeleton
@@ -58,7 +59,7 @@ export default class DayGridEventRenderer extends EventRenderer {
   // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
   // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
   // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
-  renderSegRows(segs) {
+  renderSegRows(segs: Seg[]) {
     let rowStructs = []
     let segRows
     let row
@@ -165,7 +166,7 @@ export default class DayGridEventRenderer extends EventRenderer {
 
   // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
   // NOTE: modifies segs
-  buildSegLevels(segs) {
+  buildSegLevels(segs: Seg[]) {
     let levels = []
     let i
     let seg
@@ -201,7 +202,7 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 
   // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
-  groupSegRows(segs) {
+  groupSegRows(segs: Seg[]) {
     let segRows = []
     let i
 
@@ -235,10 +236,11 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 
   // Builds the HTML to be used for the default element for an individual segment
-  fgSegHtml(seg, disableResizing) {
+  fgSegHtml(seg: Seg, disableResizing) {
     let view = this.view
-    let eventDef = seg.footprint.eventDef
-    let isAllDay = seg.footprint.componentFootprint.isAllDay
+    let eventRange = seg.eventRange
+    let eventDef = eventRange.eventDef
+    let isAllDay = eventDef.isAllDay
     let isDraggable = view.isEventDefDraggable(eventDef)
     let isResizableFromStart = !disableResizing && isAllDay &&
       seg.isStart && view.isEventDefResizableFromStart(eventDef)
@@ -254,7 +256,7 @@ export default class DayGridEventRenderer extends EventRenderer {
 
     // Only display a timed events time if it is the starting segment
     if (seg.isStart) {
-      timeText = this.getTimeText(seg.footprint)
+      timeText = this.getTimeText(eventRange)
       if (timeText) {
         timeHtml = '<span class="fc-time">' + htmlEscape(timeText) + '</span>'
       }
@@ -296,7 +298,7 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 
 // Computes whether two segments' columns collide. They are assumed to be in the same row.
-function isDaySegCollision(seg, otherSegs) {
+function isDaySegCollision(seg: Seg, otherSegs: Seg) {
   let i
   let otherSeg
 
@@ -316,6 +318,6 @@ function isDaySegCollision(seg, otherSegs) {
 
 
 // A cmp function for determining the leftmost event
-function compareDaySegCols(a, b) {
+function compareDaySegCols(a: Seg, b: Seg) {
   return a.leftCol - b.leftCol
 }

+ 60 - 88
src/component/renderers/EventRenderer.ts

@@ -3,6 +3,9 @@ import { DateMarker } from '../../datelib/marker'
 import { createFormatter, DateFormatter } from '../../datelib/formatting'
 import { htmlToElements } from '../../util/dom-manip'
 import { compareByFieldSpecs } from '../../util/misc'
+import { EventRenderRange } from '../../reducers/event-rendering'
+import { Seg } from '../../reducers/seg'
+
 
 export default class EventRenderer {
 
@@ -10,8 +13,8 @@ export default class EventRenderer {
   component: any
   fillRenderer: any // might remain null
 
-  fgSegs: any
-  bgSegs: any
+  fgSegs: Seg[]
+  bgSegs: Seg[]
 
   // derived from options
   eventTimeFormat: DateFormatter
@@ -57,72 +60,40 @@ export default class EventRenderer {
   }
 
 
-  render(eventsPayload) {
-    let dateProfile = this.component._getDateProfile()
-    let eventDefId
-    let instanceGroup
-    let eventRanges
-    let bgRanges = []
-    let fgRanges = []
-
-    for (eventDefId in eventsPayload) {
-      instanceGroup = eventsPayload[eventDefId]
+  renderSegs(allSegs: Seg[]) {
+    let bgSegs: Seg[] = []
+    let fgSegs: Seg[] = []
 
-      eventRanges = instanceGroup.sliceRenderRanges(
-        dateProfile.activeUnzonedRange
-      )
+    for (let seg of allSegs) {
+      let rendering = seg.eventRange.eventDef.rendering
 
-      if (instanceGroup.getEventDef().hasBgRendering()) {
-        bgRanges.push.apply(bgRanges, eventRanges)
+      if (rendering === 'background' || rendering === 'inverse-background') {
+        bgSegs.push(seg)
       } else {
-        fgRanges.push.apply(fgRanges, eventRanges)
+        fgSegs.push(seg)
       }
     }
 
-    this.renderBgRanges(bgRanges)
-    this.renderFgRanges(fgRanges)
-  }
-
-
-  unrender() {
-    this.unrenderBgRanges()
-    this.unrenderFgRanges()
-  }
-
-
-  renderFgRanges(eventRanges) {
-    let eventFootprints = this.component.eventRangesToEventFootprints(eventRanges)
-    let segs = this.component.eventFootprintsToSegs(eventFootprints)
+    if (this.renderBgSegs(bgSegs) !== false) { // no failure?
+      this.bgSegs = bgSegs
+    }
 
     // render an `.el` on each seg
     // returns a subset of the segs. segs that were actually rendered
-    segs = this.renderFgSegEls(segs)
+    fgSegs = this.renderFgSegEls(fgSegs)
 
-    if (this.renderFgSegs(segs) !== false) { // no failure?
-      this.fgSegs = segs
+    if (this.renderFgSegs(fgSegs) !== false) { // no failure?
+      this.fgSegs = fgSegs
     }
   }
 
 
-  unrenderFgRanges() {
-    this.unrenderFgSegs(this.fgSegs || [])
-    this.fgSegs = null
-  }
-
-
-  renderBgRanges(eventRanges) {
-    let eventFootprints = this.component.eventRangesToEventFootprints(eventRanges)
-    let segs = this.component.eventFootprintsToSegs(eventFootprints)
-
-    if (this.renderBgSegs(segs) !== false) { // no failure?
-      this.bgSegs = segs
-    }
-  }
-
-
-  unrenderBgRanges() {
+  unrender() {
     this.unrenderBgSegs()
     this.bgSegs = null
+
+    this.unrenderFgSegs(this.fgSegs || [])
+    this.fgSegs = null
   }
 
 
@@ -132,7 +103,7 @@ export default class EventRenderer {
 
 
   // Renders foreground event segments onto the grid
-  renderFgSegs(segs): (boolean | void) {
+  renderFgSegs(segs: Seg[]): (boolean | void) {
     // subclasses must implement
     // segs already has rendered els, and has been filtered.
 
@@ -141,24 +112,24 @@ export default class EventRenderer {
 
 
   // Unrenders all currently rendered foreground segments
-  unrenderFgSegs(segs) {
+  unrenderFgSegs(segs: Seg[]) {
     // subclasses must implement
   }
 
 
-  renderBgSegs(segs) {
+  renderBgSegs(segs: Seg[]) {
     if (this.fillRenderer) {
       this.fillRenderer.renderSegs('bgEvent', segs, {
         getClasses: (seg) => {
-          return this.getBgClasses(seg.footprint.eventDef)
+          return this.getBgClasses(seg.eventRange.eventDef)
         },
         getCss: (seg) => {
           return {
-            'background-color': this.getBgColor(seg.footprint.eventDef)
+            'background-color': this.getBgColor(seg.eventRange.eventDef)
           }
         },
         filterEl: (seg, el) => {
-          return this.filterEventRenderEl(seg.footprint, el)
+          return this.filterEventRenderEl(seg.eventRange, el)
         }
       })
     } else {
@@ -176,7 +147,7 @@ export default class EventRenderer {
 
   // Renders and assigns an `el` property for each foreground event segment.
   // Only returns segments that successfully rendered.
-  renderFgSegEls(segs, disableResizing= false) {
+  renderFgSegEls(segs: Seg[], disableResizing= false) {
     let hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender')
     let html = ''
     let renderedSegs = []
@@ -196,7 +167,7 @@ export default class EventRenderer {
         let seg = segs[i]
 
         if (hasEventRenderHandlers) { // optimization
-          el = this.filterEventRenderEl(seg.footprint, el)
+          el = this.filterEventRenderEl(seg.eventRange, el)
         }
 
         if (el) {
@@ -211,23 +182,23 @@ export default class EventRenderer {
   }
 
 
-  beforeFgSegHtml(seg) { // hack
+  beforeFgSegHtml(seg: Seg) { // hack
   }
 
 
   // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()
-  fgSegHtml(seg, disableResizing) {
+  fgSegHtml(seg: Seg, disableResizing) {
     // subclasses should implement
   }
 
 
   // Generic utility for generating the HTML classNames for an event segment's element
-  getSegClasses(seg, isDraggable, isResizable) {
+  getSegClasses(seg: Seg, isDraggable, isResizable) {
     let classes = [
       'fc-event',
       seg.isStart ? 'fc-start' : 'fc-not-start',
       seg.isEnd ? 'fc-end' : 'fc-not-end'
-    ].concat(this.getClasses(seg.footprint.eventDef))
+    ].concat(this.getClasses(seg.eventRange.eventDef))
 
     if (isDraggable) {
       classes.push('fc-draggable')
@@ -237,7 +208,7 @@ export default class EventRenderer {
     }
 
     // event is currently selected? attach a className.
-    if (this.view.isEventDefSelected(seg.footprint.eventDef)) {
+    if (this.view.isEventDefSelected(seg.eventRange.eventDef)) {
       classes.push('fc-selected')
     }
 
@@ -247,8 +218,7 @@ export default class EventRenderer {
 
   // Given an event and the default element used for rendering, returns the element that should actually be used.
   // Basically runs events and elements through the eventRender hook.
-  filterEventRenderEl(eventFootprint, el) {
-    let legacy = eventFootprint.getEventLegacy(this.view.calendar)
+  filterEventRenderEl(eventRange: EventRenderRange, el) {
 
     let custom = this.view.publiclyTrigger('eventRender', [
       {
@@ -273,17 +243,17 @@ export default class EventRenderer {
   // If event times are disabled, or the event has no time, will return a blank string.
   // If not specified, formatter will default to the eventTimeFormat setting,
   // and displayEnd will default to the displayEventEnd setting.
-  getTimeText(eventFootprint, formatter?, displayEnd?) {
-    let eventDateProfile = eventFootprint.eventInstance.dateProfile
+  getTimeText(eventRange: EventRenderRange, formatter?, displayEnd?) {
+    let { eventDef, eventInstance } = eventRange
 
     return this._getTimeText(
-      eventDateProfile.unzonedRange.start,
-      eventDateProfile.hasEnd ? eventDateProfile.unzonedRange.end : null,
-      eventFootprint.componentFootprint.isAllDay,
+      eventInstance.range.start,
+      eventDef.hasEnd ? eventInstance.range.end : null,
+      eventDef.isAllDay,
       formatter,
       displayEnd,
-      eventDateProfile.forcedStartTimeZoneOffset,
-      eventDateProfile.forcedEndTimeZoneOffset
+      eventInstance.forcedStartTzo,
+      eventInstance.forcedEndTzo
     )
   }
 
@@ -440,8 +410,12 @@ export default class EventRenderer {
   }
 
 
-  getFallbackStylingObjs(eventDef) {
-    return [ eventDef.source ]
+  getFallbackStylingObjs(eventDef): any {
+    if (eventDef.sourceId) {
+      return [ this.view.calendar.state.eventSources[eventDef.sourceId] ]
+    } else {
+      return []
+    }
   }
 
 
@@ -451,23 +425,21 @@ export default class EventRenderer {
 
 
   // A cmp function for determining which segments should take visual priority
-  compareEventSegs(seg1, seg2) {
-    let f1 = seg1.footprint
-    let f2 = seg2.footprint
-    let cf1 = f1.componentFootprint
-    let cf2 = f2.componentFootprint
-    let r1 = cf1.unzonedRange
-    let r2 = cf2.unzonedRange
+  compareEventSegs(seg1: Seg, seg2: Seg) {
+    let eventDef1 = seg1.eventRange.eventDef
+    let eventDef2 = seg2.eventRange.eventDef
+    let r1 = seg1.range
+    let r2 = seg2.range
 
     return r1.start.valueOf() - r2.start.valueOf() || // earlier events go first
       (r2.end.valueOf() - r2.start.valueOf()) - (r1.end.valueOf() - r1.start.valueOf()) || // tie? longer events go first
-      cf2.isAllDay - cf1.isAllDay || // tie? put all-day events first (booleans cast to 0/1)
+      Number(eventDef2.isAllDay) - Number(eventDef1.isAllDay) || // tie? put all-day events first
       compareByFieldSpecs(
-        f1.eventDef,
-        f2.eventDef,
+        eventDef1,
+        eventDef2,
         this.view.eventOrderSpecs,
-        f1.eventDef.miscProps,
-        f2.eventDef.miscProps
+        eventDef1.extendedProps,
+        eventDef2.extendedProps
       )
   }
 

+ 9 - 9
src/list/ListEventRenderer.ts

@@ -1,13 +1,14 @@
 import { htmlEscape } from '../util/html'
 import EventRenderer from '../component/renderers/EventRenderer'
 import ListView from './ListView'
+import { Seg } from '../reducers/seg'
 
 export default class ListEventRenderer extends EventRenderer {
 
   component: ListView
 
 
-  renderFgSegs(segs) {
+  renderFgSegs(segs: Seg[]) {
     if (!segs.length) {
       this.component.renderEmptyMessage()
     } else {
@@ -16,33 +17,32 @@ export default class ListEventRenderer extends EventRenderer {
   }
 
   // generates the HTML for a single event row
-  fgSegHtml(seg) {
+  fgSegHtml(seg: Seg) {
     let view = this.view
     let calendar = view.calendar
     let theme = calendar.theme
-    let eventFootprint = seg.footprint
-    let eventDef = eventFootprint.eventDef
-    let componentFootprint = eventFootprint.componentFootprint
+    let eventRange = seg.eventRange
+    let eventDef = eventRange.eventDef
     let url = eventDef.url
     let classes = [ 'fc-list-item' ].concat(this.getClasses(eventDef))
     let bgColor = this.getBgColor(eventDef)
     let timeHtml
 
-    if (componentFootprint.isAllDay) {
+    if (eventDef.isAllDay) {
       timeHtml = view.getAllDayHtml()
-    } else if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
+    } else if (view.isMultiDayRange(eventRange.range)) {
       if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day
         timeHtml = htmlEscape(this._getTimeText(
           seg.start,
           seg.end,
-          componentFootprint.isAllDay
+          false // isAllDay
         ))
       } else { // inner segment that lasts the whole day
         timeHtml = view.getAllDayHtml()
       }
     } else {
       // Display the normal time text for the *event's* times
-      timeHtml = htmlEscape(this.getTimeText(eventFootprint))
+      timeHtml = htmlEscape(this.getTimeText(eventRange))
     }
 
     if (url) {

+ 9 - 0
src/reducers/seg.ts

@@ -0,0 +1,9 @@
+import { EventRenderRange } from './event-rendering'
+
+export interface Seg {
+  isStart: boolean
+  isEnd: boolean
+  eventRange?: EventRenderRange
+  el?: HTMLElement
+  [otherProp: string]: any
+}