зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1239441 - Implement landscape / portrait button that rotates the viewport r=jryans
This commit is contained in:
Родитель
582d5628c5
Коммит
598883d5e8
|
@ -17,6 +17,9 @@ createEnum([
|
|||
// Add an additional viewport to display the document.
|
||||
"ADD_VIEWPORT",
|
||||
|
||||
// Rotate the viewport.
|
||||
"ROTATE_VIEWPORT",
|
||||
|
||||
], module.exports);
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { ADD_VIEWPORT } = require("./index");
|
||||
const { ADD_VIEWPORT, ROTATE_VIEWPORT } = require("./index");
|
||||
|
||||
module.exports = {
|
||||
|
||||
|
@ -17,4 +17,14 @@ module.exports = {
|
|||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotate the viewport.
|
||||
*/
|
||||
rotateViewport(id) {
|
||||
return {
|
||||
type: ROTATE_VIEWPORT,
|
||||
id,
|
||||
};
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ const { createClass, createFactory, PropTypes } =
|
|||
require("devtools/client/shared/vendor/react");
|
||||
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||
|
||||
const { rotateViewport } = require("./actions/viewports");
|
||||
const Types = require("./types");
|
||||
const Viewports = createFactory(require("./components/viewports"));
|
||||
|
||||
|
@ -22,6 +23,7 @@ let App = createClass({
|
|||
|
||||
render() {
|
||||
let {
|
||||
dispatch,
|
||||
location,
|
||||
viewports,
|
||||
} = this.props;
|
||||
|
@ -31,6 +33,7 @@ let App = createClass({
|
|||
return Viewports({
|
||||
location,
|
||||
viewports,
|
||||
onRotateViewport: id => dispatch(rotateViewport(id)),
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
DevToolsModules(
|
||||
'browser.js',
|
||||
'viewport-toolbar.js',
|
||||
'viewport.js',
|
||||
'viewports.js',
|
||||
)
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { DOM: dom, createClass, PropTypes } =
|
||||
require("devtools/client/shared/vendor/react");
|
||||
|
||||
module.exports = createClass({
|
||||
|
||||
displayName: "ViewportToolbar",
|
||||
|
||||
propTypes: {
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
onRotateViewport,
|
||||
} = this.props;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
className: "viewport-toolbar",
|
||||
},
|
||||
dom.button({
|
||||
className: "viewport-rotate-button viewport-toolbar-button",
|
||||
onClick: onRotateViewport,
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
});
|
|
@ -9,6 +9,7 @@ const { DOM: dom, createClass, createFactory, PropTypes } =
|
|||
|
||||
const Types = require("../types");
|
||||
const Browser = createFactory(require("./browser"));
|
||||
const ViewportToolbar = createFactory(require("./viewport-toolbar"));
|
||||
|
||||
module.exports = createClass({
|
||||
|
||||
|
@ -17,22 +18,22 @@ module.exports = createClass({
|
|||
propTypes: {
|
||||
location: Types.location.isRequired,
|
||||
viewport: PropTypes.shape(Types.viewport).isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
location,
|
||||
viewport,
|
||||
onRotateViewport,
|
||||
} = this.props;
|
||||
|
||||
// Additional elements will soon appear here around the Browser, like drag
|
||||
// handles, etc.
|
||||
return dom.div(
|
||||
{
|
||||
className: "viewport"
|
||||
},
|
||||
dom.div({
|
||||
className: "viewport-header",
|
||||
ViewportToolbar({
|
||||
onRotateViewport,
|
||||
}),
|
||||
Browser({
|
||||
location,
|
||||
|
|
|
@ -17,23 +17,26 @@ module.exports = createClass({
|
|||
propTypes: {
|
||||
location: Types.location.isRequired,
|
||||
viewports: PropTypes.arrayOf(PropTypes.shape(Types.viewport)).isRequired,
|
||||
onRotateViewport: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
render() {
|
||||
let {
|
||||
location,
|
||||
viewports,
|
||||
onRotateViewport,
|
||||
} = this.props;
|
||||
|
||||
return dom.div(
|
||||
{
|
||||
id: "viewports",
|
||||
},
|
||||
viewports.map((viewport, index) => {
|
||||
viewports.map(viewport => {
|
||||
return Viewport({
|
||||
key: index,
|
||||
key: viewport.id,
|
||||
location,
|
||||
viewport,
|
||||
onRotateViewport: () => onRotateViewport(viewport.id),
|
||||
});
|
||||
})
|
||||
);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DevToolsModules(
|
||||
'rotate-viewport.svg',
|
||||
)
|
|
@ -0,0 +1,6 @@
|
|||
<!-- This Source Code Form is subject to the terms of the Mozilla Public
|
||||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path d="M12.3 11.5l-2.2-8.2-.3-.3c-.1-.1-.2-.1-.4-.1L4 4.4c-.2.1-.4.4-.3.6l2.2 8.2c0 .1.1.2.2.3.1 0 .2.1.3.1h.1l5.4-1.5c.3 0 .5-.3.4-.6zM9.2 4.1l1.5 5.5-4.4 1.2-1.5-5.5 4.4-1.2zm-2.4 8.4l-.3-1.1 4.4-1.2.3 1.1-4.4 1.2zM3.7 13.7c-1.2 0-3.4-.6-3.7-2.8-.3-2.2 1.3-3.3 2.1-3.5.2-.1.4.1.5.3.1.2-.1.4-.3.5-.1 0-1.8.6-1.6 2.7.2 1.5 1.6 1.9 2.4 2l-.7-2.4c0-.2.2-.5.4-.5.2-.1.4 0 .5.2l.9 3c0 .1 0 .3-.1.4-.1.1-.2.1-.4.1zM12.3 3.1c1.2 0 3.4.6 3.7 2.8.3 2.2-1.3 3.3-2.1 3.5-.2.1-.4-.1-.5-.3-.1-.2.1-.4.3-.5.1 0 1.8-.6 1.6-2.7-.2-1.5-1.6-1.9-2.4-2l.7 2.4c.1.2-.1.4-.3.5-.2.1-.4-.1-.5-.3l-.9-3c0-.1 0-.3.1-.4h.3z"/>
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 908 B |
|
@ -1,6 +1,18 @@
|
|||
/* TODO: May break up into component local CSS. Pending future discussions by
|
||||
* React component group on how to best handle CSS. */
|
||||
|
||||
/**
|
||||
* CSS Variables specific to the responsive design mode
|
||||
*/
|
||||
|
||||
.theme-light {
|
||||
--viewport-box-shadow: 0 4px 4px 0 rgba(155, 155, 155, 0.26);
|
||||
}
|
||||
|
||||
.theme-dark {
|
||||
--viewport-box-shadow: 0 4px 4px 0 rgba(105, 105, 105, 0.26);
|
||||
}
|
||||
|
||||
html, body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
|
@ -42,14 +54,46 @@ body {
|
|||
/* Align all viewports to the top */
|
||||
vertical-align: top;
|
||||
border: 1px solid var(--theme-splitter-color);
|
||||
box-shadow: 0 4px 4px 0 rgba(155, 155, 155, 0.26);
|
||||
box-shadow: var(--viewport-box-shadow);
|
||||
}
|
||||
|
||||
.viewport-header {
|
||||
/**
|
||||
* Viewport Toolbar
|
||||
*/
|
||||
|
||||
.viewport-toolbar {
|
||||
background-color: var(--theme-toolbar-background);
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
color: var(--theme-body-color-alt);
|
||||
color: var(--theme-body-color);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.viewport-toolbar-button {
|
||||
border: none;
|
||||
display: block;
|
||||
margin: 1px 3px;
|
||||
padding: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
opacity: 0.8;
|
||||
background-color: var(--theme-body-color);
|
||||
transition: background 0.25s ease;
|
||||
}
|
||||
|
||||
.viewport-toolbar-button:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.viewport-toolbar-button:active {
|
||||
background-color: var(--theme-selection-background);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.viewport-rotate-button {
|
||||
mask-image: url("./images/rotate-viewport.svg");
|
||||
}
|
||||
|
||||
.browser {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
DIRS += [
|
||||
'actions',
|
||||
'components',
|
||||
'images',
|
||||
'reducers',
|
||||
]
|
||||
|
||||
|
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { ADD_VIEWPORT } = require("../actions/index");
|
||||
const { ADD_VIEWPORT, ROTATE_VIEWPORT } = require("../actions/index");
|
||||
|
||||
let nextViewportId = 0;
|
||||
|
||||
const INITIAL_VIEWPORTS = [];
|
||||
const INITIAL_VIEWPORT = {
|
||||
id: nextViewportId++,
|
||||
width: 320,
|
||||
height: 480,
|
||||
};
|
||||
|
@ -19,7 +22,20 @@ let reducers = {
|
|||
if (viewports.length === 1) {
|
||||
return viewports;
|
||||
}
|
||||
return [...viewports, INITIAL_VIEWPORT];
|
||||
return [...viewports, Object.assign({}, INITIAL_VIEWPORT)];
|
||||
},
|
||||
|
||||
[ROTATE_VIEWPORT](viewports, { id }) {
|
||||
return viewports.map(viewport => {
|
||||
if (viewport.id !== id) {
|
||||
return viewport;
|
||||
}
|
||||
|
||||
return Object.assign({}, viewport, {
|
||||
width: viewport.height,
|
||||
height: viewport.width,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test rotating the viewport.
|
||||
|
||||
const { addViewport, rotateViewport } =
|
||||
require("devtools/client/responsive.html/actions/viewports");
|
||||
|
||||
add_task(function*() {
|
||||
let store = Store();
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
dispatch(addViewport());
|
||||
|
||||
let viewport = getState().viewports[0];
|
||||
equal(viewport.width, 320, "Default width of 320");
|
||||
equal(viewport.height, 480, "Default height of 480");
|
||||
|
||||
dispatch(rotateViewport(0));
|
||||
viewport = getState().viewports[0];
|
||||
equal(viewport.width, 480, "Rotated width of 480");
|
||||
equal(viewport.height, 320, "Rotated height of 320");
|
||||
});
|
|
@ -6,3 +6,4 @@ firefox-appdir = browser
|
|||
|
||||
[test_add_viewport.js]
|
||||
[test_change_location.js]
|
||||
[test_rotate_viewport.js]
|
||||
|
|
|
@ -14,6 +14,9 @@ const { PropTypes } = require("devtools/client/shared/vendor/react");
|
|||
*/
|
||||
exports.viewport = {
|
||||
|
||||
// The id of the viewport
|
||||
id: PropTypes.number.isRequired,
|
||||
|
||||
// The width of the viewport
|
||||
width: PropTypes.number,
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче