Merge pull request #959 from openreplay/clickmap-fix
fix(player, frontend): use ScaleMode for screen refactor(player-ui): remove isClickmap from ReplayPlayer refactor(player): pass MarkerClick callback on targets ingection
This commit is contained in:
commit
d2bf74f7e9
11 changed files with 112 additions and 141 deletions
|
|
@ -7,21 +7,15 @@ import { PlayerContext } from 'App/components/Session/playerContext';
|
|||
import { observer } from 'mobx-react-lite'
|
||||
|
||||
function Player() {
|
||||
const [wrapperHeight, setWrapperHeight] = React.useState(0);
|
||||
const playerContext = React.useContext(PlayerContext);
|
||||
const screenWrapper = React.useRef<HTMLDivElement>(null);
|
||||
const portHeight = playerContext.store.get().portHeight
|
||||
React.useEffect(() => {
|
||||
const parentElement = findDOMNode(screenWrapper.current) as HTMLDivElement | null; //TODO: good architecture
|
||||
const parentElement = findDOMNode(screenWrapper.current) as HTMLDivElement | null;
|
||||
if (parentElement) {
|
||||
playerContext.player.attach(parentElement);
|
||||
playerContext.player.play();
|
||||
}
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
setWrapperHeight(portHeight)
|
||||
}, [portHeight]);
|
||||
|
||||
if (!playerContext.player) return null;
|
||||
|
||||
|
|
@ -31,7 +25,7 @@ function Player() {
|
|||
>
|
||||
<div className={cn("relative flex-1", 'overflow-visible')}>
|
||||
<Overlay isClickmap />
|
||||
<div className={cn(stl.screenWrapper, '!overflow-y-scroll')} style={{ height: wrapperHeight, maxHeight: 800 }} ref={screenWrapper} />
|
||||
<div className={cn(stl.screenWrapper, '!overflow-y-scroll')} style={{ maxHeight: 800 }} ref={screenWrapper} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createWebPlayer } from 'Player';
|
||||
import { createClickMapPlayer } from 'Player';
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
import withLocationHandlers from 'HOCs/withLocationHandlers';
|
||||
import PlayerContent from './ThinPlayerContent';
|
||||
|
|
@ -20,11 +20,10 @@ function WebPlayer(props: any) {
|
|||
const [contextValue, setContextValue] = useState<IPlayerContext>(defaultContextValue);
|
||||
|
||||
useEffect(() => {
|
||||
const [WebPlayerInst, PlayerStore] = createWebPlayer(customSession, (state) =>
|
||||
const [WebPlayerInst, PlayerStore] = createClickMapPlayer(customSession, (state) =>
|
||||
makeAutoObservable(state)
|
||||
);
|
||||
setContextValue({ player: WebPlayerInst, store: PlayerStore });
|
||||
WebPlayerInst.setMarkerClick(onMarkerClick)
|
||||
|
||||
return () => WebPlayerInst.clean();
|
||||
}, [session.sessionId]);
|
||||
|
|
@ -35,10 +34,10 @@ function WebPlayer(props: any) {
|
|||
contextValue.player && contextValue.player.play()
|
||||
if (isPlayerReady && insights.size > 0) {
|
||||
setTimeout(() => {
|
||||
contextValue.player.jump(jumpTimestamp)
|
||||
contextValue.player.pause()
|
||||
contextValue.player.scaleFullPage()
|
||||
setTimeout(() => { contextValue.player.showClickmap(insights) }, 250)
|
||||
contextValue.player.jump(jumpTimestamp)
|
||||
contextValue.player.scale()
|
||||
setTimeout(() => { contextValue.player.showClickmap(insights, onMarkerClick) }, 250)
|
||||
}, 500)
|
||||
}
|
||||
return () => {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ interface IProps {
|
|||
activeTab: string;
|
||||
jiraConfig: Record<string, any>
|
||||
fullView?: boolean
|
||||
isClickmap?: boolean
|
||||
}
|
||||
|
||||
function PlayerBlock(props: IProps) {
|
||||
|
|
@ -24,14 +23,12 @@ function PlayerBlock(props: IProps) {
|
|||
activeTab,
|
||||
jiraConfig,
|
||||
fullView = false,
|
||||
isClickmap
|
||||
} = props;
|
||||
|
||||
const shouldShowSubHeader = !fullscreen && !fullView && !isClickmap
|
||||
const shouldShowSubHeader = !fullscreen && !fullView
|
||||
return (
|
||||
<div
|
||||
className={cn(styles.playerBlock, 'flex flex-col', !isClickmap ? 'overflow-x-hidden' : 'overflow-visible')}
|
||||
style={{ zIndex: isClickmap ? 1 : undefined, minWidth: isClickmap ? '100%' : undefined }}
|
||||
className={cn(styles.playerBlock, 'flex flex-col', 'overflow-x-hidden')}
|
||||
>
|
||||
{shouldShowSubHeader ? (
|
||||
<SubHeader sessionId={sessionId} disabled={disabled} jiraConfig={jiraConfig} />
|
||||
|
|
@ -39,7 +36,6 @@ function PlayerBlock(props: IProps) {
|
|||
<Player
|
||||
activeTab={activeTab}
|
||||
fullView={fullView}
|
||||
isClickmap={isClickmap}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -17,11 +17,10 @@ interface IProps {
|
|||
fullscreen: boolean;
|
||||
activeTab: string;
|
||||
setActiveTab: (tab: string) => void;
|
||||
isClickmap: boolean;
|
||||
session: Session
|
||||
}
|
||||
|
||||
function PlayerContent({ session, fullscreen, activeTab, setActiveTab, isClickmap }: IProps) {
|
||||
function PlayerContent({ session, fullscreen, activeTab, setActiveTab }: IProps) {
|
||||
const { store } = React.useContext(PlayerContext)
|
||||
|
||||
const {
|
||||
|
|
@ -60,7 +59,7 @@ function PlayerContent({ session, fullscreen, activeTab, setActiveTab, isClickma
|
|||
style={activeTab && !fullscreen ? { maxWidth: 'calc(100% - 270px)' } : undefined}
|
||||
>
|
||||
<div className={cn(styles.session, 'relative')} data-fullscreen={fullscreen}>
|
||||
<PlayerBlock activeTab={activeTab} isClickmap={isClickmap} />
|
||||
<PlayerBlock activeTab={activeTab} />
|
||||
</div>
|
||||
</div>
|
||||
{activeTab !== '' && (
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ interface IProps {
|
|||
nextId: string;
|
||||
sessionId: string;
|
||||
activeTab: string;
|
||||
isClickmap?: boolean;
|
||||
updateLastPlayedSession: (id: string) => void
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import withLocationHandlers from 'HOCs/withLocationHandlers';
|
|||
import { useStore } from 'App/mstore';
|
||||
import PlayerBlockHeader from './Player/ReplayPlayer/PlayerBlockHeader';
|
||||
import ReadNote from '../Session_/Player/Controls/components/ReadNote';
|
||||
import { fetchList as fetchMembers } from 'Duck/member';
|
||||
import PlayerContent from './Player/ReplayPlayer/PlayerContent';
|
||||
import { IPlayerContext, PlayerContext, defaultContextValue } from './playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
|
@ -28,7 +27,6 @@ function WebPlayer(props: any) {
|
|||
fullscreen,
|
||||
fetchList,
|
||||
customSession,
|
||||
isClickmap,
|
||||
insights,
|
||||
jumpTimestamp,
|
||||
onMarkerClick,
|
||||
|
|
@ -41,28 +39,21 @@ function WebPlayer(props: any) {
|
|||
const [contextValue, setContextValue] = useState<IPlayerContext>(defaultContextValue);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isClickmap) {
|
||||
fetchList('issues');
|
||||
}
|
||||
const usedSession = isClickmap && customSession ? customSession : session;
|
||||
fetchList('issues');
|
||||
|
||||
const [WebPlayerInst, PlayerStore] = createWebPlayer(usedSession, (state) =>
|
||||
const [WebPlayerInst, PlayerStore] = createWebPlayer(session, (state) =>
|
||||
makeAutoObservable(state)
|
||||
);
|
||||
setContextValue({ player: WebPlayerInst, store: PlayerStore });
|
||||
|
||||
if (!isClickmap) {
|
||||
notesStore.fetchSessionNotes(session.sessionId).then((r) => {
|
||||
const note = props.query.get('note');
|
||||
if (note) {
|
||||
WebPlayerInst.pause();
|
||||
setNoteItem(notesStore.getNoteById(parseInt(note, 10), r));
|
||||
setShowNote(true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
WebPlayerInst.setMarkerClick(onMarkerClick)
|
||||
}
|
||||
notesStore.fetchSessionNotes(session.sessionId).then((r) => {
|
||||
const note = props.query.get('note');
|
||||
if (note) {
|
||||
WebPlayerInst.pause();
|
||||
setNoteItem(notesStore.getNoteById(parseInt(note, 10), r));
|
||||
setShowNote(true);
|
||||
}
|
||||
})
|
||||
|
||||
const jumpToTime = props.query.get('jumpto');
|
||||
const freeze = props.query.get('freeze')
|
||||
|
|
@ -100,34 +91,29 @@ function WebPlayer(props: any) {
|
|||
|
||||
return (
|
||||
<PlayerContext.Provider value={contextValue}>
|
||||
<>
|
||||
{!isClickmap ? (
|
||||
<PlayerBlockHeader
|
||||
// @ts-ignore TODO?
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
tabs={TABS}
|
||||
fullscreen={fullscreen}
|
||||
<PlayerBlockHeader
|
||||
// @ts-ignore TODO?
|
||||
activeTab={activeTab}
|
||||
setActiveTab={setActiveTab}
|
||||
tabs={TABS}
|
||||
fullscreen={fullscreen}
|
||||
/>
|
||||
{/* @ts-ignore */}
|
||||
<PlayerContent
|
||||
activeTab={activeTab}
|
||||
fullscreen={fullscreen}
|
||||
setActiveTab={setActiveTab}
|
||||
session={session}
|
||||
/>
|
||||
<Modal open={showNoteModal} onClose={onNoteClose}>
|
||||
{showNoteModal ? (
|
||||
<ReadNote
|
||||
note={noteItem}
|
||||
onClose={onNoteClose}
|
||||
notFound={!noteItem}
|
||||
/>
|
||||
) : null}
|
||||
{/* @ts-ignore */}
|
||||
<PlayerContent
|
||||
activeTab={activeTab}
|
||||
fullscreen={fullscreen}
|
||||
setActiveTab={setActiveTab}
|
||||
session={session}
|
||||
isClickmap={isClickmap}
|
||||
/>
|
||||
<Modal open={showNoteModal} onClose={onNoteClose}>
|
||||
{showNoteModal ? (
|
||||
<ReadNote
|
||||
note={noteItem}
|
||||
onClose={onNoteClose}
|
||||
notFound={!noteItem}
|
||||
/>
|
||||
) : null}
|
||||
</Modal>
|
||||
</>
|
||||
</Modal>
|
||||
</PlayerContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
@ -146,6 +132,5 @@ export default connect(
|
|||
toggleFullscreen,
|
||||
closeBottomBlock,
|
||||
fetchList,
|
||||
fetchMembers,
|
||||
}
|
||||
)(withLocationHandlers()(observer(WebPlayer)));
|
||||
|
|
|
|||
|
|
@ -27,6 +27,18 @@ export function createWebPlayer(session: Record<string, any>, wrapStore?: (s:IWe
|
|||
}
|
||||
|
||||
|
||||
export function createClickMapPlayer(session: Record<string, any>, wrapStore?: (s:IWebPlayerStore) => IWebPlayerStore): [IWebPlayer, IWebPlayerStore] {
|
||||
let store: WebPlayerStore = new SimpleStore<WebState>({
|
||||
...WebPlayer.INITIAL_STATE,
|
||||
})
|
||||
if (wrapStore) {
|
||||
store = wrapStore(store)
|
||||
}
|
||||
|
||||
const player = new WebPlayer(store, session, false, true)
|
||||
return [player, store]
|
||||
}
|
||||
|
||||
export function createLiveWebPlayer(session: Record<string, any>, config: RTCIceServer[], wrapStore?: (s:IWebLivePlayerStore) => IWebLivePlayerStore): [IWebLivePlayer, IWebLivePlayerStore] {
|
||||
let store: WebLivePlayerStore = new SimpleStore<WebLiveState>({
|
||||
...WebLivePlayer.INITIAL_STATE,
|
||||
|
|
|
|||
|
|
@ -153,15 +153,18 @@ export default class Animator {
|
|||
}
|
||||
|
||||
freeze() {
|
||||
if (this.store.get().ready) {
|
||||
// making sure that replay is displayed completely
|
||||
setTimeout(() => {
|
||||
this.store.update({ freeze: true })
|
||||
this.pause()
|
||||
}, 250)
|
||||
} else {
|
||||
setTimeout(() => this.freeze(), 500)
|
||||
}
|
||||
return new Promise<void>(res => {
|
||||
if (this.store.get().ready) {
|
||||
// making sure that replay is displayed completely
|
||||
setTimeout(() => {
|
||||
this.store.update({ freeze: true })
|
||||
this.pause()
|
||||
res()
|
||||
}, 250)
|
||||
} else {
|
||||
setTimeout(() => res(this.freeze()), 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
togglePlay = () => {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,13 @@ export const INITIAL_STATE: State = {
|
|||
}
|
||||
|
||||
|
||||
export enum ScaleMode {
|
||||
Embed,
|
||||
//AdjustParentWidth
|
||||
AdjustParentHeight,
|
||||
}
|
||||
|
||||
|
||||
function getElementsFromInternalPoint(doc: Document, { x, y }: Point): Element[] {
|
||||
// @ts-ignore (IE, Edge)
|
||||
if (typeof doc.msElementsFromRect === 'function') {
|
||||
|
|
@ -55,9 +62,9 @@ export default class Screen {
|
|||
|
||||
private readonly iframe: HTMLIFrameElement;
|
||||
private readonly screen: HTMLDivElement;
|
||||
private parentElement: HTMLElement | null = null;
|
||||
private parentElement: HTMLElement | null = null
|
||||
|
||||
constructor(isMobile: boolean) {
|
||||
constructor(isMobile: boolean, private scaleMode: ScaleMode = ScaleMode.Embed) {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.className = styles.iframe;
|
||||
this.iframe = iframe;
|
||||
|
|
@ -79,11 +86,10 @@ export default class Screen {
|
|||
attach(parentElement: HTMLElement) {
|
||||
if (this.parentElement) {
|
||||
this.parentElement = null
|
||||
console.error("BaseScreen: Trying to attach an attached screen.");
|
||||
console.warn("BaseScreen: reattaching the screen.");
|
||||
}
|
||||
|
||||
parentElement.appendChild(this.screen);
|
||||
|
||||
this.parentElement = parentElement;
|
||||
|
||||
/* == For the Inspecting Document content == */
|
||||
|
|
@ -124,6 +130,7 @@ export default class Screen {
|
|||
private boundingRect: DOMRect | null = null;
|
||||
private getBoundingClientRect(): DOMRect {
|
||||
if (this.boundingRect === null) {
|
||||
// TODO: use this.screen instead in order to separate overlay functionality
|
||||
return this.boundingRect = this.overlay.getBoundingClientRect() // expensive operation?
|
||||
}
|
||||
return this.boundingRect
|
||||
|
|
@ -200,48 +207,41 @@ export default class Screen {
|
|||
if (!this.parentElement) return;
|
||||
const { offsetWidth, offsetHeight } = this.parentElement;
|
||||
|
||||
this.scaleRatio = Math.min(offsetWidth / width, offsetHeight / height);
|
||||
if (this.scaleRatio > 1) {
|
||||
this.scaleRatio = 1;
|
||||
} else {
|
||||
this.scaleRatio = Math.round(this.scaleRatio * 1e3) / 1e3;
|
||||
let translate = ""
|
||||
let posStyles = {}
|
||||
switch (this.scaleMode) {
|
||||
case ScaleMode.Embed:
|
||||
this.scaleRatio = Math.min(offsetWidth / width, offsetHeight / height)
|
||||
translate = "translate(-50%, -50%)"
|
||||
break;
|
||||
case ScaleMode.AdjustParentHeight:
|
||||
this.scaleRatio = offsetWidth / width
|
||||
translate = "translate(-50%, 0)"
|
||||
posStyles = { top: 0 }
|
||||
break;
|
||||
}
|
||||
this.screen.style.transform = `scale(${ this.scaleRatio }) translate(-50%, -50%)`;
|
||||
this.screen.style.width = width + 'px';
|
||||
this.screen.style.height = height + 'px';
|
||||
this.iframe.style.width = width + 'px';
|
||||
this.iframe.style.height = height + 'px';
|
||||
|
||||
this.boundingRect = this.overlay.getBoundingClientRect();
|
||||
}
|
||||
|
||||
scaleFullPage() {
|
||||
if (!this.parentElement || !this.document) return;
|
||||
|
||||
const { width: boxWidth } = this.parentElement.getBoundingClientRect();
|
||||
const { height, width } = this.document.body.getBoundingClientRect();
|
||||
this.overlay.remove()
|
||||
|
||||
this.scaleRatio = boxWidth/width;
|
||||
if (this.scaleRatio > 1) {
|
||||
this.scaleRatio = 1;
|
||||
} else {
|
||||
this.scaleRatio = Math.round(this.scaleRatio * 1e3) / 1e3;
|
||||
}
|
||||
|
||||
Object.assign(this.screen.style, {
|
||||
top: '0',
|
||||
left: '50%',
|
||||
if (this.scaleMode === ScaleMode.AdjustParentHeight) {
|
||||
this.parentElement.style.height = this.scaleRatio * height + 'px'
|
||||
}
|
||||
|
||||
Object.assign(this.screen.style, posStyles, {
|
||||
height: height + 'px',
|
||||
width: width + 'px',
|
||||
transform: `scale(${this.scaleRatio}) translate(-50%, 0)`,
|
||||
transform: `scale(${this.scaleRatio}) ${translate}`,
|
||||
})
|
||||
Object.assign(this.iframe.style, {
|
||||
width: width + 'px',
|
||||
height: height + 'px',
|
||||
})
|
||||
|
||||
return height
|
||||
this.boundingRect = this.overlay.getBoundingClientRect();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ import Player from '../player/Player'
|
|||
import MessageManager from './MessageManager'
|
||||
import InspectorController from './addons/InspectorController'
|
||||
import TargetMarker from './addons/TargetMarker'
|
||||
import Screen from './Screen/Screen'
|
||||
import Screen, { ScaleMode } from './Screen/Screen'
|
||||
|
||||
|
||||
// export type State = typeof WebPlayer.INITIAL_STATE
|
||||
|
||||
|
|
@ -17,7 +18,6 @@ export default class WebPlayer extends Player {
|
|||
...MessageManager.INITIAL_STATE,
|
||||
|
||||
inspectorMode: false,
|
||||
portHeight: 0,
|
||||
}
|
||||
|
||||
private readonly inspectorController: InspectorController
|
||||
|
|
@ -26,7 +26,7 @@ export default class WebPlayer extends Player {
|
|||
|
||||
private targetMarker: TargetMarker
|
||||
|
||||
constructor(protected wpState: Store<typeof WebPlayer.INITIAL_STATE>, session: any, live: boolean) {
|
||||
constructor(protected wpState: Store<typeof WebPlayer.INITIAL_STATE>, session: any, live: boolean, isClickMap = false) {
|
||||
let initialLists = live ? {} : {
|
||||
event: session.events || [],
|
||||
stack: session.stackEvents || [],
|
||||
|
|
@ -40,7 +40,7 @@ export default class WebPlayer extends Player {
|
|||
) || [],
|
||||
}
|
||||
|
||||
const screen = new Screen(session.isMobile)
|
||||
const screen = new Screen(session.isMobile, isClickMap ? ScaleMode.AdjustParentHeight : ScaleMode.Embed)
|
||||
const messageManager = new MessageManager(session, wpState, screen, initialLists)
|
||||
super(wpState, messageManager)
|
||||
this.screen = screen
|
||||
|
|
@ -71,20 +71,11 @@ export default class WebPlayer extends Player {
|
|||
}
|
||||
|
||||
scale = () => {
|
||||
console.log('called scale')
|
||||
const { width, height } = this.wpState.get()
|
||||
this.screen.scale({ width, height })
|
||||
this.inspectorController.scale({ width, height })
|
||||
|
||||
// this.updateMarketTargets() ??
|
||||
}
|
||||
|
||||
scaleFullPage = () => {
|
||||
window.removeEventListener('resize', this.scale)
|
||||
window.addEventListener('resize', this.scaleFullPage)
|
||||
|
||||
const portHeight = this.screen.scaleFullPage()
|
||||
return this.wpState.update({ portHeight })
|
||||
this.targetMarker.updateMarkedTargets()
|
||||
}
|
||||
|
||||
// Inspector & marker
|
||||
|
|
@ -119,16 +110,11 @@ export default class WebPlayer extends Player {
|
|||
}
|
||||
|
||||
showClickmap = (...args: Parameters<TargetMarker['injectTargets']>) => {
|
||||
this.freeze()
|
||||
if (this.wpState.get().portHeight !== 0) {
|
||||
this.screen.overlay.remove() // hack. TODO: 1.split Screen functionalities (overlay, mounter) 2. separate ClickMapPlayer class that does not create overlay
|
||||
this.targetMarker.injectTargets(...args)
|
||||
this.freeze().then(() => {
|
||||
this.targetMarker.injectTargets(...args)
|
||||
} else {
|
||||
setTimeout(() => this.showClickmap(...args), 500)
|
||||
}
|
||||
}
|
||||
|
||||
setMarkerClick = (...args: Parameters<TargetMarker['setOnMarkerClick']>) => {
|
||||
this.targetMarker.setOnMarkerClick(...args)
|
||||
})
|
||||
}
|
||||
|
||||
toggleUserName = (name?: string) => {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ export default class TargetMarker {
|
|||
private clickMapOverlay: HTMLDivElement | null = null
|
||||
private clickContainers: HTMLDivElement[] = []
|
||||
private smallClicks: HTMLDivElement[] = []
|
||||
private onMarkerClick: (selector: string, innerText: string) => void
|
||||
static INITIAL_STATE: State = {
|
||||
markedTargets: null,
|
||||
activeTargetIndex: 0
|
||||
|
|
@ -50,7 +49,7 @@ export default class TargetMarker {
|
|||
private readonly store: Store<State>,
|
||||
) {}
|
||||
|
||||
updateMarketTargets() {
|
||||
updateMarkedTargets() {
|
||||
const { markedTargets } = this.store.get()
|
||||
if (markedTargets) {
|
||||
this.store.update({
|
||||
|
|
@ -137,7 +136,10 @@ export default class TargetMarker {
|
|||
}
|
||||
|
||||
|
||||
injectTargets(selections: { selector: string, count: number, clickRage?: boolean }[] | null) {
|
||||
injectTargets(
|
||||
selections: { selector: string, count: number, clickRage?: boolean }[] | null,
|
||||
onMarkerClick?: (selector: string, innerText: string) => void,
|
||||
) {
|
||||
if (selections) {
|
||||
const totalCount = selections.reduce((a, b) => {
|
||||
return a + b.count
|
||||
|
|
@ -183,7 +185,7 @@ export default class TargetMarker {
|
|||
border.onclick = (e) => {
|
||||
e.stopPropagation()
|
||||
const innerText = el.innerText.length > 25 ? `${el.innerText.slice(0, 20)}...` : el.innerText
|
||||
this.onMarkerClick?.(s.selector, innerText)
|
||||
onMarkerClick?.(s.selector, innerText)
|
||||
this.clickContainers.forEach(container => {
|
||||
if (container.id === containerId) {
|
||||
container.style.visibility = "visible"
|
||||
|
|
@ -202,7 +204,7 @@ export default class TargetMarker {
|
|||
|
||||
overlay.onclick = (e) => {
|
||||
e.stopPropagation()
|
||||
this.onMarkerClick('', '')
|
||||
onMarkerClick?.('', '')
|
||||
this.clickContainers.forEach(container => {
|
||||
container.style.visibility = "hidden"
|
||||
})
|
||||
|
|
@ -228,8 +230,4 @@ export default class TargetMarker {
|
|||
}
|
||||
}
|
||||
|
||||
setOnMarkerClick(cb: (selector: string) => void) {
|
||||
this.onMarkerClick = cb
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue