text: // Copyright 2015 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  /**
   * @constructor
   * @extends {WebInspector.VBox}
   */
  WebInspector.DevicesSettingsTab = function()
  {
      WebInspector.VBox.call(this);
      this.element.classList.add("settings-tab-container");
      this.element.classList.add("devices-settings-tab");
      this.registerRequiredCSS("emulation/devicesSettingsTab.css");
  
      var header = this.element.createChild("header");
      header.createChild("h3").createTextChild(WebInspector.UIString("Devices"));
      this.containerElement = this.element.createChild("div", "help-container-wrapper").createChild("div", "settings-tab help-content help-container");
  
      this.containerElement.createChild("div", "devices-title").textContent = WebInspector.UIString("Emulated devices");
      this._devicesList = this.containerElement.createChild("div", "devices-list");
      this._customListSearator = createElementWithClass("div", "devices-custom-separator");
  
      var buttonsRow = this.containerElement.createChild("div", "devices-button-row");
      this._addCustomButton = createTextButton(WebInspector.UIString("Add custom device..."), this._addCustomDevice.bind(this));
      buttonsRow.appendChild(this._addCustomButton);
      this._updateStandardButton = createTextButton("", this._updateStandardDevices.bind(this));
      if (Runtime.experiments.isEnabled("externalDeviceList"))
          buttonsRow.appendChild(this._updateStandardButton);
  
      this._editDevice = null;
      this._editDeviceListItem = null;
      this._createEditDeviceElement();
  
      this._muteUpdate = false;
      WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.CustomDevicesUpdated, this._devicesUpdated, this);
      WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.StandardDevicesUpdated, this._devicesUpdated, this);
      WebInspector.emulatedDevicesList.addEventListener(WebInspector.EmulatedDevicesList.Events.IsUpdatingChanged, this._isUpdatingChanged, this);
  }
  
  WebInspector.DevicesSettingsTab.prototype = {
      wasShown: function()
      {
          WebInspector.VBox.prototype.wasShown.call(this);
          this._devicesUpdated();
          this._isUpdatingChanged();
          this._stopEditing();
      },
  
      _devicesUpdated: function()
      {
          if (this._muteUpdate)
              return;
  
          this._devicesList.removeChildren();
  
          var devices = WebInspector.emulatedDevicesList.custom().slice();
          devices.sort(WebInspector.EmulatedDevice.compareByTitle);
          for (var i = 0; i < devices.length; ++i)
              this._devicesList.appendChild(this._createDeviceListItem(devices[i], true));
  
          this._devicesList.appendChild(this._customListSearator);
          this._updateSeparatorVisibility();
  
          devices = WebInspector.emulatedDevicesList.standard().slice();
          devices.sort(WebInspector.EmulatedDevice.compareByTitle);
          for (var i = 0; i < devices.length; ++i)
              this._devicesList.appendChild(this._createDeviceListItem(devices[i], false));
      },
  
      _isUpdatingChanged: function()
      {
          if (WebInspector.emulatedDevicesList.isUpdating()) {
              this._updateStandardButton.textContent = WebInspector.UIString("Updating...");
              this._updateStandardButton.disabled = true;
          } else {
              this._updateStandardButton.textContent = WebInspector.UIString("Update devices");
              this._updateStandardButton.disabled = false;
          }
      },
  
      _updateSeparatorVisibility: function()
      {
          this._customListSearator.classList.toggle("hidden", this._devicesList.firstChild === this._customListSearator);
      },
  
      /**
       * @param {boolean} custom
       */
      _muteAndSaveDeviceList: function(custom)
      {
          this._muteUpdate = true;
          if (custom)
              WebInspector.emulatedDevicesList.saveCustomDevices();
          else
              WebInspector.emulatedDevicesList.saveStandardDevices();
          this._muteUpdate = false;
      },
  
      /**
       * @param {!WebInspector.EmulatedDevice} device
       * @param {boolean} custom
       * @return {!Element}
       */
      _createDeviceListItem: function(device, custom)
      {
          var item = createElementWithClass("div", "devices-list-item");
          var checkbox = item.createChild("input", "devices-list-checkbox");
          checkbox.type = "checkbox";
          checkbox.checked = device.show();
          item.createChild("div", "devices-list-title").textContent = device.title;
          item.addEventListener("click", onItemClicked.bind(this), false);
          item.classList.toggle("device-list-item-show", device.show());
  
          if (custom) {
              var editButton = item.createChild("div", "devices-list-edit");
              editButton.title = WebInspector.UIString("Edit");
              editButton.addEventListener("click", onEditClicked.bind(this), false);
  
              var removeButton = item.createChild("div", "devices-list-remove");
              removeButton.title = WebInspector.UIString("Remove");
              removeButton.addEventListener("click", onRemoveClicked, false);
          }
  
          /**
           * @param {!Event} event
           * @this {WebInspector.DevicesSettingsTab}
           */
          function onItemClicked(event)
          {
              var show = !checkbox.checked;
              device.setShow(show);
              this._muteAndSaveDeviceList(custom);
              checkbox.checked = show;
              item.classList.toggle("device-list-item-show", show);
              event.consume();
          }
  
          /**
           * @param {!Event} event
           * @this {WebInspector.DevicesSettingsTab}
           */
          function onEditClicked(event)
          {
              event.consume();
              this._startEditing(device, item);
          }
  
          /**
           * @param {!Event} event
           */
          function onRemoveClicked(event)
          {
              WebInspector.emulatedDevicesList.removeCustomDevice(device);
              event.consume();
          }
  
          return item;
      },
  
      _addCustomDevice: function()
      {
          this._startEditing(new WebInspector.EmulatedDevice(), null);
      },
  
      _createEditDeviceElement: function()
      {
          this._editDeviceElement = createElementWithClass("div", "devices-edit-container");
          this._editDeviceElement.addEventListener("keydown", onKeyDown.bind(null, isEscKey, this._stopEditing.bind(this)), false);
          this._editDeviceElement.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, this._editDeviceCommitClicked.bind(this)), false);
          this._editDeviceCheckbox = this._editDeviceElement.createChild("input", "devices-edit-checkbox");
          this._editDeviceCheckbox.type = "checkbox";
          var fields = this._editDeviceElement.createChild("div", "devices-edit-fields");
  
          this._editDeviceTitle = this._createInput(WebInspector.UIString("Device name"));
          fields.appendChild(this._editDeviceTitle);
  
          var screen = fields.createChild("div", "hbox");
          this._editDeviceWidth = this._createInput(WebInspector.UIString("Width"), "120px");
          screen.appendChild(this._editDeviceWidth);
          this._editDeviceHeight = this._createInput(WebInspector.UIString("Height"), "120px");
          screen.appendChild(this._editDeviceHeight);
          this._editDeviceScale = this._createInput(WebInspector.UIString("Device pixel ratio"));
          screen.appendChild(this._editDeviceScale);
  
          this._editDeviceUserAgent = this._createInput(WebInspector.UIString("User agent string"));
          fields.appendChild(this._editDeviceUserAgent);
  
          var buttonsRow = fields.createChild("div", "devices-edit-buttons");
          this._editDeviceCommitButton = createTextButton("", this._editDeviceCommitClicked.bind(this));
          buttonsRow.appendChild(this._editDeviceCommitButton);
          this._editDeviceCancelButton = createTextButton(WebInspector.UIString("Cancel"), this._stopEditing.bind(this));
          this._editDeviceCancelButton.addEventListener("keydown", onKeyDown.bind(null, isEnterKey, this._stopEditing.bind(this)), false);
          buttonsRow.appendChild(this._editDeviceCancelButton);
  
          /**
           * @param {function(!Event):boolean} predicate
           * @param {function()} callback
           * @param {!Event} event
           */
          function onKeyDown(predicate, callback, event)
          {
              if (predicate(event)) {
                  event.consume(true);
                  callback();
              }
          }
      },
  
      /**
       * @param {string} title
       * @param {string=} width
       * @return {!Element}
       */
      _createInput: function(title, width)
      {
          var input = createElement("input");
          input.type = "text";
          if (width)
              input.style.width = width;
          input.placeholder = title;
          input.addEventListener("input", this._validateInputs.bind(this), false);
          return input;
      },
  
      _validateInputs: function()
      {
          var trimmedTitle = this._editDeviceTitle.value.trim();
          var titleValid = trimmedTitle.length > 0 && trimmedTitle.length < 50;
          this._editDeviceTitle.classList.toggle("error-input", !titleValid);
  
          var widthValid = !WebInspector.OverridesSupport.deviceSizeValidator(this._editDeviceWidth.value);
          this._editDeviceWidth.classList.toggle("error-input", !widthValid);
  
          var heightValid = !WebInspector.OverridesSupport.deviceSizeValidator(this._editDeviceHeight.value);
          this._editDeviceHeight.classList.toggle("error-input", !heightValid);
  
          var scaleValid = !WebInspector.OverridesSupport.deviceScaleFactorValidator(this._editDeviceScale.value);
          this._editDeviceScale.classList.toggle("error-input", !scaleValid);
  
          var allValid = titleValid && widthValid && heightValid && scaleValid;
          this._editDeviceCommitButton.disabled = !allValid;
      },
  
      /**
       * @param {number} value
       * @return {string}
       */
      _toNumericInputValue: function(value)
      {
          return value ? String(value) : "";
      },
  
      /**
       * @param {!WebInspector.EmulatedDevice} device
       * @param {?Element} listItem
       */
      _startEditing: function(device, listItem)
      {
          this._stopEditing();
  
          this._addCustomButton.disabled = true;
          this._devicesList.classList.add("devices-list-editing");
          this._editDevice = device;
          this._editDeviceListItem = listItem;
          if (listItem)
              listItem.classList.add("hidden");
  
          this._editDeviceCommitButton.textContent = listItem ? WebInspector.UIString("Save") : WebInspector.UIString("Add device");
          this._editDeviceCheckbox.checked = device.show();
          this._editDeviceTitle.value = device.title;
          this._editDeviceWidth.value = listItem ? this._toNumericInputValue(device.vertical.width) : "";
          this._editDeviceHeight.value = listItem ? this._toNumericInputValue(device.vertical.height) : "";
          this._editDeviceScale.value = listItem ? this._toNumericInputValue(device.deviceScaleFactor) : "";
          this._editDeviceUserAgent.value = device.userAgent;
          this._validateInputs();
  
          if (listItem && listItem.nextElementSibling)
              this._devicesList.insertBefore(this._editDeviceElement, listItem.nextElementSibling);
          else
              this._devicesList.insertBefore(this._editDeviceElement, this._customListSearator);
          this._editDeviceCommitButton.scrollIntoView();
          this._editDeviceTitle.focus();
      },
  
      _editDeviceCommitClicked: function()
      {
          if (this._editDeviceCommitButton.disabled)
              return;
  
          this._editDevice.setShow(this._editDeviceCheckbox.checked);
          this._editDevice.title = this._editDeviceTitle.value;
          this._editDevice.vertical.width = this._editDeviceWidth.value ? parseInt(this._editDeviceWidth.value, 10) : 0;
          this._editDevice.vertical.height = this._editDeviceHeight.value ? parseInt(this._editDeviceHeight.value, 10) : 0;
          this._editDevice.horizontal.width = this._editDevice.vertical.height;
          this._editDevice.horizontal.height = this._editDevice.vertical.width;
          this._editDevice.deviceScaleFactor = this._editDeviceScale.value ? parseFloat(this._editDeviceScale.value) : 0;
          this._editDevice.userAgent = this._editDeviceUserAgent.value;
  
          this._stopEditing();
          if (this._editDeviceListItem)
              WebInspector.emulatedDevicesList.saveCustomDevices();
          else
              WebInspector.emulatedDevicesList.addCustomDevice(this._editDevice);
          this._editDevice = null;
          this._editDeviceListItem = null;
      },
  
      _stopEditing: function()
      {
          this._devicesList.classList.remove("devices-list-editing");
          if (this._editDeviceListItem)
              this._editDeviceListItem.classList.remove("hidden");
          if (this._editDeviceElement.parentElement)
              this._devicesList.removeChild(this._editDeviceElement);
          this._addCustomButton.disabled = false;
          this._addCustomButton.focus();
      },
  
      _updateStandardDevices: function()
      {
          WebInspector.emulatedDevicesList.update();
      },
  
      __proto__: WebInspector.VBox.prototype
  }
  