mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: elHandle:screenshot captures full element (#1787)
feat: make ElementHandle.screenshot work with large elements This patch increases the viewport size if the element is bigger than viewport. Fixes #1779
This commit is contained in:
committed by
Andrey Lushnikov
parent
b07e705dc9
commit
56a475f86b
@@ -58,9 +58,7 @@ class ElementHandle extends JSHandle {
|
||||
*/
|
||||
async _visibleCenter() {
|
||||
await this._scrollIntoViewIfNeeded();
|
||||
const box = await this.boundingBox();
|
||||
if (!box)
|
||||
throw new Error('Node is not visible');
|
||||
const box = await this._assertBoundingBox();
|
||||
return {
|
||||
x: box.x + box.width / 2,
|
||||
y: box.y + box.height / 2
|
||||
@@ -137,24 +135,59 @@ class ElementHandle extends JSHandle {
|
||||
return {x, y, width, height};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Promise<?{x: number, y: number, width: number, height: number}>}
|
||||
*/
|
||||
async _assertBoundingBox() {
|
||||
const boundingBox = await this.boundingBox();
|
||||
if (boundingBox)
|
||||
return boundingBox;
|
||||
|
||||
throw new Error('Node is either not visible or not an HTMLElement');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {!Object=} options
|
||||
* @returns {!Promise<Object>}
|
||||
*/
|
||||
async screenshot(options = {}) {
|
||||
await this._scrollIntoViewIfNeeded();
|
||||
let needsViewportReset = false;
|
||||
|
||||
let boundingBox = await this._assertBoundingBox();
|
||||
|
||||
const viewport = this._page.viewport();
|
||||
|
||||
if (boundingBox.width > viewport.width || boundingBox.height > viewport.height) {
|
||||
const newViewport = {
|
||||
width: Math.max(viewport.width, Math.ceil(boundingBox.width)),
|
||||
height: Math.max(viewport.height, Math.ceil(boundingBox.height)),
|
||||
};
|
||||
await this._page.setViewport(Object.assign({}, viewport, newViewport));
|
||||
|
||||
needsViewportReset = true;
|
||||
}
|
||||
|
||||
await this.executionContext().evaluate(function(element) {
|
||||
element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});
|
||||
}, this);
|
||||
|
||||
boundingBox = await this._assertBoundingBox();
|
||||
|
||||
const { layoutViewport: { pageX, pageY } } = await this._client.send('Page.getLayoutMetrics');
|
||||
|
||||
const boundingBox = await this.boundingBox();
|
||||
if (!boundingBox)
|
||||
throw new Error('Node is not visible');
|
||||
const clip = Object.assign({}, boundingBox);
|
||||
clip.x += pageX;
|
||||
clip.y += pageY;
|
||||
return await this._page.screenshot(Object.assign({}, {
|
||||
|
||||
const imageData = await this._page.screenshot(Object.assign({}, {
|
||||
clip
|
||||
}, options));
|
||||
|
||||
if (needsViewportReset)
|
||||
await this._page.setViewport(viewport);
|
||||
|
||||
return imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user