rc-new-window
Advanced tools
Comparing version 0.1.0 to 0.1.1
import React from 'react'; | ||
interface Feature { | ||
width?: number; | ||
height?: number; | ||
left?: number; | ||
top?: number; | ||
} | ||
interface Props { | ||
@@ -13,7 +7,9 @@ children?: React.ReactNode; | ||
title?: string; | ||
features?: Feature; | ||
onUnload?: () => void; | ||
width?: number; | ||
height?: number; | ||
left?: number; | ||
top?: number; | ||
onOpen?: (w: Window) => void; | ||
onClose?: () => void; | ||
onBlock?: () => void; | ||
onOpen?: (w: Window) => void; | ||
center?: 'parent' | 'screen'; | ||
copyStyles?: boolean; | ||
@@ -34,3 +30,2 @@ } | ||
window: Window; | ||
windowCheckerInterval: any; | ||
released: boolean; | ||
@@ -53,2 +48,3 @@ container: HTMLDivElement; | ||
openChild(): void; | ||
onMainWindowUnload: () => void; | ||
/** | ||
@@ -61,3 +57,3 @@ * Close the opened window (if any) when NewWindow will unmount. | ||
*/ | ||
release(): void; | ||
release: (event?: Event) => void; | ||
} | ||
@@ -64,0 +60,0 @@ /** |
179
es/index.js
@@ -21,2 +21,11 @@ "use strict"; | ||
var react_dom_1 = __importDefault(require("react-dom")); | ||
var debounce_1 = __importDefault(require("lodash/debounce")); | ||
var onNewWindowResize = debounce_1.default(function () { | ||
// add/remove element on main document, force it to dispatch resize observer event on the popup window | ||
var div = document.createElement('div'); | ||
document.body.append(div); | ||
div.remove(); // TODO update resize event | ||
}, 200); | ||
/** | ||
@@ -27,3 +36,2 @@ * The NewWindow class object. | ||
var NewWindow = /*#__PURE__*/function (_react_1$default$Pure) { | ||
@@ -49,2 +57,34 @@ _inherits(NewWindow, _react_1$default$Pure); | ||
}; | ||
_this.onMainWindowUnload = function () { | ||
if (_this.window) { | ||
_this.window.close(); | ||
} | ||
}; | ||
/** | ||
* Release the new window and anything that was bound to it. | ||
*/ | ||
_this.release = function (event) { | ||
// This method can be called once. | ||
if (_this.released) { | ||
return; | ||
} | ||
_this.released = true; | ||
window.removeEventListener('beforeunload', _this.onMainWindowUnload); | ||
_this.window.addEventListener('beforeunload', _this.release); | ||
if (event) { | ||
// Call any function bound to the `onUnload` prop. | ||
var onClose = _this.props.onClose; | ||
if (typeof onClose === 'function') { | ||
onClose(); | ||
} | ||
} | ||
}; | ||
return _this; | ||
@@ -84,34 +124,27 @@ } | ||
name = _this$props.name, | ||
features = _this$props.features, | ||
left = _this$props.left, | ||
top = _this$props.top, | ||
width = _this$props.width, | ||
height = _this$props.height, | ||
onBlock = _this$props.onBlock, | ||
onOpen = _this$props.onOpen, | ||
center = _this$props.center; // Prepare position of the new window to be centered against the 'parent' window or 'screen'. | ||
onOpen = _this$props.onOpen; | ||
var features = { | ||
left: left, | ||
top: top, | ||
width: width, | ||
height: height | ||
}; | ||
if (typeof center === 'string' && (features.width === undefined || features.height === undefined)) { | ||
console.warn('width and height window features must be present when a center prop is provided'); | ||
} else if (center === 'parent') { | ||
features.left = window.top.outerWidth / 2 + window.top.screenX - features.width / 2; | ||
features.top = window.top.outerHeight / 2 + window.top.screenY - features.height / 2; | ||
} else if (center === 'screen') { | ||
var screenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screen.left; | ||
var screenTop = window.screenTop !== undefined ? window.screenTop : window.screen.top; | ||
var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : window.screen.width; | ||
var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : window.screen.height; | ||
features.left = width / 2 - features.width / 2 + screenLeft; | ||
features.top = height / 2 - features.height / 2 + screenTop; | ||
if (left == null || top == null) { | ||
features.left = window.top.outerWidth / 2 + window.top.screenX - width / 2; | ||
features.top = window.top.outerHeight / 2 + window.top.screenY - height / 2; | ||
} // Open a new window. | ||
this.window = window.open(url, name, toWindowFeatures(features)); // 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. | ||
this.window = window.open(url, name, toWindowFeatures(features)); // Check if the new window was successfully opened. | ||
this.windowCheckerInterval = setInterval(function () { | ||
if (!_this2.window || _this2.window.closed) { | ||
_this2.release(); | ||
} | ||
}, 50); // Check if the new window was succesfully opened. | ||
if (this.window) { | ||
this.window.document.title = title; | ||
window.addEventListener('beforeunload', this.onMainWindowUnload); | ||
this.window.addEventListener('resize', onNewWindowResize); | ||
this.window.document.title = title || document.title; | ||
this.window.document.body.appendChild(this.container); // If specified, copy styles from parent window's document. | ||
@@ -130,5 +163,3 @@ | ||
this.window.addEventListener('beforeunload', function () { | ||
return _this2.release(); | ||
}); | ||
this.window.addEventListener('beforeunload', this.release); | ||
} else { | ||
@@ -151,27 +182,6 @@ // Handle error on opening of new window. | ||
if (this.window) { | ||
this.release(); | ||
this.window.close(); | ||
} | ||
} | ||
/** | ||
* Release the new window and anything that was bound to it. | ||
*/ | ||
}, { | ||
key: "release", | ||
value: function release() { | ||
// This method can be called once. | ||
if (this.released) { | ||
return; | ||
} | ||
this.released = true; // Remove checker interval. | ||
clearInterval(this.windowCheckerInterval); // Call any function bound to the `onUnload` prop. | ||
var onUnload = this.props.onUnload; | ||
if (typeof onUnload === 'function') { | ||
onUnload(); | ||
} | ||
} | ||
}]); | ||
@@ -189,8 +199,4 @@ | ||
name: '', | ||
title: '', | ||
features: { | ||
width: 600, | ||
height: 600 | ||
}, | ||
center: 'parent', | ||
width: 640, | ||
height: 480, | ||
copyStyles: true | ||
@@ -215,36 +221,37 @@ }; | ||
try { | ||
rules = styleSheet.cssRules; | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
if (styleSheet.href) { | ||
// for <link> elements loading CSS from a URL | ||
var newLinkEl = source.createElement('link'); | ||
newLinkEl.rel = 'stylesheet'; | ||
newLinkEl.href = styleSheet.href; | ||
target.head.appendChild(newLinkEl); | ||
} else { | ||
try { | ||
rules = styleSheet.cssRules; | ||
} catch (err) {// can't access crossdomain rules | ||
} | ||
if (rules) { | ||
var newStyleEl = source.createElement('style'); // Write the text of each rule into the body of the style element | ||
if (rules) { | ||
var newStyleEl = source.createElement('style'); // Write the text of each rule into the body of the style element | ||
Array.from(styleSheet.cssRules).forEach(function (cssRule) { | ||
var cssText = cssRule.cssText, | ||
type = cssRule.type; | ||
var returnText = cssText; // Check if the cssRule type is CSSImportRule (3) or CSSFontFaceRule (5) to handle local imports on a about:blank page | ||
// '/custom.css' turns to 'http://my-site.com/custom.css' | ||
Array.from(styleSheet.cssRules).forEach(function (cssRule) { | ||
var cssText = cssRule.cssText, | ||
type = cssRule.type; | ||
var returnText = cssText; // Check if the cssRule type is CSSImportRule (3) or CSSFontFaceRule (5) to handle local imports on a about:blank page | ||
// '/custom.css' turns to 'http://my-site.com/custom.css' | ||
if ([3, 5].includes(type)) { | ||
returnText = cssText.split('url(').map(function (line) { | ||
if (line[1] === '/') { | ||
return "".concat(line.slice(0, 1)).concat(window.location.origin).concat(line.slice(1)); | ||
} | ||
if ([3, 5].includes(type)) { | ||
returnText = cssText.split('url(').map(function (line) { | ||
if (line[1] === '/') { | ||
return "".concat(line.slice(0, 1)).concat(window.location.origin).concat(line.slice(1)); | ||
} | ||
return line; | ||
}).join('url('); | ||
} | ||
return line; | ||
}).join('url('); | ||
} | ||
newStyleEl.appendChild(source.createTextNode(returnText)); | ||
}); | ||
target.head.appendChild(newStyleEl); | ||
} else if (styleSheet.href) { | ||
// for <link> elements loading CSS from a URL | ||
var newLinkEl = source.createElement('link'); | ||
newLinkEl.rel = 'stylesheet'; | ||
newLinkEl.href = styleSheet.href; | ||
target.head.appendChild(newLinkEl); | ||
newStyleEl.appendChild(source.createTextNode(returnText)); | ||
}); | ||
target.head.appendChild(newStyleEl); | ||
} | ||
} | ||
@@ -251,0 +258,0 @@ }); |
import React from 'react'; | ||
interface Feature { | ||
width?: number; | ||
height?: number; | ||
left?: number; | ||
top?: number; | ||
} | ||
interface Props { | ||
@@ -13,7 +7,9 @@ children?: React.ReactNode; | ||
title?: string; | ||
features?: Feature; | ||
onUnload?: () => void; | ||
width?: number; | ||
height?: number; | ||
left?: number; | ||
top?: number; | ||
onOpen?: (w: Window) => void; | ||
onClose?: () => void; | ||
onBlock?: () => void; | ||
onOpen?: (w: Window) => void; | ||
center?: 'parent' | 'screen'; | ||
copyStyles?: boolean; | ||
@@ -34,3 +30,2 @@ } | ||
window: Window; | ||
windowCheckerInterval: any; | ||
released: boolean; | ||
@@ -53,2 +48,3 @@ container: HTMLDivElement; | ||
openChild(): void; | ||
onMainWindowUnload: () => void; | ||
/** | ||
@@ -61,3 +57,3 @@ * Close the opened window (if any) when NewWindow will unmount. | ||
*/ | ||
release(): void; | ||
release: (event?: Event) => void; | ||
} | ||
@@ -64,0 +60,0 @@ /** |
179
lib/index.js
@@ -26,2 +26,11 @@ "use strict"; | ||
var react_dom_1 = __importDefault(require("react-dom")); | ||
var debounce_1 = __importDefault(require("lodash/debounce")); | ||
var onNewWindowResize = debounce_1.default(function () { | ||
// add/remove element on main document, force it to dispatch resize observer event on the popup window | ||
var div = document.createElement('div'); | ||
document.body.append(div); | ||
div.remove(); // TODO update resize event | ||
}, 200); | ||
/** | ||
@@ -32,3 +41,2 @@ * The NewWindow class object. | ||
var NewWindow = /*#__PURE__*/function (_react_1$default$Pure) { | ||
@@ -53,2 +61,34 @@ (0, _inherits2.default)(NewWindow, _react_1$default$Pure); | ||
}; | ||
_this.onMainWindowUnload = function () { | ||
if (_this.window) { | ||
_this.window.close(); | ||
} | ||
}; | ||
/** | ||
* Release the new window and anything that was bound to it. | ||
*/ | ||
_this.release = function (event) { | ||
// This method can be called once. | ||
if (_this.released) { | ||
return; | ||
} | ||
_this.released = true; | ||
window.removeEventListener('beforeunload', _this.onMainWindowUnload); | ||
_this.window.addEventListener('beforeunload', _this.release); | ||
if (event) { | ||
// Call any function bound to the `onUnload` prop. | ||
var onClose = _this.props.onClose; | ||
if (typeof onClose === 'function') { | ||
onClose(); | ||
} | ||
} | ||
}; | ||
return _this; | ||
@@ -88,34 +128,27 @@ } | ||
name = _this$props.name, | ||
features = _this$props.features, | ||
left = _this$props.left, | ||
top = _this$props.top, | ||
width = _this$props.width, | ||
height = _this$props.height, | ||
onBlock = _this$props.onBlock, | ||
onOpen = _this$props.onOpen, | ||
center = _this$props.center; // Prepare position of the new window to be centered against the 'parent' window or 'screen'. | ||
onOpen = _this$props.onOpen; | ||
var features = { | ||
left: left, | ||
top: top, | ||
width: width, | ||
height: height | ||
}; | ||
if (typeof center === 'string' && (features.width === undefined || features.height === undefined)) { | ||
console.warn('width and height window features must be present when a center prop is provided'); | ||
} else if (center === 'parent') { | ||
features.left = window.top.outerWidth / 2 + window.top.screenX - features.width / 2; | ||
features.top = window.top.outerHeight / 2 + window.top.screenY - features.height / 2; | ||
} else if (center === 'screen') { | ||
var screenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screen.left; | ||
var screenTop = window.screenTop !== undefined ? window.screenTop : window.screen.top; | ||
var width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : window.screen.width; | ||
var height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : window.screen.height; | ||
features.left = width / 2 - features.width / 2 + screenLeft; | ||
features.top = height / 2 - features.height / 2 + screenTop; | ||
if (left == null || top == null) { | ||
features.left = window.top.outerWidth / 2 + window.top.screenX - width / 2; | ||
features.top = window.top.outerHeight / 2 + window.top.screenY - height / 2; | ||
} // Open a new window. | ||
this.window = window.open(url, name, toWindowFeatures(features)); // 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. | ||
this.window = window.open(url, name, toWindowFeatures(features)); // Check if the new window was successfully opened. | ||
this.windowCheckerInterval = setInterval(function () { | ||
if (!_this2.window || _this2.window.closed) { | ||
_this2.release(); | ||
} | ||
}, 50); // Check if the new window was succesfully opened. | ||
if (this.window) { | ||
this.window.document.title = title; | ||
window.addEventListener('beforeunload', this.onMainWindowUnload); | ||
this.window.addEventListener('resize', onNewWindowResize); | ||
this.window.document.title = title || document.title; | ||
this.window.document.body.appendChild(this.container); // If specified, copy styles from parent window's document. | ||
@@ -134,5 +167,3 @@ | ||
this.window.addEventListener('beforeunload', function () { | ||
return _this2.release(); | ||
}); | ||
this.window.addEventListener('beforeunload', this.release); | ||
} else { | ||
@@ -155,27 +186,6 @@ // Handle error on opening of new window. | ||
if (this.window) { | ||
this.release(); | ||
this.window.close(); | ||
} | ||
} | ||
/** | ||
* Release the new window and anything that was bound to it. | ||
*/ | ||
}, { | ||
key: "release", | ||
value: function release() { | ||
// This method can be called once. | ||
if (this.released) { | ||
return; | ||
} | ||
this.released = true; // Remove checker interval. | ||
clearInterval(this.windowCheckerInterval); // Call any function bound to the `onUnload` prop. | ||
var onUnload = this.props.onUnload; | ||
if (typeof onUnload === 'function') { | ||
onUnload(); | ||
} | ||
} | ||
}]); | ||
@@ -192,8 +202,4 @@ return NewWindow; | ||
name: '', | ||
title: '', | ||
features: { | ||
width: 600, | ||
height: 600 | ||
}, | ||
center: 'parent', | ||
width: 640, | ||
height: 480, | ||
copyStyles: true | ||
@@ -218,36 +224,37 @@ }; | ||
try { | ||
rules = styleSheet.cssRules; | ||
} catch (err) { | ||
console.error(err); | ||
} | ||
if (styleSheet.href) { | ||
// for <link> elements loading CSS from a URL | ||
var newLinkEl = source.createElement('link'); | ||
newLinkEl.rel = 'stylesheet'; | ||
newLinkEl.href = styleSheet.href; | ||
target.head.appendChild(newLinkEl); | ||
} else { | ||
try { | ||
rules = styleSheet.cssRules; | ||
} catch (err) {// can't access crossdomain rules | ||
} | ||
if (rules) { | ||
var newStyleEl = source.createElement('style'); // Write the text of each rule into the body of the style element | ||
if (rules) { | ||
var newStyleEl = source.createElement('style'); // Write the text of each rule into the body of the style element | ||
Array.from(styleSheet.cssRules).forEach(function (cssRule) { | ||
var cssText = cssRule.cssText, | ||
type = cssRule.type; | ||
var returnText = cssText; // Check if the cssRule type is CSSImportRule (3) or CSSFontFaceRule (5) to handle local imports on a about:blank page | ||
// '/custom.css' turns to 'http://my-site.com/custom.css' | ||
Array.from(styleSheet.cssRules).forEach(function (cssRule) { | ||
var cssText = cssRule.cssText, | ||
type = cssRule.type; | ||
var returnText = cssText; // Check if the cssRule type is CSSImportRule (3) or CSSFontFaceRule (5) to handle local imports on a about:blank page | ||
// '/custom.css' turns to 'http://my-site.com/custom.css' | ||
if ([3, 5].includes(type)) { | ||
returnText = cssText.split('url(').map(function (line) { | ||
if (line[1] === '/') { | ||
return "".concat(line.slice(0, 1)).concat(window.location.origin).concat(line.slice(1)); | ||
} | ||
if ([3, 5].includes(type)) { | ||
returnText = cssText.split('url(').map(function (line) { | ||
if (line[1] === '/') { | ||
return "".concat(line.slice(0, 1)).concat(window.location.origin).concat(line.slice(1)); | ||
} | ||
return line; | ||
}).join('url('); | ||
} | ||
return line; | ||
}).join('url('); | ||
} | ||
newStyleEl.appendChild(source.createTextNode(returnText)); | ||
}); | ||
target.head.appendChild(newStyleEl); | ||
} else if (styleSheet.href) { | ||
// for <link> elements loading CSS from a URL | ||
var newLinkEl = source.createElement('link'); | ||
newLinkEl.rel = 'stylesheet'; | ||
newLinkEl.href = styleSheet.href; | ||
target.head.appendChild(newLinkEl); | ||
newStyleEl.appendChild(source.createTextNode(returnText)); | ||
}); | ||
target.head.appendChild(newStyleEl); | ||
} | ||
} | ||
@@ -254,0 +261,0 @@ }); |
{ | ||
"name": "rc-new-window", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "popup new browser window with react", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
22502
6
0
135