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

chore(web-extract): optimize script_get_all_texts.ts #121

Merged
merged 1 commit into from
Oct 14, 2024
Merged
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
82 changes: 34 additions & 48 deletions packages/midscene/src/query/fixture/script_get_all_texts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,49 +15,45 @@ const script = `

function setDataForNode(node) {
const taskId = window[taskIdKey];
const dataValue = window[nodeIndexKey];
window[nodeIndexKey] += 1;
if (!taskId) {
console.error('No task id found');
return;
console.error('Error: Task ID not found.');
return null;
}

const dataValue = window[nodeIndexKey];
window[nodeIndexKey] += 1;

const selector = selectorForValue(dataValue);
node.setAttribute(dataKey(), dataValue);
return selector;
}

function visibleRect(el) {
// Check if the element is in the DOM hierarchy
if (!el) {
console.log('Element is not in the DOM hierarchy');
console.warn('Warning: Element not found in DOM hierarchy.');
return false;
}

// If 'el' is not an instance of Element, find the nearest parent Element
if (!(el instanceof Element)) {
el = el.parentElement;
if (!el) {
console.log('Element is not in the DOM hierarchy');
console.warn('Warning: Parent element not found.');
return false;
}
}

// Check if the computed display property is "none"
const style = window.getComputedStyle(el);
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') {
console.log('Element is hidden');
if (['none', 'hidden'].includes(style.display) || style.visibility === 'hidden' || style.opacity === '0') {
console.warn('Warning: Element is hidden.');
return false;
}

// It seems that the value might be wrong if an external monitor is connected ?
const rect = el.getBoundingClientRect();
if (rect.width === 0 && rect.height === 0) {
console.log('Element has no size');
console.warn('Warning: Element has no size.');
return false;
}

// Check if the element is hidden via clipping or scrolling.
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

Expand All @@ -68,12 +64,10 @@ const script = `
rect.right <= (window.innerWidth || document.documentElement.clientWidth) + scrollLeft;

if (!isInViewport) {
console.log('Element is not in the viewport');
console.log(rect, window.innerHeight, window.innerWidth, scrollTop, scrollLeft);
console.warn('Warning: Element is not in the viewport.');
return false;
}

// Check for overflow:hidden on the element's ancestors
let parent = el;
while (parent && parent !== document.body) {
const parentStyle = window.getComputedStyle(parent);
Expand All @@ -86,14 +80,13 @@ const script = `
rect.bottom > parentRect.bottom + tolerance ||
rect.right > parentRect.right + tolerance
) {
console.log('Element is clipped by an ancestor', parent, rect, parentRect);
console.warn('Warning: Element is clipped by an ancestor.', parent);
return false;
}
}
parent = parent.parentElement;
}

// Return the rect object if the element is visible
return {
rect: {
left: Math.round(rect.left - scrollLeft),
Expand All @@ -114,25 +107,17 @@ const script = `
return false;
}

// if this is an <input />
if (node.tagName === 'INPUT') {
// return its value or placeholder
return node.value || node.placeholder;
return node.value || node.placeholder || false;
}

const everyChildNodeIsText = Array.from(node.childNodes).every(
(child) => child.nodeType === Node.TEXT_NODE,
);
if (!everyChildNodeIsText) {
const everyChildIsText = Array.from(node.childNodes).every((child) => child.nodeType === Node.TEXT_NODE);
if (!everyChildIsText) {
return false;
}

const content = node.textContent || node.innerText;
if (content && !/^\\s*$/.test(content)) {
return content.trim();
}

return false;
return content && !/^\\s*$/.test(content) ? content.trim() : false;
}

function extractTextWithPosition(initNode) {
Expand All @@ -141,48 +126,41 @@ const script = `
window[nodeIndexKey] = 0;

function dfs(node) {
if (!node) {
return;
}
if (!node) return;

const text = validTextNodeContent(node);
if (text) {
const answerRect = visibleRect(node);

// console.log('id is', id);
// check if the text is visible
if (!answerRect) {
console.log('Element is not visible', node);
console.warn('Warning: Element is not visible', node);
return;
}
const rect = answerRect.rect;

const { rect } = answerRect;
if (rect.width < TEXT_SIZE_THRESHOLD || rect.height < TEXT_SIZE_THRESHOLD) {
console.log('Element is too small', text);
console.warn('Warning: Element is too small.', text);
return;
}

const actualNode = answerRect.node;
const selector = setDataForNode(actualNode);

// console.log('will push', text, rect);
textInfoArray.push({
locator: selector,
content: text,
rect,
center: [Math.round(rect.left + rect.width / 2), Math.round(rect.top + rect.height / 2)],
center: [
Math.round(rect.left + rect.width / 2),
Math.round(rect.top + rect.height / 2),
],
});

// should stop searching if the text is found
return;
}

for (let i = 0; i < node.childNodes.length; i++) {
console.log('will dfs', node.childNodes[i]);
dfs(node.childNodes[i]);
}

return false;
}

dfs(initNode);
Expand All @@ -191,9 +169,17 @@ const script = `

window.extractTextWithPosition = extractTextWithPosition;
window.ifNodeIsValid = validTextNodeContent;

const container =
typeof window.get_all_text_container === 'undefined' ? document.body : window.get_all_text_container;
return extractTextWithPosition(container);
typeof window.get_all_text_container === 'undefined'
? document.body
: window.get_all_text_container;

try {
return extractTextWithPosition(container);
} catch (error) {
console.error('Error extracting text:', error);
}
})();
`;

Expand Down
Loading