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:
Gabriel Luong 2019-08-07 15:24:49 +00:00
Родитель 725df6c2ff
Коммит 788820312b
95 изменённых файлов: 2873 добавлений и 1712 удалений

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

@ -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");