{"version":3,"file":"dom/views.mjs","sources":["webpack://@agent-infra/browser-use/./src/dom/views.ts"],"sourcesContent":["/**\n * The following code is modified based on\n * https://github.com/nanobrowser/nanobrowser/blob/master/chrome-extension/src/background/dom/views.ts\n *\n * Apache-2.0 License\n * Copyright (c) 2024 alexchenzl\n * https://github.com/nanobrowser/nanobrowser/blob/master/LICENSE\n */\nimport type { ViewportInfo, CoordinateSet } from './history/views';\n\nexport abstract class DOMBaseNode {\n  isVisible: boolean;\n  parent?: DOMElementNode | null;\n\n  constructor(isVisible: boolean, parent?: DOMElementNode | null) {\n    this.isVisible = isVisible;\n    // Use None as default and set parent later to avoid circular reference issues\n    this.parent = parent;\n  }\n}\n\nexport class DOMTextNode extends DOMBaseNode {\n  type = 'TEXT_NODE' as const;\n  text: string;\n\n  constructor(\n    text: string,\n    isVisible: boolean,\n    parent?: DOMElementNode | null,\n  ) {\n    super(isVisible, parent);\n    this.text = text;\n  }\n\n  hasParentWithHighlightIndex(): boolean {\n    let current = this.parent;\n    while (current != null) {\n      if (current.highlightIndex !== undefined) {\n        return true;\n      }\n      current = current.parent;\n    }\n    return false;\n  }\n}\n\nexport class DOMElementNode extends DOMBaseNode {\n  /**\n   * xpath: the xpath of the element from the last root node (shadow root or iframe OR document if no shadow root or iframe).\n   * To properly reference the element we need to recursively switch the root node until we find the element (work you way up the tree with `.parent`)\n   */\n  tagName: string | null;\n  xpath: string | null;\n  cssSelector: string | null;\n  attributes: Record<string, string>;\n  children: DOMBaseNode[];\n  isInteractive: boolean;\n  isTopElement: boolean;\n  shadowRoot: boolean;\n  highlightIndex?: number;\n  viewportCoordinates?: CoordinateSet;\n  pageCoordinates?: CoordinateSet;\n  viewportInfo?: ViewportInfo;\n\n  constructor(params: {\n    tagName: string | null;\n    xpath: string | null;\n    cssSelector: string | null;\n    attributes: Record<string, string>;\n    children: DOMBaseNode[];\n    isVisible: boolean;\n    isInteractive?: boolean;\n    isTopElement?: boolean;\n    shadowRoot?: boolean;\n    highlightIndex?: number;\n    viewportCoordinates?: CoordinateSet;\n    pageCoordinates?: CoordinateSet;\n    viewportInfo?: ViewportInfo;\n    parent?: DOMElementNode | null;\n  }) {\n    super(params.isVisible, params.parent);\n    this.tagName = params.tagName;\n    this.xpath = params.xpath;\n    this.cssSelector = params.cssSelector;\n    this.attributes = params.attributes;\n    this.children = params.children;\n    this.isInteractive = params.isInteractive ?? false;\n    this.isTopElement = params.isTopElement ?? false;\n    this.shadowRoot = params.shadowRoot ?? false;\n    this.highlightIndex = params.highlightIndex;\n    this.viewportCoordinates = params.viewportCoordinates;\n    this.pageCoordinates = params.pageCoordinates;\n    this.viewportInfo = params.viewportInfo;\n  }\n\n  getAllTextTillNextClickableElement(maxDepth = -1): string {\n    const textParts: string[] = [];\n\n    const collectText = (node: DOMBaseNode, currentDepth: number): void => {\n      if (maxDepth !== -1 && currentDepth > maxDepth) {\n        return;\n      }\n\n      // Skip this branch if we hit a highlighted element (except for the current node)\n      if (\n        node instanceof DOMElementNode &&\n        node !== this &&\n        node.highlightIndex !== undefined\n      ) {\n        return;\n      }\n\n      if (node instanceof DOMTextNode) {\n        textParts.push(node.text);\n      } else if (node instanceof DOMElementNode) {\n        for (const child of node.children) {\n          collectText(child, currentDepth + 1);\n        }\n      }\n    };\n\n    collectText(this, 0);\n    return textParts.join('\\n').trim();\n  }\n\n  clickableElementsToString(includeAttributes: string[] = []): string {\n    const formattedText: string[] = [];\n\n    const processNode = (node: DOMBaseNode, depth: number): void => {\n      if (node instanceof DOMElementNode) {\n        // Add element with highlight_index\n        if (node.highlightIndex !== undefined) {\n          let attributesStr = '';\n          if (includeAttributes.length) {\n            attributesStr = ` ${includeAttributes\n              .map((key) =>\n                node.attributes[key] ? `${key}=\"${node.attributes[key]}\"` : '',\n              )\n              .filter(Boolean)\n              .join(' ')}`;\n          }\n\n          formattedText.push(\n            `[${node.highlightIndex}]<${node.tagName}${attributesStr}>${node.getAllTextTillNextClickableElement()}</${node.tagName}>`,\n          );\n        }\n        // Process children regardless\n        for (const child of node.children) {\n          processNode(child, depth + 1);\n        }\n      } else if (node instanceof DOMTextNode) {\n        // Add text node only if it doesn't have a highlighted parent\n        if (!node.hasParentWithHighlightIndex()) {\n          formattedText.push(`[]${node.text}`);\n        }\n      }\n    };\n\n    processNode(this, 0);\n    return formattedText.join('\\n');\n  }\n\n  getFileUploadElement(checkSiblings = true): DOMElementNode | null {\n    // biome-ignore lint/complexity/useLiteralKeys: <explanation>\n    if (this.tagName === 'input' && this.attributes['type'] === 'file') {\n      return this;\n    }\n\n    for (const child of this.children) {\n      if (child instanceof DOMElementNode) {\n        const result = child.getFileUploadElement(false);\n        if (result) return result;\n      }\n    }\n\n    if (checkSiblings && this.parent) {\n      for (const sibling of this.parent.children) {\n        if (sibling !== this && sibling instanceof DOMElementNode) {\n          const result = sibling.getFileUploadElement(false);\n          if (result) return result;\n        }\n      }\n    }\n\n    return null;\n  }\n\n  getAdvancedCssSelector(): string {\n    return this.enhancedCssSelectorForElement();\n  }\n\n  convertSimpleXPathToCssSelector(xpath: string): string {\n    if (!xpath) {\n      return '';\n    }\n\n    // Remove leading slash if present\n    const cleanXpath = xpath.replace(/^\\//, '');\n\n    // Split into parts\n    const parts = cleanXpath.split('/');\n    const cssParts: string[] = [];\n\n    for (const part of parts) {\n      if (!part) {\n        continue;\n      }\n\n      // Handle index notation [n]\n      if (part.includes('[')) {\n        const bracketIndex = part.indexOf('[');\n        let basePart = part.substring(0, bracketIndex);\n        const indexPart = part.substring(bracketIndex);\n\n        // Handle multiple indices\n        const indices = indexPart\n          .split(']')\n          .slice(0, -1)\n          .map((i) => i.replace('[', ''));\n\n        for (const idx of indices) {\n          // Handle numeric indices\n          if (/^\\d+$/.test(idx)) {\n            try {\n              const index = Number.parseInt(idx, 10) - 1;\n              basePart += `:nth-of-type(${index + 1})`;\n            } catch (error) {\n              // continue\n            }\n          }\n          // Handle last() function\n          else if (idx === 'last()') {\n            basePart += ':last-of-type';\n          }\n          // Handle position() functions\n          else if (idx.includes('position()')) {\n            if (idx.includes('>1')) {\n              basePart += ':nth-of-type(n+2)';\n            }\n          }\n        }\n\n        cssParts.push(basePart);\n      } else {\n        cssParts.push(part);\n      }\n    }\n\n    const baseSelector = cssParts.join(' > ');\n    return baseSelector;\n  }\n\n  enhancedCssSelectorForElement(includeDynamicAttributes = true): string {\n    try {\n      if (!this.xpath) {\n        return '';\n      }\n\n      // Get base selector from XPath\n      let cssSelector = this.convertSimpleXPathToCssSelector(this.xpath);\n\n      // Handle class attributes\n      // biome-ignore lint/complexity/useLiteralKeys: <explanation>\n      if (this.attributes['class'] && includeDynamicAttributes) {\n        // Define a regex pattern for valid class names in CSS\n        const validClassNamePattern = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;\n\n        // Iterate through the class attribute values\n        // biome-ignore lint/complexity/useLiteralKeys: <explanation>s\n        const classes = this.attributes['class'].split(/\\s+/);\n        for (const className of classes) {\n          // Skip empty class names\n          if (!className.trim()) {\n            continue;\n          }\n\n          // Check if the class name is valid\n          if (validClassNamePattern.test(className)) {\n            // Append the valid class name to the CSS selector\n            cssSelector += `.${className}`;\n          }\n        }\n      }\n\n      // Expanded set of safe attributes that are stable and useful for selection\n      const SAFE_ATTRIBUTES = new Set([\n        // Data attributes (if they're stable in your application)\n        'id',\n        // Standard HTML attributes\n        'name',\n        'type',\n        'value',\n        'placeholder',\n        // Accessibility attributes\n        'aria-label',\n        'aria-labelledby',\n        'aria-describedby',\n        'role',\n        // Common form attributes\n        'for',\n        'autocomplete',\n        'required',\n        'readonly',\n        // Media attributes\n        'alt',\n        'title',\n        'src',\n        // Custom stable attributes\n        'href',\n        'target',\n      ]);\n\n      // Handle other attributes\n      if (includeDynamicAttributes) {\n        SAFE_ATTRIBUTES.add('data-id');\n        SAFE_ATTRIBUTES.add('data-qa');\n        SAFE_ATTRIBUTES.add('data-cy');\n        SAFE_ATTRIBUTES.add('data-testid');\n      }\n\n      // Handle other attributes\n      for (const [attribute, value] of Object.entries(this.attributes)) {\n        if (attribute === 'class') {\n          continue;\n        }\n\n        // Skip invalid attribute names\n        if (!attribute.trim()) {\n          continue;\n        }\n\n        if (!SAFE_ATTRIBUTES.has(attribute)) {\n          continue;\n        }\n\n        // Escape special characters in attribute names\n        const safeAttribute = attribute.replace(':', '\\\\:');\n\n        // Handle different value cases\n        if (value === '') {\n          cssSelector += `[${safeAttribute}]`;\n        } else if (/[\"'<>`\\n\\r\\t]/.test(value)) {\n          // Use contains for values with special characters\n          // Regex-substitute any whitespace with a single space, then trim\n          const collapsedValue = value.replace(/\\s+/g, ' ').trim();\n          // Escape embedded double-quotes\n          const safeValue = collapsedValue.replace(/\"/g, '\\\\\"');\n          cssSelector += `[${safeAttribute}*=\"${safeValue}\"]`;\n        } else {\n          cssSelector += `[${safeAttribute}=\"${value}\"]`;\n        }\n      }\n\n      return cssSelector;\n    } catch (error) {\n      // Fallback to a more basic selector if something goes wrong\n      const tagName = this.tagName || '*';\n      return `${tagName}[highlight-index='${this.highlightIndex}']`;\n    }\n  }\n}\n\nexport interface DOMState {\n  elementTree: DOMElementNode;\n  selectorMap: Map<number, DOMElementNode>;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport function domElementNodeToDict(elementTree: DOMBaseNode): any {\n  // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n  function nodeToDict(node: DOMBaseNode): any {\n    if (node instanceof DOMTextNode) {\n      return {\n        type: 'text',\n        text: node.text,\n      };\n    }\n    if (node instanceof DOMElementNode) {\n      return {\n        type: 'element',\n        tagName: node.tagName, // Note: using camelCase to match TypeScript conventions\n        attributes: node.attributes,\n        highlightIndex: node.highlightIndex,\n        children: node.children.map((child) => nodeToDict(child)),\n      };\n    }\n\n    return {};\n  }\n\n  return nodeToDict(elementTree);\n}\n"],"names":["DOMBaseNode","isVisible","parent","DOMTextNode","current","undefined","text","DOMElementNode","maxDepth","textParts","collectText","node","currentDepth","child","includeAttributes","formattedText","processNode","depth","attributesStr","key","Boolean","checkSiblings","result","sibling","xpath","cleanXpath","parts","cssParts","part","bracketIndex","basePart","indexPart","indices","i","idx","index","Number","error","baseSelector","includeDynamicAttributes","cssSelector","validClassNamePattern","classes","className","SAFE_ATTRIBUTES","Set","attribute","value","Object","safeAttribute","collapsedValue","safeValue","tagName","params","domElementNodeToDict","elementTree","nodeToDict"],"mappings":"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"}