diff --git a/background_scripts/completion/all_completers.js b/background_scripts/completion/all_completers.js
new file mode 100644
index 000000000..5f0d87c8b
--- /dev/null
+++ b/background_scripts/completion/all_completers.js
@@ -0,0 +1 @@
+export const completerNames = ["omni", "bookmarks", "tabs"];
diff --git a/background_scripts/main.js b/background_scripts/main.js
index 7d37e6b1b..ee9f2cf96 100644
--- a/background_scripts/main.js
+++ b/background_scripts/main.js
@@ -49,7 +49,7 @@ const completionSources = {
searchEngines: new SearchEngineCompleter(),
};
-const completers = {
+export const completers = {
omni: new MultiCompleter([
completionSources.bookmarks,
completionSources.history,
diff --git a/pages/vomnibar_page.css b/pages/vomnibar_page.css
index 1c5efdf16..a8774ea88 100644
--- a/pages/vomnibar_page.css
+++ b/pages/vomnibar_page.css
@@ -22,23 +22,39 @@ ul {
z-index: 2139999999;
}
-#vomnibar input {
+#vomnibar-search-area * {
font-size: 20px;
height: 34px;
margin-bottom: 0;
padding: 4px;
- background-color: white;
- color: black;
border-radius: 3px;
border: 1px solid #e8e8e8;
box-shadow: #444 0px 0px 1px;
- width: 100%;
outline: none;
box-sizing: border-box;
}
+#vomnibar #completer-name {
+ margin-right: 8px;
+ font-size: 12px;
+ display: flex;
+ align-items: center;
+ background: unset;
+ color: #990000;
+}
+
+#vomnibar-search-area .mode:empty {
+ display: none;
+}
+
+#vomnibar-search-area input {
+ background-color: white;
+ color: black;
+ width: 100%;
+}
+
#vomnibar-search-area {
- display: block;
+ display: flex;
padding: 10px;
border-radius: 4px 4px 0 0;
border-bottom: 1px solid #c6c9ce;
@@ -149,6 +165,11 @@ ul {
border-bottom: 1px solid var(--vimium-foreground-color);
}
+ #vomnibar-search-area #completer-name {
+ color: #999000;
+ border: 1px solid var(--vimium-foreground-color);
+ }
+
#vomnibar input {
background-color: var(--vimium-foreground-color);
color: var(--vimium-foreground-text-color);
diff --git a/pages/vomnibar_page.html b/pages/vomnibar_page.html
index bb7b6f10d..2e4f1d7e9 100644
--- a/pages/vomnibar_page.html
+++ b/pages/vomnibar_page.html
@@ -11,6 +11,7 @@
+
diff --git a/pages/vomnibar_page.js b/pages/vomnibar_page.js
index eaef28dfd..a00569115 100644
--- a/pages/vomnibar_page.js
+++ b/pages/vomnibar_page.js
@@ -13,6 +13,7 @@ import "../lib/dom_utils.js";
import "../lib/handler_stack.js";
import * as UIComponentMessenger from "./ui_component_messenger.js";
import * as userSearchEngines from "../background_scripts/user_search_engines.js";
+import { completerNames } from "../background_scripts/completion/all_completers.js";
export let ui; // An instance of VomnibarUI.
@@ -98,6 +99,7 @@ class VomnibarUI {
hide(onHiddenCallback = null) {
this.onHiddenCallback = onHiddenCallback;
this.input.blur();
+ this.label.textContent = "";
this.reset();
// Wait until this iframe's DOM has been rendered before hiding the iframe. This is to prevent
// Chrome caching the previous visual state of the vomnibar iframe. See #4708.
@@ -178,6 +180,12 @@ class VomnibarUI {
return "remove";
} else if (KeyboardUtils.isBackspace(event)) {
return "delete";
+ } else if (event.altKey && key == "m") {
+ return "cycle-completer-next";
+ } else if (event.altKey && key == "M") {
+ return "cycle-completer-prev";
+ } else if (event.altKey && key == "n") {
+ return "switch-new-tab";
}
return null;
@@ -243,6 +251,18 @@ class VomnibarUI {
} else if ((action === "remove") && (this.selection >= 0)) {
const completion = this.completions[this.selection];
console.log(completion);
+ } else if (action == "cycle-completer-next") {
+ const size = completerNames.length;
+ this.completerName = completerNames[(completerNames.indexOf(this.completerName) + 1) % size];
+ this.update();
+ } else if (action == "cycle-completer-prev") {
+ const size = completerNames.length;
+ this.completerName =
+ completerNames[(completerNames.indexOf(this.completerName) + size - 1) % size];
+ this.update();
+ } else if (action == "switch-new-tab" && this.completerName != "tabs") {
+ this.forceNewTab = !this.forceNewTab;
+ this.update();
}
event.stopImmediatePropagation();
@@ -397,6 +417,10 @@ class VomnibarUI {
}
async update() {
+ this.label.textContent = this.completerName.toUpperCase();
+ if (this.forceNewTab) {
+ this.label.textContent += "\u00A0+";
+ }
await this.updateCompletions();
this.input.focus();
}
@@ -424,6 +448,7 @@ class VomnibarUI {
initDom() {
this.box = document.getElementById("vomnibar");
+ this.label = document.getElementById("completer-name");
this.input = this.box.querySelector("input");
this.input.addEventListener("input", this.onInput);
this.input.addEventListener("keydown", this.onKeyEvent);
diff --git a/tests/unit_tests/completion/completers_test.js b/tests/unit_tests/completion/completers_test.js
index a18af89bb..e6a4d450d 100644
--- a/tests/unit_tests/completion/completers_test.js
+++ b/tests/unit_tests/completion/completers_test.js
@@ -17,6 +17,8 @@ import {
import * as ranking from "../../../background_scripts/completion/ranking.js";
import { RegexpCache } from "../../../background_scripts/completion/ranking.js";
import "../../../lib/url_utils.js";
+import { completers } from "../../../background_scripts/main.js";
+import { completerNames } from "../../../background_scripts/completion/all_completers.js";
const hours = (n) => 1000 * 60 * 60 * n;
@@ -28,6 +30,12 @@ const filterCompleter = async (completer, queryTerms) => {
});
};
+context("completer list", () => {
+ should("define all completers", () => {
+ assert.equal(Object.keys(completers), completerNames);
+ });
+});
+
context("bookmark completer", () => {
const bookmark3 = { title: "bookmark3", url: "bookmark3.com" };
const bookmark2 = { title: "bookmark2", url: "bookmark2.com" };