Bug 1488503: Validation for network location. r=jdescottes
☠☠ backed out by 989c91cf970e ☠ ☠
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Wed, 20 Mar 2019 07:22:09 +0000
changeset 465187 4968b44840749c5f83a74c1c3e7371eb9b4159ba
parent 465186 708979f9c3f33c77fb2e9106054b215c77044a04
child 465188 1b763fdfc0ba121950f386e15d7b72432079835d
push id80946
push userdakatsuka@mozilla.com
push dateWed, 20 Mar 2019 07:25:46 +0000
treeherderautoland@1b763fdfc0ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1488503
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1488503: Validation for network location. r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D23993
devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.js
devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css
devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.js
devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl
--- a/devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.js
+++ b/devtools/client/aboutdebugging-new/src/components/connect/ConnectPage.js
@@ -191,17 +191,17 @@ class ConnectPage extends PureComponent 
         {
           className: "connect-page__breather",
           icon: GLOBE_ICON_SRC,
           title: "Network Location",
           extraContent: networkEnabled
             ? dom.div(
               {},
               NetworkLocationsList({ dispatch, networkLocations }),
-              NetworkLocationsForm({ dispatch }),
+              NetworkLocationsForm({ dispatch, networkLocations }),
             )
             : null,
         },
         networkEnabled
           ? null
           : Localized(
             {
                 id: "about-debugging-connect-network-disabled",
--- a/devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css
+++ b/devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.css
@@ -12,8 +12,12 @@
 .connect-page__network-form {
   display: grid;
   grid-column-gap: calc(var(--base-unit) * 2);
   grid-template-columns: auto 1fr auto;
   align-items: center;
   padding-block-start: calc(var(--base-unit) * 4);
   padding-inline: calc(var(--base-unit) * 6);
 }
+
+.connect-page__network-form__error-message {
+  grid-column: 1 / -1;
+}
--- a/devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.js
+++ b/devtools/client/aboutdebugging-new/src/components/connect/NetworkLocationsForm.js
@@ -6,45 +6,98 @@
 
 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 FluentReact = require("devtools/client/shared/vendor/fluent-react");
 const Localized = createFactory(FluentReact.Localized);
 
+const Message = createFactory(require("../shared/Message"));
+
 const Actions = require("../../actions/index");
+const { MESSAGE_LEVEL } = require("../../constants");
+const Types = require("../../types/index");
 
 class NetworkLocationsForm extends PureComponent {
   static get propTypes() {
     return {
       dispatch: PropTypes.func.isRequired,
+      networkLocations: PropTypes.arrayOf(Types.location).isRequired,
     };
   }
 
   constructor(props) {
     super(props);
     this.state = {
+      errorHostValue: null,
+      errorMessageId: null,
       value: "",
     };
   }
 
+  onSubmit(e) {
+    const { networkLocations } = this.props;
+    const { value } = this.state;
+
+    e.preventDefault();
+
+    if (!value) {
+      return;
+    }
+
+    if (!value.match(/[^:]+:\d+/)) {
+      this.setState({
+        errorHostValue: value,
+        errorMessageId: "about-debugging-network-location-form-invalid",
+      });
+      return;
+    }
+
+    if (networkLocations.includes(value)) {
+      this.setState({
+        errorHostValue: value,
+        errorMessageId: "about-debugging-network-location-form-duplicate",
+      });
+      return;
+    }
+
+    this.props.dispatch(Actions.addNetworkLocation(value));
+    this.setState({ errorHostValue: null, errorMessageId: null, value: "" });
+  }
+
+  renderError() {
+    const { errorHostValue, errorMessageId } = this.state;
+
+    if (!errorMessageId) {
+      return null;
+    }
+
+    return Message(
+      {
+        className: "connect-page__network-form__error-message",
+        level: MESSAGE_LEVEL.ERROR,
+      },
+      Localized(
+        {
+          id: errorMessageId,
+          "$host-value": errorHostValue,
+        },
+        dom.p({}, errorMessageId)
+      ),
+    );
+  }
+
   render() {
     return dom.form(
       {
         className: "connect-page__network-form",
-        onSubmit: (e) => {
-          const { value } = this.state;
-          if (value) {
-            this.props.dispatch(Actions.addNetworkLocation(value));
-            this.setState({ value: "" });
-          }
-          e.preventDefault();
-        },
+        onSubmit: (e) => this.onSubmit(e),
       },
+      this.renderError(),
       Localized(
         {
           id: "about-debugging-network-locations-host-input-label",
         },
         dom.label(
           {
             htmlFor: "about-debugging-network-locations-host-input",
           },
@@ -67,14 +120,14 @@ class NetworkLocationsForm extends PureC
           id: "about-debugging-network-locations-add-button",
         },
         dom.button(
           {
             className: "primary-button js-network-form-submit-button",
           },
           "Add"
         )
-      )
+      ),
     );
   }
 }
 
 module.exports = NetworkLocationsForm;
--- a/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl
+++ b/devtools/client/aboutdebugging-new/tmp-locale/en-US/aboutdebugging.notftl
@@ -213,16 +213,24 @@ about-debugging-network-locations-empty-
 # the Connect page. A host is a hostname and a port separated by a colon, as suggested by
 # the input's placeholder "localhost:6080".
 about-debugging-network-locations-host-input-label = Host
 
 # Text of a button displayed next to existing network locations in the Connect page.
 # Clicking on it removes the network location from the list.
 about-debugging-network-locations-remove-button = Remove
 
+# Text used as error message if the format of the input value was invalid in the network locations form of the Setup page.
+# { $host-value } is the input value submitted by the user in the network locations form
+about-debugging-network-location-form-invalid = Invalid host "{ $host-value }". The expected format is "hostname:portnumber".
+
+# Text used as error message if the input value was already registered in the network locations form of the Setup page.
+# { $host-value } is the input value submitted by the user in the network locations form
+about-debugging-network-location-form-duplicate = The host "{ $host-value }" is already registered
+
 # This string is displayed as a label of the button that pushes a test payload
 # to a service worker.
 # Notes, this relates to the "Push" API, which is normally not localized so it is
 # probably better to not localize it.
 about-debugging-worker-action-push = Push
 
 # This string is displayed as a label of the button that starts a service worker.
 about-debugging-worker-action-start = Start