Explorar el Código

simplify screenshot workflow for webkit

Mike L hace 3 años
padre
commit
4e95e10b35
Se han modificado 2 ficheros con 32 adiciones y 74 borrados
  1. 13 34
      dist/webshot.js
  2. 19 40
      src/webshot.ts

+ 13 - 34
dist/webshot.js

@@ -84,7 +84,7 @@ class Webshot extends CallableInstance {
                             .then(() => page.reload({ timeout: getTimeout() })),
                     ]))
                         .then(() => page.addStyleTag({
-                        content: 'header,#layers{display:none!important}article{background-color:transparent!important}' +
+                        content: 'header,#layers,section>div>div>div~div{display:none!important}article{background-color:transparent!important}' +
                             '[data-testid="caret"],[role="group"],[data-testid="tweet"] [class*=" "]+:last-child>*+[class*=" "]~div{display:none}',
                     }))
                         .then(() => page.addStyleTag({
@@ -128,45 +128,24 @@ class Webshot extends CallableInstance {
                         .then(handle => {
                         if (handle === null)
                             throw new puppeteer.errors.TimeoutError();
-                        return (0, utils_1.chainPromises)(morePostProcessings.map(func => () => func(page, handle)));
+                        return (0, utils_1.chainPromises)(morePostProcessings.map(func => () => func(page, handle)))
+                            .then(() => (0, util_1.promisify)(setTimeout)(getTimeout()))
+                            .then(() => page.evaluate(() => document.activeElement.blur()))
+                            .then(() => handle.$eval('article', article => article.clientHeight).then(height => handle.evaluate((div, minHeight) => {
+                            div.parentElement.setAttribute('style', `min-height: ${minHeight}`);
+                            div.setAttribute('style', 'margin: 0 -1px; padding: 0 1px');
+                        }, height)))
+                            .then(() => handle.screenshot());
                     })
-                        .then(() => (0, util_1.promisify)(setTimeout)(getTimeout()))
-                        .then(() => page.evaluate(() => document.activeElement.blur()))
-                        .then(() => page.screenshot())
                         .then(screenshot => {
                         new pngjs_1.PNG({
                             filterType: 4,
                             deflateLevel: 0,
                         }).on('parsed', function () {
-                            const idx = (x, y) => (this.width * y + x) << 2;
-                            let boundary = null;
-                            const x = zoomFactor * 2;
-                            for (let y = x; y < this.height; y += zoomFactor) {
-                                if (this.data[idx(x, y)] !== this.data[idx(x, y - zoomFactor)] &&
-                                    this.data[idx(x, y)] === this.data[idx(x + zoomFactor * 10, y)]) {
-                                    boundary = y;
-                                    break;
-                                }
-                            }
-                            if (boundary !== null) {
-                                logger.info(`found boundary at ${boundary}, cropping image`);
-                                this.data = this.data.slice(0, idx(this.width, boundary));
-                                this.height = boundary;
-                                sharpToFile(jpeg(this.pack())).then(path => {
-                                    logger.info(`finished webshot for ${url}`);
-                                    resolve({ path, boundary });
-                                });
-                            }
-                            else if (height >= 8 * 1920) {
-                                logger.warn('too large, consider as a bug, returning');
-                                sharpToFile(jpeg(this.pack())).then(path => {
-                                    resolve({ path, boundary: 0 });
-                                });
-                            }
-                            else {
-                                logger.info('unable to find boundary, try shooting a larger image');
-                                resolve({ path: '', boundary });
-                            }
+                            sharpToFile(jpeg(this.pack())).then(path => {
+                                logger.info(`finished webshot for ${url}`);
+                                resolve({ path, boundary: this.height });
+                            });
                         }).parse(screenshot);
                     })
                         .catch(err => {

+ 19 - 40
src/webshot.ts

@@ -109,7 +109,7 @@ class Webshot extends CallableInstance<[Tweet[], (...args) => void, number], Pro
             ]))
             // hide header, "more options" button, like and retweet count
             .then(() => page.addStyleTag({
-              content: 'header,#layers{display:none!important}article{background-color:transparent!important}' +
+              content: 'header,#layers,section>div>div>div~div{display:none!important}article{background-color:transparent!important}' +
                 '[data-testid="caret"],[role="group"],[data-testid="tweet"] [class*=" "]+:last-child>*+[class*=" "]~div{display:none}',
             }))
             .then(() => page.addStyleTag({
@@ -131,7 +131,7 @@ class Webshot extends CallableInstance<[Tweet[], (...args) => void, number], Pro
             .then(() => page.waitForSelector(
               'xpath=//section/*/*/div[.//article[not(.//time[not(ancestor::div[@aria-labelledby])])]]',
               {state: 'attached', timeout: getTimeout()}
-            ))
+            ) as Promise<puppeteer.ElementHandle<HTMLDivElement>>)
             // toggle visibility of sensitive tweets
             .then(handle => handle.$$('xpath=..//a[contains(@href,"content_you_see")]/../../..//*[@role="button"]')
               .then(sensitiveToggles => {
@@ -159,50 +159,29 @@ class Webshot extends CallableInstance<[Tweet[], (...args) => void, number], Pro
             })
             .then(handle => {
               if (handle === null) throw new puppeteer.errors.TimeoutError();
-              return chainPromises(morePostProcessings.map(func => () => func(page, handle)));
+              return chainPromises(morePostProcessings.map(func => () => func(page, handle)))
+                .then(() => promisify(setTimeout)(getTimeout()))
+                // hide highlight of retweet header
+                .then(() => page.evaluate(() => (document.activeElement as unknown as HTMLOrSVGElement).blur()))
+                // determine screenshot height
+                .then(() =>
+                  handle.$eval('article', article => article.clientHeight).then(height =>
+                    handle.evaluate((div, minHeight) => {
+                      div.parentElement.setAttribute('style', `min-height: ${minHeight}`);
+                      div.setAttribute('style', 'margin: 0 -1px; padding: 0 1px');
+                    }, height))
+                )
+                .then(() => handle.screenshot());
             })
-            .then(() => promisify(setTimeout)(getTimeout()))
-            // hide highlight of retweet header
-            .then(() => page.evaluate(() => (document.activeElement as unknown as HTMLOrSVGElement).blur()))
-            .then(() => page.screenshot())
             .then(screenshot => {
               new PNG({
                 filterType: 4,
                 deflateLevel: 0,
               }).on('parsed', function () {
-                // remove comment area
-                // tslint:disable-next-line: no-shadowed-variable
-                // eslint-disable-next-line @typescript-eslint/no-shadow
-                const idx = (x: number, y: number) => (this.width * y + x) << 2;
-                let boundary: number = null;
-                const x = zoomFactor * 2;
-                for (let y = x; y < this.height; y += zoomFactor) {
-                  if (
-                    this.data[idx(x, y)] !== this.data[idx(x, y - zoomFactor)] &&
-                    this.data[idx(x, y)] === this.data[idx(x + zoomFactor * 10, y)]
-                  ) {
-                    boundary = y;
-                    break;
-                  }
-                }
-                if (boundary !== null) {
-                  logger.info(`found boundary at ${boundary}, cropping image`);
-                  this.data = this.data.slice(0, idx(this.width, boundary));
-                  this.height = boundary;
-
-                  sharpToFile(jpeg(this.pack())).then(path => {
-                    logger.info(`finished webshot for ${url}`);
-                    resolve({path, boundary});
-                  });
-                } else if (height >= 8 * 1920) {
-                  logger.warn('too large, consider as a bug, returning');
-                  sharpToFile(jpeg(this.pack())).then(path => {
-                    resolve({path, boundary: 0});
-                  });
-                } else {
-                  logger.info('unable to find boundary, try shooting a larger image');
-                  resolve({path: '', boundary});
-                }
+                sharpToFile(jpeg(this.pack())).then(path => {
+                  logger.info(`finished webshot for ${url}`);
+                  resolve({path, boundary: this.height});
+                });
               }).parse(screenshot);
             })
             .catch(err => {