Skip to content

Commit

Permalink
🚸 User experience fixes (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
trickypr authored Jan 20, 2024
1 parent e5cdfbf commit a685208
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 31 deletions.
1 change: 1 addition & 0 deletions apps/content/src/browser/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'remixicon/fonts/remixicon.css'
import '@shared/styles/window.css'

import App from './Browser.svelte'
import './browser.css'
import { initializeShortcuts } from './lib/shortcuts'
import { initializeWindow } from './lib/window'
import './lib/window/api'
Expand Down
19 changes: 13 additions & 6 deletions apps/content/src/browser/components/omnibox/Omnibox.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
let inputElement: HTMLInputElement
let suggestions: Suggestion[] = []
let selectedSuggestion = 0
let selectionChange = false
$: focusedOmnibox = tab.focusedOmnibox
$: uri = tab.uri
Expand Down Expand Up @@ -73,13 +74,16 @@
bind:value={inputContent}
on:focusin={() => {
focusedOmnibox.set(true)
selectionChange = false
generateSuggestions()
}}
on:blur|capture={() =>
setTimeout(() => {
focusedOmnibox.set(false)
suggestions = []
}, 100)}
on:blur|capture={() => setTimeout(() => focusedOmnibox.set(false), 100)}
on:mouseup={(_) => {
if (!selectionChange) inputElement.select()
}}
on:selectionchange={() => {
selectionChange = true
}}
on:keyup={async (e) => {
if (e.key === 'Enter') {
focusedOmnibox.set(false)
Expand Down Expand Up @@ -119,8 +123,8 @@

<div
class="suggestions"
hidden={!$focusedOmnibox}
id="omnibox__suggestions-list"
hidden={!$focusedOmnibox}
role="listbox"
>
{#each suggestions as suggestion, index}
Expand Down Expand Up @@ -184,6 +188,9 @@
padding: 0.5rem 1rem;
border-radius: 0.25rem;
cursor: pointer;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.suggestion:hover {
Expand Down
9 changes: 6 additions & 3 deletions apps/content/src/browser/lib/window/tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ export class Tab {
this.progressListener.events.on('locationChange', (event) => {
if (!event.aWebProgress.isTopLevel) return

this.icon.set(null)
const sameLocation =
event.aFlags & 0x01 /* LOCATION_CHANGE_SAME_DOCUMENT */
if (!sameLocation) {
this.icon.set(null)
}

this.uri.set(event.aLocation)
this.canGoBack.set(this.browserElement.canGoBack)
Expand Down Expand Up @@ -219,8 +223,7 @@ export class Tab {

const findbar = this.findbar.readOnce()
if (findbar) {
if (findbar.hidden) findbar.open()
else findbar.close()
findbar.onFindCommand()
return
}

Expand Down
55 changes: 33 additions & 22 deletions apps/content/src/browser/lib/window/tabs.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { viewableWritable } from '@experiment/shared'
import { writable } from 'svelte/store'
import { Ring, not, viewableWritable } from '@experiment/shared'

import { resource } from '../resources'
import { Tab } from './tab'

let internalSelectedTab = -1
export const selectedTabId = writable(-1)
selectedTabId.subscribe((v) => (internalSelectedTab = v))
const tabHistory = new Ring<number>(10)
export const selectedTabId = viewableWritable(-1)
selectedTabId.subscribe((id) => tabHistory.next(id))

const uriPref = (pref: string) => (): nsIURIType =>
resource.NetUtil.newURI(Services.prefs.getStringPref(pref, 'about:blank'))
Expand All @@ -18,8 +17,16 @@ export const ABOUT_BLANK = resource.NetUtil.newURI('about:blank')

export const tabs = viewableWritable<Tab[]>([])

const matchTab = (id: number) => (tab: Tab) => tab.getId() === id

export function openTab(uri: nsIURIType = newTabUri()) {
const newTab = new Tab(uri)

// We only want to focus the omnibox on new tab pages
if (uri.asciiSpec != newTabUri().asciiSpec) {
newTab.focusedOmnibox.set(false)
}

tabs.update((tabs) => {
selectedTabId.set(newTab.getId())
return [...tabs, newTab]
Expand All @@ -29,18 +36,24 @@ export function openTab(uri: nsIURIType = newTabUri()) {

export function closeTab(tab: Tab) {
tabs.update((tabs) => {
const tabIndex = tabs.findIndex((t) => t.getId() == tab.getId())
const filtered = tabs.filter((t) => t.getId() != tab.getId())
const tabIndex = tabs.findIndex(matchTab(tab.getId()))
const filtered = tabs.filter(not(matchTab(tab.getId())))

if (filtered.length == 0) {
window.close()
return []
}

if (filtered[tabIndex]) {
selectedTabId.set(filtered[tabIndex].getId())
const lastTabId = tabHistory.prev()
const hasLastTab = filtered.some(matchTab(lastTabId))
if (hasLastTab) {
selectedTabId.set(lastTabId)
} else {
selectedTabId.set(filtered[tabIndex - 1].getId())
if (filtered[tabIndex]) {
selectedTabId.set(filtered[tabIndex].getId())
} else {
selectedTabId.set(filtered[tabIndex - 1].getId())
}
}

tab.destroy()
Expand All @@ -49,15 +62,15 @@ export function closeTab(tab: Tab) {
}

export function getTabById(id: number): Tab | undefined {
return tabs.readOnce().find((tab) => tab.getId() == id)
return tabs.readOnce().find(matchTab(id))
}

export function getCurrentTab(): Tab | undefined {
return getTabById(internalSelectedTab)
return getTabById(selectedTabId.readOnce())
}

export function setCurrentTab(tab: Tab) {
const index = tabs.readOnce().findIndex((t) => t.getId() == tab.getId())
const index = tabs.readOnce().findIndex(matchTab(tab.getId()))
setCurrentTabIndex(index)
}

Expand All @@ -67,7 +80,7 @@ export function runOnCurrentTab<R>(method: (tab: Tab) => R): R | undefined {
}

export function getCurrentTabIndex(): number {
return tabs.readOnce().findIndex((tab) => tab.getId() == internalSelectedTab)
return tabs.readOnce().findIndex(matchTab(selectedTabId.readOnce()))
}

export function setCurrentTabIndex(index: number) {
Expand All @@ -77,16 +90,14 @@ export function setCurrentTabIndex(index: number) {
if (index < 0) index = allTabs.length - 1
if (index >= allTabs.length) index = 0

selectedTabId.set(allTabs[index].getId())
const tabId = allTabs[index].getId()
selectedTabId.set(tabId)
}

export function moveTabBefore(toMoveId: number, targetId: number) {
tabs.update((tabs) => {
const toMoveIndex = tabs.findIndex((tab) => tab.getId() == toMoveId)
const targetIndex = Math.max(
tabs.findIndex((tab) => tab.getId() == targetId) - 1,
0,
)
const toMoveIndex = tabs.findIndex(matchTab(toMoveId))
const targetIndex = Math.max(tabs.findIndex(matchTab(targetId)) - 1, 0)

// If we do in-place modifications with tabs, svelte won't notice the
// change
Expand All @@ -98,8 +109,8 @@ export function moveTabBefore(toMoveId: number, targetId: number) {

export function moveTabAfter(toMoveId: number, targetId: number) {
tabs.update((tabs) => {
const toMoveIndex = tabs.findIndex((tab) => tab.getId() == toMoveId)
const targetIndex = tabs.findIndex((tab) => tab.getId() == targetId)
const toMoveIndex = tabs.findIndex(matchTab(toMoveId))
const targetIndex = tabs.findIndex(matchTab(targetId))

// If we do in-place modifications with tabs, svelte won't notice the
// change
Expand Down
2 changes: 2 additions & 0 deletions apps/content/src/shared/search/providers/EngineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export class EngineProvider extends Provider {
}

async getFastResults(query: string) {
if (query == '' || isUrlLike(query)) return []

const engine = await this.engine.promise
const defaultSearchResult: ProviderResult = {
title: query,
Expand Down
1 change: 1 addition & 0 deletions apps/content/src/shared/search/providers/URLProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export function isUrlLike(query: string): boolean {
export class URLProvider extends Provider {
public providerPriority = 0

/* eslint @typescript-eslint/no-unused-vars: 0 */
public async getResults(_query: string) {
return []
}
Expand Down
18 changes: 18 additions & 0 deletions apps/content/src/tests/shared/search/providers/EngineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,24 @@ export default async function () {
)
})

await test('EngineProvider: fast recomendations ignore URL like', async (t) => {
const provider = new EngineProvider()
{
const results = await provider.getFastResults('http://google.com')
t.eq(results, [], 'Should ignore full URLs')
}
{
const results = await provider.getFastResults('google.com')
t.eq(results, [], 'Should ignore domains')
}
{
const results = await provider.getFastResults(
'chrome://browser/content/tests/index.html',
)
t.eq(results, [], 'Should ignore chrome URLs')
}
})

for (const engine of SEARCH_ENGINE_IDS) {
await testProvider(engine)
}
Expand Down
2 changes: 2 additions & 0 deletions libs/link/types/globals/Elements.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ declare interface XULFindBarElement extends HTMLElement {
browser: XULBrowserElement
open()
close()

onFindCommand(): void
}

declare interface XULPanel extends HTMLElement {
Expand Down
8 changes: 8 additions & 0 deletions libs/shared/src/utilities/fn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

export const not =
<T extends Array<unknown>>(fn: (...args: T) => boolean) =>
(...args: T) =>
!fn(...args)
2 changes: 2 additions & 0 deletions libs/shared/src/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

export * from './deferred.js'
export * from './fn.js'
export * from './mitt.js'
export * from './ring.js'
export * from './svelte.js'
24 changes: 24 additions & 0 deletions libs/shared/src/utilities/ring.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

export class Ring<T> {
private values: T[]
private index = -1

constructor(count = 5) {
this.values = Array(count)
}

public next(value: T) {
this.index += 1
if (this.index >= this.values.length) this.index = 0
this.values[this.index] = value
}

public prev(): T {
this.index -= 1
if (this.index <= -1) this.index = this.values.length - 1
return this.values[this.index]
}
}

0 comments on commit a685208

Please sign in to comment.