Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #24111 from cctuan/1060191
Browse files Browse the repository at this point in the history
Bug 1060191 - Web compat issues with window.open
  • Loading branch information
cctuan committed Sep 26, 2014
2 parents 40dff26 + ee8a87e commit 6163c5e
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 43 deletions.
14 changes: 6 additions & 8 deletions apps/system/js/app_window_factory.js
Expand Up @@ -49,6 +49,7 @@
window.addEventListener('webapps-launch', this.preHandleEvent);
window.addEventListener('webapps-close', this.preHandleEvent);
window.addEventListener('open-app', this.preHandleEvent);
window.addEventListener('openwindow', this.preHandleEvent);
window.addEventListener('appopenwindow', this.preHandleEvent);
window.addEventListener('applicationready', (function appReady(e) {
window.removeEventListener('applicationready', appReady);
Expand All @@ -69,6 +70,7 @@
window.removeEventListener('webapps-launch', this.preHandleEvent);
window.removeEventListener('webapps-close', this.preHandleEvent);
window.removeEventListener('open-app', this.preHandleEvent);
window.removeEventListener('openwindow', this.preHandleEvent);
window.removeEventListener('appopenwindow', this.preHandleEvent);
},

Expand Down Expand Up @@ -98,20 +100,16 @@

handleEvent: function awf_handleEvent(evt) {
var detail = evt.detail;
var manifestURL = detail.manifestURL;
if (!manifestURL) {
if (!detail.url) {
return;
}

var config = new BrowserConfigHelper(detail.url, detail.manifestURL);

if (!config.manifest) {
return;
}
var config = new BrowserConfigHelper(detail);

config.evtType = evt.type;

switch (evt.type) {
case 'openwindow':
case 'appopenwindow':
case 'webapps-launch':
config.timestamp = detail.timestamp;
Expand Down Expand Up @@ -180,7 +178,7 @@
// The rocketbar currently handles the management of normal search app
// launches. Requests for the 'newtab' page will continue to filter
// through and publish the launchapp event.
if (config.manifest.role === 'search' &&
if (config.manifest && config.manifest.role === 'search' &&
config.url.indexOf('newtab.html') === -1) {
return;
}
Expand Down
2 changes: 1 addition & 1 deletion apps/system/js/browser.js
Expand Up @@ -5,7 +5,7 @@
'use strict';

function handleOpenUrl(url) {
var config = new BrowserConfigHelper(url);
var config = new BrowserConfigHelper({url: url});
config.useAsyncPanZoom = true;
config.oop = true;
var newApp = new AppWindow(config);
Expand Down
31 changes: 18 additions & 13 deletions apps/system/js/browser_config_helper.js
Expand Up @@ -31,14 +31,18 @@
*
* * oop: indicate it's running out of process or in process.
*
* @param {String} appURL The URL of the app or the page to be opened.
* @param {String} [manifestURL] The manifest URL of the app.
*
* @class BrowserConfigHelper
* @param {Object} [config] Config for creating appWindow.
* @param {String} [config.appURL] The URL of the app or the page to be
* opened.
* @param {String} [config.manifestURL] The manifest URL of the app.
* @param {String} [config.name] - optional The name of the app.
* @param {DOMFRAMEElement} [config.iframe] - optionalThe exisiting frame to
* inject.
*/
window.BrowserConfigHelper = function(appURL, manifestURL) {
var app = applications.getByManifestURL(manifestURL);
this.url = appURL;
window.BrowserConfigHelper = function(config) {
var app = config.manifestURL &&
applications.getByManifestURL(config.manifestURL);
this.url = config.url;

if (app) {
var manifest = app.manifest;
Expand All @@ -65,8 +69,8 @@
}

//Remove the origin and / to find if if the url is the entry point
if (path.indexOf('/' + ep) == 0 &&
(currentEp.launch_path == path)) {
if (path.indexOf('/' + ep) === 0 &&
(currentEp.launch_path === path)) {
origin = origin + currentEp.launch_path;
name = new ManifestHelper(currentEp).name;
for (var key in currentEp) {
Expand All @@ -92,18 +96,19 @@
];

if (!isOutOfProcessDisabled &&
outOfProcessBlackList.indexOf(manifestURL) === -1) {
outOfProcessBlackList.indexOf(config.manifestURL) === -1) {
// FIXME: content shouldn't control this directly
this.oop = true;
}

this.name = name;
this.manifestURL = manifestURL;
this.manifestURL = config.manifestURL;
this.origin = origin;
this.manifest = manifest;
} else {
this.name = '';
this.origin = appURL;
this.iframe = config.iframe;
this.name = config.name || '';
this.origin = config.url;
this.manifestURL = '';
this.manifest = null;
}
Expand Down
18 changes: 17 additions & 1 deletion apps/system/js/child_window_factory.js
Expand Up @@ -57,7 +57,7 @@
// <a href="" target="_blank"> should never be part of the app
if (evt.detail.name == '_blank' &&
evt.detail.features !== 'attention') {
this.launchActivity(evt);
this.createNewWindow(evt);
evt.stopPropagation();
return;
}
Expand Down Expand Up @@ -132,6 +132,22 @@
return (a[0] === b[0] && a[2] === b[2]);
};

ChildWindowFactory.prototype.createNewWindow = function(evt) {
if (!this.app.isActive() || this.app.isTransitioning()) {
return false;
}
var configObject = {
url: evt.detail.url,
name: evt.detail.name,
iframe: evt.detail.frameElement
};

window.dispatchEvent(new CustomEvent('openwindow', {
detail: configObject
}));
return true;
};

ChildWindowFactory.prototype.createChildWindow = function(evt) {
if (!this.app.isActive() || this.app.isTransitioning()) {
return false;
Expand Down
5 changes: 4 additions & 1 deletion apps/system/js/homescreen_window.js
Expand Up @@ -86,7 +86,10 @@
this.url = app.origin + '/index.html#root';

this.browser_config =
new BrowserConfigHelper(this.origin, this.manifestURL);
new BrowserConfigHelper({
url: this.origin,
manifestURL: this.manifestURL
});

// Necessary for b2gperf now.
this.name = this.browser_config.name;
Expand Down
5 changes: 4 additions & 1 deletion apps/system/js/search_window.js
Expand Up @@ -85,7 +85,10 @@
this.url = app.origin + '/index.html';

this.browser_config =
new BrowserConfigHelper(this.origin, this.manifestURL);
new BrowserConfigHelper({
url: this.origin,
manifestURL: this.manifestURL
});

this.manifest = this.browser_config.manifest;
this.browser_config.url = this.url;
Expand Down
5 changes: 4 additions & 1 deletion apps/system/js/secure_window_factory.js
Expand Up @@ -139,7 +139,10 @@
*/
SecureWindowFactory.prototype.create =
function(url, manifestURL) {
var config = new self.BrowserConfigHelper(url, manifestURL);
var config = new self.BrowserConfigHelper({
url: url,
manifestURL: manifestURL
});
for (var instanceID in this.states.apps) {
var secureWindow = this.states.apps[instanceID];
if (config.manifestURL === secureWindow.manifestURL) {
Expand Down
26 changes: 23 additions & 3 deletions apps/system/test/marionette/browser_launch_window_open_test.js
Expand Up @@ -21,7 +21,7 @@ marionette('Browser - Launch the same origin after navigating away',
'lockscreen.enabled': false
}
});

client.scope({ searchTimeout: 20000 });
var home, rocketbar, search, server, system;

suiteSetup(function(done) {
Expand Down Expand Up @@ -58,7 +58,7 @@ marionette('Browser - Launch the same origin after navigating away',
client.switchToFrame(frame);

client.switchToFrame();
var browsers = client.findElements( 'iframe[src*="http://localhost"]');
var browsers = client.findElements( 'iframe[data-url*="http://localhost"]');
assert.equal(browsers.length, 1);

client.switchToFrame(frame);
Expand All @@ -68,8 +68,28 @@ marionette('Browser - Launch the same origin after navigating away',
client.switchToFrame();

client.waitFor(function() {
browsers = client.findElements('iframe[src*="http://localhost"]');
browsers = client.findElements('iframe[data-url*="http://localhost"]');
return browsers.length === 2;
});
});

test('checks for web compat issues', function() {
var url = server.url('windowopen.html');
// rest condition, the alert might be show up quciker than new page
// Open the first URL in a sheet.
rocketbar.homescreenFocus();
rocketbar.enterText(url + '\uE006');

// Switch to the app, and navigate to a different url.
system.gotoBrowser(url);
client.helper.waitForElement('#trigger2').tap();
client.switchToFrame();

client.waitFor(function() {
return client.findElement(
'.appWindow .modal-dialog-alert-message')
.text()
.indexOf('caller received') !== -1;
});
});
});
14 changes: 14 additions & 0 deletions apps/system/test/marionette/fixtures/callopener.html
@@ -0,0 +1,14 @@
<html>
<head>
<title>Hyperlink Test Page</title>
<meta charset="UTF-8">
<meta name="application-name" content="Hyperlink Fixture">
<script type="text/javascript">
window.opener.alert('caller received');
window.close();
</script>
</head>
<body>
Calling opener alert.
</body>
</html>
1 change: 1 addition & 0 deletions apps/system/test/marionette/fixtures/windowopen.html
Expand Up @@ -8,6 +8,7 @@

<ul>
<li><a href="#" id="trigger1" onclick="window.open('http://localhost:8080', '_blank')">window.open() with _blank</a></li>
<li><a href="#" id="trigger2" onclick="window.open('/callopener.html', '_blank')">window.open() /callopener.html named: _blank</a></li>
</ul>

</body>
Expand Down
12 changes: 12 additions & 0 deletions apps/system/test/unit/app_window_factory_test.js
Expand Up @@ -283,6 +283,18 @@ suite('system/AppWindowFactory', function() {
fakeLaunchConfig2.url);
});

test('open a new window', function() {
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
appWindowFactory.handleEvent({
type: 'openwindow',
detail: fakeLaunchConfig2
});
assert.isTrue(stubDispatchEvent.called);
assert.equal(stubDispatchEvent.getCall(0).args[0].type, 'launchapp');
assert.equal(stubDispatchEvent.getCall(0).args[0].detail.url,
fakeLaunchConfig2.url);
});

test('opening from a system message', function() {
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
appWindowFactory.handleEvent({
Expand Down
28 changes: 14 additions & 14 deletions apps/system/test/unit/child_window_factory_test.js
Expand Up @@ -254,21 +254,21 @@ suite('system/ChildWindowFactory', function() {

test('Target _blank support', function() {
var app1 = new MockAppWindow(fakeAppConfig1);
var activitySpy = this.sinon.spy(window, 'MozActivity');
var cwf = new ChildWindowFactory(app1);
var expectedActivity = {
name: 'view',
data: {
type: 'url',
url: 'http://blank.com/index.html'
}
};
cwf.handleEvent(new CustomEvent('mozbrowseropenwindow',
{
detail: fakeWindowOpenBlank
}));
assert.isTrue(activitySpy.calledWithNew());
sinon.assert.calledWith(activitySpy, expectedActivity);
this.sinon.stub(app1, 'isActive').returns(true);
this.sinon.stub(app1, 'isTransitioning').returns(false);
var stubDispatchEvent = this.sinon.stub(window, 'dispatchEvent');
var testEvt = (new CustomEvent('mozbrowseropenwindow', {
detail: fakeWindowOpenBlank
}));
cwf.handleEvent(testEvt);

assert.equal(stubDispatchEvent.getCall(0).args[0].type, 'openwindow');
assert.deepEqual(stubDispatchEvent.getCall(0).args[0].detail, {
url: fakeWindowOpenBlank.url,
name: fakeWindowOpenBlank.name,
iframe: fakeWindowOpenBlank.frameElement
});
});

test('Create ActivityWindow', function() {
Expand Down

0 comments on commit 6163c5e

Please sign in to comment.