mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1239562 - Use explicit events to fix test races in responsive design. r=ochameau
This commit is contained in:
parent
1813d29694
commit
0e4da7b1f1
@ -92,11 +92,11 @@ exports.items = [
|
||||
}
|
||||
];
|
||||
|
||||
function gcli_cmd_resize(args, context) {
|
||||
function* gcli_cmd_resize(args, context) {
|
||||
let browserWindow = context.environment.chromeWindow;
|
||||
let mgr = browserWindow.ResponsiveUI.ResponsiveUIManager;
|
||||
mgr.handleGcliCommand(browserWindow,
|
||||
browserWindow.gBrowser.selectedTab,
|
||||
this.name,
|
||||
args);
|
||||
yield mgr.handleGcliCommand(browserWindow,
|
||||
browserWindow.gBrowser.selectedTab,
|
||||
this.name,
|
||||
args);
|
||||
}
|
||||
|
@ -2,131 +2,181 @@
|
||||
* 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/. */
|
||||
|
||||
var Ci = Components.interfaces;
|
||||
const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://devtools/skin/floating-scrollbars-responsive-design.css", null, null);
|
||||
var gRequiresFloatingScrollbars;
|
||||
"use strict";
|
||||
|
||||
var active = false;
|
||||
/* global content, docShell, addEventListener, addMessageListener,
|
||||
removeEventListener, removeMessageListener, sendAsyncMessage */
|
||||
|
||||
addMessageListener("ResponsiveMode:Start", startResponsiveMode);
|
||||
addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
|
||||
var global = this;
|
||||
|
||||
function startResponsiveMode({data:data}) {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
addMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
addMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
docShell.deviceSizeIsPageSize = true;
|
||||
gRequiresFloatingScrollbars = data.requiresFloatingScrollbars;
|
||||
|
||||
// At this point, a content viewer might not be loaded for this
|
||||
// docshell. makeScrollbarsFloating will be triggered by onLocationChange.
|
||||
if (docShell.contentViewer) {
|
||||
makeScrollbarsFloating();
|
||||
}
|
||||
active = true;
|
||||
sendAsyncMessage("ResponsiveMode:Start:Done");
|
||||
}
|
||||
|
||||
function notifiyOnResize() {
|
||||
content.addEventListener("resize", () => {
|
||||
sendAsyncMessage("ResponsiveMode:OnContentResize");
|
||||
}, false);
|
||||
sendAsyncMessage("ResponsiveMode:NotifyOnResize:Done");
|
||||
}
|
||||
|
||||
function stopResponsiveMode() {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
active = false;
|
||||
removeMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
removeMessageListener("ResponsiveMode:NotifyOnResize", notifiyOnResize);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
restoreScrollbars();
|
||||
sendAsyncMessage("ResponsiveMode:Stop:Done");
|
||||
}
|
||||
|
||||
function makeScrollbarsFloating() {
|
||||
if (!gRequiresFloatingScrollbars) {
|
||||
// Guard against loading this frame script mutiple times
|
||||
(function() {
|
||||
if (global.responsiveFrameScriptLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
let allDocShells = [docShell];
|
||||
var Ci = Components.interfaces;
|
||||
const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://devtools/skin/floating-scrollbars-responsive-design.css", null, null);
|
||||
var gRequiresFloatingScrollbars;
|
||||
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
let child = docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell);
|
||||
allDocShells.push(child);
|
||||
var active = false;
|
||||
var resizeNotifications = false;
|
||||
|
||||
addMessageListener("ResponsiveMode:Start", startResponsiveMode);
|
||||
addMessageListener("ResponsiveMode:Stop", stopResponsiveMode);
|
||||
|
||||
function debug(msg) {
|
||||
// dump(`RDM CHILD: ${msg}\n`);
|
||||
}
|
||||
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScrollbars() {
|
||||
let allDocShells = [docShell];
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
allDocShells.push(docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell));
|
||||
}
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function flushStyle() {
|
||||
// Force presContext destruction
|
||||
let isSticky = docShell.contentViewer.sticky;
|
||||
docShell.contentViewer.sticky = false;
|
||||
docShell.contentViewer.hide();
|
||||
docShell.contentViewer.show();
|
||||
docShell.contentViewer.sticky = isSticky;
|
||||
}
|
||||
|
||||
function screenshot() {
|
||||
let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let width = content.innerWidth;
|
||||
let height = content.innerHeight;
|
||||
canvas.mozOpaque = true;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(content, content.scrollX, content.scrollY, width, height, "#fff");
|
||||
sendAsyncMessage("ResponsiveMode:RequestScreenshot:Done", canvas.toDataURL());
|
||||
}
|
||||
|
||||
var WebProgressListener = {
|
||||
onLocationChange(webProgress, request, URI, flags) {
|
||||
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
|
||||
function startResponsiveMode({data:data}) {
|
||||
debug("START");
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
aIID.equals(Ci.nsISupportsWeakReference) ||
|
||||
aIID.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
addMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
docShell.deviceSizeIsPageSize = true;
|
||||
gRequiresFloatingScrollbars = data.requiresFloatingScrollbars;
|
||||
if (data.notifyOnResize) {
|
||||
startOnResize();
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
// At this point, a content viewer might not be loaded for this
|
||||
// docshell. makeScrollbarsFloating will be triggered by onLocationChange.
|
||||
if (docShell.contentViewer) {
|
||||
makeScrollbarsFloating();
|
||||
}
|
||||
active = true;
|
||||
sendAsyncMessage("ResponsiveMode:Start:Done");
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
let { width, height } = content.screen;
|
||||
debug(`EMIT RESIZE: ${width} x ${height}`);
|
||||
sendAsyncMessage("ResponsiveMode:OnContentResize", {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
}
|
||||
|
||||
function bindOnResize() {
|
||||
content.addEventListener("resize", onResize, false);
|
||||
}
|
||||
|
||||
function startOnResize() {
|
||||
debug("START ON RESIZE");
|
||||
if (resizeNotifications) {
|
||||
return;
|
||||
}
|
||||
resizeNotifications = true;
|
||||
bindOnResize();
|
||||
addEventListener("DOMWindowCreated", bindOnResize, false);
|
||||
}
|
||||
|
||||
function stopOnResize() {
|
||||
debug("STOP ON RESIZE");
|
||||
if (!resizeNotifications) {
|
||||
return;
|
||||
}
|
||||
resizeNotifications = false;
|
||||
content.removeEventListener("resize", onResize, false);
|
||||
removeEventListener("DOMWindowCreated", bindOnResize, false);
|
||||
}
|
||||
|
||||
function stopResponsiveMode() {
|
||||
debug("STOP");
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
active = false;
|
||||
removeMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
restoreScrollbars();
|
||||
stopOnResize();
|
||||
sendAsyncMessage("ResponsiveMode:Stop:Done");
|
||||
}
|
||||
|
||||
function makeScrollbarsFloating() {
|
||||
if (!gRequiresFloatingScrollbars) {
|
||||
return;
|
||||
}
|
||||
|
||||
let allDocShells = [docShell];
|
||||
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
let child = docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell);
|
||||
allDocShells.push(child);
|
||||
}
|
||||
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.loadSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScrollbars() {
|
||||
let allDocShells = [docShell];
|
||||
for (let i = 0; i < docShell.childCount; i++) {
|
||||
allDocShells.push(docShell.getChildAt(i).QueryInterface(Ci.nsIDocShell));
|
||||
}
|
||||
for (let d of allDocShells) {
|
||||
let win = d.contentViewer.DOMDocument.defaultView;
|
||||
let winUtils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
try {
|
||||
winUtils.removeSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch(e) { }
|
||||
}
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function flushStyle() {
|
||||
// Force presContext destruction
|
||||
let isSticky = docShell.contentViewer.sticky;
|
||||
docShell.contentViewer.sticky = false;
|
||||
docShell.contentViewer.hide();
|
||||
docShell.contentViewer.show();
|
||||
docShell.contentViewer.sticky = isSticky;
|
||||
}
|
||||
|
||||
function screenshot() {
|
||||
let canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
let width = content.innerWidth;
|
||||
let height = content.innerHeight;
|
||||
canvas.mozOpaque = true;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
let ctx = canvas.getContext("2d");
|
||||
ctx.drawWindow(content, content.scrollX, content.scrollY, width, height, "#fff");
|
||||
sendAsyncMessage("ResponsiveMode:RequestScreenshot:Done", canvas.toDataURL());
|
||||
}
|
||||
|
||||
var WebProgressListener = {
|
||||
onLocationChange(webProgress, request, URI, flags) {
|
||||
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
|
||||
return;
|
||||
}
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
aIID.equals(Ci.nsISupportsWeakReference) ||
|
||||
aIID.equals(Ci.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
global.responsiveFrameScriptLoaded = true;
|
||||
sendAsyncMessage("ResponsiveMode:ChildScriptReady");
|
||||
|
@ -21,6 +21,7 @@ var { showDoorhanger } = require("devtools/client/shared/doorhanger");
|
||||
var { TouchEventSimulator } = require("devtools/shared/touch/simulator");
|
||||
var { Task } = require("resource://gre/modules/Task.jsm");
|
||||
var promise = require("promise");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ResponsiveUIManager"];
|
||||
|
||||
@ -37,6 +38,10 @@ const INPUT_PARSER = /(\d+)[^\d]+(\d+)/;
|
||||
|
||||
const SHARED_L10N = new ViewHelpers.L10N("chrome://devtools/locale/shared.properties");
|
||||
|
||||
function debug(msg) {
|
||||
// dump(`RDM UI: ${msg}\n`);
|
||||
}
|
||||
|
||||
var ActiveTabs = new Map();
|
||||
|
||||
var Manager = {
|
||||
@ -92,25 +97,27 @@ var Manager = {
|
||||
* @param aCommand the command name.
|
||||
* @param aArgs command arguments.
|
||||
*/
|
||||
handleGcliCommand: function(aWindow, aTab, aCommand, aArgs) {
|
||||
handleGcliCommand: Task.async(function*(aWindow, aTab, aCommand, aArgs) {
|
||||
switch (aCommand) {
|
||||
case "resize to":
|
||||
this.runIfNeeded(aWindow, aTab);
|
||||
ActiveTabs.get(aTab).setSize(aArgs.width, aArgs.height);
|
||||
let ui = ActiveTabs.get(aTab);
|
||||
yield ui.inited;
|
||||
ui.setSize(aArgs.width, aArgs.height);
|
||||
break;
|
||||
case "resize on":
|
||||
this.runIfNeeded(aWindow, aTab);
|
||||
break;
|
||||
case "resize off":
|
||||
if (this.isActiveForTab(aTab)) {
|
||||
ActiveTabs.get(aTab).close();
|
||||
yield ActiveTabs.get(aTab).close();
|
||||
}
|
||||
break;
|
||||
case "resize toggle":
|
||||
this.toggle(aWindow, aTab);
|
||||
this.toggle(aWindow, aTab);
|
||||
default:
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
EventEmitter.decorate(Manager);
|
||||
@ -126,7 +133,7 @@ if (Services.prefs.getBoolPref("devtools.responsive.html.enabled")) {
|
||||
this.ResponsiveUIManager = Manager;
|
||||
}
|
||||
|
||||
var presets = [
|
||||
var defaultPresets = [
|
||||
// Phones
|
||||
{key: "320x480", width: 320, height: 480}, // iPhone, B2G, with <meta viewport>
|
||||
{key: "360x640", width: 360, height: 640}, // Android 4, phones, with <meta viewport>
|
||||
@ -155,59 +162,6 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.stack = this.container.querySelector(".browserStack");
|
||||
this._telemetry = new Telemetry();
|
||||
|
||||
let childOn = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Start:Done", childOn);
|
||||
|
||||
let requiresFloatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
this.mm.loadFrameScript("resource://devtools/client/responsivedesign/responsivedesign-child.js", true);
|
||||
this.mm.addMessageListener("ResponsiveMode:ChildScriptReady", () => {
|
||||
this.mm.sendAsyncMessage("ResponsiveMode:Start", {
|
||||
requiresFloatingScrollbars: requiresFloatingScrollbars
|
||||
});
|
||||
});
|
||||
|
||||
// Try to load presets from prefs
|
||||
if (Services.prefs.prefHasUserValue("devtools.responsiveUI.presets")) {
|
||||
try {
|
||||
presets = JSON.parse(Services.prefs.getCharPref("devtools.responsiveUI.presets"));
|
||||
} catch(e) {
|
||||
// User pref is malformated.
|
||||
Cu.reportError("Could not parse pref `devtools.responsiveUI.presets`: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.customPreset = {key: "custom", custom: true};
|
||||
|
||||
if (Array.isArray(presets)) {
|
||||
this.presets = [this.customPreset].concat(presets);
|
||||
} else {
|
||||
Cu.reportError("Presets value (devtools.responsiveUI.presets) is malformated.");
|
||||
this.presets = [this.customPreset];
|
||||
}
|
||||
|
||||
try {
|
||||
let width = Services.prefs.getIntPref("devtools.responsiveUI.customWidth");
|
||||
let height = Services.prefs.getIntPref("devtools.responsiveUI.customHeight");
|
||||
this.customPreset.width = Math.min(MAX_WIDTH, width);
|
||||
this.customPreset.height = Math.min(MAX_HEIGHT, height);
|
||||
|
||||
this.currentPresetKey = Services.prefs.getCharPref("devtools.responsiveUI.currentPreset");
|
||||
} catch(e) {
|
||||
// Default size. The first preset (custom) is the one that will be used.
|
||||
let bbox = this.stack.getBoundingClientRect();
|
||||
|
||||
this.customPreset.width = bbox.width - 40; // horizontal padding of the container
|
||||
this.customPreset.height = bbox.height - 80; // vertical padding + toolbar height
|
||||
|
||||
this.currentPresetKey = this.presets[1].key; // most common preset
|
||||
}
|
||||
|
||||
this.container.setAttribute("responsivemode", "true");
|
||||
this.stack.setAttribute("responsivemode", "true");
|
||||
|
||||
// Let's bind some callbacks.
|
||||
this.bound_presetSelected = this.presetSelected.bind(this);
|
||||
this.bound_handleManualInput = this.handleManualInput.bind(this);
|
||||
@ -220,34 +174,14 @@ function ResponsiveUI(aWindow, aTab)
|
||||
this.bound_startResizing = this.startResizing.bind(this);
|
||||
this.bound_stopResizing = this.stopResizing.bind(this);
|
||||
this.bound_onDrag = this.onDrag.bind(this);
|
||||
this.bound_onContentResize = this.onContentResize.bind(this);
|
||||
|
||||
// Events
|
||||
this.tab.addEventListener("TabClose", this);
|
||||
this.tabContainer.addEventListener("TabSelect", this);
|
||||
this.mm.addMessageListener("ResponsiveMode:OnContentResize",
|
||||
this.bound_onContentResize);
|
||||
|
||||
this.buildUI();
|
||||
this.checkMenus();
|
||||
ActiveTabs.set(this.tab, this);
|
||||
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
|
||||
this.rotate();
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
ActiveTabs.set(aTab, this);
|
||||
|
||||
this._telemetry.toolOpened("responsive");
|
||||
|
||||
// Touch events support
|
||||
this.touchEnableBefore = false;
|
||||
this.touchEventSimulator = new TouchEventSimulator(this.browser);
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger. Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
type: "deveditionpromo",
|
||||
anchor: this.chromeDoc.querySelector("#content")
|
||||
});
|
||||
this.inited = this.init();
|
||||
}
|
||||
|
||||
ResponsiveUI.prototype = {
|
||||
@ -264,22 +198,131 @@ ResponsiveUI.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
init: Task.async(function*() {
|
||||
debug("INIT BEGINS");
|
||||
|
||||
let ready = this.waitForMessage("ResponsiveMode:ChildScriptReady");
|
||||
this.mm.loadFrameScript("resource://devtools/client/responsivedesign/responsivedesign-child.js", true);
|
||||
yield ready;
|
||||
|
||||
let requiresFloatingScrollbars =
|
||||
!this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
let started = this.waitForMessage("ResponsiveMode:Start:Done");
|
||||
debug("SEND START");
|
||||
this.mm.sendAsyncMessage("ResponsiveMode:Start", {
|
||||
requiresFloatingScrollbars,
|
||||
// Tests expect events on resize to yield on various size changes
|
||||
notifyOnResize: DevToolsUtils.testing,
|
||||
});
|
||||
yield started;
|
||||
|
||||
// Load Presets
|
||||
this.loadPresets();
|
||||
|
||||
// Events
|
||||
this.tab.addEventListener("TabClose", this);
|
||||
this.tabContainer.addEventListener("TabSelect", this);
|
||||
|
||||
// Setup the UI
|
||||
this.container.setAttribute("responsivemode", "true");
|
||||
this.stack.setAttribute("responsivemode", "true");
|
||||
this.buildUI();
|
||||
this.checkMenus();
|
||||
|
||||
// Rotate the responsive mode if needed
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("devtools.responsiveUI.rotate")) {
|
||||
this.rotate();
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
// Touch events support
|
||||
this.touchEnableBefore = false;
|
||||
this.touchEventSimulator = new TouchEventSimulator(this.browser);
|
||||
|
||||
// Hook to display promotional Developer Edition doorhanger.
|
||||
// Only displayed once.
|
||||
showDoorhanger({
|
||||
window: this.mainWindow,
|
||||
type: "deveditionpromo",
|
||||
anchor: this.chromeDoc.querySelector("#content")
|
||||
});
|
||||
|
||||
// Notify that responsive mode is on.
|
||||
this._telemetry.toolOpened("responsive");
|
||||
ResponsiveUIManager.emit("on", { tab: this.tab });
|
||||
}),
|
||||
|
||||
loadPresets: function() {
|
||||
// Try to load presets from prefs
|
||||
let presets = defaultPresets;
|
||||
if (Services.prefs.prefHasUserValue("devtools.responsiveUI.presets")) {
|
||||
try {
|
||||
presets = JSON.parse(Services.prefs.getCharPref("devtools.responsiveUI.presets"));
|
||||
} catch(e) {
|
||||
// User pref is malformated.
|
||||
Cu.reportError("Could not parse pref `devtools.responsiveUI.presets`: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.customPreset = {key: "custom", custom: true};
|
||||
|
||||
if (Array.isArray(presets)) {
|
||||
this.presets = [this.customPreset].concat(presets);
|
||||
} else {
|
||||
Cu.reportError("Presets value (devtools.responsiveUI.presets) is malformated.");
|
||||
this.presets = [this.customPreset];
|
||||
}
|
||||
|
||||
try {
|
||||
let width = Services.prefs.getIntPref("devtools.responsiveUI.customWidth");
|
||||
let height = Services.prefs.getIntPref("devtools.responsiveUI.customHeight");
|
||||
this.customPreset.width = Math.min(MAX_WIDTH, width);
|
||||
this.customPreset.height = Math.min(MAX_HEIGHT, height);
|
||||
|
||||
this.currentPresetKey = Services.prefs.getCharPref("devtools.responsiveUI.currentPreset");
|
||||
} catch(e) {
|
||||
// Default size. The first preset (custom) is the one that will be used.
|
||||
let bbox = this.stack.getBoundingClientRect();
|
||||
|
||||
this.customPreset.width = bbox.width - 40; // horizontal padding of the container
|
||||
this.customPreset.height = bbox.height - 80; // vertical padding + toolbar height
|
||||
|
||||
this.currentPresetKey = this.presets[1].key; // most common preset
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy the nodes. Remove listeners. Reset the style.
|
||||
*/
|
||||
close: function RUI_close() {
|
||||
if (this.closing)
|
||||
close: Task.async(function*() {
|
||||
debug("CLOSE BEGINS");
|
||||
if (this.closing) {
|
||||
debug("ALREADY CLOSING, ABORT");
|
||||
return;
|
||||
}
|
||||
this.closing = true;
|
||||
|
||||
// If we're closing very fast (in tests), ensure init has finished.
|
||||
debug("CLOSE: WAIT ON INITED");
|
||||
yield this.inited;
|
||||
debug("CLOSE: INITED DONE");
|
||||
|
||||
this.unCheckMenus();
|
||||
// Reset style of the stack.
|
||||
debug(`CURRENT SIZE: ${this.stack.getAttribute("style")}`);
|
||||
let style = "max-width: none;" +
|
||||
"min-width: 0;" +
|
||||
"max-height: none;" +
|
||||
"min-height: 0;";
|
||||
debug("RESET STACK SIZE");
|
||||
this.stack.setAttribute("style", style);
|
||||
|
||||
// Wait for resize message before stopping in the child when testing
|
||||
if (DevToolsUtils.testing) {
|
||||
yield this.waitForMessage("ResponsiveMode:OnContentResize");
|
||||
}
|
||||
|
||||
if (this.isResizing)
|
||||
this.stopResizing();
|
||||
|
||||
@ -316,35 +359,33 @@ ResponsiveUI.prototype = {
|
||||
this.touchEventSimulator.stop();
|
||||
}
|
||||
this._telemetry.toolClosed("responsive");
|
||||
let childOff = () => {
|
||||
this.mm.removeMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
}
|
||||
this.mm.addMessageListener("ResponsiveMode:Stop:Done", childOff);
|
||||
let stopped = this.waitForMessage("ResponsiveMode:Stop:Done");
|
||||
this.tab.linkedBrowser.messageManager.sendAsyncMessage("ResponsiveMode:Stop");
|
||||
yield stopped;
|
||||
|
||||
this.inited = null;
|
||||
ResponsiveUIManager.emit("off", { tab: this.tab });
|
||||
}),
|
||||
|
||||
waitForMessage(message) {
|
||||
return new Promise(resolve => {
|
||||
let listener = () => {
|
||||
this.mm.removeMessageListener(message, listener);
|
||||
resolve();
|
||||
};
|
||||
this.mm.addMessageListener(message, listener);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Notify when the content has been resized. Only used in tests.
|
||||
* Emit an event when the content has been resized. Only used in tests.
|
||||
*/
|
||||
_test_notifyOnResize: function() {
|
||||
let deferred = promise.defer();
|
||||
let mm = this.mm;
|
||||
|
||||
this.bound_onContentResize = this.onContentResize.bind(this);
|
||||
|
||||
mm.addMessageListener("ResponsiveMode:OnContentResize", this.bound_onContentResize);
|
||||
|
||||
mm.sendAsyncMessage("ResponsiveMode:NotifyOnResize");
|
||||
mm.addMessageListener("ResponsiveMode:NotifyOnResize:Done", function onListeningResize() {
|
||||
mm.removeMessageListener("ResponsiveMode:NotifyOnResize:Done", onListeningResize);
|
||||
deferred.resolve();
|
||||
onContentResize: function(msg) {
|
||||
ResponsiveUIManager.emit("contentResize", {
|
||||
tab: this.tab,
|
||||
width: msg.data.width,
|
||||
height: msg.data.height,
|
||||
});
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
onContentResize: function() {
|
||||
ResponsiveUIManager.emit("contentResize", { tab: this.tab });
|
||||
},
|
||||
|
||||
/**
|
||||
@ -863,6 +904,18 @@ ResponsiveUI.prototype = {
|
||||
}
|
||||
}),
|
||||
|
||||
/**
|
||||
* Get the current width and height.
|
||||
*/
|
||||
getSize() {
|
||||
let width = Number(this.stack.style.minWidth.replace("px", ""));
|
||||
let height = Number(this.stack.style.minHeight.replace("px", ""));
|
||||
return {
|
||||
width,
|
||||
height,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the size of the browser.
|
||||
*
|
||||
@ -870,6 +923,7 @@ ResponsiveUI.prototype = {
|
||||
* @param aHeight height of the browser.
|
||||
*/
|
||||
setSize: function RUI_setSize(aWidth, aHeight) {
|
||||
debug(`SET SIZE TO ${aWidth} x ${aHeight}`);
|
||||
this.setWidth(aWidth);
|
||||
this.setHeight(aHeight);
|
||||
},
|
||||
|
@ -11,6 +11,9 @@
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("destroy");
|
||||
|
||||
function test() {
|
||||
let manager = ResponsiveUI.ResponsiveUIManager;
|
||||
let done;
|
||||
|
||||
function isOpen() {
|
||||
return gBrowser.getBrowserContainer(gBrowser.selectedBrowser)
|
||||
.hasAttribute("responsivemode");
|
||||
@ -19,7 +22,10 @@ function test() {
|
||||
helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", (options) => {
|
||||
return helpers.audit(options, [
|
||||
{
|
||||
setup: "resize toggle",
|
||||
setup() {
|
||||
done = once(manager, "on");
|
||||
return helpers.setInput(options, "resize toggle");
|
||||
},
|
||||
check: {
|
||||
input: "resize toggle",
|
||||
hints: "",
|
||||
@ -29,12 +35,16 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(isOpen(), "responsive mode is open");
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
setup: "resize toggle",
|
||||
setup() {
|
||||
done = once(manager, "off");
|
||||
return helpers.setInput(options, "resize toggle");
|
||||
},
|
||||
check: {
|
||||
input: "resize toggle",
|
||||
hints: "",
|
||||
@ -44,12 +54,16 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(!isOpen(), "responsive mode is closed");
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
setup: "resize on",
|
||||
setup() {
|
||||
done = once(manager, "on");
|
||||
return helpers.setInput(options, "resize on");
|
||||
},
|
||||
check: {
|
||||
input: "resize on",
|
||||
hints: "",
|
||||
@ -59,12 +73,16 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(isOpen(), "responsive mode is open");
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
setup: "resize off",
|
||||
setup() {
|
||||
done = once(manager, "off");
|
||||
return helpers.setInput(options, "resize off");
|
||||
},
|
||||
check: {
|
||||
input: "resize off",
|
||||
hints: "",
|
||||
@ -74,12 +92,16 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(!isOpen(), "responsive mode is closed");
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
setup: "resize to 400 400",
|
||||
setup() {
|
||||
done = once(manager, "on");
|
||||
return helpers.setInput(options, "resize to 400 400");
|
||||
},
|
||||
check: {
|
||||
input: "resize to 400 400",
|
||||
hints: "",
|
||||
@ -93,12 +115,16 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(isOpen(), "responsive mode is open");
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
setup: "resize off",
|
||||
setup() {
|
||||
done = once(manager, "off");
|
||||
return helpers.setInput(options, "resize off");
|
||||
},
|
||||
check: {
|
||||
input: "resize off",
|
||||
hints: "",
|
||||
@ -108,9 +134,10 @@ function test() {
|
||||
exec: {
|
||||
output: ""
|
||||
},
|
||||
post: function() {
|
||||
post: Task.async(function*() {
|
||||
yield done;
|
||||
ok(!isOpen(), "responsive mode is closed");
|
||||
},
|
||||
}),
|
||||
},
|
||||
]);
|
||||
}).then(finish);
|
||||
|
@ -5,15 +5,15 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(function*() {
|
||||
let tab = yield addTab("about:logo");
|
||||
let {rdm} = yield openRDM(tab);
|
||||
let { rdm, manager } = yield openRDM(tab);
|
||||
ok(rdm, "An instance of the RDM should be attached to the tab.");
|
||||
rdm.setSize(110, 500);
|
||||
yield setSize(rdm, manager, 110, 500);
|
||||
|
||||
info("Checking initial width/height properties.");
|
||||
yield doInitialChecks();
|
||||
|
||||
info("Changing the RDM size");
|
||||
rdm.setSize(90, 500);
|
||||
yield setSize(rdm, manager, 90, 500);
|
||||
|
||||
info("Checking for screen props");
|
||||
yield checkScreenProps();
|
||||
|
@ -22,36 +22,36 @@ add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
||||
info("Open the responsive design mode and set its size to 500x500 to start");
|
||||
let {rdm} = yield openRDM();
|
||||
rdm.setSize(500, 500);
|
||||
let { rdm, manager } = yield openRDM();
|
||||
yield setSize(rdm, manager, 500, 500);
|
||||
|
||||
info("Open the inspector, computed-view and select the test node");
|
||||
let {inspector, view} = yield openComputedView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
info("Try shrinking the viewport and checking the applied styles");
|
||||
yield testShrink(view, inspector, rdm);
|
||||
yield testShrink(view, inspector, rdm, manager);
|
||||
|
||||
info("Try growing the viewport and checking the applied styles");
|
||||
yield testGrow(view, inspector, rdm);
|
||||
yield testGrow(view, inspector, rdm, manager);
|
||||
|
||||
yield closeRDM(rdm);
|
||||
yield closeToolbox();
|
||||
});
|
||||
|
||||
function* testShrink(computedView, inspector, rdm) {
|
||||
function* testShrink(computedView, inspector, rdm, manager) {
|
||||
is(computedWidth(computedView), "500px", "Should show 500px initially.");
|
||||
|
||||
let onRefresh = inspector.once("computed-view-refreshed");
|
||||
rdm.setSize(100, 100);
|
||||
yield setSize(rdm, manager, 100, 100);
|
||||
yield onRefresh;
|
||||
|
||||
is(computedWidth(computedView), "100px", "Should be 100px after shrinking.");
|
||||
}
|
||||
|
||||
function* testGrow(computedView, inspector, rdm) {
|
||||
function* testGrow(computedView, inspector, rdm, manager) {
|
||||
let onRefresh = inspector.once("computed-view-refreshed");
|
||||
rdm.setSize(500, 500);
|
||||
yield setSize(rdm, manager, 500, 500);
|
||||
yield onRefresh;
|
||||
|
||||
is(computedWidth(computedView), "500px", "Should be 500px after growing.");
|
||||
|
@ -25,18 +25,18 @@ add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
||||
info("Open the responsive design mode and set its size to 500x500 to start");
|
||||
let {rdm} = yield openRDM();
|
||||
rdm.setSize(500, 500);
|
||||
let { rdm, manager } = yield openRDM();
|
||||
yield setSize(rdm, manager, 500, 500);
|
||||
|
||||
info("Open the inspector, rule-view and select the test node");
|
||||
let {inspector, view} = yield openRuleView();
|
||||
yield selectNode("div", inspector);
|
||||
|
||||
info("Try shrinking the viewport and checking the applied styles");
|
||||
yield testShrink(view, rdm);
|
||||
yield testShrink(view, rdm, manager);
|
||||
|
||||
info("Try growing the viewport and checking the applied styles");
|
||||
yield testGrow(view, rdm);
|
||||
yield testGrow(view, rdm, manager);
|
||||
|
||||
info("Check that ESC still opens the split console");
|
||||
yield testEscapeOpensSplitConsole(inspector);
|
||||
@ -49,21 +49,21 @@ add_task(function*() {
|
||||
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
|
||||
});
|
||||
|
||||
function* testShrink(ruleView, rdm) {
|
||||
function* testShrink(ruleView, rdm, manager) {
|
||||
is(numberOfRules(ruleView), 2, "Should have two rules initially.");
|
||||
|
||||
info("Resize to 100x100 and wait for the rule-view to update");
|
||||
let onRefresh = ruleView.once("ruleview-refreshed");
|
||||
rdm.setSize(100, 100);
|
||||
yield setSize(rdm, manager, 100, 100);
|
||||
yield onRefresh;
|
||||
|
||||
is(numberOfRules(ruleView), 3, "Should have three rules after shrinking.");
|
||||
}
|
||||
|
||||
function* testGrow(ruleView, rdm) {
|
||||
function* testGrow(ruleView, rdm, manager) {
|
||||
info("Resize to 500x500 and wait for the rule-view to update");
|
||||
let onRefresh = ruleView.once("ruleview-refreshed");
|
||||
rdm.setSize(500, 500);
|
||||
yield setSize(rdm, manager, 500, 500);
|
||||
yield onRefresh;
|
||||
|
||||
is(numberOfRules(ruleView), 2, "Should have two rules after growing.");
|
||||
|
@ -4,7 +4,6 @@
|
||||
"use strict";
|
||||
|
||||
add_task(function*() {
|
||||
SimpleTest.requestCompleteLog();
|
||||
let tab = yield addTab("data:text/html,mop");
|
||||
|
||||
let {rdm, manager} = yield openRDM(tab, "menu");
|
||||
@ -26,9 +25,6 @@ add_task(function*() {
|
||||
let newWidth = (yield getSizing()).width;
|
||||
is(originalWidth, newWidth, "Floating scrollbars shouldn't change the width");
|
||||
|
||||
yield rdm._test_notifyOnResize();
|
||||
yield waitForTick();
|
||||
|
||||
yield testPresets(rdm, manager);
|
||||
|
||||
info("Testing mouse resizing");
|
||||
@ -53,7 +49,10 @@ add_task(function*() {
|
||||
|
||||
info("Restarting responsive mode");
|
||||
yield closeRDM(rdm);
|
||||
|
||||
let resized = waitForResizeTo(manager, widthBeforeClose, heightBeforeClose);
|
||||
({rdm} = yield openRDM(tab, "keyboard"));
|
||||
yield resized;
|
||||
|
||||
let currentSize = yield getSizing();
|
||||
is(currentSize.width, widthBeforeClose, "width should be restored");
|
||||
@ -80,9 +79,7 @@ function* testPresets(rdm, manager) {
|
||||
for (let c = rdm.menulist.firstChild.childNodes.length - 4; c >= 0; c--) {
|
||||
let item = rdm.menulist.firstChild.childNodes[c];
|
||||
let [width, height] = extractSizeFromString(item.getAttribute("label"));
|
||||
let onContentResize = once(manager, "contentResize");
|
||||
rdm.menulist.selectedIndex = c;
|
||||
yield onContentResize;
|
||||
yield setPresetIndex(rdm, manager, c);
|
||||
|
||||
let {width: contentWidth, height: contentHeight} = yield getSizing();
|
||||
is(contentWidth, width, "preset" + c + ": the width should be changed");
|
||||
@ -91,8 +88,7 @@ function* testPresets(rdm, manager) {
|
||||
}
|
||||
|
||||
function* testManualMouseResize(rdm, manager, pressedKey) {
|
||||
rdm.setSize(100, 100);
|
||||
yield once(manager, "contentResize");
|
||||
yield setSize(rdm, manager, 100, 100);
|
||||
|
||||
let {width: initialWidth, height: initialHeight} = yield getSizing();
|
||||
is(initialWidth, 100, "Width should be reset to 100");
|
||||
@ -171,8 +167,7 @@ function* testInvalidUserInput(rdm) {
|
||||
}
|
||||
|
||||
function* testRotate(rdm, manager) {
|
||||
rdm.setSize(100, 200);
|
||||
yield once(manager, "contentResize");
|
||||
yield setSize(rdm, manager, 100, 200);
|
||||
|
||||
let {width: initialWidth, height: initialHeight} = yield getSizing();
|
||||
rdm.rotate();
|
||||
|
@ -6,7 +6,7 @@
|
||||
add_task(function*() {
|
||||
let tab = yield addTab("data:text/html;charset=utf8,Test RDM custom presets");
|
||||
|
||||
let {rdm} = yield openRDM(tab);
|
||||
let { rdm, manager } = yield openRDM(tab);
|
||||
|
||||
let oldPrompt = Services.prompt;
|
||||
Services.prompt = {
|
||||
@ -29,8 +29,6 @@ add_task(function*() {
|
||||
|
||||
ok(rdm, "RDM instance should be attached to the tab.");
|
||||
|
||||
yield rdm._test_notifyOnResize();
|
||||
|
||||
// Tries to add a custom preset and cancel the prompt
|
||||
let idx = rdm.menulist.selectedIndex;
|
||||
let presetCount = rdm.presets.length;
|
||||
@ -48,35 +46,27 @@ add_task(function*() {
|
||||
Services.prompt.value = "Testing preset";
|
||||
Services.prompt.returnBool = true;
|
||||
|
||||
let resized = once(manager, "contentResize");
|
||||
let customHeight = 123, customWidth = 456;
|
||||
rdm.startResizing({});
|
||||
rdm.setSize(customWidth, customHeight);
|
||||
rdm.stopResizing({});
|
||||
|
||||
rdm.addbutton.doCommand();
|
||||
|
||||
// Force document reflow to avoid intermittent failures.
|
||||
info("document height " + document.height);
|
||||
yield resized;
|
||||
|
||||
yield closeRDM(rdm);
|
||||
|
||||
// We're still in the loop of initializing the responsive mode.
|
||||
// Let's wait next loop to stop it.
|
||||
yield waitForTick();
|
||||
|
||||
({rdm} = yield openRDM(tab));
|
||||
is(container.getAttribute("responsivemode"), "true",
|
||||
"Should be in responsive mode.");
|
||||
|
||||
let presetLabel = "456" + "\u00D7" + "123 (Testing preset)";
|
||||
let customPresetIndex = getPresetIndex(rdm, presetLabel);
|
||||
info(customPresetIndex);
|
||||
let customPresetIndex = yield getPresetIndex(rdm, manager, presetLabel);
|
||||
ok(customPresetIndex >= 0, "(idx = " + customPresetIndex + ") should be the" +
|
||||
" previously added preset in the list of items");
|
||||
|
||||
let resizePromise = rdm._test_notifyOnResize();
|
||||
rdm.menulist.selectedIndex = customPresetIndex;
|
||||
yield resizePromise;
|
||||
yield setPresetIndex(rdm, manager, customPresetIndex);
|
||||
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
let props = yield ContentTask.spawn(browser, {}, function*() {
|
||||
@ -87,43 +77,44 @@ add_task(function*() {
|
||||
is(props.innerWidth, 456, "Selecting preset should change the width");
|
||||
is(props.innerHeight, 123, "Selecting preset should change the height");
|
||||
|
||||
info(`menulist count: ${rdm.menulist.itemCount}`)
|
||||
|
||||
rdm.removebutton.doCommand();
|
||||
|
||||
rdm.menulist.selectedIndex = 2;
|
||||
yield setPresetIndex(rdm, manager, 2);
|
||||
let deletedPresetA = rdm.menulist.selectedItem.getAttribute("label");
|
||||
rdm.removebutton.doCommand();
|
||||
|
||||
rdm.menulist.selectedIndex = 2;
|
||||
yield setPresetIndex(rdm, manager, 2);
|
||||
let deletedPresetB = rdm.menulist.selectedItem.getAttribute("label");
|
||||
rdm.removebutton.doCommand();
|
||||
|
||||
yield closeRDM(rdm);
|
||||
yield waitForTick();
|
||||
({rdm} = yield openRDM(tab));
|
||||
|
||||
customPresetIndex = getPresetIndex(rdm, deletedPresetA);
|
||||
customPresetIndex = yield getPresetIndex(rdm, manager, deletedPresetA);
|
||||
is(customPresetIndex, -1,
|
||||
"Deleted preset " + deletedPresetA + " should not be in the list anymore");
|
||||
|
||||
customPresetIndex = getPresetIndex(rdm, deletedPresetB);
|
||||
customPresetIndex = yield getPresetIndex(rdm, manager, deletedPresetB);
|
||||
is(customPresetIndex, -1,
|
||||
"Deleted preset " + deletedPresetB + " should not be in the list anymore");
|
||||
|
||||
yield closeRDM(rdm);
|
||||
});
|
||||
|
||||
function getPresetIndex(rdm, presetLabel) {
|
||||
function testOnePreset(c) {
|
||||
var getPresetIndex = Task.async(function*(rdm, manager, presetLabel) {
|
||||
var testOnePreset = Task.async(function*(c) {
|
||||
if (c == 0) {
|
||||
return -1;
|
||||
}
|
||||
rdm.menulist.selectedIndex = c;
|
||||
yield setPresetIndex(rdm, manager, c);
|
||||
|
||||
let item = rdm.menulist.firstChild.childNodes[c];
|
||||
if (item.getAttribute("label") === presetLabel) {
|
||||
return c;
|
||||
}
|
||||
return testOnePreset(c - 1);
|
||||
}
|
||||
});
|
||||
return testOnePreset(rdm.menulist.firstChild.childNodes.length - 4);
|
||||
}
|
||||
});
|
||||
|
@ -15,11 +15,15 @@ Services.scriptloader.loadSubScript(gcliHelpersURI, this);
|
||||
DevToolsUtils.testing = true;
|
||||
registerCleanupFunction(() => {
|
||||
DevToolsUtils.testing = false;
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
Services.prefs.clearUserPref("devtools.responsiveUI.currentPreset");
|
||||
Services.prefs.clearUserPref("devtools.responsiveUI.customHeight");
|
||||
Services.prefs.clearUserPref("devtools.responsiveUI.customWidth");
|
||||
Services.prefs.clearUserPref("devtools.responsiveUI.presets");
|
||||
Services.prefs.clearUserPref("devtools.responsiveUI.rotate");
|
||||
});
|
||||
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
/**
|
||||
* Open the Responsive Design Mode
|
||||
* @param {Tab} The browser tab to open it into (defaults to the selected tab).
|
||||
@ -29,19 +33,26 @@ registerCleanupFunction(() => {
|
||||
var openRDM = Task.async(function*(tab = gBrowser.selectedTab,
|
||||
method = "menu") {
|
||||
let manager = ResponsiveUI.ResponsiveUIManager;
|
||||
let mgrOn = once(manager, "on");
|
||||
|
||||
let opened = once(manager, "on");
|
||||
let resized = once(manager, "contentResize");
|
||||
if (method == "menu") {
|
||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
||||
} else {
|
||||
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
|
||||
}
|
||||
yield mgrOn;
|
||||
yield opened;
|
||||
|
||||
let rdm = manager.getResponsiveUIForTab(tab);
|
||||
rdm.transitionsEnabled = false;
|
||||
registerCleanupFunction(() => {
|
||||
rdm.transitionsEnabled = true;
|
||||
});
|
||||
|
||||
// Wait for content to resize. This is triggered async by the preset menu
|
||||
// auto-selecting its default entry once it's in the document.
|
||||
yield resized;
|
||||
|
||||
return {rdm, manager};
|
||||
});
|
||||
|
||||
@ -50,13 +61,15 @@ var openRDM = Task.async(function*(tab = gBrowser.selectedTab,
|
||||
* @param {rdm} ResponsiveUI instance for the tab
|
||||
*/
|
||||
var closeRDM = Task.async(function*(rdm) {
|
||||
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||
let manager = ResponsiveUI.ResponsiveUIManager;
|
||||
if (!rdm) {
|
||||
rdm = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
rdm = manager.getResponsiveUIForTab(gBrowser.selectedTab);
|
||||
}
|
||||
let mgrOff = mgr.once("off");
|
||||
let closed = once(manager, "off");
|
||||
let resized = once(manager, "contentResize");
|
||||
rdm.close();
|
||||
yield mgrOff;
|
||||
yield resized;
|
||||
yield closed;
|
||||
});
|
||||
|
||||
/**
|
||||
@ -252,3 +265,38 @@ var selectNode = Task.async(function*(selector, inspector, reason = "test") {
|
||||
inspector.selection.setNodeFront(nodeFront, reason);
|
||||
yield updated;
|
||||
});
|
||||
|
||||
function waitForResizeTo(manager, width, height) {
|
||||
return new Promise(resolve => {
|
||||
let onResize = (_, data) => {
|
||||
if (data.width != width || data.height != height) {
|
||||
return;
|
||||
}
|
||||
manager.off("contentResize", onResize);
|
||||
info(`Got contentResize to ${width} x ${height}`);
|
||||
resolve();
|
||||
};
|
||||
info(`Waiting for contentResize to ${width} x ${height}`);
|
||||
manager.on("contentResize", onResize);
|
||||
});
|
||||
}
|
||||
|
||||
var setPresetIndex = Task.async(function*(rdm, manager, index) {
|
||||
info(`Current preset: ${rdm.menulist.selectedIndex}, change to: ${index}`);
|
||||
if (rdm.menulist.selectedIndex != index) {
|
||||
let resized = once(manager, "contentResize");
|
||||
rdm.menulist.selectedIndex = index;
|
||||
yield resized;
|
||||
}
|
||||
});
|
||||
|
||||
var setSize = Task.async(function*(rdm, manager, width, height) {
|
||||
let size = rdm.getSize();
|
||||
info(`Current size: ${size.width} x ${size.height}, ` +
|
||||
`set to: ${width} x ${height}`);
|
||||
if (size.width != width || size.height != height) {
|
||||
let resized = waitForResizeTo(manager, width, height);
|
||||
rdm.setSize(width, height);
|
||||
yield resized;
|
||||
}
|
||||
});
|
||||
|
@ -35,28 +35,30 @@ function* testButton(toolbox, Telemetry) {
|
||||
checkResults("_RESPONSIVE_", Telemetry);
|
||||
}
|
||||
|
||||
function delayedClicks(node, clicks) {
|
||||
function waitForToggle() {
|
||||
return new Promise(resolve => {
|
||||
let clicked = 0;
|
||||
|
||||
// See TOOL_DELAY for why we need setTimeout here
|
||||
setTimeout(function delayedClick() {
|
||||
info("Clicking button " + node.id);
|
||||
if (clicked >= clicks) {
|
||||
node.addEventListener("click", function listener() {
|
||||
node.removeEventListener("click", listener);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
setTimeout(delayedClick, TOOL_DELAY);
|
||||
}
|
||||
|
||||
node.click();
|
||||
clicked++;
|
||||
}, TOOL_DELAY);
|
||||
let handler = () => {
|
||||
manager.off("on", handler);
|
||||
manager.off("off", handler);
|
||||
resolve();
|
||||
};
|
||||
let manager = ResponsiveUI.ResponsiveUIManager;
|
||||
manager.on("on", handler);
|
||||
manager.on("off", handler);
|
||||
});
|
||||
}
|
||||
|
||||
var delayedClicks = Task.async(function*(node, clicks) {
|
||||
for (let i = 0; i < clicks; i++) {
|
||||
info("Clicking button " + node.id);
|
||||
let toggled = waitForToggle();
|
||||
node.click();
|
||||
yield toggled;
|
||||
// See TOOL_DELAY for why we need setTimeout here
|
||||
yield DevToolsUtils.waitForTime(TOOL_DELAY);
|
||||
}
|
||||
});
|
||||
|
||||
function checkResults(histIdFocus, Telemetry) {
|
||||
let result = Telemetry.prototype.telemetryInfo;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user