Skip to content

Commit

Permalink
feat: emulateTouchFromMouseEvent
Browse files Browse the repository at this point in the history
  • Loading branch information
surunzi committed Aug 19, 2024
1 parent 079fe9b commit 47f72ee
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 5 deletions.
55 changes: 51 additions & 4 deletions devtools/target.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,68 @@
.motto {
display: inline-block;
}
.scroll {
margin-top: 15px;
border: 1px solid black;
width: 400px;
height: 200px;
overflow: auto;
}
.big {
width: 300px;
height: 300px;
margin-top: 15px;
background-color: red;
}
.small {
width: 100px;
height: 100px;
margin-top: 15px;
background-color: blue;
}
</style>
<script src="chobitsu.js"></script>
</head>
<body>
<div class="motto">Hello Chii!</div>
<button onclick="reload()">Reload</button>
<button id="reload">Reload</button>
<button id="click">Click</button>
<button id="touch">Touch</button>
<script>
document.getElementById('reload').addEventListener('click', function () {
location.reload()
})
document.getElementById('click').addEventListener('click', function () {
console.log('click')
})
document
.getElementById('touch')
.addEventListener('touchstart', function () {
console.log('touch')
})
</script>
<div class="scroll">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus.
Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies
sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a,
semper congue, euismod non, mi. Proin porttitor, orci nec nonummy
molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat.
Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a,
enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor.
Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent
blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales.
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere
cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque
fermentum. Maecenas adipiscing ante non diam sodales hendrerit.
</div>
<div class="big"></div>
<div class="small"></div>
<script>
console.log('Page loaded!')
setTimeout(function () {
console.log('Hello Chii')
fetch(location.href)
}, 1000)
window.reload = function () {
location.reload()
}
</script>
<script>
function testWs() {
Expand Down
97 changes: 97 additions & 0 deletions src/domains/Input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import isUndef from 'licia/isUndef'
import toBool from 'licia/toBool'
import Protocol from 'devtools-protocol'
import Input = Protocol.Input

let isClick = false

export function emulateTouchFromMouseEvent(
params: Input.EmulateTouchFromMouseEventRequest
) {
const { type, x, y, deltaX, deltaY } = params

const el = document.elementFromPoint(x, y) || document.documentElement

switch (type) {
case 'mousePressed':
isClick = true
triggerTouchEvent('touchstart', el, x, y)
break
case 'mouseMoved':
isClick = false
triggerTouchEvent('touchmove', el, x, y)
break
case 'mouseReleased':
triggerTouchEvent('touchend', el, x, y)
if (isClick) {
el.dispatchEvent(
new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
})
)
}
isClick = false
break
case 'mouseWheel':
if (!isUndef(deltaX) && !isUndef(deltaY)) {
triggerScroll(el, deltaX, deltaY)
}
break
}
}

function triggerTouchEvent(type: string, el: Element, x: number, y: number) {
const touch = new Touch({
identifier: 0,
target: el,
clientX: x,
clientY: y,
force: 1,
})

el.dispatchEvent(
new TouchEvent(type, {
bubbles: true,
touches: [touch],
changedTouches: [touch],
targetTouches: [touch],
})
)
}

function triggerScroll(el: Element, deltaX: number, deltaY: number) {
el = findScrollableEl(el, deltaX, deltaY)
el.scrollLeft -= deltaX
el.scrollTop -= deltaY
}

function findScrollableEl(el: Element | null, deltaX: number, deltaY: number) {
while (el) {
if (toBool(deltaX) && isScrollable(el, 'x')) {
return el
}
if (toBool(deltaY) && isScrollable(el, 'y')) {
return el
}

el = el.parentElement
}

return el || document.documentElement
}

function isScrollable(el: Element, direction: 'x' | 'y') {
const computedStyle = getComputedStyle(el)

if (direction === 'x') {
return (
el.scrollWidth > el.clientWidth && computedStyle.overflowX !== 'hidden'
)
}

return (
el.scrollHeight > el.clientHeight && computedStyle.overflowY !== 'hidden'
)
}
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as Debugger from './domains/Debugger'
import * as Storage from './domains/Storage'
import * as CacheStorage from './domains/CacheStorage'
import * as IndexedDB from './domains/IndexedDB'
import * as Input from './domains/Input'

const chobitsu = new Chobitsu()
chobitsu.register('Network', {
Expand Down Expand Up @@ -136,7 +137,7 @@ chobitsu.register('HeapProfiler', {
enable: noop,
})
chobitsu.register('Input', {
emulateTouchFromMouseEvent: noop,
...Input,
})

export default chobitsu

0 comments on commit 47f72ee

Please sign in to comment.