{"version":3,"file":"web-page.mjs","sources":["../../src/web-page.ts"],"sourcesContent":["import type { Point } from '@midscene/core';\nimport { z } from '@midscene/core';\nimport {\n  AbstractInterface,\n  type BrowserInputPrimitives,\n  type DeviceAction,\n  type InputStrategy,\n  defineAction,\n  defineActionsFromInputPrimitives,\n  resolveTextInputOptions,\n  sendTextSequentially,\n} from '@midscene/core/device';\n\nimport { sleep } from '@midscene/core/utils';\nimport type { ElementInfo } from '@midscene/shared/extractor';\nimport { transformHotkeyInput } from '@midscene/shared/us-keyboard-layout';\n\nconst navigateParamSchema = z.object({\n  url: z\n    .string()\n    .describe(\n      'The URL to navigate to. Must start with https://, file://, or a similar protocol.',\n    ),\n});\n\nfunction normalizeKeyInputs(value: string | string[]): string[] {\n  const inputs = Array.isArray(value) ? value : [value];\n  const result: string[] = [];\n\n  for (const input of inputs) {\n    if (typeof input !== 'string') {\n      result.push(input as unknown as string);\n      continue;\n    }\n\n    const trimmed = input.trim();\n    if (!trimmed) {\n      result.push(input);\n      continue;\n    }\n\n    let normalized = trimmed;\n    if (normalized.length > 1 && normalized.includes('+')) {\n      normalized = normalized.replace(/\\s*\\+\\s*/g, ' ');\n    }\n    if (/\\s/.test(normalized)) {\n      normalized = normalized.replace(/\\s+/g, ' ');\n    }\n\n    const transformed = transformHotkeyInput(normalized);\n    if (transformed.length === 1 && transformed[0] === '' && trimmed !== '') {\n      result.push(input);\n      continue;\n    }\n    if (transformed.length === 0) {\n      result.push(input);\n      continue;\n    }\n\n    result.push(...transformed);\n  }\n\n  return result;\n}\n\nexport function getKeyCommands(\n  value: string | string[],\n): Array<{ key: string; command?: string }> {\n  const keys = normalizeKeyInputs(value);\n\n  return keys.reduce((acc: Array<{ key: string; command?: string }>, k) => {\n    const includeMeta = keys.includes('Meta') || keys.includes('Control');\n    if (includeMeta && (k === 'a' || k === 'A')) {\n      return acc.concat([{ key: k, command: 'SelectAll' }]);\n    }\n    if (includeMeta && (k === 'c' || k === 'C')) {\n      return acc.concat([{ key: k, command: 'Copy' }]);\n    }\n    if (includeMeta && (k === 'v' || k === 'V')) {\n      return acc.concat([{ key: k, command: 'Paste' }]);\n    }\n    return acc.concat([{ key: k }]);\n  }, []);\n}\n\n// this is copied from puppeteer, but we don't want to import puppeteer here\nexport declare type KeyInput =\n  | '0'\n  | '1'\n  | '2'\n  | '3'\n  | '4'\n  | '5'\n  | '6'\n  | '7'\n  | '8'\n  | '9'\n  | 'Power'\n  | 'Eject'\n  | 'Abort'\n  | 'Help'\n  | 'Backspace'\n  | 'Tab'\n  | 'Numpad5'\n  | 'NumpadEnter'\n  | 'Enter'\n  | '\\r'\n  | '\\n'\n  | 'ShiftLeft'\n  | 'ShiftRight'\n  | 'ControlLeft'\n  | 'ControlRight'\n  | 'AltLeft'\n  | 'AltRight'\n  | 'Pause'\n  | 'CapsLock'\n  | 'Escape'\n  | 'Convert'\n  | 'NonConvert'\n  | 'Space'\n  | 'Numpad9'\n  | 'PageUp'\n  | 'Numpad3'\n  | 'PageDown'\n  | 'End'\n  | 'Numpad1'\n  | 'Home'\n  | 'Numpad7'\n  | 'ArrowLeft'\n  | 'Numpad4'\n  | 'Numpad8'\n  | 'ArrowUp'\n  | 'ArrowRight'\n  | 'Numpad6'\n  | 'Numpad2'\n  | 'ArrowDown'\n  | 'Select'\n  | 'Open'\n  | 'PrintScreen'\n  | 'Insert'\n  | 'Numpad0'\n  | 'Delete'\n  | 'NumpadDecimal'\n  | 'Digit0'\n  | 'Digit1'\n  | 'Digit2'\n  | 'Digit3'\n  | 'Digit4'\n  | 'Digit5'\n  | 'Digit6'\n  | 'Digit7'\n  | 'Digit8'\n  | 'Digit9'\n  | 'KeyA'\n  | 'KeyB'\n  | 'KeyC'\n  | 'KeyD'\n  | 'KeyE'\n  | 'KeyF'\n  | 'KeyG'\n  | 'KeyH'\n  | 'KeyI'\n  | 'KeyJ'\n  | 'KeyK'\n  | 'KeyL'\n  | 'KeyM'\n  | 'KeyN'\n  | 'KeyO'\n  | 'KeyP'\n  | 'KeyQ'\n  | 'KeyR'\n  | 'KeyS'\n  | 'KeyT'\n  | 'KeyU'\n  | 'KeyV'\n  | 'KeyW'\n  | 'KeyX'\n  | 'KeyY'\n  | 'KeyZ'\n  | 'MetaLeft'\n  | 'MetaRight'\n  | 'ContextMenu'\n  | 'NumpadMultiply'\n  | 'NumpadAdd'\n  | 'NumpadSubtract'\n  | 'NumpadDivide'\n  | 'F1'\n  | 'F2'\n  | 'F3'\n  | 'F4'\n  | 'F5'\n  | 'F6'\n  | 'F7'\n  | 'F8'\n  | 'F9'\n  | 'F10'\n  | 'F11'\n  | 'F12'\n  | 'F13'\n  | 'F14'\n  | 'F15'\n  | 'F16'\n  | 'F17'\n  | 'F18'\n  | 'F19'\n  | 'F20'\n  | 'F21'\n  | 'F22'\n  | 'F23'\n  | 'F24'\n  | 'NumLock'\n  | 'ScrollLock'\n  | 'AudioVolumeMute'\n  | 'AudioVolumeDown'\n  | 'AudioVolumeUp'\n  | 'MediaTrackNext'\n  | 'MediaTrackPrevious'\n  | 'MediaStop'\n  | 'MediaPlayPause'\n  | 'Semicolon'\n  | 'Equal'\n  | 'NumpadEqual'\n  | 'Comma'\n  | 'Minus'\n  | 'Period'\n  | 'Slash'\n  | 'Backquote'\n  | 'BracketLeft'\n  | 'Backslash'\n  | 'BracketRight'\n  | 'Quote'\n  | 'AltGraph'\n  | 'Props'\n  | 'Cancel'\n  | 'Clear'\n  | 'Shift'\n  | 'Control'\n  | 'Alt'\n  | 'Accept'\n  | 'ModeChange'\n  | ' '\n  | 'Print'\n  | 'Execute'\n  | '\\u0000'\n  | 'a'\n  | 'b'\n  | 'c'\n  | 'd'\n  | 'e'\n  | 'f'\n  | 'g'\n  | 'h'\n  | 'i'\n  | 'j'\n  | 'k'\n  | 'l'\n  | 'm'\n  | 'n'\n  | 'o'\n  | 'p'\n  | 'q'\n  | 'r'\n  | 's'\n  | 't'\n  | 'u'\n  | 'v'\n  | 'w'\n  | 'x'\n  | 'y'\n  | 'z'\n  | 'Meta'\n  | '*'\n  | '+'\n  | '-'\n  | '/'\n  | ';'\n  | '='\n  | ','\n  | '.'\n  | '`'\n  | '['\n  | '\\\\'\n  | ']'\n  | \"'\"\n  | 'Attn'\n  | 'CrSel'\n  | 'ExSel'\n  | 'EraseEof'\n  | 'Play'\n  | 'ZoomOut'\n  | ')'\n  | '!'\n  | '@'\n  | '#'\n  | '$'\n  | '%'\n  | '^'\n  | '&'\n  | '('\n  | 'A'\n  | 'B'\n  | 'C'\n  | 'D'\n  | 'E'\n  | 'F'\n  | 'G'\n  | 'H'\n  | 'I'\n  | 'J'\n  | 'K'\n  | 'L'\n  | 'M'\n  | 'N'\n  | 'O'\n  | 'P'\n  | 'Q'\n  | 'R'\n  | 'S'\n  | 'T'\n  | 'U'\n  | 'V'\n  | 'W'\n  | 'X'\n  | 'Y'\n  | 'Z'\n  | ':'\n  | '<'\n  | '_'\n  | '>'\n  | '?'\n  | '~'\n  | '{'\n  | '|'\n  | '}'\n  | '\"'\n  | 'SoftLeft'\n  | 'SoftRight'\n  | 'Camera'\n  | 'Call'\n  | 'EndCall'\n  | 'VolumeDown'\n  | 'VolumeUp';\n\nexport type MouseButton = 'left' | 'right' | 'middle';\n\nexport interface MouseAction {\n  click: (\n    x: number,\n    y: number,\n    options: { button: MouseButton; count?: number },\n  ) => Promise<void>;\n  wheel: (deltaX: number, deltaY: number) => Promise<void>;\n  move: (x: number, y: number) => Promise<void>;\n  drag: (\n    from: { x: number; y: number },\n    to: { x: number; y: number },\n  ) => Promise<void>;\n}\n\nexport interface KeyboardAction {\n  type: (text: string, options?: { delay?: number }) => Promise<void>;\n  insertText: (text: string) => Promise<void>;\n  press: (\n    action:\n      | { key: KeyInput; command?: string }\n      | { key: KeyInput; command?: string }[],\n  ) => Promise<void>;\n}\n\nexport interface ChromePageDestroyOptions {\n  closeTab?: boolean; // should close the tab when the page object is destroyed\n}\n\nexport abstract class AbstractWebPage extends AbstractInterface {\n  readonly keyboardTypeDelay?: number;\n  readonly inputStrategy?: InputStrategy;\n  navigate?(url: string): Promise<void>;\n  reload?(): Promise<void>;\n  goBack?(): Promise<void>;\n  goForward?(): Promise<void>;\n  stopLoading?(): Promise<void>;\n  navigationState?(): Promise<{ isLoading: boolean }>;\n  flushPendingVisualUpdate?(force?: boolean): Promise<void>;\n  schedulePendingVisualUpdate?(force?: boolean): void;\n  waitForDomQuiet?(opts?: {\n    quietMs?: number;\n    timeoutMs?: number;\n    target?: ElementInfo;\n  }): Promise<void>;\n\n  get mouse(): MouseAction {\n    return {\n      click: async (\n        x: number,\n        y: number,\n        options: { button: MouseButton },\n      ) => {},\n      wheel: async (deltaX: number, deltaY: number) => {},\n      move: async (x: number, y: number) => {},\n      drag: async (\n        from: { x: number; y: number },\n        to: { x: number; y: number },\n      ) => {},\n    };\n  }\n\n  get keyboard(): KeyboardAction {\n    return {\n      type: async (text: string, options?: { delay?: number }) => {},\n      insertText: async (text: string) => {},\n      press: async (\n        action:\n          | { key: KeyInput; command?: string }\n          | { key: KeyInput; command?: string }[],\n      ) => {},\n    };\n  }\n\n  async clearInput(element?: ElementInfo): Promise<void> {}\n\n  async selectAllInput(element?: ElementInfo): Promise<void> {\n    throw new Error('Bulk text input is not supported by this web page');\n  }\n\n  abstract scrollUntilTop(startingPoint?: Point): Promise<void>;\n  abstract scrollUntilBottom(startingPoint?: Point): Promise<void>;\n  abstract scrollUntilLeft(startingPoint?: Point): Promise<void>;\n  abstract scrollUntilRight(startingPoint?: Point): Promise<void>;\n  abstract scrollUp(distance?: number, startingPoint?: Point): Promise<void>;\n  abstract scrollDown(distance?: number, startingPoint?: Point): Promise<void>;\n  abstract scrollLeft(distance?: number, startingPoint?: Point): Promise<void>;\n  abstract scrollRight(distance?: number, startingPoint?: Point): Promise<void>;\n  abstract longPress(x: number, y: number, duration?: number): Promise<void>;\n  abstract swipe(\n    from: { x: number; y: number },\n    to: { x: number; y: number },\n    duration?: number,\n  ): Promise<void>;\n  abstract pinch(\n    centerX: number,\n    centerY: number,\n    startDistance: number,\n    endDistance: number,\n    duration?: number,\n  ): Promise<void>;\n}\n\nconst scheduleWebVisualUpdate = (\n  page: AbstractWebPage,\n  force = false,\n): void => {\n  if (page.schedulePendingVisualUpdate) {\n    if (force) {\n      page.schedulePendingVisualUpdate(true);\n    } else {\n      page.schedulePendingVisualUpdate();\n    }\n    return;\n  }\n\n  const pendingRefresh = force\n    ? page.flushPendingVisualUpdate?.(true)\n    : page.flushPendingVisualUpdate?.();\n  void pendingRefresh?.catch(() => undefined);\n};\n\nexport function createWebInputPrimitives(\n  page: AbstractWebPage,\n): BrowserInputPrimitives {\n  const scheduleVisualUpdate = () => scheduleWebVisualUpdate(page);\n\n  return {\n    pointer: {\n      tap: async ({ x, y }) => {\n        await page.mouse.click(x, y, { button: 'left' });\n        scheduleVisualUpdate();\n      },\n      rightClick: async ({ x, y }) => {\n        await page.mouse.click(x, y, { button: 'right' });\n        scheduleVisualUpdate();\n      },\n      doubleClick: async ({ x, y }) => {\n        await page.mouse.click(x, y, { button: 'left', count: 2 });\n        scheduleVisualUpdate();\n      },\n      hover: async ({ x, y }) => {\n        await page.mouse.move(x, y);\n        scheduleVisualUpdate();\n      },\n      dragAndDrop: async (from, to) => {\n        await page.mouse.drag(from, to);\n        scheduleVisualUpdate();\n      },\n      longPress: async ({ x, y }, opts) => {\n        await page.longPress(x, y, opts?.duration);\n        scheduleVisualUpdate();\n      },\n    },\n    keyboard: {\n      typeText: async (value, opts) => {\n        const element = opts?.target;\n        const { inputStrategy, keyboardTypeDelay } = resolveTextInputOptions(\n          opts,\n          page,\n        );\n        if (element && opts?.replace !== false) {\n          if (inputStrategy === 'bulk') {\n            // Keep the current value selected so insertText replaces it in one\n            // input operation instead of emitting a separate empty value.\n            await page.selectAllInput(element as ElementInfo);\n          } else {\n            await page.clearInput(element as ElementInfo);\n            // Frameworks (React/Vue/etc.) often re-render in response to\n            // the `input` event fired by clearing. If that re-render lands\n            // between clearInput returning and the first typed character,\n            // the keypresses can be dropped. Wait for the DOM to settle\n            // before starting to type.\n            await page.waitForDomQuiet?.({ target: element as ElementInfo });\n          }\n        } else if (element && opts?.focusOnly) {\n          const target = element as ElementInfo;\n          await page.mouse.click(target.center[0], target.center[1], {\n            button: 'left',\n          });\n          await page.keyboard.press([{ key: 'End' }]);\n        }\n\n        if (opts?.focusOnly) {\n          return;\n        }\n\n        if (inputStrategy === 'bulk') {\n          await page.keyboard.insertText(value);\n        } else if (inputStrategy === 'sequential') {\n          await sendTextSequentially(\n            value,\n            {\n              // The shared loop owns the inter-character delay. Explicitly\n              // disable the page default so action-level zero remains\n              // effective and positive delays are not applied twice.\n              sendCharacter: (character) =>\n                page.keyboard.type(character, { delay: 0 }),\n              wait: sleep,\n            },\n            { delayMs: keyboardTypeDelay },\n          );\n        } else {\n          const keyboardTypeOptions =\n            keyboardTypeDelay === undefined\n              ? undefined\n              : { delay: keyboardTypeDelay };\n          await page.keyboard.type(value, keyboardTypeOptions);\n        }\n        scheduleVisualUpdate();\n      },\n      keyboardPress: async (keyName, opts) => {\n        const element = opts?.target as\n          | { center: [number, number] }\n          | undefined;\n        if (element) {\n          await page.mouse.click(element.center[0], element.center[1], {\n            button: 'left',\n          });\n        }\n\n        const keys = getKeyCommands(keyName);\n        await page.keyboard.press(keys as any);\n        scheduleVisualUpdate();\n      },\n      cursorMove: async (direction, times = 1) => {\n        const arrowKey = direction === 'left' ? 'ArrowLeft' : 'ArrowRight';\n        for (let i = 0; i < times; i++) {\n          await page.keyboard.press([{ key: arrowKey as any }]);\n          await sleep(100);\n        }\n      },\n      clearInput: async (target) => {\n        await page.clearInput(target as ElementInfo | undefined);\n      },\n    },\n    touch: {\n      pinch: async ({ x, y }, opts) => {\n        await page.pinch(\n          x,\n          y,\n          opts.startDistance,\n          opts.endDistance,\n          opts.duration,\n        );\n      },\n      swipe: async (from, to, opts) => {\n        await page.swipe(from, to, opts?.duration);\n      },\n    },\n    scroll: {\n      scroll: async (param) => {\n        const element = param.locate;\n        const startingPoint = element\n          ? {\n              left: element.center[0],\n              top: element.center[1],\n            }\n          : undefined;\n        const scrollToEventName = param?.scrollType;\n        if (scrollToEventName === 'scrollToTop') {\n          await page.scrollUntilTop(startingPoint);\n        } else if (scrollToEventName === 'scrollToBottom') {\n          await page.scrollUntilBottom(startingPoint);\n        } else if (scrollToEventName === 'scrollToRight') {\n          await page.scrollUntilRight(startingPoint);\n        } else if (scrollToEventName === 'scrollToLeft') {\n          await page.scrollUntilLeft(startingPoint);\n        } else if (scrollToEventName === 'singleAction' || !scrollToEventName) {\n          if (param?.direction === 'down' || !param || !param.direction) {\n            await page.scrollDown(param?.distance || undefined, startingPoint);\n          } else if (param.direction === 'up') {\n            await page.scrollUp(param.distance || undefined, startingPoint);\n          } else if (param.direction === 'left') {\n            await page.scrollLeft(param.distance || undefined, startingPoint);\n          } else if (param.direction === 'right') {\n            await page.scrollRight(param.distance || undefined, startingPoint);\n          } else {\n            throw new Error(`Unknown scroll direction: ${param.direction}`);\n          }\n          await sleep(500);\n        } else {\n          throw new Error(\n            `Unknown scroll event type: ${scrollToEventName}, param: ${JSON.stringify(\n              param,\n            )}`,\n          );\n        }\n        scheduleVisualUpdate();\n      },\n    },\n  };\n}\n\nexport const commonWebActionsForWebPage = <T extends AbstractWebPage>(\n  page: T,\n  includeTouchEvents = false,\n): DeviceAction<any>[] => {\n  const input = createWebInputPrimitives(page);\n  return [\n    ...defineActionsFromInputPrimitives(input, {\n      size: () => page.size(),\n      includeSwipe: includeTouchEvents,\n    }),\n\n    defineAction<typeof navigateParamSchema, { url: string }>({\n      name: 'Navigate',\n      description:\n        'Navigate the browser to a specified URL. Opens the URL in the current tab.',\n      paramSchema: navigateParamSchema,\n      sample: {\n        url: 'https://www.example.com',\n      },\n      call: async (param) => {\n        if (!page.navigate) {\n          throw new Error(\n            'Navigate operation is not supported on this page type',\n          );\n        }\n        await page.navigate(param.url);\n        scheduleWebVisualUpdate(page, true);\n      },\n    }),\n\n    defineAction({\n      name: 'Reload',\n      description: 'Reload the current page',\n      call: async () => {\n        if (!page.reload) {\n          throw new Error(\n            'Reload operation is not supported on this page type',\n          );\n        }\n        await page.reload();\n        scheduleWebVisualUpdate(page, true);\n      },\n    }),\n\n    defineAction({\n      name: 'GoBack',\n      description: 'Navigate back in browser history',\n      call: async () => {\n        if (!page.goBack) {\n          throw new Error(\n            'GoBack operation is not supported on this page type',\n          );\n        }\n        await page.goBack();\n        scheduleWebVisualUpdate(page, true);\n      },\n    }),\n    defineAction({\n      name: 'GoForward',\n      description: 'Navigate forward in browser history',\n      call: async () => {\n        if (!page.goForward) {\n          throw new Error(\n            'GoForward operation is not supported on this page type',\n          );\n        }\n        await page.goForward();\n        scheduleWebVisualUpdate(page, true);\n      },\n    }),\n  ];\n};\n"],"names":["navigateParamSchema","z","normalizeKeyInputs","value","inputs","Array","result","input","trimmed","normalized","transformed","transformHotkeyInput","getKeyCommands","keys","acc","k","includeMeta","AbstractWebPage","AbstractInterface","x","y","options","deltaX","deltaY","from","to","text","action","element","Error","scheduleWebVisualUpdate","page","force","pendingRefresh","undefined","createWebInputPrimitives","scheduleVisualUpdate","opts","inputStrategy","keyboardTypeDelay","resolveTextInputOptions","target","sendTextSequentially","character","sleep","keyboardTypeOptions","keyName","direction","times","arrowKey","i","param","startingPoint","scrollToEventName","JSON","commonWebActionsForWebPage","includeTouchEvents","defineActionsFromInputPrimitives","defineAction"],"mappings":"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"}