Bug 1381463 - Reload to clear UA when exiting RDM. r=ochameau

When exiting RDM with a device applied, we clear the UA override, but we did not
force a refresh of the page.  This means that the customized UA was still
accessible via `navigator.userAgent` and the page might have a non-default
layout if it tests the UA value.

To ensure there's no chance of confusion after exiting RDM, force a reload if
clearing emulation values determines it is needed.

MozReview-Commit-ID: Fkji12Utmis

--HG--
extra : rebase_source : a7ae8851165fae7aec5875d10f51cbb703b3f870
This commit is contained in:
J. Ryan Stinnett 2018-01-04 21:04:17 -06:00
Родитель 63b7c47b72
Коммит 6f6bc3bbbf
3 изменённых файлов: 122 добавлений и 40 удалений

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

@ -373,7 +373,7 @@ ResponsiveUI.prototype = {
* Whether this call is actually destroying. False means destruction * Whether this call is actually destroying. False means destruction
* was already in progress. * was already in progress.
*/ */
destroy: Task.async(function* (options) { async destroy(options) {
if (this.destroying) { if (this.destroying) {
return false; return false;
} }
@ -389,7 +389,7 @@ ResponsiveUI.prototype = {
// Ensure init has finished before starting destroy // Ensure init has finished before starting destroy
if (!isTabContentDestroying) { if (!isTabContentDestroying) {
yield this.inited; await this.inited;
} }
this.tab.removeEventListener("TabClose", this); this.tab.removeEventListener("TabClose", this);
@ -399,7 +399,20 @@ ResponsiveUI.prototype = {
if (!isTabContentDestroying) { if (!isTabContentDestroying) {
// Notify the inner browser to stop the frame script // Notify the inner browser to stop the frame script
yield message.request(this.toolWindow, "stop-frame-script"); await message.request(this.toolWindow, "stop-frame-script");
}
// Ensure the tab is reloaded if required when exiting RDM so that no emulated
// settings are left in a customized state.
if (!isTabContentDestroying) {
let reloadNeeded = false;
reloadNeeded |= await this.updateDPPX();
reloadNeeded |= await this.updateNetworkThrottling();
reloadNeeded |= await this.updateUserAgent();
reloadNeeded |= await this.updateTouchSimulation();
if (reloadNeeded) {
this.getViewportBrowser().reload();
}
} }
// Destroy local state // Destroy local state
@ -415,7 +428,7 @@ ResponsiveUI.prototype = {
// anything on shutdown client side. // anything on shutdown client side.
let clientClosed = this.client.close(); let clientClosed = this.client.close();
if (!isTabContentDestroying) { if (!isTabContentDestroying) {
yield clientClosed; await clientClosed;
} }
this.client = this.emulationFront = null; this.client = this.emulationFront = null;
@ -427,7 +440,7 @@ ResponsiveUI.prototype = {
this.destroyed = true; this.destroyed = true;
return true; return true;
}), },
connectToServer: Task.async(function* () { connectToServer: Task.async(function* () {
DebuggerServer.init(); DebuggerServer.init();
@ -487,9 +500,13 @@ ResponsiveUI.prototype = {
onChangeDevice: Task.async(function* (event) { onChangeDevice: Task.async(function* (event) {
let { userAgent, pixelRatio, touch } = event.data.device; let { userAgent, pixelRatio, touch } = event.data.device;
// Bug 1428799: Should we reload on UA change as well?
yield this.updateUserAgent(userAgent); yield this.updateUserAgent(userAgent);
yield this.updateDPPX(pixelRatio); yield this.updateDPPX(pixelRatio);
yield this.updateTouchSimulation(touch); let reloadNeeded = yield this.updateTouchSimulation(touch);
if (reloadNeeded) {
this.getViewportBrowser().reload();
}
// Used by tests // Used by tests
this.emit("device-changed"); this.emit("device-changed");
}), }),
@ -506,9 +523,12 @@ ResponsiveUI.prototype = {
this.updateDPPX(pixelRatio); this.updateDPPX(pixelRatio);
}, },
onChangeTouchSimulation(event) { async onChangeTouchSimulation(event) {
let { enabled } = event.data; let { enabled } = event.data;
this.updateTouchSimulation(enabled); let reloadNeeded = await this.updateTouchSimulation(enabled);
if (reloadNeeded) {
this.getViewportBrowser().reload();
}
// Used by tests // Used by tests
this.emit("touch-simulation-changed"); this.emit("touch-simulation-changed");
}, },
@ -527,25 +547,44 @@ ResponsiveUI.prototype = {
}, },
onRemoveDeviceAssociation: Task.async(function* (event) { onRemoveDeviceAssociation: Task.async(function* (event) {
// Bug 1428799: Should we reload on UA change as well?
yield this.updateUserAgent(); yield this.updateUserAgent();
yield this.updateDPPX(); yield this.updateDPPX();
yield this.updateTouchSimulation(); let reloadNeeded = yield this.updateTouchSimulation();
if (reloadNeeded) {
this.getViewportBrowser().reload();
}
// Used by tests // Used by tests
this.emit("device-association-removed"); this.emit("device-association-removed");
}), }),
/**
* Set or clear the emulated device pixel ratio.
*
* @return boolean
* Whether a reload is needed to apply the change.
* (This is always immediate, so it's always false.)
*/
updateDPPX: Task.async(function* (dppx) { updateDPPX: Task.async(function* (dppx) {
if (!dppx) { if (!dppx) {
yield this.emulationFront.clearDPPXOverride(); yield this.emulationFront.clearDPPXOverride();
return; return false;
} }
yield this.emulationFront.setDPPXOverride(dppx); yield this.emulationFront.setDPPXOverride(dppx);
return false;
}), }),
/**
* Set or clear network throttling.
*
* @return boolean
* Whether a reload is needed to apply the change.
* (This is always immediate, so it's always false.)
*/
updateNetworkThrottling: Task.async(function* (enabled, profile) { updateNetworkThrottling: Task.async(function* (enabled, profile) {
if (!enabled) { if (!enabled) {
yield this.emulationFront.clearNetworkThrottling(); yield this.emulationFront.clearNetworkThrottling();
return; return false;
} }
let data = throttlingProfiles.find(({ id }) => id == profile); let data = throttlingProfiles.find(({ id }) => id == profile);
let { download, upload, latency } = data; let { download, upload, latency } = data;
@ -554,29 +593,36 @@ ResponsiveUI.prototype = {
uploadThroughput: upload, uploadThroughput: upload,
latency, latency,
}); });
return false;
}), }),
updateUserAgent: Task.async(function* (userAgent) { /**
* Set or clear the emulated user agent.
*
* @return boolean
* Whether a reload is needed to apply the change.
*/
updateUserAgent(userAgent) {
if (!userAgent) { if (!userAgent) {
yield this.emulationFront.clearUserAgentOverride(); return this.emulationFront.clearUserAgentOverride();
return;
} }
yield this.emulationFront.setUserAgentOverride(userAgent); return this.emulationFront.setUserAgentOverride(userAgent);
}), },
updateTouchSimulation: Task.async(function* (enabled) { /**
let reloadNeeded; * Set or clear touch simulation.
if (enabled) { *
reloadNeeded = yield this.emulationFront.setTouchEventsOverride( * @return boolean
* Whether a reload is needed to apply the change.
*/
updateTouchSimulation(enabled) {
if (!enabled) {
return this.emulationFront.clearTouchEventsOverride();
}
return this.emulationFront.setTouchEventsOverride(
Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED Ci.nsIDocShell.TOUCHEVENTS_OVERRIDE_ENABLED
); );
} else { },
reloadNeeded = yield this.emulationFront.clearTouchEventsOverride();
}
if (reloadNeeded) {
this.getViewportBrowser().reload();
}
}),
/** /**
* Helper for tests. Assumes a single viewport for now. * Helper for tests. Assumes a single viewport for now.

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

@ -3,8 +3,8 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict"; "use strict";
// Tests changing viewport device // Tests changing viewport device (need HTTP load for proper UA testing)
const TEST_URL = "data:text/html;charset=utf-8,Device list test"; const TEST_URL = `${URL_ROOT}doc_page_state.html`;
const DEFAULT_DPPX = window.devicePixelRatio; const DEFAULT_DPPX = window.devicePixelRatio;
const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"] const DEFAULT_UA = Cc["@mozilla.org/network/protocol;1?name=http"]
@ -28,7 +28,7 @@ const testDevice = {
// Add the new device to the list // Add the new device to the list
addDeviceForTest(testDevice); addDeviceForTest(testDevice);
addRDMTask(TEST_URL, function* ({ ui, manager }) { addRDMTask(TEST_URL, function* ({ ui }) {
let { store } = ui.toolWindow; let { store } = ui.toolWindow;
// Wait until the viewport has been added and the device list has been loaded // Wait until the viewport has been added and the device list has been loaded
@ -37,23 +37,29 @@ addRDMTask(TEST_URL, function* ({ ui, manager }) {
// Test defaults // Test defaults
testViewportDimensions(ui, 320, 480); testViewportDimensions(ui, 320, 480);
info("Should have default UA at the start of the test");
yield testUserAgent(ui, DEFAULT_UA); yield testUserAgent(ui, DEFAULT_UA);
yield testDevicePixelRatio(ui, DEFAULT_DPPX); yield testDevicePixelRatio(ui, DEFAULT_DPPX);
yield testTouchEventsOverride(ui, false); yield testTouchEventsOverride(ui, false);
testViewportDeviceSelectLabel(ui, "no device selected"); testViewportDeviceSelectLabel(ui, "no device selected");
// Test device with custom properties // Test device with custom properties
let reloaded = waitForViewportLoad(ui);
yield selectDevice(ui, "Fake Phone RDM Test"); yield selectDevice(ui, "Fake Phone RDM Test");
yield reloaded;
yield waitForViewportResizeTo(ui, testDevice.width, testDevice.height); yield waitForViewportResizeTo(ui, testDevice.width, testDevice.height);
info("Should have device UA now that device is applied");
yield testUserAgent(ui, testDevice.userAgent); yield testUserAgent(ui, testDevice.userAgent);
yield testDevicePixelRatio(ui, testDevice.pixelRatio); yield testDevicePixelRatio(ui, testDevice.pixelRatio);
yield testTouchEventsOverride(ui, true); yield testTouchEventsOverride(ui, true);
// Test resetting device when resizing viewport // Test resetting device when resizing viewport
let deviceRemoved = once(ui, "device-association-removed"); let deviceRemoved = once(ui, "device-association-removed");
reloaded = waitForViewportLoad(ui);
yield testViewportResize(ui, ".viewport-vertical-resize-handle", yield testViewportResize(ui, ".viewport-vertical-resize-handle",
[-10, -10], [testDevice.width, testDevice.height - 10], [0, -10], ui); [-10, -10], [testDevice.width, testDevice.height - 10], [0, -10], ui);
yield deviceRemoved; yield Promise.all([ deviceRemoved, reloaded ]);
info("Should have default UA after resizing viewport");
yield testUserAgent(ui, DEFAULT_UA); yield testUserAgent(ui, DEFAULT_UA);
yield testDevicePixelRatio(ui, DEFAULT_DPPX); yield testDevicePixelRatio(ui, DEFAULT_DPPX);
yield testTouchEventsOverride(ui, false); yield testTouchEventsOverride(ui, false);
@ -62,11 +68,42 @@ addRDMTask(TEST_URL, function* ({ ui, manager }) {
// Test device with generic properties // Test device with generic properties
yield selectDevice(ui, "Laptop (1366 x 768)"); yield selectDevice(ui, "Laptop (1366 x 768)");
yield waitForViewportResizeTo(ui, 1366, 768); yield waitForViewportResizeTo(ui, 1366, 768);
info("Should have default UA when using device without specific UA");
yield testUserAgent(ui, DEFAULT_UA); yield testUserAgent(ui, DEFAULT_UA);
yield testDevicePixelRatio(ui, 1); yield testDevicePixelRatio(ui, 1);
yield testTouchEventsOverride(ui, false); yield testTouchEventsOverride(ui, false);
}); });
add_task(async function () {
const tab = await addTab(TEST_URL);
const { ui } = await openRDM(tab);
let { 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.deviceListState.LOADED);
// Select device with custom UA
let reloaded = waitForViewportLoad(ui);
await selectDevice(ui, "Fake Phone RDM Test");
await reloaded;
await waitForViewportResizeTo(ui, testDevice.width, testDevice.height);
info("Should have device UA now that device is applied");
await testUserAgent(ui, testDevice.userAgent);
// Browser will reload to clear the UA on RDM close
reloaded = waitForViewportLoad(ui);
await closeRDM(tab);
await reloaded;
// Ensure UA is reset to default after closing RDM
info("Should have default UA after closing RDM");
await testUserAgentFromBrowser(tab.linkedBrowser, DEFAULT_UA);
await removeTab(tab);
});
function testViewportDimensions(ui, w, h) { function testViewportDimensions(ui, w, h) {
let viewport = ui.toolWindow.document.querySelector(".viewport-content"); let viewport = ui.toolWindow.document.querySelector(".viewport-content");

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

@ -301,12 +301,7 @@ function waitForPageShow(browser) {
} }
function waitForViewportLoad(ui) { function waitForViewportLoad(ui) {
return new Promise(resolve => { return BrowserTestUtils.waitForContentEvent(ui.getViewportBrowser(), "load", true);
let browser = ui.getViewportBrowser();
browser.addEventListener("mozbrowserloadend", () => {
resolve();
}, { once: true });
});
} }
function load(browser, url) { function load(browser, url) {
@ -371,8 +366,12 @@ function* toggleTouchSimulation(ui) {
yield Promise.all([ changed, loaded ]); yield Promise.all([ changed, loaded ]);
} }
function* testUserAgent(ui, expected) { function testUserAgent(ui, expected) {
let ua = yield ContentTask.spawn(ui.getViewportBrowser(), {}, function* () { testUserAgentFromBrowser(ui.getViewportBrowser(), expected);
}
async function testUserAgentFromBrowser(browser, expected) {
let ua = await ContentTask.spawn(browser, {}, function* () {
return content.navigator.userAgent; return content.navigator.userAgent;
}); });
is(ua, expected, `UA should be set to ${expected}`); is(ua, expected, `UA should be set to ${expected}`);