|
import React, { PropTypes } from 'react' |
|
const BEFOREUNLOAD = "beforeunload"; // see: http://stackoverflow.com/questions/39094138/reactjs-event-listener-beforeunload-added-but-not-removed |
|
|
|
class NavigationPrompt extends React.Component { |
|
static contextTypes = { |
|
router: PropTypes.object.isRequired |
|
} |
|
|
|
static defaultProps = { |
|
when: true |
|
} |
|
|
|
block() { |
|
if (!this.teardownPrompt) |
|
this.teardownPrompt = this.context.router.blockTransitions(this.props.message) |
|
} |
|
|
|
unblock() { |
|
if (this.teardownPrompt) { |
|
this.teardownPrompt() |
|
delete this.teardownPrompt |
|
} |
|
} |
|
|
|
blockUnload(_onbeforeunload) { |
|
if(this._subscribed) { return } |
|
this._subscribed = _onbeforeunload ? _onbeforeunload : this.onbeforeunload; |
|
window.addEventListener(BEFOREUNLOAD, this._subscribed) |
|
} |
|
|
|
unblockUnload() { |
|
window.removeEventListener(BEFOREUNLOAD, this._subscribed) |
|
delete this._subscribed |
|
} |
|
|
|
componentWillMount() { |
|
if (this.props.when) |
|
this.block() |
|
if (this.props.beforeUnload) |
|
this.blockUnload(); |
|
} |
|
|
|
onbeforeunload(e) { |
|
var dialogText = "leave" |
|
e.returnValue = dialogText |
|
return dialogText |
|
} |
|
|
|
componentWillReceiveProps(nextProps) { |
|
if (nextProps.when === true && this.props.when === false) { |
|
this.block() |
|
} else if (nextProps.when === false && this.props.when === true) { |
|
this.unblock() |
|
} |
|
|
|
// props.beforeUnload = Boolean : True |
|
if (nextProps.beforeUnload === true && this.props.beforeUnload === false) { |
|
this.blockUnload() |
|
} else if (nextProps.beforeUnload === false && |
|
(this.props.beforeUnload === true || typeof this.props.beforeUnload === "function")) { |
|
this.unblockUnload() |
|
} |
|
|
|
// props.beforeUnload = function |
|
if (typeof nextProps.beforeUnload === "function") { |
|
this.blockUnload(nextProps.beforeUnload) |
|
} |
|
} |
|
|
|
componentWillUnmount() { |
|
this.unblock() |
|
this.unblockUnload() |
|
} |
|
|
|
render() { |
|
return null |
|
} |
|
} |
|
|
|
if (__DEV__) { |
|
NavigationPrompt.propTypes = { |
|
when: PropTypes.bool, |
|
message: PropTypes.oneOfType([ |
|
PropTypes.func, |
|
PropTypes.string |
|
]).isRequired, |
|
beforeUnload: PropTypes.oneOfType([ |
|
PropTypes.func, |
|
PropTypes.bool |
|
]) |
|
} |
|
} |
|
|
|
export default NavigationPrompt |