Skip to content

Instantly share code, notes, and snippets.

@ccapndave
Created August 15, 2017 11:13
Show Gist options
  • Save ccapndave/1ed9f6ec5090c1bfb7aa9fd7ce041e6e to your computer and use it in GitHub Desktop.
Save ccapndave/1ed9f6ec5090c1bfb7aa9fd7ce041e6e to your computer and use it in GitHub Desktop.
function clickjackElement(doc: Document, element: HTMLElement, pollingInterval: number = 500) {
const clickjacker = document.createElement("div");
clickjacker.style.position = "absolute";
const scrollParent = getScrollParent(element, false);
const positionElement = () => {
const elementRect = element.getBoundingClientRect();
const shadowRootRect = (<any>doc).host.getBoundingClientRect();
Object.assign(clickjacker.style, {
left: `${elementRect.left - shadowRootRect.left + scrollParent.scrollLeft}px`,
top: `${elementRect.top - shadowRootRect.top}px`,
width: `${elementRect.width}px`,
height: `${elementRect.height}px`
});
};
const $positionElement =
Rx.Observable.merge(
Rx.Observable.just(true),
Rx.Observable.fromEvent(window, "resize"),
Rx.Observable.fromEvent(scrollParent, "scroll"),
Rx.Observable.interval(pollingInterval)
);
(<any>doc).appendChild(clickjacker);
return {
clickjacker,
disposable: $positionElement.subscribe(positionElement)
};
}
function getScrollParent(element, includeHidden) {
let style = window.getComputedStyle(element);
const excludeStaticParent = style.position === "absolute";
const overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
if (style.position === "fixed") return document.body;
for (let parent = element; (parent = parent.parentElement);) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) {
return parent;
}
}
return document.body;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment