Skip to content
This repository has been archived by the owner on Feb 26, 2022. It is now read-only.

Commit

Permalink
Bug 886329 - drop-down list in Jetpack add-on breaks entire UI in Aur…
Browse files Browse the repository at this point in the history
…ora (23.0a2)

- Ignored `popupshowing` events are not emitted by panel
- Added unit test
- Added `ready` helper function
  • Loading branch information
ZER0 committed Aug 28, 2013
1 parent 758e697 commit 214ad10
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 4 deletions.
7 changes: 6 additions & 1 deletion lib/sdk/panel/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,12 @@ function make(document) {
let viewFrame = createFrame(panel, frameOptions);
setupPanelFrame(viewFrame);

function onDisplayChange({type}) {
function onDisplayChange({type, target}) {
// Events from child element like <select /> may propagate (dropdowns are
// popups too), in which case frame loader shouldn't be swapped.
// See Bug 886329
if (target !== this) return;

try { swapFrameLoaders(backgroundFrame, viewFrame); }
catch(error) { console.exception(error); }
events.emit(type, { subject: panel });
Expand Down
17 changes: 15 additions & 2 deletions lib/sdk/window/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

const { defer } = require('../core/promise');
const events = require('../system/events');
const { open: openWindow, onFocus, getToplevelWindow } = require('./utils');
const { open: openWindow, onFocus, getToplevelWindow,
isInteractive } = require('./utils');

function open(uri, options) {
return promise(openWindow.apply(null, arguments), 'load');
Expand Down Expand Up @@ -36,6 +37,18 @@ function focus(window) {
}
exports.focus = focus;

function ready(window) {
let { promise: result, resolve } = defer();

if (isInteractive(window))
resolve(window);
else
resolve(promise(window, 'DOMContentLoaded'));

return result;
}
exports.ready = ready;

function promise(target, evt, capture) {
let deferred = defer();
capture = !!capture;
Expand All @@ -47,4 +60,4 @@ function promise(target, evt, capture) {

return deferred.promise;
}
exports.promise = promise;
exports.promise = promise;
39 changes: 38 additions & 1 deletion test/test-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const { Loader } = require('sdk/test/loader');
const { LoaderWithHookedConsole } = require("sdk/test/loader");
const timer = require("sdk/timers");
const self = require('sdk/self');
const { open, close, focus } = require('sdk/window/helpers');
const { open, close, focus, ready } = require('sdk/window/helpers');
const { isPrivate } = require('sdk/private-browsing');
const { isWindowPBSupported, isGlobalPBSupported } = require('sdk/private-browsing/utils');
const { defer, all } = require('sdk/core/promise');
Expand Down Expand Up @@ -896,6 +896,43 @@ exports['test passing DOM node as first argument'] = function (assert, done) {
panel.show(widgetNode);
};

// This test is checking that `onpupshowing` events emitted by panel's children
// are not considered.
// See Bug 886329
exports['test nested popups'] = function (assert, done) {
let loader = Loader(module);
let { Panel } = loader.require('sdk/panel');
let { getActiveView } = loader.require('sdk/view/core');
let url = '<select><option>1<option>2<option>3</select>';

let getContentWindow = panel => {
return getActiveView(panel).querySelector('iframe').contentWindow;
}

let panel = Panel({
contentURL: 'data:text/html;charset=utf-8,' + encodeURIComponent(url),
onShow: () => {
ready(getContentWindow(panel)).then(({ window, document }) => {
let select = document.querySelector('select');
let event = document.createEvent('UIEvent');

event.initUIEvent('popupshowing', true, true, window, null);
select.dispatchEvent(event);

assert.equal(
select,
getContentWindow(panel).document.querySelector('select'),
'select is still loaded in panel'
);

done();
});
}
});

panel.show();
};

if (isWindowPBSupported) {
exports.testGetWindow = function(assert, done) {
let activeWindow = getMostRecentBrowserWindow();
Expand Down

0 comments on commit 214ad10

Please sign in to comment.