forked from mirrors/gecko-dev
		
	This will help transition to ES Modules as this symbol is exposed to them.
$ sed -ie "/require(.Services.)/d" $(git grep -l 'require("Services")' devtools/)
$ sed -ie "/loader.lazyRequireGetter(this, .Services./d" $(git grep -l 'loader.lazyRequireGetter(this, "Services"' devtools/)
+ the edition of builtin-modules.js + eslintrc.js
+ manual eslint fixes
+ removal of devtools-services in the debugger, except for jest tests
Differential Revision: https://phabricator.services.mozilla.com/D156401
		
	
			
		
			
				
	
	
		
			445 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			445 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* 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 {
 | 
						|
  createFactory,
 | 
						|
  PureComponent,
 | 
						|
} = require("devtools/client/shared/vendor/react");
 | 
						|
const dom = require("devtools/client/shared/vendor/react-dom-factories");
 | 
						|
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 | 
						|
const { connect } = require("devtools/client/shared/vendor/react-redux");
 | 
						|
 | 
						|
const Toolbar = createFactory(
 | 
						|
  require("devtools/client/responsive/components/Toolbar")
 | 
						|
);
 | 
						|
 | 
						|
loader.lazyGetter(this, "DeviceModal", () =>
 | 
						|
  createFactory(require("devtools/client/responsive/components/DeviceModal"))
 | 
						|
);
 | 
						|
 | 
						|
const {
 | 
						|
  changeNetworkThrottling,
 | 
						|
} = require("devtools/client/shared/components/throttling/actions");
 | 
						|
const {
 | 
						|
  addCustomDevice,
 | 
						|
  editCustomDevice,
 | 
						|
  removeCustomDevice,
 | 
						|
  updateDeviceDisplayed,
 | 
						|
  updateDeviceModal,
 | 
						|
  updatePreferredDevices,
 | 
						|
} = require("devtools/client/responsive/actions/devices");
 | 
						|
const {
 | 
						|
  takeScreenshot,
 | 
						|
} = require("devtools/client/responsive/actions/screenshot");
 | 
						|
const {
 | 
						|
  changeUserAgent,
 | 
						|
  toggleLeftAlignment,
 | 
						|
  toggleReloadOnTouchSimulation,
 | 
						|
  toggleReloadOnUserAgent,
 | 
						|
  toggleTouchSimulation,
 | 
						|
  toggleUserAgentInput,
 | 
						|
} = require("devtools/client/responsive/actions/ui");
 | 
						|
const {
 | 
						|
  changeDevice,
 | 
						|
  changePixelRatio,
 | 
						|
  changeViewportAngle,
 | 
						|
  removeDeviceAssociation,
 | 
						|
  resizeViewport,
 | 
						|
  rotateViewport,
 | 
						|
} = require("devtools/client/responsive/actions/viewports");
 | 
						|
const {
 | 
						|
  getOrientation,
 | 
						|
} = require("devtools/client/responsive/utils/orientation");
 | 
						|
 | 
						|
const Types = require("devtools/client/responsive/types");
 | 
						|
 | 
						|
