зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1240896 - Port browser_device_width.js to new RDM. r=gl
This also adds the test infrastructure for detecting content resizing. MozReview-Commit-ID: H3bkAOkpMbs
This commit is contained in:
Родитель
6379a92120
Коммит
6c4bc0307f
|
@ -39,6 +39,14 @@ let App = createClass({
|
|||
this.props.dispatch(changeDevice(id, device));
|
||||
},
|
||||
|
||||
onContentResize({ width, height }) {
|
||||
window.postMessage({
|
||||
type: "content-resize",
|
||||
width,
|
||||
height,
|
||||
}, "*");
|
||||
},
|
||||
|
||||
onExit() {
|
||||
window.postMessage({ type: "exit" }, "*");
|
||||
},
|
||||
|
@ -64,8 +72,9 @@ let App = createClass({
|
|||
} = this.props;
|
||||
|
||||
let {
|
||||
onChangeViewportDevice,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onExit,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
|
@ -88,6 +97,7 @@ let App = createClass({
|
|||
viewports,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onRotateViewport,
|
||||
onResizeViewport,
|
||||
})
|
||||
|
|
|
@ -30,6 +30,7 @@ module.exports = createClass({
|
|||
propTypes: {
|
||||
location: Types.location.isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -37,8 +38,16 @@ module.exports = createClass({
|
|||
* various features, like floating scrollbars.
|
||||
*/
|
||||
componentDidMount: Task.async(function*() {
|
||||
let { onContentResize } = this;
|
||||
let browser = this.refs.browserContainer.querySelector("iframe.browser");
|
||||
let mm = browser.frameLoader.messageManager;
|
||||
|
||||
// Notify tests when the content has received a resize event. This is not
|
||||
// quite the same timing as when we _set_ a new size around the browser,
|
||||
// since it still needs to do async work before the content is actually
|
||||
// resized to match.
|
||||
mm.addMessageListener("ResponsiveMode:OnContentResize", onContentResize);
|
||||
|
||||
let ready = waitForMessage(mm, "ResponsiveMode:ChildScriptReady");
|
||||
mm.loadFrameScript("resource://devtools/client/responsivedesign/" +
|
||||
"responsivedesign-child.js", true);
|
||||
|
@ -60,11 +69,22 @@ module.exports = createClass({
|
|||
}),
|
||||
|
||||
componentWillUnmount() {
|
||||
let { onContentResize } = this;
|
||||
let browser = this.refs.browserContainer.querySelector("iframe.browser");
|
||||
let mm = browser.frameLoader.messageManager;
|
||||
mm.removeMessageListener("ResponsiveMode:OnContentResize", onContentResize);
|
||||
mm.sendAsyncMessage("ResponsiveMode:Stop");
|
||||
},
|
||||
|
||||
onContentResize(msg) {
|
||||
let { onContentResize } = this.props;
|
||||
let { width, height } = msg.data;
|
||||
onContentResize({
|
||||
width,
|
||||
height,
|
||||
});
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
location,
|
||||
|
|
|
@ -28,6 +28,7 @@ module.exports = createClass({
|
|||
viewport: PropTypes.shape(Types.viewport).isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportDevice: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
@ -118,6 +119,7 @@ module.exports = createClass({
|
|||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
} = this.props;
|
||||
|
@ -154,6 +156,7 @@ module.exports = createClass({
|
|||
Browser({
|
||||
location,
|
||||
onBrowserMounted,
|
||||
onContentResize,
|
||||
})
|
||||
),
|
||||
dom.div({
|
||||
|
|
|
@ -22,6 +22,7 @@ module.exports = createClass({
|
|||
viewport: PropTypes.shape(Types.viewport).isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportDevice: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
@ -59,6 +60,7 @@ module.exports = createClass({
|
|||
location,
|
||||
screenshot,
|
||||
viewport,
|
||||
onContentResize,
|
||||
onBrowserMounted,
|
||||
} = this.props;
|
||||
|
||||
|
@ -79,6 +81,7 @@ module.exports = createClass({
|
|||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
}),
|
||||
|
|
|
@ -21,6 +21,7 @@ module.exports = createClass({
|
|||
viewports: PropTypes.arrayOf(PropTypes.shape(Types.viewport)).isRequired,
|
||||
onBrowserMounted: PropTypes.func.isRequired,
|
||||
onChangeViewportDevice: PropTypes.func.isRequired,
|
||||
onContentResize: PropTypes.func.isRequired,
|
||||
onResizeViewport: PropTypes.func.isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
@ -33,6 +34,7 @@ module.exports = createClass({
|
|||
viewports,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
} = this.props;
|
||||
|
@ -50,6 +52,7 @@ module.exports = createClass({
|
|||
viewport,
|
||||
onBrowserMounted,
|
||||
onChangeViewportDevice,
|
||||
onContentResize,
|
||||
onResizeViewport,
|
||||
onRotateViewport,
|
||||
});
|
||||
|
|
|
@ -115,6 +115,14 @@ window.addInitialViewport = contentURI => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by manager.js when tests want to check the viewport size.
|
||||
*/
|
||||
window.getViewportSize = () => {
|
||||
let { width, height } = bootstrap.store.getState().viewports[0];
|
||||
return { width, height };
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by manager.js to set viewport size from GCLI.
|
||||
*/
|
||||
|
@ -125,3 +133,10 @@ window.setViewportSize = (width, height) => {
|
|||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called by manager.js when tests want to use the viewport's message manager.
|
||||
*/
|
||||
window.getViewportMessageManager = () => {
|
||||
return document.querySelector("iframe.browser").frameLoader;
|
||||
};
|
||||
|
|
|
@ -195,10 +195,10 @@ ResponsiveUI.prototype = {
|
|||
tabBrowser.loadURI(TOOL_URL);
|
||||
yield tabLoaded(this.tab);
|
||||
let toolWindow = this.toolWindow = tabBrowser.contentWindow;
|
||||
toolWindow.addEventListener("message", this);
|
||||
yield waitForMessage(toolWindow, "init");
|
||||
toolWindow.addInitialViewport(contentURI);
|
||||
yield waitForMessage(toolWindow, "browser-mounted");
|
||||
toolWindow.addEventListener("message", this);
|
||||
}),
|
||||
|
||||
destroy() {
|
||||
|
@ -219,6 +219,13 @@ ResponsiveUI.prototype = {
|
|||
}
|
||||
|
||||
switch (event.data.type) {
|
||||
case "content-resize":
|
||||
let { width, height } = event.data;
|
||||
this.emit("content-resize", {
|
||||
width,
|
||||
height,
|
||||
});
|
||||
break;
|
||||
case "exit":
|
||||
toolWindow.removeEventListener(event.type, this);
|
||||
ResponsiveUIManager.closeIfNeeded(window, tab);
|
||||
|
@ -226,13 +233,23 @@ ResponsiveUI.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
getViewportSize() {
|
||||
return this.toolWindow.getViewportSize();
|
||||
},
|
||||
|
||||
setViewportSize: Task.async(function*(width, height) {
|
||||
yield this.inited;
|
||||
this.toolWindow.setViewportSize(width, height);
|
||||
}),
|
||||
|
||||
getViewportMessageManager() {
|
||||
return this.toolWindow.getViewportMessageManager();
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
EventEmitter.decorate(ResponsiveUI.prototype);
|
||||
|
||||
function waitForMessage(win, type) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ support-files =
|
|||
!/devtools/client/framework/test/shared-head.js
|
||||
!/devtools/client/framework/test/shared-redux-head.js
|
||||
|
||||
[browser_device_width.js]
|
||||
[browser_exit_button.js]
|
||||
[browser_resize_cmd.js]
|
||||
[browser_screenshot_button.js]
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URL = "about:logo";
|
||||
|
||||
addRDMTask(TEST_URL, function*({ ui, manager }) {
|
||||
ok(ui, "An instance of the RDM should be attached to the tab.");
|
||||
yield setViewportSize(ui, manager, 110, 500);
|
||||
|
||||
info("Checking initial width/height properties.");
|
||||
yield doInitialChecks(ui);
|
||||
|
||||
info("Changing the RDM size");
|
||||
yield setViewportSize(ui, manager, 90, 500);
|
||||
|
||||
info("Checking for screen props");
|
||||
yield checkScreenProps(ui);
|
||||
|
||||
info("Setting docShell.deviceSizeIsPageSize to false");
|
||||
yield ContentTask.spawn(ui.getViewportMessageManager(), {}, function*() {
|
||||
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell);
|
||||
docShell.deviceSizeIsPageSize = false;
|
||||
});
|
||||
|
||||
info("Checking for screen props once again.");
|
||||
yield checkScreenProps2(ui);
|
||||
});
|
||||
|
||||
function* doInitialChecks(ui) {
|
||||
let { innerWidth, matchesMedia } = yield grabContentInfo(ui);
|
||||
is(innerWidth, 110, "initial width should be 110px");
|
||||
ok(!matchesMedia, "media query shouldn't match.");
|
||||
}
|
||||
|
||||
function* checkScreenProps(ui) {
|
||||
let { matchesMedia, screen } = yield grabContentInfo(ui);
|
||||
ok(matchesMedia, "media query should match");
|
||||
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");
|
||||
}
|
||||
|
||||
function* checkScreenProps2(ui) {
|
||||
let { matchesMedia, screen } = yield 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.");
|
||||
}
|
||||
|
||||
function grabContentInfo(ui) {
|
||||
return ContentTask.spawn(ui.getViewportMessageManager(), {}, function*() {
|
||||
return {
|
||||
screen: {
|
||||
width: content.screen.width,
|
||||
height: content.screen.height
|
||||
},
|
||||
innerWidth: content.innerWidth,
|
||||
matchesMedia: content.matchMedia("(max-device-width:100px)").matches
|
||||
};
|
||||
});
|
||||
}
|
|
@ -94,3 +94,29 @@ var waitForFrameLoad = Task.async(function*(frame, targetURL) {
|
|||
}
|
||||
yield once(frame, "load");
|
||||
});
|
||||
|
||||
function waitForViewportResizeTo(ui, width, height) {
|
||||
return new Promise(resolve => {
|
||||
let onResize = (_, data) => {
|
||||
if (data.width != width || data.height != height) {
|
||||
return;
|
||||
}
|
||||
ui.off("content-resize", onResize);
|
||||
info(`Got content-resize to ${width} x ${height}`);
|
||||
resolve();
|
||||
};
|
||||
info(`Waiting for content-resize to ${width} x ${height}`);
|
||||
ui.on("content-resize", onResize);
|
||||
});
|
||||
}
|
||||
|
||||
var setViewportSize = Task.async(function*(ui, manager, width, height) {
|
||||
let size = ui.getViewportSize();
|
||||
info(`Current size: ${size.width} x ${size.height}, ` +
|
||||
`set to: ${width} x ${height}`);
|
||||
if (size.width != width || size.height != height) {
|
||||
let resized = waitForViewportResizeTo(ui, width, height);
|
||||
ui.setViewportSize(width, height);
|
||||
yield resized;
|
||||
}
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче