Added itb_scroll
This commit is contained in:
@@ -13,9 +13,19 @@ class ScreenshotGenerator:
|
|||||||
def get_page_content(self) -> dict:
|
def get_page_content(self) -> dict:
|
||||||
script = """
|
script = """
|
||||||
function processElement(element) {
|
function processElement(element) {
|
||||||
if (!element.offsetParent && element !== document.body) return null;
|
// Check if element is actually visible in viewport
|
||||||
|
|
||||||
const rect = element.getBoundingClientRect();
|
const rect = element.getBoundingClientRect();
|
||||||
|
if (!element.offsetParent && element !== document.body) return null;
|
||||||
|
if (rect.width === 0 || rect.height === 0) return null;
|
||||||
|
|
||||||
|
// Check if element is within viewport bounds
|
||||||
|
const viewportWidth = window.innerWidth;
|
||||||
|
const viewportHeight = window.innerHeight;
|
||||||
|
if (rect.bottom < 0 || rect.top > viewportHeight ||
|
||||||
|
rect.right < 0 || rect.left > viewportWidth) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const styles = window.getComputedStyle(element);
|
const styles = window.getComputedStyle(element);
|
||||||
|
|
||||||
const text = Array.from(element.childNodes)
|
const text = Array.from(element.childNodes)
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
from selenium import webdriver
|
||||||
|
|
||||||
|
class ScrollController:
|
||||||
|
def __init__(self, debug_port: int):
|
||||||
|
options = webdriver.ChromeOptions()
|
||||||
|
options.add_experimental_option("debuggerAddress", f"127.0.0.1:{debug_port}")
|
||||||
|
self.driver = webdriver.Chrome(options=options)
|
||||||
|
|
||||||
|
def get_viewport_info(self) -> dict:
|
||||||
|
script = """
|
||||||
|
return {
|
||||||
|
scroll_x: window.pageXOffset,
|
||||||
|
scroll_y: window.pageYOffset,
|
||||||
|
max_scroll_x: Math.max(document.documentElement.scrollWidth - window.innerWidth, 0),
|
||||||
|
max_scroll_y: Math.max(document.documentElement.scrollHeight - window.innerHeight, 0)
|
||||||
|
};
|
||||||
|
"""
|
||||||
|
return self.driver.execute_script(script)
|
||||||
|
|
||||||
|
def smooth_scroll(self, target_x: int, target_y: int):
|
||||||
|
viewport = self.get_viewport_info()
|
||||||
|
start_x = viewport['scroll_x']
|
||||||
|
start_y = viewport['scroll_y']
|
||||||
|
|
||||||
|
# Clamp target values to valid ranges
|
||||||
|
target_x = max(0, min(target_x, viewport['max_scroll_x']))
|
||||||
|
target_y = max(0, min(target_y, viewport['max_scroll_y']))
|
||||||
|
|
||||||
|
# Calculate number of steps (random for natural feel)
|
||||||
|
steps = random.randint(5, 10)
|
||||||
|
|
||||||
|
for step in range(1, steps + 1):
|
||||||
|
progress = step / steps
|
||||||
|
current_x = start_x + (target_x - start_x) * progress
|
||||||
|
current_y = start_y + (target_y - start_y) * progress
|
||||||
|
|
||||||
|
self.driver.execute_script(
|
||||||
|
'window.scrollTo(arguments[0], arguments[1]);',
|
||||||
|
current_x, current_y
|
||||||
|
)
|
||||||
|
|
||||||
|
# Random small delay between steps
|
||||||
|
time.sleep(random.uniform(0.01, 0.05))
|
||||||
|
|
||||||
|
# Final position check
|
||||||
|
final = self.get_viewport_info()
|
||||||
|
return {
|
||||||
|
'x': final['scroll_x'],
|
||||||
|
'y': final['scroll_y']
|
||||||
|
}
|
||||||
|
|
||||||
|
def main(debug_port: int, target_x: int, target_y: int):
|
||||||
|
try:
|
||||||
|
controller = ScrollController(debug_port)
|
||||||
|
result = controller.smooth_scroll(target_x, target_y)
|
||||||
|
print(result)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) != 4:
|
||||||
|
print("Usage: itb_scroll <debug_port> <x> <y>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
main(int(sys.argv[1]), int(sys.argv[2]), int(sys.argv[3]))
|
||||||
|
|||||||
Reference in New Issue
Block a user