class App extends PureComponent {
 | 
						|
  static get propTypes() {
 | 
						|
    return {
 | 
						|
      devices: PropTypes.shape(Types.devices).isRequired,
 | 
						|
      dispatch: PropTypes.func.isRequired,
 | 
						|
      leftAlignmentEnabled: PropTypes.bool.isRequired,
 | 
						|
      networkThrottling: PropTypes.shape(Types.networkThrottling).isRequired,
 | 
						|
      screenshot: PropTypes.shape(Types.screenshot).isRequired,
 | 
						|
      viewports: PropTypes.arrayOf(PropTypes.shape(Types.viewport)).isRequired,
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  constructor(props) {
 | 
						|
    super(props);
 | 
						|
 | 
						|
    this.onAddCustomDevice = this.onAddCustomDevice.bind(this);
 | 
						|
    this.onBrowserContextMenu = this.onBrowserContextMenu.bind(this);
 | 
						|
    this.onChangeDevice = this.onChangeDevice.bind(this);
 | 
						|
    this.onChangeNetworkThrottling = this.onChangeNetworkThrottling.bind(this);
 | 
						|
    this.onChangePixelRatio = this.onChangePixelRatio.bind(this);
 | 
						|
    this.onChangeTouchSimulation = this.onChangeTouchSimulation.bind(this);
 | 
						|
    this.onChangeUserAgent = this.onChangeUserAgent.bind(this);
 | 
						|
    this.onChangeViewportOrientation = this.onChangeViewportOrientation.bind(
 | 
						|
      this
 | 
						|
    );
 | 
						|
    this.onDeviceListUpdate = this.onDeviceListUpdate.bind(this);
 | 
						|
    this.onEditCustomDevice = this.onEditCustomDevice.bind(this);
 | 
						|
    this.onExit = this.onExit.bind(this);
 | 
						|
    this.onRemoveCustomDevice = this.onRemoveCustomDevice.bind(this);
 | 
						|
    this.onRemoveDeviceAssociation = this.onRemoveDeviceAssociation.bind(this);
 | 
						|
    this.doResizeViewport = this.doResizeViewport.bind(this);
 | 
						|
    this.onRotateViewport = this.onRotateViewport.bind(this);
 | 
						|
    this.onScreenshot = this.onScreenshot.bind(this);
 | 
						|
    this.onToggleLeftAlignment = this.onToggleLeftAlignment.bind(this);
 | 
						|
    this.onToggleReloadOnTouchSimulation = this.onToggleReloadOnTouchSimulation.bind(
 | 
						|
      this
 | 
						|
    );
 | 
						|
    this.onToggleReloadOnUserAgent = this.onToggleReloadOnUserAgent.bind(this);
 | 
						|
    this.onToggleUserAgentInput = this.onToggleUserAgentInput.bind(this);
 | 
						|
    this.onUpdateDeviceDisplayed = this.onUpdateDeviceDisplayed.bind(this);
 | 
						|
    this.onUpdateDeviceModal = this.onUpdateDeviceModal.bind(this);
 | 
						|
  }
 | 
						|
 | 
						|
  componentWillUnmount() {
 | 
						|
    this.browser.removeEventListener("contextmenu", this.onContextMenu);
 | 
						|
    this.browser = null;
 | 
						|
  }
 | 
						|
 | 
						|
  onAddCustomDevice(device) {
 | 
						|
    this.props.dispatch(addCustomDevice(device));
 | 
						|
  }
 | 
						|
 | 
						|
  onBrowserContextMenu() {
 | 
						|
    // Update the position of remote browser so that makes the context menu to show at
 | 
						|
    // proper position before showing.
 | 
						|
    this.browser.frameLoader.requestUpdatePosition();
 | 
						|
  }
 | 
						|
 | 
						|
  onChangeDevice(id, device, deviceType) {
 | 
						|
    // Resize the viewport first.
 | 
						|
    this.doResizeViewport(id, device.width, device.height);
 | 
						|
 | 
						|
    // TODO: Bug 1332754: Move messaging and logic into the action creator so that the
 | 
						|
    // message is sent from the action creator and device property changes are sent from
 | 
						|
    // there instead of this function.
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "change-device",
 | 
						|
        device,
 | 
						|
        viewport: device,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
 | 
						|
    const orientation = getOrientation(device, device);
 | 
						|
 | 
						|
    this.props.dispatch(changeViewportAngle(0, orientation.angle));
 | 
						|
    this.props.dispatch(changeDevice(id, device.name, deviceType));
 | 
						|
    this.props.dispatch(changePixelRatio(id, device.pixelRatio));
 | 
						|
    this.props.dispatch(changeUserAgent(device.userAgent));
 | 
						|
    this.props.dispatch(toggleTouchSimulation(device.touch));
 | 
						|
  }
 | 
						|
 | 
						|
  onChangeNetworkThrottling(enabled, profile) {
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "change-network-throttling",
 | 
						|
        enabled,
 | 
						|
        profile,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
    this.props.dispatch(changeNetworkThrottling(enabled, profile));
 | 
						|
  }
 | 
						|
 | 
						|
  onChangePixelRatio(pixelRatio) {
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "change-pixel-ratio",
 | 
						|
        pixelRatio,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
    this.props.dispatch(changePixelRatio(0, pixelRatio));
 | 
						|
  }
 | 
						|
 | 
						|
  onChangeTouchSimulation(enabled) {
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "change-touch-simulation",
 | 
						|
        enabled,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
    this.props.dispatch(toggleTouchSimulation(enabled));
 | 
						|
  }
 | 
						|
 | 
						|
  onChangeUserAgent(userAgent) {
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "change-user-agent",
 | 
						|
        userAgent,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
    this.props.dispatch(changeUserAgent(userAgent));
 | 
						|
  }
 | 
						|
 | 
						|
  onChangeViewportOrientation(id, type, angle, isViewportRotated = false) {
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "viewport-orientation-change",
 | 
						|
        orientationType: type,
 | 
						|
        angle,
 | 
						|
        isViewportRotated,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
 | 
						|
    if (isViewportRotated) {
 | 
						|
      this.props.dispatch(changeViewportAngle(id, angle));
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  onDeviceListUpdate(devices) {
 | 
						|
    updatePreferredDevices(devices);
 | 
						|
  }
 | 
						|
 | 
						|
  onEditCustomDevice(oldDevice, newDevice) {
 | 
						|
    // If the edited device is currently selected, then update its original association
 | 
						|
    // and reset UI state.
 | 
						|
    let viewport = this.props.viewports.find(
 | 
						|
      ({ device }) => device === oldDevice.name
 | 
						|
    );
 | 
						|
 | 
						|
    if (viewport) {
 | 
						|
      viewport = {
 | 
						|
        ...viewport,
 | 
						|
        device: newDevice.name,
 | 
						|
        deviceType: "custom",
 | 
						|
        height: newDevice.height,
 | 
						|
        width: newDevice.width,
 | 
						|
        pixelRatio: newDevice.pixelRatio,
 | 
						|
        touch: newDevice.touch,
 | 
						|
        userAgent: newDevice.userAgent,
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    this.props.dispatch(editCustomDevice(viewport, oldDevice, newDevice));
 | 
						|
  }
 | 
						|
 | 
						|
  onExit() {
 | 
						|
    window.postMessage({ type: "exit" }, "*");
 | 
						|
  }
 | 
						|
 | 
						|
  onRemoveCustomDevice(device) {
 | 
						|
    // If the custom device is currently selected on any of the viewports,
 | 
						|
    // remove the device association and reset all the ui state.
 | 
						|
    for (const viewport of this.props.viewports) {
 | 
						|
      if (viewport.device === device.name) {
 | 
						|
        this.onRemoveDeviceAssociation(viewport.id);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    this.props.dispatch(removeCustomDevice(device));
 | 
						|
  }
 | 
						|
 | 
						|
  onRemoveDeviceAssociation(id) {
 | 
						|
    // TODO: Bug 1332754: Move messaging and logic into the action creator so that device
 | 
						|
    // property changes are sent from there instead of this function.
 | 
						|
    this.props.dispatch(removeDeviceAssociation(id));
 | 
						|
    this.props.dispatch(toggleTouchSimulation(false));
 | 
						|
    this.props.dispatch(changePixelRatio(id, 0));
 | 
						|
    this.props.dispatch(changeUserAgent(""));
 | 
						|
  }
 | 
						|
 | 
						|
  doResizeViewport(id, width, height) {
 | 
						|
    // This is the setter function that we pass to Toolbar and Viewports
 | 
						|
    // so they can modify the viewport.
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "viewport-resize",
 | 
						|
        width,
 | 
						|
        height,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
    this.props.dispatch(resizeViewport(id, width, height));
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
   * Dispatches the rotateViewport action creator. This utilized by the RDM toolbar as
 | 
						|
   * a prop.
 | 
						|
   *
 | 
						|
   * @param {Number} id
 | 
						|
   *        The viewport ID.
 | 
						|
   */
 | 
						|
  onRotateViewport(id) {
 | 
						|
    let currentDevice;
 | 
						|
    const viewport = this.props.viewports[id];
 | 
						|
 | 
						|
    for (const type of this.props.devices.types) {
 | 
						|
      for (const device of this.props.devices[type]) {
 | 
						|
        if (viewport.device === device.name) {
 | 
						|
          currentDevice = device;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    // If no device is selected, then assume the selected device's primary orientation is
 | 
						|
    // opposite of the viewport orientation.
 | 
						|
    if (!currentDevice) {
 | 
						|
      currentDevice = {
 | 
						|
        height: viewport.width,
 | 
						|
        width: viewport.height,
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
    const currentAngle = Services.prefs.getIntPref(
 | 
						|
      "devtools.responsive.viewport.angle"
 | 
						|
    );
 | 
						|
    const angleToRotateTo = currentAngle === 90 ? 0 : 90;
 | 
						|
    const { type, angle } = getOrientation(
 | 
						|
      currentDevice,
 | 
						|
      viewport,
 | 
						|
      angleToRotateTo
 | 
						|
    );
 | 
						|
 | 
						|
    this.onChangeViewportOrientation(id, type, angle, true);
 | 
						|
    this.props.dispatch(rotateViewport(id));
 | 
						|
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "viewport-resize",
 | 
						|
        height: viewport.width,
 | 
						|
        width: viewport.height,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  onScreenshot() {
 | 
						|
    this.props.dispatch(takeScreenshot());
 | 
						|
  }
 | 
						|
 | 
						|
  onToggleLeftAlignment() {
 | 
						|
    this.props.dispatch(toggleLeftAlignment());
 | 
						|
 | 
						|
    window.postMessage(
 | 
						|
      {
 | 
						|
        type: "toggle-left-alignment",
 | 
						|
        leftAlignmentEnabled: this.props.leftAlignmentEnabled,
 | 
						|
      },
 | 
						|
      "*"
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  onToggleReloadOnTouchSimulation() {
 | 
						|
    this.props.dispatch(toggleReloadOnTouchSimulation());
 | 
						|
  }
 | 
						|
 | 
						|
  onToggleReloadOnUserAgent() {
 | 
						|
    this.props.dispatch(toggleReloadOnUserAgent());
 | 
						|
  }
 | 
						|
 | 
						|
  onToggleUserAgentInput() {
 | 
						|
    this.props.dispatch(toggleUserAgentInput());
 | 
						|
  }
 | 
						|
 | 
						|
  onUpdateDeviceDisplayed(device, deviceType, displayed) {
 | 
						|
    this.props.dispatch(updateDeviceDisplayed(device, deviceType, displayed));
 | 
						|
  }
 | 
						|
 | 
						|
  onUpdateDeviceModal(isOpen, modalOpenedFromViewport) {
 | 
						|
    this.props.dispatch(updateDeviceModal(isOpen, modalOpenedFromViewport));
 | 
						|
    window.postMessage({ type: "update-device-modal", isOpen }, "*");
 | 
						|
  }
 | 
						|
 | 
						|
  render() {
 | 
						|
    const { devices, networkThrottling, screenshot, viewports } = this.props;
 | 
						|
 | 
						|
    const {
 | 
						|
      onAddCustomDevice,
 | 
						|
      onChangeDevice,
 | 
						|
      onChangeNetworkThrottling,
 | 
						|
      onChangePixelRatio,
 | 
						|
      onChangeTouchSimulation,
 | 
						|
      onChangeUserAgent,
 | 
						|
      onDeviceListUpdate,
 | 
						|
      onEditCustomDevice,
 | 
						|
      onExit,
 | 
						|
      onRemoveCustomDevice,
 | 
						|
      onRemoveDeviceAssociation,
 | 
						|
      doResizeViewport,
 | 
						|
      onRotateViewport,
 | 
						|
      onScreenshot,
 | 
						|
      onToggleLeftAlignment,
 | 
						|
      onToggleReloadOnTouchSimulation,
 | 
						|
      onToggleReloadOnUserAgent,
 | 
						|
      onToggleUserAgentInput,
 | 
						|
      onUpdateDeviceDisplayed,
 | 
						|
      onUpdateDeviceModal,
 | 
						|
    } = this;
 | 
						|
 | 
						|
    if (!viewports.length) {
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    const selectedDevice = viewports[0].device;
 | 
						|
    const selectedPixelRatio = viewports[0].pixelRatio;
 | 
						|
 | 
						|
    let deviceAdderViewportTemplate = {};
 | 
						|
    if (devices.modalOpenedFromViewport !== null) {
 | 
						|
      deviceAdderViewportTemplate = viewports[devices.modalOpenedFromViewport];
 | 
						|
    }
 | 
						|
 | 
						|
    return dom.div(
 | 
						|
      { id: "app" },
 | 
						|
      Toolbar({
 | 
						|
        devices,
 | 
						|
        networkThrottling,
 | 
						|
        screenshot,
 | 
						|
        selectedDevice,
 | 
						|
        selectedPixelRatio,
 | 
						|
        viewport: viewports[0],
 | 
						|
        onChangeDevice,
 | 
						|
        onChangeNetworkThrottling,
 | 
						|
        onChangePixelRatio,
 | 
						|
        onChangeTouchSimulation,
 | 
						|
        onChangeUserAgent,
 | 
						|
        onExit,
 | 
						|
        onRemoveDeviceAssociation,
 | 
						|
        doResizeViewport,
 | 
						|
        onRotateViewport,
 | 
						|
        onScreenshot,
 | 
						|
        onToggleLeftAlignment,
 | 
						|
        onToggleReloadOnTouchSimulation,
 | 
						|
        onToggleReloadOnUserAgent,
 | 
						|
        onToggleUserAgentInput,
 | 
						|
        onUpdateDeviceModal,
 | 
						|
      }),
 | 
						|
      devices.isModalOpen
 | 
						|
        ? DeviceModal({
 | 
						|
            deviceAdderViewportTemplate,
 | 
						|
            devices,
 | 
						|
            onAddCustomDevice,
 | 
						|
            onDeviceListUpdate,
 | 
						|
            onEditCustomDevice,
 | 
						|
            onRemoveCustomDevice,
 | 
						|
            onUpdateDeviceDisplayed,
 | 
						|
            onUpdateDeviceModal,
 | 
						|
          })
 | 
						|
        : null
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
const mapStateToProps = state => {
 | 
						|
  return {
 | 
						|
    ...state,
 | 
						|
    leftAlignmentEnabled: state.ui.leftAlignmentEnabled,
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
module.exports = connect(mapStateToProps)(App);
 |