160 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
import { Points } from './utils.js'
 | 
						|
import { Capabilities } from './capabilities.js'
 | 
						|
 | 
						|
export class FrameContainer {
 | 
						|
    constructor(element) {
 | 
						|
        this.element = element
 | 
						|
        this.delegate = new InteractionMapper(element, this, {
 | 
						|
            mouseWheelElement: window,
 | 
						|
        })
 | 
						|
    }
 | 
						|
 | 
						|
    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 {
 | 
						|
    constructor(frame, target, debug = false) {
 | 
						|
        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,
 | 
						|
            clientY: p.y,
 | 
						|
        })
 | 
						|
        this.target.dispatchEvent(event)
 | 
						|
    }
 | 
						|
 | 
						|
    createTouchList(pointMap) {
 | 
						|
        let touches = []
 | 
						|
        let doc = this.frame.contentWindow.document
 | 
						|
        for (let key of pointMap.keys()) {
 | 
						|
            let point = pointMap.get(key)
 | 
						|
            let p = Points.fromPageToNode(this.frame, point)
 | 
						|
            let touchTarget = doc.elementFromPoint(p.x, p.y)
 | 
						|
            let touch = new Touch(undefined, touchTarget, key, p.x, p.y, p.x, p.y)
 | 
						|
            touches.push(touch)
 | 
						|
        }
 | 
						|
        return new TouchList(...touches)
 | 
						|
    }
 | 
						|
 | 
						|
    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,
 | 
						|
            force: 0.5,
 | 
						|
        })
 | 
						|
 | 
						|
        const touchEvent = new TouchEvent(type, {
 | 
						|
            cancelable: true,
 | 
						|
            bubbles: true,
 | 
						|
            touches: [touchObj],
 | 
						|
            targetTouches: [touchObj],
 | 
						|
            changedTouches: [touchObj],
 | 
						|
            shiftKey: false,
 | 
						|
        })
 | 
						|
        if (this.debug) console.log('simulateTouchEventChrome', touchEvent)
 | 
						|
        this.target.dispatchEvent(touchEvent)
 | 
						|
    }
 | 
						|
 | 
						|
    simulateTouchEventSafari(type, point, pointMap, touchEventKey = 'targetTouches') {
 | 
						|
        let p = Points.fromPageToNode(this.frame, point)
 | 
						|
        let data = {
 | 
						|
            view: this.frame.contentWindow,
 | 
						|
            bubbles: true,
 | 
						|
            cancelable: true,
 | 
						|
            clientX: p.x,
 | 
						|
            clientY: p.y,
 | 
						|
        }
 | 
						|
        data[touchEventKey] = this.createTouchList(pointMap)
 | 
						|
        let event = new TouchEvent(type, data)
 | 
						|
        if (this.debug) console.log('simulateTouchEventChrome', touchEvent)
 | 
						|
        this.target.dispatchEvent(event)
 | 
						|
    }
 | 
						|
 | 
						|
    simulateTouchEvent(type, point, pointMap, touchEventKey = 'targetTouches') {
 | 
						|
        if (Capabilities.isSafari) {
 | 
						|
            this.simulateTouchEventSafari(type, point, pointMap, touchEventKey)
 | 
						|
        } else {
 | 
						|
            this.simulateTouchEventChrome(type, point, pointMap)
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    isMouseLikeEvent(event) {
 | 
						|
        return event.type.startsWith('mouse') || event.type.startsWith('pointer')
 | 
						|
    }
 | 
						|
 | 
						|
    onStart(event, interaction) {
 | 
						|
        if (this.debug) console.log('onStart', this.frame.parentNode)
 | 
						|
        for (let [key, point] of interaction.current.entries()) {
 | 
						|
            if (this.isMouseLikeEvent(event)) {
 | 
						|
                this.simulateMouseEvent('mousedown', point)
 | 
						|
            } else {
 | 
						|
                this.simulateTouchEvent('touchstart', point, interaction.current)
 | 
						|
                return
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    onMove(event, interaction) {
 | 
						|
        if (this.debug) console.log('onMove')
 | 
						|
        for (let [key, point] of interaction.current.entries()) {
 | 
						|
            if (this.isMouseLikeEvent(event)) {
 | 
						|
                this.simulateMouseEvent('mousemove', point)
 | 
						|
            } else {
 | 
						|
                this.simulateTouchEvent('touchmove', point, interaction.current)
 | 
						|
                return
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    onEnd(event, interaction) {
 | 
						|
        if (this.debug) console.log('onEnd')
 | 
						|
        for (let [key, point] of interaction.current.entries()) {
 | 
						|
            if (this.isMouseLikeEvent(event)) {
 | 
						|
                this.simulateMouseEvent('mouseend', point)
 | 
						|
            } else {
 | 
						|
                this.simulateTouchEvent('touchend', point, interaction.ended, 'changedTouches')
 | 
						|
                return
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |