Bug 1250084 - The 'Responsive Design View' button from the Menu is not checked while the RDM is opened; r=jryans

MozReview-Commit-ID: 9i9rYI48H4G
This commit is contained in:
Matteo Ferretti 2016-04-24 14:54:08 +02:00
Родитель 435717397c
Коммит 969b9bd63b
9 изменённых файлов: 217 добавлений и 4 удалений

Просмотреть файл

@ -6,7 +6,7 @@
const { defer, all } = require('../core/promise');
const events = require('../system/events');
const { open: openWindow, onFocus, getToplevelWindow,
isInteractive, getOuterId } = require('./utils');
isInteractive, isStartupFinished, getOuterId } = require('./utils');
const { Ci } = require("chrome");
function open(uri, options) {
@ -49,6 +49,24 @@ function ready(window) {
}
exports.ready = ready;
function startup(window) {
let { promise: result, resolve } = defer();
if (isStartupFinished(window)) {
resolve(window);
} else {
events.on("browser-delayed-startup-finished", function listener({subject}) {
if (subject === window) {
events.off("browser-delayed-startup-finished", listener);
resolve(window);
}
});
}
return result;
}
exports.startup = startup;
function promise(target, evt, capture) {
let deferred = defer();
capture = !!capture;

Просмотреть файл

@ -322,6 +322,17 @@ const isInteractive = window =>
isXULDocumentWindow(window) && window.document.readyState === "interactive";
exports.isInteractive = isInteractive;
/**
* Check if the given browser window has finished the startup.
* @params {nsIDOMWindow} window
*/
const isStartupFinished = (window) =>
isBrowser(window) &&
window.gBrowserInit &&
window.gBrowserInit.delayedStartupFinished;
exports.isStartupFinished = isStartupFinished;
const isXULDocumentWindow = ({document}) =>
document.documentElement &&
document.documentElement.namespaceURI === XUL_NS;

Просмотреть файл

@ -0,0 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const { filter, map, merge } = require("sdk/event/utils");
const { events: browserEvents } = require("sdk/browser/events");
const { events: tabEvents } = require("sdk/tab/events");
const { getTabs, getActiveTab, getOwnerWindow } = require("sdk/tabs/utils");
const tabSelect = filter(tabEvents, e => e.type === "TabSelect");
const tabClose = filter(tabEvents, e => e.type === "TabClose");
const windowOpen = filter(browserEvents, e => e.type === "load");
const windowClose = filter(browserEvents, e => e.type === "close");
// The `activate` event stream, observes when any tab is activated.
// It has the activated `tab` as argument.
const activate = merge([
map(tabSelect, ({target}) => target),
map(windowOpen, ({target}) => getActiveTab(target))
]);
exports.activate = activate;
// The `close` event stream, observes when any tab or any window is closed.
// The event has an object as argument, with the `tabs` involved in the closing
// process and their owner window.
const close = merge([
map(tabClose, ({target}) => ({
window: getOwnerWindow(target),
tabs: [target]
})),
map(windowClose, ({target}) => ({
window: target,
tabs: getTabs(target)
}))
]);
exports.close = close;

Просмотреть файл

@ -9,6 +9,10 @@ const promise = require("promise");
const { Task } = require("resource://gre/modules/Task.jsm");
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
const EventEmitter = require("devtools/shared/event-emitter");
const { getOwnerWindow } = require("sdk/tabs/utils");
const { on, off } = require("sdk/event/core");
const { startup } = require("sdk/window/helpers");
const events = require("./events");
const TOOL_URL = "chrome://devtools/content/responsive.html/index.xhtml";
@ -53,8 +57,13 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
*/
openIfNeeded: Task.async(function* (window, tab) {
if (!this.isActiveForTab(tab)) {
if (!this.activeTabs.size) {
on(events.activate, "data", onActivate);
on(events.close, "data", onClose);
}
let ui = new ResponsiveUI(window, tab);
this.activeTabs.set(tab, ui);
yield setMenuCheckFor(tab, window);
yield ui.inited;
this.emit("on", { tab });
}
@ -73,9 +82,18 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
*/
closeIfNeeded: Task.async(function* (window, tab) {
if (this.isActiveForTab(tab)) {
yield this.activeTabs.get(tab).destroy();
let ui = this.activeTabs.get(tab);
this.activeTabs.delete(tab);
if (!this.activeTabs.size) {
off(events.activate, "data", onActivate);
off(events.close, "data", onClose);
}
yield ui.destroy();
this.emit("off", { tab });
yield setMenuCheckFor(tab, window);
}
return promise.resolve();
}),
@ -140,6 +158,7 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
// GCLI commands in ../responsivedesign/resize-commands.js listen for events
// from this object to know when the UI for a tab has opened or closed.
EventEmitter.decorate(ResponsiveUIManager);
/**
* ResponsiveUI manages the responsive design tool for a specific tab. The
* actual tool itself lives in a separate chrome:// document that is loaded into
@ -309,3 +328,20 @@ function waitForDocLoadComplete(gBrowser) {
gBrowser.addProgressListener(progressListener);
return deferred.promise;
}
const onActivate = (tab) => setMenuCheckFor(tab);
const onClose = ({ window, tabs }) => {
for (let tab of tabs) {
ResponsiveUIManager.closeIfNeeded(window, tab);
}
};
const setMenuCheckFor = Task.async(
function* (tab, window = getOwnerWindow(tab)) {
yield startup(window);
let menu = window.document.getElementById("menu_responsiveUI");
menu.setAttribute("checked", ResponsiveUIManager.isActiveForTab(tab));
}
);

Просмотреть файл

@ -17,6 +17,7 @@ DevToolsModules(
'app.js',
'constants.js',
'devices.js',
'events.js',
'index.css',
'manager.js',
'reducers.js',

Просмотреть файл

@ -13,6 +13,9 @@ support-files =
[browser_device_modal_submit.js]
[browser_device_width.js]
[browser_exit_button.js]
[browser_menu_item_01.js]
[browser_menu_item_02.js]
skip-if = os == "win" && debug # Bug 1267278 - RDM's browser_menu_item_02 test is failing on Windows Debug
[browser_mouse_resize.js]
[browser_resize_cmd.js]
[browser_screenshot_button.js]

Просмотреть файл

@ -0,0 +1,58 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test RDM menu item is checked when expected, on multiple tabs.
const TEST_URL = "data:text/html;charset=utf-8,";
const tabUtils = require("sdk/tabs/utils");
const { startup } = require("sdk/window/helpers");
const { activate } = require("devtools/client/responsive.html/events");
const events = require("sdk/event/core");
const activateTab = (tab) => new Promise(resolve => {
events.once(activate, "data", resolve);
tabUtils.activateTab(tab);
});
const isMenuChecked = () => {
let menu = document.getElementById("menu_responsiveUI");
return menu.getAttribute("checked") === "true";
};
add_task(function* () {
yield startup(window);
ok(!isMenuChecked(),
"RDM menu item is unchecked by default");
const tab = yield addTab(TEST_URL);
ok(!isMenuChecked(),
"RDM menu item is unchecked for new tab");
yield openRDM(tab);
ok(isMenuChecked(),
"RDM menu item is checked with RDM open");
const tab2 = yield addTab(TEST_URL);
ok(!isMenuChecked(),
"RDM menu item is unchecked for new tab");
yield activateTab(tab);
ok(isMenuChecked(),
"RDM menu item is checked for the tab where RDM is open");
yield closeRDM(tab);
ok(!isMenuChecked(),
"RDM menu item is unchecked after RDM is closed");
yield removeTab(tab);
yield removeTab(tab2);
});

Просмотреть файл

@ -0,0 +1,47 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test RDM menu item is checked when expected, on multiple windows.
const TEST_URL = "data:text/html;charset=utf-8,";
const { getActiveTab } = require("sdk/tabs/utils");
const { getMostRecentBrowserWindow } = require("sdk/window/utils");
const { open, close, startup } = require("sdk/window/helpers");
const { partial } = require("sdk/lang/functional");
const openBrowserWindow = partial(open, null, { features: { toolbar: true } });
const isMenuCheckedFor = ({document}) => {
let menu = document.getElementById("menu_responsiveUI");
return menu.getAttribute("checked") === "true";
};
add_task(function* () {
const window1 = yield openBrowserWindow(TEST_URL);
yield startup(window1);
const tab1 = getActiveTab(window1);
is(window1, getMostRecentBrowserWindow(),
"The new window is the active one");
ok(!isMenuCheckedFor(window1),
"RDM menu item is unchecked by default");
yield openRDM(tab1);
ok(isMenuCheckedFor(window1),
"RDM menu item is checked with RDM open");
yield close(window1);
is(window, getMostRecentBrowserWindow(),
"The original window is the active one");
ok(!isMenuCheckedFor(window),
"RDM menu item is unchecked");
});

Просмотреть файл

@ -37,8 +37,9 @@ registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.responsive.html.enabled");
Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
});
const { ResponsiveUIManager } = Cu.import("resource://devtools/client/responsivedesign/responsivedesign.jsm", {});
const { ResponsiveUIManager } = require("resource://devtools/client/responsivedesign/responsivedesign.jsm");
const { loadDeviceList } = require("devtools/client/responsive.html/devices");
const { getOwnerWindow } = require("sdk/tabs/utils");
const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
@ -48,7 +49,7 @@ const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
var openRDM = Task.async(function* (tab) {
info("Opening responsive design mode");
let manager = ResponsiveUIManager;
let ui = yield manager.openIfNeeded(window, tab);
let ui = yield manager.openIfNeeded(getOwnerWindow(tab), tab);
info("Responsive design mode opened");
return { ui, manager };
});