Procházet zdrojové kódy

fix popover event dragging. dragScroll setting

Adam Shaw před 7 roky
rodič
revize
ace2f0c995

+ 2 - 1
src/agenda/TimeGrid.ts

@@ -633,7 +633,8 @@ export default class TimeGrid extends DateComponent {
             right: colPositions.rights[colIndex] + leftOrigin,
             right: colPositions.rights[colIndex] + leftOrigin,
             top: slatTop,
             top: slatTop,
             bottom: slatTop + slatHeight
             bottom: slatTop + slatHeight
-          }
+          },
+          layer: 0
         }
         }
       }
       }
     }
     }

+ 2 - 1
src/basic/DayGrid.ts

@@ -350,7 +350,8 @@ export default class DayGrid extends DateComponent {
             right: colPositions.rights[col] + leftOrigin,
             right: colPositions.rights[col] + leftOrigin,
             top: rowPositions.tops[row] + topOrigin,
             top: rowPositions.tops[row] + topOrigin,
             bottom: rowPositions.bottoms[row] + topOrigin
             bottom: rowPositions.bottoms[row] + topOrigin
-          }
+          },
+          layer: 0
         }
         }
       }
       }
     }
     }

+ 46 - 0
src/basic/DayTile.ts

@@ -4,12 +4,21 @@ import DayGridEventRenderer from './DayGridEventRenderer'
 import { htmlEscape } from '../util/html'
 import { htmlEscape } from '../util/html'
 import { createFormatter } from '../datelib/formatting'
 import { createFormatter } from '../datelib/formatting'
 import { Seg } from '../component/DateComponent'
 import { Seg } from '../component/DateComponent'
+import { Hit } from '../interactions/HitDragging'
+import OffsetTracker from '../common/OffsetTracker'
+import { computeRect } from '../util/dom-geom'
+import { Rect, pointInsideRect } from '../util/geom'
+import { addDays } from '../datelib/marker'
 
 
 export default class DayTile extends DateComponent {
 export default class DayTile extends DateComponent {
 
 
   isInteractable = true
   isInteractable = true
+  useEventCenter = false
   date: Date
   date: Date
   segContainerEl: HTMLElement
   segContainerEl: HTMLElement
+  width: number
+  height: number
+  offsetTracker: OffsetTracker // TODO: abstraction for tracking dims of whole element rect
 
 
   constructor(component, date) {
   constructor(component, date) {
     super(component)
     super(component)
@@ -39,6 +48,43 @@ export default class DayTile extends DateComponent {
     this.segContainerEl = this.el.querySelector('.fc-event-container')
     this.segContainerEl = this.el.querySelector('.fc-event-container')
   }
   }
 
 
+  prepareHits() {
+    let rect = computeRect(this.el)
+    this.width = rect.right - rect.left
+    this.height = rect.bottom - rect.top
+    this.offsetTracker = new OffsetTracker(this.el)
+  }
+
+  releaseHits() {
+    this.offsetTracker.destroy()
+  }
+
+  queryHit(leftOffset, topOffset): Hit | null {
+    let rectLeft = this.offsetTracker.computeLeft()
+    let rectTop = this.offsetTracker.computeTop()
+    let rect: Rect = {
+      left: rectLeft,
+      right: rectLeft + this.width,
+      top: rectTop,
+      bottom: rectTop + this.height
+    }
+
+    if (pointInsideRect({ left: leftOffset, top: topOffset }, rect)) {
+      return {
+        component: this,
+        dateSpan: {
+          isAllDay: true,
+          range: { start: this.date, end: addDays(this.date, 1) }
+        },
+        dayEl: this.el,
+        rect: rect,
+        layer: 1
+      }
+    }
+
+    return null
+  }
+
 }
 }
 
 
 export class DayTileEventRenderer extends EventRenderer {
 export class DayTileEventRenderer extends EventRenderer {

+ 13 - 2
src/component/DateComponent.ts

@@ -52,6 +52,7 @@ export default abstract class DateComponent extends Component {
 
 
   // self-config, overridable by subclasses
   // self-config, overridable by subclasses
   isInteractable: boolean = false
   isInteractable: boolean = false
+  useEventCenter: boolean = true // for dragging geometry
   doesDragHelper: boolean = false // for events that ORIGINATE from this component
   doesDragHelper: boolean = false // for events that ORIGINATE from this component
   doesDragHighlight: boolean = false // for events that ORIGINATE from this component
   doesDragHighlight: boolean = false // for events that ORIGINATE from this component
   segSelector: string = '.fc-event-container > *' // what constitutes an event element?
   segSelector: string = '.fc-event-container > *' // what constitutes an event element?
@@ -1049,15 +1050,25 @@ export default abstract class DateComponent extends Component {
 
 
   isValidSegDownEl(el: HTMLElement) {
   isValidSegDownEl(el: HTMLElement) {
     return !this.eventDrag && !this.eventResize &&
     return !this.eventDrag && !this.eventResize &&
-      !elementClosest(el, '.fc-helper')
+      !elementClosest(el, '.fc-helper') &&
+      !this.isInPopover(el)
   }
   }
 
 
 
 
   isValidDateDownEl(el: HTMLElement) {
   isValidDateDownEl(el: HTMLElement) {
     let segEl = elementClosest(el, this.segSelector)
     let segEl = elementClosest(el, this.segSelector)
+
     return (!segEl || segEl.classList.contains('fc-helper')) &&
     return (!segEl || segEl.classList.contains('fc-helper')) &&
       !elementClosest(el, '.fc-more') && // a "more.." link
       !elementClosest(el, '.fc-more') && // a "more.." link
-      !elementClosest(el, 'a[data-goto]') // a clickable nav link
+      !elementClosest(el, 'a[data-goto]') && // a clickable nav link
+      !this.isInPopover(el)
+  }
+
+
+  // is the element inside of an inner popover?
+  isInPopover(el: HTMLElement) {
+    let popoverEl = elementClosest(el, '.fc-popover')
+    return popoverEl && popoverEl !== this.el // if the current component IS a popover, okay
   }
   }
 
 
 }
 }

+ 1 - 0
src/interactions/DateSelecting.ts

@@ -24,6 +24,7 @@ export default class DateSelecting {
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     dragging.touchScrollAllowed = false
     dragging.touchScrollAllowed = false
     dragging.minDistance = component.opt('selectMinDistance') || 0
     dragging.minDistance = component.opt('selectMinDistance') || 0
+    dragging.autoScroller.isEnabled = component.opt('dragScroll')
 
 
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, component)
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, component)
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)

+ 2 - 1
src/interactions/EventDragging.ts

@@ -36,9 +36,10 @@ export default class EventDragging { // TODO: rename to EventSelectingAndDraggin
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     dragging.pointer.selector = '.fc-draggable, .fc-resizable' // TODO: test this in IE11
     dragging.pointer.selector = '.fc-draggable, .fc-resizable' // TODO: test this in IE11
     dragging.touchScrollAllowed = false
     dragging.touchScrollAllowed = false
+    dragging.autoScroller.isEnabled = component.opt('dragScroll')
 
 
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, browserContext.componentHash)
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, browserContext.componentHash)
-    hitDragging.useSubjectCenter = true
+    hitDragging.useSubjectCenter = component.useEventCenter
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)
     hitDragging.emitter.on('dragstart', this.handleDragStart)
     hitDragging.emitter.on('dragstart', this.handleDragStart)
     hitDragging.emitter.on('hitupdate', this.handleHitUpdate)
     hitDragging.emitter.on('hitupdate', this.handleHitUpdate)

