iwmlib/lib/frames.js

160 lines
5.0 KiB
JavaScript
Raw Permalink Normal View History

2019-07-18 12:26:39 +02:00
import { Points } from './utils.js'
import { Capabilities } from './capabilities.js'
2019-03-21 09:57:27 +01:00
export class FrameContainer {
constructor(element) {
this.element = element
2019-07-18 12:26:39 +02:00
this.delegate = new InteractionMapper(element, this, {
mouseWheelElement: window
})
2019-03-21 09:57:27 +01:00
}
capture(event) {
return true
}
findTarget(event, local, global) {
let found = document.elementFromPoint(global.x, global.y)
let iframe = found.querySelector('iframe')
if (iframe) {
let p = Points.fromPageToNode(found, global)
let doc = iframe.contentWindow.document
let target = doc.elementFromPoint(p.x, p.y)
if (target != null) {
console.log('iframe element', target)
return new FrameTarget(iframe, target)
}
}
return null
}
}
export class FrameTarget {
2019-07-18 12:26:39 +02:00
constructor(frame, target, debug = false) {
2019-03-21 09:57:27 +01:00
this.frame = frame
this.target = target
this.debug = debug
}
capture(event) {
return true
}
simulateMouseEvent(type, point) {
let p = Points.fromPageToNode(this.frame, point)
let event = new MouseEvent(type, {
view: this.frame.contentWindow,
bubbles: true,
cancelable: true,
clientX: p.x,
2019-07-18 12:26:39 +02:00
clientY: p.y
})
2019-03-21 09:57:27 +01:00
this.target.dispatchEvent(event)
}
createTouchList(pointMap) {
let touches = []
let doc = this.frame.contentWindow.document
2019-07-18 12:26:39 +02:00
for (let key of pointMap.keys()) {
2019-03-21 09:57:27 +01:00
let point = pointMap.get(key)
let p = Points.fromPageToNode(this.frame, point)
let touchTarget = doc.elementFromPoint(p.x, p.y)
2019-07-30 16:56:29 +02:00
let touch = new Touch(undefined, touchTarget, key, p.x, p.y, p.x, p.y)
2019-03-21 09:57:27 +01:00
touches.push(touch)
}
2019-07-18 12:26:39 +02:00
return new TouchList(...touches)
2019-03-21 09:57:27 +01:00
}
simulateTouchEventChrome(type, point, pointMap) {
let doc = this.frame.contentWindow.document
let p = Points.fromPageToNode(this.frame, point)
let touchTarget = doc.elementFromPoint(p.x, p.y)
const touchObj = new Touch({
identifier: Date.now(),
target: touchTarget,
clientX: p.x,
clientY: p.y,
pageX: p.x,
pageY: p.y,
radiusX: 2.5,
radiusY: 2.5,
rotationAngle: 10,
2019-07-18 12:26:39 +02:00
force: 0.5
})
2019-03-21 09:57:27 +01:00
const touchEvent = new TouchEvent(type, {
cancelable: true,
bubbles: true,
touches: [touchObj],
targetTouches: [touchObj],
changedTouches: [touchObj],
2019-07-18 12:26:39 +02:00
shiftKey: false
})
if (this.debug) console.log('simulateTouchEventChrome', touchEvent)
this.target.dispatchEvent(touchEvent)
2019-03-21 09:57:27 +01:00
}
2019-07-30 16:56:29 +02:00
simulateTouchEventSafari(type, point, pointMap, touchEventKey = 'targetTouches') {
2019-03-21 09:57:27 +01:00
let p = Points.fromPageToNode(this.frame, point)
2019-07-18 12:26:39 +02:00
let data = {
view: this.frame.contentWindow,
2019-03-21 09:57:27 +01:00
bubbles: true,
cancelable: true,
clientX: p.x,
2019-07-18 12:26:39 +02:00
clientY: p.y
}
2019-03-21 09:57:27 +01:00
data[touchEventKey] = this.createTouchList(pointMap)
let event = new TouchEvent(type, data)
2019-07-18 12:26:39 +02:00
if (this.debug) console.log('simulateTouchEventChrome', touchEvent)
2019-03-21 09:57:27 +01:00
this.target.dispatchEvent(event)
}
2019-07-18 12:26:39 +02:00
simulateTouchEvent(type, point, pointMap, touchEventKey = 'targetTouches') {
2019-03-21 09:57:27 +01:00
if (Capabilities.isSafari) {
this.simulateTouchEventSafari(type, point, pointMap, touchEventKey)
2019-07-18 12:26:39 +02:00
} else {
2019-03-21 09:57:27 +01:00
this.simulateTouchEventChrome(type, point, pointMap)
}
}
isMouseLikeEvent(event) {
2019-07-30 16:56:29 +02:00
return event.type.startsWith('mouse') || event.type.startsWith('pointer')
2019-03-21 09:57:27 +01:00
}
onStart(event, interaction) {
if (this.debug) console.log('onStart', this.frame.parentNode)
2019-07-18 12:26:39 +02:00
for (let [key, point] of interaction.current.entries()) {
2019-03-21 09:57:27 +01:00
if (this.isMouseLikeEvent(event)) {
this.simulateMouseEvent('mousedown', point)
2019-07-18 12:26:39 +02:00
} else {
2019-07-30 16:56:29 +02:00
this.simulateTouchEvent('touchstart', point, interaction.current)
2019-03-21 09:57:27 +01:00
return
}
}
}
onMove(event, interaction) {
if (this.debug) console.log('onMove')
2019-07-18 12:26:39 +02:00
for (let [key, point] of interaction.current.entries()) {
2019-03-21 09:57:27 +01:00
if (this.isMouseLikeEvent(event)) {
this.simulateMouseEvent('mousemove', point)
2019-07-18 12:26:39 +02:00
} else {
this.simulateTouchEvent('touchmove', point, interaction.current)
2019-03-21 09:57:27 +01:00
return
}
}
}
onEnd(event, interaction) {
if (this.debug) console.log('onEnd')
2019-07-18 12:26:39 +02:00
for (let [key, point] of interaction.current.entries()) {
2019-03-21 09:57:27 +01:00
if (this.isMouseLikeEvent(event)) {
this.simulateMouseEvent('mouseend', point)
2019-07-18 12:26:39 +02:00
} else {
2019-07-30 16:56:29 +02:00
this.simulateTouchEvent('touchend', point, interaction.ended, 'changedTouches')
2019-03-21 09:57:27 +01:00
return
}
}
}
}