Skip to content

Commit

Permalink
Handle target="_top" and target="_parent"
Browse files Browse the repository at this point in the history
  • Loading branch information
kfay committed Jun 13, 2017
1 parent 94f6faf commit bc0b3a6
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
17 changes: 14 additions & 3 deletions src/libs/clickHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Copyright 2015, Yahoo Inc.
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
/* globals document */
/* globals document, window */

function isLeftClickEvent (e) {
return e.button === 0;
Expand All @@ -12,8 +12,12 @@ function isModifiedEvent (e) {
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
}

function getLinkTarget (target, props) {
return props.target || (target && target.target) || '_self';
}

function isNewWindow (target, props) {
return props.target === '_blank' || (target && target.target && '_blank' === target.target);
return getLinkTarget(target, props) === '_blank';
}

function isDefaultRedirectLink (target) {
Expand Down Expand Up @@ -98,7 +102,14 @@ module.exports = function clickHandler (e) {
// if the button has no form linked, then do nothing
target.form && target.form.submit();
} else {
document.location.assign(href);
var linkTarget = getLinkTarget(target, props);
if (linkTarget === '_top') {
window.top.location.href = href;
} else if (linkTarget === '_parent') {
window.parent.location.href = href;
} else {
document.location.assign(href);
}
}
}
});
Expand Down
76 changes: 70 additions & 6 deletions tests/unit/libs/clickHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
'use strict';

var expect = require('expect.js');
var JSDOM = require('jsdom').JSDOM;
var clickHandler;
var React;
var mockData = {};
Expand All @@ -15,10 +14,26 @@ var mockComponent;
var I13nNode = require('../../../src/libs/I13nNode');
describe('clickHandler', function () {
beforeEach(function () {
var jsdom = new JSDOM('<html><body></body></html>');
global.window = jsdom.window;
global.document = jsdom.window.document;
global.navigator = jsdom.window.navigator;
global.window = {
parent: {
location: {
href: 'about:blank'
}
},
top: {
location: {
href: 'about:blank'
}
}
};
global.document = {
location: {
assign: function (href) {
this.href = href;
},
href: 'about:blank'
}
};

React = require('react');
clickHandler = require('../../../src/libs/clickHandler');
Expand All @@ -40,7 +55,6 @@ describe('clickHandler', function () {
afterEach(function () {
delete global.window;
delete global.document;
delete global.navigator;
});

it('should run click handler correctly', function (done) {
Expand Down Expand Up @@ -268,4 +282,54 @@ describe('clickHandler', function () {
};
clickHandler.apply(mockComponent, [mockClickEvent]);
});

it('should execute event with prevent default and redirection if props.target=_top', function (done) {
var i13nNode = new I13nNode(null, {});
var executedActions = [];
mockClickEvent.target = {
tagName: 'A'
};
mockComponent.props.target = '_top';
mockClickEvent.preventDefault = function () {
executedActions.push('preventDefault');
};
document.location.assign = function () {
executedActions.push('assign');
};
mockComponent.executeI13nEvent = function (eventName, payload, callback) {
callback();
expect(executedActions).to.eql(['preventDefault']);
expect(global.window.top.location.href).to.eql('foo');
done();
};
mockComponent.getI13nNode = function () {
return i13nNode;
};
clickHandler.apply(mockComponent, [mockClickEvent]);
});

it('should execute event with prevent default and redirection if props.target=_parent', function (done) {
var i13nNode = new I13nNode(null, {});
var executedActions = [];
mockClickEvent.target = {
tagName: 'A'
};
mockComponent.props.target = '_parent';
mockClickEvent.preventDefault = function () {
executedActions.push('preventDefault');
};
document.location.assign = function () {
executedActions.push('assign');
};
mockComponent.executeI13nEvent = function (eventName, payload, callback) {
callback();
expect(executedActions).to.eql(['preventDefault']);
expect(global.window.parent.location.href).to.eql('foo');
done();
};
mockComponent.getI13nNode = function () {
return i13nNode;
};
clickHandler.apply(mockComponent, [mockClickEvent]);
});
});

0 comments on commit bc0b3a6

Please sign in to comment.