import {Bounds} from '../css/layout/bounds'; import { isBodyElement, isCanvasElement, isCustomElement, isElementNode, isHTMLElementNode, isIFrameElement, isImageElement, isScriptElement, isSelectElement, isSlotElement, isStyleElement, isSVGElementNode, isTextareaElement, isTextNode, isVideoElement } from './node-parser'; import {isIdentToken, nonFunctionArgSeparator} from '../css/syntax/parser'; import {TokenType} from '../css/syntax/tokenizer'; import {CounterState, createCounterText} from '../css/types/functions/counter'; import {LIST_STYLE_TYPE, listStyleType} from '../css/property-descriptors/list-style-type'; import {CSSParsedCounterDeclaration, CSSParsedPseudoDeclaration} from '../css/index'; import {getQuote} from '../css/property-descriptors/quotes'; import {Context} from '../core/context'; import {DebuggerType, isDebugging} from '../core/debugger'; export interface CloneOptions { ignoreElements?: (element: Element) => boolean; onclone?: (document: Document, element: HTMLElement) => void; allowTaint?: boolean; } export interface WindowOptions { scrollX: number; scrollY: number; windowWidth: number; windowHeight: number; } export type CloneConfigurations = CloneOptions & { inlineImages: boolean; copyStyles: boolean; }; const IGNORE_ATTRIBUTE = 'data-html2canvas-ignore'; export class DocumentCloner { private readonly scrolledElements: [Element, number, number][]; private readonly referenceElement: HTMLElement; clonedReferenceElement?: HTMLElement; private readonly documentElement: HTMLElement; private readonly counters: CounterState; private quoteDepth: number; constructor( private readonly context: Context, element: HTMLElement, private readonly options: CloneConfigurations ) { this.scrolledElements = []; this.referenceElement = element; this.counters = new CounterState(); this.quoteDepth = 0; if (!element.ownerDocument) { throw new Error('Cloned element does not have an owner document'); } this.documentElement = this.cloneNode(element.ownerDocument.documentElement, false) as HTMLElement; } toIFrame(ownerDocument: Document, windowSize: Bounds): Promise { const iframe: HTMLIFrameElement = createIFrameContainer(ownerDocument, windowSize); if (!iframe.contentWindow) { return Promise.reject(`Unable to find iframe window`); } const scrollX = (ownerDocument.defaultView as Window).pageXOffset; const scrollY = (ownerDocument.defaultView as Window).pageYOffset; const cloneWindow = iframe.contentWindow; const documentClone: Document = cloneWindow.document; /* Chrome doesn't detect relative background-images assigned in inline