зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1569574 - Part 2: Format devtools/client/responsive/. a=automatic-formatting r=vporof
# ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D40930 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
725df6c2ff
Коммит
788820312b
|
@ -20,9 +20,18 @@ const {
|
|||
} = require("./index");
|
||||
const { post } = require("../utils/message");
|
||||
|
||||
const { addDevice, editDevice, getDevices, removeDevice } = require("devtools/client/shared/devices");
|
||||
const {
|
||||
addDevice,
|
||||
editDevice,
|
||||
getDevices,
|
||||
removeDevice,
|
||||
} = require("devtools/client/shared/devices");
|
||||
const { changeUserAgent, toggleTouchSimulation } = require("./ui");
|
||||
const { changeDevice, changePixelRatio, changeViewportAngle } = require("./viewports");
|
||||
const {
|
||||
changeDevice,
|
||||
changePixelRatio,
|
||||
changeViewportAngle,
|
||||
} = require("./viewports");
|
||||
|
||||
const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList";
|
||||
|
||||
|
@ -35,8 +44,8 @@ const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList";
|
|||
*/
|
||||
function loadPreferredDevices() {
|
||||
const preferredDevices = {
|
||||
"added": new Set(),
|
||||
"removed": new Set(),
|
||||
added: new Set(),
|
||||
removed: new Set(),
|
||||
};
|
||||
|
||||
if (Services.prefs.prefHasUserValue(DISPLAYED_DEVICES_PREF)) {
|
||||
|
@ -72,7 +81,6 @@ function updatePreferredDevices(devices) {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
// This function is only exported for testing purposes
|
||||
_loadPreferredDevices: loadPreferredDevices,
|
||||
|
||||
|
@ -175,8 +183,9 @@ module.exports = {
|
|||
}
|
||||
|
||||
const newDevice = Object.assign({}, device, {
|
||||
displayed: preferredDevices.added.has(device.name) ||
|
||||
(device.featured && !(preferredDevices.removed.has(device.name))),
|
||||
displayed:
|
||||
preferredDevices.added.has(device.name) ||
|
||||
(device.featured && !preferredDevices.removed.has(device.name)),
|
||||
});
|
||||
|
||||
dispatch(module.exports.addDevice(newDevice, type));
|
||||
|
@ -194,7 +203,9 @@ module.exports = {
|
|||
|
||||
restoreDeviceState() {
|
||||
return async function(dispatch, getState) {
|
||||
const deviceState = await asyncStorage.getItem("devtools.responsive.deviceState");
|
||||
const deviceState = await asyncStorage.getItem(
|
||||
"devtools.responsive.deviceState"
|
||||
);
|
||||
if (!deviceState) {
|
||||
return;
|
||||
}
|
||||
|
@ -235,5 +246,4 @@ module.exports = {
|
|||
modalOpenedFromViewport,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -14,92 +14,93 @@ const {
|
|||
CHANGE_NETWORK_THROTTLING,
|
||||
} = require("devtools/client/shared/components/throttling/actions");
|
||||
|
||||
createEnum([
|
||||
createEnum(
|
||||
[
|
||||
// Add a new device.
|
||||
"ADD_DEVICE",
|
||||
|
||||
// Add a new device.
|
||||
"ADD_DEVICE",
|
||||
// Add a new device type.
|
||||
"ADD_DEVICE_TYPE",
|
||||
|
||||
// Add a new device type.
|
||||
"ADD_DEVICE_TYPE",
|
||||
// Add an additional viewport to display the document.
|
||||
"ADD_VIEWPORT",
|
||||
|
||||
// Add an additional viewport to display the document.
|
||||
"ADD_VIEWPORT",
|
||||
// Change the device displayed in the viewport.
|
||||
"CHANGE_DEVICE",
|
||||
|
||||
// Change the device displayed in the viewport.
|
||||
"CHANGE_DEVICE",
|
||||
// Change the location of the page. This may be triggered by the user
|
||||
// directly entering a new URL, navigating with links, etc.
|
||||
"CHANGE_LOCATION",
|
||||
|
||||
// Change the location of the page. This may be triggered by the user
|
||||
// directly entering a new URL, navigating with links, etc.
|
||||
"CHANGE_LOCATION",
|
||||
// The pixel ratio of the display has changed. This may be triggered by the user
|
||||
// when changing the monitor resolution, or when the window is dragged to a different
|
||||
// display with a different pixel ratio.
|
||||
"CHANGE_DISPLAY_PIXEL_RATIO",
|
||||
|
||||
// The pixel ratio of the display has changed. This may be triggered by the user
|
||||
// when changing the monitor resolution, or when the window is dragged to a different
|
||||
// display with a different pixel ratio.
|
||||
"CHANGE_DISPLAY_PIXEL_RATIO",
|
||||
// Change the network throttling profile.
|
||||
CHANGE_NETWORK_THROTTLING,
|
||||
|
||||
// Change the network throttling profile.
|
||||
CHANGE_NETWORK_THROTTLING,
|
||||
// Change the user agent of the viewport.
|
||||
"CHANGE_USER_AGENT",
|
||||
|
||||
// Change the user agent of the viewport.
|
||||
"CHANGE_USER_AGENT",
|
||||
// The pixel ratio of the viewport has changed. This may be triggered by the user
|
||||
// when changing the device displayed in the viewport, or when a pixel ratio is
|
||||
// selected from the device pixel ratio dropdown.
|
||||
"CHANGE_PIXEL_RATIO",
|
||||
|
||||
// The pixel ratio of the viewport has changed. This may be triggered by the user
|
||||
// when changing the device displayed in the viewport, or when a pixel ratio is
|
||||
// selected from the device pixel ratio dropdown.
|
||||
"CHANGE_PIXEL_RATIO",
|
||||
// Change the viewport angle.
|
||||
"CHANGE_VIEWPORT_ANGLE",
|
||||
|
||||
// Change the viewport angle.
|
||||
"CHANGE_VIEWPORT_ANGLE",
|
||||
// Edit a device.
|
||||
"EDIT_DEVICE",
|
||||
|
||||
// Edit a device.
|
||||
"EDIT_DEVICE",
|
||||
// Indicates that the device list is being loaded.
|
||||
"LOAD_DEVICE_LIST_START",
|
||||
|
||||
// Indicates that the device list is being loaded.
|
||||
"LOAD_DEVICE_LIST_START",
|
||||
// Indicates that the device list loading action threw an error.
|
||||
"LOAD_DEVICE_LIST_ERROR",
|
||||
|
||||
// Indicates that the device list loading action threw an error.
|
||||
"LOAD_DEVICE_LIST_ERROR",
|
||||
// Indicates that the device list has been loaded successfully.
|
||||
"LOAD_DEVICE_LIST_END",
|
||||
|
||||
// Indicates that the device list has been loaded successfully.
|
||||
"LOAD_DEVICE_LIST_END",
|
||||
// Remove a device.
|
||||
"REMOVE_DEVICE",
|
||||
|
||||
// Remove a device.
|
||||
"REMOVE_DEVICE",
|
||||
// Remove the viewport's device assocation.
|
||||
"REMOVE_DEVICE_ASSOCIATION",
|
||||
|
||||
// Remove the viewport's device assocation.
|
||||
"REMOVE_DEVICE_ASSOCIATION",
|
||||
// Resize the viewport.
|
||||
"RESIZE_VIEWPORT",
|
||||
|
||||
// Resize the viewport.
|
||||
"RESIZE_VIEWPORT",
|
||||
// Rotate the viewport.
|
||||
"ROTATE_VIEWPORT",
|
||||
|
||||
// Rotate the viewport.
|
||||
"ROTATE_VIEWPORT",
|
||||
// Take a screenshot of the viewport.
|
||||
"TAKE_SCREENSHOT_START",
|
||||
|
||||
// Take a screenshot of the viewport.
|
||||
"TAKE_SCREENSHOT_START",
|
||||
// Indicates when the screenshot action ends.
|
||||
"TAKE_SCREENSHOT_END",
|
||||
|
||||
// Indicates when the screenshot action ends.
|
||||
"TAKE_SCREENSHOT_END",
|
||||
// Toggles the left alignment of the viewports.
|
||||
"TOGGLE_LEFT_ALIGNMENT",
|
||||
|
||||
// Toggles the left alignment of the viewports.
|
||||
"TOGGLE_LEFT_ALIGNMENT",
|
||||
// Toggles the reload on touch simulation changes.
|
||||
"TOGGLE_RELOAD_ON_TOUCH_SIMULATION",
|
||||
|
||||
// Toggles the reload on touch simulation changes.
|
||||
"TOGGLE_RELOAD_ON_TOUCH_SIMULATION",
|
||||
// Toggles the reload on user agent changes.
|
||||
"TOGGLE_RELOAD_ON_USER_AGENT",
|
||||
|
||||
// Toggles the reload on user agent changes.
|
||||
"TOGGLE_RELOAD_ON_USER_AGENT",
|
||||
// Toggles the touch simulation state of the viewports.
|
||||
"TOGGLE_TOUCH_SIMULATION",
|
||||
|
||||
// Toggles the touch simulation state of the viewports.
|
||||
"TOGGLE_TOUCH_SIMULATION",
|
||||
// Toggles the user agent input displayed in the toolbar.
|
||||
"TOGGLE_USER_AGENT_INPUT",
|
||||
|
||||
// Toggles the user agent input displayed in the toolbar.
|
||||
"TOGGLE_USER_AGENT_INPUT",
|
||||
// Update the device display state in the device selector.
|
||||
"UPDATE_DEVICE_DISPLAYED",
|
||||
|
||||
// Update the device display state in the device selector.
|
||||
"UPDATE_DEVICE_DISPLAYED",
|
||||
|
||||
// Update the device modal state.
|
||||
"UPDATE_DEVICE_MODAL",
|
||||
|
||||
], module.exports);
|
||||
// Update the device modal state.
|
||||
"UPDATE_DEVICE_MODAL",
|
||||
],
|
||||
module.exports
|
||||
);
|
||||
|
|
|
@ -8,10 +8,7 @@
|
|||
|
||||
const Services = require("Services");
|
||||
|
||||
const {
|
||||
TAKE_SCREENSHOT_START,
|
||||
TAKE_SCREENSHOT_END,
|
||||
} = require("./index");
|
||||
const { TAKE_SCREENSHOT_START, TAKE_SCREENSHOT_END } = require("./index");
|
||||
|
||||
const { getFormatStr } = require("../utils/l10n");
|
||||
const { getTopLevelWindow } = require("../utils/window");
|
||||
|
@ -19,19 +16,26 @@ const e10s = require("../utils/e10s");
|
|||
|
||||
const CAMERA_AUDIO_URL = "resource://devtools/client/themes/audio/shutter.wav";
|
||||
|
||||
const animationFrame = () => new Promise(resolve => {
|
||||
window.requestAnimationFrame(resolve);
|
||||
});
|
||||
const animationFrame = () =>
|
||||
new Promise(resolve => {
|
||||
window.requestAnimationFrame(resolve);
|
||||
});
|
||||
|
||||
function getFileName() {
|
||||
const date = new Date();
|
||||
const month = ("0" + (date.getMonth() + 1)).substr(-2);
|
||||
const day = ("0" + date.getDate()).substr(-2);
|
||||
const dateString = [date.getFullYear(), month, day].join("-");
|
||||
const timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0];
|
||||
const timeString = date
|
||||
.toTimeString()
|
||||
.replace(/:/g, ".")
|
||||
.split(" ")[0];
|
||||
|
||||
return getFormatStr("responsive.screenshotGeneratedFilename", dateString,
|
||||
timeString);
|
||||
return getFormatStr(
|
||||
"responsive.screenshotGeneratedFilename",
|
||||
dateString,
|
||||
timeString
|
||||
);
|
||||
}
|
||||
|
||||
function createScreenshotFor(node) {
|
||||
|
@ -48,9 +52,7 @@ function saveToFile(data, filename) {
|
|||
filename = filename.replace(/\.png$|$/i, ".png");
|
||||
|
||||
// In chrome doc, we don't need to pass a referrer, just pass null
|
||||
chromeWindow.saveURL(data, filename, null,
|
||||
true, true,
|
||||
null, chromeDocument);
|
||||
chromeWindow.saveURL(data, filename, null, true, true, null, chromeDocument);
|
||||
}
|
||||
|
||||
function simulateCameraEffects(node) {
|
||||
|
@ -58,11 +60,10 @@ function simulateCameraEffects(node) {
|
|||
const cameraAudio = new window.Audio(CAMERA_AUDIO_URL);
|
||||
cameraAudio.play();
|
||||
}
|
||||
node.animate({ opacity: [ 0, 1 ] }, 500);
|
||||
node.animate({ opacity: [0, 1] }, 500);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
takeScreenshot() {
|
||||
return async function(dispatch, getState) {
|
||||
await dispatch({ type: TAKE_SCREENSHOT_START });
|
||||
|
|
|
@ -15,7 +15,6 @@ const {
|
|||
} = require("./index");
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* The pixel ratio of the display has changed. This may be triggered by the user
|
||||
* when changing the monitor resolution, or when the window is dragged to a different
|
||||
|
@ -69,5 +68,4 @@ module.exports = {
|
|||
enabled,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@ const {
|
|||
const { post } = require("../utils/message");
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Add an additional viewport to display the document.
|
||||
*/
|
||||
|
@ -45,8 +44,11 @@ module.exports = {
|
|||
});
|
||||
|
||||
try {
|
||||
await asyncStorage.setItem("devtools.responsive.deviceState",
|
||||
{ id, device, deviceType });
|
||||
await asyncStorage.setItem("devtools.responsive.deviceState", {
|
||||
id,
|
||||
device,
|
||||
deviceType,
|
||||
});
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
@ -109,5 +111,4 @@ module.exports = {
|
|||
id,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -16,7 +16,9 @@ var global = this;
|
|||
}
|
||||
|
||||
const gDeviceSizeWasPageSize = docShell.deviceSizeIsPageSize;
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI("chrome://devtools/skin/floating-scrollbars-responsive-design.css");
|
||||
const gFloatingScrollbarsStylesheet = Services.io.newURI(
|
||||
"chrome://devtools/skin/floating-scrollbars-responsive-design.css"
|
||||
);
|
||||
|
||||
let requiresFloatingScrollbars;
|
||||
let active = false;
|
||||
|
@ -45,9 +47,13 @@ var global = this;
|
|||
return;
|
||||
}
|
||||
addMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
const webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
const webProgress = docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(
|
||||
WebProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_ALL
|
||||
);
|
||||
docShell.deviceSizeIsPageSize = true;
|
||||
requiresFloatingScrollbars = data.requiresFloatingScrollbars;
|
||||
if (data.notifyOnResize) {
|
||||
|
@ -117,8 +123,9 @@ var global = this;
|
|||
}
|
||||
active = false;
|
||||
removeMessageListener("ResponsiveMode:RequestScreenshot", screenshot);
|
||||
const webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
const webProgress = docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
docShell.deviceSizeIsPageSize = gDeviceSizeWasPageSize;
|
||||
// Restore the original physical screen orientation values before RDM is stopped.
|
||||
|
@ -149,7 +156,7 @@ var global = this;
|
|||
const winUtils = win.windowUtils;
|
||||
try {
|
||||
winUtils.loadSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch (e) { }
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
flushStyle();
|
||||
|
@ -165,13 +172,16 @@ var global = this;
|
|||
const winUtils = win.windowUtils;
|
||||
try {
|
||||
winUtils.removeSheet(gFloatingScrollbarsStylesheet, win.AGENT_SHEET);
|
||||
} catch (e) { }
|
||||
} catch (e) {}
|
||||
}
|
||||
flushStyle();
|
||||
}
|
||||
|
||||
function restoreScreenOrientation() {
|
||||
docShell.contentViewer.DOMDocument.setRDMPaneOrientation("landscape-primary", 0);
|
||||
docShell.contentViewer.DOMDocument.setRDMPaneOrientation(
|
||||
"landscape-primary",
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
function setDocumentInRDMPane(inRDMPane) {
|
||||
|
@ -189,7 +199,10 @@ var global = this;
|
|||
}
|
||||
|
||||
function screenshot() {
|
||||
const canvas = content.document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||
const canvas = content.document.createElementNS(
|
||||
"http://www.w3.org/1999/xhtml",
|
||||
"canvas"
|
||||
);
|
||||
const ratio = content.devicePixelRatio;
|
||||
const width = content.innerWidth * ratio;
|
||||
const height = content.innerHeight * ratio;
|
||||
|
@ -198,8 +211,18 @@ var global = this;
|
|||
canvas.height = height;
|
||||
const ctx = canvas.getContext("2d");
|
||||
ctx.scale(ratio, ratio);
|
||||
ctx.drawWindow(content, content.scrollX, content.scrollY, width, height, "#fff");
|
||||
sendAsyncMessage("ResponsiveMode:RequestScreenshot:Done", canvas.toDataURL());
|
||||
ctx.drawWindow(
|
||||
content,
|
||||
content.scrollX,
|
||||
content.scrollY,
|
||||
width,
|
||||
height,
|
||||
"#fff"
|
||||
);
|
||||
sendAsyncMessage(
|
||||
"ResponsiveMode:RequestScreenshot:Done",
|
||||
canvas.toDataURL()
|
||||
);
|
||||
}
|
||||
|
||||
const WebProgressListener = {
|
||||
|
@ -217,8 +240,10 @@ var global = this;
|
|||
});
|
||||
makeScrollbarsFloating();
|
||||
},
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener",
|
||||
"nsISupportsWeakReference"]),
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIWebProgressListener",
|
||||
"nsISupportsWeakReference",
|
||||
]),
|
||||
};
|
||||
})();
|
||||
|
||||
|
|
|
@ -56,12 +56,18 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
// The swap process uses a temporary tab, and there's no real need for others to hear
|
||||
// about it. This hides the temporary tab from things like WebExtensions.
|
||||
const addTabSilently = (uri, options) => {
|
||||
browserWindow.addEventListener("TabOpen", event => {
|
||||
event.stopImmediatePropagation();
|
||||
}, { capture: true, once: true });
|
||||
options.triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({
|
||||
userContextId: options.userContextId,
|
||||
});
|
||||
browserWindow.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
event.stopImmediatePropagation();
|
||||
},
|
||||
{ capture: true, once: true }
|
||||
);
|
||||
options.triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal(
|
||||
{
|
||||
userContextId: options.userContextId,
|
||||
}
|
||||
);
|
||||
return gBrowser.addWebTab(uri, options);
|
||||
};
|
||||
|
||||
|
@ -69,9 +75,13 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
// The swap process uses a temporary tab, and there's no real need for others to hear
|
||||
// about it. This hides the temporary tab from things like WebExtensions.
|
||||
const swapBrowsersAndCloseOtherSilently = (ourTab, otherTab) => {
|
||||
browserWindow.addEventListener("TabClose", event => {
|
||||
event.stopImmediatePropagation();
|
||||
}, { capture: true, once: true });
|
||||
browserWindow.addEventListener(
|
||||
"TabClose",
|
||||
event => {
|
||||
event.stopImmediatePropagation();
|
||||
},
|
||||
{ capture: true, once: true }
|
||||
);
|
||||
gBrowser.swapBrowsersAndCloseOther(ourTab, otherTab);
|
||||
};
|
||||
|
||||
|
@ -83,7 +93,10 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
// making it much easier to track such errors when they happen.
|
||||
const swapBrowserDocShells = (ourTab, otherBrowser) => {
|
||||
// The verification step here assumes both browsers are remote.
|
||||
if (!ourTab.linkedBrowser.isRemoteBrowser || !otherBrowser.isRemoteBrowser) {
|
||||
if (
|
||||
!ourTab.linkedBrowser.isRemoteBrowser ||
|
||||
!otherBrowser.isRemoteBrowser
|
||||
) {
|
||||
throw new Error("Both browsers should be remote before swapping.");
|
||||
}
|
||||
const contentTabId = ourTab.linkedBrowser.frameLoader.remoteTab.tabId;
|
||||
|
@ -97,13 +110,14 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
// Wait for a browser to load into a new frame loader.
|
||||
function loadURIWithNewFrameLoader(browser, uri, options) {
|
||||
return new Promise(resolve => {
|
||||
gBrowser.addEventListener("XULFrameLoaderCreated", resolve, { once: true });
|
||||
gBrowser.addEventListener("XULFrameLoaderCreated", resolve, {
|
||||
once: true,
|
||||
});
|
||||
browser.loadURI(uri, options);
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
async start() {
|
||||
// In some cases, such as a preloaded browser used for about:newtab, browser code
|
||||
// will force a new frameloader on next navigation to remote content to ensure
|
||||
|
@ -116,14 +130,18 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
mustChangeProcess,
|
||||
newFrameloader,
|
||||
} = E10SUtils.shouldLoadURIInBrowser(
|
||||
tab.linkedBrowser,
|
||||
tab.linkedBrowser,
|
||||
"http://example.com"
|
||||
);
|
||||
if (newFrameloader) {
|
||||
debug(`Tab will force a new frameloader on navigation, load about:blank first`);
|
||||
debug(
|
||||
`Tab will force a new frameloader on navigation, load about:blank first`
|
||||
);
|
||||
await loadURIWithNewFrameLoader(tab.linkedBrowser, "about:blank", {
|
||||
flags: Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_HISTORY,
|
||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({}),
|
||||
triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal(
|
||||
{}
|
||||
),
|
||||
});
|
||||
}
|
||||
// When the separate privileged content process is enabled, about:home and
|
||||
|
@ -140,10 +158,14 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
//
|
||||
// Bug 1510806 has been filed to fix this properly, by making RDM resilient
|
||||
// to process flips.
|
||||
if (mustChangeProcess &&
|
||||
tab.linkedBrowser.remoteType == "privilegedabout") {
|
||||
debug(`Tab must flip away from the privileged content process ` +
|
||||
`on navigation`);
|
||||
if (
|
||||
mustChangeProcess &&
|
||||
tab.linkedBrowser.remoteType == "privilegedabout"
|
||||
) {
|
||||
debug(
|
||||
`Tab must flip away from the privileged content process ` +
|
||||
`on navigation`
|
||||
);
|
||||
gBrowser.updateBrowserRemoteness(tab.linkedBrowser, {
|
||||
remoteType: requiredRemoteType,
|
||||
});
|
||||
|
@ -214,8 +236,9 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
innerBrowser = await getInnerBrowser(containerBrowser);
|
||||
addXULBrowserDecorations(innerBrowser);
|
||||
if (innerBrowser.isRemoteBrowser != tab.linkedBrowser.isRemoteBrowser) {
|
||||
throw new Error("The inner browser's remoteness must match the " +
|
||||
"original tab.");
|
||||
throw new Error(
|
||||
"The inner browser's remoteness must match the " + "original tab."
|
||||
);
|
||||
}
|
||||
|
||||
// 4. Swap tab content from the regular browser tab to the browser within
|
||||
|
@ -337,7 +360,6 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
// Show the browser content again now that the move is done.
|
||||
tab.linkedBrowser.style.visibility = "";
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -346,11 +368,7 @@ function swapToInnerBrowser({ tab, containerURL, getInnerBrowser }) {
|
|||
* location bar, etc. caused by the containerURL peeking through before the swap is
|
||||
* complete.
|
||||
*/
|
||||
const NAVIGATION_PROPERTIES = [
|
||||
"currentURI",
|
||||
"contentTitle",
|
||||
"securityUI",
|
||||
];
|
||||
const NAVIGATION_PROPERTIES = ["currentURI", "contentTitle", "securityUI"];
|
||||
|
||||
function freezeNavigationState(tab) {
|
||||
// Browser navigation properties we'll freeze temporarily to avoid "blinking" in the
|
||||
|
@ -452,8 +470,10 @@ function addXULBrowserDecorations(browser) {
|
|||
function tabLoaded(tab) {
|
||||
return new Promise(resolve => {
|
||||
function handle(event) {
|
||||
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank") {
|
||||
if (
|
||||
event.originalTarget != tab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
tab.linkedBrowser.removeEventListener("load", handle, true);
|
||||
|
|
|
@ -112,7 +112,8 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
inner._imageDocument = outer._imageDocument;
|
||||
inner._isSyntheticDocument = outer._isSyntheticDocument;
|
||||
inner._innerWindowID = outer._innerWindowID;
|
||||
inner._remoteWebNavigationImpl._currentURI = outer._remoteWebNavigationImpl._currentURI;
|
||||
inner._remoteWebNavigationImpl._currentURI =
|
||||
outer._remoteWebNavigationImpl._currentURI;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -123,7 +124,6 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
};
|
||||
|
||||
return {
|
||||
|
||||
async start() {
|
||||
if (outer.isRemoteBrowser) {
|
||||
throw new Error("The outer browser must be non-remote.");
|
||||
|
@ -239,8 +239,10 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
// reattach it here.
|
||||
const tab = gBrowser.getTabForBrowser(outer);
|
||||
const filteredProgressListener = gBrowser._tabFilters.get(tab);
|
||||
outer.webProgress.addProgressListener(filteredProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_ALL);
|
||||
outer.webProgress.addProgressListener(
|
||||
filteredProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_ALL
|
||||
);
|
||||
outer.webProgress.addProgressListener(
|
||||
mirroringProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_ALL | Ci.nsIWebProgress.NOTIFY_LOCATION
|
||||
|
@ -306,9 +308,13 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
// regular browser tabs (which calls `openURIInFrame`). The more elaborate APIs
|
||||
// that support openers, window features, etc. didn't seem callable from JS and / or
|
||||
// this event doesn't give enough info to use them.
|
||||
browserWindow.browserDOMWindow
|
||||
.openURI(uri, null, flags, Ci.nsIBrowserDOMWindow.OPEN_NEW,
|
||||
outer.contentPrincipal);
|
||||
browserWindow.browserDOMWindow.openURI(
|
||||
uri,
|
||||
null,
|
||||
flags,
|
||||
Ci.nsIBrowserDOMWindow.OPEN_NEW,
|
||||
outer.contentPrincipal
|
||||
);
|
||||
},
|
||||
|
||||
handleModalPromptEvent({ detail }) {
|
||||
|
@ -391,7 +397,6 @@ function tunnelToInnerBrowser(outer, inner) {
|
|||
browserWindow = null;
|
||||
gBrowser = null;
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -413,7 +418,6 @@ function MessageManagerTunnel(outer, inner) {
|
|||
}
|
||||
|
||||
MessageManagerTunnel.prototype = {
|
||||
|
||||
/**
|
||||
* Most message manager methods are left alone and are just passed along to
|
||||
* the outer browser's real message manager.
|
||||
|
@ -674,7 +678,11 @@ MessageManagerTunnel.prototype = {
|
|||
|
||||
// If the message name is part of a prefix we're tunneling, we also need to add the
|
||||
// tunnel as an inner listener.
|
||||
if (this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix => name.startsWith(prefix))) {
|
||||
if (
|
||||
this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix =>
|
||||
name.startsWith(prefix)
|
||||
)
|
||||
) {
|
||||
debug(`Add inner listener for ${name}`);
|
||||
this.innerParentMM.addMessageListener(name, this);
|
||||
this.tunneledMessageNames.add(name);
|
||||
|
@ -720,17 +728,24 @@ MessageManagerTunnel.prototype = {
|
|||
},
|
||||
|
||||
_shouldTunnelOuterToInner(name) {
|
||||
return this.OUTER_TO_INNER_MESSAGES.includes(name) ||
|
||||
this.OUTER_TO_INNER_MESSAGE_PREFIXES.some(prefix => name.startsWith(prefix));
|
||||
return (
|
||||
this.OUTER_TO_INNER_MESSAGES.includes(name) ||
|
||||
this.OUTER_TO_INNER_MESSAGE_PREFIXES.some(prefix =>
|
||||
name.startsWith(prefix)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
_shouldTunnelInnerToOuter(name) {
|
||||
return this.INNER_TO_OUTER_MESSAGES.includes(name) ||
|
||||
this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix => name.startsWith(prefix));
|
||||
return (
|
||||
this.INNER_TO_OUTER_MESSAGES.includes(name) ||
|
||||
this.INNER_TO_OUTER_MESSAGE_PREFIXES.some(prefix =>
|
||||
name.startsWith(prefix)
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
toString() {
|
||||
return "[object MessageManagerTunnel]";
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -32,10 +32,7 @@ function BrowserElementWebNavigation(browser) {
|
|||
}
|
||||
|
||||
BrowserElementWebNavigation.prototype = {
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
Ci.nsIWebNavigation,
|
||||
]),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebNavigation]),
|
||||
|
||||
get _mm() {
|
||||
return this._browser.frameLoader.messageManager;
|
||||
|
@ -59,17 +56,32 @@ BrowserElementWebNavigation.prototype = {
|
|||
|
||||
loadURI(uri, flags, referrer, postData, headers) {
|
||||
// No equivalent in the current BrowserElement API
|
||||
this.loadURIWithOptions(uri, flags, referrer,
|
||||
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
|
||||
postData, headers, null,
|
||||
Services.scriptSecurityManager.createNullPrincipal({}));
|
||||
this.loadURIWithOptions(
|
||||
uri,
|
||||
flags,
|
||||
referrer,
|
||||
Ci.nsIHttpChannel.REFERRER_POLICY_UNSET,
|
||||
postData,
|
||||
headers,
|
||||
null,
|
||||
Services.scriptSecurityManager.createNullPrincipal({})
|
||||
);
|
||||
},
|
||||
|
||||
loadURIWithOptions(uri, flags, referrer, referrerPolicy, postData, headers,
|
||||
baseURI, triggeringPrincipal) {
|
||||
loadURIWithOptions(
|
||||
uri,
|
||||
flags,
|
||||
referrer,
|
||||
referrerPolicy,
|
||||
postData,
|
||||
headers,
|
||||
baseURI,
|
||||
triggeringPrincipal
|
||||
) {
|
||||
// No equivalent in the current BrowserElement API
|
||||
let referrerInfo = Cc["@mozilla.org/referrer-info;1"]
|
||||
.createInstance(Ci.nsIReferrerInfo);
|
||||
let referrerInfo = Cc["@mozilla.org/referrer-info;1"].createInstance(
|
||||
Ci.nsIReferrerInfo
|
||||
);
|
||||
referrerInfo.init(referrerPolicy, true, referrer);
|
||||
referrerInfo = E10SUtils.serializeReferrerInfo(referrerInfo);
|
||||
this._sendMessage("WebNavigation:LoadURI", {
|
||||
|
@ -80,8 +92,9 @@ BrowserElementWebNavigation.prototype = {
|
|||
headers: headers ? readInputStreamToString(headers) : null,
|
||||
baseURI: baseURI ? baseURI.spec : null,
|
||||
triggeringPrincipal: E10SUtils.serializePrincipal(
|
||||
triggeringPrincipal ||
|
||||
Services.scriptSecurityManager.createNullPrincipal({})),
|
||||
triggeringPrincipal ||
|
||||
Services.scriptSecurityManager.createNullPrincipal({})
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -94,8 +107,10 @@ BrowserElementWebNavigation.prototype = {
|
|||
|
||||
reload(flags) {
|
||||
let hardReload = false;
|
||||
if (flags & this.LOAD_FLAGS_BYPASS_PROXY ||
|
||||
flags & this.LOAD_FLAGS_BYPASS_CACHE) {
|
||||
if (
|
||||
flags & this.LOAD_FLAGS_BYPASS_PROXY ||
|
||||
flags & this.LOAD_FLAGS_BYPASS_CACHE
|
||||
) {
|
||||
hardReload = true;
|
||||
}
|
||||
this._browser.reload(hardReload);
|
||||
|
@ -145,16 +160,11 @@ BrowserElementWebNavigation.prototype = {
|
|||
},
|
||||
|
||||
copyStateFrom(otherWebNavigation) {
|
||||
const state = [
|
||||
"canGoBack",
|
||||
"canGoForward",
|
||||
"_currentURI",
|
||||
];
|
||||
const state = ["canGoBack", "canGoForward", "_currentURI"];
|
||||
for (const property of state) {
|
||||
this[property] = otherWebNavigation[property];
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
const FLAGS = [
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
@ -15,10 +18,13 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
|
|||
const Toolbar = createFactory(require("./Toolbar"));
|
||||
const Viewports = createFactory(require("./Viewports"));
|
||||
|
||||
loader.lazyGetter(this, "DeviceModal",
|
||||
() => createFactory(require("./DeviceModal")));
|
||||
loader.lazyGetter(this, "DeviceModal", () =>
|
||||
createFactory(require("./DeviceModal"))
|
||||
);
|
||||
|
||||
const { changeNetworkThrottling } = require("devtools/client/shared/components/throttling/actions");
|
||||
const {
|
||||
changeNetworkThrottling,
|
||||
} = require("devtools/client/shared/components/throttling/actions");
|
||||
const {
|
||||
addCustomDevice,
|
||||
editCustomDevice,
|
||||
|
@ -70,7 +76,9 @@ class App extends PureComponent {
|
|||
this.onChangePixelRatio = this.onChangePixelRatio.bind(this);
|
||||
this.onChangeTouchSimulation = this.onChangeTouchSimulation.bind(this);
|
||||
this.onChangeUserAgent = this.onChangeUserAgent.bind(this);
|
||||
this.onChangeViewportOrientation = this.onChangeViewportOrientation.bind(this);
|
||||
this.onChangeViewportOrientation = this.onChangeViewportOrientation.bind(
|
||||
this
|
||||
);
|
||||
this.onContentResize = this.onContentResize.bind(this);
|
||||
this.onDeviceListUpdate = this.onDeviceListUpdate.bind(this);
|
||||
this.onEditCustomDevice = this.onEditCustomDevice.bind(this);
|
||||
|
@ -82,8 +90,9 @@ class App extends PureComponent {
|
|||
this.onRotateViewport = this.onRotateViewport.bind(this);
|
||||
this.onScreenshot = this.onScreenshot.bind(this);
|
||||
this.onToggleLeftAlignment = this.onToggleLeftAlignment.bind(this);
|
||||
this.onToggleReloadOnTouchSimulation =
|
||||
this.onToggleReloadOnTouchSimulation.bind(this);
|
||||
this.onToggleReloadOnTouchSimulation = this.onToggleReloadOnTouchSimulation.bind(
|
||||
this
|
||||
);
|
||||
this.onToggleReloadOnUserAgent = this.onToggleReloadOnUserAgent.bind(this);
|
||||
this.onToggleUserAgentInput = this.onToggleUserAgentInput.bind(this);
|
||||
this.onUpdateDeviceDisplayed = this.onUpdateDeviceDisplayed.bind(this);
|
||||
|
@ -115,11 +124,14 @@ class App extends PureComponent {
|
|||
// TODO: Bug 1332754: Move messaging and logic into the action creator so that the
|
||||
// message is sent from the action creator and device property changes are sent from
|
||||
// there instead of this function.
|
||||
window.postMessage({
|
||||
type: "change-device",
|
||||
device,
|
||||
viewport: this.props.viewports[id],
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "change-device",
|
||||
device,
|
||||
viewport: this.props.viewports[id],
|
||||
},
|
||||
"*"
|
||||
);
|
||||
|
||||
const orientation = getOrientation(device, this.props.viewports[0]);
|
||||
|
||||
|
@ -131,45 +143,60 @@ class App extends PureComponent {
|
|||
}
|
||||
|
||||
onChangeNetworkThrottling(enabled, profile) {
|
||||
window.postMessage({
|
||||
type: "change-network-throttling",
|
||||
enabled,
|
||||
profile,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "change-network-throttling",
|
||||
enabled,
|
||||
profile,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
this.props.dispatch(changeNetworkThrottling(enabled, profile));
|
||||
}
|
||||
|
||||
onChangePixelRatio(pixelRatio) {
|
||||
window.postMessage({
|
||||
type: "change-pixel-ratio",
|
||||
pixelRatio,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "change-pixel-ratio",
|
||||
pixelRatio,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
this.props.dispatch(changePixelRatio(0, pixelRatio));
|
||||
}
|
||||
|
||||
onChangeTouchSimulation(enabled) {
|
||||
window.postMessage({
|
||||
type: "change-touch-simulation",
|
||||
enabled,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "change-touch-simulation",
|
||||
enabled,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
this.props.dispatch(toggleTouchSimulation(enabled));
|
||||
}
|
||||
|
||||
onChangeUserAgent(userAgent) {
|
||||
window.postMessage({
|
||||
type: "change-user-agent",
|
||||
userAgent,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "change-user-agent",
|
||||
userAgent,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
this.props.dispatch(changeUserAgent(userAgent));
|
||||
}
|
||||
|
||||
onChangeViewportOrientation(id, type, angle, isViewportRotated = false) {
|
||||
window.postMessage({
|
||||
type: "viewport-orientation-change",
|
||||
orientationType: type,
|
||||
angle,
|
||||
isViewportRotated,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "viewport-orientation-change",
|
||||
orientationType: type,
|
||||
angle,
|
||||
isViewportRotated,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
|
||||
if (isViewportRotated) {
|
||||
this.props.dispatch(changeViewportAngle(id, angle));
|
||||
|
@ -177,11 +204,14 @@ class App extends PureComponent {
|
|||
}
|
||||
|
||||
onContentResize({ width, height }) {
|
||||
window.postMessage({
|
||||
type: "content-resize",
|
||||
width,
|
||||
height,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "content-resize",
|
||||
width,
|
||||
height,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
}
|
||||
|
||||
onDeviceListUpdate(devices) {
|
||||
|
@ -191,7 +221,9 @@ class App extends PureComponent {
|
|||
onEditCustomDevice(oldDevice, newDevice) {
|
||||
// If the edited device is currently selected, then update its original association
|
||||
// and reset UI state.
|
||||
let viewport = this.props.viewports.find(({ device }) => device === oldDevice.name);
|
||||
let viewport = this.props.viewports.find(
|
||||
({ device }) => device === oldDevice.name
|
||||
);
|
||||
|
||||
if (viewport) {
|
||||
viewport = {
|
||||
|
@ -243,11 +275,14 @@ class App extends PureComponent {
|
|||
onResizeViewport({ width, height }) {
|
||||
// This is the response function that listens to changes to the size
|
||||
// and sends out a "viewport-resize" message with the new size.
|
||||
window.postMessage({
|
||||
type: "viewport-resize",
|
||||
width,
|
||||
height,
|
||||
}, "*");
|
||||
window.postMessage(
|
||||
{
|
||||
type: "viewport-resize",
|
||||
width,
|
||||
height,
|
||||
},
|
||||
"*"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +313,15 @@ class App extends PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
const currentAngle = Services.prefs.getIntPref("devtools.responsive.viewport.angle");
|
||||
const currentAngle = Services.prefs.getIntPref(
|
||||
"devtools.responsive.viewport.angle"
|
||||
);
|
||||
const angleToRotateTo = currentAngle === 90 ? 0 : 90;
|
||||
const { type, angle } = getOrientation(currentDevice, viewport, angleToRotateTo);
|
||||
const { type, angle } = getOrientation(
|
||||
currentDevice,
|
||||
viewport,
|
||||
angleToRotateTo
|
||||
);
|
||||
|
||||
this.onChangeViewportOrientation(id, type, angle, true);
|
||||
this.props.dispatch(rotateViewport(id));
|
||||
|
@ -315,12 +356,7 @@ class App extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
devices,
|
||||
networkThrottling,
|
||||
screenshot,
|
||||
viewports,
|
||||
} = this.props;
|
||||
const { devices, networkThrottling, screenshot, viewports } = this.props;
|
||||
|
||||
const {
|
||||
onAddCustomDevice,
|
||||
|
@ -361,43 +397,43 @@ class App extends PureComponent {
|
|||
deviceAdderViewportTemplate = viewports[devices.modalOpenedFromViewport];
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({ id: "app" },
|
||||
Toolbar({
|
||||
devices,
|
||||
networkThrottling,
|
||||
screenshot,
|
||||
selectedDevice,
|
||||
selectedPixelRatio,
|
||||
viewport: viewports[0],
|
||||
onChangeDevice,
|
||||
onChangeNetworkThrottling,
|
||||
onChangePixelRatio,
|
||||
onChangeTouchSimulation,
|
||||
onChangeUserAgent,
|
||||
onExit,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onRotateViewport,
|
||||
onScreenshot,
|
||||
onToggleLeftAlignment,
|
||||
onToggleReloadOnTouchSimulation,
|
||||
onToggleReloadOnUserAgent,
|
||||
onToggleUserAgentInput,
|
||||
onUpdateDeviceModal,
|
||||
}),
|
||||
Viewports({
|
||||
screenshot,
|
||||
viewports,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onResizeViewport,
|
||||
}),
|
||||
devices.isModalOpen ?
|
||||
DeviceModal({
|
||||
return dom.div(
|
||||
{ id: "app" },
|
||||
Toolbar({
|
||||
devices,
|
||||
networkThrottling,
|
||||
screenshot,
|
||||
selectedDevice,
|
||||
selectedPixelRatio,
|
||||
viewport: viewports[0],
|
||||
onChangeDevice,
|
||||
onChangeNetworkThrottling,
|
||||
onChangePixelRatio,
|
||||
onChangeTouchSimulation,
|
||||
onChangeUserAgent,
|
||||
onExit,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onRotateViewport,
|
||||
onScreenshot,
|
||||
onToggleLeftAlignment,
|
||||
onToggleReloadOnTouchSimulation,
|
||||
onToggleReloadOnUserAgent,
|
||||
onToggleUserAgentInput,
|
||||
onUpdateDeviceModal,
|
||||
}),
|
||||
Viewports({
|
||||
screenshot,
|
||||
viewports,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onResizeViewport,
|
||||
}),
|
||||
devices.isModalOpen
|
||||
? DeviceModal({
|
||||
deviceAdderViewportTemplate,
|
||||
devices,
|
||||
onAddCustomDevice,
|
||||
|
@ -407,9 +443,7 @@ class App extends PureComponent {
|
|||
onUpdateDeviceDisplayed,
|
||||
onUpdateDeviceModal,
|
||||
})
|
||||
:
|
||||
null
|
||||
)
|
||||
: null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,8 +143,9 @@ class Browser extends PureComponent {
|
|||
await ready;
|
||||
|
||||
const browserWindow = getTopLevelWindow(window);
|
||||
const requiresFloatingScrollbars =
|
||||
!browserWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
const requiresFloatingScrollbars = !browserWindow.matchMedia(
|
||||
"(-moz-overlay-scrollbars)"
|
||||
).matches;
|
||||
|
||||
await e10s.request(mm, "Start", {
|
||||
requiresFloatingScrollbars,
|
||||
|
@ -170,9 +171,7 @@ class Browser extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
userContextId,
|
||||
} = this.props;
|
||||
const { userContextId } = this.props;
|
||||
|
||||
// In the case of @remote and @remoteType, the attribute must be set before the
|
||||
// element is added to the DOM to have any effect, which we are able to do with this
|
||||
|
@ -181,25 +180,21 @@ class Browser extends PureComponent {
|
|||
// @noisolation and @allowfullscreen are needed so that these frames have the same
|
||||
// access to browser features as regular browser tabs. The `swapFrameLoaders` platform
|
||||
// API we use compares such features before allowing the swap to proceed.
|
||||
return (
|
||||
dom.iframe(
|
||||
{
|
||||
allowFullScreen: "true",
|
||||
className: "browser",
|
||||
height: "100%",
|
||||
mozbrowser: "true",
|
||||
noisolation: "true",
|
||||
remote: "true",
|
||||
remoteType: "web",
|
||||
src: "about:blank",
|
||||
usercontextid: userContextId,
|
||||
width: "100%",
|
||||
ref: browser => {
|
||||
this.browser = browser;
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
return dom.iframe({
|
||||
allowFullScreen: "true",
|
||||
className: "browser",
|
||||
height: "100%",
|
||||
mozbrowser: "true",
|
||||
noisolation: "true",
|
||||
remote: "true",
|
||||
remoteType: "web",
|
||||
src: "about:blank",
|
||||
usercontextid: userContextId,
|
||||
width: "100%",
|
||||
ref: browser => {
|
||||
this.browser = browser;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,30 +48,30 @@ class Device extends PureComponent {
|
|||
render() {
|
||||
const { children, device } = this.props;
|
||||
const details = getFormatStr(
|
||||
"responsive.deviceDetails", device.width, device.height,
|
||||
device.pixelRatio, device.userAgent, device.touch
|
||||
"responsive.deviceDetails",
|
||||
device.width,
|
||||
device.height,
|
||||
device.pixelRatio,
|
||||
device.userAgent,
|
||||
device.touch
|
||||
);
|
||||
|
||||
return (
|
||||
dom.label(
|
||||
{
|
||||
className: "device-label",
|
||||
key: device.name,
|
||||
title: details,
|
||||
},
|
||||
dom.input({
|
||||
className: "device-input-checkbox",
|
||||
name: device.name,
|
||||
type: "checkbox",
|
||||
value: device.name,
|
||||
checked: device.isChecked,
|
||||
onChange: this.onCheckboxChanged,
|
||||
}),
|
||||
dom.span({ className: "device-name" },
|
||||
device.name
|
||||
),
|
||||
children
|
||||
)
|
||||
return dom.label(
|
||||
{
|
||||
className: "device-label",
|
||||
key: device.name,
|
||||
title: details,
|
||||
},
|
||||
dom.input({
|
||||
className: "device-input-checkbox",
|
||||
name: device.name,
|
||||
type: "checkbox",
|
||||
value: device.name,
|
||||
checked: device.isChecked,
|
||||
onChange: this.onCheckboxChanged,
|
||||
}),
|
||||
dom.span({ className: "device-name" }, device.name),
|
||||
children
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
|
@ -27,10 +30,7 @@ class DeviceAdder extends PureComponent {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
height,
|
||||
width,
|
||||
} = this.props.viewportTemplate;
|
||||
const { height, width } = this.props.viewportTemplate;
|
||||
|
||||
this.state = {
|
||||
deviceAdderDisplayed: false,
|
||||
|
@ -57,10 +57,7 @@ class DeviceAdder extends PureComponent {
|
|||
}
|
||||
|
||||
onDeviceAdderSave() {
|
||||
const {
|
||||
devices,
|
||||
onAddCustomDevice,
|
||||
} = this.props;
|
||||
const { devices, onAddCustomDevice } = this.props;
|
||||
|
||||
if (!this.pixelRatioInput.checkValidity()) {
|
||||
return;
|
||||
|
@ -86,16 +83,9 @@ class DeviceAdder extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
devices,
|
||||
viewportTemplate,
|
||||
} = this.props;
|
||||
const { devices, viewportTemplate } = this.props;
|
||||
|
||||
const {
|
||||
deviceAdderDisplayed,
|
||||
height,
|
||||
width,
|
||||
} = this.state;
|
||||
const { deviceAdderDisplayed, height, width } = this.state;
|
||||
|
||||
if (!deviceAdderDisplayed) {
|
||||
return dom.div(
|
||||
|
@ -121,7 +111,10 @@ class DeviceAdder extends PureComponent {
|
|||
const device = devices[viewportTemplate.deviceType].find(d => {
|
||||
return d.name == viewportTemplate.device;
|
||||
});
|
||||
deviceName = getFormatStr("responsive.customDeviceNameFromBase", device.name);
|
||||
deviceName = getFormatStr(
|
||||
"responsive.customDeviceNameFromBase",
|
||||
device.name
|
||||
);
|
||||
Object.assign(normalizedViewport, {
|
||||
pixelRatio: device.pixelRatio,
|
||||
userAgent: device.userAgent,
|
||||
|
@ -136,81 +129,93 @@ class DeviceAdder extends PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({ id: "device-adder" },
|
||||
dom.div({ id: "device-adder-content" },
|
||||
dom.div({ id: "device-adder-column-1" },
|
||||
dom.label({ id: "device-adder-name" },
|
||||
dom.span({ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderName")
|
||||
),
|
||||
dom.input({
|
||||
defaultValue: deviceName,
|
||||
ref: input => {
|
||||
this.nameInput = input;
|
||||
},
|
||||
})
|
||||
return dom.div(
|
||||
{ id: "device-adder" },
|
||||
dom.div(
|
||||
{ id: "device-adder-content" },
|
||||
dom.div(
|
||||
{ id: "device-adder-column-1" },
|
||||
dom.label(
|
||||
{ id: "device-adder-name" },
|
||||
dom.span(
|
||||
{ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderName")
|
||||
),
|
||||
dom.label({ id: "device-adder-size" },
|
||||
dom.span({ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderSize")
|
||||
),
|
||||
ViewportDimension({
|
||||
viewport: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
doResizeViewport: this.onChangeSize,
|
||||
onRemoveDeviceAssociation: () => {},
|
||||
})
|
||||
),
|
||||
dom.label({ id: "device-adder-pixel-ratio" },
|
||||
dom.span({ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderPixelRatio")
|
||||
),
|
||||
dom.input({
|
||||
type: "number",
|
||||
step: "any",
|
||||
defaultValue: normalizedViewport.pixelRatio,
|
||||
ref: input => {
|
||||
this.pixelRatioInput = input;
|
||||
},
|
||||
})
|
||||
)
|
||||
dom.input({
|
||||
defaultValue: deviceName,
|
||||
ref: input => {
|
||||
this.nameInput = input;
|
||||
},
|
||||
})
|
||||
),
|
||||
dom.div({ id: "device-adder-column-2" },
|
||||
dom.label({ id: "device-adder-user-agent" },
|
||||
dom.span({ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderUserAgent")
|
||||
),
|
||||
dom.input({
|
||||
defaultValue: normalizedViewport.userAgent,
|
||||
ref: input => {
|
||||
this.userAgentInput = input;
|
||||
},
|
||||
})
|
||||
dom.label(
|
||||
{ id: "device-adder-size" },
|
||||
dom.span(
|
||||
{ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderSize")
|
||||
),
|
||||
dom.label({ id: "device-adder-touch" },
|
||||
dom.span({ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderTouch")
|
||||
),
|
||||
dom.input({
|
||||
defaultChecked: normalizedViewport.touch,
|
||||
type: "checkbox",
|
||||
ref: input => {
|
||||
this.touchInput = input;
|
||||
},
|
||||
})
|
||||
)
|
||||
ViewportDimension({
|
||||
viewport: {
|
||||
width,
|
||||
height,
|
||||
},
|
||||
doResizeViewport: this.onChangeSize,
|
||||
onRemoveDeviceAssociation: () => {},
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-adder-pixel-ratio" },
|
||||
dom.span(
|
||||
{ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderPixelRatio")
|
||||
),
|
||||
dom.input({
|
||||
type: "number",
|
||||
step: "any",
|
||||
defaultValue: normalizedViewport.pixelRatio,
|
||||
ref: input => {
|
||||
this.pixelRatioInput = input;
|
||||
},
|
||||
})
|
||||
)
|
||||
),
|
||||
dom.button(
|
||||
{
|
||||
id: "device-adder-save",
|
||||
onClick: this.onDeviceAdderSave,
|
||||
},
|
||||
getStr("responsive.deviceAdderSave")
|
||||
dom.div(
|
||||
{ id: "device-adder-column-2" },
|
||||
dom.label(
|
||||
{ id: "device-adder-user-agent" },
|
||||
dom.span(
|
||||
{ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderUserAgent")
|
||||
),
|
||||
dom.input({
|
||||
defaultValue: normalizedViewport.userAgent,
|
||||
ref: input => {
|
||||
this.userAgentInput = input;
|
||||
},
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-adder-touch" },
|
||||
dom.span(
|
||||
{ className: "device-adder-label" },
|
||||
getStr("responsive.deviceAdderTouch")
|
||||
),
|
||||
dom.input({
|
||||
defaultChecked: normalizedViewport.touch,
|
||||
type: "checkbox",
|
||||
ref: input => {
|
||||
this.touchInput = input;
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
),
|
||||
dom.button(
|
||||
{
|
||||
id: "device-adder-save",
|
||||
onClick: this.onDeviceAdderSave,
|
||||
},
|
||||
getStr("responsive.deviceAdderSave")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, createRef, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
createRef,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
|
@ -30,10 +34,7 @@ class DeviceForm extends PureComponent {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const {
|
||||
height,
|
||||
width,
|
||||
} = this.props.viewportTemplate;
|
||||
const { height, width } = this.props.viewportTemplate;
|
||||
|
||||
this.state = {
|
||||
height,
|
||||
|
@ -46,7 +47,7 @@ class DeviceForm extends PureComponent {
|
|||
this.userAgentInputRef = createRef();
|
||||
|
||||
this.onChangeSize = this.onChangeSize.bind(this);
|
||||
this.onDeviceFormHide = this.onDeviceFormHide.bind(this);
|
||||
this.onDeviceFormHide = this.onDeviceFormHide.bind(this);
|
||||
this.onDeviceFormSave = this.onDeviceFormSave.bind(this);
|
||||
this.validateNameField = this.validateNameField.bind(this);
|
||||
}
|
||||
|
@ -63,9 +64,15 @@ class DeviceForm extends PureComponent {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this.validateNameField(this.nameInputRef.current.value, this.props.device)) {
|
||||
this.nameInputRef.current
|
||||
.setCustomValidity(getStr("responsive.deviceNameAlreadyInUse"));
|
||||
if (
|
||||
!this.validateNameField(
|
||||
this.nameInputRef.current.value,
|
||||
this.props.device
|
||||
)
|
||||
) {
|
||||
this.nameInputRef.current.setCustomValidity(
|
||||
getStr("responsive.deviceNameAlreadyInUse")
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -102,8 +109,9 @@ class DeviceForm extends PureComponent {
|
|||
// If the formType is "add", then we just need to check if a custom device with that
|
||||
// same name exists.
|
||||
if (this.props.formType === "add") {
|
||||
isValidDeviceName = !this.props.devices.custom
|
||||
.find(device => device.name == nameFieldValue);
|
||||
isValidDeviceName = !this.props.devices.custom.find(
|
||||
device => device.name == nameFieldValue
|
||||
);
|
||||
} else {
|
||||
// Otherwise, the formType is "edit". We'd have to find another device that
|
||||
// already has the same name, but not itself, so:
|
||||
|
@ -125,66 +133,78 @@ class DeviceForm extends PureComponent {
|
|||
const { device, formType } = this.props;
|
||||
const { width, height } = this.state;
|
||||
|
||||
return (
|
||||
dom.form({ id: "device-form" },
|
||||
dom.label({ id: "device-form-name" },
|
||||
dom.span({ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderName")
|
||||
),
|
||||
dom.input({
|
||||
defaultValue: device.name,
|
||||
ref: this.nameInputRef,
|
||||
})
|
||||
return dom.form(
|
||||
{ id: "device-form" },
|
||||
dom.label(
|
||||
{ id: "device-form-name" },
|
||||
dom.span(
|
||||
{ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderName")
|
||||
),
|
||||
dom.label({ id: "device-form-size" },
|
||||
dom.span({ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderSize")
|
||||
),
|
||||
ViewportDimension({
|
||||
viewport: { width, height },
|
||||
doResizeViewport: this.onChangeSize,
|
||||
onRemoveDeviceAssociation: () => {},
|
||||
})
|
||||
dom.input({
|
||||
defaultValue: device.name,
|
||||
ref: this.nameInputRef,
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-form-size" },
|
||||
dom.span(
|
||||
{ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderSize")
|
||||
),
|
||||
dom.label({ id: "device-form-pixel-ratio" },
|
||||
dom.span({ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderPixelRatio2")
|
||||
),
|
||||
dom.input({
|
||||
type: "number",
|
||||
step: "any",
|
||||
defaultValue: device.pixelRatio,
|
||||
ref: this.pixelRatioInputRef,
|
||||
})
|
||||
ViewportDimension({
|
||||
viewport: { width, height },
|
||||
doResizeViewport: this.onChangeSize,
|
||||
onRemoveDeviceAssociation: () => {},
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-form-pixel-ratio" },
|
||||
dom.span(
|
||||
{ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderPixelRatio2")
|
||||
),
|
||||
dom.label({ id: "device-form-user-agent" },
|
||||
dom.span({ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderUserAgent2")
|
||||
),
|
||||
dom.input({
|
||||
defaultValue: device.userAgent,
|
||||
ref: this.userAgentInputRef,
|
||||
})
|
||||
dom.input({
|
||||
type: "number",
|
||||
step: "any",
|
||||
defaultValue: device.pixelRatio,
|
||||
ref: this.pixelRatioInputRef,
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-form-user-agent" },
|
||||
dom.span(
|
||||
{ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderUserAgent2")
|
||||
),
|
||||
dom.label({ id: "device-form-touch" },
|
||||
dom.input({
|
||||
defaultChecked: device.touch,
|
||||
type: "checkbox",
|
||||
ref: this.touchInputRef,
|
||||
}),
|
||||
dom.span({ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderTouch2")
|
||||
)
|
||||
dom.input({
|
||||
defaultValue: device.userAgent,
|
||||
ref: this.userAgentInputRef,
|
||||
})
|
||||
),
|
||||
dom.label(
|
||||
{ id: "device-form-touch" },
|
||||
dom.input({
|
||||
defaultChecked: device.touch,
|
||||
type: "checkbox",
|
||||
ref: this.touchInputRef,
|
||||
}),
|
||||
dom.span(
|
||||
{ className: "device-form-label" },
|
||||
getStr("responsive.deviceAdderTouch2")
|
||||
)
|
||||
),
|
||||
dom.div(
|
||||
{ className: "device-form-buttons" },
|
||||
dom.button(
|
||||
{ id: "device-form-save", onClick: this.onDeviceFormSave },
|
||||
formType === "add"
|
||||
? getStr("responsive.deviceAdderSave")
|
||||
: getStr("responsive.deviceFormUpdate")
|
||||
),
|
||||
dom.div({ className: "device-form-buttons" },
|
||||
dom.button({ id: "device-form-save", onClick: this.onDeviceFormSave },
|
||||
formType === "add" ?
|
||||
getStr("responsive.deviceAdderSave") :
|
||||
getStr("responsive.deviceFormUpdate")
|
||||
),
|
||||
dom.button({ id: "device-form-cancel", onClick: this.onDeviceFormHide },
|
||||
getStr("responsive.deviceAdderCancel")
|
||||
)
|
||||
dom.button(
|
||||
{ id: "device-form-cancel", onClick: this.onDeviceFormHide },
|
||||
getStr("responsive.deviceAdderCancel")
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
|
@ -38,12 +41,12 @@ class DeviceList extends PureComponent {
|
|||
|
||||
// Show a remove button for custom devices.
|
||||
const removeDeviceButton = dom.button({
|
||||
id: "device-edit-remove",
|
||||
className: "device-remove-button devtools-button",
|
||||
onClick: () => {
|
||||
onRemoveCustomDevice(device);
|
||||
this.props.onDeviceFormHide();
|
||||
},
|
||||
id: "device-edit-remove",
|
||||
className: "device-remove-button devtools-button",
|
||||
onClick: () => {
|
||||
onRemoveCustomDevice(device);
|
||||
this.props.onDeviceFormHide();
|
||||
},
|
||||
});
|
||||
|
||||
// Show an edit button for custom devices
|
||||
|
@ -64,28 +67,27 @@ class DeviceList extends PureComponent {
|
|||
},
|
||||
// Don't show the remove/edit buttons for a custom device if the form is open.
|
||||
!isDeviceFormShown ? editButton : null,
|
||||
!isDeviceFormShown ? removeDeviceButton : null,
|
||||
!isDeviceFormShown ? removeDeviceButton : null
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { devices, type, onDeviceCheckboxChange } = this.props;
|
||||
|
||||
return (
|
||||
dom.div({ className: "device-list"},
|
||||
devices[type].map(device => {
|
||||
if (type === "custom") {
|
||||
return this.renderCustomDevice(device);
|
||||
}
|
||||
return dom.div(
|
||||
{ className: "device-list" },
|
||||
devices[type].map(device => {
|
||||
if (type === "custom") {
|
||||
return this.renderCustomDevice(device);
|
||||
}
|
||||
|
||||
return Device({
|
||||
device,
|
||||
key: device.name,
|
||||
type,
|
||||
onDeviceCheckboxChange,
|
||||
});
|
||||
})
|
||||
)
|
||||
return Device({
|
||||
device,
|
||||
key: device.name,
|
||||
type,
|
||||
onDeviceCheckboxChange,
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
|
@ -106,8 +109,8 @@ class DeviceModal extends PureComponent {
|
|||
} = this.props;
|
||||
|
||||
const preferredDevices = {
|
||||
"added": new Set(),
|
||||
"removed": new Set(),
|
||||
added: new Set(),
|
||||
removed: new Set(),
|
||||
};
|
||||
|
||||
for (const type of devices.types) {
|
||||
|
@ -147,9 +150,7 @@ class DeviceModal extends PureComponent {
|
|||
}
|
||||
// Escape keycode
|
||||
if (event.keyCode === 27) {
|
||||
const {
|
||||
onUpdateDeviceModal,
|
||||
} = this.props;
|
||||
const { onUpdateDeviceModal } = this.props;
|
||||
onUpdateDeviceModal(false);
|
||||
}
|
||||
}
|
||||
|
@ -179,33 +180,31 @@ class DeviceModal extends PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
return (
|
||||
DeviceForm({
|
||||
formType: "add",
|
||||
device: deviceTemplate,
|
||||
devices: this.props.devices,
|
||||
onDeviceFormHide: this.onDeviceFormHide,
|
||||
onSave: this.onAddCustomDevice,
|
||||
viewportTemplate,
|
||||
})
|
||||
);
|
||||
return DeviceForm({
|
||||
formType: "add",
|
||||
device: deviceTemplate,
|
||||
devices: this.props.devices,
|
||||
onDeviceFormHide: this.onDeviceFormHide,
|
||||
onSave: this.onAddCustomDevice,
|
||||
viewportTemplate,
|
||||
});
|
||||
}
|
||||
|
||||
renderDevices() {
|
||||
const sortedDevices = {};
|
||||
for (const type of this.props.devices.types) {
|
||||
sortedDevices[type] = this.props.devices[type]
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
sortedDevices[type] = this.props.devices[type].sort((a, b) =>
|
||||
a.name.localeCompare(b.name)
|
||||
);
|
||||
|
||||
sortedDevices[type].forEach(device => {
|
||||
device.isChecked = this.state[device.name];
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
this.props.devices.types.map(type => {
|
||||
return sortedDevices[type].length ?
|
||||
dom.div(
|
||||
return this.props.devices.types.map(type => {
|
||||
return sortedDevices[type].length
|
||||
? dom.div(
|
||||
{
|
||||
className: `device-type device-type-${type}`,
|
||||
key: type,
|
||||
|
@ -222,26 +221,22 @@ class DeviceModal extends PureComponent {
|
|||
onRemoveCustomDevice: this.props.onRemoveCustomDevice,
|
||||
})
|
||||
)
|
||||
:
|
||||
null;
|
||||
})
|
||||
);
|
||||
: null;
|
||||
});
|
||||
}
|
||||
|
||||
renderEditForm() {
|
||||
return (
|
||||
DeviceForm({
|
||||
formType: "edit",
|
||||
device: this.state.editingDevice,
|
||||
devices: this.props.devices,
|
||||
onDeviceFormHide: this.onDeviceFormHide,
|
||||
onSave: this.onEditCustomDevice,
|
||||
viewportTemplate: {
|
||||
width: this.state.editingDevice.width,
|
||||
height: this.state.editingDevice.height,
|
||||
},
|
||||
})
|
||||
);
|
||||
return DeviceForm({
|
||||
formType: "edit",
|
||||
device: this.state.editingDevice,
|
||||
devices: this.props.devices,
|
||||
onDeviceFormHide: this.onDeviceFormHide,
|
||||
onSave: this.onEditCustomDevice,
|
||||
viewportTemplate: {
|
||||
width: this.state.editingDevice.width,
|
||||
height: this.state.editingDevice.height,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
renderForm() {
|
||||
|
@ -260,48 +255,43 @@ class DeviceModal extends PureComponent {
|
|||
const { onUpdateDeviceModal } = this.props;
|
||||
const isDeviceFormShown = this.state.deviceFormType;
|
||||
|
||||
return (
|
||||
return dom.div(
|
||||
{
|
||||
id: "device-modal-wrapper",
|
||||
className: this.props.devices.isModalOpen ? "opened" : "closed",
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
id: "device-modal-wrapper",
|
||||
className: this.props.devices.isModalOpen ? "opened" : "closed",
|
||||
},
|
||||
dom.div({ className: "device-modal" },
|
||||
dom.div({ className: "device-modal-header" },
|
||||
!isDeviceFormShown ?
|
||||
dom.header({ className: "device-modal-title" },
|
||||
{ className: "device-modal" },
|
||||
dom.div(
|
||||
{ className: "device-modal-header" },
|
||||
!isDeviceFormShown
|
||||
? dom.header(
|
||||
{ className: "device-modal-title" },
|
||||
getStr("responsive.deviceSettings"),
|
||||
dom.button({
|
||||
id: "device-close-button",
|
||||
className: "devtools-button",
|
||||
onClick: () => onUpdateDeviceModal(false),
|
||||
}),
|
||||
})
|
||||
)
|
||||
:
|
||||
null,
|
||||
!isDeviceFormShown ?
|
||||
dom.button(
|
||||
: null,
|
||||
!isDeviceFormShown
|
||||
? dom.button(
|
||||
{
|
||||
id: "device-add-button",
|
||||
onClick: () => this.onDeviceFormShow("add"),
|
||||
},
|
||||
getStr("responsive.addDevice2")
|
||||
)
|
||||
:
|
||||
null,
|
||||
this.renderForm(),
|
||||
),
|
||||
dom.div({ className: "device-modal-content" },
|
||||
this.renderDevices()
|
||||
),
|
||||
: null,
|
||||
this.renderForm()
|
||||
),
|
||||
dom.div(
|
||||
{
|
||||
className: "modal-overlay",
|
||||
onClick: () => onUpdateDeviceModal(false),
|
||||
}
|
||||
)
|
||||
)
|
||||
dom.div({ className: "device-modal-content" }, this.renderDevices())
|
||||
),
|
||||
dom.div({
|
||||
className: "modal-overlay",
|
||||
onClick: () => onUpdateDeviceModal(false),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,12 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||
const { getStr, getFormatStr } = require("../utils/l10n");
|
||||
const Types = require("../types");
|
||||
|
||||
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"showMenu",
|
||||
"devtools/client/shared/components/menu/utils",
|
||||
true
|
||||
);
|
||||
|
||||
const PIXEL_RATIO_PRESET = [1, 2, 3];
|
||||
|
||||
|
@ -44,9 +49,10 @@ class DevicePixelRatioMenu extends PureComponent {
|
|||
return {
|
||||
label: getFormatStr("responsive.devicePixelRatioOption", value),
|
||||
type: "checkbox",
|
||||
checked: selectedPixelRatio > 0 ?
|
||||
selectedPixelRatio === value :
|
||||
displayPixelRatio === value,
|
||||
checked:
|
||||
selectedPixelRatio > 0
|
||||
? selectedPixelRatio === value
|
||||
: displayPixelRatio === value,
|
||||
click: () => onChangePixelRatio(+value),
|
||||
};
|
||||
});
|
||||
|
@ -64,8 +70,8 @@ class DevicePixelRatioMenu extends PureComponent {
|
|||
selectedPixelRatio,
|
||||
} = this.props;
|
||||
|
||||
const isDisabled = devices.listState !== Types.loadableState.LOADED ||
|
||||
selectedDevice !== "";
|
||||
const isDisabled =
|
||||
devices.listState !== Types.loadableState.LOADED || selectedDevice !== "";
|
||||
|
||||
let title;
|
||||
if (isDisabled) {
|
||||
|
@ -74,18 +80,19 @@ class DevicePixelRatioMenu extends PureComponent {
|
|||
title = getStr("responsive.changeDevicePixelRatio");
|
||||
}
|
||||
|
||||
return (
|
||||
dom.button(
|
||||
{
|
||||
id: "device-pixel-ratio-menu",
|
||||
className: "devtools-button devtools-dropdown-button",
|
||||
disabled: isDisabled,
|
||||
title,
|
||||
onClick: this.onShowDevicePixelMenu,
|
||||
},
|
||||
dom.span({ className: "title" },
|
||||
getFormatStr("responsive.devicePixelRatioOption",
|
||||
selectedPixelRatio || displayPixelRatio)
|
||||
return dom.button(
|
||||
{
|
||||
id: "device-pixel-ratio-menu",
|
||||
className: "devtools-button devtools-dropdown-button",
|
||||
disabled: isDisabled,
|
||||
title,
|
||||
onClick: this.onShowDevicePixelMenu,
|
||||
},
|
||||
dom.span(
|
||||
{ className: "title" },
|
||||
getFormatStr(
|
||||
"responsive.devicePixelRatioOption",
|
||||
selectedPixelRatio || displayPixelRatio
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -11,7 +11,12 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||
const { getStr } = require("../utils/l10n");
|
||||
const Types = require("../types");
|
||||
|
||||
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"showMenu",
|
||||
"devtools/client/shared/components/menu/utils",
|
||||
true
|
||||
);
|
||||
|
||||
class DeviceSelector extends PureComponent {
|
||||
static get propTypes() {
|
||||
|
@ -77,23 +82,19 @@ class DeviceSelector extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
devices,
|
||||
selectedDevice,
|
||||
} = this.props;
|
||||
const { devices, selectedDevice } = this.props;
|
||||
|
||||
return (
|
||||
dom.button(
|
||||
{
|
||||
id: "device-selector",
|
||||
className: "devtools-button devtools-dropdown-button",
|
||||
disabled: devices.listState !== Types.loadableState.LOADED,
|
||||
title: selectedDevice,
|
||||
onClick: this.onShowDeviceMenu,
|
||||
},
|
||||
dom.span({ className: "title" },
|
||||
selectedDevice || getStr("responsive.responsiveMode")
|
||||
)
|
||||
return dom.button(
|
||||
{
|
||||
id: "device-selector",
|
||||
className: "devtools-button devtools-dropdown-button",
|
||||
disabled: devices.listState !== Types.loadableState.LOADED,
|
||||
title: selectedDevice,
|
||||
onClick: this.onShowDeviceMenu,
|
||||
},
|
||||
dom.span(
|
||||
{ className: "title" },
|
||||
selectedDevice || getStr("responsive.responsiveMode")
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
|
||||
|
@ -52,10 +55,7 @@ class ResizableViewport extends PureComponent {
|
|||
}
|
||||
|
||||
onRemoveDeviceAssociation() {
|
||||
const {
|
||||
viewport,
|
||||
onRemoveDeviceAssociation,
|
||||
} = this.props;
|
||||
const { viewport, onRemoveDeviceAssociation } = this.props;
|
||||
|
||||
onRemoveDeviceAssociation(viewport.id);
|
||||
}
|
||||
|
@ -98,10 +98,7 @@ class ResizableViewport extends PureComponent {
|
|||
}
|
||||
|
||||
// Update the viewport store with the new width and height.
|
||||
const {
|
||||
doResizeViewport,
|
||||
viewport,
|
||||
} = this.props;
|
||||
const { doResizeViewport, viewport } = this.props;
|
||||
doResizeViewport(viewport.id, width, height);
|
||||
// Change the device selector back to an unselected device
|
||||
// TODO: Bug 1332754: Logic like this probably belongs in the action creator.
|
||||
|
@ -166,42 +163,42 @@ class ResizableViewport extends PureComponent {
|
|||
contentClass += " resizing";
|
||||
}
|
||||
|
||||
return (
|
||||
dom.div({ className: "viewport" },
|
||||
dom.div({ className: "resizable-viewport" },
|
||||
dom.div(
|
||||
{
|
||||
className: contentClass,
|
||||
style: {
|
||||
width: viewport.width + "px",
|
||||
height: viewport.height + "px",
|
||||
},
|
||||
return dom.div(
|
||||
{ className: "viewport" },
|
||||
dom.div(
|
||||
{ className: "resizable-viewport" },
|
||||
dom.div(
|
||||
{
|
||||
className: contentClass,
|
||||
style: {
|
||||
width: viewport.width + "px",
|
||||
height: viewport.height + "px",
|
||||
},
|
||||
Browser({
|
||||
swapAfterMount,
|
||||
userContextId: viewport.userContextId,
|
||||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
})
|
||||
),
|
||||
dom.div({
|
||||
className: resizeHandleClass,
|
||||
onMouseDown: this.onResizeStart,
|
||||
}),
|
||||
dom.div({
|
||||
ref: "resizeBarX",
|
||||
className: "viewport-horizontal-resize-handle",
|
||||
onMouseDown: this.onResizeStart,
|
||||
}),
|
||||
dom.div({
|
||||
ref: "resizeBarY",
|
||||
className: "viewport-vertical-resize-handle",
|
||||
onMouseDown: this.onResizeStart,
|
||||
},
|
||||
Browser({
|
||||
swapAfterMount,
|
||||
userContextId: viewport.userContextId,
|
||||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
})
|
||||
)
|
||||
),
|
||||
dom.div({
|
||||
className: resizeHandleClass,
|
||||
onMouseDown: this.onResizeStart,
|
||||
}),
|
||||
dom.div({
|
||||
ref: "resizeBarX",
|
||||
className: "viewport-horizontal-resize-handle",
|
||||
onMouseDown: this.onResizeStart,
|
||||
}),
|
||||
dom.div({
|
||||
ref: "resizeBarY",
|
||||
className: "viewport-vertical-resize-handle",
|
||||
onMouseDown: this.onResizeStart,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,12 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
|
|||
|
||||
const { getStr } = require("../utils/l10n");
|
||||
|
||||
loader.lazyRequireGetter(this, "showMenu", "devtools/client/shared/components/menu/utils", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"showMenu",
|
||||
"devtools/client/shared/components/menu/utils",
|
||||
true
|
||||
);
|
||||
|
||||
class SettingsMenu extends PureComponent {
|
||||
static get propTypes() {
|
||||
|
@ -91,13 +96,11 @@ class SettingsMenu extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
dom.button({
|
||||
id: "settings-button",
|
||||
className: "devtools-button",
|
||||
onClick: this.onToggleSettingMenu,
|
||||
})
|
||||
);
|
||||
return dom.button({
|
||||
id: "settings-button",
|
||||
className: "devtools-button",
|
||||
onClick: this.onToggleSettingMenu,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
|
|||
|
||||
const DevicePixelRatioMenu = createFactory(require("./DevicePixelRatioMenu"));
|
||||
const DeviceSelector = createFactory(require("./DeviceSelector"));
|
||||
const NetworkThrottlingMenu = createFactory(require("devtools/client/shared/components/throttling/NetworkThrottlingMenu"));
|
||||
const NetworkThrottlingMenu = createFactory(
|
||||
require("devtools/client/shared/components/throttling/NetworkThrottlingMenu")
|
||||
);
|
||||
const SettingsMenu = createFactory(require("./SettingsMenu"));
|
||||
const ViewportDimension = createFactory(require("./ViewportDimension"));
|
||||
|
||||
|
@ -59,20 +61,19 @@ class Toolbar extends PureComponent {
|
|||
}
|
||||
|
||||
renderUserAgent() {
|
||||
const {
|
||||
onChangeUserAgent,
|
||||
showUserAgentInput,
|
||||
} = this.props;
|
||||
const { onChangeUserAgent, showUserAgentInput } = this.props;
|
||||
|
||||
if (!showUserAgentInput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return createElement(Fragment, null,
|
||||
return createElement(
|
||||
Fragment,
|
||||
null,
|
||||
UserAgentInput({
|
||||
onChangeUserAgent,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
dom.div({ className: "devtools-separator" })
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -104,86 +105,87 @@ class Toolbar extends PureComponent {
|
|||
viewport,
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
dom.header(
|
||||
{
|
||||
id: "toolbar",
|
||||
className: [
|
||||
leftAlignmentEnabled ? "left-aligned" : "",
|
||||
showUserAgentInput ? "user-agent" : "",
|
||||
].join(" ").trim(),
|
||||
},
|
||||
dom.div(
|
||||
{ id: "toolbar-center-controls" },
|
||||
DeviceSelector({
|
||||
devices,
|
||||
onChangeDevice,
|
||||
doResizeViewport,
|
||||
onUpdateDeviceModal,
|
||||
selectedDevice,
|
||||
viewportId: viewport.id,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
ViewportDimension({
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
viewport,
|
||||
}),
|
||||
dom.button({
|
||||
id: "rotate-button",
|
||||
className: `devtools-button viewport-orientation-${
|
||||
viewport.width > viewport.height ? "landscape" : "portrait"
|
||||
}`,
|
||||
onClick: () => onRotateViewport(viewport.id),
|
||||
title: getStr("responsive.rotate"),
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
DevicePixelRatioMenu({
|
||||
devices,
|
||||
displayPixelRatio,
|
||||
onChangePixelRatio,
|
||||
selectedDevice,
|
||||
selectedPixelRatio,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
NetworkThrottlingMenu({
|
||||
networkThrottling,
|
||||
onChangeNetworkThrottling,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
this.renderUserAgent(),
|
||||
dom.button({
|
||||
id: "touch-simulation-button",
|
||||
className: "devtools-button" +
|
||||
(touchSimulationEnabled ? " checked" : ""),
|
||||
title: (touchSimulationEnabled ?
|
||||
getStr("responsive.disableTouch") : getStr("responsive.enableTouch")),
|
||||
onClick: () => onChangeTouchSimulation(!touchSimulationEnabled),
|
||||
})
|
||||
),
|
||||
dom.div(
|
||||
{ id: "toolbar-end-controls" },
|
||||
dom.button({
|
||||
id: "screenshot-button",
|
||||
className: "devtools-button",
|
||||
title: getStr("responsive.screenshot"),
|
||||
onClick: onScreenshot,
|
||||
disabled: screenshot.isCapturing,
|
||||
}),
|
||||
SettingsMenu({
|
||||
onToggleLeftAlignment,
|
||||
onToggleReloadOnTouchSimulation,
|
||||
onToggleReloadOnUserAgent,
|
||||
onToggleUserAgentInput,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
dom.button({
|
||||
id: "exit-button",
|
||||
className: "devtools-button",
|
||||
title: getStr("responsive.exit"),
|
||||
onClick: onExit,
|
||||
})
|
||||
)
|
||||
return dom.header(
|
||||
{
|
||||
id: "toolbar",
|
||||
className: [
|
||||
leftAlignmentEnabled ? "left-aligned" : "",
|
||||
showUserAgentInput ? "user-agent" : "",
|
||||
]
|
||||
.join(" ")
|
||||
.trim(),
|
||||
},
|
||||
dom.div(
|
||||
{ id: "toolbar-center-controls" },
|
||||
DeviceSelector({
|
||||
devices,
|
||||
onChangeDevice,
|
||||
doResizeViewport,
|
||||
onUpdateDeviceModal,
|
||||
selectedDevice,
|
||||
viewportId: viewport.id,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
ViewportDimension({
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
viewport,
|
||||
}),
|
||||
dom.button({
|
||||
id: "rotate-button",
|
||||
className: `devtools-button viewport-orientation-${
|
||||
viewport.width > viewport.height ? "landscape" : "portrait"
|
||||
}`,
|
||||
onClick: () => onRotateViewport(viewport.id),
|
||||
title: getStr("responsive.rotate"),
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
DevicePixelRatioMenu({
|
||||
devices,
|
||||
displayPixelRatio,
|
||||
onChangePixelRatio,
|
||||
selectedDevice,
|
||||
selectedPixelRatio,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
NetworkThrottlingMenu({
|
||||
networkThrottling,
|
||||
onChangeNetworkThrottling,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
this.renderUserAgent(),
|
||||
dom.button({
|
||||
id: "touch-simulation-button",
|
||||
className:
|
||||
"devtools-button" + (touchSimulationEnabled ? " checked" : ""),
|
||||
title: touchSimulationEnabled
|
||||
? getStr("responsive.disableTouch")
|
||||
: getStr("responsive.enableTouch"),
|
||||
onClick: () => onChangeTouchSimulation(!touchSimulationEnabled),
|
||||
})
|
||||
),
|
||||
dom.div(
|
||||
{ id: "toolbar-end-controls" },
|
||||
dom.button({
|
||||
id: "screenshot-button",
|
||||
className: "devtools-button",
|
||||
title: getStr("responsive.screenshot"),
|
||||
onClick: onScreenshot,
|
||||
disabled: screenshot.isCapturing,
|
||||
}),
|
||||
SettingsMenu({
|
||||
onToggleLeftAlignment,
|
||||
onToggleReloadOnTouchSimulation,
|
||||
onToggleReloadOnUserAgent,
|
||||
onToggleUserAgentInput,
|
||||
}),
|
||||
dom.div({ className: "devtools-separator" }),
|
||||
dom.button({
|
||||
id: "exit-button",
|
||||
className: "devtools-button",
|
||||
title: getStr("responsive.exit"),
|
||||
onClick: onExit,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class UserAgentInput extends PureComponent {
|
|||
onChange({ target }) {
|
||||
const value = target.value;
|
||||
|
||||
this.setState((prevState) => {
|
||||
this.setState(prevState => {
|
||||
return {
|
||||
...prevState,
|
||||
value,
|
||||
|
@ -71,19 +71,18 @@ class UserAgentInput extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
dom.label({ id: "user-agent-label" },
|
||||
"UA:",
|
||||
dom.input({
|
||||
id: "user-agent-input",
|
||||
class: "text-input",
|
||||
onChange: this.onChange,
|
||||
onKeyUp: this.onKeyUp,
|
||||
placeholder: getStr("responsive.customUserAgent"),
|
||||
type: "text",
|
||||
value: this.state.value,
|
||||
})
|
||||
)
|
||||
return dom.label(
|
||||
{ id: "user-agent-label" },
|
||||
"UA:",
|
||||
dom.input({
|
||||
id: "user-agent-input",
|
||||
class: "text-input",
|
||||
onChange: this.onChange,
|
||||
onKeyUp: this.onKeyUp,
|
||||
placeholder: getStr("responsive.customUserAgent"),
|
||||
type: "text",
|
||||
value: this.state.value,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,9 @@ class ViewportDimension extends PureComponent {
|
|||
* and false otherwise.
|
||||
*/
|
||||
isInputValid(value) {
|
||||
return /^\d{2,4}$/.test(value) && parseInt(value, 10) >= MIN_VIEWPORT_DIMENSION;
|
||||
return (
|
||||
/^\d{2,4}$/.test(value) && parseInt(value, 10) >= MIN_VIEWPORT_DIMENSION
|
||||
);
|
||||
}
|
||||
|
||||
onInputBlur() {
|
||||
|
@ -76,17 +78,23 @@ class ViewportDimension extends PureComponent {
|
|||
}
|
||||
|
||||
if (this.widthInput == target) {
|
||||
this.setState({
|
||||
width: target.value,
|
||||
isWidthValid: this.isInputValid(target.value),
|
||||
}, callback);
|
||||
this.setState(
|
||||
{
|
||||
width: target.value,
|
||||
isWidthValid: this.isInputValid(target.value),
|
||||
},
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
if (this.heightInput == target) {
|
||||
this.setState({
|
||||
height: target.value,
|
||||
isHeightValid: this.isInputValid(target.value),
|
||||
}, callback);
|
||||
this.setState(
|
||||
{
|
||||
height: target.value,
|
||||
isHeightValid: this.isInputValid(target.value),
|
||||
},
|
||||
callback
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,8 +156,11 @@ class ViewportDimension extends PureComponent {
|
|||
onRemoveDeviceAssociation(viewport.id);
|
||||
}
|
||||
|
||||
doResizeViewport(viewport.id,
|
||||
parseInt(this.state.width, 10), parseInt(this.state.height, 10));
|
||||
doResizeViewport(
|
||||
viewport.id,
|
||||
parseInt(this.state.width, 10),
|
||||
parseInt(this.state.height, 10)
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -158,14 +169,17 @@ class ViewportDimension extends PureComponent {
|
|||
className:
|
||||
"viewport-dimension" +
|
||||
(this.state.isEditing ? " editing" : "") +
|
||||
(!this.state.isWidthValid || !this.state.isHeightValid ? " invalid" : ""),
|
||||
(!this.state.isWidthValid || !this.state.isHeightValid
|
||||
? " invalid"
|
||||
: ""),
|
||||
},
|
||||
dom.input({
|
||||
ref: input => {
|
||||
this.widthInput = input;
|
||||
},
|
||||
className: "text-input viewport-dimension-input" +
|
||||
(this.state.isWidthValid ? "" : " invalid"),
|
||||
className:
|
||||
"text-input viewport-dimension-input" +
|
||||
(this.state.isWidthValid ? "" : " invalid"),
|
||||
size: 4,
|
||||
type: "number",
|
||||
value: this.state.width,
|
||||
|
@ -175,15 +189,19 @@ class ViewportDimension extends PureComponent {
|
|||
onKeyDown: this.onInputKeyDown,
|
||||
onKeyUp: this.onInputKeyUp,
|
||||
}),
|
||||
dom.span({
|
||||
className: "viewport-dimension-separator",
|
||||
}, "×"),
|
||||
dom.span(
|
||||
{
|
||||
className: "viewport-dimension-separator",
|
||||
},
|
||||
"×"
|
||||
),
|
||||
dom.input({
|
||||
ref: input => {
|
||||
this.heightInput = input;
|
||||
},
|
||||
className: "text-input viewport-dimension-input" +
|
||||
(this.state.isHeightValid ? "" : " invalid"),
|
||||
className:
|
||||
"text-input viewport-dimension-input" +
|
||||
(this.state.isHeightValid ? "" : " invalid"),
|
||||
size: 4,
|
||||
type: "number",
|
||||
value: this.state.height,
|
||||
|
|
|
@ -4,7 +4,10 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
PureComponent,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
@ -50,40 +53,40 @@ class Viewports extends PureComponent {
|
|||
// justify-content to start so that the left-most viewport is visible when there's
|
||||
// horizontal overflow. That is when the horizontal space become smaller than the
|
||||
// viewports and a scrollbar appears, then the first viewport will still be visible.
|
||||
if (leftAlignmentEnabled ||
|
||||
(viewportSize && viewportSize.width > window.innerWidth)) {
|
||||
if (
|
||||
leftAlignmentEnabled ||
|
||||
(viewportSize && viewportSize.width > window.innerWidth)
|
||||
) {
|
||||
justifyContent = "start";
|
||||
}
|
||||
|
||||
return (
|
||||
return dom.div(
|
||||
{
|
||||
id: "viewports-container",
|
||||
style: {
|
||||
justifyContent,
|
||||
},
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
id: "viewports-container",
|
||||
style: {
|
||||
justifyContent,
|
||||
},
|
||||
id: "viewports",
|
||||
className: leftAlignmentEnabled ? "left-aligned" : "",
|
||||
},
|
||||
dom.div(
|
||||
{
|
||||
id: "viewports",
|
||||
className: leftAlignmentEnabled ? "left-aligned" : "",
|
||||
},
|
||||
viewports.map((viewport, i) => {
|
||||
return ResizableViewport({
|
||||
key: viewport.id,
|
||||
leftAlignmentEnabled,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onResizeViewport,
|
||||
screenshot,
|
||||
swapAfterMount: i == 0,
|
||||
viewport,
|
||||
});
|
||||
})
|
||||
)
|
||||
viewports.map((viewport, i) => {
|
||||
return ResizableViewport({
|
||||
key: viewport.id,
|
||||
leftAlignmentEnabled,
|
||||
onBrowserMounted,
|
||||
onChangeViewportOrientation,
|
||||
onContentResize,
|
||||
onRemoveDeviceAssociation,
|
||||
doResizeViewport,
|
||||
onResizeViewport,
|
||||
screenshot,
|
||||
swapAfterMount: i == 0,
|
||||
viewport,
|
||||
});
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -6,16 +6,19 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { BrowserLoader } =
|
||||
ChromeUtils.import("resource://devtools/client/shared/browser-loader.js");
|
||||
const { BrowserLoader } = ChromeUtils.import(
|
||||
"resource://devtools/client/shared/browser-loader.js"
|
||||
);
|
||||
const { require } = BrowserLoader({
|
||||
baseURI: "resource://devtools/client/responsive/",
|
||||
window,
|
||||
});
|
||||
const Telemetry = require("devtools/client/shared/telemetry");
|
||||
|
||||
const { createFactory, createElement } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
const {
|
||||
createFactory,
|
||||
createElement,
|
||||
} = require("devtools/client/shared/vendor/react");
|
||||
const ReactDOM = require("devtools/client/shared/vendor/react-dom");
|
||||
const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
|
@ -30,7 +33,6 @@ const { changeDisplayPixelRatio } = require("./actions/ui");
|
|||
window.require = require;
|
||||
|
||||
const bootstrap = {
|
||||
|
||||
telemetry: new Telemetry(),
|
||||
|
||||
store: null,
|
||||
|
@ -40,7 +42,7 @@ const bootstrap = {
|
|||
// toolbox session id.
|
||||
this.telemetry.toolOpened("responsive", -1, this);
|
||||
|
||||
const store = this.store = Store();
|
||||
const store = (this.store = Store());
|
||||
const provider = createElement(Provider, { store }, App());
|
||||
ReactDOM.render(provider, document.querySelector("#root"));
|
||||
message.post(window, "init:done");
|
||||
|
@ -69,7 +71,6 @@ const bootstrap = {
|
|||
}
|
||||
this.store.dispatch(action);
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// manager.js sends a message to signal init
|
||||
|
@ -83,9 +84,13 @@ message.wait(window, "post-init").then(() => {
|
|||
});
|
||||
});
|
||||
|
||||
window.addEventListener("unload", function() {
|
||||
bootstrap.destroy();
|
||||
}, {once: true});
|
||||
window.addEventListener(
|
||||
"unload",
|
||||
function() {
|
||||
bootstrap.destroy();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
// Allows quick testing of actions from the console
|
||||
window.dispatch = action => bootstrap.dispatch(action);
|
||||
|
|
|
@ -10,26 +10,79 @@ const Services = require("Services");
|
|||
const EventEmitter = require("devtools/shared/event-emitter");
|
||||
const { getOrientation } = require("./utils/orientation");
|
||||
|
||||
loader.lazyRequireGetter(this, "DebuggerClient", "devtools/shared/client/debugger-client", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"DebuggerClient",
|
||||
"devtools/shared/client/debugger-client",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(this, "DebuggerServer", "devtools/server/main", true);
|
||||
loader.lazyRequireGetter(this, "throttlingProfiles", "devtools/client/shared/components/throttling/profiles");
|
||||
loader.lazyRequireGetter(this, "SettingOnboardingTooltip", "devtools/client/responsive/setting-onboarding-tooltip");
|
||||
loader.lazyRequireGetter(this, "swapToInnerBrowser", "devtools/client/responsive/browser/swap", true);
|
||||
loader.lazyRequireGetter(this, "startup", "devtools/client/responsive/utils/window", true);
|
||||
loader.lazyRequireGetter(this, "message", "devtools/client/responsive/utils/message");
|
||||
loader.lazyRequireGetter(this, "showNotification", "devtools/client/responsive/utils/notification", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"throttlingProfiles",
|
||||
"devtools/client/shared/components/throttling/profiles"
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"SettingOnboardingTooltip",
|
||||
"devtools/client/responsive/setting-onboarding-tooltip"
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"swapToInnerBrowser",
|
||||
"devtools/client/responsive/browser/swap",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"startup",
|
||||
"devtools/client/responsive/utils/window",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"message",
|
||||
"devtools/client/responsive/utils/message"
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"showNotification",
|
||||
"devtools/client/responsive/utils/notification",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(this, "l10n", "devtools/client/responsive/utils/l10n");
|
||||
loader.lazyRequireGetter(this, "EmulationFront", "devtools/shared/fronts/emulation", true);
|
||||
loader.lazyRequireGetter(this, "PriorityLevels", "devtools/client/shared/components/NotificationBox", true);
|
||||
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"EmulationFront",
|
||||
"devtools/shared/fronts/emulation",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"PriorityLevels",
|
||||
"devtools/client/shared/components/NotificationBox",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"TargetFactory",
|
||||
"devtools/client/framework/target",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"gDevTools",
|
||||
"devtools/client/framework/devtools",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(this, "Telemetry", "devtools/client/shared/telemetry");
|
||||
loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage");
|
||||
|
||||
const TOOL_URL = "chrome://devtools/content/responsive/index.xhtml";
|
||||
|
||||
const RELOAD_CONDITION_PREF_PREFIX = "devtools.responsive.reloadConditions.";
|
||||
const RELOAD_NOTIFICATION_PREF = "devtools.responsive.reloadNotification.enabled";
|
||||
const RELOAD_NOTIFICATION_PREF =
|
||||
"devtools.responsive.reloadNotification.enabled";
|
||||
const SHOW_SETTING_TOOLTIP_PREF = "devtools.responsive.show-setting-tooltip";
|
||||
|
||||
function debug(msg) {
|
||||
|
@ -40,7 +93,7 @@ function debug(msg) {
|
|||
* ResponsiveUIManager is the external API for the browser UI, etc. to use when
|
||||
* opening and closing the responsive UI.
|
||||
*/
|
||||
const ResponsiveUIManager = exports.ResponsiveUIManager = {
|
||||
const ResponsiveUIManager = (exports.ResponsiveUIManager = {
|
||||
_telemetry: new Telemetry(),
|
||||
|
||||
activeTabs: new Map(),
|
||||
|
@ -128,9 +181,9 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
|
|||
}
|
||||
|
||||
tel.recordEvent("activate", "responsive_design", null, {
|
||||
"host": hostType,
|
||||
"width": Math.ceil(window.outerWidth / 50) * 50,
|
||||
"session_id": toolbox ? toolbox.sessionId : -1,
|
||||
host: hostType,
|
||||
width: Math.ceil(window.outerWidth / 50) * 50,
|
||||
session_id: toolbox ? toolbox.sessionId : -1,
|
||||
});
|
||||
|
||||
// Track opens keyed by the UI entry point used.
|
||||
|
@ -191,9 +244,9 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
|
|||
const hostType = toolbox ? toolbox.hostType : "none";
|
||||
const t = this._telemetry;
|
||||
t.recordEvent("deactivate", "responsive_design", null, {
|
||||
"host": hostType,
|
||||
"width": Math.ceil(window.outerWidth / 50) * 50,
|
||||
"session_id": toolbox ? toolbox.sessionId : -1,
|
||||
host: hostType,
|
||||
width: Math.ceil(window.outerWidth / 50) * 50,
|
||||
session_id: toolbox ? toolbox.sessionId : -1,
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -231,7 +284,7 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
|
|||
return this.activeTabs.get(tab);
|
||||
},
|
||||
|
||||
handleMenuCheck({target}) {
|
||||
handleMenuCheck({ target }) {
|
||||
ResponsiveUIManager.setMenuCheckFor(target);
|
||||
},
|
||||
|
||||
|
@ -263,7 +316,7 @@ const ResponsiveUIManager = exports.ResponsiveUIManager = {
|
|||
priority: PriorityLevels.PRIORITY_CRITICAL_MEDIUM,
|
||||
});
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
EventEmitter.decorate(ResponsiveUIManager);
|
||||
|
||||
|
@ -280,7 +333,6 @@ function ResponsiveUI(window, tab) {
|
|||
}
|
||||
|
||||
ResponsiveUI.prototype = {
|
||||
|
||||
/**
|
||||
* The main browser chrome window (that holds many tabs).
|
||||
*/
|
||||
|
@ -337,7 +389,7 @@ ResponsiveUI.prototype = {
|
|||
tab: this.tab,
|
||||
containerURL: TOOL_URL,
|
||||
async getInnerBrowser(containerBrowser) {
|
||||
const toolWindow = ui.toolWindow = containerBrowser.contentWindow;
|
||||
const toolWindow = (ui.toolWindow = containerBrowser.contentWindow);
|
||||
toolWindow.addEventListener("message", ui);
|
||||
debug("Wait until init from inner");
|
||||
await message.request(toolWindow, "init");
|
||||
|
@ -387,8 +439,9 @@ ResponsiveUI.prototype = {
|
|||
|
||||
// Show the settings onboarding tooltip
|
||||
if (Services.prefs.getBoolPref(SHOW_SETTING_TOOLTIP_PREF)) {
|
||||
this.settingOnboardingTooltip =
|
||||
new SettingOnboardingTooltip(ui.toolWindow.document);
|
||||
this.settingOnboardingTooltip = new SettingOnboardingTooltip(
|
||||
ui.toolWindow.document
|
||||
);
|
||||
}
|
||||
|
||||
// Re-apply our cached zoom levels. Other Zoom UI update events have finished
|
||||
|
@ -421,10 +474,13 @@ ResponsiveUI.prototype = {
|
|||
// gracefully, but that shouldn't be a problem since the tab will go away.
|
||||
// So, skip any waiting when we're about to close the tab.
|
||||
const isTabDestroyed = !this.tab.linkedBrowser;
|
||||
const isWindowClosing = (options && options.reason === "unload") || isTabDestroyed;
|
||||
const isWindowClosing =
|
||||
(options && options.reason === "unload") || isTabDestroyed;
|
||||
const isTabContentDestroying =
|
||||
isWindowClosing || (options && (options.reason === "TabClose" ||
|
||||
options.reason === "BeforeTabRemotenessChange"));
|
||||
isWindowClosing ||
|
||||
(options &&
|
||||
(options.reason === "TabClose" ||
|
||||
options.reason === "BeforeTabRemotenessChange"));
|
||||
|
||||
// Ensure init has finished before starting destroy
|
||||
if (!isTabContentDestroying) {
|
||||
|
@ -447,10 +503,11 @@ ResponsiveUI.prototype = {
|
|||
let reloadNeeded = false;
|
||||
await this.updateDPPX();
|
||||
await this.updateNetworkThrottling();
|
||||
reloadNeeded |= await this.updateUserAgent() &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |= await this.updateTouchSimulation() &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
reloadNeeded |=
|
||||
(await this.updateUserAgent()) && this.reloadOnChange("userAgent");
|
||||
reloadNeeded |=
|
||||
(await this.updateTouchSimulation()) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
}
|
||||
|
@ -592,10 +649,12 @@ ResponsiveUI.prototype = {
|
|||
const { type, angle } = getOrientation(device, viewport);
|
||||
await this.updateScreenOrientation(type, angle);
|
||||
|
||||
reloadNeeded |= await this.updateUserAgent(userAgent) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |= await this.updateTouchSimulation(touch) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
reloadNeeded |=
|
||||
(await this.updateUserAgent(userAgent)) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |=
|
||||
(await this.updateTouchSimulation(touch)) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
}
|
||||
|
@ -617,8 +676,9 @@ ResponsiveUI.prototype = {
|
|||
|
||||
async onChangeTouchSimulation(event) {
|
||||
const { enabled } = event.data;
|
||||
const reloadNeeded = await this.updateTouchSimulation(enabled) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
const reloadNeeded =
|
||||
(await this.updateTouchSimulation(enabled)) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
}
|
||||
|
@ -628,8 +688,9 @@ ResponsiveUI.prototype = {
|
|||
|
||||
async onChangeUserAgent(event) {
|
||||
const { userAgent } = event.data;
|
||||
const reloadNeeded = await this.updateUserAgent(userAgent) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
const reloadNeeded =
|
||||
(await this.updateUserAgent(userAgent)) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
}
|
||||
|
@ -652,10 +713,11 @@ ResponsiveUI.prototype = {
|
|||
async onRemoveDeviceAssociation() {
|
||||
let reloadNeeded = false;
|
||||
await this.updateDPPX();
|
||||
reloadNeeded |= await this.updateUserAgent() &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |= await this.updateTouchSimulation() &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
reloadNeeded |=
|
||||
(await this.updateUserAgent()) && this.reloadOnChange("userAgent");
|
||||
reloadNeeded |=
|
||||
(await this.updateTouchSimulation()) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
}
|
||||
|
@ -680,36 +742,54 @@ ResponsiveUI.prototype = {
|
|||
* Restores the previous state of RDM.
|
||||
*/
|
||||
async restoreState() {
|
||||
const deviceState = await asyncStorage.getItem("devtools.responsive.deviceState");
|
||||
const deviceState = await asyncStorage.getItem(
|
||||
"devtools.responsive.deviceState"
|
||||
);
|
||||
if (deviceState) {
|
||||
// Return if there is a device state to restore, this will be done when the
|
||||
// device list is loaded after the post-init.
|
||||
return;
|
||||
}
|
||||
|
||||
const height =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.height", 0);
|
||||
const pixelRatio =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.pixelRatio", 0);
|
||||
const touchSimulationEnabled =
|
||||
Services.prefs.getBoolPref("devtools.responsive.touchSimulation.enabled", false);
|
||||
const userAgent = Services.prefs.getCharPref("devtools.responsive.userAgent", "");
|
||||
const width =
|
||||
Services.prefs.getIntPref("devtools.responsive.viewport.width", 0);
|
||||
const height = Services.prefs.getIntPref(
|
||||
"devtools.responsive.viewport.height",
|
||||
0
|
||||
);
|
||||
const pixelRatio = Services.prefs.getIntPref(
|
||||
"devtools.responsive.viewport.pixelRatio",
|
||||
0
|
||||
);
|
||||
const touchSimulationEnabled = Services.prefs.getBoolPref(
|
||||
"devtools.responsive.touchSimulation.enabled",
|
||||
false
|
||||
);
|
||||
const userAgent = Services.prefs.getCharPref(
|
||||
"devtools.responsive.userAgent",
|
||||
""
|
||||
);
|
||||
const width = Services.prefs.getIntPref(
|
||||
"devtools.responsive.viewport.width",
|
||||
0
|
||||
);
|
||||
|
||||
let reloadNeeded = false;
|
||||
const { type, angle } = this.getInitialViewportOrientation({ width, height });
|
||||
const { type, angle } = this.getInitialViewportOrientation({
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
await this.updateDPPX(pixelRatio);
|
||||
await this.updateScreenOrientation(type, angle);
|
||||
|
||||
if (touchSimulationEnabled) {
|
||||
reloadNeeded |= await this.updateTouchSimulation(touchSimulationEnabled) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
reloadNeeded |=
|
||||
(await this.updateTouchSimulation(touchSimulationEnabled)) &&
|
||||
this.reloadOnChange("touchSimulation");
|
||||
}
|
||||
if (userAgent) {
|
||||
reloadNeeded |= await this.updateUserAgent(userAgent) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
reloadNeeded |=
|
||||
(await this.updateUserAgent(userAgent)) &&
|
||||
this.reloadOnChange("userAgent");
|
||||
}
|
||||
if (reloadNeeded) {
|
||||
this.getViewportBrowser().reload();
|
||||
|
@ -780,15 +860,19 @@ ResponsiveUI.prototype = {
|
|||
async updateTouchSimulation(enabled) {
|
||||
let reloadNeeded;
|
||||
if (enabled) {
|
||||
const metaViewportEnabled =
|
||||
Services.prefs.getBoolPref("devtools.responsive.metaViewport.enabled", false);
|
||||
const metaViewportEnabled = Services.prefs.getBoolPref(
|
||||
"devtools.responsive.metaViewport.enabled",
|
||||
false
|
||||
);
|
||||
|
||||
reloadNeeded = await this.emulationFront.setTouchEventsOverride(
|
||||
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED);
|
||||
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
|
||||
);
|
||||
|
||||
if (metaViewportEnabled) {
|
||||
reloadNeeded |= await this.emulationFront.setMetaViewportOverride(
|
||||
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED);
|
||||
Ci.nsIDocShell.META_VIEWPORT_OVERRIDE_ENABLED
|
||||
);
|
||||
}
|
||||
} else {
|
||||
reloadNeeded = await this.emulationFront.clearTouchEventsOverride();
|
||||
|
@ -813,13 +897,18 @@ ResponsiveUI.prototype = {
|
|||
*/
|
||||
async updateScreenOrientation(type, angle, isViewportRotated = false) {
|
||||
const targetFront = await this.client.mainRoot.getTab();
|
||||
const simulateOrientationChangeSupported =
|
||||
await targetFront.actorHasMethod("emulation", "simulateScreenOrientationChange");
|
||||
const simulateOrientationChangeSupported = await targetFront.actorHasMethod(
|
||||
"emulation",
|
||||
"simulateScreenOrientationChange"
|
||||
);
|
||||
|
||||
// Ensure that simulateScreenOrientationChange is supported.
|
||||
if (simulateOrientationChangeSupported) {
|
||||
await this.emulationFront.simulateScreenOrientationChange(type, angle,
|
||||
isViewportRotated);
|
||||
await this.emulationFront.simulateScreenOrientationChange(
|
||||
type,
|
||||
angle,
|
||||
isViewportRotated
|
||||
);
|
||||
}
|
||||
|
||||
// Used by tests.
|
||||
|
|
|
@ -26,7 +26,6 @@ const INITIAL_DEVICES = {
|
|||
};
|
||||
|
||||
const reducers = {
|
||||
|
||||
[ADD_DEVICE](devices, { device, deviceType }) {
|
||||
return {
|
||||
...devices,
|
||||
|
@ -114,7 +113,6 @@ const reducers = {
|
|||
modalOpenedFromViewport,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = function(devices = INITIAL_DEVICES, action) {
|
||||
|
|
|
@ -14,7 +14,6 @@ const INITIAL_SCREENSHOT = {
|
|||
};
|
||||
|
||||
const reducers = {
|
||||
|
||||
[TAKE_SCREENSHOT_END](screenshot, action) {
|
||||
return {
|
||||
...screenshot,
|
||||
|
|
|
@ -17,7 +17,8 @@ const {
|
|||
} = require("../actions/index");
|
||||
|
||||
const LEFT_ALIGNMENT_ENABLED = "devtools.responsive.leftAlignViewport.enabled";
|
||||
const RELOAD_ON_TOUCH_SIMULATION = "devtools.responsive.reloadConditions.touchSimulation";
|
||||
const RELOAD_ON_TOUCH_SIMULATION =
|
||||
"devtools.responsive.reloadConditions.touchSimulation";
|
||||
const RELOAD_ON_USER_AGENT = "devtools.responsive.reloadConditions.userAgent";
|
||||
const SHOW_USER_AGENT_INPUT = "devtools.responsive.showUserAgentInput";
|
||||
const TOUCH_SIMULATION_ENABLED = "devtools.responsive.touchSimulation.enabled";
|
||||
|
@ -27,21 +28,29 @@ const INITIAL_UI = {
|
|||
// The pixel ratio of the display.
|
||||
displayPixelRatio: 0,
|
||||
// Whether or not the viewports are left aligned.
|
||||
leftAlignmentEnabled: Services.prefs.getBoolPref(LEFT_ALIGNMENT_ENABLED, false),
|
||||
leftAlignmentEnabled: Services.prefs.getBoolPref(
|
||||
LEFT_ALIGNMENT_ENABLED,
|
||||
false
|
||||
),
|
||||
// Whether or not to reload when touch simulation is toggled.
|
||||
reloadOnTouchSimulation: Services.prefs.getBoolPref(RELOAD_ON_TOUCH_SIMULATION, false),
|
||||
reloadOnTouchSimulation: Services.prefs.getBoolPref(
|
||||
RELOAD_ON_TOUCH_SIMULATION,
|
||||
false
|
||||
),
|
||||
// Whether or not to reload when user agent is changed.
|
||||
reloadOnUserAgent: Services.prefs.getBoolPref(RELOAD_ON_USER_AGENT, false),
|
||||
// Whether or not to show the user agent input in the toolbar.
|
||||
showUserAgentInput: Services.prefs.getBoolPref(SHOW_USER_AGENT_INPUT, false),
|
||||
// Whether or not touch simulation is enabled.
|
||||
touchSimulationEnabled: Services.prefs.getBoolPref(TOUCH_SIMULATION_ENABLED, false),
|
||||
touchSimulationEnabled: Services.prefs.getBoolPref(
|
||||
TOUCH_SIMULATION_ENABLED,
|
||||
false
|
||||
),
|
||||
// The user agent of the viewport.
|
||||
userAgent: Services.prefs.getCharPref(USER_AGENT, ""),
|
||||
};
|
||||
|
||||
const reducers = {
|
||||
|
||||
[CHANGE_DISPLAY_PIXEL_RATIO](ui, { displayPixelRatio }) {
|
||||
return {
|
||||
...ui,
|
||||
|
@ -59,8 +68,8 @@ const reducers = {
|
|||
},
|
||||
|
||||
[TOGGLE_LEFT_ALIGNMENT](ui, { enabled }) {
|
||||
const leftAlignmentEnabled = enabled !== undefined ?
|
||||
enabled : !ui.leftAlignmentEnabled;
|
||||
const leftAlignmentEnabled =
|
||||
enabled !== undefined ? enabled : !ui.leftAlignmentEnabled;
|
||||
|
||||
Services.prefs.setBoolPref(LEFT_ALIGNMENT_ENABLED, leftAlignmentEnabled);
|
||||
|
||||
|
@ -71,10 +80,13 @@ const reducers = {
|
|||
},
|
||||
|
||||
[TOGGLE_RELOAD_ON_TOUCH_SIMULATION](ui, { enabled }) {
|
||||
const reloadOnTouchSimulation = enabled !== undefined ?
|
||||
enabled : !ui.reloadOnTouchSimulation;
|
||||
const reloadOnTouchSimulation =
|
||||
enabled !== undefined ? enabled : !ui.reloadOnTouchSimulation;
|
||||
|
||||
Services.prefs.setBoolPref(RELOAD_ON_TOUCH_SIMULATION, reloadOnTouchSimulation);
|
||||
Services.prefs.setBoolPref(
|
||||
RELOAD_ON_TOUCH_SIMULATION,
|
||||
reloadOnTouchSimulation
|
||||
);
|
||||
|
||||
return {
|
||||
...ui,
|
||||
|
@ -83,8 +95,8 @@ const reducers = {
|
|||
},
|
||||
|
||||
[TOGGLE_RELOAD_ON_USER_AGENT](ui, { enabled }) {
|
||||
const reloadOnUserAgent = enabled !== undefined ?
|
||||
enabled : !ui.reloadOnUserAgent;
|
||||
const reloadOnUserAgent =
|
||||
enabled !== undefined ? enabled : !ui.reloadOnUserAgent;
|
||||
|
||||
Services.prefs.setBoolPref(RELOAD_ON_USER_AGENT, reloadOnUserAgent);
|
||||
|
||||
|
@ -104,8 +116,8 @@ const reducers = {
|
|||
},
|
||||
|
||||
[TOGGLE_USER_AGENT_INPUT](ui, { enabled }) {
|
||||
const showUserAgentInput = enabled !== undefined ?
|
||||
enabled : !ui.showUserAgentInput;
|
||||
const showUserAgentInput =
|
||||
enabled !== undefined ? enabled : !ui.showUserAgentInput;
|
||||
|
||||
Services.prefs.setBoolPref(SHOW_USER_AGENT_INPUT, showUserAgentInput);
|
||||
|
||||
|
@ -114,7 +126,6 @@ const reducers = {
|
|||
showUserAgentInput,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = function(ui = INITIAL_UI, action) {
|
||||
|
|
|
@ -37,7 +37,6 @@ const INITIAL_VIEWPORT = {
|
|||
};
|
||||
|
||||
const reducers = {
|
||||
|
||||
[ADD_VIEWPORT](viewports, { userContextId }) {
|
||||
// For the moment, there can be at most one viewport.
|
||||
if (viewports.length === 1) {
|
||||
|
@ -109,7 +108,10 @@ const reducers = {
|
|||
|
||||
Services.prefs.setIntPref(VIEWPORT_WIDTH_PREF, newDevice.width);
|
||||
Services.prefs.setIntPref(VIEWPORT_HEIGHT_PREF, newDevice.height);
|
||||
Services.prefs.setIntPref(VIEWPORT_PIXEL_RATIO_PREF, newDevice.pixelRatio);
|
||||
Services.prefs.setIntPref(
|
||||
VIEWPORT_PIXEL_RATIO_PREF,
|
||||
newDevice.pixelRatio
|
||||
);
|
||||
|
||||
return {
|
||||
...viewport,
|
||||
|
@ -182,7 +184,6 @@ const reducers = {
|
|||
};
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
module.exports = function(viewports = INITIAL_VIEWPORTS, action) {
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
"use strict";
|
||||
|
||||
const Services = require("Services");
|
||||
const { HTMLTooltip } = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
|
||||
const {
|
||||
HTMLTooltip,
|
||||
} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
|
||||
|
||||
const { getStr } = require("./utils/l10n");
|
||||
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
// Ensure Cmd/Ctrl-clicking link opens a new tab
|
||||
|
||||
const TAB_URL = "http://example.com/";
|
||||
const TEST_URL =
|
||||
`data:text/html,<a href="${TAB_URL}">Click me</a>`
|
||||
.replace(/ /g, "%20");
|
||||
const TEST_URL = `data:text/html,<a href="${TAB_URL}">Click me</a>`.replace(
|
||||
/ /g,
|
||||
"%20"
|
||||
);
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui }) {
|
||||
const store = ui.toolWindow.store;
|
||||
|
@ -19,10 +20,14 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
// Cmd-click the link and wait for a new tab
|
||||
await waitForFrameLoad(ui, TEST_URL);
|
||||
const newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, TAB_URL);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("a", {
|
||||
ctrlKey: true,
|
||||
metaKey: true,
|
||||
}, ui.getViewportBrowser());
|
||||
BrowserTestUtils.synthesizeMouseAtCenter(
|
||||
"a",
|
||||
{
|
||||
ctrlKey: true,
|
||||
metaKey: true,
|
||||
},
|
||||
ui.getViewportBrowser()
|
||||
);
|
||||
const newTab = await newTabPromise;
|
||||
ok(newTab, "New tab opened from link");
|
||||
await removeTab(newTab);
|
||||
|
|
|
@ -41,7 +41,8 @@ async function sendMessages(receiver) {
|
|||
function(opts) {
|
||||
const bc = new content.BroadcastChannel(opts.name);
|
||||
bc.postMessage(opts.message);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -54,14 +55,17 @@ async function sendMessages(receiver) {
|
|||
async function verifyResults({ sender1, sender2, receiver }) {
|
||||
// Since sender1 sends before sender2, if the title is exactly
|
||||
// sender2's message, sender1's message must've been blocked
|
||||
await ContentTask.spawn(receiver.browser, sender2.message,
|
||||
async function(message) {
|
||||
await content.testPromise.then(function() {
|
||||
is(content.document.title, message,
|
||||
"should only receive messages from the same user context");
|
||||
});
|
||||
}
|
||||
);
|
||||
await ContentTask.spawn(receiver.browser, sender2.message, async function(
|
||||
message
|
||||
) {
|
||||
await content.testPromise.then(function() {
|
||||
is(
|
||||
content.document.title,
|
||||
message,
|
||||
"should only receive messages from the same user context"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
gBrowser.removeTab(sender1.tab);
|
||||
gBrowser.removeTab(sender2.tab);
|
||||
|
@ -70,9 +74,7 @@ async function verifyResults({ sender1, sender2, receiver }) {
|
|||
add_task(async function() {
|
||||
// Make sure userContext is enabled.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["privacy.userContext.enabled", true],
|
||||
],
|
||||
set: [["privacy.userContext.enabled", true]],
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -11,15 +11,15 @@ const DEFAULT_DPPX = window.devicePixelRatio;
|
|||
const Types = require("devtools/client/responsive/types");
|
||||
|
||||
const testDevice = {
|
||||
"name": "Fake Phone RDM Test",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 5.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "custom",
|
||||
"featured": true,
|
||||
name: "Fake Phone RDM Test",
|
||||
width: 320,
|
||||
height: 570,
|
||||
pixelRatio: 5.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "custom",
|
||||
featured: true,
|
||||
};
|
||||
|
||||
// Add the new device to the list
|
||||
|
@ -31,8 +31,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
reloadOnUAChange(true);
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
// Test defaults
|
||||
testViewportDimensions(ui, 320, 480);
|
||||
|
@ -55,9 +59,15 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
// Test resetting device when resizing viewport
|
||||
const deviceRemoved = once(ui, "device-association-removed");
|
||||
reloaded = waitForViewportLoad(ui);
|
||||
await testViewportResize(ui, ".viewport-vertical-resize-handle",
|
||||
[-10, -10], [testDevice.width, testDevice.height - 10], [0, -10], ui);
|
||||
await Promise.all([ deviceRemoved, reloaded ]);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-vertical-resize-handle",
|
||||
[-10, -10],
|
||||
[testDevice.width, testDevice.height - 10],
|
||||
[0, -10],
|
||||
ui
|
||||
);
|
||||
await Promise.all([deviceRemoved, reloaded]);
|
||||
info("Should have default UA after resizing viewport");
|
||||
await testUserAgent(ui, DEFAULT_UA);
|
||||
await testDevicePixelRatio(ui, DEFAULT_DPPX);
|
||||
|
@ -84,10 +94,13 @@ add_task(async function() {
|
|||
reloadOnUAChange(true);
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === "Laptop (1366 x 768)" &&
|
||||
state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === "Laptop (1366 x 768)" &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
// Select device with custom UA
|
||||
let reloaded = waitForViewportLoad(ui);
|
||||
|
|
|
@ -31,8 +31,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
|
@ -52,7 +56,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await addDeviceInModal(ui, device);
|
||||
|
||||
info("Verify device defaults to enabled in modal");
|
||||
const deviceCb = [...document.querySelectorAll(".device-input-checkbox")].find(cb => {
|
||||
const deviceCb = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].find(cb => {
|
||||
return cb.value == device.name;
|
||||
});
|
||||
ok(deviceCb, "Custom device checkbox added to modal");
|
||||
|
@ -62,7 +68,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Look for custom device in device selector");
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, items => {
|
||||
const menuItem = items.find(item => item.getAttribute("label") === device.name);
|
||||
const menuItem = items.find(
|
||||
item => item.getAttribute("label") === device.name
|
||||
);
|
||||
ok(menuItem, "Custom device menu item added to device selector");
|
||||
});
|
||||
});
|
||||
|
@ -72,20 +80,29 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
info("Select existing device from the selector");
|
||||
await selectDevice(ui, "Test Device");
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
info("Reveal device adder form, check that defaults are based on selected device");
|
||||
info(
|
||||
"Reveal device adder form, check that defaults are based on selected device"
|
||||
);
|
||||
const adderShow = document.getElementById("device-add-button");
|
||||
adderShow.click();
|
||||
testDeviceAdder(ui, Object.assign({}, device, {
|
||||
name: "Test Device (Custom)",
|
||||
}));
|
||||
testDeviceAdder(
|
||||
ui,
|
||||
Object.assign({}, device, {
|
||||
name: "Test Device (Custom)",
|
||||
})
|
||||
);
|
||||
|
||||
info("Remove previously added custom device");
|
||||
// Close the form since custom device buttons are only shown when form is not open.
|
||||
|
@ -106,12 +123,18 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Ensure custom device was removed from device selector");
|
||||
await waitUntilState(store, state => state.viewports[0].device == "");
|
||||
const deviceSelectorTitle = document.querySelector("#device-selector .title");
|
||||
is(deviceSelectorTitle.textContent, "Responsive", "Device selector reset to no device");
|
||||
is(
|
||||
deviceSelectorTitle.textContent,
|
||||
"Responsive",
|
||||
"Device selector reset to no device"
|
||||
);
|
||||
|
||||
info("Look for custom device in device selector");
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const menuItem = menuItems.find(item => item.getAttribute("label") === device.name);
|
||||
const menuItem = menuItems.find(
|
||||
item => item.getAttribute("label") === device.name
|
||||
);
|
||||
ok(!menuItem, "Custom device option removed from device selector");
|
||||
});
|
||||
|
||||
|
@ -124,8 +147,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
|
@ -133,11 +160,15 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const adderShow = document.querySelector("#device-add-button");
|
||||
adderShow.click();
|
||||
|
||||
info("Fill out device adder form by setting details to unicode device and save");
|
||||
info(
|
||||
"Fill out device adder form by setting details to unicode device and save"
|
||||
);
|
||||
await addDeviceInModal(ui, unicodeDevice);
|
||||
|
||||
info("Verify unicode device defaults to enabled in modal");
|
||||
const deviceCb = [...document.querySelectorAll(".device-input-checkbox")].find(cb => {
|
||||
const deviceCb = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].find(cb => {
|
||||
return cb.value == unicodeDevice.name;
|
||||
});
|
||||
ok(deviceCb, "Custom unicode device checkbox added to modal");
|
||||
|
@ -147,7 +178,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Look for custom unicode device in device selector");
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, items => {
|
||||
const menuItem = items.find(i => i.getAttribute("label") === unicodeDevice.name);
|
||||
const menuItem = items.find(
|
||||
i => i.getAttribute("label") === unicodeDevice.name
|
||||
);
|
||||
ok(menuItem, "Custom unicode device option added to device selector");
|
||||
});
|
||||
});
|
||||
|
@ -157,8 +190,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
// Check if the unicode custom device is present in the list of device options since
|
||||
// we want to ensure that unicode device names are not forgotten after restarting RDM
|
||||
|
@ -166,7 +203,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Look for custom unicode device in device selector");
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, items => {
|
||||
const menuItem = items.find(i => i.getAttribute("label") === unicodeDevice.name);
|
||||
const menuItem = items.find(
|
||||
i => i.getAttribute("label") === unicodeDevice.name
|
||||
);
|
||||
ok(menuItem, "Custom unicode device option present in device selector");
|
||||
});
|
||||
});
|
||||
|
@ -175,17 +214,25 @@ function testDeviceAdder(ui, expected) {
|
|||
const { document } = ui.toolWindow;
|
||||
|
||||
const nameInput = document.querySelector("#device-form-name input");
|
||||
const [ widthInput, heightInput ] =
|
||||
document.querySelectorAll("#device-form-size input");
|
||||
const pixelRatioInput = document.querySelector("#device-form-pixel-ratio input");
|
||||
const userAgentInput = document.querySelector("#device-form-user-agent input");
|
||||
const [widthInput, heightInput] = document.querySelectorAll(
|
||||
"#device-form-size input"
|
||||
);
|
||||
const pixelRatioInput = document.querySelector(
|
||||
"#device-form-pixel-ratio input"
|
||||
);
|
||||
const userAgentInput = document.querySelector(
|
||||
"#device-form-user-agent input"
|
||||
);
|
||||
const touchInput = document.querySelector("#device-form-touch input");
|
||||
|
||||
is(nameInput.value, expected.name, "Device name matches");
|
||||
is(parseInt(widthInput.value, 10), expected.width, "Width matches");
|
||||
is(parseInt(heightInput.value, 10), expected.height, "Height matches");
|
||||
is(parseFloat(pixelRatioInput.value), expected.pixelRatio,
|
||||
"devicePixelRatio matches");
|
||||
is(
|
||||
parseFloat(pixelRatioInput.value),
|
||||
expected.pixelRatio,
|
||||
"devicePixelRatio matches"
|
||||
);
|
||||
is(userAgentInput.value, expected.userAgent, "User agent matches");
|
||||
is(touchInput.checked, expected.touch, "Touch matches");
|
||||
}
|
||||
|
|
|
@ -31,8 +31,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { toolWindow } = ui;
|
||||
const { store, document } = toolWindow;
|
||||
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
await openDeviceModal(ui);
|
||||
|
||||
info("Add device.");
|
||||
|
@ -45,7 +49,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
document.getElementById("device-close-button").click();
|
||||
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const originalDevice = menuItems.find(i => i.getAttribute("label") === device.name);
|
||||
const originalDevice = menuItems.find(
|
||||
i => i.getAttribute("label") === device.name
|
||||
);
|
||||
ok(originalDevice, "Original custom device menu item exists.");
|
||||
});
|
||||
|
||||
|
@ -54,43 +60,62 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await openDeviceModal(ui);
|
||||
|
||||
info("Edit the device.");
|
||||
const editorShow = document.querySelector(".device-type-custom #device-edit-button");
|
||||
const editorShow = document.querySelector(
|
||||
".device-type-custom #device-edit-button"
|
||||
);
|
||||
editorShow.click();
|
||||
await editDeviceInModal(ui, device, newDevice);
|
||||
|
||||
info("Ensure the edited device name is updated in the custom device list.");
|
||||
const customDevicesList = document.querySelector(".device-type-custom");
|
||||
const editedCustomDevice = customDevicesList.querySelector(".device-name");
|
||||
is(editedCustomDevice.textContent, newDevice.name,
|
||||
`${device.name} is updated to ${newDevice.name} in the custom device list`);
|
||||
is(
|
||||
editedCustomDevice.textContent,
|
||||
newDevice.name,
|
||||
`${device.name} is updated to ${newDevice.name} in the custom device list`
|
||||
);
|
||||
|
||||
info("Ensure the viewport width and height are updated in the toolbar.");
|
||||
const [ width, height ] = document
|
||||
.querySelectorAll(".text-input.viewport-dimension-input");
|
||||
const [width, height] = document.querySelectorAll(
|
||||
".text-input.viewport-dimension-input"
|
||||
);
|
||||
is(width.value, "300", "Viewport width is 300");
|
||||
is(height.value, "900", "Viewport height is 900");
|
||||
|
||||
info("Ensure the pixel ratio is updated in the toolbar.");
|
||||
const devicePixelRatioSpan = document.querySelector("#device-pixel-ratio-menu span");
|
||||
const devicePixelRatioSpan = document.querySelector(
|
||||
"#device-pixel-ratio-menu span"
|
||||
);
|
||||
is(devicePixelRatioSpan.textContent, "DPR: 4", "Viewport pixel ratio is 4.");
|
||||
|
||||
info("Ensure the user agent has been updated.");
|
||||
const userAgentInput = document.querySelector("#user-agent-input");
|
||||
is(userAgentInput.value, newDevice.userAgent,
|
||||
`Viewport user agent is ${newDevice.userAgent}`);
|
||||
is(
|
||||
userAgentInput.value,
|
||||
newDevice.userAgent,
|
||||
`Viewport user agent is ${newDevice.userAgent}`
|
||||
);
|
||||
|
||||
info("Ensure touch simulation has been updated");
|
||||
const touchSimulation = document.querySelector("#touch-simulation-button");
|
||||
ok(touchSimulation.classList.contains("checked"),
|
||||
"Viewport touch simulation is enabled.");
|
||||
ok(
|
||||
touchSimulation.classList.contains("checked"),
|
||||
"Viewport touch simulation is enabled."
|
||||
);
|
||||
|
||||
info("Ensure the edited device is updated in the device selector when submitted");
|
||||
info(
|
||||
"Ensure the edited device is updated in the device selector when submitted"
|
||||
);
|
||||
document.getElementById("device-close-button").click();
|
||||
deviceSelector = document.getElementById("device-selector");
|
||||
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const originalDevice = menuItems.find(i => i.getAttribute("label") === device.name);
|
||||
const editedDevice = menuItems.find(i => i.getAttribute("label") === newDevice.name);
|
||||
const originalDevice = menuItems.find(
|
||||
i => i.getAttribute("label") === device.name
|
||||
);
|
||||
const editedDevice = menuItems.find(
|
||||
i => i.getAttribute("label") === newDevice.name
|
||||
);
|
||||
ok(!originalDevice, "Original custom device menu item does not exist");
|
||||
ok(editedDevice, "Edited Custom Device menu item exists");
|
||||
});
|
||||
|
|
|
@ -31,8 +31,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Verify that remove buttons affect the correct device");
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
|
||||
|
@ -53,8 +57,9 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await addDeviceInModal(ui, device2);
|
||||
|
||||
info("Verify all custom devices default to enabled in modal");
|
||||
const deviceCbs =
|
||||
[...document.querySelectorAll(".device-type-custom .device-input-checkbox")];
|
||||
const deviceCbs = [
|
||||
...document.querySelectorAll(".device-type-custom .device-input-checkbox"),
|
||||
];
|
||||
is(deviceCbs.length, 2, "Both devices have a checkbox in modal");
|
||||
for (const cb of deviceCbs) {
|
||||
ok(cb.checked, "Custom device enabled");
|
||||
|
@ -64,8 +69,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Look for device 1 and 2 in device selector");
|
||||
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const deviceItem1 = menuItems.find(i => i.getAttribute("label") === device1.name);
|
||||
const deviceItem2 = menuItems.find(i => i.getAttribute("label") === device2.name);
|
||||
const deviceItem1 = menuItems.find(
|
||||
i => i.getAttribute("label") === device1.name
|
||||
);
|
||||
const deviceItem2 = menuItems.find(
|
||||
i => i.getAttribute("label") === device2.name
|
||||
);
|
||||
ok(deviceItem1, "Test device 1 menu item added to device selector");
|
||||
ok(deviceItem2, "Test device 2 menu item added to device selector");
|
||||
});
|
||||
|
@ -73,17 +82,30 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await openDeviceModal(ui);
|
||||
|
||||
info("Remove device 2");
|
||||
const deviceRemoveButtons = [...document.querySelectorAll(".device-remove-button")];
|
||||
is(deviceRemoveButtons.length, 2, "Both devices have a remove button in modal");
|
||||
const removed = waitUntilState(store, state => state.devices.custom.length == 1);
|
||||
const deviceRemoveButtons = [
|
||||
...document.querySelectorAll(".device-remove-button"),
|
||||
];
|
||||
is(
|
||||
deviceRemoveButtons.length,
|
||||
2,
|
||||
"Both devices have a remove button in modal"
|
||||
);
|
||||
const removed = waitUntilState(
|
||||
store,
|
||||
state => state.devices.custom.length == 1
|
||||
);
|
||||
deviceRemoveButtons[1].click();
|
||||
await removed;
|
||||
document.getElementById("device-close-button").click();
|
||||
|
||||
info("Ensure device 2 is no longer in device selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const deviceItem1 = menuItems.find(i => i.getAttribute("label") === device1.name);
|
||||
const deviceItem2 = menuItems.find(i => i.getAttribute("label") === device2.name);
|
||||
const deviceItem1 = menuItems.find(
|
||||
i => i.getAttribute("label") === device1.name
|
||||
);
|
||||
const deviceItem2 = menuItems.find(
|
||||
i => i.getAttribute("label") === device2.name
|
||||
);
|
||||
ok(deviceItem1, "Test device 1 menu item exists");
|
||||
ok(!deviceItem2, "Test device 2 menu item removed");
|
||||
});
|
||||
|
@ -94,15 +116,23 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
|
||||
info("Ensure device 1 is still in device selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
const deviceItem1 = menuItems.find(i => i.getAttribute("label") === device1.name);
|
||||
const deviceItem2 = menuItems.find(i => i.getAttribute("label") === device2.name);
|
||||
const deviceItem1 = menuItems.find(
|
||||
i => i.getAttribute("label") === device1.name
|
||||
);
|
||||
const deviceItem2 = menuItems.find(
|
||||
i => i.getAttribute("label") === device2.name
|
||||
);
|
||||
ok(deviceItem1, "Test device 1 menu item exists");
|
||||
ok(!deviceItem2, "Test device 2 option removed");
|
||||
});
|
||||
|
@ -110,14 +140,17 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await openDeviceModal(ui);
|
||||
|
||||
info("Ensure device 1 is still in device modal");
|
||||
const deviceCbs =
|
||||
[...document.querySelectorAll(".device-type-custom .device-input-checkbox")];
|
||||
const deviceCbs = [
|
||||
...document.querySelectorAll(".device-type-custom .device-input-checkbox"),
|
||||
];
|
||||
is(deviceCbs.length, 1, "Only 1 custom present in modal");
|
||||
const deviceCb1 = deviceCbs.find(cb => cb.value == device1.name);
|
||||
ok(deviceCb1 && deviceCb1.checked, "Test device 1 checkbox exists and enabled");
|
||||
ok(
|
||||
deviceCb1 && deviceCb1.checked,
|
||||
"Test device 1 checkbox exists and enabled"
|
||||
);
|
||||
|
||||
info("Ensure device 2 is no longer in device modal");
|
||||
const deviceCb2 = deviceCbs.find(cb => cb.value == device2.name);
|
||||
ok(!deviceCb2, "Test device 2 checkbox does not exist");
|
||||
});
|
||||
|
||||
|
|
|
@ -21,8 +21,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
|
||||
// Wait until the viewport has been added and the device list state indicates
|
||||
// an error
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.ERROR);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.ERROR
|
||||
);
|
||||
|
||||
// The device selector should be disabled
|
||||
ok(button.disabled, "Device selector is disabled");
|
||||
|
|
|
@ -12,29 +12,45 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { document, store } = ui.toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
const preferredDevicesBefore = _loadPreferredDevices();
|
||||
|
||||
info("Check the first unchecked device and exit the modal.");
|
||||
const uncheckedCb = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => !cb.checked)[0];
|
||||
const uncheckedCb = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].filter(cb => !cb.checked)[0];
|
||||
const value = uncheckedCb.value;
|
||||
uncheckedCb.click();
|
||||
document.getElementById("device-close-button").click();
|
||||
|
||||
ok(!store.getState().devices.isModalOpen, "The device modal is closed on exit.");
|
||||
ok(
|
||||
!store.getState().devices.isModalOpen,
|
||||
"The device modal is closed on exit."
|
||||
);
|
||||
|
||||
info("Check that the device list remains unchanged after exitting.");
|
||||
const preferredDevicesAfter = _loadPreferredDevices();
|
||||
|
||||
is(preferredDevicesAfter.added.size - preferredDevicesBefore.added.size, 1,
|
||||
"Got expected number of added devices.");
|
||||
is(preferredDevicesBefore.removed.size, preferredDevicesAfter.removed.size,
|
||||
"Got expected number of removed devices.");
|
||||
ok(!preferredDevicesAfter.removed.has(value),
|
||||
value + " was not added to removed device list.");
|
||||
is(
|
||||
preferredDevicesAfter.added.size - preferredDevicesBefore.added.size,
|
||||
1,
|
||||
"Got expected number of added devices."
|
||||
);
|
||||
is(
|
||||
preferredDevicesBefore.removed.size,
|
||||
preferredDevicesAfter.removed.size,
|
||||
"Got expected number of removed devices."
|
||||
);
|
||||
ok(
|
||||
!preferredDevicesAfter.removed.has(value),
|
||||
value + " was not added to removed device list."
|
||||
);
|
||||
});
|
||||
|
|
|
@ -7,15 +7,15 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
|||
const { getDevices } = require("devtools/client/shared/devices");
|
||||
|
||||
const addedDevice = {
|
||||
"name": "Fake Phone RDM Test",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "custom",
|
||||
"featured": true,
|
||||
name: "Fake Phone RDM Test",
|
||||
width: 320,
|
||||
height: 570,
|
||||
pixelRatio: 1.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: false,
|
||||
os: "custom",
|
||||
featured: true,
|
||||
};
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,";
|
||||
|
@ -27,40 +27,57 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const deviceSelector = document.getElementById("device-selector");
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
info("Checking displayed device checkboxes are checked in the device modal.");
|
||||
const checkedCbs = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => cb.checked);
|
||||
const checkedCbs = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].filter(cb => cb.checked);
|
||||
|
||||
const remoteList = await getDevices();
|
||||
|
||||
const featuredCount = remoteList.TYPES.reduce((total, type) => {
|
||||
return total + remoteList[type].reduce((subtotal, device) => {
|
||||
return subtotal + ((device.os != "fxos" && device.featured) ? 1 : 0);
|
||||
}, 0);
|
||||
return (
|
||||
total +
|
||||
remoteList[type].reduce((subtotal, device) => {
|
||||
return subtotal + (device.os != "fxos" && device.featured ? 1 : 0);
|
||||
}, 0)
|
||||
);
|
||||
}, 0);
|
||||
|
||||
is(featuredCount, checkedCbs.length,
|
||||
"Got expected number of displayed devices.");
|
||||
is(
|
||||
featuredCount,
|
||||
checkedCbs.length,
|
||||
"Got expected number of displayed devices."
|
||||
);
|
||||
|
||||
for (const cb of checkedCbs) {
|
||||
ok(Object.keys(remoteList).filter(type => remoteList[type][cb.value]),
|
||||
cb.value + " is correctly checked.");
|
||||
ok(
|
||||
Object.keys(remoteList).filter(type => remoteList[type][cb.value]),
|
||||
cb.value + " is correctly checked."
|
||||
);
|
||||
}
|
||||
|
||||
// Tests where the user adds a non-featured device
|
||||
info("Check the first unchecked device and submit new device list.");
|
||||
const uncheckedCb = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => !cb.checked)[0];
|
||||
const uncheckedCb = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].filter(cb => !cb.checked)[0];
|
||||
const value = uncheckedCb.value;
|
||||
uncheckedCb.click();
|
||||
document.getElementById("device-close-button").click();
|
||||
|
||||
ok(!store.getState().devices.isModalOpen, "The device modal is closed on submit.");
|
||||
ok(
|
||||
!store.getState().devices.isModalOpen,
|
||||
"The device modal is closed on submit."
|
||||
);
|
||||
|
||||
info("Checking that the new device is added to the user preference list.");
|
||||
let preferredDevices = _loadPreferredDevices();
|
||||
|
@ -68,24 +85,33 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
|
||||
info("Checking new device is added to the device selector.");
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
is(menuItems.length - 2, featuredCount + 1,
|
||||
"Got expected number of devices in device selector.");
|
||||
is(
|
||||
menuItems.length - 2,
|
||||
featuredCount + 1,
|
||||
"Got expected number of devices in device selector."
|
||||
);
|
||||
|
||||
const menuItem = menuItems.find(item => item.getAttribute("label") === name);
|
||||
const menuItem = menuItems.find(
|
||||
item => item.getAttribute("label") === name
|
||||
);
|
||||
ok(menuItem, value + " added to the device selector.");
|
||||
});
|
||||
|
||||
info("Reopen device modal and check new device is correctly checked");
|
||||
await openDeviceModal(ui);
|
||||
|
||||
ok([...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => cb.checked && cb.value === value)[0],
|
||||
value + " is checked in the device modal.");
|
||||
ok(
|
||||
[...document.querySelectorAll(".device-input-checkbox")].filter(
|
||||
cb => cb.checked && cb.value === value
|
||||
)[0],
|
||||
value + " is checked in the device modal."
|
||||
);
|
||||
|
||||
// Tests where the user removes a featured device
|
||||
info("Uncheck the first checked device different than the previous one");
|
||||
const checkedCb = [...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => cb.checked && cb.value != value)[0];
|
||||
const checkedCb = [
|
||||
...document.querySelectorAll(".device-input-checkbox"),
|
||||
].filter(cb => cb.checked && cb.value != value)[0];
|
||||
const checkedVal = checkedCb.value;
|
||||
checkedCb.click();
|
||||
document.getElementById("device-close-button").click();
|
||||
|
@ -96,18 +122,26 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
|
||||
info("Checking that the device is not in the device selector.");
|
||||
await testMenuItems(toolWindow, deviceSelector, menuItems => {
|
||||
is(menuItems.length - 2, featuredCount,
|
||||
"Got expected number of devices in device selector.");
|
||||
is(
|
||||
menuItems.length - 2,
|
||||
featuredCount,
|
||||
"Got expected number of devices in device selector."
|
||||
);
|
||||
|
||||
const menuItem = menuItems.find(item => item.getAttribute("label") === checkedVal);
|
||||
const menuItem = menuItems.find(
|
||||
item => item.getAttribute("label") === checkedVal
|
||||
);
|
||||
ok(!menuItem, checkedVal + " removed from the device selector.");
|
||||
});
|
||||
|
||||
info("Reopen device modal and check device is correctly unchecked");
|
||||
await openDeviceModal(ui);
|
||||
ok([...document.querySelectorAll(".device-input-checkbox")]
|
||||
.filter(cb => !cb.checked && cb.value === checkedVal)[0],
|
||||
checkedVal + " is unchecked in the device modal.");
|
||||
ok(
|
||||
[...document.querySelectorAll(".device-input-checkbox")].filter(
|
||||
cb => !cb.checked && cb.value === checkedVal
|
||||
)[0],
|
||||
checkedVal + " is unchecked in the device modal."
|
||||
);
|
||||
|
||||
// Let's add a dummy device to simulate featured flag changes for next test
|
||||
addDeviceForTest(addedDevice);
|
||||
|
@ -118,16 +152,23 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
const { document, store } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
await openDeviceModal(ui);
|
||||
|
||||
const remoteList = await getDevices();
|
||||
const featuredCount = remoteList.TYPES.reduce((total, type) => {
|
||||
return total + remoteList[type].reduce((subtotal, device) => {
|
||||
return subtotal + ((device.os != "fxos" && device.featured) ? 1 : 0);
|
||||
}, 0);
|
||||
return (
|
||||
total +
|
||||
remoteList[type].reduce((subtotal, device) => {
|
||||
return subtotal + (device.os != "fxos" && device.featured ? 1 : 0);
|
||||
}, 0)
|
||||
);
|
||||
}, 0);
|
||||
const preferredDevices = _loadPreferredDevices();
|
||||
|
||||
|
@ -135,9 +176,13 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
info("Checking new featured device appears in the device selector.");
|
||||
const deviceSelector = document.getElementById("device-selector");
|
||||
await testMenuItems(toolWindow, deviceSelector, items => {
|
||||
is(items.length - 2, featuredCount
|
||||
- preferredDevices.removed.size + preferredDevices.added.size,
|
||||
"Got expected number of devices in device selector.");
|
||||
is(
|
||||
items.length - 2,
|
||||
featuredCount -
|
||||
preferredDevices.removed.size +
|
||||
preferredDevices.added.size,
|
||||
"Got expected number of devices in device selector."
|
||||
);
|
||||
|
||||
const added = items.find(i => i.getAttribute("label") === addedDevice.name);
|
||||
ok(added, "Dummy device added to the device selector.");
|
||||
|
|
|
@ -11,15 +11,15 @@ const VIEWPORT_DPPX = DEFAULT_DPPX + 1;
|
|||
const Types = require("devtools/client/responsive/types");
|
||||
|
||||
const testDevice = {
|
||||
"name": "Fake Phone RDM Test",
|
||||
"width": 320,
|
||||
"height": 470,
|
||||
"pixelRatio": 5.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "custom",
|
||||
"featured": true,
|
||||
name: "Fake Phone RDM Test",
|
||||
width: 320,
|
||||
height: 470,
|
||||
pixelRatio: 5.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "custom",
|
||||
featured: true,
|
||||
};
|
||||
|
||||
// Add the new device to the list
|
||||
|
@ -38,8 +38,12 @@ async function waitStartup(ui) {
|
|||
const { store } = ui.toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
}
|
||||
|
||||
async function testDefaults(ui) {
|
||||
|
@ -72,8 +76,14 @@ async function testResetWhenResizingViewport(ui) {
|
|||
info("Test reset when resizing the viewport");
|
||||
|
||||
const deviceRemoved = once(ui, "device-association-removed");
|
||||
await testViewportResize(ui, ".viewport-vertical-resize-handle",
|
||||
[-10, -10], [testDevice.width, testDevice.height - 10], [0, -10], ui);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-vertical-resize-handle",
|
||||
[-10, -10],
|
||||
[testDevice.width, testDevice.height - 10],
|
||||
[0, -10],
|
||||
ui
|
||||
);
|
||||
await deviceRemoved;
|
||||
|
||||
const dppx = await waitForDevicePixelRatio(ui, DEFAULT_DPPX);
|
||||
|
@ -102,19 +112,35 @@ async function testChangingDevicePixelRatio(ui) {
|
|||
function testViewportDevicePixelRatioSelect(ui, expected) {
|
||||
info("Test viewport's DevicePixelRatio Select");
|
||||
|
||||
const button = ui.toolWindow.document.getElementById("device-pixel-ratio-menu");
|
||||
const title = ui.toolWindow.document.querySelector("#device-pixel-ratio-menu .title");
|
||||
is(title.textContent, `DPR: ${expected.value}`,
|
||||
`DevicePixelRatio Select value should be: ${expected.value}`);
|
||||
is(button.disabled, expected.disabled,
|
||||
`DevicePixelRatio Select should be ${expected.disabled ? "disabled" : "enabled"}.`);
|
||||
const button = ui.toolWindow.document.getElementById(
|
||||
"device-pixel-ratio-menu"
|
||||
);
|
||||
const title = ui.toolWindow.document.querySelector(
|
||||
"#device-pixel-ratio-menu .title"
|
||||
);
|
||||
is(
|
||||
title.textContent,
|
||||
`DPR: ${expected.value}`,
|
||||
`DevicePixelRatio Select value should be: ${expected.value}`
|
||||
);
|
||||
is(
|
||||
button.disabled,
|
||||
expected.disabled,
|
||||
`DevicePixelRatio Select should be ${
|
||||
expected.disabled ? "disabled" : "enabled"
|
||||
}.`
|
||||
);
|
||||
}
|
||||
|
||||
function waitForDevicePixelRatio(ui, expected) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(), { expected }, function(args) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(), { expected }, function(
|
||||
args
|
||||
) {
|
||||
const initial = content.devicePixelRatio;
|
||||
info(`Listening for pixel ratio change ` +
|
||||
`(current: ${initial}, expected: ${args.expected})`);
|
||||
info(
|
||||
`Listening for pixel ratio change ` +
|
||||
`(current: ${initial}, expected: ${args.expected})`
|
||||
);
|
||||
return new Promise(resolve => {
|
||||
const mql = content.matchMedia(`(resolution: ${args.expected}dppx)`);
|
||||
if (mql.matches) {
|
||||
|
|
|
@ -10,15 +10,16 @@ const DEFAULT_DPPX = window.devicePixelRatio;
|
|||
|
||||
/* eslint-disable max-len */
|
||||
const TEST_DEVICE = {
|
||||
"name": "Apple iPhone 6s",
|
||||
"width": 375,
|
||||
"height": 667,
|
||||
"pixelRatio": 2,
|
||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
"touch": true,
|
||||
"firefoxOS": false,
|
||||
"os": "ios",
|
||||
"featured": true,
|
||||
name: "Apple iPhone 6s",
|
||||
width: 375,
|
||||
height: 667,
|
||||
pixelRatio: 2,
|
||||
userAgent:
|
||||
"Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4",
|
||||
touch: true,
|
||||
firefoxOS: false,
|
||||
os: "ios",
|
||||
featured: true,
|
||||
};
|
||||
/* eslint-enable max-len */
|
||||
|
||||
|
@ -30,8 +31,12 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
reloadOnUAChange(true);
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
|
||||
info("Checking the default RDM state.");
|
||||
testViewportDeviceMenuLabel(ui, "Responsive");
|
||||
|
@ -60,13 +65,18 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
|
||||
reloadOnUAChange(true);
|
||||
|
||||
info("Reopening RDM and checking that the previous device state is restored.");
|
||||
info(
|
||||
"Reopening RDM and checking that the previous device state is restored."
|
||||
);
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === TEST_DEVICE.name &&
|
||||
state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === TEST_DEVICE.name &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
await waitForViewportResizeTo(ui, TEST_DEVICE.width, TEST_DEVICE.height);
|
||||
await waitForViewportLoad(ui);
|
||||
|
||||
|
@ -88,13 +98,18 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
|
||||
reloadOnUAChange(true);
|
||||
|
||||
info("Reopening RDM and checking that the previous device state is restored.");
|
||||
info(
|
||||
"Reopening RDM and checking that the previous device state is restored."
|
||||
);
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === TEST_DEVICE.name &&
|
||||
state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.viewports[0].device === TEST_DEVICE.name &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
await waitForViewportResizeTo(ui, TEST_DEVICE.height, TEST_DEVICE.width);
|
||||
await waitForViewportLoad(ui);
|
||||
|
||||
|
|
|
@ -32,12 +32,15 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
});
|
||||
|
||||
async function setViewportSizeWithInputKeys(ui) {
|
||||
const width = 320, height = 500;
|
||||
const width = 320,
|
||||
height = 500;
|
||||
let resized = waitForViewportResizeTo(ui, width, height);
|
||||
ui.setViewportSize({ width, height });
|
||||
await resized;
|
||||
|
||||
const dimensions = ui.toolWindow.document.querySelectorAll(".viewport-dimension-input");
|
||||
const dimensions = ui.toolWindow.document.querySelectorAll(
|
||||
".viewport-dimension-input"
|
||||
);
|
||||
|
||||
// Increase width value to 420 by using the Up arrow key
|
||||
resized = waitForViewportResizeTo(ui, 420, height);
|
||||
|
@ -51,40 +54,54 @@ async function setViewportSizeWithInputKeys(ui) {
|
|||
resized = waitForViewportResizeTo(ui, width, height);
|
||||
dimensions[0].focus();
|
||||
for (let i = 1; i <= 10; i++) {
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown", {shiftKey: true});
|
||||
EventUtils.synthesizeKey("KEY_ArrowDown", { shiftKey: true });
|
||||
}
|
||||
await resized;
|
||||
|
||||
// Increase height value to 600 by using `PageUp + Shift` key
|
||||
resized = waitForViewportResizeTo(ui, width, 600);
|
||||
dimensions[1].focus();
|
||||
EventUtils.synthesizeKey("KEY_PageUp", {shiftKey: true});
|
||||
EventUtils.synthesizeKey("KEY_PageUp", { shiftKey: true });
|
||||
await resized;
|
||||
|
||||
// Resetting height value back to 500 by using `PageDown + Shift` key
|
||||
resized = waitForViewportResizeTo(ui, width, height);
|
||||
dimensions[1].focus();
|
||||
EventUtils.synthesizeKey("KEY_PageDown", {shiftKey: true});
|
||||
EventUtils.synthesizeKey("KEY_PageDown", { shiftKey: true });
|
||||
await resized;
|
||||
}
|
||||
|
||||
async function doInitialChecks(ui) {
|
||||
const { innerWidth, matchesMedia, outerHeight, outerWidth } = await grabContentInfo(ui);
|
||||
const {
|
||||
innerWidth,
|
||||
matchesMedia,
|
||||
outerHeight,
|
||||
outerWidth,
|
||||
} = await grabContentInfo(ui);
|
||||
is(innerWidth, 110, "initial width should be 110px");
|
||||
is(outerWidth, 110, "device's outerWidth should be 110px");
|
||||
is(outerHeight, 500, "device's outerHeight should be 500px");
|
||||
isnot(window.outerHeight, outerHeight,
|
||||
"window.outerHeight should not be the size of the device's outerHeight");
|
||||
isnot(window.outerWidth, outerWidth,
|
||||
"window.outerWidth should not be the size of the device's outerWidth");
|
||||
isnot(
|
||||
window.outerHeight,
|
||||
outerHeight,
|
||||
"window.outerHeight should not be the size of the device's outerHeight"
|
||||
);
|
||||
isnot(
|
||||
window.outerWidth,
|
||||
outerWidth,
|
||||
"window.outerWidth should not be the size of the device's outerWidth"
|
||||
);
|
||||
ok(!matchesMedia, "media query shouldn't match.");
|
||||
}
|
||||
|
||||
async function checkScreenProps(ui) {
|
||||
const { matchesMedia, screen } = await grabContentInfo(ui);
|
||||
ok(matchesMedia, "media query should match");
|
||||
isnot(window.screen.width, screen.width,
|
||||
"screen.width should not be the size of the screen.");
|
||||
isnot(
|
||||
window.screen.width,
|
||||
screen.width,
|
||||
"screen.width should not be the size of the screen."
|
||||
);
|
||||
is(screen.width, 90, "screen.width should be the page width");
|
||||
is(screen.height, 500, "screen.height should be the page height");
|
||||
}
|
||||
|
@ -92,8 +109,11 @@ async function checkScreenProps(ui) {
|
|||
async function checkScreenProps2(ui) {
|
||||
const { matchesMedia, screen } = await grabContentInfo(ui);
|
||||
ok(!matchesMedia, "media query should be re-evaluated.");
|
||||
is(window.screen.width, screen.width,
|
||||
"screen.width should be the size of the screen.");
|
||||
is(
|
||||
window.screen.width,
|
||||
screen.width,
|
||||
"screen.width should be the size of the screen."
|
||||
);
|
||||
}
|
||||
|
||||
function grabContentInfo(ui) {
|
||||
|
|
|
@ -34,8 +34,10 @@ add_task(async function() {
|
|||
tab = newWindow.gBrowser.tabs[0];
|
||||
|
||||
// Detaching a tab closes RDM.
|
||||
ok(!manager.isActiveForTab(tab),
|
||||
"Responsive Design Mode is not active for the tab");
|
||||
ok(
|
||||
!manager.isActiveForTab(tab),
|
||||
"Responsive Design Mode is not active for the tab"
|
||||
);
|
||||
|
||||
// Reopen the RDM and test the exit button again.
|
||||
await testExitButton(await openRDM(tab));
|
||||
|
@ -54,18 +56,22 @@ async function waitBootstrap(ui) {
|
|||
await waitForFrameLoad(ui, url);
|
||||
}
|
||||
|
||||
async function testExitButton({ui, manager}) {
|
||||
async function testExitButton({ ui, manager }) {
|
||||
await waitBootstrap(ui);
|
||||
|
||||
const exitButton = ui.toolWindow.document.getElementById("exit-button");
|
||||
|
||||
ok(manager.isActiveForTab(ui.tab),
|
||||
"Responsive Design Mode active for the tab");
|
||||
ok(
|
||||
manager.isActiveForTab(ui.tab),
|
||||
"Responsive Design Mode active for the tab"
|
||||
);
|
||||
|
||||
exitButton.click();
|
||||
|
||||
await once(manager, "off");
|
||||
|
||||
ok(!manager.isActiveForTab(ui.tab),
|
||||
"Responsive Design Mode is not active for the tab");
|
||||
ok(
|
||||
!manager.isActiveForTab(ui.tab),
|
||||
"Responsive Design Mode is not active for the tab"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,28 +9,34 @@ const TEST_URL = "http://example.com/";
|
|||
|
||||
// These allowed rejections are copied from
|
||||
// browser/components/extensions/test/browser/head.js.
|
||||
const { PromiseTestUtils } = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm");
|
||||
const { PromiseTestUtils } = ChromeUtils.import(
|
||||
"resource://testing-common/PromiseTestUtils.jsm"
|
||||
);
|
||||
PromiseTestUtils.whitelistRejectionsGlobally(/Message manager disconnected/);
|
||||
PromiseTestUtils.whitelistRejectionsGlobally(/Receiving end does not exist/);
|
||||
|
||||
add_task(async function test_port_kept_connected_on_switch_to_RDB() {
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"content_scripts": [{
|
||||
"matches": [TEST_URL],
|
||||
"js": ["content-script.js"],
|
||||
"run_at": "document_start",
|
||||
}],
|
||||
content_scripts: [
|
||||
{
|
||||
matches: [TEST_URL],
|
||||
js: ["content-script.js"],
|
||||
run_at: "document_start",
|
||||
},
|
||||
],
|
||||
},
|
||||
background() {
|
||||
let currentPort;
|
||||
|
||||
browser.runtime.onConnect.addListener(port => {
|
||||
currentPort = port;
|
||||
port.onDisconnect.addListener(
|
||||
() => browser.test.sendMessage("port-disconnected"));
|
||||
port.onMessage.addListener(
|
||||
msg => browser.test.sendMessage("port-message-received", msg));
|
||||
port.onDisconnect.addListener(() =>
|
||||
browser.test.sendMessage("port-disconnected")
|
||||
);
|
||||
port.onMessage.addListener(msg =>
|
||||
browser.test.sendMessage("port-message-received", msg)
|
||||
);
|
||||
browser.test.sendMessage("port-connected");
|
||||
});
|
||||
|
||||
|
@ -64,15 +70,21 @@ add_task(async function test_port_kept_connected_on_switch_to_RDB() {
|
|||
|
||||
extension.sendMessage("test:port-message-send");
|
||||
|
||||
is(await extension.awaitMessage("port-message-received"), "ping-pong",
|
||||
"Got the expected message back from the content script");
|
||||
is(
|
||||
await extension.awaitMessage("port-message-received"),
|
||||
"ping-pong",
|
||||
"Got the expected message back from the content script"
|
||||
);
|
||||
|
||||
await closeRDM(tab);
|
||||
|
||||
extension.sendMessage("test:port-message-send");
|
||||
|
||||
is(await extension.awaitMessage("port-message-received"), "ping-pong",
|
||||
"Got the expected message back from the content script");
|
||||
is(
|
||||
await extension.awaitMessage("port-message-received"),
|
||||
"ping-pong",
|
||||
"Got the expected message back from the content script"
|
||||
);
|
||||
|
||||
await removeTab(tab);
|
||||
|
||||
|
@ -87,13 +99,15 @@ add_task(async function test_tab_sender() {
|
|||
|
||||
const extension = ExtensionTestUtils.loadExtension({
|
||||
manifest: {
|
||||
"permissions": ["tabs"],
|
||||
permissions: ["tabs"],
|
||||
|
||||
"content_scripts": [{
|
||||
"matches": [TEST_URL],
|
||||
"js": ["content-script.js"],
|
||||
"run_at": "document_start",
|
||||
}],
|
||||
content_scripts: [
|
||||
{
|
||||
matches: [TEST_URL],
|
||||
js: ["content-script.js"],
|
||||
run_at: "document_start",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
async background() {
|
||||
|
@ -105,25 +119,37 @@ add_task(async function test_tab_sender() {
|
|||
const contentMessage = new Promise(resolve => {
|
||||
browser.test.log("Listen to content");
|
||||
const listener = async (msg, sender, respond) => {
|
||||
browser.test.assertEq(msg, "hello-from-content",
|
||||
"Background script got hello-from-content message");
|
||||
browser.test.assertEq(
|
||||
msg,
|
||||
"hello-from-content",
|
||||
"Background script got hello-from-content message"
|
||||
);
|
||||
|
||||
const tabs = await browser.tabs.query({
|
||||
currentWindow: true,
|
||||
active: true,
|
||||
});
|
||||
browser.test.assertEq(tabs.length, 1,
|
||||
"One tab is active in the current window");
|
||||
browser.test.assertEq(
|
||||
tabs.length,
|
||||
1,
|
||||
"One tab is active in the current window"
|
||||
);
|
||||
extTab = tabs[0];
|
||||
browser.test.log(`Tab: id ${extTab.id}, url ${extTab.url}`);
|
||||
browser.test.assertEq(extTab.url, TEST_URL, "Tab has the test URL");
|
||||
|
||||
browser.test.assertTrue(!!sender, "Message has a sender");
|
||||
browser.test.assertTrue(!!sender.tab, "Message has a sender.tab");
|
||||
browser.test.assertEq(sender.tab.id, extTab.id,
|
||||
"Sender's tab ID matches the RDM tab ID");
|
||||
browser.test.assertEq(sender.tab.url, extTab.url,
|
||||
"Sender's tab URL matches the RDM tab URL");
|
||||
browser.test.assertEq(
|
||||
sender.tab.id,
|
||||
extTab.id,
|
||||
"Sender's tab ID matches the RDM tab ID"
|
||||
);
|
||||
browser.test.assertEq(
|
||||
sender.tab.url,
|
||||
extTab.url,
|
||||
"Sender's tab URL matches the RDM tab URL"
|
||||
);
|
||||
|
||||
browser.runtime.onMessage.removeListener(listener);
|
||||
resolve();
|
||||
|
@ -144,8 +170,11 @@ add_task(async function test_tab_sender() {
|
|||
extTab.id,
|
||||
"hello-from-background"
|
||||
);
|
||||
browser.test.assertEq(contentSender.id, browser.runtime.id,
|
||||
"The sender ID in content matches this extension");
|
||||
browser.test.assertEq(
|
||||
contentSender.id,
|
||||
browser.runtime.id,
|
||||
"The sender ID in content matches this extension"
|
||||
);
|
||||
|
||||
browser.test.notifyPass("rdm-messaging");
|
||||
},
|
||||
|
@ -156,8 +185,11 @@ add_task(async function test_tab_sender() {
|
|||
|
||||
browser.test.log("Listen to background");
|
||||
browser.runtime.onMessage.addListener((msg, sender, respond) => {
|
||||
browser.test.assertEq(msg, "hello-from-background",
|
||||
"Content script got hello-from-background message");
|
||||
browser.test.assertEq(
|
||||
msg,
|
||||
"hello-from-background",
|
||||
"Content script got hello-from-background message"
|
||||
);
|
||||
|
||||
browser.test.assertTrue(!!sender, "Message has a sender");
|
||||
browser.test.assertTrue(!!sender.id, "Message has a sender.id");
|
||||
|
@ -179,7 +211,9 @@ add_task(async function test_tab_sender() {
|
|||
});
|
||||
|
||||
const contentScriptReady = extension.awaitMessage("content-script-ready");
|
||||
const backgroundScriptReady = extension.awaitMessage("background-script-ready");
|
||||
const backgroundScriptReady = extension.awaitMessage(
|
||||
"background-script-ready"
|
||||
);
|
||||
const finish = extension.awaitFinish("rdm-messaging");
|
||||
|
||||
await extension.startup();
|
||||
|
|
|
@ -8,10 +8,12 @@
|
|||
const TEST_URL = "http://example.com/";
|
||||
const CONTAINER_URL = "chrome://devtools/content/responsive/index.xhtml";
|
||||
|
||||
const { TabStateFlusher } =
|
||||
ChromeUtils.import("resource:///modules/sessionstore/TabStateFlusher.jsm");
|
||||
const { OUTER_FRAME_LOADER_SYMBOL } =
|
||||
require("devtools/client/responsive/browser/tunnel");
|
||||
const { TabStateFlusher } = ChromeUtils.import(
|
||||
"resource:///modules/sessionstore/TabStateFlusher.jsm"
|
||||
);
|
||||
const {
|
||||
OUTER_FRAME_LOADER_SYMBOL,
|
||||
} = require("devtools/client/responsive/browser/tunnel");
|
||||
|
||||
function flushContainerTabState(tab) {
|
||||
const browser = tab.linkedBrowser;
|
||||
|
|
|
@ -9,18 +9,19 @@ const TEST_URL = "data:text/html;charset=utf-8,";
|
|||
|
||||
const { startup } = require("devtools/client/responsive/utils/window");
|
||||
|
||||
const activateTab = (tab) => new Promise(resolve => {
|
||||
const { gBrowser } = tab.ownerGlobal;
|
||||
const { tabContainer } = gBrowser;
|
||||
const activateTab = tab =>
|
||||
new Promise(resolve => {
|
||||
const { gBrowser } = tab.ownerGlobal;
|
||||
const { tabContainer } = gBrowser;
|
||||
|
||||
tabContainer.addEventListener("TabSelect", function listener({type}) {
|
||||
tabContainer.removeEventListener(type, listener);
|
||||
resolve();
|
||||
tabContainer.addEventListener("TabSelect", function listener({ type }) {
|
||||
tabContainer.removeEventListener(type, listener);
|
||||
resolve();
|
||||
});
|
||||
|
||||
gBrowser.selectedTab = tab;
|
||||
});
|
||||
|
||||
gBrowser.selectedTab = tab;
|
||||
});
|
||||
|
||||
const isMenuChecked = () => {
|
||||
const menu = document.getElementById("menu_responsiveUI");
|
||||
return menu.getAttribute("checked") === "true";
|
||||
|
@ -29,33 +30,27 @@ const isMenuChecked = () => {
|
|||
add_task(async function() {
|
||||
await startup(window);
|
||||
|
||||
ok(!isMenuChecked(),
|
||||
"RDM menu item is unchecked by default");
|
||||
ok(!isMenuChecked(), "RDM menu item is unchecked by default");
|
||||
|
||||
const tab = await addTab(TEST_URL);
|
||||
|
||||
ok(!isMenuChecked(),
|
||||
"RDM menu item is unchecked for new tab");
|
||||
ok(!isMenuChecked(), "RDM menu item is unchecked for new tab");
|
||||
|
||||
await openRDM(tab);
|
||||
|
||||
ok(isMenuChecked(),
|
||||
"RDM menu item is checked with RDM open");
|
||||
ok(isMenuChecked(), "RDM menu item is checked with RDM open");
|
||||
|
||||
const tab2 = await addTab(TEST_URL);
|
||||
|
||||
ok(!isMenuChecked(),
|
||||
"RDM menu item is unchecked for new tab");
|
||||
ok(!isMenuChecked(), "RDM menu item is unchecked for new tab");
|
||||
|
||||
await activateTab(tab);
|
||||
|
||||
ok(isMenuChecked(),
|
||||
"RDM menu item is checked for the tab where RDM is open");
|
||||
ok(isMenuChecked(), "RDM menu item is checked for the tab where RDM is open");
|
||||
|
||||
await closeRDM(tab);
|
||||
|
||||
ok(!isMenuChecked(),
|
||||
"RDM menu item is unchecked after RDM is closed");
|
||||
ok(!isMenuChecked(), "RDM menu item is unchecked after RDM is closed");
|
||||
|
||||
await removeTab(tab);
|
||||
await removeTab(tab2);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
const TEST_URL = "data:text/html;charset=utf-8,";
|
||||
|
||||
const isMenuCheckedFor = ({document}) => {
|
||||
const isMenuCheckedFor = ({ document }) => {
|
||||
const menu = document.getElementById("menu_responsiveUI");
|
||||
return menu.getAttribute("checked") === "true";
|
||||
};
|
||||
|
@ -16,32 +16,38 @@ add_task(async function() {
|
|||
const window1 = await BrowserTestUtils.openNewBrowserWindow();
|
||||
const { gBrowser } = window1;
|
||||
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: TEST_URL },
|
||||
async function(browser) {
|
||||
const tab = gBrowser.getTabForBrowser(browser);
|
||||
await BrowserTestUtils.withNewTab({ gBrowser, url: TEST_URL }, async function(
|
||||
browser
|
||||
) {
|
||||
const tab = gBrowser.getTabForBrowser(browser);
|
||||
|
||||
is(window1, Services.wm.getMostRecentWindow("navigator:browser"),
|
||||
"The new window is the active one");
|
||||
is(
|
||||
window1,
|
||||
Services.wm.getMostRecentWindow("navigator:browser"),
|
||||
"The new window is the active one"
|
||||
);
|
||||
|
||||
ok(!isMenuCheckedFor(window1),
|
||||
"RDM menu item is unchecked by default");
|
||||
ok(!isMenuCheckedFor(window1), "RDM menu item is unchecked by default");
|
||||
|
||||
await openRDM(tab);
|
||||
await openRDM(tab);
|
||||
|
||||
ok(isMenuCheckedFor(window1),
|
||||
"RDM menu item is checked with RDM open");
|
||||
ok(isMenuCheckedFor(window1), "RDM menu item is checked with RDM open");
|
||||
|
||||
await closeRDM(tab);
|
||||
await closeRDM(tab);
|
||||
|
||||
ok(!isMenuCheckedFor(window1),
|
||||
"RDM menu item is unchecked with RDM closed");
|
||||
});
|
||||
ok(
|
||||
!isMenuCheckedFor(window1),
|
||||
"RDM menu item is unchecked with RDM closed"
|
||||
);
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(window1);
|
||||
|
||||
is(window, Services.wm.getMostRecentWindow("navigator:browser"),
|
||||
"The original window is the active one");
|
||||
is(
|
||||
window,
|
||||
Services.wm.getMostRecentWindow("navigator:browser"),
|
||||
"The original window is the active one"
|
||||
);
|
||||
|
||||
ok(!isMenuCheckedFor(window),
|
||||
"RDM menu item is unchecked");
|
||||
ok(!isMenuCheckedFor(window), "RDM menu item is unchecked");
|
||||
});
|
||||
|
|
|
@ -14,14 +14,30 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
await setViewportSize(ui, manager, 300, 300);
|
||||
|
||||
// Do horizontal + vertical resize
|
||||
await testViewportResize(ui, ".viewport-resize-handle",
|
||||
[10, 10], [320, 310], [10, 10]);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-resize-handle",
|
||||
[10, 10],
|
||||
[320, 310],
|
||||
[10, 10]
|
||||
);
|
||||
|
||||
// Do horizontal resize
|
||||
await testViewportResize(ui, ".viewport-horizontal-resize-handle",
|
||||
[-10, 10], [300, 310], [-10, 0]);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-horizontal-resize-handle",
|
||||
[-10, 10],
|
||||
[300, 310],
|
||||
[-10, 0]
|
||||
);
|
||||
|
||||
// Do vertical resize
|
||||
await testViewportResize(ui, ".viewport-vertical-resize-handle",
|
||||
[-10, -10], [300, 300], [0, -10], ui);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-vertical-resize-handle",
|
||||
[-10, -10],
|
||||
[300, 300],
|
||||
[0, -10],
|
||||
ui
|
||||
);
|
||||
});
|
||||
|
|
|
@ -51,7 +51,11 @@ add_task(async function() {
|
|||
ok(browser.webNavigation.canGoBack, "Going back is allowed");
|
||||
ok(!browser.webNavigation.canGoForward, "Going forward is not allowed");
|
||||
is(browser.documentURI.spec, DUMMY_2_URL, "documentURI matches page 2");
|
||||
is(browser.contentTitle, "mochitest index /browser/", "contentTitle matches page 2");
|
||||
is(
|
||||
browser.contentTitle,
|
||||
"mochitest index /browser/",
|
||||
"contentTitle matches page 2"
|
||||
);
|
||||
|
||||
await back(browser);
|
||||
await back(browser);
|
||||
|
@ -82,8 +86,11 @@ add_task(async function() {
|
|||
ok(browser.webNavigation.canGoBack, "Going back is allowed");
|
||||
ok(!browser.webNavigation.canGoForward, "Going forward is not allowed");
|
||||
is(browser.documentURI.spec, DUMMY_3_URL, "documentURI matches page 3");
|
||||
is(browser.contentTitle, "mochitest index /browser/devtools/",
|
||||
"contentTitle matches page 3");
|
||||
is(
|
||||
browser.contentTitle,
|
||||
"mochitest index /browser/devtools/",
|
||||
"contentTitle matches page 3"
|
||||
);
|
||||
|
||||
await closeRDM(tab);
|
||||
|
||||
|
|
|
@ -31,14 +31,23 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
});
|
||||
|
||||
function testNetworkThrottlingSelectorLabel(ui, expected) {
|
||||
const title = ui.toolWindow.document.querySelector("#network-throttling-menu .title");
|
||||
is(title.textContent, expected, `Button title should be changed to ${expected}`);
|
||||
const title = ui.toolWindow.document.querySelector(
|
||||
"#network-throttling-menu .title"
|
||||
);
|
||||
is(
|
||||
title.textContent,
|
||||
expected,
|
||||
`Button title should be changed to ${expected}`
|
||||
);
|
||||
}
|
||||
|
||||
var testNetworkThrottlingState = async function(ui, expected) {
|
||||
const state = await ui.emulationFront.getNetworkThrottling();
|
||||
Assert.deepEqual(state, expected, "Network throttling state should be " +
|
||||
JSON.stringify(expected, null, 2));
|
||||
Assert.deepEqual(
|
||||
state,
|
||||
expected,
|
||||
"Network throttling state should be " + JSON.stringify(expected, null, 2)
|
||||
);
|
||||
};
|
||||
|
||||
var testThrottlingProfile = async function(ui, profile) {
|
||||
|
|
|
@ -12,42 +12,59 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
await pushPref("devtools.responsive.viewport.angle", 0);
|
||||
rotateViewport(ui);
|
||||
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {},
|
||||
async function() {
|
||||
info("Check the original orientation values before the orientationchange");
|
||||
is(content.screen.orientation.type, "portrait-primary",
|
||||
"Primary orientation type is portrait-primary.");
|
||||
is(content.screen.orientation.angle, 0,
|
||||
"Original angle is set at 0 degrees");
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
info("Check the original orientation values before the orientationchange");
|
||||
is(
|
||||
content.screen.orientation.type,
|
||||
"portrait-primary",
|
||||
"Primary orientation type is portrait-primary."
|
||||
);
|
||||
is(
|
||||
content.screen.orientation.angle,
|
||||
0,
|
||||
"Original angle is set at 0 degrees"
|
||||
);
|
||||
|
||||
const orientationChange = new Promise(resolve => {
|
||||
content.window.addEventListener("orientationchange", () => {
|
||||
ok(true, "'orientationchange' event fired");
|
||||
is(content.screen.orientation.type, "landscape-primary",
|
||||
"Orientation state was updated to landscape-primary");
|
||||
is(content.screen.orientation.angle, 90,
|
||||
"Orientation angle was updated to 90 degrees.");
|
||||
resolve();
|
||||
});
|
||||
const orientationChange = new Promise(resolve => {
|
||||
content.window.addEventListener("orientationchange", () => {
|
||||
ok(true, "'orientationchange' event fired");
|
||||
is(
|
||||
content.screen.orientation.type,
|
||||
"landscape-primary",
|
||||
"Orientation state was updated to landscape-primary"
|
||||
);
|
||||
is(
|
||||
content.screen.orientation.angle,
|
||||
90,
|
||||
"Orientation angle was updated to 90 degrees."
|
||||
);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
|
||||
await orientationChange;
|
||||
}
|
||||
await orientationChange;
|
||||
});
|
||||
|
||||
info(
|
||||
"Check that the viewport orientation changed, but not the angle after a reload"
|
||||
);
|
||||
|
||||
info("Check that the viewport orientation changed, but not the angle after a reload");
|
||||
const browser = ui.getViewportBrowser();
|
||||
const reload = browser.reload();
|
||||
const onViewportOrientationChange = once(ui, "only-viewport-orientation-changed");
|
||||
const onViewportOrientationChange = once(
|
||||
ui,
|
||||
"only-viewport-orientation-changed"
|
||||
);
|
||||
await reload;
|
||||
await onViewportOrientationChange;
|
||||
ok(true, "orientationchange event was not dispatched on reload.");
|
||||
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {},
|
||||
async function() {
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
info("Check that we still have the previous orientation values.");
|
||||
is(content.screen.orientation.angle, 90, "Orientation angle is still 90");
|
||||
is(content.screen.orientation.type,
|
||||
"landscape-primary", "Orientation is still landscape-primary.");
|
||||
is(
|
||||
content.screen.orientation.type,
|
||||
"landscape-primary",
|
||||
"Orientation is still landscape-primary."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -46,21 +46,29 @@ add_task(async function() {
|
|||
|
||||
// Check color inside the viewport
|
||||
let color = await spawnViewportTask(ui, {}, function() {
|
||||
return content.getComputedStyle(content.document.body)
|
||||
.getPropertyValue("background-color");
|
||||
return content
|
||||
.getComputedStyle(content.document.body)
|
||||
.getPropertyValue("background-color");
|
||||
});
|
||||
is(color, "rgb(0, 128, 0)",
|
||||
"Content is still modified from click in viewport");
|
||||
is(
|
||||
color,
|
||||
"rgb(0, 128, 0)",
|
||||
"Content is still modified from click in viewport"
|
||||
);
|
||||
|
||||
await closeRDM(tab);
|
||||
|
||||
// Check color back in the browser tab
|
||||
color = await ContentTask.spawn(browser, {}, async function() {
|
||||
return content.getComputedStyle(content.document.body)
|
||||
.getPropertyValue("background-color");
|
||||
return content
|
||||
.getComputedStyle(content.document.body)
|
||||
.getPropertyValue("background-color");
|
||||
});
|
||||
is(color, "rgb(0, 128, 0)",
|
||||
"Content is still modified from click in browser tab");
|
||||
is(
|
||||
color,
|
||||
"rgb(0, 128, 0)",
|
||||
"Content is still modified from click in browser tab"
|
||||
);
|
||||
|
||||
// Check session history state
|
||||
history = await getSessionHistory(browser);
|
||||
|
|
|
@ -11,31 +11,49 @@ const TEST_URL = `${URL_ROOT}page_style.html`;
|
|||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Store the RDM body text color for later.
|
||||
const rdmWindow = ui.toolWindow;
|
||||
const rdmTextColor = rdmWindow.getComputedStyle(rdmWindow.document.body).color;
|
||||
const rdmTextColor = rdmWindow.getComputedStyle(rdmWindow.document.body)
|
||||
.color;
|
||||
|
||||
info("Trigger the no page style action and wait for the text color to change");
|
||||
info(
|
||||
"Trigger the no page style action and wait for the text color to change"
|
||||
);
|
||||
let onPageColorChanged = waitForContentPageTextColor(ui, "rgb(0, 0, 0)");
|
||||
let menuItem = document.querySelector("#menu_pageStyleNoStyle");
|
||||
menuItem.click();
|
||||
let color = await onPageColorChanged;
|
||||
|
||||
is(color, "rgb(0, 0, 0)", "The text color is black, so the style was disabled");
|
||||
is(
|
||||
color,
|
||||
"rgb(0, 0, 0)",
|
||||
"The text color is black, so the style was disabled"
|
||||
);
|
||||
|
||||
info("Check that the RDM page style wasn't disabled");
|
||||
is(rdmWindow.getComputedStyle(rdmWindow.document.body).color, rdmTextColor,
|
||||
"The color of the text in the RDM window is correct, so that style still applies");
|
||||
is(
|
||||
rdmWindow.getComputedStyle(rdmWindow.document.body).color,
|
||||
rdmTextColor,
|
||||
"The color of the text in the RDM window is correct, so that style still applies"
|
||||
);
|
||||
|
||||
info("Trigger the page style back and wait for the text color to change again");
|
||||
info(
|
||||
"Trigger the page style back and wait for the text color to change again"
|
||||
);
|
||||
onPageColorChanged = waitForContentPageTextColor(ui, "rgb(255, 0, 0)");
|
||||
menuItem = document.querySelector("#menu_pageStylePersistentOnly");
|
||||
menuItem.click();
|
||||
color = await onPageColorChanged;
|
||||
|
||||
is(color, "rgb(255, 0, 0)", "The text color is red, so the style was enabled");
|
||||
is(
|
||||
color,
|
||||
"rgb(255, 0, 0)",
|
||||
"The text color is red, so the style was enabled"
|
||||
);
|
||||
});
|
||||
|
||||
function waitForContentPageTextColor(ui, expectedColor) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(), { expectedColor }, function(args) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(), { expectedColor }, function(
|
||||
args
|
||||
) {
|
||||
return new Promise(resolve => {
|
||||
const interval = content.setInterval(() => {
|
||||
const color = content.getComputedStyle(content.document.body).color;
|
||||
|
|
|
@ -10,13 +10,22 @@ const TEST_SURL = TEST_URL.replace("http://example.com", "https://example.com");
|
|||
|
||||
function waitForGeolocationPrompt(win, browser) {
|
||||
return new Promise(resolve => {
|
||||
win.PopupNotifications.panel.addEventListener("popupshown", function popupShown() {
|
||||
const notification = win.PopupNotifications.getNotification("geolocation", browser);
|
||||
if (notification) {
|
||||
win.PopupNotifications.panel.removeEventListener("popupshown", popupShown);
|
||||
resolve();
|
||||
win.PopupNotifications.panel.addEventListener(
|
||||
"popupshown",
|
||||
function popupShown() {
|
||||
const notification = win.PopupNotifications.getNotification(
|
||||
"geolocation",
|
||||
browser
|
||||
);
|
||||
if (notification) {
|
||||
win.PopupNotifications.panel.removeEventListener(
|
||||
"popupshown",
|
||||
popupShown
|
||||
);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,11 @@ add_task(async function() {
|
|||
waitForLoad: false,
|
||||
});
|
||||
const browser = tab.linkedBrowser;
|
||||
is(browser.getAttribute("preloadedState"), "consumed",
|
||||
"Got a preloaded browser for newtab");
|
||||
is(
|
||||
browser.getAttribute("preloadedState"),
|
||||
"consumed",
|
||||
"Got a preloaded browser for newtab"
|
||||
);
|
||||
|
||||
// Open RDM and try to navigate
|
||||
const { ui } = await openRDM(tab);
|
||||
|
|
|
@ -18,7 +18,11 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
// Alerts coming from inside the viewport are relayed by RDM to the outer browser.
|
||||
// So, in order to test that those relayed prompts occur, let's override the usual
|
||||
// alert, prompt and confirm methods there to test that they get called.
|
||||
const { alert: oldAlert, prompt: oldPrompt, confirm: oldConfirm } = toolWindow;
|
||||
const {
|
||||
alert: oldAlert,
|
||||
prompt: oldPrompt,
|
||||
confirm: oldConfirm,
|
||||
} = toolWindow;
|
||||
|
||||
info("Listen for calls on alert, prompt and confirm");
|
||||
const prompts = [];
|
||||
|
@ -57,16 +61,31 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
ok(!prompts[0].initialValue, "Prompt 1 has the right initialValue");
|
||||
|
||||
is(prompts[1].promptType, "prompt", "Prompt 2 has the right type");
|
||||
is(prompts[1].message, "Some simple prompt", "Prompt 2 has the right message");
|
||||
is(
|
||||
prompts[1].message,
|
||||
"Some simple prompt",
|
||||
"Prompt 2 has the right message"
|
||||
);
|
||||
ok(!prompts[1].initialValue, "Prompt 2 has the right initialValue");
|
||||
|
||||
is(prompts[2].promptType, "prompt", "Prompt 3 has the right type");
|
||||
is(prompts[2].message, "Some simple prompt with initial value",
|
||||
"Prompt 3 has the right message");
|
||||
is(prompts[2].initialValue, "initial value", "Prompt 3 has the right initialValue");
|
||||
is(
|
||||
prompts[2].message,
|
||||
"Some simple prompt with initial value",
|
||||
"Prompt 3 has the right message"
|
||||
);
|
||||
is(
|
||||
prompts[2].initialValue,
|
||||
"initial value",
|
||||
"Prompt 3 has the right initialValue"
|
||||
);
|
||||
|
||||
is(prompts[3].promptType, "confirm", "Prompt 4 has the right type");
|
||||
is(prompts[3].message, "Some simple confirm", "Prompt 4 has the right message");
|
||||
is(
|
||||
prompts[3].message,
|
||||
"Some simple confirm",
|
||||
"Prompt 4 has the right message"
|
||||
);
|
||||
ok(!prompts[3].initialValue, "Prompt 4 has the right initialValue");
|
||||
|
||||
// Revert the old versions of alert, prompt and confirm.
|
||||
|
|
|
@ -27,7 +27,7 @@ function waitUntilScreenshot() {
|
|||
});
|
||||
}
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui: {toolWindow} }) {
|
||||
addRDMTask(TEST_URL, async function({ ui: { toolWindow } }) {
|
||||
const { store, document } = toolWindow;
|
||||
|
||||
// Wait until the viewport has been added
|
||||
|
@ -49,11 +49,17 @@ addRDMTask(TEST_URL, async function({ ui: {toolWindow} }) {
|
|||
const viewport = store.getState().viewports[0];
|
||||
const ratio = window.devicePixelRatio;
|
||||
|
||||
is(image.width, viewport.width * ratio,
|
||||
"screenshot width has the expected width");
|
||||
is(
|
||||
image.width,
|
||||
viewport.width * ratio,
|
||||
"screenshot width has the expected width"
|
||||
);
|
||||
|
||||
is(image.height, viewport.height * ratio,
|
||||
"screenshot width has the expected height");
|
||||
is(
|
||||
image.height,
|
||||
viewport.height * ratio,
|
||||
"screenshot width has the expected height"
|
||||
);
|
||||
|
||||
await OS.File.remove(filePath);
|
||||
});
|
||||
|
|
|
@ -8,8 +8,9 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
|||
* behaves correctly, both with and without touch simulation enabled.
|
||||
*/
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<div style=\"background:blue; width:200px; height:200px\"></div>";
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
'<div style="background:blue; width:200px; height:200px"></div>';
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
await setViewportSize(ui, manager, 100, 100);
|
||||
|
|
|
@ -6,9 +6,10 @@
|
|||
// Ensure target="_blank" link opens a new tab
|
||||
|
||||
const TAB_URL = "http://example.com/";
|
||||
const TEST_URL =
|
||||
`data:text/html,<a href="${TAB_URL}" target="_blank">Click me</a>`
|
||||
.replace(/ /g, "%20");
|
||||
const TEST_URL = `data:text/html,<a href="${TAB_URL}" target="_blank">Click me</a>`.replace(
|
||||
/ /g,
|
||||
"%20"
|
||||
);
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui }) {
|
||||
const store = ui.toolWindow.store;
|
||||
|
|
|
@ -15,7 +15,8 @@ const DATA = [
|
|||
host: "none",
|
||||
width: "1300",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
timestamp: null,
|
||||
category: "devtools.main",
|
||||
method: "deactivate",
|
||||
|
@ -25,7 +26,8 @@ const DATA = [
|
|||
host: "none",
|
||||
width: "1300",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
timestamp: null,
|
||||
category: "devtools.main",
|
||||
method: "activate",
|
||||
|
@ -35,7 +37,8 @@ const DATA = [
|
|||
host: "bottom",
|
||||
width: "1300",
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
timestamp: null,
|
||||
category: "devtools.main",
|
||||
method: "deactivate",
|
||||
|
@ -83,13 +86,14 @@ async function openCloseRDM(tab) {
|
|||
|
||||
async function checkResults() {
|
||||
const snapshot = Services.telemetry.snapshotEvents(ALL_CHANNELS, true);
|
||||
const events = snapshot.parent.filter(event => event[1] === "devtools.main" &&
|
||||
(event[2] === "activate" ||
|
||||
event[2] === "deactivate")
|
||||
const events = snapshot.parent.filter(
|
||||
event =>
|
||||
event[1] === "devtools.main" &&
|
||||
(event[2] === "activate" || event[2] === "deactivate")
|
||||
);
|
||||
|
||||
for (const i in events) {
|
||||
const [ timestamp, category, method, object, value, extra ] = events[i];
|
||||
const [timestamp, category, method, object, value, extra] = events[i];
|
||||
|
||||
const expected = DATA[i];
|
||||
|
||||
|
|
|
@ -27,15 +27,21 @@ add_task(async function() {
|
|||
|
||||
// Get the initial zoom level.
|
||||
const initialOuterZoom = getZoomForBrowser(browser);
|
||||
is(initialOuterZoom, INITIAL_ZOOM_LEVEL, "Initial outer zoom should be " +
|
||||
INITIAL_ZOOM_LEVEL + ".");
|
||||
is(
|
||||
initialOuterZoom,
|
||||
INITIAL_ZOOM_LEVEL,
|
||||
"Initial outer zoom should be " + INITIAL_ZOOM_LEVEL + "."
|
||||
);
|
||||
|
||||
// Change the zoom level before we open RDM.
|
||||
setZoomForBrowser(browser, PRE_RDM_ZOOM_LEVEL);
|
||||
|
||||
const preRDMOuterZoom = getZoomForBrowser(browser);
|
||||
is(preRDMOuterZoom, PRE_RDM_ZOOM_LEVEL, "Pre-RDM outer zoom should be " +
|
||||
PRE_RDM_ZOOM_LEVEL + ".");
|
||||
is(
|
||||
preRDMOuterZoom,
|
||||
PRE_RDM_ZOOM_LEVEL,
|
||||
"Pre-RDM outer zoom should be " + PRE_RDM_ZOOM_LEVEL + "."
|
||||
);
|
||||
|
||||
// Start RDM on the tab. This will fundamentally change the way that browser behaves.
|
||||
// It will now pass all of its messages through to the RDM docshell, meaning that when
|
||||
|
@ -50,8 +56,11 @@ add_task(async function() {
|
|||
// RDM pane not useful.
|
||||
|
||||
const preZoomUIZoom = uiDocShell.contentViewer.fullZoom;
|
||||
is(preZoomUIZoom, INITIAL_ZOOM_LEVEL,
|
||||
"Pre-zoom UI zoom should be " + INITIAL_ZOOM_LEVEL + ".");
|
||||
is(
|
||||
preZoomUIZoom,
|
||||
INITIAL_ZOOM_LEVEL,
|
||||
"Pre-zoom UI zoom should be " + INITIAL_ZOOM_LEVEL + "."
|
||||
);
|
||||
|
||||
// Set the zoom level. This should tunnel to the inner browser and leave the UI alone.
|
||||
setZoomForBrowser(browser, MID_RDM_ZOOM_LEVEL);
|
||||
|
@ -62,12 +71,20 @@ add_task(async function() {
|
|||
|
||||
// The RDM zoom should be changed.
|
||||
const finalRDMZoom = getZoomForBrowser(browser);
|
||||
is(finalRDMZoom, MID_RDM_ZOOM_LEVEL, "RDM zoom should be " + MID_RDM_ZOOM_LEVEL + ".");
|
||||
is(
|
||||
finalRDMZoom,
|
||||
MID_RDM_ZOOM_LEVEL,
|
||||
"RDM zoom should be " + MID_RDM_ZOOM_LEVEL + "."
|
||||
);
|
||||
|
||||
// Leave RDM. This should cause the outer pane to take on the full zoom of the RDM pane.
|
||||
await closeRDM(tab);
|
||||
|
||||
// Bug 1541692: the following todo_is check will become an is check when this bug lands.
|
||||
const finalOuterZoom = getZoomForBrowser(browser);
|
||||
todo_is(finalOuterZoom, finalRDMZoom, "Final outer zoom should match last RDM zoom.");
|
||||
todo_is(
|
||||
finalOuterZoom,
|
||||
finalRDMZoom,
|
||||
"Final outer zoom should match last RDM zoom."
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,18 +5,19 @@
|
|||
|
||||
// Check that when the viewport is resized, the computed-view refreshes.
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>";
|
||||
const TEST_URI =
|
||||
"data:text/html;charset=utf-8,<html><style>" +
|
||||
"div {" +
|
||||
" width: 500px;" +
|
||||
" height: 10px;" +
|
||||
" background: purple;" +
|
||||
"} " +
|
||||
"@media screen and (max-width: 200px) {" +
|
||||
" div { " +
|
||||
" width: 100px;" +
|
||||
" }" +
|
||||
"};" +
|
||||
"</style><div></div></html>";
|
||||
|
||||
addRDMTask(TEST_URI, async function({ ui, manager }) {
|
||||
info("Open the responsive design mode and set its size to 500x500 to start");
|
||||
|
|
|
@ -10,7 +10,9 @@ const TEST_URL = "http://example.com/";
|
|||
function getServerConnections(browser) {
|
||||
ok(browser.isRemoteBrowser, "Content browser is remote");
|
||||
return ContentTask.spawn(browser, {}, async function() {
|
||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm");
|
||||
const { require } = ChromeUtils.import(
|
||||
"resource://devtools/shared/Loader.jsm"
|
||||
);
|
||||
const { DebuggerServer } = require("devtools/server/main");
|
||||
if (!DebuggerServer._connections) {
|
||||
return 0;
|
||||
|
@ -32,89 +34,135 @@ const checkToolbox = async function(tab, location) {
|
|||
add_task(async function() {
|
||||
const tab = await addTab(TEST_URL);
|
||||
|
||||
const tabsInDifferentProcesses = E10S_MULTI_ENABLED &&
|
||||
(gBrowser.tabs[0].linkedBrowser.frameLoader.childID !=
|
||||
gBrowser.tabs[1].linkedBrowser.frameLoader.childID);
|
||||
const tabsInDifferentProcesses =
|
||||
E10S_MULTI_ENABLED &&
|
||||
gBrowser.tabs[0].linkedBrowser.frameLoader.childID !=
|
||||
gBrowser.tabs[1].linkedBrowser.frameLoader.childID;
|
||||
|
||||
info("Open toolbox outside RDM");
|
||||
{
|
||||
// 0: No DevTools connections yet
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 0,
|
||||
"0: No DevTools connections yet");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
0,
|
||||
"0: No DevTools connections yet"
|
||||
);
|
||||
const { toolbox } = await openInspector();
|
||||
if (tabsInDifferentProcesses) {
|
||||
// 1: Two tabs open, but only one per content process
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 1,
|
||||
"1: Two tabs open, but only one per content process");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
1,
|
||||
"1: Two tabs open, but only one per content process"
|
||||
);
|
||||
} else {
|
||||
// 2: One for each tab (starting tab plus the one we opened)
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 2,
|
||||
"2: One for each tab (starting tab plus the one we opened)");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
2,
|
||||
"2: One for each tab (starting tab plus the one we opened)"
|
||||
);
|
||||
}
|
||||
await checkToolbox(tab, "outside RDM");
|
||||
const { ui } = await openRDM(tab);
|
||||
if (tabsInDifferentProcesses) {
|
||||
// 2: RDM UI adds an extra connection, 1 + 1 = 2
|
||||
await checkServerConnectionCount(ui.getViewportBrowser(), 2,
|
||||
"2: RDM UI uses an extra connection");
|
||||
await checkServerConnectionCount(
|
||||
ui.getViewportBrowser(),
|
||||
2,
|
||||
"2: RDM UI uses an extra connection"
|
||||
);
|
||||
} else {
|
||||
// 3: RDM UI adds an extra connection, 2 + 1 = 3
|
||||
await checkServerConnectionCount(ui.getViewportBrowser(), 3,
|
||||
"3: RDM UI uses an extra connection");
|
||||
await checkServerConnectionCount(
|
||||
ui.getViewportBrowser(),
|
||||
3,
|
||||
"3: RDM UI uses an extra connection"
|
||||
);
|
||||
}
|
||||
await checkToolbox(tab, "after opening RDM");
|
||||
await closeRDM(tab);
|
||||
if (tabsInDifferentProcesses) {
|
||||
// 1: RDM UI closed, return to previous connection count
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 1,
|
||||
"1: RDM UI closed, return to previous connection count");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
1,
|
||||
"1: RDM UI closed, return to previous connection count"
|
||||
);
|
||||
} else {
|
||||
// 2: RDM UI closed, return to previous connection count
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 2,
|
||||
"2: RDM UI closed, return to previous connection count");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
2,
|
||||
"2: RDM UI closed, return to previous connection count"
|
||||
);
|
||||
}
|
||||
await checkToolbox(tab, tab.linkedBrowser, "after closing RDM");
|
||||
await toolbox.destroy();
|
||||
// 0: All DevTools usage closed
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 0,
|
||||
"0: All DevTools usage closed");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
0,
|
||||
"0: All DevTools usage closed"
|
||||
);
|
||||
}
|
||||
|
||||
info("Open toolbox inside RDM");
|
||||
{
|
||||
// 0: No DevTools connections yet
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 0,
|
||||
"0: No DevTools connections yet");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
0,
|
||||
"0: No DevTools connections yet"
|
||||
);
|
||||
const { ui } = await openRDM(tab);
|
||||
// 1: RDM UI uses an extra connection
|
||||
await checkServerConnectionCount(ui.getViewportBrowser(), 1,
|
||||
"1: RDM UI uses an extra connection");
|
||||
await checkServerConnectionCount(
|
||||
ui.getViewportBrowser(),
|
||||
1,
|
||||
"1: RDM UI uses an extra connection"
|
||||
);
|
||||
const { toolbox } = await openInspector();
|
||||
if (tabsInDifferentProcesses) {
|
||||
// 2: Two tabs open, but only one per content process
|
||||
await checkServerConnectionCount(ui.getViewportBrowser(), 2,
|
||||
"2: Two tabs open, but only one per content process");
|
||||
await checkServerConnectionCount(
|
||||
ui.getViewportBrowser(),
|
||||
2,
|
||||
"2: Two tabs open, but only one per content process"
|
||||
);
|
||||
} else {
|
||||
// 3: One for each tab (starting tab plus the one we opened)
|
||||
await checkServerConnectionCount(ui.getViewportBrowser(), 3,
|
||||
"3: One for each tab (starting tab plus the one we opened)");
|
||||
await checkServerConnectionCount(
|
||||
ui.getViewportBrowser(),
|
||||
3,
|
||||
"3: One for each tab (starting tab plus the one we opened)"
|
||||
);
|
||||
}
|
||||
await checkToolbox(tab, ui.getViewportBrowser(), "inside RDM");
|
||||
await closeRDM(tab);
|
||||
if (tabsInDifferentProcesses) {
|
||||
// 1: RDM UI closed, one less connection
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 1,
|
||||
"1: RDM UI closed, one less connection");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
1,
|
||||
"1: RDM UI closed, one less connection"
|
||||
);
|
||||
} else {
|
||||
// 2: RDM UI closed, one less connection
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 2,
|
||||
"2: RDM UI closed, one less connection");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
2,
|
||||
"2: RDM UI closed, one less connection"
|
||||
);
|
||||
}
|
||||
await checkToolbox(tab, tab.linkedBrowser, "after closing RDM");
|
||||
await toolbox.destroy();
|
||||
// 0: All DevTools usage closed
|
||||
await checkServerConnectionCount(tab.linkedBrowser, 0,
|
||||
"0: All DevTools usage closed");
|
||||
await checkServerConnectionCount(
|
||||
tab.linkedBrowser,
|
||||
0,
|
||||
"0: All DevTools usage closed"
|
||||
);
|
||||
}
|
||||
|
||||
await removeTab(tab);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"use strict";
|
||||
|
||||
const TEST_CONTENT = `<h1 title="test title">test h1</h1>`;
|
||||
const TEST_URL = `data:text/html;charset=utf-8,${ TEST_CONTENT }`;
|
||||
const TEST_URL = `data:text/html;charset=utf-8,${TEST_CONTENT}`;
|
||||
|
||||
// Test for the tooltip coordinate on the browsing document in RDM.
|
||||
|
||||
|
@ -15,19 +15,32 @@ addRDMTask(TEST_URL, async ({ ui }) => {
|
|||
await spawnViewportTask(ui, {}, async () => {
|
||||
const target = content.document.querySelector("h1");
|
||||
await EventUtils.synthesizeMouse(
|
||||
target, 1, 1, { type: "mouseover", isSynthesized: false }, content
|
||||
target,
|
||||
1,
|
||||
1,
|
||||
{ type: "mouseover", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
await EventUtils.synthesizeMouse(
|
||||
target, 2, 1, { type: "mousemove", isSynthesized: false }, content
|
||||
target,
|
||||
2,
|
||||
1,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
await EventUtils.synthesizeMouse(
|
||||
target, 3, 1, { type: "mousemove", isSynthesized: false }, content
|
||||
target,
|
||||
3,
|
||||
1,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
});
|
||||
|
||||
info("Wait for showing the tooltip");
|
||||
const tooltip =
|
||||
ui.browserWindow.gBrowser.ownerDocument.getElementById("remoteBrowserTooltip");
|
||||
const tooltip = ui.browserWindow.gBrowser.ownerDocument.getElementById(
|
||||
"remoteBrowserTooltip"
|
||||
);
|
||||
await waitUntil(() => tooltip.state === "open");
|
||||
|
||||
info("Test the X coordinate of the tooltip");
|
||||
|
|
|
@ -8,15 +8,15 @@ const TEST_URL = "data:text/html;charset=utf-8,touch simulation test";
|
|||
const Types = require("devtools/client/responsive/types");
|
||||
|
||||
const testDevice = {
|
||||
"name": "Fake Phone RDM Test",
|
||||
"width": 320,
|
||||
"height": 470,
|
||||
"pixelRatio": 5.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "custom",
|
||||
"featured": true,
|
||||
name: "Fake Phone RDM Test",
|
||||
width: 320,
|
||||
height: 470,
|
||||
pixelRatio: 5.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "custom",
|
||||
featured: true,
|
||||
};
|
||||
|
||||
// Add the new device to the list
|
||||
|
@ -41,8 +41,12 @@ async function waitStartup(ui) {
|
|||
const { store } = ui.toolWindow;
|
||||
|
||||
// Wait until the viewport has been added and the device list has been loaded
|
||||
await waitUntilState(store, state => state.viewports.length == 1
|
||||
&& state.devices.listState == Types.loadableState.LOADED);
|
||||
await waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.viewports.length == 1 &&
|
||||
state.devices.listState == Types.loadableState.LOADED
|
||||
);
|
||||
}
|
||||
|
||||
async function testDefaults(ui) {
|
||||
|
@ -68,8 +72,14 @@ async function testResizingViewport(ui, device, touch) {
|
|||
if (device) {
|
||||
deviceRemoved = once(ui, "device-association-removed");
|
||||
}
|
||||
await testViewportResize(ui, ".viewport-vertical-resize-handle",
|
||||
[-10, -10], [testDevice.width, testDevice.height - 10], [0, -10], ui);
|
||||
await testViewportResize(
|
||||
ui,
|
||||
".viewport-vertical-resize-handle",
|
||||
[-10, -10],
|
||||
[testDevice.width, testDevice.height - 10],
|
||||
[0, -10],
|
||||
ui
|
||||
);
|
||||
if (device) {
|
||||
await deviceRemoved;
|
||||
}
|
||||
|
|
|
@ -27,35 +27,49 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
});
|
||||
|
||||
async function testButtonHoverState(ui, expected) {
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), { expected },
|
||||
async function(args) {
|
||||
let button = content.document.querySelector("button");
|
||||
const { expected: contentExpected } = args;
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), { expected }, async function(
|
||||
args
|
||||
) {
|
||||
let button = content.document.querySelector("button");
|
||||
const { expected: contentExpected } = args;
|
||||
|
||||
info("Move mouse into the button element.");
|
||||
await EventUtils.synthesizeMouseAtCenter(button,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
button = content.document.querySelector("button");
|
||||
const win = content.document.defaultView;
|
||||
info("Move mouse into the button element.");
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
button,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
button = content.document.querySelector("button");
|
||||
const win = content.document.defaultView;
|
||||
|
||||
is(win.getComputedStyle(button).getPropertyValue("background-color"),
|
||||
contentExpected, `Button background color is ${contentExpected}.`);
|
||||
});
|
||||
is(
|
||||
win.getComputedStyle(button).getPropertyValue("background-color"),
|
||||
contentExpected,
|
||||
`Button background color is ${contentExpected}.`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function testDropDownHoverState(ui, expected) {
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), { expected },
|
||||
async function(args) {
|
||||
const dropDownMenu = content.document.querySelector(".drop-down-menu");
|
||||
const { expected: contentExpected } = args;
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), { expected }, async function(
|
||||
args
|
||||
) {
|
||||
const dropDownMenu = content.document.querySelector(".drop-down-menu");
|
||||
const { expected: contentExpected } = args;
|
||||
|
||||
info("Move mouse into the drop down menu.");
|
||||
await EventUtils.synthesizeMouseAtCenter(dropDownMenu,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
const win = content.document.defaultView;
|
||||
const menuItems = content.document.querySelector(".menu-items-list");
|
||||
info("Move mouse into the drop down menu.");
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
dropDownMenu,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
const win = content.document.defaultView;
|
||||
const menuItems = content.document.querySelector(".menu-items-list");
|
||||
|
||||
is(win.getComputedStyle(menuItems).getPropertyValue("display"), contentExpected,
|
||||
`Menu items is display: ${contentExpected}.`);
|
||||
});
|
||||
is(
|
||||
win.getComputedStyle(menuItems).getPropertyValue("display"),
|
||||
contentExpected,
|
||||
`Menu items is display: ${contentExpected}.`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -27,101 +27,188 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
async function testWithNoTouch(ui) {
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
const div = content.document.querySelector("div");
|
||||
let x = 0, y = 0;
|
||||
let x = 0,
|
||||
y = 0;
|
||||
|
||||
info("testWithNoTouch: Initial test parameter and mouse mouse outside div");
|
||||
x = -1; y = -1;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
x = -1;
|
||||
y = -1;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
div.style.transform = "none";
|
||||
div.style.backgroundColor = "";
|
||||
|
||||
info("testWithNoTouch: Move mouse into the div element");
|
||||
await EventUtils.synthesizeMouseAtCenter(div,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
div,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
is(div.style.backgroundColor, "red", "mouseenter or mouseover should work");
|
||||
|
||||
info("testWithNoTouch: Drag the div element");
|
||||
await EventUtils.synthesizeMouseAtCenter(div,
|
||||
{ type: "mousedown", isSynthesized: false }, content);
|
||||
x = 100; y = 100;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
div,
|
||||
{ type: "mousedown", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
x = 100;
|
||||
y = 100;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
is(div.style.transform, "none", "touchmove shouldn't work");
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mouseup", isSynthesized: false }, content);
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mouseup", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
|
||||
info("testWithNoTouch: Move mouse out of the div element");
|
||||
x = -1; y = -1;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
x = -1;
|
||||
y = -1;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
is(div.style.backgroundColor, "blue", "mouseout or mouseleave should work");
|
||||
|
||||
info("testWithNoTouch: Click the div element");
|
||||
await EventUtils.synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "false",
|
||||
"300ms delay between touch events and mouse events should not work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"false",
|
||||
"300ms delay between touch events and mouse events should not work"
|
||||
);
|
||||
|
||||
// Assuming that this test runs on devices having no touch screen device.
|
||||
ok(!content.document.defaultView.matchMedia("(pointer: coarse)").matches,
|
||||
"pointer: coarse shouldn't be matched");
|
||||
ok(!content.document.defaultView.matchMedia("(hover: none)").matches,
|
||||
"hover: none shouldn't be matched");
|
||||
ok(!content.document.defaultView.matchMedia("(any-pointer: coarse)").matches,
|
||||
"any-pointer: coarse shouldn't be matched");
|
||||
ok(!content.document.defaultView.matchMedia("(any-hover: none)").matches,
|
||||
"any-hover: none shouldn't be matched");
|
||||
ok(
|
||||
!content.document.defaultView.matchMedia("(pointer: coarse)").matches,
|
||||
"pointer: coarse shouldn't be matched"
|
||||
);
|
||||
ok(
|
||||
!content.document.defaultView.matchMedia("(hover: none)").matches,
|
||||
"hover: none shouldn't be matched"
|
||||
);
|
||||
ok(
|
||||
!content.document.defaultView.matchMedia("(any-pointer: coarse)").matches,
|
||||
"any-pointer: coarse shouldn't be matched"
|
||||
);
|
||||
ok(
|
||||
!content.document.defaultView.matchMedia("(any-hover: none)").matches,
|
||||
"any-hover: none shouldn't be matched"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function testWithTouch(ui) {
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
const div = content.document.querySelector("div");
|
||||
let x = 0, y = 0;
|
||||
let x = 0,
|
||||
y = 0;
|
||||
|
||||
info("testWithTouch: Initial test parameter and mouse mouse outside div");
|
||||
x = -1; y = -1;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
x = -1;
|
||||
y = -1;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
div.style.transform = "none";
|
||||
div.style.backgroundColor = "";
|
||||
|
||||
info("testWithTouch: Move mouse into the div element");
|
||||
await EventUtils.synthesizeMouseAtCenter(div,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
isnot(div.style.backgroundColor, "red",
|
||||
"mouseenter or mouseover should not work");
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
div,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
isnot(
|
||||
div.style.backgroundColor,
|
||||
"red",
|
||||
"mouseenter or mouseover should not work"
|
||||
);
|
||||
|
||||
info("testWithTouch: Drag the div element");
|
||||
await EventUtils.synthesizeMouseAtCenter(div,
|
||||
{ type: "mousedown", isSynthesized: false }, content);
|
||||
x = 100; y = 100;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
await EventUtils.synthesizeMouseAtCenter(
|
||||
div,
|
||||
{ type: "mousedown", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
x = 100;
|
||||
y = 100;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
isnot(div.style.transform, "none", "touchmove should work");
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mouseup", isSynthesized: false }, content);
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mouseup", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
|
||||
info("testWithTouch: Move mouse out of the div element");
|
||||
x = -1; y = -1;
|
||||
await EventUtils.synthesizeMouse(div, x, y,
|
||||
{ type: "mousemove", isSynthesized: false }, content);
|
||||
isnot(div.style.backgroundColor, "blue",
|
||||
"mouseout or mouseleave should not work");
|
||||
x = -1;
|
||||
y = -1;
|
||||
await EventUtils.synthesizeMouse(
|
||||
div,
|
||||
x,
|
||||
y,
|
||||
{ type: "mousemove", isSynthesized: false },
|
||||
content
|
||||
);
|
||||
isnot(
|
||||
div.style.backgroundColor,
|
||||
"blue",
|
||||
"mouseout or mouseleave should not work"
|
||||
);
|
||||
|
||||
ok(content.document.defaultView.matchMedia("(pointer: coarse)").matches,
|
||||
"pointer: coarse should be matched");
|
||||
ok(content.document.defaultView.matchMedia("(hover: none)").matches,
|
||||
"hover: none should be matched");
|
||||
ok(content.document.defaultView.matchMedia("(any-pointer: coarse)").matches,
|
||||
"any-pointer: coarse should be matched");
|
||||
ok(content.document.defaultView.matchMedia("(any-hover: none)").matches,
|
||||
"any-hover: none should be matched");
|
||||
ok(
|
||||
content.document.defaultView.matchMedia("(pointer: coarse)").matches,
|
||||
"pointer: coarse should be matched"
|
||||
);
|
||||
ok(
|
||||
content.document.defaultView.matchMedia("(hover: none)").matches,
|
||||
"hover: none should be matched"
|
||||
);
|
||||
ok(
|
||||
content.document.defaultView.matchMedia("(any-pointer: coarse)").matches,
|
||||
"any-pointer: coarse should be matched"
|
||||
);
|
||||
ok(
|
||||
content.document.defaultView.matchMedia("(any-hover: none)").matches,
|
||||
"any-hover: none should be matched"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function testWithMetaViewportEnabled(ui) {
|
||||
await SpecialPowers.pushPrefEnv({set: [[PREF_DOM_META_VIEWPORT_ENABLED, true]]});
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PREF_DOM_META_VIEWPORT_ENABLED, true]],
|
||||
});
|
||||
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
const { synthesizeClick } = EventUtils;
|
||||
|
@ -130,41 +217,63 @@ async function testWithMetaViewportEnabled(ui) {
|
|||
const div = content.document.querySelector("div");
|
||||
div.dataset.isDelay = "false";
|
||||
|
||||
info("testWithMetaViewportEnabled: " +
|
||||
"click the div element with <meta name='viewport'>");
|
||||
info(
|
||||
"testWithMetaViewportEnabled: " +
|
||||
"click the div element with <meta name='viewport'>"
|
||||
);
|
||||
meta.content = "";
|
||||
await synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "true",
|
||||
"300ms delay between touch events and mouse events should work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"true",
|
||||
"300ms delay between touch events and mouse events should work"
|
||||
);
|
||||
|
||||
info("testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='user-scalable=no'>");
|
||||
info(
|
||||
"testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='user-scalable=no'>"
|
||||
);
|
||||
meta.content = "user-scalable=no";
|
||||
await synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "false",
|
||||
"300ms delay between touch events and mouse events should not work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"false",
|
||||
"300ms delay between touch events and mouse events should not work"
|
||||
);
|
||||
|
||||
info("testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='minimum-scale=1,maximum-scale=1'>");
|
||||
info(
|
||||
"testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='minimum-scale=1,maximum-scale=1'>"
|
||||
);
|
||||
meta.content = "minimum-scale=1,maximum-scale=1";
|
||||
await synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "false",
|
||||
"300ms delay between touch events and mouse events should not work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"false",
|
||||
"300ms delay between touch events and mouse events should not work"
|
||||
);
|
||||
|
||||
info("testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='width=device-width'>");
|
||||
info(
|
||||
"testWithMetaViewportEnabled: " +
|
||||
"click the div element with " +
|
||||
"<meta name='viewport' content='width=device-width'>"
|
||||
);
|
||||
meta.content = "width=device-width";
|
||||
await synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "false",
|
||||
"300ms delay between touch events and mouse events should not work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"false",
|
||||
"300ms delay between touch events and mouse events should not work"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async function testWithMetaViewportDisabled(ui) {
|
||||
await SpecialPowers.pushPrefEnv({set: [[PREF_DOM_META_VIEWPORT_ENABLED, false]]});
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PREF_DOM_META_VIEWPORT_ENABLED, false]],
|
||||
});
|
||||
|
||||
await ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
const { synthesizeClick } = EventUtils;
|
||||
|
@ -173,11 +282,16 @@ async function testWithMetaViewportDisabled(ui) {
|
|||
const div = content.document.querySelector("div");
|
||||
div.dataset.isDelay = "false";
|
||||
|
||||
info("testWithMetaViewportDisabled: click the div with <meta name='viewport'>");
|
||||
info(
|
||||
"testWithMetaViewportDisabled: click the div with <meta name='viewport'>"
|
||||
);
|
||||
meta.content = "";
|
||||
await synthesizeClick(div);
|
||||
is(div.dataset.isDelay, "true",
|
||||
"300ms delay between touch events and mouse events should work");
|
||||
is(
|
||||
div.dataset.isDelay,
|
||||
"true",
|
||||
"300ms delay between touch events and mouse events should work"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,18 +299,24 @@ function testTouchButton(ui) {
|
|||
const { document } = ui.toolWindow;
|
||||
const touchButton = document.getElementById("touch-simulation-button");
|
||||
|
||||
ok(touchButton.classList.contains("checked"),
|
||||
"Touch simulation is active at end of test.");
|
||||
ok(
|
||||
touchButton.classList.contains("checked"),
|
||||
"Touch simulation is active at end of test."
|
||||
);
|
||||
|
||||
touchButton.click();
|
||||
|
||||
ok(!touchButton.classList.contains("checked"),
|
||||
"Touch simulation is stopped on click.");
|
||||
ok(
|
||||
!touchButton.classList.contains("checked"),
|
||||
"Touch simulation is stopped on click."
|
||||
);
|
||||
|
||||
touchButton.click();
|
||||
|
||||
ok(touchButton.classList.contains("checked"),
|
||||
"Touch simulation is started on click.");
|
||||
ok(
|
||||
touchButton.classList.contains("checked"),
|
||||
"Touch simulation is started on click."
|
||||
);
|
||||
}
|
||||
|
||||
async function waitBootstrap(ui) {
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
* characters.
|
||||
*/
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<body id=\"body\"><input id=\"input\" type=\"text\"/><p>text</body>";
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
'<body id="body"><input id="input" type="text"/><p>text</body>';
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Turn on the pref that allows meta viewport support.
|
||||
|
@ -62,9 +63,16 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
|
||||
const findBar = await gBrowser.getFindBar();
|
||||
|
||||
const findIsTriggered = (findBar._findField.value == "t");
|
||||
is(findIsTriggered, e.findTriggered, "Text input with focused element " + e.id +
|
||||
" should " + (e.findTriggered ? "" : "not ") + "trigger find.");
|
||||
const findIsTriggered = findBar._findField.value == "t";
|
||||
is(
|
||||
findIsTriggered,
|
||||
e.findTriggered,
|
||||
"Text input with focused element " +
|
||||
e.id +
|
||||
" should " +
|
||||
(e.findTriggered ? "" : "not ") +
|
||||
"trigger find."
|
||||
);
|
||||
findBar._findField.value = "";
|
||||
|
||||
await ContentTask.spawn(browser, {}, async function() {
|
||||
|
|
|
@ -16,10 +16,16 @@ addRDMTask(TEST_URL, async function({ ui }) {
|
|||
// A single viewport of default size appeared
|
||||
const viewport = ui.toolWindow.document.querySelector(".viewport-content");
|
||||
|
||||
is(ui.toolWindow.getComputedStyle(viewport).getPropertyValue("width"),
|
||||
"320px", "Viewport has default width");
|
||||
is(ui.toolWindow.getComputedStyle(viewport).getPropertyValue("height"),
|
||||
"480px", "Viewport has default height");
|
||||
is(
|
||||
ui.toolWindow.getComputedStyle(viewport).getPropertyValue("width"),
|
||||
"320px",
|
||||
"Viewport has default width"
|
||||
);
|
||||
is(
|
||||
ui.toolWindow.getComputedStyle(viewport).getPropertyValue("height"),
|
||||
"480px",
|
||||
"Viewport has default height"
|
||||
);
|
||||
|
||||
// Browser's location should match original tab
|
||||
await waitForFrameLoad(ui, TEST_URL);
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
|
||||
// Test viewport resizing, with and without meta viewport support.
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<head><meta name=\"viewport\" content=\"width=300\"/></head>" +
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
'<head><meta name="viewport" content="width=300"/></head>' +
|
||||
"<body>meta viewport width 300</body>";
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Turn on the pref that allows meta viewport support.
|
||||
|
@ -52,18 +53,30 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
await setViewportSize(ui, manager, 600, 300);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " before resize",
|
||||
ui, b[0], b[1], b[2]);
|
||||
ui,
|
||||
b[0],
|
||||
b[1],
|
||||
b[2]
|
||||
);
|
||||
|
||||
// Move to the smaller size.
|
||||
await setViewportSize(ui, manager, 50, 50);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " after resize",
|
||||
ui, a[0], a[1], a[2]);
|
||||
ui,
|
||||
a[0],
|
||||
a[1],
|
||||
a[2]
|
||||
);
|
||||
|
||||
// Go back to the initial size and check again.
|
||||
await setViewportSize(ui, manager, 600, 300);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " return to initial size",
|
||||
ui, b[0], b[1], b[2]);
|
||||
ui,
|
||||
b[0],
|
||||
b[1],
|
||||
b[2]
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
|
||||
// Test viewport resizing, with and without meta viewport support.
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<head><meta name=\"viewport\" content=\"width=device-width, " +
|
||||
"initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0\"></head>" +
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
'<head><meta name="viewport" content="width=device-width, ' +
|
||||
'initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"></head>' +
|
||||
"<body>meta viewport scaled locked at 1.0</body>";
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Turn on the pref that allows meta viewport support.
|
||||
|
@ -69,18 +70,30 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
await setViewportSize(ui, manager, 300, 600);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " before resize",
|
||||
ui, b.zoom, b.width, b.height);
|
||||
ui,
|
||||
b.zoom,
|
||||
b.width,
|
||||
b.height
|
||||
);
|
||||
|
||||
// Move to the smaller size.
|
||||
await setViewportSize(ui, manager, 600, 300);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " after resize",
|
||||
ui, a.zoom, a.width, a.height);
|
||||
ui,
|
||||
a.zoom,
|
||||
a.width,
|
||||
a.height
|
||||
);
|
||||
|
||||
// Go back to the initial size and check again.
|
||||
await setViewportSize(ui, manager, 300, 600);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " return to initial size",
|
||||
ui, b.zoom, b.width, b.height);
|
||||
ui,
|
||||
b.zoom,
|
||||
b.width,
|
||||
b.height
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -5,10 +5,11 @@
|
|||
|
||||
// Test viewport resizing, with and without meta viewport support.
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<head><meta name=\"viewport\" content=\"initial-scale=1.0, " +
|
||||
"minimum-scale=1.0, width=device-width\"></head>" +
|
||||
"<div style=\"width:100%;background-color:green\">test</div>" +
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
'<head><meta name="viewport" content="initial-scale=1.0, ' +
|
||||
'minimum-scale=1.0, width=device-width"></head>' +
|
||||
'<div style="width:100%;background-color:green">test</div>' +
|
||||
"</body>";
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Turn on the pref that allows meta viewport support.
|
||||
|
@ -56,18 +57,30 @@ addRDMTask(TEST_URL, async function({ ui, manager }) {
|
|||
await setViewportSizeAndAwaitReflow(ui, manager, 300, 600);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " before resize",
|
||||
ui, b.zoom, b.width, b.height);
|
||||
ui,
|
||||
b.zoom,
|
||||
b.width,
|
||||
b.height
|
||||
);
|
||||
|
||||
// Move to the smaller size.
|
||||
await setViewportSizeAndAwaitReflow(ui, manager, 600, 300);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " after resize",
|
||||
ui, a.zoom, a.width, a.height);
|
||||
ui,
|
||||
a.zoom,
|
||||
a.width,
|
||||
a.height
|
||||
);
|
||||
|
||||
// Go back to the initial size and check again.
|
||||
await setViewportSizeAndAwaitReflow(ui, manager, 300, 600);
|
||||
await testViewportZoomWidthAndHeight(
|
||||
message + " return to initial size",
|
||||
ui, b.zoom, b.width, b.height);
|
||||
ui,
|
||||
b.zoom,
|
||||
b.width,
|
||||
b.height
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
// meta viewport support.
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js", this);
|
||||
"chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js",
|
||||
this
|
||||
);
|
||||
|
||||
// The quest for a TEST_ROOT: we have to choose a way of addressing the RDM document
|
||||
// such that two things can happen:
|
||||
|
@ -39,20 +41,23 @@ Services.scriptloader.loadSubScript(
|
|||
// Instead we're going to mess with a security preference to allow a data URI to be
|
||||
// treated as same-origin. This doesn't work either for reasons that I don't understand.
|
||||
|
||||
const TEST_URL = "data:text/html;charset=utf-8," +
|
||||
"<head>" +
|
||||
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>" +
|
||||
"</head>" +
|
||||
"<body><div style=\"background:orange; width:1000px; height:1000px\"></div></body>";
|
||||
const TEST_URL =
|
||||
"data:text/html;charset=utf-8," +
|
||||
"<head>" +
|
||||
'<meta name="viewport" content="width=device-width, initial-scale=1"/>' +
|
||||
"</head>" +
|
||||
'<body><div style="background:orange; width:1000px; height:1000px"></div></body>';
|
||||
|
||||
addRDMTask(TEST_URL, async function({ ui, manager }) {
|
||||
// Turn on the prefs that allow meta viewport support, and force overlay
|
||||
// scrollbars to always be visible, and to allow data URIs to be considered
|
||||
// as same-origin.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [["devtools.responsive.metaViewport.enabled", true],
|
||||
["layout.testing.overlay-scrollbars.always-visible", true],
|
||||
["security.data_uri.unique_opaque_origin", false]],
|
||||
set: [
|
||||
["devtools.responsive.metaViewport.enabled", true],
|
||||
["layout.testing.overlay-scrollbars.always-visible", true],
|
||||
["security.data_uri.unique_opaque_origin", false],
|
||||
],
|
||||
});
|
||||
|
||||
const store = ui.toolWindow.store;
|
||||
|
|
|
@ -17,8 +17,10 @@ add_task(async function() {
|
|||
// Close the window on a tab with an active responsive design UI and
|
||||
// wait for the UI to gracefully shutdown. This has leaked the window
|
||||
// in the past.
|
||||
ok(ResponsiveUIManager.isActiveForTab(tab),
|
||||
"ResponsiveUI should be active for tab when the window is closed");
|
||||
ok(
|
||||
ResponsiveUIManager.isActiveForTab(tab),
|
||||
"ResponsiveUI should be active for tab when the window is closed"
|
||||
);
|
||||
const offPromise = once(ResponsiveUIManager, "off");
|
||||
await BrowserTestUtils.closeWindow(newWindow);
|
||||
await offPromise;
|
||||
|
|
|
@ -30,36 +30,56 @@ add_task(async function() {
|
|||
});
|
||||
|
||||
async function checkWindowOuterSize(ui) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(),
|
||||
return ContentTask.spawn(
|
||||
ui.getViewportBrowser(),
|
||||
{ width: WIDTH, height: HEIGHT },
|
||||
async function({ width, height }) {
|
||||
// Approximate the outer size value returned on the window content with the expected
|
||||
// value. We should expect, at the very most, a 1px difference between the two due
|
||||
// to floating point rounding errors that occur when scaling from inner size CSS
|
||||
// integer values to outer size CSS integer values. See Part 1 of Bug 1107456.
|
||||
ok(Math.abs(content.outerWidth - width) <= 1,
|
||||
`window.outerWidth should be ${width} and we got ${content.outerWidth}.`);
|
||||
ok(Math.abs(content.outerHeight - height) <= 1,
|
||||
`window.outerHeight should be ${height} and we got ${content.outerHeight}.`);
|
||||
});
|
||||
ok(
|
||||
Math.abs(content.outerWidth - width) <= 1,
|
||||
`window.outerWidth should be ${width} and we got ${content.outerWidth}.`
|
||||
);
|
||||
ok(
|
||||
Math.abs(content.outerHeight - height) <= 1,
|
||||
`window.outerHeight should be ${height} and we got ${
|
||||
content.outerHeight
|
||||
}.`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function checkWindowScreenSize(ui) {
|
||||
return ContentTask.spawn(ui.getViewportBrowser(),
|
||||
return ContentTask.spawn(
|
||||
ui.getViewportBrowser(),
|
||||
{ width: WIDTH, height: HEIGHT },
|
||||
async function({ width, height }) {
|
||||
const { screen } = content;
|
||||
|
||||
ok(Math.abs(screen.availWidth - width) <= 1,
|
||||
`screen.availWidth should be ${width} and we got ${screen.availWidth}.`);
|
||||
ok(
|
||||
Math.abs(screen.availWidth - width) <= 1,
|
||||
`screen.availWidth should be ${width} and we got ${screen.availWidth}.`
|
||||
);
|
||||
|
||||
ok(Math.abs(screen.availHeight - height) <= 1,
|
||||
`screen.availHeight should be ${height} and we got ${screen.availHeight}.`);
|
||||
ok(
|
||||
Math.abs(screen.availHeight - height) <= 1,
|
||||
`screen.availHeight should be ${height} and we got ${
|
||||
screen.availHeight
|
||||
}.`
|
||||
);
|
||||
|
||||
ok(Math.abs(screen.width - width) <= 1,
|
||||
`screen.width should be ${width} and we got ${screen.width}.`);
|
||||
ok(
|
||||
Math.abs(screen.width - width) <= 1,
|
||||
`screen.width should be ${width} and we got ${screen.width}.`
|
||||
);
|
||||
|
||||
ok(Math.abs(screen.height - height) <= 1,
|
||||
`screen.height should be ${height} and we got ${screen.height}.`);
|
||||
});
|
||||
ok(
|
||||
Math.abs(screen.height - height) <= 1,
|
||||
`screen.height should be ${height} and we got ${screen.height}.`
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,36 +10,55 @@
|
|||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
|
||||
this);
|
||||
this
|
||||
);
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-redux-head.js",
|
||||
this);
|
||||
this
|
||||
);
|
||||
|
||||
// Import helpers registering the test-actor in remote targets
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/test-actor-registry.js",
|
||||
this);
|
||||
this
|
||||
);
|
||||
|
||||
// Import helpers for the inspector that are also shared with others
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/shared-head.js",
|
||||
this);
|
||||
this
|
||||
);
|
||||
|
||||
const { _loadPreferredDevices } = require("devtools/client/responsive/actions/devices");
|
||||
const {
|
||||
_loadPreferredDevices,
|
||||
} = require("devtools/client/responsive/actions/devices");
|
||||
const { getStr } = require("devtools/client/responsive/utils/l10n");
|
||||
const { getTopLevelWindow } = require("devtools/client/responsive/utils/window");
|
||||
const { addDevice, removeDevice, removeLocalDevices } = require("devtools/client/shared/devices");
|
||||
const {
|
||||
getTopLevelWindow,
|
||||
} = require("devtools/client/responsive/utils/window");
|
||||
const {
|
||||
addDevice,
|
||||
removeDevice,
|
||||
removeLocalDevices,
|
||||
} = require("devtools/client/shared/devices");
|
||||
const { KeyCodes } = require("devtools/client/shared/keycodes");
|
||||
const asyncStorage = require("devtools/shared/async-storage");
|
||||
|
||||
loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive/manager", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"ResponsiveUIManager",
|
||||
"devtools/client/responsive/manager",
|
||||
true
|
||||
);
|
||||
|
||||
const E10S_MULTI_ENABLED = Services.prefs.getIntPref("dom.ipc.processCount") > 1;
|
||||
const TEST_URI_ROOT = "http://example.com/browser/devtools/client/responsive/test/browser/";
|
||||
const E10S_MULTI_ENABLED =
|
||||
Services.prefs.getIntPref("dom.ipc.processCount") > 1;
|
||||
const TEST_URI_ROOT =
|
||||
"http://example.com/browser/devtools/client/responsive/test/browser/";
|
||||
const RELOAD_CONDITION_PREF_PREFIX = "devtools.responsive.reloadConditions.";
|
||||
const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Ci.nsIHttpProtocolHandler)
|
||||
.userAgent;
|
||||
const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"].getService(
|
||||
Ci.nsIHttpProtocolHandler
|
||||
).userAgent;
|
||||
|
||||
SimpleTest.requestCompleteLog();
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -49,20 +68,32 @@ SimpleTest.waitForExplicitFinish();
|
|||
// should be enough.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
Services.prefs.setCharPref("devtools.devices.url", TEST_URI_ROOT + "devices.json");
|
||||
Services.prefs.setCharPref(
|
||||
"devtools.devices.url",
|
||||
TEST_URI_ROOT + "devices.json"
|
||||
);
|
||||
// The appearance of this notification causes intermittent behavior in some tests that
|
||||
// send mouse events, since it causes the content to shift when it appears.
|
||||
Services.prefs.setBoolPref("devtools.responsive.reloadNotification.enabled", false);
|
||||
Services.prefs.setBoolPref(
|
||||
"devtools.responsive.reloadNotification.enabled",
|
||||
false
|
||||
);
|
||||
// Don't show the setting onboarding tooltip in the test suites.
|
||||
Services.prefs.setBoolPref("devtools.responsive.show-setting-tooltip", false);
|
||||
Services.prefs.setBoolPref("devtools.responsive.showUserAgentInput", true);
|
||||
|
||||
registerCleanupFunction(async () => {
|
||||
Services.prefs.clearUserPref("devtools.devices.url");
|
||||
Services.prefs.clearUserPref("devtools.responsive.reloadNotification.enabled");
|
||||
Services.prefs.clearUserPref(
|
||||
"devtools.responsive.reloadNotification.enabled"
|
||||
);
|
||||
Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
|
||||
Services.prefs.clearUserPref("devtools.responsive.reloadConditions.touchSimulation");
|
||||
Services.prefs.clearUserPref("devtools.responsive.reloadConditions.userAgent");
|
||||
Services.prefs.clearUserPref(
|
||||
"devtools.responsive.reloadConditions.touchSimulation"
|
||||
);
|
||||
Services.prefs.clearUserPref(
|
||||
"devtools.responsive.reloadConditions.userAgent"
|
||||
);
|
||||
Services.prefs.clearUserPref("devtools.responsive.show-setting-tooltip");
|
||||
Services.prefs.clearUserPref("devtools.responsive.showUserAgentInput");
|
||||
Services.prefs.clearUserPref("devtools.responsive.touchSimulation.enabled");
|
||||
|
@ -81,7 +112,9 @@ registerCleanupFunction(async () => {
|
|||
var openRDM = async function(tab) {
|
||||
info("Opening responsive design mode");
|
||||
const manager = ResponsiveUIManager;
|
||||
const ui = await manager.openIfNeeded(tab.ownerGlobal, tab, { trigger: "test" });
|
||||
const ui = await manager.openIfNeeded(tab.ownerGlobal, tab, {
|
||||
trigger: "test",
|
||||
});
|
||||
info("Responsive design mode opened");
|
||||
return { ui, manager };
|
||||
};
|
||||
|
@ -129,9 +162,11 @@ function spawnViewportTask(ui, args, task) {
|
|||
|
||||
function waitForFrameLoad(ui, targetURL) {
|
||||
return spawnViewportTask(ui, { targetURL }, async function(args) {
|
||||
if ((content.document.readyState == "complete" ||
|
||||
content.document.readyState == "interactive") &&
|
||||
content.location.href == args.targetURL) {
|
||||
if (
|
||||
(content.document.readyState == "complete" ||
|
||||
content.document.readyState == "interactive") &&
|
||||
content.location.href == args.targetURL
|
||||
) {
|
||||
return;
|
||||
}
|
||||
await ContentTaskUtils.waitForEvent(this, "DOMContentLoaded");
|
||||
|
@ -177,15 +212,18 @@ function waitForViewportResizeTo(ui, width, height) {
|
|||
// size. We wait on the viewport resize event, and check for the
|
||||
// desired size.
|
||||
ui.on("viewport-resize", onResizeViewport);
|
||||
browser.addEventListener("mozbrowserloadend",
|
||||
onBrowserLoadEnd, { once: true });
|
||||
browser.addEventListener("mozbrowserloadend", onBrowserLoadEnd, {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var setViewportSize = async function(ui, manager, width, height) {
|
||||
const size = ui.getViewportSize();
|
||||
info(`Current size: ${size.width} x ${size.height}, ` +
|
||||
`set to: ${width} x ${height}`);
|
||||
info(
|
||||
`Current size: ${size.width} x ${size.height}, ` +
|
||||
`set to: ${width} x ${height}`
|
||||
);
|
||||
if (size.width != width || size.height != height) {
|
||||
const resized = waitForViewportResizeTo(ui, width, height);
|
||||
ui.setViewportSize({ width, height });
|
||||
|
@ -197,11 +235,15 @@ var setViewportSize = async function(ui, manager, width, height) {
|
|||
// ensures that reflow of the viewport has completed.
|
||||
var setViewportSizeAndAwaitReflow = async function(ui, manager, width, height) {
|
||||
await setViewportSize(ui, manager, width, height);
|
||||
const reflowed = ContentTask.spawn(ui.getViewportBrowser(), {}, async function() {
|
||||
return new Promise(resolve => {
|
||||
content.requestAnimationFrame(resolve);
|
||||
});
|
||||
});
|
||||
const reflowed = ContentTask.spawn(
|
||||
ui.getViewportBrowser(),
|
||||
{},
|
||||
async function() {
|
||||
return new Promise(resolve => {
|
||||
content.requestAnimationFrame(resolve);
|
||||
});
|
||||
}
|
||||
);
|
||||
await reflowed;
|
||||
};
|
||||
|
||||
|
@ -221,13 +263,15 @@ function getElRect(selector, win) {
|
|||
* the rect of the dragged element as it was before drag.
|
||||
*/
|
||||
function dragElementBy(selector, x, y, win) {
|
||||
const { Simulate } = win.require("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const { Simulate } = win.require(
|
||||
"devtools/client/shared/vendor/react-dom-test-utils"
|
||||
);
|
||||
const rect = getElRect(selector, win);
|
||||
const startPoint = {
|
||||
clientX: Math.floor(rect.left + rect.width / 2),
|
||||
clientY: Math.floor(rect.top + rect.height / 2),
|
||||
};
|
||||
const endPoint = [ startPoint.clientX + x, startPoint.clientY + y ];
|
||||
const endPoint = [startPoint.clientX + x, startPoint.clientY + y];
|
||||
|
||||
const elem = win.document.querySelector(selector);
|
||||
|
||||
|
@ -241,18 +285,29 @@ function dragElementBy(selector, x, y, win) {
|
|||
return rect;
|
||||
}
|
||||
|
||||
async function testViewportResize(ui, selector, moveBy,
|
||||
expectedViewportSize, expectedHandleMove) {
|
||||
async function testViewportResize(
|
||||
ui,
|
||||
selector,
|
||||
moveBy,
|
||||
expectedViewportSize,
|
||||
expectedHandleMove
|
||||
) {
|
||||
const win = ui.toolWindow;
|
||||
const resized = waitForViewportResizeTo(ui, ...expectedViewportSize);
|
||||
const startRect = dragElementBy(selector, ...moveBy, win);
|
||||
await resized;
|
||||
|
||||
const endRect = getElRect(selector, win);
|
||||
is(endRect.left - startRect.left, expectedHandleMove[0],
|
||||
`The x move of ${selector} is as expected`);
|
||||
is(endRect.top - startRect.top, expectedHandleMove[1],
|
||||
`The y move of ${selector} is as expected`);
|
||||
is(
|
||||
endRect.left - startRect.left,
|
||||
expectedHandleMove[0],
|
||||
`The x move of ${selector} is as expected`
|
||||
);
|
||||
is(
|
||||
endRect.top - startRect.top,
|
||||
expectedHandleMove[1],
|
||||
`The y move of ${selector} is as expected`
|
||||
);
|
||||
}
|
||||
|
||||
async function openDeviceModal(ui) {
|
||||
|
@ -260,25 +315,39 @@ async function openDeviceModal(ui) {
|
|||
|
||||
info("Opening device modal through device selector.");
|
||||
const onModalOpen = waitUntilState(store, state => state.devices.isModalOpen);
|
||||
await selectMenuItem(ui, "#device-selector", getStr("responsive.editDeviceList2"));
|
||||
await selectMenuItem(
|
||||
ui,
|
||||
"#device-selector",
|
||||
getStr("responsive.editDeviceList2")
|
||||
);
|
||||
await onModalOpen;
|
||||
|
||||
const modal = document.getElementById("device-modal-wrapper");
|
||||
ok(modal.classList.contains("opened") && !modal.classList.contains("closed"),
|
||||
"The device modal is displayed.");
|
||||
ok(
|
||||
modal.classList.contains("opened") && !modal.classList.contains("closed"),
|
||||
"The device modal is displayed."
|
||||
);
|
||||
}
|
||||
|
||||
async function selectMenuItem({ toolWindow }, selector, value) {
|
||||
const { document } = toolWindow;
|
||||
|
||||
const button = document.querySelector(selector);
|
||||
isnot(button, null, `Selector "${selector}" should match an existing element.`);
|
||||
isnot(
|
||||
button,
|
||||
null,
|
||||
`Selector "${selector}" should match an existing element.`
|
||||
);
|
||||
|
||||
info(`Selecting ${value} in ${selector}.`);
|
||||
|
||||
await testMenuItems(toolWindow, button, items => {
|
||||
const menuItem = items.find(item => item.getAttribute("label") === value);
|
||||
isnot(menuItem, undefined, `Value "${value}" should match an existing menu item.`);
|
||||
isnot(
|
||||
menuItem,
|
||||
undefined,
|
||||
`Value "${value}" should match an existing menu item.`
|
||||
);
|
||||
menuItem.click();
|
||||
});
|
||||
}
|
||||
|
@ -300,38 +369,45 @@ function testMenuItems(toolWindow, button, testFn) {
|
|||
const win = getTopLevelWindow(toolWindow);
|
||||
|
||||
return new Promise(resolve => {
|
||||
win.document.addEventListener("popupshown", () => {
|
||||
const popup = win.document.querySelector("menupopup[menu-api=\"true\"]");
|
||||
const menuItems = [...popup.children];
|
||||
win.document.addEventListener(
|
||||
"popupshown",
|
||||
() => {
|
||||
const popup = win.document.querySelector('menupopup[menu-api="true"]');
|
||||
const menuItems = [...popup.children];
|
||||
|
||||
testFn(menuItems);
|
||||
testFn(menuItems);
|
||||
|
||||
popup.hidePopup();
|
||||
resolve();
|
||||
}, { once: true });
|
||||
popup.hidePopup();
|
||||
resolve();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
button.click();
|
||||
});
|
||||
}
|
||||
|
||||
const selectDevice = (ui, value) => Promise.all([
|
||||
once(ui, "device-changed"),
|
||||
selectMenuItem(ui, "#device-selector", value),
|
||||
]);
|
||||
const selectDevice = (ui, value) =>
|
||||
Promise.all([
|
||||
once(ui, "device-changed"),
|
||||
selectMenuItem(ui, "#device-selector", value),
|
||||
]);
|
||||
|
||||
const selectDevicePixelRatio = (ui, value) =>
|
||||
selectMenuItem(ui, "#device-pixel-ratio-menu", `DPR: ${value}`);
|
||||
|
||||
const selectNetworkThrottling = (ui, value) => Promise.all([
|
||||
once(ui, "network-throttling-changed"),
|
||||
selectMenuItem(ui, "#network-throttling-menu", value),
|
||||
]);
|
||||
const selectNetworkThrottling = (ui, value) =>
|
||||
Promise.all([
|
||||
once(ui, "network-throttling-changed"),
|
||||
selectMenuItem(ui, "#network-throttling-menu", value),
|
||||
]);
|
||||
|
||||
function getSessionHistory(browser) {
|
||||
return ContentTask.spawn(browser, {}, async function() {
|
||||
/* eslint-disable no-undef */
|
||||
const { SessionHistory } =
|
||||
ChromeUtils.import("resource://gre/modules/sessionstore/SessionHistory.jsm");
|
||||
const { SessionHistory } = ChromeUtils.import(
|
||||
"resource://gre/modules/sessionstore/SessionHistory.jsm"
|
||||
);
|
||||
return SessionHistory.collect(docShell);
|
||||
/* eslint-enable no-undef */
|
||||
});
|
||||
|
@ -357,7 +433,9 @@ async function waitForPageShow(browser) {
|
|||
if (ui) {
|
||||
browser = ui.getViewportBrowser();
|
||||
}
|
||||
info("Waiting for pageshow from " + (ui ? "responsive" : "regular") + " browser");
|
||||
info(
|
||||
"Waiting for pageshow from " + (ui ? "responsive" : "regular") + " browser"
|
||||
);
|
||||
// Need to wait an extra tick after pageshow to ensure everyone is up-to-date,
|
||||
// hence the waitForTick.
|
||||
await BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
|
@ -365,11 +443,19 @@ async function waitForPageShow(browser) {
|
|||
}
|
||||
|
||||
function waitForViewportLoad(ui) {
|
||||
return BrowserTestUtils.waitForContentEvent(ui.getViewportBrowser(), "load", true);
|
||||
return BrowserTestUtils.waitForContentEvent(
|
||||
ui.getViewportBrowser(),
|
||||
"load",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
function waitForViewportScroll(ui) {
|
||||
return BrowserTestUtils.waitForContentEvent(ui.getViewportBrowser(), "scroll", true);
|
||||
return BrowserTestUtils.waitForContentEvent(
|
||||
ui.getViewportBrowser(),
|
||||
"scroll",
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
function load(browser, url) {
|
||||
|
@ -396,7 +482,10 @@ function addDeviceForTest(device) {
|
|||
|
||||
registerCleanupFunction(() => {
|
||||
// Note that assertions in cleanup functions are not displayed unless they failed.
|
||||
ok(removeDevice(device), `Removed Test Device "${device.name}" from the list.`);
|
||||
ok(
|
||||
removeDevice(device),
|
||||
`Removed Test Device "${device.name}" from the list.`
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -416,10 +505,16 @@ async function testTouchEventsOverride(ui, expected) {
|
|||
const touchButton = document.getElementById("touch-simulation-button");
|
||||
|
||||
const flag = await ui.emulationFront.getTouchEventsOverride();
|
||||
is(flag === Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED, expected,
|
||||
`Touch events override should be ${expected ? "enabled" : "disabled"}`);
|
||||
is(touchButton.classList.contains("checked"), expected,
|
||||
`Touch simulation button should be ${expected ? "" : "in"}active.`);
|
||||
is(
|
||||
flag === Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED,
|
||||
expected,
|
||||
`Touch events override should be ${expected ? "enabled" : "disabled"}`
|
||||
);
|
||||
is(
|
||||
touchButton.classList.contains("checked"),
|
||||
expected,
|
||||
`Touch simulation button should be ${expected ? "" : "in"}active.`
|
||||
);
|
||||
}
|
||||
|
||||
function testViewportDeviceMenuLabel(ui, expected) {
|
||||
|
@ -435,7 +530,7 @@ async function toggleTouchSimulation(ui) {
|
|||
const changed = once(ui, "touch-simulation-changed");
|
||||
const loaded = waitForViewportLoad(ui);
|
||||
touchButton.click();
|
||||
await Promise.all([ changed, loaded ]);
|
||||
await Promise.all([changed, loaded]);
|
||||
}
|
||||
|
||||
async function testUserAgent(ui, expected) {
|
||||
|
@ -461,26 +556,36 @@ async function testUserAgentFromBrowser(browser, expected) {
|
|||
function testViewportDimensions(ui, w, h) {
|
||||
const viewport = ui.toolWindow.document.querySelector(".viewport-content");
|
||||
|
||||
is(ui.toolWindow.getComputedStyle(viewport).getPropertyValue("width"),
|
||||
`${w}px`, `Viewport should have width of ${w}px`);
|
||||
is(ui.toolWindow.getComputedStyle(viewport).getPropertyValue("height"),
|
||||
`${h}px`, `Viewport should have height of ${h}px`);
|
||||
is(
|
||||
ui.toolWindow.getComputedStyle(viewport).getPropertyValue("width"),
|
||||
`${w}px`,
|
||||
`Viewport should have width of ${w}px`
|
||||
);
|
||||
is(
|
||||
ui.toolWindow.getComputedStyle(viewport).getPropertyValue("height"),
|
||||
`${h}px`,
|
||||
`Viewport should have height of ${h}px`
|
||||
);
|
||||
}
|
||||
|
||||
async function changeUserAgentInput(ui, value) {
|
||||
const { Simulate } =
|
||||
ui.toolWindow.require("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const { Simulate } = ui.toolWindow.require(
|
||||
"devtools/client/shared/vendor/react-dom-test-utils"
|
||||
);
|
||||
const { document, store } = ui.toolWindow;
|
||||
|
||||
const userAgentInput = document.getElementById("user-agent-input");
|
||||
userAgentInput.value = value;
|
||||
Simulate.change(userAgentInput);
|
||||
|
||||
const userAgentChanged = waitUntilState(store, state => state.ui.userAgent === value);
|
||||
const userAgentChanged = waitUntilState(
|
||||
store,
|
||||
state => state.ui.userAgent === value
|
||||
);
|
||||
const changed = once(ui, "user-agent-changed");
|
||||
const loaded = waitForViewportLoad(ui);
|
||||
Simulate.keyUp(userAgentInput, { keyCode: KeyCodes.DOM_VK_RETURN });
|
||||
await Promise.all([ changed, loaded, userAgentChanged ]);
|
||||
await Promise.all([changed, loaded, userAgentChanged]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -488,15 +593,21 @@ async function changeUserAgentInput(ui, value) {
|
|||
* function adds `device` via the form, saves it, and waits for it to appear in the store.
|
||||
*/
|
||||
function addDeviceInModal(ui, device) {
|
||||
const { Simulate } =
|
||||
ui.toolWindow.require("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const { Simulate } = ui.toolWindow.require(
|
||||
"devtools/client/shared/vendor/react-dom-test-utils"
|
||||
);
|
||||
const { document, store } = ui.toolWindow;
|
||||
|
||||
const nameInput = document.querySelector("#device-form-name input");
|
||||
const [ widthInput, heightInput ] =
|
||||
document.querySelectorAll("#device-form-size input");
|
||||
const pixelRatioInput = document.querySelector("#device-form-pixel-ratio input");
|
||||
const userAgentInput = document.querySelector("#device-form-user-agent input");
|
||||
const [widthInput, heightInput] = document.querySelectorAll(
|
||||
"#device-form-size input"
|
||||
);
|
||||
const pixelRatioInput = document.querySelector(
|
||||
"#device-form-pixel-ratio input"
|
||||
);
|
||||
const userAgentInput = document.querySelector(
|
||||
"#device-form-user-agent input"
|
||||
);
|
||||
const touchInput = document.querySelector("#device-form-touch input");
|
||||
|
||||
nameInput.value = device.name;
|
||||
|
@ -516,23 +627,30 @@ function addDeviceInModal(ui, device) {
|
|||
|
||||
const existingCustomDevices = store.getState().devices.custom.length;
|
||||
const adderSave = document.querySelector("#device-form-save");
|
||||
const saved = waitUntilState(store, state =>
|
||||
state.devices.custom.length == existingCustomDevices + 1
|
||||
const saved = waitUntilState(
|
||||
store,
|
||||
state => state.devices.custom.length == existingCustomDevices + 1
|
||||
);
|
||||
Simulate.click(adderSave);
|
||||
return saved;
|
||||
}
|
||||
|
||||
function editDeviceInModal(ui, device, newDevice) {
|
||||
const { Simulate } =
|
||||
ui.toolWindow.require("devtools/client/shared/vendor/react-dom-test-utils");
|
||||
const { Simulate } = ui.toolWindow.require(
|
||||
"devtools/client/shared/vendor/react-dom-test-utils"
|
||||
);
|
||||
const { document, store } = ui.toolWindow;
|
||||
|
||||
const nameInput = document.querySelector("#device-form-name input");
|
||||
const [ widthInput, heightInput ] =
|
||||
document.querySelectorAll("#device-form-size input");
|
||||
const pixelRatioInput = document.querySelector("#device-form-pixel-ratio input");
|
||||
const userAgentInput = document.querySelector("#device-form-user-agent input");
|
||||
const [widthInput, heightInput] = document.querySelectorAll(
|
||||
"#device-form-size input"
|
||||
);
|
||||
const pixelRatioInput = document.querySelector(
|
||||
"#device-form-pixel-ratio input"
|
||||
);
|
||||
const userAgentInput = document.querySelector(
|
||||
"#device-form-user-agent input"
|
||||
);
|
||||
const touchInput = document.querySelector("#device-form-touch input");
|
||||
|
||||
nameInput.value = newDevice.name;
|
||||
|
@ -553,10 +671,12 @@ function editDeviceInModal(ui, device, newDevice) {
|
|||
const existingCustomDevices = store.getState().devices.custom.length;
|
||||
const formSave = document.querySelector("#device-form-save");
|
||||
|
||||
const saved = waitUntilState(store, state =>
|
||||
state.devices.custom.length == existingCustomDevices &&
|
||||
state.devices.custom.find(({ name }) => name == newDevice.name) &&
|
||||
!state.devices.custom.find(({ name }) => name == device.name)
|
||||
const saved = waitUntilState(
|
||||
store,
|
||||
state =>
|
||||
state.devices.custom.length == existingCustomDevices &&
|
||||
state.devices.custom.find(({ name }) => name == newDevice.name) &&
|
||||
!state.devices.custom.find(({ name }) => name == device.name)
|
||||
);
|
||||
Simulate.click(formSave);
|
||||
return saved;
|
||||
|
@ -593,7 +713,13 @@ async function setTouchAndMetaViewportSupport(ui, value) {
|
|||
|
||||
// This function checks that zoom, layout viewport width and height
|
||||
// are all as expected.
|
||||
async function testViewportZoomWidthAndHeight(message, ui, zoom, width, height) {
|
||||
async function testViewportZoomWidthAndHeight(
|
||||
message,
|
||||
ui,
|
||||
zoom,
|
||||
width,
|
||||
height
|
||||
) {
|
||||
if (typeof zoom !== "undefined") {
|
||||
const resolution = await spawnViewportTask(ui, {}, function() {
|
||||
return content.windowUtils.getResolution();
|
||||
|
@ -609,10 +735,18 @@ async function testViewportZoomWidthAndHeight(message, ui, zoom, width, height)
|
|||
};
|
||||
});
|
||||
if (typeof width !== "undefined") {
|
||||
is(layoutSize.width, width, message + " should have expected layout width.");
|
||||
is(
|
||||
layoutSize.width,
|
||||
width,
|
||||
message + " should have expected layout width."
|
||||
);
|
||||
}
|
||||
if (typeof height !== "undefined") {
|
||||
is(layoutSize.height, height, message + " should have expected layout height.");
|
||||
is(
|
||||
layoutSize.height,
|
||||
height,
|
||||
message + " should have expected layout height."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
let div = document.querySelector("div");
|
||||
const div = document.querySelector("div");
|
||||
let initX, initY;
|
||||
let previousEvent = "", touchendTime = 0;
|
||||
let updatePreviousEvent = function (e) {
|
||||
const updatePreviousEvent = function (e) {
|
||||
previousEvent = e.type;
|
||||
};
|
||||
|
||||
|
@ -27,16 +27,16 @@
|
|||
div.style.backgroundColor = "";
|
||||
|
||||
div.addEventListener("touchstart", function (evt) {
|
||||
let touch = evt.changedTouches[0];
|
||||
const touch = evt.changedTouches[0];
|
||||
initX = touch.pageX;
|
||||
initY = touch.pageY;
|
||||
updatePreviousEvent(evt);
|
||||
}, true);
|
||||
|
||||
div.addEventListener("touchmove", function (evt) {
|
||||
let touch = evt.changedTouches[0];
|
||||
let deltaX = touch.pageX - initX;
|
||||
let deltaY = touch.pageY - initY;
|
||||
const touch = evt.changedTouches[0];
|
||||
const deltaX = touch.pageX - initX;
|
||||
const deltaY = touch.pageY - initY;
|
||||
div.style.transform = "translate(" + deltaX + "px, " + deltaY + "px)";
|
||||
updatePreviousEvent(evt);
|
||||
}, true);
|
||||
|
@ -70,7 +70,7 @@
|
|||
|
||||
div.addEventListener("mousedown", function (evt) {
|
||||
if (previousEvent === "touchend" && touchendTime !== 0) {
|
||||
let now = performance.now();
|
||||
const now = performance.now();
|
||||
// Do to time spent processing events our measurement might
|
||||
// be fractionally short of the actual delay. Round up any
|
||||
// microsecond changes in case we get something like 299.9.
|
||||
|
|
|
@ -15,21 +15,22 @@ add_task(async function() {
|
|||
const { getState, dispatch } = store;
|
||||
|
||||
const device = {
|
||||
"name": "Firefox OS Flame",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos",
|
||||
name: "Firefox OS Flame",
|
||||
width: 320,
|
||||
height: 570,
|
||||
pixelRatio: 1.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "fxos",
|
||||
};
|
||||
|
||||
dispatch(addDeviceType("phones"));
|
||||
dispatch(addDevice(device, "phones"));
|
||||
|
||||
equal(getState().devices.phones.length, 1,
|
||||
"Correct number of phones");
|
||||
ok(getState().devices.phones.includes(device),
|
||||
"Device phone list contains Firefox OS Flame");
|
||||
equal(getState().devices.phones.length, 1, "Correct number of phones");
|
||||
ok(
|
||||
getState().devices.phones.includes(device),
|
||||
"Device phone list contains Firefox OS Flame"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
// Test adding a new device type.
|
||||
|
||||
const { addDeviceType } =
|
||||
require("devtools/client/responsive/actions/devices");
|
||||
const { addDeviceType } = require("devtools/client/responsive/actions/devices");
|
||||
|
||||
add_task(async function() {
|
||||
const store = Store();
|
||||
|
@ -15,8 +14,13 @@ add_task(async function() {
|
|||
dispatch(addDeviceType("phones"));
|
||||
|
||||
equal(getState().devices.types.length, 1, "Correct number of device types");
|
||||
equal(getState().devices.phones.length, 0,
|
||||
"Defaults to an empty array of phones");
|
||||
ok(getState().devices.types.includes("phones"),
|
||||
"Device types contain phones");
|
||||
equal(
|
||||
getState().devices.phones.length,
|
||||
0,
|
||||
"Defaults to an empty array of phones"
|
||||
);
|
||||
ok(
|
||||
getState().devices.types.includes("phones"),
|
||||
"Device types contain phones"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
|
||||
// Test adding viewports to the page.
|
||||
|
||||
const { addViewport } =
|
||||
require("devtools/client/responsive/actions/viewports");
|
||||
const { addViewport } = require("devtools/client/responsive/actions/viewports");
|
||||
|
||||
add_task(async function() {
|
||||
const store = Store();
|
||||
|
|
|
@ -19,16 +19,21 @@ add_task(async function() {
|
|||
const { getState, dispatch } = store;
|
||||
|
||||
dispatch(addDeviceType("phones"));
|
||||
dispatch(addDevice({
|
||||
"name": "Firefox OS Flame",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos",
|
||||
}, "phones"));
|
||||
dispatch(
|
||||
addDevice(
|
||||
{
|
||||
name: "Firefox OS Flame",
|
||||
width: 320,
|
||||
height: 570,
|
||||
pixelRatio: 1.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "fxos",
|
||||
},
|
||||
"phones"
|
||||
)
|
||||
);
|
||||
dispatch(addViewport());
|
||||
|
||||
let viewport = getState().viewports[0];
|
||||
|
@ -37,6 +42,9 @@ add_task(async function() {
|
|||
dispatch(changeDevice(0, "Firefox OS Flame", "phones"));
|
||||
|
||||
viewport = getState().viewports[0];
|
||||
equal(viewport.device, "Firefox OS Flame",
|
||||
"Changed to Firefox OS Flame device");
|
||||
equal(
|
||||
viewport.device,
|
||||
"Firefox OS Flame",
|
||||
"Changed to Firefox OS Flame device"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
// Test changing the display pixel ratio.
|
||||
|
||||
const { changeDisplayPixelRatio } = require("devtools/client/responsive/actions/ui");
|
||||
const {
|
||||
changeDisplayPixelRatio,
|
||||
} = require("devtools/client/responsive/actions/ui");
|
||||
|
||||
const NEW_PIXEL_RATIO = 5.5;
|
||||
|
||||
|
@ -13,10 +15,12 @@ add_task(async function() {
|
|||
const store = Store();
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
equal(getState().ui.displayPixelRatio, 0,
|
||||
"Defaults to 0 at startup");
|
||||
equal(getState().ui.displayPixelRatio, 0, "Defaults to 0 at startup");
|
||||
|
||||
dispatch(changeDisplayPixelRatio(NEW_PIXEL_RATIO));
|
||||
equal(getState().ui.displayPixelRatio, NEW_PIXEL_RATIO,
|
||||
`Display Pixel Ratio changed to ${NEW_PIXEL_RATIO}`);
|
||||
equal(
|
||||
getState().ui.displayPixelRatio,
|
||||
NEW_PIXEL_RATIO,
|
||||
`Display Pixel Ratio changed to ${NEW_PIXEL_RATIO}`
|
||||
);
|
||||
});
|
||||
|
|
|
@ -13,15 +13,22 @@ add_task(async function() {
|
|||
const store = Store();
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
ok(!getState().networkThrottling.enabled,
|
||||
"Network throttling is disabled by default.");
|
||||
equal(getState().networkThrottling.profile, "",
|
||||
"Network throttling profile is empty by default.");
|
||||
ok(
|
||||
!getState().networkThrottling.enabled,
|
||||
"Network throttling is disabled by default."
|
||||
);
|
||||
equal(
|
||||
getState().networkThrottling.profile,
|
||||
"",
|
||||
"Network throttling profile is empty by default."
|
||||
);
|
||||
|
||||
dispatch(changeNetworkThrottling(true, "Bob"));
|
||||
|
||||
ok(getState().networkThrottling.enabled,
|
||||
"Network throttling is enabled.");
|
||||
equal(getState().networkThrottling.profile, "Bob",
|
||||
"Network throttling profile is set.");
|
||||
ok(getState().networkThrottling.enabled, "Network throttling is enabled.");
|
||||
equal(
|
||||
getState().networkThrottling.profile,
|
||||
"Bob",
|
||||
"Network throttling profile is set."
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
// Test changing the viewport pixel ratio.
|
||||
|
||||
const { addViewport, changePixelRatio } =
|
||||
require("devtools/client/responsive/actions/viewports");
|
||||
const {
|
||||
addViewport,
|
||||
changePixelRatio,
|
||||
} = require("devtools/client/responsive/actions/viewports");
|
||||
const NEW_PIXEL_RATIO = 5.5;
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -17,6 +19,9 @@ add_task(async function() {
|
|||
dispatch(changePixelRatio(0, NEW_PIXEL_RATIO));
|
||||
|
||||
const viewport = getState().viewports[0];
|
||||
equal(viewport.pixelRatio, NEW_PIXEL_RATIO,
|
||||
`Viewport's pixel ratio changed to ${NEW_PIXEL_RATIO}`);
|
||||
equal(
|
||||
viewport.pixelRatio,
|
||||
NEW_PIXEL_RATIO,
|
||||
`Viewport's pixel ratio changed to ${NEW_PIXEL_RATIO}`
|
||||
);
|
||||
});
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
const { changeUserAgent } = require("devtools/client/responsive/actions/ui");
|
||||
|
||||
const NEW_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) " +
|
||||
const NEW_USER_AGENT =
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) " +
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36";
|
||||
|
||||
add_task(async function() {
|
||||
|
@ -17,6 +18,9 @@ add_task(async function() {
|
|||
equal(getState().ui.userAgent, "", "User agent is empty by default.");
|
||||
|
||||
dispatch(changeUserAgent(NEW_USER_AGENT));
|
||||
equal(getState().ui.userAgent, NEW_USER_AGENT,
|
||||
`User Agent changed to ${NEW_USER_AGENT}`);
|
||||
equal(
|
||||
getState().ui.userAgent,
|
||||
NEW_USER_AGENT,
|
||||
`User Agent changed to ${NEW_USER_AGENT}`
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
|
||||
// Test resizing the viewport.
|
||||
|
||||
const { addViewport, resizeViewport } =
|
||||
require("devtools/client/responsive/actions/viewports");
|
||||
const { toggleTouchSimulation } = require("devtools/client/responsive/actions/ui");
|
||||
const {
|
||||
addViewport,
|
||||
resizeViewport,
|
||||
} = require("devtools/client/responsive/actions/viewports");
|
||||
const {
|
||||
toggleTouchSimulation,
|
||||
} = require("devtools/client/responsive/actions/ui");
|
||||
|
||||
add_task(async function() {
|
||||
const store = Store();
|
||||
|
@ -25,5 +29,9 @@ add_task(async function() {
|
|||
|
||||
viewport = getState().viewports[0];
|
||||
equal(viewport.width, 400, "Resized width of 400 (with touch simulation on)");
|
||||
equal(viewport.height, 400, "Resized height of 400 (with touch simulation on)");
|
||||
equal(
|
||||
viewport.height,
|
||||
400,
|
||||
"Resized height of 400 (with touch simulation on)"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
// Test rotating the viewport.
|
||||
|
||||
const { addViewport, rotateViewport } =
|
||||
require("devtools/client/responsive/actions/viewports");
|
||||
const {
|
||||
addViewport,
|
||||
rotateViewport,
|
||||
} = require("devtools/client/responsive/actions/viewports");
|
||||
|
||||
add_task(async function() {
|
||||
const store = Store();
|
||||
|
|
|
@ -16,22 +16,23 @@ add_task(async function() {
|
|||
const { getState, dispatch } = store;
|
||||
|
||||
const device = {
|
||||
"name": "Firefox OS Flame",
|
||||
"width": 320,
|
||||
"height": 570,
|
||||
"pixelRatio": 1.5,
|
||||
"userAgent": "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
"touch": true,
|
||||
"firefoxOS": true,
|
||||
"os": "fxos",
|
||||
name: "Firefox OS Flame",
|
||||
width: 320,
|
||||
height: 570,
|
||||
pixelRatio: 1.5,
|
||||
userAgent: "Mozilla/5.0 (Mobile; rv:39.0) Gecko/39.0 Firefox/39.0",
|
||||
touch: true,
|
||||
firefoxOS: true,
|
||||
os: "fxos",
|
||||
};
|
||||
|
||||
dispatch(addDeviceType("phones"));
|
||||
dispatch(addDevice(device, "phones"));
|
||||
dispatch(updateDeviceDisplayed(device, "phones", true));
|
||||
|
||||
equal(getState().devices.phones.length, 1,
|
||||
"Correct number of phones");
|
||||
ok(getState().devices.phones[0].displayed,
|
||||
"Device phone list contains enabled Firefox OS Flame");
|
||||
equal(getState().devices.phones.length, 1, "Correct number of phones");
|
||||
ok(
|
||||
getState().devices.phones[0].displayed,
|
||||
"Device phone list contains enabled Firefox OS Flame"
|
||||
);
|
||||
});
|
||||
|
|
|
@ -5,17 +5,20 @@
|
|||
|
||||
// Test updating the touch simulation `enabled` property
|
||||
|
||||
const { toggleTouchSimulation } = require("devtools/client/responsive/actions/ui");
|
||||
const {
|
||||
toggleTouchSimulation,
|
||||
} = require("devtools/client/responsive/actions/ui");
|
||||
|
||||
add_task(async function() {
|
||||
const store = Store();
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
ok(!getState().ui.touchSimulationEnabled,
|
||||
"Touch simulation is disabled by default.");
|
||||
ok(
|
||||
!getState().ui.touchSimulationEnabled,
|
||||
"Touch simulation is disabled by default."
|
||||
);
|
||||
|
||||
dispatch(toggleTouchSimulation(true));
|
||||
|
||||
ok(getState().ui.touchSimulationEnabled,
|
||||
"Touch simulation is enabled.");
|
||||
ok(getState().ui.touchSimulationEnabled, "Touch simulation is enabled.");
|
||||
});
|
||||
|
|
|
@ -28,7 +28,6 @@ exports.loadableState = createEnum([
|
|||
* A single device that can be displayed in the viewport.
|
||||
*/
|
||||
const device = {
|
||||
|
||||
// The name of the device
|
||||
name: PropTypes.string,
|
||||
|
||||
|
@ -52,14 +51,12 @@ const device = {
|
|||
|
||||
// Whether or not the device is displayed in the device selector
|
||||
displayed: PropTypes.bool,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A list of devices and their types that can be displayed in the viewport.
|
||||
*/
|
||||
exports.devices = {
|
||||
|
||||
// An array of device types
|
||||
types: PropTypes.arrayOf(PropTypes.string),
|
||||
|
||||
|
@ -89,7 +86,6 @@ exports.devices = {
|
|||
|
||||
// Device list state, possible values are exported above in an enum
|
||||
listState: PropTypes.oneOf(Object.keys(exports.loadableState)),
|
||||
|
||||
};
|
||||
|
||||
/* VIEWPORT */
|
||||
|
@ -98,20 +94,17 @@ exports.devices = {
|
|||
* Network throttling state for a given viewport.
|
||||
*/
|
||||
exports.networkThrottling = {
|
||||
|
||||
// Whether or not network throttling is enabled
|
||||
enabled: PropTypes.bool,
|
||||
|
||||
// Name of the selected throttling profile
|
||||
profile: PropTypes.string,
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A single viewport displaying a document.
|
||||
*/
|
||||
exports.viewport = {
|
||||
|
||||
// The id of the viewport
|
||||
id: PropTypes.number,
|
||||
|
||||
|
@ -133,7 +126,6 @@ exports.viewport = {
|
|||
// The user context (container) ID for the viewport
|
||||
// Defaults to 0 meaning the default context
|
||||
userContextId: PropTypes.number,
|
||||
|
||||
};
|
||||
|
||||
/* ACTIONS IN PROGRESS */
|
||||
|
@ -142,8 +134,6 @@ exports.viewport = {
|
|||
* The progression of the screenshot.
|
||||
*/
|
||||
exports.screenshot = {
|
||||
|
||||
// Whether screenshot capturing is in progress
|
||||
isCapturing: PropTypes.bool,
|
||||
|
||||
};
|
||||
|
|
|
@ -51,7 +51,7 @@ exports.off = off;
|
|||
*/
|
||||
function once(mm, message) {
|
||||
return new Promise(resolve => {
|
||||
on(mm, message, function onMessage({data}) {
|
||||
on(mm, message, function onMessage({ data }) {
|
||||
off(mm, message, onMessage);
|
||||
resolve(data);
|
||||
});
|
||||
|
|
|
@ -4,8 +4,18 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
loader.lazyRequireGetter(this, "TargetFactory", "devtools/client/framework/target", true);
|
||||
loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools", true);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"TargetFactory",
|
||||
"devtools/client/framework/target",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"gDevTools",
|
||||
"devtools/client/framework/devtools",
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* Displays a notification either at the browser or toolbox level, depending on whether
|
||||
|
@ -22,7 +32,11 @@ loader.lazyRequireGetter(this, "gDevTools", "devtools/client/framework/devtools"
|
|||
* - `priority`: Priority level for the notification, which affects the icon and
|
||||
* overall appearance.
|
||||
*/
|
||||
async function showNotification(window, tab, { toolboxButton, msg, priority } = {}) {
|
||||
async function showNotification(
|
||||
window,
|
||||
tab,
|
||||
{ toolboxButton, msg, priority } = {}
|
||||
) {
|
||||
// Default to using the browser's per-tab notification box
|
||||
let nbox = window.gBrowser.getNotificationBox(tab.linkedBrowser);
|
||||
|
||||
|
|
|
@ -30,14 +30,12 @@ function getOrientation(device, viewport, angleToRotateTo = null) {
|
|||
const { width: viewportWidth, height: viewportHeight } = viewport;
|
||||
|
||||
// Determine the primary orientation of the device screen.
|
||||
const primaryOrientation = deviceHeight >= deviceWidth ?
|
||||
PORTRAIT_PRIMARY :
|
||||
LANDSCAPE_PRIMARY;
|
||||
const primaryOrientation =
|
||||
deviceHeight >= deviceWidth ? PORTRAIT_PRIMARY : LANDSCAPE_PRIMARY;
|
||||
|
||||
// Determine the current orientation of the device screen.
|
||||
const currentOrientation = viewportHeight >= viewportWidth ?
|
||||
PORTRAIT_PRIMARY :
|
||||
LANDSCAPE_PRIMARY;
|
||||
const currentOrientation =
|
||||
viewportHeight >= viewportWidth ? PORTRAIT_PRIMARY : LANDSCAPE_PRIMARY;
|
||||
|
||||
// Calculate the orientation angle of the device.
|
||||
let angle;
|
||||
|
|
|
@ -23,9 +23,8 @@ exports.getDOMWindowUtils = getDOMWindowUtils;
|
|||
* Check if the given browser window has finished the startup.
|
||||
* @params {nsIDOMWindow} window
|
||||
*/
|
||||
const isStartupFinished = (window) =>
|
||||
window.gBrowserInit &&
|
||||
window.gBrowserInit.delayedStartupFinished;
|
||||
const isStartupFinished = window =>
|
||||
window.gBrowserInit && window.gBrowserInit.delayedStartupFinished;
|
||||
|
||||
function startup(window) {
|
||||
return new Promise(resolve => {
|
||||
|
@ -35,7 +34,10 @@ function startup(window) {
|
|||
}
|
||||
Services.obs.addObserver(function listener({ subject }) {
|
||||
if (subject === window) {
|
||||
Services.obs.removeObserver(listener, "browser-delayed-startup-finished");
|
||||
Services.obs.removeObserver(
|
||||
listener,
|
||||
"browser-delayed-startup-finished"
|
||||
);
|
||||
resolve(window);
|
||||
}
|
||||
}, "browser-delayed-startup-finished");
|
||||
|
|
Загрузка…
Ссылка в новой задаче