diff options
Diffstat (limited to 'devtools/client/responsive/reducers')
-rw-r--r-- | devtools/client/responsive/reducers/devices.js | 124 | ||||
-rw-r--r-- | devtools/client/responsive/reducers/moz.build | 12 | ||||
-rw-r--r-- | devtools/client/responsive/reducers/screenshot.js | 38 | ||||
-rw-r--r-- | devtools/client/responsive/reducers/ui.js | 135 | ||||
-rw-r--r-- | devtools/client/responsive/reducers/viewports.js | 212 |
5 files changed, 521 insertions, 0 deletions
diff --git a/devtools/client/responsive/reducers/devices.js b/devtools/client/responsive/reducers/devices.js new file mode 100644 index 0000000000..98f0602175 --- /dev/null +++ b/devtools/client/responsive/reducers/devices.js @@ -0,0 +1,124 @@ +/* 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 { + ADD_DEVICE, + ADD_DEVICE_TYPE, + EDIT_DEVICE, + LOAD_DEVICE_LIST_START, + LOAD_DEVICE_LIST_ERROR, + LOAD_DEVICE_LIST_END, + REMOVE_DEVICE, + UPDATE_DEVICE_DISPLAYED, + UPDATE_DEVICE_MODAL, +} = require("resource://devtools/client/responsive/actions/index.js"); + +const Types = require("resource://devtools/client/responsive/types.js"); + +const INITIAL_DEVICES = { + isModalOpen: false, + listState: Types.loadableState.INITIALIZED, + modalOpenedFromViewport: null, + types: [], +}; + +const reducers = { + [ADD_DEVICE](devices, { device, deviceType }) { + return { + ...devices, + [deviceType]: [...devices[deviceType], device], + }; + }, + + [ADD_DEVICE_TYPE](devices, { deviceType }) { + return { + ...devices, + types: [...devices.types, deviceType], + [deviceType]: [], + }; + }, + + [EDIT_DEVICE](devices, { oldDevice, newDevice, deviceType }) { + const index = devices[deviceType].indexOf(oldDevice); + if (index < 0) { + return devices; + } + + devices[deviceType].splice(index, 1, newDevice); + + return { + ...devices, + [deviceType]: [...devices[deviceType]], + }; + }, + + [UPDATE_DEVICE_DISPLAYED](devices, { device, deviceType, displayed }) { + const newDevices = devices[deviceType].map(d => { + if (d == device) { + d.displayed = displayed; + } + + return d; + }); + + return { + ...devices, + [deviceType]: newDevices, + }; + }, + + [LOAD_DEVICE_LIST_START](devices, action) { + return { + ...devices, + listState: Types.loadableState.LOADING, + }; + }, + + [LOAD_DEVICE_LIST_ERROR](devices, action) { + return { + ...devices, + listState: Types.loadableState.ERROR, + }; + }, + + [LOAD_DEVICE_LIST_END](devices, action) { + return { + ...devices, + listState: Types.loadableState.LOADED, + }; + }, + + [REMOVE_DEVICE](devices, { device, deviceType }) { + const index = devices[deviceType].indexOf(device); + if (index < 0) { + return devices; + } + + const list = [...devices[deviceType]]; + list.splice(index, 1); + + return { + ...devices, + [deviceType]: list, + }; + }, + + [UPDATE_DEVICE_MODAL](devices, { isOpen, modalOpenedFromViewport }) { + return { + ...devices, + isModalOpen: isOpen, + modalOpenedFromViewport, + }; + }, +}; + +module.exports = function (devices = INITIAL_DEVICES, action) { + const reducer = reducers[action.type]; + if (!reducer) { + return devices; + } + return reducer(devices, action); +}; diff --git a/devtools/client/responsive/reducers/moz.build b/devtools/client/responsive/reducers/moz.build new file mode 100644 index 0000000000..9f2fb54e16 --- /dev/null +++ b/devtools/client/responsive/reducers/moz.build @@ -0,0 +1,12 @@ +# -*- Mode: python; 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( + "devices.js", + "screenshot.js", + "ui.js", + "viewports.js", +) diff --git a/devtools/client/responsive/reducers/screenshot.js b/devtools/client/responsive/reducers/screenshot.js new file mode 100644 index 0000000000..67f26f1f9a --- /dev/null +++ b/devtools/client/responsive/reducers/screenshot.js @@ -0,0 +1,38 @@ +/* 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 { + TAKE_SCREENSHOT_END, + TAKE_SCREENSHOT_START, +} = require("resource://devtools/client/responsive/actions/index.js"); + +const INITIAL_SCREENSHOT = { + isCapturing: false, +}; + +const reducers = { + [TAKE_SCREENSHOT_END](screenshot, action) { + return { + ...screenshot, + isCapturing: false, + }; + }, + + [TAKE_SCREENSHOT_START](screenshot, action) { + return { + ...screenshot, + isCapturing: true, + }; + }, +}; + +module.exports = function (screenshot = INITIAL_SCREENSHOT, action) { + const reducer = reducers[action.type]; + if (!reducer) { + return screenshot; + } + return reducer(screenshot, action); +}; diff --git a/devtools/client/responsive/reducers/ui.js b/devtools/client/responsive/reducers/ui.js new file mode 100644 index 0000000000..bf03353bf3 --- /dev/null +++ b/devtools/client/responsive/reducers/ui.js @@ -0,0 +1,135 @@ +/* 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 { + CHANGE_DISPLAY_PIXEL_RATIO, + CHANGE_USER_AGENT, + TOGGLE_LEFT_ALIGNMENT, + TOGGLE_RELOAD_ON_TOUCH_SIMULATION, + TOGGLE_RELOAD_ON_USER_AGENT, + TOGGLE_TOUCH_SIMULATION, + TOGGLE_USER_AGENT_INPUT, +} = require("resource://devtools/client/responsive/actions/index.js"); + +const LEFT_ALIGNMENT_ENABLED = "devtools.responsive.leftAlignViewport.enabled"; +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"; +const USER_AGENT = "devtools.responsive.userAgent"; + +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 + ), + // Whether or not to reload when touch simulation is toggled. + 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 + ), + // The user agent of the viewport. + userAgent: Services.prefs.getCharPref(USER_AGENT, ""), +}; + +const reducers = { + [CHANGE_DISPLAY_PIXEL_RATIO](ui, { displayPixelRatio }) { + return { + ...ui, + displayPixelRatio, + }; + }, + + [CHANGE_USER_AGENT](ui, { userAgent }) { + Services.prefs.setCharPref(USER_AGENT, userAgent); + + return { + ...ui, + userAgent, + }; + }, + + [TOGGLE_LEFT_ALIGNMENT](ui, { enabled }) { + const leftAlignmentEnabled = + enabled !== undefined ? enabled : !ui.leftAlignmentEnabled; + + Services.prefs.setBoolPref(LEFT_ALIGNMENT_ENABLED, leftAlignmentEnabled); + + return { + ...ui, + leftAlignmentEnabled, + }; + }, + + [TOGGLE_RELOAD_ON_TOUCH_SIMULATION](ui, { enabled }) { + const reloadOnTouchSimulation = + enabled !== undefined ? enabled : !ui.reloadOnTouchSimulation; + + Services.prefs.setBoolPref( + RELOAD_ON_TOUCH_SIMULATION, + reloadOnTouchSimulation + ); + + return { + ...ui, + reloadOnTouchSimulation, + }; + }, + + [TOGGLE_RELOAD_ON_USER_AGENT](ui, { enabled }) { + const reloadOnUserAgent = + enabled !== undefined ? enabled : !ui.reloadOnUserAgent; + + Services.prefs.setBoolPref(RELOAD_ON_USER_AGENT, reloadOnUserAgent); + + return { + ...ui, + reloadOnUserAgent, + }; + }, + + [TOGGLE_TOUCH_SIMULATION](ui, { enabled }) { + Services.prefs.setBoolPref(TOUCH_SIMULATION_ENABLED, enabled); + + return { + ...ui, + touchSimulationEnabled: enabled, + }; + }, + + [TOGGLE_USER_AGENT_INPUT](ui, { enabled }) { + const showUserAgentInput = + enabled !== undefined ? enabled : !ui.showUserAgentInput; + + Services.prefs.setBoolPref(SHOW_USER_AGENT_INPUT, showUserAgentInput); + + return { + ...ui, + showUserAgentInput, + }; + }, +}; + +module.exports = function (ui = INITIAL_UI, action) { + const reducer = reducers[action.type]; + if (!reducer) { + return ui; + } + return reducer(ui, action); +}; diff --git a/devtools/client/responsive/reducers/viewports.js b/devtools/client/responsive/reducers/viewports.js new file mode 100644 index 0000000000..71ced90975 --- /dev/null +++ b/devtools/client/responsive/reducers/viewports.js @@ -0,0 +1,212 @@ +/* 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 { + ADD_VIEWPORT, + CHANGE_DEVICE, + CHANGE_PIXEL_RATIO, + CHANGE_VIEWPORT_ANGLE, + EDIT_DEVICE, + REMOVE_DEVICE_ASSOCIATION, + RESIZE_VIEWPORT, + ROTATE_VIEWPORT, + ZOOM_VIEWPORT, +} = require("resource://devtools/client/responsive/actions/index.js"); + +const VIEWPORT_WIDTH_PREF = "devtools.responsive.viewport.width"; +const VIEWPORT_HEIGHT_PREF = "devtools.responsive.viewport.height"; +const VIEWPORT_PIXEL_RATIO_PREF = "devtools.responsive.viewport.pixelRatio"; +const VIEWPORT_ANGLE_PREF = "devtools.responsive.viewport.angle"; + +let nextViewportId = 0; + +const INITIAL_VIEWPORTS = []; +const INITIAL_VIEWPORT = { + id: nextViewportId++, + angle: Services.prefs.getIntPref(VIEWPORT_ANGLE_PREF, 0), + device: "", + deviceType: "", + height: Services.prefs.getIntPref(VIEWPORT_HEIGHT_PREF, 480), + width: Services.prefs.getIntPref(VIEWPORT_WIDTH_PREF, 320), + pixelRatio: Services.prefs.getIntPref(VIEWPORT_PIXEL_RATIO_PREF, 0), + userContextId: 0, + zoom: 1, +}; + +const reducers = { + [ADD_VIEWPORT](viewports, { userContextId }) { + // For the moment, there can be at most one viewport. + if (viewports.length === 1) { + return viewports; + } + + return [ + ...viewports, + { + ...INITIAL_VIEWPORT, + userContextId, + }, + ]; + }, + + [CHANGE_DEVICE](viewports, { id, device, deviceType }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + return { + ...viewport, + device, + deviceType, + }; + }); + }, + + [CHANGE_PIXEL_RATIO](viewports, { id, pixelRatio }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + Services.prefs.setIntPref(VIEWPORT_PIXEL_RATIO_PREF, pixelRatio); + + return { + ...viewport, + pixelRatio, + }; + }); + }, + + [CHANGE_VIEWPORT_ANGLE](viewports, { id, angle }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + Services.prefs.setIntPref(VIEWPORT_ANGLE_PREF, angle); + + return { + ...viewport, + angle, + }; + }); + }, + + [EDIT_DEVICE](viewports, { viewport, newDevice, deviceType }) { + if (!viewport) { + return viewports; + } + + return viewports.map(v => { + if (v.id !== viewport.id) { + return viewport; + } + + 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 + ); + + return { + ...viewport, + device: newDevice.name, + deviceType, + height: newDevice.height, + width: newDevice.width, + pixelRatio: newDevice.pixelRatio, + userAgent: newDevice.userAgent, + touch: newDevice.touch, + }; + }); + }, + + [REMOVE_DEVICE_ASSOCIATION](viewports, { id }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + return { + ...viewport, + device: "", + deviceType: "", + }; + }); + }, + + [RESIZE_VIEWPORT](viewports, { id, width, height }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + if (!height) { + height = viewport.height; + } + + if (!width) { + width = viewport.width; + } + + Services.prefs.setIntPref(VIEWPORT_WIDTH_PREF, width); + Services.prefs.setIntPref(VIEWPORT_HEIGHT_PREF, height); + + return { + ...viewport, + height, + width, + }; + }); + }, + + [ROTATE_VIEWPORT](viewports, { id }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + const height = viewport.width; + const width = viewport.height; + + Services.prefs.setIntPref(VIEWPORT_WIDTH_PREF, width); + Services.prefs.setIntPref(VIEWPORT_HEIGHT_PREF, height); + + return { + ...viewport, + height, + width, + }; + }); + }, + + [ZOOM_VIEWPORT](viewports, { id, zoom }) { + return viewports.map(viewport => { + if (viewport.id !== id) { + return viewport; + } + + if (!zoom) { + zoom = viewport.zoom; + } + + return { + ...viewport, + zoom, + }; + }); + }, +}; + +module.exports = function (viewports = INITIAL_VIEWPORTS, action) { + const reducer = reducers[action.type]; + if (!reducer) { + return viewports; + } + return reducer(viewports, action); +}; |