diff options
Diffstat (limited to 'devtools/client/responsive.html/actions')
9 files changed, 482 insertions, 0 deletions
diff --git a/devtools/client/responsive.html/actions/devices.js b/devtools/client/responsive.html/actions/devices.js new file mode 100644 index 000000000..b06134450 --- /dev/null +++ b/devtools/client/responsive.html/actions/devices.js @@ -0,0 +1,138 @@ +/* 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, + LOAD_DEVICE_LIST_START, + LOAD_DEVICE_LIST_ERROR, + LOAD_DEVICE_LIST_END, + UPDATE_DEVICE_DISPLAYED, + UPDATE_DEVICE_MODAL_OPEN, +} = require("./index"); + +const { getDevices } = require("devtools/client/shared/devices"); + +const Services = require("Services"); +const DISPLAYED_DEVICES_PREF = "devtools.responsive.html.displayedDeviceList"; + +/** + * Returns an object containing the user preference of displayed devices. + * + * @return {Object} containing two Sets: + * - added: Names of the devices that were explicitly enabled by the user + * - removed: Names of the devices that were explicitly removed by the user + */ +function loadPreferredDevices() { + let preferredDevices = { + "added": new Set(), + "removed": new Set(), + }; + + if (Services.prefs.prefHasUserValue(DISPLAYED_DEVICES_PREF)) { + try { + let savedData = Services.prefs.getCharPref(DISPLAYED_DEVICES_PREF); + savedData = JSON.parse(savedData); + if (savedData.added && savedData.removed) { + preferredDevices.added = new Set(savedData.added); + preferredDevices.removed = new Set(savedData.removed); + } + } catch (e) { + console.error(e); + } + } + + return preferredDevices; +} + +/** + * Update the displayed device list preference with the given device list. + * + * @param {Object} containing two Sets: + * - added: Names of the devices that were explicitly enabled by the user + * - removed: Names of the devices that were explicitly removed by the user + */ +function updatePreferredDevices(devices) { + let devicesToSave = { + added: Array.from(devices.added), + removed: Array.from(devices.removed), + }; + devicesToSave = JSON.stringify(devicesToSave); + Services.prefs.setCharPref(DISPLAYED_DEVICES_PREF, devicesToSave); +} + +module.exports = { + + // This function is only exported for testing purposes + _loadPreferredDevices: loadPreferredDevices, + + updatePreferredDevices: updatePreferredDevices, + + addDevice(device, deviceType) { + return { + type: ADD_DEVICE, + device, + deviceType, + }; + }, + + addDeviceType(deviceType) { + return { + type: ADD_DEVICE_TYPE, + deviceType, + }; + }, + + updateDeviceDisplayed(device, deviceType, displayed) { + return { + type: UPDATE_DEVICE_DISPLAYED, + device, + deviceType, + displayed, + }; + }, + + loadDevices() { + return function* (dispatch, getState) { + yield dispatch({ type: LOAD_DEVICE_LIST_START }); + let preferredDevices = loadPreferredDevices(); + let devices; + + try { + devices = yield getDevices(); + } catch (e) { + console.error("Could not load device list: " + e); + dispatch({ type: LOAD_DEVICE_LIST_ERROR }); + return; + } + + for (let type of devices.TYPES) { + dispatch(module.exports.addDeviceType(type)); + for (let device of devices[type]) { + if (device.os == "fxos") { + continue; + } + + let newDevice = Object.assign({}, device, { + displayed: preferredDevices.added.has(device.name) || + (device.featured && !(preferredDevices.removed.has(device.name))), + }); + + dispatch(module.exports.addDevice(newDevice, type)); + } + } + dispatch({ type: LOAD_DEVICE_LIST_END }); + }; + }, + + updateDeviceModalOpen(isOpen) { + return { + type: UPDATE_DEVICE_MODAL_OPEN, + isOpen, + }; + }, + +}; diff --git a/devtools/client/responsive.html/actions/display-pixel-ratio.js b/devtools/client/responsive.html/actions/display-pixel-ratio.js new file mode 100644 index 000000000..ff3343bb5 --- /dev/null +++ b/devtools/client/responsive.html/actions/display-pixel-ratio.js @@ -0,0 +1,23 @@ +/* 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 } = 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 + * display with a different pixel ratio. + */ + changeDisplayPixelRatio(displayPixelRatio) { + return { + type: CHANGE_DISPLAY_PIXEL_RATIO, + displayPixelRatio, + }; + }, + +}; diff --git a/devtools/client/responsive.html/actions/index.js b/devtools/client/responsive.html/actions/index.js new file mode 100644 index 000000000..06cc8d1a5 --- /dev/null +++ b/devtools/client/responsive.html/actions/index.js @@ -0,0 +1,77 @@ +/* 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"; + +// This file lists all of the actions available in responsive design. This +// central list of constants makes it easy to see all possible action names at +// a glance. Please add a comment with each new action type. + +const { createEnum } = require("../utils/enum"); + +createEnum([ + + // Add a new device. + "ADD_DEVICE", + + // Add a new device type. + "ADD_DEVICE_TYPE", + + // Add an additional viewport to display the document. + "ADD_VIEWPORT", + + // 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", + + // 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", + + // 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 DPR dropdown. + "CHANGE_PIXEL_RATIO", + + // Change the touch simulation state. + "CHANGE_TOUCH_SIMULATION", + + // 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 has been loaded successfully + "LOAD_DEVICE_LIST_END", + + // Remove the viewport's device assocation. + "REMOVE_DEVICE", + + // Resize the viewport. + "RESIZE_VIEWPORT", + + // Rotate the viewport. + "ROTATE_VIEWPORT", + + // Take a screenshot of the viewport. + "TAKE_SCREENSHOT_START", + + // Indicates when the screenshot action ends. + "TAKE_SCREENSHOT_END", + + // Update the device display state in the device selector. + "UPDATE_DEVICE_DISPLAYED", + + // Update the device modal open state. + "UPDATE_DEVICE_MODAL_OPEN", + +], module.exports); diff --git a/devtools/client/responsive.html/actions/location.js b/devtools/client/responsive.html/actions/location.js new file mode 100644 index 000000000..565825e5e --- /dev/null +++ b/devtools/client/responsive.html/actions/location.js @@ -0,0 +1,22 @@ +/* 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_LOCATION } = require("./index"); + +module.exports = { + + /** + * The location of the page has changed. This may be triggered by the user + * directly entering a new URL, navigating with links, etc. + */ + changeLocation(location) { + return { + type: CHANGE_LOCATION, + location, + }; + }, + +}; diff --git a/devtools/client/responsive.html/actions/moz.build b/devtools/client/responsive.html/actions/moz.build new file mode 100644 index 000000000..8f44c7118 --- /dev/null +++ b/devtools/client/responsive.html/actions/moz.build @@ -0,0 +1,16 @@ +# -*- 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', + 'display-pixel-ratio.js', + 'index.js', + 'location.js', + 'network-throttling.js', + 'screenshot.js', + 'touch-simulation.js', + 'viewports.js', +) diff --git a/devtools/client/responsive.html/actions/network-throttling.js b/devtools/client/responsive.html/actions/network-throttling.js new file mode 100644 index 000000000..e92fb995c --- /dev/null +++ b/devtools/client/responsive.html/actions/network-throttling.js @@ -0,0 +1,21 @@ +/* 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_NETWORK_THROTTLING, +} = require("./index"); + +module.exports = { + + changeNetworkThrottling(enabled, profile) { + return { + type: CHANGE_NETWORK_THROTTLING, + enabled, + profile, + }; + }, + +}; diff --git a/devtools/client/responsive.html/actions/screenshot.js b/devtools/client/responsive.html/actions/screenshot.js new file mode 100644 index 000000000..8d660d74f --- /dev/null +++ b/devtools/client/responsive.html/actions/screenshot.js @@ -0,0 +1,82 @@ +/* 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/. */ + +/* eslint-env browser */ + +"use strict"; + +const { + TAKE_SCREENSHOT_START, + TAKE_SCREENSHOT_END, +} = require("./index"); + +const { getFormatStr } = require("../utils/l10n"); +const { getToplevelWindow } = require("sdk/window/utils"); +const { Task: { spawn } } = require("devtools/shared/task"); +const e10s = require("../utils/e10s"); + +const CAMERA_AUDIO_URL = "resource://devtools/client/themes/audio/shutter.wav"; + +const animationFrame = () => new Promise(resolve => { + window.requestAnimationFrame(resolve); +}); + +function getFileName() { + let date = new Date(); + let month = ("0" + (date.getMonth() + 1)).substr(-2); + let day = ("0" + date.getDate()).substr(-2); + let dateString = [date.getFullYear(), month, day].join("-"); + let timeString = date.toTimeString().replace(/:/g, ".").split(" ")[0]; + + return getFormatStr("responsive.screenshotGeneratedFilename", dateString, + timeString); +} + +function createScreenshotFor(node) { + let mm = node.frameLoader.messageManager; + + return e10s.request(mm, "RequestScreenshot"); +} + +function saveToFile(data, filename) { + return spawn(function* () { + const chromeWindow = getToplevelWindow(window); + const chromeDocument = chromeWindow.document; + + // append .png extension to filename if it doesn't exist + filename = filename.replace(/\.png$|$/i, ".png"); + + chromeWindow.saveURL(data, filename, null, + true, true, + chromeDocument.documentURIObject, chromeDocument); + }); +} + +function simulateCameraEffects(node) { + let cameraAudio = new window.Audio(CAMERA_AUDIO_URL); + cameraAudio.play(); + node.animate({ opacity: [ 0, 1 ] }, 500); +} + +module.exports = { + + takeScreenshot() { + return function* (dispatch, getState) { + yield dispatch({ type: TAKE_SCREENSHOT_START }); + + // Waiting the next repaint, to ensure the react components + // can be properly render after the action dispatched above + yield animationFrame(); + + let iframe = document.querySelector("iframe"); + let data = yield createScreenshotFor(iframe); + + simulateCameraEffects(iframe); + + yield saveToFile(data, getFileName()); + + dispatch({ type: TAKE_SCREENSHOT_END }); + }; + } +}; diff --git a/devtools/client/responsive.html/actions/touch-simulation.js b/devtools/client/responsive.html/actions/touch-simulation.js new file mode 100644 index 000000000..8f98101e7 --- /dev/null +++ b/devtools/client/responsive.html/actions/touch-simulation.js @@ -0,0 +1,22 @@ +/* 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/. */ + +/* eslint-env browser */ + +"use strict"; + +const { + CHANGE_TOUCH_SIMULATION +} = require("./index"); + +module.exports = { + + changeTouchSimulation(enabled) { + return { + type: CHANGE_TOUCH_SIMULATION, + enabled, + }; + }, + +}; diff --git a/devtools/client/responsive.html/actions/viewports.js b/devtools/client/responsive.html/actions/viewports.js new file mode 100644 index 000000000..7e51ada4a --- /dev/null +++ b/devtools/client/responsive.html/actions/viewports.js @@ -0,0 +1,81 @@ +/* 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, + REMOVE_DEVICE, + RESIZE_VIEWPORT, + ROTATE_VIEWPORT +} = require("./index"); + +module.exports = { + + /** + * Add an additional viewport to display the document. + */ + addViewport() { + return { + type: ADD_VIEWPORT, + }; + }, + + /** + * Change the viewport device. + */ + changeDevice(id, device) { + return { + type: CHANGE_DEVICE, + id, + device, + }; + }, + + /** + * Change the viewport pixel ratio. + */ + changePixelRatio(id, pixelRatio = 0) { + return { + type: CHANGE_PIXEL_RATIO, + id, + pixelRatio, + }; + }, + + /** + * Remove the viewport's device assocation. + */ + removeDevice(id) { + return { + type: REMOVE_DEVICE, + id, + }; + }, + + /** + * Resize the viewport. + */ + resizeViewport(id, width, height) { + return { + type: RESIZE_VIEWPORT, + id, + width, + height, + }; + }, + + /** + * Rotate the viewport. + */ + rotateViewport(id) { + return { + type: ROTATE_VIEWPORT, + id, + }; + }, + +}; |