Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(browser): add browser iframe mouse interaction #5815

Merged
merged 5 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/browser/src/client/orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ function createIframe(container: HTMLDivElement, file: string) {

iframe.style.display = 'block'
iframe.style.border = 'none'
iframe.style.pointerEvents = 'none'
iframe.setAttribute('allowfullscreen', 'true')
iframe.setAttribute('allow', 'clipboard-write;')

Expand Down Expand Up @@ -187,7 +186,7 @@ async function createTesters(testFiles: string[]) {
const container = await getContainer(config)

if (config.browser.ui) {
container.className = ''
container.className = 'scrolls'
container.textContent = ''
}

Expand Down
6 changes: 5 additions & 1 deletion packages/ui/client/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,22 @@ declare global {
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
const provide: typeof import('vue')['provide']
const provideLocal: typeof import('@vueuse/core')['provideLocal']
const provideResizing: typeof import('./composables/browser')['provideResizing']
const reactify: typeof import('@vueuse/core')['reactify']
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
const reactive: typeof import('vue')['reactive']
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
const reactivePick: typeof import('@vueuse/core')['reactivePick']
const readonly: typeof import('vue')['readonly']
const recalculateDetailPanels: typeof import('./composables/navigation')['recalculateDetailPanels']
const recalculateDetailPanels: typeof import('./composables/browser')['recalculateDetailPanels']
const ref: typeof import('vue')['ref']
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
const refDebounced: typeof import('@vueuse/core')['refDebounced']
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
const registerResizingListener: typeof import('./composables/browser')['registerResizingListener']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
Expand Down Expand Up @@ -239,6 +241,7 @@ declare global {
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
const useNetwork: typeof import('@vueuse/core')['useNetwork']
const useNotifyResizing: typeof import('./composables/browser')['useNotifyResizing']
const useNow: typeof import('@vueuse/core')['useNow']
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
Expand All @@ -260,6 +263,7 @@ declare global {
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
const useResizing: typeof import('./composables/browser')['useResizing']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
Expand Down
20 changes: 13 additions & 7 deletions packages/ui/client/components/BrowserIframe.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
<script setup lang="ts">
const viewport = ref('custom')
import { recalculateDetailPanels } from '~/composables/navigation'
import { useResizing } from '~/composables/browser'

const sizes = {
type ViewportSize = 'small-mobile' | 'large-mobile' | 'tablet' | 'custom'

const sizes: Record<ViewportSize, [width: string, height: string]> = {
'small-mobile': ['320px', '568px'],
'large-mobile': ['414px', '896px'],
tablet: ['834px', '1112px'],
custom: ['100%', '100%'],
}

async function changeViewport(name: string) {
const testerRef = ref<HTMLDivElement | undefined>()
const viewport = ref<ViewportSize>('custom')

const { recalculateDetailPanels } = useResizing(testerRef)

async function changeViewport(name: ViewportSize) {
if (viewport.value === name) {
viewport.value = 'custom'
} else {
viewport.value = name
}

const iframe = document.querySelector('#tester-ui iframe[data-vitest]')
const iframe = document.querySelector<HTMLIFrameElement>('#tester-ui iframe[data-vitest]')
if (!iframe) {
console.warn('Iframe not found')
return
Expand Down Expand Up @@ -84,8 +90,8 @@ async function changeViewport(name: string) {
@click="changeViewport('tablet')"
/>
</div>
<div flex-auto overflow-auto>
<div id="tester-ui" class="flex h-full justify-center items-center font-light op70" style="overflow: auto; width: 100%; height: 100%">
<div flex-auto class="scrolls">
<div id="tester-ui" ref="testerRef" class="flex h-full justify-center items-center font-light op70" style="overflow: auto; width: 100%; height: 100%">
Select a test to run
</div>
</div>
Expand Down
45 changes: 45 additions & 0 deletions packages/ui/client/composables/browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { Ref } from 'vue'
import { detailSizes } from '~/composables/navigation'

type ResizingListener = (isResizing: boolean) => void

const resizingListeners = new Set<ResizingListener>()

export function recalculateDetailPanels() {
const iframe = document.querySelector('#tester-ui iframe[data-vitest]')!
const panel = document.querySelector('#details-splitpanes')!
const panelWidth = panel.clientWidth
const iframeWidth = iframe.clientWidth
const iframePercent = Math.min((iframeWidth / panelWidth) * 100, 95)
const detailsPercent = 100 - iframePercent
detailSizes.value = [iframePercent, detailsPercent]
}

export function useResizing(testerRef: Ref<HTMLDivElement | undefined>) {
function onResizing(isResizing: boolean) {
const tester = testerRef.value
if (!tester)
return

tester.style.pointerEvents = isResizing ? 'none' : ''
}

onMounted(() => {
resizingListeners.add(onResizing)
})

onUnmounted(() => {
resizingListeners.delete(onResizing)
})

return { recalculateDetailPanels }
}

export function useNotifyResizing() {
function notifyResizing(isResizing: boolean) {
for (const listener of resizingListeners)
listener(isResizing)
}

return { notifyResizing }
}
10 changes: 0 additions & 10 deletions packages/ui/client/composables/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ export const detailSizes = useLocalStorage<[left: number, right: number]>('vites
initOnMounted: true,
})

export function recalculateDetailPanels() {
const iframe = document.querySelector('#tester-ui iframe[data-vitest]')!
const panel = document.querySelector('#details-splitpanes')!
const panelWidth = panel.clientWidth
const iframeWidth = iframe.clientWidth
const iframePercent = Math.min((iframeWidth / panelWidth) * 100, 95)
const detailsPercent = 100 - iframePercent
detailSizes.value = [iframePercent, detailsPercent]
}

// @ts-expect-error not typed global
window.__vitest_ui_api__ = {
get currentModule() {
Expand Down
8 changes: 6 additions & 2 deletions packages/ui/client/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
// @ts-expect-error missing types
import { Pane, Splitpanes } from 'splitpanes'
import { browserState } from '~/composables/client';
import { coverageUrl, coverageVisible, initializeNavigation, detailSizes } from '../composables/navigation'
import { coverageUrl, coverageVisible, initializeNavigation, detailSizes } from '~/composables/navigation'
import { useNotifyResizing } from '~/composables/browser'

const { notifyResizing } = useNotifyResizing()
const dashboardVisible = initializeNavigation()

const mainSizes = useLocalStorage<[left: number, right: number]>('vitest-ui_splitpanes-mainSizes', [33, 67], {
initOnMounted: true,
})
Expand All @@ -18,6 +21,7 @@ const onModuleResized = useDebounceFn((event: { size: number }[]) => {
event.forEach((e, i) => {
detailSizes.value[i] = e.size
})
notifyResizing(false)
}, 0)

function resizeMain() {
Expand All @@ -41,7 +45,7 @@ function resizeMain() {
<Coverage v-else-if="coverageVisible" key="coverage" :src="coverageUrl" />
<FileDetails v-else />
</transition>
<Splitpanes v-else key="detail" id="details-splitpanes" @resized="onModuleResized">
<Splitpanes v-else key="detail" id="details-splitpanes" @resize="notifyResizing(true)" @resized="onModuleResized">
<Pane :size="detailSizes[0]">
<BrowserIframe v-once />
</Pane>
Expand Down
Loading