d; if (this._closedClients[id]) { this._selectParentRow(); } this._change("all"); }, _isOpen(client) { return !this._closedClients[client.id]; }, moveSelectionDown() { let branchRow = this._selectedRow[0]; let childRow = this._selectedRow[1]; let branch = this.data[branchRow]; if (this.filter) { this.selectRow(branchRow + 1); return; } if (branchRow < 0) { this.selectRow(0, -1); } else if ( (!branch.tabs.length || childRow >= branch.tabs.length - 1 || !this._isOpen(branch)) && branchRow < this.data.length ) { this.selectRow(branchRow + 1, -1); } else if (childRow < branch.tabs.length) { this.selectRow(branchRow, childRow + 1); } }, moveSelectionUp() { let branchRow = this._selectedRow[0]; let childRow = this._selectedRow[1]; if (this.filter) { this.selectRow(branchRow - 1); return; } if (branchRow < 0) { this.selectRow(0, -1); } else if (childRow < 0 && branchRow > 0) { let prevBranch = this.data[branchRow - 1]; let newChildRow = this._isOpen(prevBranch) ? prevBranch.tabs.length - 1 : -1; this.selectRow(branchRow - 1, newChildRow); } else if (childRow >= 0) { this.selectRow(branchRow, childRow - 1); } }, // Selects a row and makes sure the selection is within bounds selectRow(parent, child) { let maxParentRow = this.filter ? this._tabCount() : this.data.length; let parentRow = parent; if (parent <= -1) { parentRow = 0; } else if (parent >= maxParentRow) { return; } let childRow = child; if ( parentRow === -1 || this.filter || typeof child === "undefined" || child < -1 ) { childRow = -1; } else if (child >= this.data[parentRow].tabs.length) { childRow = this.data[parentRow].tabs.length - 1; } if ( this._selectedRow[0] === parentRow && this._selectedRow[1] === childRow ) { return; } this._selectedRow = [parentRow, childRow]; this.inputFocused = false; this._change("all"); // Record the telemetry event let extraOptions = { tab_pos: this._selectedRow[1].toString(), filter: this.filter, }; this._SyncedTabs.recordSyncedTabsTelemetry( "synced_tabs_sidebar", "click", extraOptions ); }, _tabCount() { return this.data.reduce((prev, curr) => curr.tabs.length + prev, 0); }, toggleBranch(id) { this._toggleBranch(id, !this._closedClients[id]); }, closeBranch(id) { this._toggleBranch(id, true); }, openBranch(id) { this._toggleBranch(id, false); }, focusInput() { this.inputFocused = true; // A change type of "all" updates rather than rebuilds, which is what we // want here - only the selection/focus has changed. this._change("all"); }, blurInput() { this.inputFocused = false; // A change type of "all" updates rather than rebuilds, which is what we // want here - only the selection/focus has changed. this._change("all"); }, clearFilter() { this.filter = ""; this._selectedRow = [-1, -1]; return this.getData(); }, // Fetches data from the SyncedTabs module and triggers // and update getData(filter) { let updateType; let hasFilter = typeof filter !== "undefined"; if (hasFilter) { this.filter = filter; this._selectedRow = [-1, -1]; // When a filter is specified we tell the view that only the list // needs to be rerendered so that it doesn't disrupt the input // field's focus. updateType = "searchbox"; } // return promise for tests return this._SyncedTabs .getTabClients(this.filter) .then(result => { if (!hasFilter) { // Only sort clients and tabs if we're rendering the whole list. this._SyncedTabs.sortTabClientsByLastUsed(result); } this.data = result; this._change(updateType); }) .catch(console.error); }, }); PK