Bug 1269352 - Synced Tabs sidebar does not register duplicate listeners. r=markh
authorEdouard Oger <eoger@fastmail.com>
Wed, 04 May 2016 11:52:00 -0400
changeset 296374 35f90f41182e2b384788ac29d0be0e0d362b86fa
parent 296373 e9149132e07a04f5bcaf5f5519d74d1079febe14
child 296375 7a279747fbc8574f34d8617ffd4ab742363fca21
push id76311
push usercbook@mozilla.com
push dateFri, 06 May 2016 12:26:12 +0000
treeherdermozilla-inbound@84a3e5716801 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmarkh
bugs1269352
milestone49.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 1269352 - Synced Tabs sidebar does not register duplicate listeners. r=markh
browser/components/syncedtabs/TabListView.js
--- a/browser/components/syncedtabs/TabListView.js
+++ b/browser/components/syncedtabs/TabListView.js
@@ -38,19 +38,24 @@ function TabListView(window, props) {
 
   this._window = window;
   this._doc = this._window.document;
 
   this._tabsContainerTemplate = this._doc.getElementById("tabs-container-template");
   this._clientTemplate = this._doc.getElementById("client-template");
   this._emptyClientTemplate = this._doc.getElementById("empty-client-template");
   this._tabTemplate = this._doc.getElementById("tab-template");
+  this.tabsFilter = this._doc.querySelector(".tabsFilter");
+  this.clearFilter = this._doc.querySelector(".textbox-search-clear");
+  this.searchBox = this._doc.querySelector(".search-box");
+  this.searchIcon = this._doc.querySelector(".textbox-search-icon");
 
   this.container = this._doc.createElement("div");
 
+  this._attachFixedListeners();
   this._setupContextMenu();
 }
 
 TabListView.prototype = {
   render(state) {
     // Don't rerender anything; just update attributes, e.g. selection
     if (state.canUpdateAll) {
       this._update(state);
@@ -67,28 +72,22 @@ TabListView.prototype = {
   },
 
   // Create the initial DOM from templates
   _create(state) {
     let wrapper = this._doc.importNode(this._tabsContainerTemplate.content, true).firstElementChild;
     this._clearChilden();
     this.container.appendChild(wrapper);
 
-    // The search-box is outside of our container (it's not scrollable)
-    this.tabsFilter = this._doc.querySelector(".tabsFilter");
-    this.clearFilter = this._doc.querySelector(".textbox-search-clear");
-    this.searchBox = this._doc.querySelector(".search-box");
-    this.searchIcon = this._doc.querySelector(".textbox-search-icon");
-
     this.list = this.container.querySelector(".list");
 
     this._createList(state);
     this._updateSearchBox(state);
 
-    this._attachListeners();
+    this._attachListListeners();
   },
 
   _createList(state) {
     this._clearChilden(this.list);
     for (let client of state.clients) {
       if (state.filter) {
         this._renderFilteredClient(client);
       } else {
@@ -165,26 +164,31 @@ TabListView.prototype = {
 
   _clearChilden(node) {
     let parent = node || this.container;
     while (parent.firstChild) {
       parent.removeChild(parent.firstChild);
     }
   },
 
-  _attachListeners() {
-    this.list.addEventListener("click", this.onClick.bind(this));
-    this.list.addEventListener("keydown", this.onKeyDown.bind(this));
+  // These listeners are attached only once, when we initialize the view
+  _attachFixedListeners() {
     this.tabsFilter.addEventListener("input", this.onFilter.bind(this));
     this.tabsFilter.addEventListener("focus", this.onFilterFocus.bind(this));
     this.tabsFilter.addEventListener("blur", this.onFilterBlur.bind(this));
     this.clearFilter.addEventListener("click", this.onClearFilter.bind(this));
     this.searchIcon.addEventListener("click", this.onFilterFocus.bind(this));
   },
 
+  // These listeners have to be re-created every time since we re-create the list
+  _attachListListeners() {
+    this.list.addEventListener("click", this.onClick.bind(this));
+    this.list.addEventListener("keydown", this.onKeyDown.bind(this));
+  },
+
   _updateSearchBox(state) {
     if (state.filter) {
       this.searchBox.classList.add("filtered");
     } else {
       this.searchBox.classList.remove("filtered");
     }
     this.tabsFilter.value = state.filter;
     if (state.inputFocused) {