Bug 954017 - Use Function.bind instead of 'self' variables and getBindingParent calls.
authorFlorian Quèze <florian@instantbird.org>
Thu, 26 May 2011 10:17:19 +0200
changeset 18242 1fd5ed0368da8115e4eb2f824bc4fdd7fb313ccf
parent 18241 5200938534ebaedaf935199c705a1a4f55244efd
child 18243 825dfef87c7d47d6f2c5f1e401006df6ece3e367
push idunknown
push userunknown
push dateunknown
bugs954017
Bug 954017 - Use Function.bind instead of 'self' variables and getBindingParent calls.
im/content/account.xml
im/content/contact.xml
im/content/conversation.xml
purple/purplexpcom/src/jsTestProtocol.js
--- a/im/content/account.xml
+++ b/im/content/account.xml
@@ -147,33 +147,32 @@
           text = account.connectionErrorMessage;
         text = bundle.getFormattedString(key, [text]);
 
         this.setAttribute("error", "true");
         var error = document.getAnonymousElementByAttribute(this, "anonid",
                                                             "error");
         error.textContent = text;
 
-        var self = this;
-        var updateReconnect = function() {
+        var updateReconnect = (function() {
           var date = Math.round((account.timeOfNextReconnect - Date.now()) / 1000);
           let reconnect = "";
           if (date > 0) {
             let [val1, unit1, val2, unit2] = DownloadUtils.convertTimeUnits(date);
             if (!val2)
               reconnect = bundle.getFormattedString("account.reconnectInSingle",
                                                     [val1, unit1])
             else
               reconnect = bundle.getFormattedString("account.reconnectInDouble",
                                                     [val1, unit1, val2, unit2])
           }
-          document.getAnonymousElementByAttribute(self, "anonid", "reconnect")
+          document.getAnonymousElementByAttribute(this, "anonid", "reconnect")
                   .textContent = reconnect;
           return reconnect;
-        };
+        }).bind(this);
         if (updateReconnect() && !this.reconnectUpdateInterval) {
           this.setAttribute("reconnectPending", "true");
           this.reconnectUpdateInterval = setInterval(updateReconnect, 1000);
           gAccountManager.disableCommandItems();
         }
       ]]>
       </body>
      </method>
--- a/im/content/contact.xml
+++ b/im/content/contact.xml
@@ -267,21 +267,20 @@
         let textbox =
           document.getAnonymousElementByAttribute(this, "anonid", "displayname");
         textbox.getBoundingClientRect(); // force binding attachmant by forcing layout
         textbox.select();
 
         // Some keys (home/end for example) can make the selected item
         // of the richlistbox change without producing a blur event on
         // our textbox. Make sure we watch richlistbox selection changes.
-        var self = this;
-        this._parentSelectListener = function(aEvent) {
-          if (aEvent.target == self.parentNode)
-            self.finishAliasing(true);
-        };
+        this._parentSelectListener = (function(aEvent) {
+          if (aEvent.target == this.parentNode)
+            this.finishAliasing(true);
+        }).bind(this);
         this.parentNode.addEventListener("select", this._parentSelectListener, false);
       ]]>
       </body>
      </method>
 
      <method name="finishAliasing">
       <parameter name="aSave"/>
       <body>
