Permalink
Browse files

Merge branch 'master' of git://github.com/mozilla/addon-sdk into 8397…

…46v2

Conflicts:
	test/test-panel.js
  • Loading branch information...
2 parents 529de86 + 924fd2f commit 3ea1dcb4a521bb2b0cc34e33e47e8e02458b0e3e @erikvold committed Mar 23, 2013
View
12 doc/module-source/sdk/panel.md
@@ -31,6 +31,8 @@ in preparation for the next time it is shown.
Your add-on can receive notifications when a panel is shown or hidden by
listening to its `show` and `hide` events.
+Opening a panel will close an already opened panel.
+
<div class="warning">
If your add-on has
<a href="modules/sdk/private-browsing.html#Opting into private browsing">opted into private browsing</a>,
@@ -419,6 +421,10 @@ Creates a panel.
The width of the panel in pixels. Optional.
@prop [height] {number}
The height of the panel in pixels. Optional.
+ @prop [focus] {boolean}
+ Set to `false` to prevent taking the focus away when the panel is shown.
+ Only turn this off if necessary, to prevent accessibility issue.
+ Optional, default to `true`.
@prop [contentURL] {string}
The URL of the content to load in the panel.
@prop [allow] {object}
@@ -491,6 +497,12 @@ The height of the panel in pixels.
The width of the panel in pixels.
</api>
+<api name="focus">
+@property {boolean}
+Whether of not focus will be taken away when the panel is shown.
+This property is read-only.
+</api>
+
<api name="contentURL">
@property {string}
The URL of content loaded into the panel. This can point to
View
20 lib/sdk/frame/hidden-frame.js
@@ -21,10 +21,11 @@ const { defer } = require("../core/promise");
const { when: unload } = require("../system/unload");
const { validateOptions, getTypeOf } = require("../deprecated/api-utils");
const { window } = require("../addon/window");
+const { fromIterator } = require("../util/array");
// This cache is used to access friend properties between functions
// without exposing them on the public API.
-let cache = [];
+let cache = new Set();
let elements = new WeakMap();
function contentLoaded(target) {
@@ -75,20 +76,13 @@ var HiddenFrame = Class({
});
exports.HiddenFrame = HiddenFrame
-function isFrameCached(frame) {
- // Function returns `true` if frame was already cached.
- return cache.some(function(value) {
- return value === frame
- })
-}
-
function addHidenFrame(frame) {
if (!(frame instanceof HiddenFrame))
throw Error("The object to be added must be a HiddenFrame.");
// This instance was already added.
- if (isFrameCached(frame)) return frame;
- else cache.push(frame);
+ if (cache.has(frame)) return frame;
+ else cache.add(frame);
let element = makeFrame(window.document, {
nodeName: "iframe",
@@ -111,14 +105,14 @@ function removeHiddenFrame(frame) {
if (!(frame instanceof HiddenFrame))
throw Error("The object to be removed must be a HiddenFrame.");
- if (!isFrameCached(frame)) return;
+ if (!cache.has(frame)) return;
// Remove from cache before calling in order to avoid loop
- cache.splice(cache.indexOf(frame), 1);
+ cache.delete(frame);
emit(frame, "unload")
let element = frame.element
if (element) element.parentNode.removeChild(element)
}
exports.remove = removeHiddenFrame;
-unload(function() cache.splice(0).forEach(removeHiddenFrame));
+unload(function() fromIterator(cache).forEach(removeHiddenFrame));
View
45 lib/sdk/panel.js
@@ -17,6 +17,7 @@ const { validateOptions: valid } = require('./deprecated/api-utils');
const { Symbiont } = require('./content/content');
const { EventEmitter } = require('./deprecated/events');
const { setTimeout } = require('./timers');
+const { on, off, emit } = require('./system/events');
const runtime = require('./system/runtime');
const { getDocShell } = require("./frame/utils");
const { getWindow } = require('./panel/window');
@@ -26,7 +27,9 @@ const { isWindowPBSupported } = require('./private-browsing/utils');
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
ON_SHOW = 'popupshown',
ON_HIDE = 'popuphidden',
- validNumber = { is: ['number', 'undefined', 'null'] };
+ validNumber = { is: ['number', 'undefined', 'null'] },
+ validBoolean = { is: ['boolean', 'undefined', 'null'] },
+ ADDON_ID = require('./self').id;
if (isPrivateBrowsingSupported && isWindowPBSupported) {
throw Error('The panel module cannot be used with per-window private browsing at the moment, see Bug 816257');
@@ -68,6 +71,9 @@ const Panel = Symbiont.resolve({
constructor: function Panel(options) {
this._onShow = this._onShow.bind(this);
this._onHide = this._onHide.bind(this);
+ this._onAnyPanelShow = this._onAnyPanelShow.bind(this);
+ on('sdk-panel-show', this._onAnyPanelShow);
+
this.on('inited', this._onSymbiontInit.bind(this));
this.on('propertyChange', this._onChange.bind(this));
@@ -82,6 +88,12 @@ const Panel = Symbiont.resolve({
this.height = options.height;
if ('contentURL' in options)
this.contentURL = options.contentURL;
+ if ('focus' in options) {
+ var value = options.focus;
+ var validatedValue = valid({ $: value }, { $: validBoolean }).$;
+ this._focus =
+ (typeof validatedValue == 'boolean') ? validatedValue : this._focus;
+ }
this._init(options);
},
@@ -91,6 +103,7 @@ const Panel = Symbiont.resolve({
this._removeAllListeners('hide');
this._removeAllListeners('propertyChange');
this._removeAllListeners('inited');
+ off('sdk-panel-show', this._onAnyPanelShow);
// defer cleanup to be performed after panel gets hidden
this._xulPanel = null;
this._symbiontDestructor(this);
@@ -109,6 +122,9 @@ const Panel = Symbiont.resolve({
set height(value)
this._height = valid({ $: value }, { $: validNumber }).$ || this._height,
_height: 240,
+ /* Public API: Panel.focus */
+ get focus() this._focus,
+ _focus: true,
/* Public API: Panel.isShowing */
get isShowing() !!this._xulPanel && this._xulPanel.state == "open",
@@ -126,6 +142,7 @@ const Panel = Symbiont.resolve({
let document = anchorWindow.document;
let xulPanel = this._xulPanel;
+ let panel = this;
if (!xulPanel) {
xulPanel = this._xulPanel = document.createElementNS(XUL_NS, 'panel');
xulPanel.setAttribute("type", "arrow");
@@ -165,7 +182,7 @@ const Panel = Symbiont.resolve({
xulPanel.appendChild(frame);
document.getElementById("mainPopupSet").appendChild(xulPanel);
}
- let { width, height } = this, x, y, position;
+ let { width, height, focus } = this, x, y, position;
if (!anchor) {
// Open the popup in the middle of the window.
@@ -210,13 +227,25 @@ const Panel = Symbiont.resolve({
xulPanel.firstChild.style.width = width + "px";
xulPanel.firstChild.style.height = height + "px";
+ // Only display xulPanel if Panel.hide() was not called
+ // after Panel.show(), but before xulPanel.openPopup
+ // was loaded
+ emit('sdk-panel-show', { data: ADDON_ID, subject: xulPanel });
+
+ // Prevent the panel from getting focus when showing up
+ // if focus is set to false
+ xulPanel.setAttribute("noautofocus",!focus);
+
// Wait for the XBL binding to be constructed
function waitForBinding() {
if (!xulPanel.openPopup) {
setTimeout(waitForBinding, 50);
return;
}
- xulPanel.openPopup(anchor, position, x, y);
+
+ if (xulPanel.state !== 'hiding') {
+ xulPanel.openPopup(anchor, position, x, y);
+ }
}
waitForBinding();
@@ -336,6 +365,16 @@ const Panel = Symbiont.resolve({
this._emit('error', e);
}
},
+
+ /**
+ * When any panel is displayed, system-wide, close `this`
+ * panel unless it's the most recently displayed panel
+ */
+ _onAnyPanelShow: function _onAnyPanelShow(e) {
+ if (e.subject !== this._xulPanel)
+ this.hide();
+ },
+
/**
* Notification that panel was fully initialized.
*/
View
3 lib/sdk/util/array.js
@@ -90,8 +90,7 @@ exports.flatten = function flatten(array){
function fromIterator(iterator) {
let array = [];
- for each (let item in iterator)
- array.push(item);
+ for (let item of iterator) array.push(item);
return array;
}
exports.fromIterator = fromIterator;
View
4 python-lib/cuddlefish/prefs.py
@@ -11,6 +11,9 @@
'javascript.options.strict': True,
'javascript.options.showInConsole': True,
+ # Allow remote connections to the debugger
+ 'devtools.debugger.remote-enabled' : True,
+
'extensions.sdk.console.logLevel': 'info',
'extensions.checkCompatibility.nightly' : False,
@@ -51,6 +54,7 @@
'browser.startup.homepage' : 'about:blank',
'startup.homepage_welcome_url' : 'about:blank',
'devtools.errorconsole.enabled' : True,
+ 'devtools.chrome.enabled' : True,
# Disable the feedback extension
'extensions.testpilot.runStudies' : False,
View
49 test/addons/layout-change/main.js
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
+const app = require("sdk/system/xul-app");
// This test makes sure that require statements used by all AMO hosted
// add-ons will be able to use old require statements.
@@ -16,14 +17,18 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("tabs"),
require("sdk/tabs"), "sdk/tabs -> tabs");
- assert.equal(require("widget"),
- require("sdk/widget"), "sdk/widget -> widget");
+ if (app.is("Firefox")) {
+ assert.equal(require("widget"),
+ require("sdk/widget"), "sdk/widget -> widget");
+ }
assert.equal(require("page-mod"),
require("sdk/page-mod"), "sdk/page-mod -> page-mod");
- assert.equal(require("panel"),
- require("sdk/panel"), "sdk/panel -> panel");
+ if (app.is("Firefox")) {
+ assert.equal(require("panel"),
+ require("sdk/panel"), "sdk/panel -> panel");
+ }
assert.equal(require("request"),
require("sdk/request"), "sdk/request -> request");
@@ -34,8 +39,10 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("simple-storage"),
require("sdk/simple-storage"), "sdk/simple-storage -> simple-storage");
- assert.equal(require("context-menu"),
- require("sdk/context-menu"), "sdk/context-menu -> context-menu");
+ if (app.is("Firefox")) {
+ assert.equal(require("context-menu"),
+ require("sdk/context-menu"), "sdk/context-menu -> context-menu");
+ }
assert.equal(require("notifications"),
require("sdk/notifications"), "sdk/notifications -> notifications");
@@ -49,8 +56,10 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("url"),
require("sdk/url"), "sdk/url -> url");
- assert.equal(require("selection"),
- require("sdk/selection"), "sdk/selection -> selection");
+ if (app.is("Firefox")) {
+ assert.equal(require("selection"),
+ require("sdk/selection"), "sdk/selection -> selection");
+ }
assert.equal(require("timers"),
require("sdk/timers"), "sdk/timers -> timers");
@@ -97,8 +106,10 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("match-pattern"),
require("sdk/page-mod/match-pattern"), "sdk/page-mod/match-pattern -> match-pattern");
- assert.equal(require("tab-browser"),
- require("sdk/deprecated/tab-browser"), "sdk/deprecated/tab-browser -> tab-browser");
+ if (app.is("Firefox")) {
+ assert.equal(require("tab-browser"),
+ require("sdk/deprecated/tab-browser"), "sdk/deprecated/tab-browser -> tab-browser");
+ }
assert.equal(require("file"),
require("sdk/io/file"), "sdk/io/file -> file");
@@ -154,8 +165,12 @@ exports["test compatibility"] = function(assert) {
assert.equal(require("environment"),
require("sdk/system/environment"), "sdk/system/environment -> environment");
- assert.equal(require("utils/data"),
- require("sdk/io/data"), "sdk/io/data -> utils/data");
+ if (app.is("Firefox")) {
+ // This module fails on fennec because of favicon xpcom component
+ // being not implemented on it.
+ assert.equal(require("utils/data"),
+ require("sdk/io/data"), "sdk/io/data -> utils/data");
+ }
assert.equal(require("test/assert"),
require("sdk/test/assert"), "sdk/test/assert -> test/assert");
@@ -174,14 +189,4 @@ exports["test compatibility"] = function(assert) {
"api-utils/cortex -> sdk/deprecated/cortex");
};
-if (require("sdk/system/xul-app").is("Fennec")) {
- module.exports = {
- "test Unsupported Test": function UnsupportedTest (assert) {
- assert.pass(
- "Skipping this test until Fennec support is implemented." +
- "See bug 809352");
- }
- }
-}
-
require("sdk/test/runner").runTestsFromModule(module);
View
7 test/addons/private-browsing-supported/main.js
@@ -4,9 +4,9 @@
'use strict';
const { merge } = require('sdk/util/object');
+const app = require("sdk/system/xul-app");
merge(module.exports,
- require('./test-windows'),
require('./test-tabs'),
require('./test-page-mod'),
require('./test-selection'),
@@ -15,4 +15,9 @@ merge(module.exports,
require('./test-global-private-browsing')
);
+// Doesn't make sense to test window-utils and windows on fennec,
+// as there is only one window which is never private
+if (!app.is("Fennec"))
+ merge(module.exports, require('./test-windows'));
+
require('sdk/test/runner').runTestsFromModule(module);
View
38 test/addons/require/main.js
@@ -12,13 +12,13 @@ exports["test local vs sdk module"] = function (assert) {
}
exports["test 3rd party vs sdk module"] = function (assert) {
- // We are testing with a 3rd party package called `panel` with 3 modules
+ // We are testing with a 3rd party package called `tabs` with 3 modules
// main, page-mod and third-party
// the only way to require 3rd party package modules are to use absolute paths
- // require("panel/main"), require("panel/page-mod"),
- // require("panel/third-party") and also require("panel") which will refer
- // to panel's main package module.
+ // require("tabs/main"), require("tabs/page-mod"),
+ // require("tabs/third-party") and also require("tabs") which will refer
+ // to tabs's main package module.
// So require(page-mod) shouldn't map the 3rd party
assert.equal(require("page-mod"),
@@ -27,27 +27,27 @@ exports["test 3rd party vs sdk module"] = function (assert) {
assert.ok(require("page-mod").PageMod,
"page-mod module is really the sdk one");
- assert.equal(require("panel/page-mod").id, "page-mod",
- "panel/page-mod is the 3rd party");
+ assert.equal(require("tabs/page-mod").id, "page-mod",
+ "tabs/page-mod is the 3rd party");
- // But require(panel) will map to 3rd party main module
+ // But require(tabs) will map to 3rd party main module
// *and* overload the sdk module
// and also any local module with the same name
- assert.equal(require("panel").id, "panel-main",
+ assert.equal(require("tabs").id, "tabs-main",
"Third party main module overload sdk modules");
- assert.equal(require("panel"),
- require("panel/main"),
- "require(panel) maps to require(panel/main)");
+ assert.equal(require("tabs"),
+ require("tabs/main"),
+ "require(tabs) maps to require(tabs/main)");
// So that you have to use relative path to ensure getting the local module
- assert.equal(require("./panel").id,
- "local-panel",
- "require(./panel) maps to the local module");
+ assert.equal(require("./tabs").id,
+ "local-tabs",
+ "require(./tabs) maps to the local module");
// It should still be possible to require sdk module with absolute path
- assert.ok(require("sdk/panel").Panel,
+ assert.ok(require("sdk/tabs").open,
"We can bypass this overloading with absolute path to sdk modules");
- assert.equal(require("sdk/panel"),
- require("addon-kit/panel"),
+ assert.equal(require("sdk/tabs"),
+ require("addon-kit/tabs"),
"Old and new layout both work");
}
@@ -70,8 +70,8 @@ exports.testMultipleRequirePerLine = function (assert) {
}
exports.testSDKRequire = function (assert) {
- assert.deepEqual(Object.keys(require('sdk/widget')), ['Widget']);
- assert.equal(require('widget'), require('sdk/widget'));
+ assert.deepEqual(Object.keys(require('sdk/page-worker')), ['Page']);
+ assert.equal(require('page-worker'), require('sdk/page-worker'));
}
require("sdk/test/runner").runTestsFromModule(module);
View
2 test/addons/require/packages/panel/main.js → test/addons/require/packages/tabs/main.js
@@ -2,4 +2,4 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-exports.id = "panel-main";
+exports.id = "tabs-main";
View
0 ...ddons/require/packages/panel/package.json → ...addons/require/packages/tabs/package.json
File renamed without changes.
View
0 ...addons/require/packages/panel/page-mod.js → .../addons/require/packages/tabs/page-mod.js
File renamed without changes.
View
2 test/addons/require/panel.js → test/addons/require/tabs.js
@@ -2,4 +2,4 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-exports.id = "local-panel";
+exports.id = "local-tabs";
View
43 test/test-hidden-frame.js
@@ -4,6 +4,7 @@
"use strict";
+const { Loader } = require("sdk/test/loader");
const hiddenFrames = require("sdk/frame/hidden-frame");
const { HiddenFrame } = hiddenFrames;
@@ -29,4 +30,46 @@ exports["test Frame"] = function(assert, done) {
}));
};
+exports["test frame removed properly"] = function(assert, done) {
+ let url = "data:text/html;charset=utf-8,<!DOCTYPE%20html>";
+
+ let hiddenFrame = hiddenFrames.add(HiddenFrame({
+ onReady: function () {
+ let frame = this.element;
+ assert.ok(frame.parentNode, "frame has a parent node");
+ hiddenFrames.remove(hiddenFrame);
+ assert.ok(!frame.parentNode, "frame no longer has a parent node");
+ done();
+ }
+ }));
+};
+
+
+exports["test unload detaches panels"] = function(assert, done) {
+ let loader = Loader(module);
+ let { add, remove, HiddenFrame } = loader.require("sdk/frame/hidden-frame");
+ let frames = []
+
+ function ready() {
+ frames.push(this.element);
+ if (frames.length === 2) complete();
+ }
+
+ add(HiddenFrame({ onReady: ready }));
+ add(HiddenFrame({ onReady: ready }));
+
+ function complete() {
+ frames.forEach(function(frame) {
+ assert.ok(frame.parentNode, "frame is in the document");
+ })
+ loader.unload();
+ frames.forEach(function(frame) {
+ assert.ok(!frame.parentNode, "frame isn't in the document'");
+ });
+ done();
+ }
+};
+
+
+
require("test").run(exports);
View
155 test/test-panel.js
@@ -289,24 +289,33 @@ exports["test Anchor And Arrow"] = function(assert, done) {
const { Panel } = require('sdk/panel');
let count = 0;
- function newPanel(tab, anchor) {
+ let queue = [];
+ let tab;
+
+ function newPanel(anchor) {
let panel = Panel({
contentURL: "data:text/html;charset=utf-8,<html><body style='padding: 0; margin: 0; " +
"background: gray; text-align: center;'>Anchor: " +
anchor.id + "</body></html>",
width: 200,
height: 100,
onShow: function () {
- count++;
panel.destroy();
- if (count==5) {
- assert.pass("All anchored panel test displayed");
- tab.close(function () {
- done();
- });
- }
+ next();
}
});
+ queue.push({ panel: panel, anchor: anchor });
+ }
+
+ function next () {
+ if (!queue.length) {
+ assert.pass("All anchored panel test displayed");
+ tab.close(function () {
+ done();
+ });
+ return;
+ }
+ let { panel, anchor } = queue.shift();
panel.show(anchor);
}
@@ -323,22 +332,105 @@ exports["test Anchor And Arrow"] = function(assert, done) {
tabs.open({
url: url,
- onReady: function(tab) {
+ onReady: function(_tab) {
+ tab = _tab;
let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
getMostRecentWindow("navigator:browser");
let window = browserWindow.content;
- newPanel(tab, window.document.getElementById('tl'));
- newPanel(tab, window.document.getElementById('tr'));
- newPanel(tab, window.document.getElementById('bl'));
- newPanel(tab, window.document.getElementById('br'));
+ newPanel(window.document.getElementById('tl'));
+ newPanel(window.document.getElementById('tr'));
+ newPanel(window.document.getElementById('bl'));
+ newPanel(window.document.getElementById('br'));
let anchor = browserWindow.document.getElementById("identity-box");
- newPanel(tab, anchor);
+ newPanel(anchor);
+
+ next();
+ }
+ });
+};
+
+exports["test Panel Focus True"] = function(assert, done) {
+ const { Panel } = require('sdk/panel');
+
+ const FM = Cc["@mozilla.org/focus-manager;1"].
+ getService(Ci.nsIFocusManager);
+
+ let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator).
+ getMostRecentWindow("navigator:browser");
+
+ // Make sure there is a focused element
+ browserWindow.document.documentElement.focus();
+
+ // Get the current focused element
+ let focusedElement = FM.focusedElement;
+
+ let panel = Panel({
+ contentURL: "about:buildconfig",
+ focus: true,
+ onShow: function () {
+ assert.ok(focusedElement !== FM.focusedElement,
+ "The panel takes the focus away.");
+ done();
+ }
+ });
+ panel.show();
+};
+
+exports["test Panel Focus False"] = function(assert, done) {
+ const { Panel } = require('sdk/panel');
+
+ const FM = Cc["@mozilla.org/focus-manager;1"].
+ getService(Ci.nsIFocusManager);
+
+ let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator).
+ getMostRecentWindow("navigator:browser");
+
+ // Make sure there is a focused element
+ browserWindow.document.documentElement.focus();
+
+ // Get the current focused element
+ let focusedElement = FM.focusedElement;
+
+ let panel = Panel({
+ contentURL: "about:buildconfig",
+ focus: false,
+ onShow: function () {
+ assert.ok(focusedElement === FM.focusedElement,
+ "The panel does not take the focus away.");
+ done();
}
});
+ panel.show();
+};
+exports["test Panel Focus Not Set"] = function(assert, done) {
+ const { Panel } = require('sdk/panel');
+ const FM = Cc["@mozilla.org/focus-manager;1"].
+ getService(Ci.nsIFocusManager);
+ let browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
+ getService(Ci.nsIWindowMediator).
+ getMostRecentWindow("navigator:browser");
+
+ // Make sure there is a focused element
+ browserWindow.document.documentElement.focus();
+
+ // Get the current focused element
+ let focusedElement = FM.focusedElement;
+
+ let panel = Panel({
+ contentURL: "about:buildconfig",
+ onShow: function () {
+ assert.ok(focusedElement !== FM.focusedElement,
+ "The panel takes the focus away.");
+ done();
+ }
+ });
+ panel.show();
};
exports["test Panel Text Color"] = function(assert, done) {
@@ -520,7 +612,7 @@ exports["test console.log in Panel"] = function(assert, done) {
});
panel.show();
-
+
function onMessage(type, message) {
assert.equal(type, 'log', 'console.log() works');
assert.equal(message, text, 'console.log() works');
@@ -727,6 +819,39 @@ else if (isGlobalPBSupported) {
}
}
+exports['test Only One Panel Open Concurrently'] = function (assert, done) {
+ const loader = Loader(module);
+ const { Panel } = loader.require('sdk/panel')
+
+ let panelA = Panel({
+ contentURL: 'about:buildconfig'
+ });
+
+ let panelB = Panel({
+ contentURL: 'about:buildconfig',
+ onShow: function () {
+ // When loading two panels simulataneously, only the second
+ // should be shown, never showing the first
+ assert.equal(panelA.isShowing, false, 'First panel is hidden');
+ assert.equal(panelB.isShowing, true, 'Second panel is showing');
+ panelC.show();
+ }
+ });
+
+ let panelC = Panel({
+ contentURL: 'about:buildconfig',
+ onShow: function () {
+ assert.equal(panelA.isShowing, false, 'First panel is hidden');
+ assert.equal(panelB.isShowing, false, 'Second panel is hidden');
+ assert.equal(panelC.isShowing, true, 'Third panel is showing');
+ done();
+ }
+ });
+
+ panelA.show();
+ panelB.show();
+};
+
try {
require("sdk/panel");
}

0 comments on commit 3ea1dcb

Please sign in to comment.