Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,7 @@ Preview:
| search-engine | string | no | duckduckgo |
| new-tab | boolean | no | false |
| autofocus | boolean | no | false |
| use-layout | boolean | no | false |
| target | string | no | _blank |
| placeholder | string | no | Type here to search… |
| bangs | array | no | |
Expand All @@ -1239,6 +1240,9 @@ When set to `true`, swaps the shortcuts for showing results in the same or new t
##### `autofocus`
When set to `true`, automatically focuses the search input on page load.

##### `use-layout`
When set to `true`, the <kbd>S</kbd> search shortcut follows the active keyboard layout. By default, the shortcut uses the physical <kbd>S</kbd> key position regardless of layout.

##### `target`
The target to use when opening the search results in a new tab. Possible values are `_blank`, `_self`, `_parent` and `_top`.

Expand Down
4 changes: 3 additions & 1 deletion internal/glance/static/js/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function setupSearchBoxes() {
const defaultSearchUrl = widget.dataset.defaultSearchUrl;
const target = widget.dataset.target || "_blank";
const newTab = widget.dataset.newTab === "true";
const useLayout = widget.dataset.useLayout === "true";
const inputElement = widget.getElementsByClassName("search-input")[0];
const bangElement = widget.getElementsByClassName("search-bang")[0];
const bangs = widget.querySelectorAll(".search-bangs > input");
Expand Down Expand Up @@ -194,7 +195,8 @@ function setupSearchBoxes() {

document.addEventListener("keydown", (event) => {
if (['INPUT', 'TEXTAREA'].includes(document.activeElement.tagName)) return;
if (event.code != "KeyS") return;
if (useLayout && event.key.toLowerCase() != "s") return;
if (!useLayout && event.code != "KeyS") return;

inputElement.focus();
event.preventDefault();
Expand Down
2 changes: 1 addition & 1 deletion internal/glance/templates/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{{ define "widget-content-classes" }}widget-content-frameless{{ end }}

{{ define "widget-content" }}
<div class="search widget-content-frame padding-inline-widget flex gap-15 items-center" data-default-search-url="{{ .SearchEngine }}" data-new-tab="{{ .NewTab }}" data-target="{{ .Target }}">
<div class="search widget-content-frame padding-inline-widget flex gap-15 items-center" data-default-search-url="{{ .SearchEngine }}" data-new-tab="{{ .NewTab }}" data-target="{{ .Target }}" data-use-layout="{{ .UseLayout }}">
<div class="search-bangs">
{{ range .Bangs }}
<input type="hidden" data-shortcut="{{ .Shortcut }}" data-title="{{ .Title }}" data-url="{{ .URL }}">
Expand Down
5 changes: 3 additions & 2 deletions internal/glance/widget-search.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type searchWidget struct {
NewTab bool `yaml:"new-tab"`
Target string `yaml:"target"`
Autofocus bool `yaml:"autofocus"`
UseLayout bool `yaml:"use-layout"`
Placeholder string `yaml:"placeholder"`
}

Expand All @@ -36,8 +37,8 @@ var searchEngines = map[string]string{
"google": "https://www.google.com/search?q={QUERY}",
"bing": "https://www.bing.com/search?q={QUERY}",
"perplexity": "https://www.perplexity.ai/search?q={QUERY}",
"kagi": "https://kagi.com/search?q={QUERY}",
"startpage": "https://www.startpage.com/search?q={QUERY}",
"kagi": "https://kagi.com/search?q={QUERY}",
"startpage": "https://www.startpage.com/search?q={QUERY}",
}

func (widget *searchWidget) initialize() error {
Expand Down
17 changes: 17 additions & 0 deletions internal/glance/widget-search_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package glance

import (
"strings"
"testing"
)

func TestSearchWidgetRendersUseLayout(t *testing.T) {
widget := &searchWidget{UseLayout: true}
if err := widget.initialize(); err != nil {
t.Fatalf("initialize search widget: %v", err)
}

if !strings.Contains(string(widget.Render()), `data-use-layout="true"`) {
t.Fatal("expected rendered search widget to enable layout-aware shortcut handling")
}
}