Bug 953542 - When the user types, focus should be given to message area. p=Romain Bezut <romain@bezut.info>,r=florian
authorFlorian Quèze <florian@instantbird.org>
Wed, 13 Aug 2008 23:51:32 +0200
changeset 13758 705db44df8e55efc99e7b948e4b4d816c4913edd
parent 13757 b03375c4e9fe85a2fed5b94051f5beffe01f41fb
child 13759 3eb77b2c6770e7e177257605b15a9ed2ea3661e1
push id9778
push userflorian@queze.net
push dateSun, 12 Jan 2014 18:25:45 +0000
treeherdercomm-central@f81a23bfefcd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian
bugs953542
Bug 953542 - When the user types, focus should be given to message area. p=Romain Bezut <romain@bezut.info>,r=florian
im/base/content/instantbird/conversation.xml
--- a/im/base/content/instantbird/conversation.xml
+++ b/im/base/content/instantbird/conversation.xml
@@ -70,16 +70,18 @@
     </content>
     <implementation implements="nsIWebProgressListener">
      <constructor>
       <![CDATA[
        document.getAnonymousElementByAttribute(this, "anonid", "input")
                .addEventListener("keypress", this.onSendMsg, false);
 
        var browser = document.getAnonymousElementByAttribute(this, "anonid", "browser");
+       browser.addEventListener("keypress", this.browserKeyPress, false);
+
        var docShell = browser.docShell;
        docShell.allowJavascript = false;
        docShell.allowAuth = false;
        docShell.allowPlugins = false;
        docShell.allowMetaRedirects = false;
        docShell.allowSubframes = false;
        docShell.allowImages = false;
 
@@ -241,44 +243,46 @@
 
      <method name="onSendMsg">
       <parameter name="event"/>
       <body>
       <![CDATA[
         if (event.keyCode != 13)
           return;
 
-        /* this method is called by an eventListener.
-           This points to the textbox element. */
+        /* "this" can point to the textbox when this method is used by an eventListener,
+            get the conversation element */
         var conv = this;
-        while (conv.localName != "conversation")
-          conv = conv.parentNode;
+        if (this.localName != "conversation")
+          conv = document.getBindingParent(this);
+
+        var input = document.getAnonymousElementByAttribute(conv, "anonid", "input");
         if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
-          conv.sendMsg(this.value);
-          this.value = "";
+          conv.sendMsg(input.value);
+          input.value = "";
           event.preventDefault();
         }
         else if (!event.shiftKey)
-          this.value += "\n";
+          conv.addString("\n");
       ]]>
       </body>
      </method>
 
      <method name="onSendHTMLMsg">
       <parameter name="event"/>
       <body>
       <![CDATA[
         if (event.keyCode != 13)
           return;
 
-        /* this method is called by an eventListener.
-           This points to the textbox element. */
+        /* "this" can point to the textbox when this method is used by an eventListener,
+            get the conversation element */
         var conv = this;
-        while (conv.localName != "conversation")
-          conv = conv.parentNode;
+        if (this.localName != "conversation")
+          conv = document.getBindingParent(this);
 
         var editor = this.getEditor(this.contentWindow);
         var docRoot = editor.rootElement;
 
         if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
           conv.sendMsg(docRoot.innerHTML);
           docRoot.innerHTML = "";
           event.preventDefault();
@@ -298,16 +302,105 @@
       <body>
       <![CDATA[
         var editor = document.getAnonymousElementByAttribute(this, "anonid", "editor");
         editor.contentDocument.execCommand(aCmd, false, aHtml);
       ]]>
       </body>
      </method>
 
+     <method name="browserKeyPress">
+     <parameter name="event"/>
+      <body>
+      <![CDATA[
+        // 118 is the decimal code for "v" character, 13 keyCode for "return" key
+        if (((event.ctrlKey && event.charCode != 118) || event.altKey) &&
+            event.keyCode != 13)
+          return;
+
+        var conv = document.getBindingParent(this);
+        var isHtmlMode = conv.isHtmlMode;
+        var editor = conv.editor;
+
+        // "Return" key
+        if (event.keyCode == 13) {
+          editor.focus();
+
+          if (isHtmlMode)
+            conv.onSendHTMLMsg(event);
+          else
+            conv.onSendMsg(event);
+
+          // Alt and Ctrl + return are handled in onSendMsg
+          if (event.shiftKey) {
+            if (!isHtmlMode)
+              conv.addString("\n");
+          }
+        }
+        // "Backspace" key
+        else if (event.keyCode == 8) {
+          editor.focus();
+
+          if (!isHtmlMode) {
+            if (editor.selectionStart > 0 &&
+                editor.selectionStart == editor.selectionEnd)
+              --editor.selectionStart;
+
+            conv.addString("");
+          }
+        }
+        // "Delete" key
+        else if (event.keyCode == 46) {
+          editor.focus();
+
+          if (!isHtmlMode) {
+            var length = editor.textLength;
+            if (editor.selectionStart < length &&
+                editor.selectionStart == editor.selectionEnd)
+              ++editor.selectionEnd;
+
+            conv.addString("");
+          }
+        }
+
+        // CharCode=0 means not a character
+        if (event.charCode == 0)
+          return;
+
+        editor.focus();
+
+        // Returns for Ctrl+V
+        if (event.ctrlKey)
+          return;
+
+        if (!isHtmlMode)
+          conv.addString(String.fromCharCode(event.charCode));
+      ]]>
+      </body>
+     </method>
+
+     <!-- Replace the current selection in the editor by the given string -->
+     <method name="addString">
+       <parameter name="aString"/>
+       <body>
+       <![CDATA[
+         var editor = this.editor;
+         var length = (aString != "")
+                      ? aString.length
+                      : 0;
+
+         var cursorPosition = editor.selectionStart + length;
+
+         editor.value = editor.value.substr(0, editor.selectionStart) + aString +
+                        editor.value.substr(editor.selectionEnd);
+         editor.selectionStart = editor.selectionEnd = cursorPosition;
+       ]]>
+       </body>
+     </method>
+
      <!-- nsIWebProgressListener implementation -->
      <method name="onStateChange">
       <parameter name="aProgress"/>
       <parameter name="aRequest"/>
       <parameter name="aStateFlags"/>
       <parameter name="aStatus"/>
       <body>
       <![CDATA[
@@ -369,16 +462,38 @@
        </getter>
        <setter>
          <![CDATA[
            this._conv = val;
            return val;
          ]]>
        </setter>
      </property>
+
+     <property name="isHtmlMode">
+       <getter>
+         <![CDATA[
+           var editorIndex = document.getAnonymousElementByAttribute(this, "anonid", "conv-bottom")
+                                     .selectedIndex;
+           return (editorIndex == "0");
+         ]]>
+       </getter>
+     </property>
+
+     <property name="editor">
+       <getter>
+         <![CDATA[
+          if (this.isHtmlMode)
+            return document.getAnonymousElementByAttribute(this, "anonid", "editor");
+          else
+            return document.getAnonymousElementByAttribute(this, "anonid", "input");
+         ]]>
+       </getter>
+     </property>
+
     </implementation>
     <handlers>
      <handler event="focus" phase="capturing">
        <![CDATA[
          if (event.originalTarget != this)
            return;
          if (!this.hasAttribute("focused")) {
            var input = document.getAnonymousElementByAttribute(this, "anonid", "input");