UNPKG

browser-use-typescript

Version:

A TypeScript-based browser automation framework

158 lines 5.56 kB
import { HistoryTreeProcessor } from "../domHIstory/historyTypes"; export class DOMTextNode { text; type = 'TEXT_NODE'; isVisible; parent; constructor(text, isVisible, parent) { this.text = text; this.isVisible = isVisible; this.parent = parent; } hasParentWithHighlightIndex() { let current = this.parent; while (current !== null) { if (current.highlightIndex !== null) { return true; } current = current.parent; } return false; } isParentInViewport() { return this.parent?.isInViewport ?? false; } isParentTopElement() { return this.parent?.isTopElement ?? false; } } export class DOMElementNode { tagName; //okay xpath; //okay attributes; //okay children; //okay isVisible; parent; isInteractive = false; //okay isTopElement = false; //okay isInViewport = false; //okay shadowRoot = false; highlightIndex = null; viewportCoordinates = null; pageCoordinates = null; viewportInfo = null; constructor(tagName, xpath, attributes, children, isVisible, parent) { this.tagName = tagName; this.xpath = xpath; this.attributes = attributes; this.children = children; this.isVisible = isVisible; this.parent = parent; } toString() { let tagStr = `<${this.tagName}`; for (const [key, value] of Object.entries(this.attributes)) { tagStr += ` ${key}="${value}"`; } tagStr += '>'; const extras = []; if (this.isInteractive) extras.push('interactive'); if (this.isTopElement) extras.push('top'); if (this.shadowRoot) extras.push('shadow-root'); if (this.highlightIndex !== null) extras.push(`highlight:${this.highlightIndex}`); if (this.isInViewport) extras.push('in-viewport'); if (extras.length > 0) { tagStr += ` [${extras.join(', ')}]`; } return tagStr; } get hash() { return HistoryTreeProcessor.hashDomElement(this); } getAllTextTillNextClickableElement(maxDepth = -1) { const textParts = []; const collectText = (node, currentDepth) => { if (maxDepth !== -1 && currentDepth > maxDepth) return; if (node instanceof DOMElementNode && node !== this && node.highlightIndex !== null) return; if (node instanceof DOMTextNode) { textParts.push(node.text); } else if (node instanceof DOMElementNode) { node.children.forEach(child => collectText(child, currentDepth + 1)); } }; collectText(this, 0); return textParts.join('\n').trim(); } clickableElementsToString(includeAttributes = null) { const formattedText = []; const processNode = (node, depth) => { if (node instanceof DOMElementNode) { if (node.highlightIndex !== null) { let attributesStr = ''; const text = node.getAllTextTillNextClickableElement(); if (includeAttributes) { const attributes = Array.from(new Set(Object.entries(node.attributes) .filter(([key, value]) => includeAttributes.includes(key) && value !== node.tagName) .map(([, value]) => value))); if (attributes.includes(text)) attributes.splice(attributes.indexOf(text), 1); attributesStr = attributes.join(';'); } let line = `[${node.highlightIndex}]<${node.tagName} `; if (attributesStr) line += `${attributesStr}`; if (text) line += `${attributesStr ? '>' : ''}${text}`; line += '/>'; formattedText.push(line); } node.children.forEach(child => processNode(child, depth + 1)); } else if (node instanceof DOMTextNode) { if (!node.hasParentWithHighlightIndex() && node.isVisible) { formattedText.push(node.text); } } }; processNode(this, 0); return formattedText.join('\n'); } getFileUploadElement(checkSiblings = true) { if (this.tagName === 'input' && this.attributes.type === 'file') return this; for (const child of this.children) { if (child instanceof DOMElementNode) { const result = child.getFileUploadElement(false); if (result) return result; } } if (checkSiblings && this.parent) { for (const sibling of this.parent.children) { if (sibling !== this && sibling instanceof DOMElementNode) { const result = sibling.getFileUploadElement(false); if (result) return result; } } } return null; } } export class DOMState { elementTree; selectorMap; constructor(elementTree, selectorMap) { this.elementTree = elementTree; this.selectorMap = selectorMap; } } //# sourceMappingURL=domClass.js.map