#!/usr/bin/env node const fs = require('fs').promises; const process = require('process'); const puppeteer = require('puppeteer'); // Size of the rendering of the web page const size = { width: 1280, height: 720 }; async function main() { if (process.argv[2] === undefined) { console.error("This program expects an argument."); console.error("USAGE: locator "); process.exit(1); } // Path to the HTML file to analyse (given as relative path from current directory) // We need the full path so that puppeteer is able to access it const path = process.argv[2].startsWith('/') ? process.argv[2] : process.cwd() + '/' + process.argv[2]; // Check that the file exists try { await fs.access(path, fs.constants.F_OK); } catch (e) { console.error("No such file: " + path); process.exit(1); } // Initialize browser const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport(size); await page.goto("file://" + path); let currentSlide = 1; let hierarchy = []; while (true) { let root = await page.$("#\\3" + currentSlide); if (root === null) { break; } let currentInfo = {}; hierarchy.push(currentInfo); await analyseElement(root, currentInfo); currentSlide++; } console.log(JSON.stringify(hierarchy, undefined, 4)); await browser.close(); } async function analyseElement(element, hierarchy, tabs = '', stop = false) { let tagAttr = await element.getProperty("tagName"); let tagName = await tagAttr.jsonValue(); let classAttr = await element.getProperty("className"); let className = await classAttr.jsonValue(); let box = await element.boundingBox(); hierarchy.tag = tagName; hierarchy.class = className; hierarchy.x = box.x / size.width; hierarchy.width = box.width / size.width; hierarchy.y = box.y / size.height; hierarchy.height = box.height / size.height; hierarchy.children = []; console.log(tabs + tagName + ' "' + className + '" ' + JSON.stringify(box)); let children = await element.$$('> *'); for (let child of children) { let currentInfo = {}; hierarchy.children.push(currentInfo); await analyseElement(child, currentInfo, tabs + ' ', true); } } main();