Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.86 KB | None | 0 0
  1. const url = process.argv[2];
  2. if (!url) {
  3. console.log(`Missing a url to analyze.`);
  4. process.exit(1);
  5. }
  6. const puppeteer = require('puppeteer');
  7. puppeteer.launch().then(async browser => {
  8. const page = await browser.newPage();
  9. await page.goto(url);
  10. const client = await page.target().createCDPSession();
  11.  
  12. // go fullpage
  13. const metrics = await client.send('Page.getLayoutMetrics');
  14. const width = Math.ceil(metrics.contentSize.width);
  15. const height = Math.ceil(metrics.contentSize.height);
  16. await page.setViewport({
  17. width, height
  18. });
  19. const screenshot = await page.screenshot({encoding: 'base64'});
  20.  
  21.  
  22. await page.exposeFunction('sendTab', () => page.keyboard.press('Tab'));
  23. const rects = await page.evaluate(async () => {
  24.  
  25. const visited = new Set();
  26. const blacklist = new Set([document.body, document.documentElement]);
  27. /** @type {DOMRect[]} */
  28. const rects = [];
  29. while (true) {
  30. const element = deepActiveElement();
  31. if (!element || visited.has(element))
  32. break;
  33. visited.add(element);
  34. if (!blacklist.has(element))
  35. rects.push(element.getBoundingClientRect().toJSON());
  36. await sendTab();
  37. }
  38.  
  39. return rects;
  40.  
  41. function deepActiveElement() {
  42. let activeElement = document.activeElement;
  43. while (activeElement && activeElement.shadowRoot && activeElement.shadowRoot.activeElement)
  44. activeElement = activeElement.shadowRoot.activeElement;
  45. return activeElement;
  46. }
  47. });
  48.  
  49. let prev = rects[rects.length - 1];
  50. for (const rect of rects) {
  51. rect.bad = !isOk(prev, rect);
  52. prev = rect;
  53. }
  54.  
  55. function isOk(from, to) {
  56. // dont care if its the same
  57. // if (from.top === to.top && from.bottom === to.bottom && from.left === to.left && from.right === to.right)
  58. // return true;
  59. // if we collide just say its ok
  60. if (to.top < from.bottom && to.left < from.right && from.top < to.bottom && from.left < to.right)
  61. return true;
  62. // if we go down its ok
  63. if (from.bottom < to.bottom || from.top < to.top)
  64. return true;
  65. // if we go right its ok
  66. if (from.left < to.left || from.right < to.right)
  67. return true;
  68. return false;
  69. }
  70.  
  71. // draw it on a canvas
  72. await page.goto('about:blank');
  73. const canvas = await page.evaluateHandle(async (rects, screenshot) => {
  74. document.body.style.margin = '0';
  75. const canvas = document.createElement('canvas');
  76. const image = new Image();
  77. await new Promise(x => {
  78. image.src = 'data:image/png;base64,' + screenshot;
  79. image.onload = x;
  80. });
  81. canvas.width = image.width;
  82. canvas.height = image.height;
  83. document.body.appendChild(canvas);
  84. const ctx = canvas.getContext('2d');
  85. ctx.drawImage(image, 0, 0);
  86.  
  87.  
  88. ctx.lineWidth = 2;
  89. ctx.beginPath();
  90. let count = 0;
  91. for (const rect of rects) {
  92. const center = {x: rect.x + rect.width/2, y: rect.y + rect.height/2};
  93. if (count === 0)
  94. ctx.moveTo(center.x, center.y);
  95. else
  96. ctx.lineTo(center.x, center.y);
  97.  
  98. ctx.fillStyle = 'rgba(255,128,0,0.2)';
  99. ctx.strokeStyle = 'rgba(255,128,0,0.7)';
  100. if (rect.bad) {
  101. ctx.fillStyle = 'rgba(255,0,0,0.2)';
  102. ctx.strokeStyle = 'rgba(255,0,0,0.7)';
  103. }
  104. ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
  105. ctx.strokeRect(rect.x, rect.y, rect.width, rect.height);
  106. count++;
  107. ctx.fillStyle = 'rgba(255,255,255,0.5)';
  108. ctx.strokeStyle = 'rgba(0,0,0,0.5)';
  109. ctx.font = '40px sans-serif';
  110. ctx.strokeText(count, center.x - ctx.measureText(count).width/2, center.y + 10);
  111. ctx.fillText(count, center.x - ctx.measureText(count).width/2, center.y + 10);
  112. }
  113.  
  114. ctx.setLineDash([2, 2]);
  115. ctx.strokeStyle = 'rgba(255,0,0,0.5)';
  116. ctx.stroke();
  117.  
  118. return canvas;
  119. }, rects, screenshot);
  120.  
  121. await canvas.screenshot({path: 'output.png'});
  122.  
  123. await browser.close();
  124.  
  125.  
  126. }).catch(e => {
  127. console.error(e)
  128. process.exit(1);
  129. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement