UNPKG

remoteview

Version:

Remote isolated browser platform by Dosyago

258 lines (241 loc) 7.87 kB
import {DEBUG, logit} from './common.js'; export const getKeyId = event => event.key && event.key.length > 1 ? event.key : event.code; export const controlChars = new Set([ "Enter", "Backspace", "Control", "Shift", "Alt", "Meta", "Space", "Delete", "ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight", "Tab" ]); export default function transformEvent(e) { const transformedEvent = { type: e.type }; let event, synthetic, originalEvent; if (e.synthetic) { synthetic = e; originalEvent = e.event; let form; if ( originalEvent ) { form = originalEvent.target && originalEvent.target.matches && originalEvent.target.matches('form') ? originalEvent.target : null; transformedEvent.originalType = originalEvent.type; transformedEvent.originalEvent = originalEvent; } switch(synthetic.type) { case "auth-response": { const {authResponse, requestId} = synthetic; Object.assign(transformedEvent, {authResponse, requestId}); break; } case "typing": { // get (composed) characters created let data = synthetic.data; Object.assign(transformedEvent, { characters: data }); break; } case "typing-syncValue": case "typing-clearAndInsertValue": { const {value,contextId} = synthetic; let encodedValue; if ( value != null && value != undefined ) { encodedValue = btoa(unescape(encodeURIComponent(value))); } Object.assign(transformedEvent, { encodedValue, value, contextId }); break; } case "typing-deleteContentBackward": { let encodedValueToDelete; if ( synthetic.valueToDelete ) { encodedValueToDelete = btoa(unescape(encodeURIComponent(synthetic.valueToDelete))); } Object.assign(transformedEvent, { encodedValueToDelete, contextId: synthetic.contextId }); break; } case "url-address": { // get URL address const address = synthetic.url; Object.assign(transformedEvent, {address}); break; } case "search-bar": { // get URL address const search = originalEvent.target.search.value; Object.assign(transformedEvent, {search}); break; } case "history": { // get button const action = form.clickedButton.value; Object.assign(transformedEvent, { action } ); break; } case "touchscroll": { const {deltaX, deltaY, bitmapX, bitmapY, contextId} = synthetic; Object.assign(transformedEvent, {deltaX, deltaY, bitmapX, bitmapY, contextId}); break; } case "zoom": { const {scale} = synthetic; const coords = getBitmapCoordinates(originalEvent); Object.assign(transformedEvent, coords, {scale}); break; } case "select": { const value = originalEvent.target.value; const executionContext = synthetic.state.waitingExecutionContext; Object.assign(transformedEvent, {value, executionContext}); break; } case "window-bounds": { const {width, height, targetId} = synthetic; DEBUG.val > DEBUG.med && console.log({windowBounds:{width,height,targetId}}); Object.assign(transformedEvent, {width, height,targetId}); break; } case "window-bounds-preImplementation": { // This is here until Browser.getWindowForTarget and Browser.setWindowBounds come online let width, height; if ( synthetic.width !== undefined && synthetic.height !== undefined ) { ({width,height} = synthetic); } else { ({width:{value:width}, height:{value:height}} = form); } Object.assign(transformedEvent, {width, height}); break; } case "user-agent": { const {userAgent, platform, acceptLanguage} = synthetic; Object.assign(transformedEvent, {userAgent, platform, acceptLanguage}); break; } case "hide-scrollbars": { break; } case "canKeysInput": { break; } case "getFavicon": { break; } case "getElementInfo": { transformedEvent.data = e.data; const {bitmapX:clientX, bitmapY:clientY} = getBitmapCoordinates(transformedEvent.data); Object.assign(transformedEvent.data, {clientX,clientY}); break; } case "touchcancel": { break; } case "respond-to-modal" : { Object.assign(transformedEvent, e); break; } case "isSafari": { break; } case "isMobile": { break; } case "isFirefox": { break; } case "newIncognitoTab": { break; } case "clearAllPageHistory": { break; } case "clearCache": { break; } case "clearCookies": { break; } default: { console.warn(`Unknown command ${JSON.stringify({synthetic})}`); break; } } } else if (e.raw || e.custom) { Object.assign(transformedEvent, e); } else { event = e; transformedEvent.originalEvent = e; switch(event.type) { case "keypress": case "keydown": case "keyup": { const id = getKeyId(event); if ( controlChars.has(id) ) { event.type == "keypress" && event.preventDefault && event.preventDefault(); transformedEvent.synthetic = true; transformedEvent.originalType = event.type; transformedEvent.type = "control-chars"; transformedEvent.key = event.key; transformedEvent.code = event.code; transformedEvent.keyCode = event.keyCode; DEBUG.val >= DEBUG.med && console.log(transformedEvent); } else if ( event.code == "Unidentified" || event.key == "Unidentified" ) { transformedEvent.key = event.key; transformedEvent.code = event.code; } else { transformedEvent.synthetic = true; transformedEvent.originalType = event.type; transformedEvent.type = event.type; transformedEvent.key = event.key; transformedEvent.code = event.code; transformedEvent.keyCode = event.keyCode; } break; } case "wheel": case "mousemove": case "mousedown": case "mouseup": case "pointermove": case "pointerdown": case "pointerup": { // get relevant X, Y coordinates and element under point // also get any relevant touch points and pressures and other associated // pointer or touch metadata or properties const {button} = event; const coords = getBitmapCoordinates(event); Object.assign(transformedEvent, coords, {button}); break; } } } DEBUG.val >= DEBUG.med && console.log(transformedEvent); return transformedEvent; } export function getBitmapCoordinates(event, scale = 1) { const {clientX,clientY} = event; const bitmap = event.target; let coordinates; if ( bitmap ) { const { left:parentX, top:parentY, width:elementWidth, height:elementHeight } = bitmap.getBoundingClientRect(); const scaleX = bitmap.width / elementWidth * scale; const scaleY = bitmap.height / elementHeight * scale; coordinates = { bitmapX: (clientX - parentX), bitmapY: (clientY - parentY) }; if ( DEBUG.val > DEBUG.high ) { const dpi = window.devicePixelRatio; const info = {coordinates, parentX, parentY, clientX, clientY, scaleX, scaleY, dpi }; logit(info); } } else { coordinates = {clientX,clientY}; } return coordinates; }