+ 1 - 0
src/interactions/EventResizing.ts

@@ -31,6 +31,7 @@ export default class EventDragging {
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     let dragging = this.dragging = new FeaturefulElementDragging(component.el)
     dragging.pointer.selector = '.fc-resizer'
     dragging.pointer.selector = '.fc-resizer'
     dragging.touchScrollAllowed = false
     dragging.touchScrollAllowed = false
+    dragging.autoScroller.isEnabled = component.opt('dragScroll')
 
 
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, component)
     let hitDragging = this.hitDragging = new HitDragging(this.dragging, component)
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)
     hitDragging.emitter.on('pointerdown', this.handlePointerDown)

+ 14 - 5
src/interactions/HitDragging.ts

@@ -12,6 +12,7 @@ export interface Hit {
   dateSpan: DateSpan
   dateSpan: DateSpan
   dayEl: HTMLElement
   dayEl: HTMLElement
   rect: Rect
   rect: Rect
+  layer: number
 }
 }
 
 
 /*
 /*
@@ -73,7 +74,7 @@ export default class HitDragging {
 
 
     if (this.initialHit || !this.requireInitial) {
     if (this.initialHit || !this.requireInitial) {
       dragging.setIgnoreMove(false)
       dragging.setIgnoreMove(false)
-      this.emitter.trigger('pointerdown', ev)
+      this.emitter.trigger('pointerdown', ev) // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
     } else {
     } else {
       dragging.setIgnoreMove(true)
       dragging.setIgnoreMove(true)
     }
     }
@@ -163,18 +164,26 @@ export default class HitDragging {
 
 
   queryHit(x: number, y: number): Hit | null {
   queryHit(x: number, y: number): Hit | null {
     let { droppableHash } = this
     let { droppableHash } = this
+    let bestHit: Hit | null = null
 
 
     for (let id in droppableHash) {
     for (let id in droppableHash) {
       let component = droppableHash[id]
       let component = droppableHash[id]
       let hit = component.queryHit(x, y)
       let hit = component.queryHit(x, y)
 
 
-      // make sure the hit is within activeRange, meaning it's not a deal cell
-      if (hit && rangeContainsRange(component.dateProfile.activeRange, hit.dateSpan.range)) {
-        return hit
+      if (
+        hit &&
+        (
+          // make sure the hit is within activeRange, meaning it's not a deal cell
+          !component.dateProfile || // hack for DayTile
+          rangeContainsRange(component.dateProfile.activeRange, hit.dateSpan.range)
+        ) &&
+        (!bestHit || hit.layer > bestHit.layer)
+      ) {
+        bestHit = hit
       }
       }
     }
     }
 
 
-    return null
+    return bestHit
   }
   }
 
 
 }
 }