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

Bug 886329 - drop-down list in Jetpack add-on breaks entire UI in Aurora (23.0a2) #1221

Merged
merged 1 commit into from Aug 28, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/sdk/panel/utils.js
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
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
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