diff --git a/src/NewWindow.js b/src/NewWindow.js index 019980a..197513d 100644 --- a/src/NewWindow.js +++ b/src/NewWindow.js @@ -99,7 +99,8 @@ class NewWindow extends React.PureComponent { // Open a new window. this.window = window.open(url, name, toWindowFeatures(features)) - this.container = this.window.document.createElement('div') + let doc = this.window.document; + this.container = doc.createElement('div') // When a new window use content from a cross-origin there's no way we can attach event // to it. Therefore, we need to detect in a interval when the new window was destroyed // or was closed. @@ -111,27 +112,32 @@ class NewWindow extends React.PureComponent { // Check if the new window was succesfully opened. if (this.window) { - this.window.document.title = title + doc.title = title; // Check if the container already exists as the window may have been already open - this.container = this.window.document.getElementById( + this.container = doc.getElementById( 'new-window-container' ) if (this.container === null) { - this.container = this.window.document.createElement('div') + // Set the base href for links. + this.base = doc.createElement('base'); + this.base.setAttribute('href', window.location.href); + doc.head.appendChild(this.base); + + this.container = doc.createElement('div') this.container.setAttribute('id', 'new-window-container') - this.window.document.body.appendChild(this.container) + doc.body.appendChild(this.container) } else { // Remove any existing content - const staticContainer = this.window.document.getElementById( + const staticContainer = doc.getElementById( 'new-window-container-static' ) - this.window.document.body.removeChild(staticContainer) + doc.body.removeChild(staticContainer) } // If specified, copy styles from parent window's document. if (this.props.copyStyles) { - setTimeout(() => copyStyles(document, this.window.document), 0) + setTimeout(() => this.copyStyles(document, doc), 0) } if (typeof onOpen === 'function') { @@ -180,6 +186,12 @@ class NewWindow extends React.PureComponent { // Remove checker interval. clearInterval(this.windowCheckerInterval) + // Clear the observer. + if (this.observer) { + this.observer.disconnect(); + this.observer = null; + } + // Call any function bound to the `onUnload` prop. const { onUnload } = this.props @@ -187,6 +199,94 @@ class NewWindow extends React.PureComponent { onUnload(null) } } + + /** + * Copy styles from a source document to a target. + * @param {Object} source + * @param {Object} target + * @private + */ + + copyStyles(source, target) { + // Store style tags, avoid reflow in the loop + const headFrag = target.createDocumentFragment() + + Array.from(source.styleSheets).forEach(styleSheet => { + // For