Bug 1105525 - Enlarge Loop room rename field to prevent l10n issues. r=Standard8
authorNicolas Perriault <nperriault@mozilla.com>
Wed, 17 Dec 2014 14:16:53 +0100
changeset 220242 4ffe25a396c9bc360007aa592722cc121184b804
parent 220241 fbe5dc1dfcfcf4654340e15ae3b5e86aae02f47f
child 220243 94902e0d21201d1950f0ea4cf5c771597562ca1d
push id53051
push userryanvm@gmail.com
push dateThu, 18 Dec 2014 02:08:11 +0000
treeherdermozilla-inbound@ffb2b4550976 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1105525
milestone37.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 1105525 - Enlarge Loop room rename field to prevent l10n issues. r=Standard8
browser/components/loop/content/js/roomViews.js
browser/components/loop/content/js/roomViews.jsx
browser/components/loop/content/shared/css/conversation.css
browser/components/loop/test/desktop-local/roomViews_test.js
browser/components/loop/ui/ui-showcase.js
browser/components/loop/ui/ui-showcase.jsx
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -76,16 +76,26 @@ loop.roomViews = (function(mozL10n) {
       this.listenTo(this.props.roomStore, "change:error",
                     this.onRoomError);
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.roomStore);
     },
 
+    handleTextareaKeyDown: function(event) {
+      // Submit the form as soon as the user press Enter in that field
+      // Note: We're using a textarea instead of a simple text input to display
+      // placeholder and entered text on two lines, to circumvent l10n
+      // rendering/UX issues for some locales.
+      if (event.which === 13) {
+        this.handleFormSubmit(event);
+      }
+    },
+
     handleFormSubmit: function(event) {
       event.preventDefault();
 
       var newRoomName = this.state.newRoomName;
 
       if (newRoomName && this.state.roomName != newRoomName) {
         this.props.dispatcher.dispatch(
           new sharedActions.RenameRoom({
@@ -124,19 +134,20 @@ loop.roomViews = (function(mozL10n) {
       var cx = React.addons.classSet;
       return (
         React.DOM.div({className: "room-invitation-overlay"}, 
           React.DOM.p({className: cx({"error": !!this.state.error,
                             "error-display-area": true})}, 
             mozL10n.get("rooms_name_change_failed_label")
           ), 
           React.DOM.form({onSubmit: this.handleFormSubmit}, 
-            React.DOM.input({type: "text", className: "input-room-name", 
+            React.DOM.textarea({rows: "2", type: "text", className: "input-room-name", 
               valueLink: this.linkState("newRoomName"), 
               onBlur: this.handleFormSubmit, 
+              onKeyDown: this.handleTextareaKeyDown, 
               placeholder: mozL10n.get("rooms_name_this_room_label")})
           ), 
           React.DOM.p(null, mozL10n.get("invite_header_text")), 
           React.DOM.div({className: "btn-group call-action-group"}, 
             React.DOM.button({className: "btn btn-info btn-email", 
                     onClick: this.handleEmailButtonClick}, 
               mozL10n.get("share_button2")
             ), 
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -76,16 +76,26 @@ loop.roomViews = (function(mozL10n) {
       this.listenTo(this.props.roomStore, "change:error",
                     this.onRoomError);
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.roomStore);
     },
 
+    handleTextareaKeyDown: function(event) {
+      // Submit the form as soon as the user press Enter in that field
+      // Note: We're using a textarea instead of a simple text input to display
+      // placeholder and entered text on two lines, to circumvent l10n
+      // rendering/UX issues for some locales.
+      if (event.which === 13) {
+        this.handleFormSubmit(event);
+      }
+    },
+
     handleFormSubmit: function(event) {
       event.preventDefault();
 
       var newRoomName = this.state.newRoomName;
 
       if (newRoomName && this.state.roomName != newRoomName) {
         this.props.dispatcher.dispatch(
           new sharedActions.RenameRoom({
@@ -124,19 +134,20 @@ loop.roomViews = (function(mozL10n) {
       var cx = React.addons.classSet;
       return (
         <div className="room-invitation-overlay">
           <p className={cx({"error": !!this.state.error,
                             "error-display-area": true})}>
             {mozL10n.get("rooms_name_change_failed_label")}
           </p>
           <form onSubmit={this.handleFormSubmit}>
-            <input type="text" className="input-room-name"
+            <textarea rows="2" type="text" className="input-room-name"
               valueLink={this.linkState("newRoomName")}
               onBlur={this.handleFormSubmit}
+              onKeyDown={this.handleTextareaKeyDown}
               placeholder={mozL10n.get("rooms_name_this_room_label")} />
           </form>
           <p>{mozL10n.get("invite_header_text")}</p>
           <div className="btn-group call-action-group">
             <button className="btn btn-info btn-email"
                     onClick={this.handleEmailButtonClick}>
               {mozL10n.get("share_button2")}
             </button>
--- a/browser/components/loop/content/shared/css/conversation.css
+++ b/browser/components/loop/content/shared/css/conversation.css
@@ -805,25 +805,30 @@ html, .fx-embedded, #main,
   left: 1em;
   right: 1em;
   text-align: start;
   width: calc(258px - 2em);
   color: #d74345;
 }
 
 .room-invitation-overlay form {
-  padding: 8em 0 2.5em 0;
+  padding: 6em 0 2em 0;
 }
 
-.room-invitation-overlay input[type="text"] {
+.room-invitation-overlay textarea {
+  display: block;
+  background: rgba(0, 0, 0, .5);
   color: #fff;
+  font-family: "Helvetica Neue", Arial, sans;
   font-size: 1.2em;
   border: none;
   width: 200px;
   margin: 0 auto;
+  padding: .2em .4em;
+  border-radius: .5em;
 }
 
 .room-invitation-overlay .btn-group {
   position: absolute;
   bottom: 10px;
 }
 
 /* Standalone rooms */
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -141,19 +141,19 @@ describe("loop.roomViews", function () {
           sinon.assert.calledOnce(dispatcher.dispatch);
           sinon.assert.calledWithExactly(dispatcher.dispatch,
             new sharedActions.RenameRoom({
               roomToken: "fakeToken",
               newRoomName: "reallyFake"
             }));
         });
 
-      it("should dispatch a RenameRoom action when enter is pressed",
+      it("should dispatch a RenameRoom action when Enter key is pressed",
         function() {
-          React.addons.TestUtils.Simulate.submit(roomNameBox);
+          TestUtils.Simulate.keyDown(roomNameBox, {key: "Enter", which: 13});
 
           sinon.assert.calledOnce(dispatcher.dispatch);
           sinon.assert.calledWithExactly(dispatcher.dispatch,
             new sharedActions.RenameRoom({
               roomToken: "fakeToken",
               newRoomName: "reallyFake"
             }));
         });
--- a/browser/components/loop/ui/ui-showcase.js
+++ b/browser/components/loop/ui/ui-showcase.js
@@ -699,17 +699,21 @@
           iframeHead.appendChild(style.cloneNode(true));
         });
 
       };
     }
   }
 
   window.addEventListener("DOMContentLoaded", function() {
-    React.renderComponent(App(null), document.body);
+    try {
+      React.renderComponent(App(null), document.body);
+    } catch(err) {
+      console.log(err);
+    }
 
     _renderComponentsInIframes();
 
     // Put the title back, in case views changed it.
     document.title = "Loop UI Components Showcase";
   });
 
 })();
--- a/browser/components/loop/ui/ui-showcase.jsx
+++ b/browser/components/loop/ui/ui-showcase.jsx
@@ -699,17 +699,21 @@
           iframeHead.appendChild(style.cloneNode(true));
         });
 
       };
     }
   }
 
   window.addEventListener("DOMContentLoaded", function() {
-    React.renderComponent(<App />, document.body);
+    try {
+      React.renderComponent(<App />, document.body);
+    } catch(err) {
+      console.log(err);
+    }
 
     _renderComponentsInIframes();
 
     // Put the title back, in case views changed it.
     document.title = "Loop UI Components Showcase";
   });
 
 })();