Skip to content

Commit

Permalink
fix: correctly screen elements inside iframes
Browse files Browse the repository at this point in the history
  • Loading branch information
DudaGod committed Mar 7, 2024
1 parent 03d40dd commit 16bc710
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 7 deletions.
14 changes: 8 additions & 6 deletions src/browser/client-scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,11 @@ function prepareScreenshotUnsafe(areas, opts) {
}
}

var viewportWidth = document.documentElement.clientWidth,
viewportHeight = document.documentElement.clientHeight,
documentWidth = document.documentElement.scrollWidth,
documentHeight = document.documentElement.scrollHeight,
var mainDocumentElem = util.getMainDocumentElem(),
viewportWidth = mainDocumentElem.clientWidth,
viewportHeight = mainDocumentElem.clientHeight,
documentWidth = mainDocumentElem.scrollWidth,
documentHeight = mainDocumentElem.scrollHeight,
viewPort = new Rect({
left: util.getScrollLeft(scrollElem),
top: util.getScrollTop(scrollElem),
Expand Down Expand Up @@ -381,8 +382,9 @@ function isEditable(element) {
}

function scrollToCaptureAreaInSafari(viewportCurr, captureArea, scrollElem) {
var documentHeight = Math.round(document.documentElement.scrollHeight);
var viewportHeight = Math.round(document.documentElement.clientHeight);
var mainDocumentElem = util.getMainDocumentElem();
var documentHeight = Math.round(mainDocumentElem.scrollHeight);
var viewportHeight = Math.round(mainDocumentElem.clientHeight);
var maxScrollByY = documentHeight - viewportHeight;

scrollElem.scrollTo(viewportCurr.left, Math.min(captureArea.top, maxScrollByY));
Expand Down
75 changes: 74 additions & 1 deletion src/browser/client-scripts/rect.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ Rect.prototype = {

exports.Rect = Rect;
exports.getAbsoluteClientRect = function getAbsoluteClientRect(element, opts) {
var coords = element.getBoundingClientRect();
var coords = getNestedBoundingClientRect(element, window);
var widthRatio = coords.width % opts.viewportWidth;
var heightRatio = coords.height % opts.documentHeight;

Expand All @@ -164,3 +164,76 @@ exports.getAbsoluteClientRect = function getAbsoluteClientRect(element, opts) {

return clientRect.translate(util.getScrollLeft(opts.scrollElem), util.getScrollTop(opts.scrollElem));
};

function getNestedBoundingClientRect(node, boundaryWindow) {
var ownerIframe = util.getOwnerIframe(node);
if (ownerIframe === null || util.getOwnerWindow(ownerIframe) === boundaryWindow) {
return node.getBoundingClientRect();
}

var rects = [node.getBoundingClientRect()];
var currentIframe = ownerIframe;

while (currentIframe) {
var rect = getBoundingClientRectWithBorderOffset(currentIframe);
rects.push(rect);

currentIframe = util.getOwnerIframe(currentIframe);
if (currentIframe && util.getOwnerWindow(currentIframe) === boundaryWindow) {
rect = getBoundingClientRectWithBorderOffset(currentIframe);
rects.push(rect);
break;
}
}

return mergeRectOffsets(rects);
}

function getBoundingClientRectWithBorderOffset(node) {
var dimensions = getElementDimensions(node);

return mergeRectOffsets([
node.getBoundingClientRect(),
{
top: dimensions.borderTop,
left: dimensions.borderLeft,
bottom: dimensions.borderBottom,
right: dimensions.borderRight,
x: dimensions.borderLeft,
y: dimensions.borderTop
}
]);
}

function getElementDimensions(element) {
var calculatedStyle = util.getOwnerWindow(element).getComputedStyle(element);

return {
borderLeft: parseFloat(calculatedStyle.borderLeftWidth),
borderRight: parseFloat(calculatedStyle.borderRightWidth),
borderTop: parseFloat(calculatedStyle.borderTopWidth),
borderBottom: parseFloat(calculatedStyle.borderBottomWidth)
};
}

function mergeRectOffsets(rects) {
return rects.reduce(function (previousRect, rect) {
if (previousRect === null) {
return rect;
}

var nextTop = previousRect.top + rect.top;
var nextLeft = previousRect.left + rect.left;

return {
top: nextTop,
left: nextLeft,
width: previousRect.width,
height: previousRect.height,
bottom: nextTop + previousRect.height,
right: nextLeft + previousRect.width,
x: nextLeft,
y: nextTop
};
});
}
35 changes: 35 additions & 0 deletions src/browser/client-scripts/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,38 @@ exports.forEachRoot = function (cb) {

traverseRoots(document.documentElement);
};

exports.getOwnerWindow = function (node) {
if (!node.ownerDocument) {
return null;
}

return node.ownerDocument.defaultView;
};

exports.getOwnerIframe = function (node) {
var nodeWindow = exports.getOwnerWindow(node);
if (nodeWindow) {
return nodeWindow.frameElement;
}

return null;
};

exports.getMainDocumentElem = function (currDocumentElem) {
if (!currDocumentElem) {
currDocumentElem = document.documentElement;
}

var currIframe = exports.getOwnerIframe(currDocumentElem);
if (!currIframe) {
return currDocumentElem;
}

var currWindow = exports.getOwnerWindow(currIframe);
if (!currWindow) {
return currDocumentElem;
}

return exports.getMainDocumentElem(currWindow.document.documentElement);
};

0 comments on commit 16bc710

Please sign in to comment.