mirror of
https://github.com/vale981/tridactyl
synced 2025-03-04 17:11:40 -05:00
Fix array index out of bounds error
This commit is contained in:
parent
5f33c6135b
commit
bf9b5db067
2 changed files with 3 additions and 235 deletions
|
@ -1,235 +0,0 @@
|
|||
import * as Perf from "@src/perf"
|
||||
import { browserBg } from "@src/lib/webext"
|
||||
import * as Containers from "@src/lib/containers"
|
||||
import * as Completions from "@src/completions"
|
||||
import * as Messaging from "@src/lib/messaging"
|
||||
import * as config from "@src/lib/config"
|
||||
import {
|
||||
tgroups,
|
||||
tabTgroup,
|
||||
} from "@src/lib/tab_groups"
|
||||
|
||||
class TabAllCompletionOption
|
||||
extends Completions.CompletionOptionHTML
|
||||
implements Completions.CompletionOptionFuse {
|
||||
public fuseKeys = []
|
||||
public tab: browser.tabs.Tab
|
||||
constructor(
|
||||
public value: string,
|
||||
tab: browser.tabs.Tab,
|
||||
isAlternative: boolean,
|
||||
isCurrent: boolean,
|
||||
winindex: number,
|
||||
container: browser.contextualIdentities.ContextualIdentity,
|
||||
incognito: boolean,
|
||||
tgroupname: string
|
||||
) {
|
||||
super()
|
||||
const valueStr = `${winindex}.${tab.index + 1}`
|
||||
this.value = valueStr
|
||||
this.fuseKeys.push(this.value, tab.title, tab.url)
|
||||
this.tab = tab
|
||||
|
||||
// pre contains max four uppercase characters for tab status.
|
||||
// If statusstylepretty is set to true replace use unicode characters,
|
||||
// but keep plain letters in hidden column for completion.
|
||||
let preplain = ""
|
||||
if (isCurrent) {
|
||||
preplain += "%"
|
||||
} else if (isAlternative) {
|
||||
preplain += "#"
|
||||
this.value = "#"
|
||||
}
|
||||
let pre = preplain
|
||||
if (tab.pinned) preplain += "P"
|
||||
if (tab.audible) preplain += "A"
|
||||
if (tab.mutedInfo.muted) preplain += "M"
|
||||
if (tab.discarded) preplain += "D"
|
||||
|
||||
if (config.get("completions", "Tab", "statusstylepretty") === "true") {
|
||||
if (tab.pinned) pre += "\uD83D\uDCCC"
|
||||
if (tab.audible) pre += "\uD83D\uDD0A"
|
||||
if (tab.mutedInfo.muted) pre += "\uD83D\uDD07"
|
||||
if (tab.discarded) pre += "\u2296"
|
||||
} else {
|
||||
pre = preplain
|
||||
}
|
||||
|
||||
tgroupname = (tgroupname === undefined) ? "" : tgroupname
|
||||
|
||||
// Push prefix before padding so we don't match on whitespace
|
||||
this.fuseKeys.push(pre)
|
||||
this.fuseKeys.push(preplain)
|
||||
this.fuseKeys.push(tgroupname)
|
||||
|
||||
// Push properties we want to fuzmatch on
|
||||
this.fuseKeys.push(String(tab.index + 1), tab.title, tab.url)
|
||||
|
||||
// Create HTMLElement
|
||||
const favIconUrl = tab.favIconUrl
|
||||
? tab.favIconUrl
|
||||
: Completions.DEFAULT_FAVICON
|
||||
this.html = html`<tr
|
||||
class="BufferAllCompletionOption option container_${container.color} container_${container.icon} container_${container.name} ${incognito
|
||||
? "incognito"
|
||||
: ""}"
|
||||
>
|
||||
<td class="prefix">${pre}</td>
|
||||
<td class="prefixplain" hidden>${preplain}</td>
|
||||
<td class="privatewindow"></td>
|
||||
<td class="container"></td>
|
||||
<td class="icon"><img src="${favIconUrl}" /></td>
|
||||
<td class="title">${valueStr}: ${tab.title}</td>
|
||||
<td class="tgroup">${tgroupname}</td>
|
||||
<td class="content">
|
||||
<a class="url" target="_blank" href=${tab.url}>${tab.url}</a>
|
||||
</td>
|
||||
</tr>`
|
||||
}
|
||||
}
|
||||
|
||||
export class TabAllCompletionSource extends Completions.CompletionSourceFuse {
|
||||
public options: TabAllCompletionOption[]
|
||||
private shouldSetStateFromScore = true
|
||||
|
||||
constructor(private _parent) {
|
||||
super(["taball", "tabgrab"], "TabAllCompletionSource", "All Tabs")
|
||||
|
||||
this.updateOptions()
|
||||
this._parent.appendChild(this.node)
|
||||
this.shouldSetStateFromScore =
|
||||
config.get("completions", "TabAll", "autoselect") === "true"
|
||||
|
||||
Messaging.addListener("tab_changes", () => this.reactToTabChanges())
|
||||
}
|
||||
|
||||
async onInput(exstr) {
|
||||
return this.updateOptions(exstr)
|
||||
}
|
||||
|
||||
setStateFromScore(scoredOpts: Completions.ScoredOption[]) {
|
||||
super.setStateFromScore(scoredOpts, this.shouldSetStateFromScore)
|
||||
}
|
||||
|
||||
/**
|
||||
* Map all windows into a {[windowId]: window} object
|
||||
*/
|
||||
private async getWindows() {
|
||||
const windows = await browserBg.windows.getAll()
|
||||
const response: { [windowId: number]: browser.windows.Window } = {}
|
||||
windows.forEach(win => (response[win.id] = win))
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the list of possible tab options and select (focus on)
|
||||
* the appropriate option.
|
||||
*/
|
||||
private async reactToTabChanges(): Promise<void> {
|
||||
// const prevOptions = this.options
|
||||
await this.updateOptions(this.lastExstr)
|
||||
|
||||
// TODO: update this from Tab.ts for TabAll.ts
|
||||
// if (!prevOptions || !this.options || !this.lastFocused) return
|
||||
|
||||
// // Determine which option to focus on
|
||||
// const diff = R.differenceWith(
|
||||
// (x, y) => x.tab.id === y.tab.id,
|
||||
// prevOptions,
|
||||
// this.options,
|
||||
// )
|
||||
// const lastFocusedTabCompletion = this
|
||||
// .lastFocused as TabAllCompletionOption
|
||||
|
||||
// // If the focused option was removed then focus on the next option
|
||||
// if (
|
||||
// diff.length === 1 &&
|
||||
// diff[0].tab.id === lastFocusedTabCompletion.tab.id
|
||||
// ) {
|
||||
// //this.select(this.getTheNextTabOption(lastFocusedTabCompletion))
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next option in this BufferCompletionSource assuming
|
||||
* that this BufferCompletionSource length has been reduced by 1
|
||||
*
|
||||
* TODO: this ain't going to work, need to work out position based on win.tab
|
||||
*/
|
||||
// private getTheNextTabOption(option: TabAllCompletionOption) {
|
||||
// if (option.tab.index === this.options.length) {
|
||||
// return this.options[this.options.length - 1]
|
||||
// }
|
||||
// return this.options[option.tab.index]
|
||||
// }
|
||||
|
||||
// Eslint doesn't like this decorator but there's nothing we can do about it
|
||||
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||||
@Perf.measuredAsync
|
||||
private async updateOptions(exstr = "") {
|
||||
this.lastExstr = exstr
|
||||
const [prefix] = this.splitOnPrefix(exstr)
|
||||
|
||||
// Hide self and stop if prefixes don't match
|
||||
if (prefix) {
|
||||
// Show self if prefix and currently hidden
|
||||
if (this.state === "hidden") {
|
||||
this.state = "normal"
|
||||
}
|
||||
} else {
|
||||
this.state = "hidden"
|
||||
return
|
||||
}
|
||||
|
||||
const tabsPromise = browserBg.tabs.query({})
|
||||
const windowsPromise = this.getWindows()
|
||||
const [tabs, windows] = await Promise.all([tabsPromise, windowsPromise])
|
||||
|
||||
const options = []
|
||||
|
||||
tabs.sort((a, b) => {
|
||||
if (a.windowId === b.windowId) return a.index - b.index
|
||||
return a.windowId - b.windowId
|
||||
})
|
||||
|
||||
const currentWindowTabs = await browserBg.tabs.query({
|
||||
currentWindow: true
|
||||
})
|
||||
currentWindowTabs.sort((a, b) => b.lastAccessed - a.lastAccessed)
|
||||
const altTab = currentWindowTabs[1]
|
||||
|
||||
// Check to see if this is a command that needs to exclude the current
|
||||
// window
|
||||
const excludeCurrentWindow = ["tabgrab"].includes(prefix.trim())
|
||||
const currentWindow = await browserBg.windows.getCurrent()
|
||||
// Window Ids don't make sense so we're using LASTID and WININDEX to compute a window index
|
||||
// This relies on the fact that tabs are sorted by window ids
|
||||
let lastId = 0
|
||||
let winindex = 0
|
||||
for (const tab of tabs) {
|
||||
if (lastId !== tab.windowId) {
|
||||
lastId = tab.windowId
|
||||
winindex += 1
|
||||
}
|
||||
// if we are excluding the current window and this tab is in the current window
|
||||
// then skip it
|
||||
if (excludeCurrentWindow && tab.windowId === currentWindow.id) continue
|
||||
options.push(
|
||||
new TabAllCompletionOption(
|
||||
tab.id.toString(),
|
||||
tab,
|
||||
tab.index === altTab.index && tab.windowId === altTab.windowId,
|
||||
tab.active && tab.windowId === currentWindowTabs[0].windowId,
|
||||
winindex,
|
||||
await Containers.getFromId(tab.cookieStoreId),
|
||||
windows[tab.windowId].incognito,
|
||||
await tabTgroup(tab.id)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
this.completion = undefined
|
||||
this.options = options
|
||||
return this.updateChain()
|
||||
}
|
||||
}
|
|
@ -81,6 +81,9 @@ export async function setWindowTgroup(name: string, id?: number) {
|
|||
*/
|
||||
export async function windowLastTgroup(id?: number) {
|
||||
const otherGroupsTabs = await tgroupTabs(await windowTgroup(id), true)
|
||||
if (otherGroupsTabs.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
otherGroupsTabs.sort((a, b) => b.lastAccessed - a.lastAccessed)
|
||||
const lastTabId = otherGroupsTabs[0].id
|
||||
return tabTgroup(lastTabId)
|
||||
|
|
Loading…
Add table
Reference in a new issue