--- a/im/content/conversation.xml
+++ b/im/content/conversation.xml
@@ -118,22 +118,23 @@
           <xul:textbox anonid="inputBox" class="conv-textbox" multiline="true" flex="1"/>
         </xul:deck>
       </xul:vbox>
     </content>
     <implementation implements="nsIObserver">
      <constructor>
       <![CDATA[
        let textbox = this.editor;
-       textbox.addEventListener("keypress", this.inputKeyPress, false);
-       textbox.addEventListener("overflow", this.inputExpand, true);
+       textbox.addEventListener("keypress", this.inputKeyPress.bind(this), false);
+       textbox.addEventListener("overflow", this.inputExpand.bind(this), true);
        textbox.addEventListener("underflow", this._onTextboxUnderflow, true);
 
        this.getElt("splitter-bottom")
-           .addEventListener("DOMAttrModified", this._onSplitterChange, false);
+           .addEventListener("DOMAttrModified",
+                             this._onSplitterChange.bind(this), false);
 
        var editor = this.getElt("editor");
        editor.addEventListener("keypress", this.editorKeyPress, false);
        //this doesn't work at the moment
        //editor.contentDocument.designMode = "on";
        //setTimeout(function() { editor.contentWindow.focus(); }, 100);
 
        var browser = this.browser;
@@ -379,20 +380,20 @@
 
      <method name="_onSplitterChange">
       <parameter name="aEvent"/>
       <body>
       <![CDATA[
         if (aEvent.attrName != "state" || aEvent.prevValue != "dragging")
           return;
 
-        let textbox = document.getBindingParent(this).editor;
+        let textbox = this.editor;
         // set the default height as the deck height (modified by the splitter)
         textbox.defaultHeight = parseInt(textbox.parentNode.height) -
-          document.getBindingParent(this)._TEXTBOX_VERTICAL_OVERHEAD;
+          this._TEXTBOX_VERTICAL_OVERHEAD;
       ]]>
       </body>
      </method>
 
      <!--
       This value represents the difference between the deck's height and the
       textbox's content height (borders, margins, paddings).
       Differ according to the Operating System native theme.
@@ -464,63 +465,57 @@
       ]]>
       </body>
      </method>
 
      <method name="inputKeyPress">
       <parameter name="event"/>
       <body>
       <![CDATA[
-        /* "this" can point to the textbox when this method is used by an eventListener,
-            get the conversation element */
-        var conv = this;
-        if (this.localName != "conversation")
-          conv = document.getBindingParent(this);
-
         if (event.shiftKey && (event.keyCode == KeyEvent.DOM_VK_PAGE_UP ||
                                event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN)) {
 
           let direction = (event.keyCode == KeyEvent.DOM_VK_PAGE_UP) ? -1 : 1;
-          conv.browser.docShell
+          this.browser.docShell
               .QueryInterface(Components.interfaces.nsITextScroll)
               .scrollByPages(direction);
 
           event.preventDefault();
           return;
         }
 
-        var inputBox = conv.editor;
+        var inputBox = this.editor;
         if (event.keyCode != 13) {
-          if (!conv._conv.isChat)
+          if (!this._conv.isChat)
             setTimeout(function () {
               // By the time the timeout is executed, the conversation may have
               // been closed.
-              if (!conv._conv)
+              if (!this._conv)
                 return;
 
               let text = inputBox.value;
               // try to avoid sending typing notifications when the user is
               // typing a command in the conversation.
               // These checks are not perfect (especially if non-existing
               // commands are sent as regular messages on the in-use prpl).
               if (! /^\//.test(text))
-                conv._conv.sendTyping(text.length);
+                this._conv.sendTyping(text.length);
               else
                 if (/^\/me /.test(text))
-                  conv._conv.sendTyping(text.length - 4);
+                  this._conv.sendTyping(text.length - 4);
             }, 0);
           return;
         }
 
         if (!event.ctrlKey && !event.shiftKey && !event.altKey) {
-          conv.sendMsg(inputBox.value);
+          this.sendMsg(inputBox.value);
           event.preventDefault();
         }
         else if (!event.shiftKey)
-          conv.addString("\n");
+          this.addString("\n");
       ]]>
       </body>
      </method>
 
      <method name="resetInput">
       <body>
       <![CDATA[
         var inputBox = this.editor;
@@ -539,42 +534,37 @@
       ]]>
       </body>
      </method>
 
      <method name="inputExpand">
       <parameter name="event"/>
       <body>
       <![CDATA[
-        let textbox, conv;
-        // In case it is called from the binding itself
-        if (!(this instanceof Components.interfaces.nsIDOMXULControlElement))
-          [textbox, conv] = [this.editor, this];
-        else
-          [textbox, conv] = [this, document.getBindingParent(this)];
+        let textbox = this.editor;
         let input = textbox.inputField;
 
         // This feature has been disabled, or the user is currently dragging
         // the splitter and the textbox has received an overflow event
         if (!TextboxSize.autoResize ||
-            conv.getElt("splitter-bottom").getAttribute("state") == "dragging") {
+            this.getElt("splitter-bottom").getAttribute("state") == "dragging") {
           input.style.overflowY = "";
           return;
         }
 
         // Check whether we can increase the height without hidding the status bar
         // (ensure the min-height property on the top part of this dialog)
-        let topBox = conv.getElt("conv-top");
+        let topBox = this.getElt("conv-top");
         let topBoxStyle = window.getComputedStyle(topBox, null);
         let topMinSize = parseInt(topBoxStyle.getPropertyValue("min-height"));
         let topSize = parseInt(topBoxStyle.getPropertyValue("height"));
         let deck = textbox.parentNode;
         let oldDeckHeight = parseInt(deck.height);
         let newDeckHeight =
-          parseInt(input.scrollHeight) + conv._TEXTBOX_VERTICAL_OVERHEAD;
+          parseInt(input.scrollHeight) + this._TEXTBOX_VERTICAL_OVERHEAD;
 
         if (!topMinSize || topSize - topMinSize > newDeckHeight - oldDeckHeight) {
           // Hide a possible vertical scrollbar.
           input.style.overflowY = "hidden";
           deck.height = newDeckHeight;
         }
         else {
           input.style.overflowY = "";
@@ -632,22 +622,18 @@
 
      <method name="editorKeyPress">
       <parameter name="event"/>
       <body>
       <![CDATA[
         if (event.keyCode != 13)
           return;
 
-        /* "this" can point to the textbox when this method is used by an eventListener,
-            get the conversation element */
-        var conv = this;
-        if (this.localName != "conversation")
-          conv = document.getBindingParent(this);
-
+        // "this" points to the textbox, get the conversation element.
+        var 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();
         }
@@ -1288,19 +1274,17 @@
      <method name="onNicklistKeyPress">
       <parameter name="event"/>
       <body>
       <![CDATA[
         if (event.keyCode != 13)
           return;
 
         // Return is pressed
-        var conv = this;
-        if (this.localName != "conversation")
-          conv = document.getBindingParent(this);
+        var conv = document.getBindingParent(this);
         var listbox = event.originalTarget;
         for (var i = 0; i < listbox.selectedCount; ++i) {
           var nick = listbox.getSelectedItem(i).chatBuddy.name;
           conv._conv.account.createConversation(nick);
         }
       ]]>
       </body>
      </method>
--- a/purple/purplexpcom/src/jsTestProtocol.js
+++ b/purple/purplexpcom/src/jsTestProtocol.js
@@ -70,21 +70,20 @@ function Account(aProtoInstance, aKey, a
 {
   this._init(aProtoInstance, aKey, aName);
 }
 Account.prototype = {
   connect: function() {
     this.base.connecting();
     // do something here
     this.base.connected();
-    let self = this;
-    setTimeout(function() {
-      self._conv = new Conversation(self);
-      self._conv.writeMessage("jstest", "You are now talking to /dev/null", {system: true});
-    }, 0);
+    setTimeout((function() {
+      this._conv = new Conversation(this);
+      this._conv.writeMessage("jstest", "You are now talking to /dev/null", {system: true});
+    }).bind(this), 0);
   },
   _conv: null,
   disconnect: function(aSilent) {
     this.base.disconnecting(this._base.NO_ERROR, "");
     if (!aSilent)
       this._conv.writeMessage("jstest", "You have disconnected.", {system: true});
     if (this._conv) {
       this._conv._setDisconnected();