Skip to content

Commit

Permalink
Merge pull request #15 from zapier/add-option-to-emit-cross-origin-ro…
Browse files Browse the repository at this point in the history
…uting

Add the ability to emit cross-origin links
  • Loading branch information
neilff authored May 16, 2018
2 parents c75029e + ae29804 commit e88cee6
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
14 changes: 12 additions & 2 deletions src/components/History.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@ const History = createReactClass({
state: PropTypes.object,
onChange: PropTypes.func,
isWaiting: PropTypes.bool,
history: PropTypes.object
history: PropTypes.object,
shouldEmitCrossOriginLinks: PropTypes.bool,
},

getDefaultProps() {
return {
shouldEmitCrossOriginLinks: false,
};
},

shouldComponentUpdate({url, state, isWaiting}) {
Expand All @@ -42,6 +49,7 @@ const History = createReactClass({
},

componentWillMount() {
const { shouldEmitCrossOriginLinks } = this.props;
this.history = this.props.history || createHistory();
if (this.props.url == null) {
const unlistenCurrent = this.history.listen(location => {
Expand All @@ -52,7 +60,9 @@ const History = createReactClass({
}
this.unlistenBeforeLocationChange =
this.history.listenBefore(this.onBeforeLocationChange);
this.unsubscribeFromLinks = onLink((event) => {
this.unsubscribeFromLinks = onLink({
shouldEmitCrossOriginLinks: shouldEmitCrossOriginLinks,
},(event) => {
if (event.target.href) {
// Anchor tags are frontend-only anyway, so they will get picked up
// by history. Don't let them call `onChange`.
Expand Down
10 changes: 9 additions & 1 deletion src/components/RouterHistoryContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ import History from './History';
const RouterHistoryContainer = createReactClass({
propTypes: {
routes: PropTypes.object.isRequired,
shouldEmitCrossOriginLinks: PropTypes.bool,
},

getDefaultProps() {
return {
shouldEmitCrossOriginLinks: false,
};
},

onChangeAddress(url, state) {
Expand All @@ -25,7 +32,7 @@ const RouterHistoryContainer = createReactClass({
},

render() {
const { router } = this.props;
const { router, shouldEmitCrossOriginLinks } = this.props;

const url = router.current ? router.current.url : null;
const state = router.current ? router.current.state : undefined;
Expand All @@ -35,6 +42,7 @@ const RouterHistoryContainer = createReactClass({
<Router key="router" {...this.props} router={router} />,
<History
key="history"
shouldEmitCrossOriginLinks={shouldEmitCrossOriginLinks}
history={this.props.history}
url={url}
state={state}
Expand Down
6 changes: 4 additions & 2 deletions src/utils/onLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ let isListening = false;

const listeners = [];

const onLink = (handler) => {
const onLink = (config, handler) => {

listeners.push(handler);

Expand Down Expand Up @@ -80,7 +80,9 @@ const onLink = (handler) => {
if (element.target) { return false; }

// x-origin
if (!isSameOrigin(element.href)) { return false; }
if (config.shouldEmitCrossOriginLinks !== true && !isSameOrigin(element.href)) {
return false;
}

return href;
};
Expand Down
51 changes: 49 additions & 2 deletions test/utils/onLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ test('onLink subscribe/click/unsubscribe', t => {
<a id="hello" href="/hello">Hello</a>
`;
const onLinkSpy = sinon.spy();
const unsubscribe = onLink(onLinkSpy);
const unsubscribe = onLink({ shouldEmitCrossOriginLinks: false }, onLinkSpy);
var mouseEvent = new document.defaultView.MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
cancelable: true,
});
document.getElementById('hello').dispatchEvent(mouseEvent);
t.is(onLinkSpy.callCount, 1);
Expand All @@ -26,3 +26,50 @@ test('onLink subscribe/click/unsubscribe', t => {
document.getElementById('hello').dispatchEvent(mouseEvent);
t.is(onLinkSpy.callCount, 1);
});

test('onLink should emit cross-origin links when enabled', t => {
const node = document.createElement('div');
node.id = 'onLinkContaine-1';
document.body.appendChild(node);
node.innerHTML = `
<a id="onlink-1" href="http://www.google.com/hello">Hello</a>
`;

const onLinkSpy = sinon.spy();
const unsubscribe = onLink({ shouldEmitCrossOriginLinks: true }, onLinkSpy);

const mouseEvent = new document.defaultView.MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true,
});

document.getElementById('onlink-1').dispatchEvent(mouseEvent);
t.is(onLinkSpy.lastCall.args[0].target.href, 'http://www.google.com/hello');
unsubscribe();

document.getElementById('onlink-1').dispatchEvent(mouseEvent);
t.is(onLinkSpy.callCount, 1);
});

test('onLink should NOT emit cross-origin links when enabled', t => {
const node = document.createElement('div');
node.id = 'onLinkContainer-2';
document.body.appendChild(node);
node.innerHTML = `
<a id="onlink-2" href="http://www.google.com/hello">Hello</a>
`;

const onLinkSpy = sinon.spy();
const unsubscribe = onLink({ shouldEmitCrossOriginLinks: false }, onLinkSpy);

const mouseEvent = new document.defaultView.MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true,
});

document.getElementById('onlink-2').dispatchEvent(mouseEvent);
t.is(onLinkSpy.lastCall.args[0].href, undefined);
unsubscribe();
});

0 comments on commit e88cee6

Please sign in to comment.