summaryrefslogtreecommitdiffstats
path: root/devtools/client/responsive.html/actions
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/responsive.html/actions')
-rw-r--r--devtools/client/responsive.html/actions/devices.js138
-rw-r--r--devtools/client/responsive.html/actions/display-pixel-ratio.js23
-rw-r--r--devtools/client/responsive.html/actions/index.js77
-rw-r--r--devtools/client/responsive.html/actions/location.js22
-rw-r--r--devtools/client/responsive.html/actions/moz.build16
-rw-r--r--devtools/client/responsive.html/actions/network-throttling.js21
-rw-r--r--devtools/client/responsive.html/actions/screenshot.js82
-rw-r--r--devtools/client/responsive.html/actions/touch-simulation.js22
-rw-r--r--devtools/client/responsive.html/actions/viewports.js81
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,
+ };
+ },
+
+};