Repository: alyssaxuu/omni
Branch: master
Commit: 8bd26168ec17
Files: 24
Total size: 313.5 KB
Directory structure:
gitextract_czb4mn5n/
├── .editorconfig
├── .gitattributes
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── firefox/
│ ├── assets/
│ │ └── nice-select.css
│ ├── background.js
│ ├── content.css
│ ├── content.html
│ ├── content.js
│ ├── focus.js
│ ├── jquery.js
│ ├── manifest.json
│ └── newtab.html
└── src/
├── assets/
│ └── nice-select.css
├── background.js
├── content.css
├── content.html
├── content.js
├── focus.js
├── jquery.js
├── manifest.json
└── newtab.html
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
indent_style = tab
end_of_line = crlf
charset = utf-8
trim_trailing_whitespace = false
indent_size = 2
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .gitattributes
================================================
# Auto detect text files and perform LF normalization
* text=auto
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: alyssaxuu
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
================================================
FILE: .gitignore
================================================
.history
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 Alyssa X
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Omni

The most powerful interface for your browser 🔥
With Omni you can use your browser like a pro. Manage tabs, bookmarks, your browser history, perform all sorts of actions and more with a simple command interface.
👉 Get it now [for Chrome](https://chrome.google.com/webstore/detail/omni/mapjgeachilmcbbokkgcbgpbakaaeehi?hl=en&authuser=0) and [for Firefox](https://addons.mozilla.org/en-GB/firefox/addon/omnisearch/)
> You can support this project (and many others) through [GitHub Sponsors](https://github.com/sponsors/alyssaxuu)! ❤️
Made by [Alyssa X](https://twitter.com/alyssaxuu)
## Table of contents
- [Features](#features)
- [Controlling the interface](#controlling-the-interface)
- [Opening Omni](#opening-omni)
- [Closing Omni](#closing-omni)
- [Switching between dark and light mode](#switching-between-dark-and-light-mode)
- [List of commands](#list-of-commands)
- [Self-hosting Omni](#self-hosting-omni)
- [Installing on Chrome](#installing-on-chrome)
- [Installing on Firefox](#installing-on-firefox)
- [Libraries used](#libraries-used)
## Features
🗄 Switch, open, close, and search your tabs 📚 Browse and manage your bookmarks 🔍 Search your browsing history ⚡️ 50+ actions to improve your productivity 🔮 Special commands to filter and perform more actions 🧩 Integrations with Notion, Figma, Docs, Asana... ⌨️ Shortcuts for actions such as muting, pinning, bookmarking... ⚙️ Advanced settings to help troubleshoot browsing issues 🌙 Dark mode ...and much more - all for free & no sign in needed!
## Controlling the interface
### Opening Omni
To open Omni, simply press `⌘+Shift+K` on Mac or `Ctrl+Shift+K` on Windows. You can change the shortcut by going to chrome://extensions/shortcuts in Chrome, or by following [these steps](https://support.mozilla.org/en-US/kb/manage-extension-shortcuts-firefox) in Firefox
Alternatively you can click on the extension icon in the toolbar to toggle it.
### Closing Omni
To close Omni you can press `Esc`, click on the background, or press the extension icon.
### Switching between dark and light mode
The dark and light theme in Omni is tied to your system's theme.
On Mac you can change the theme by clicking on the Apple menu (on the top left), opening the System preferences, going into the General section, and then choosing between dark, light, or auto.
On Windows it depends on the OS version. [Here is a guide for Windows 11 and 10.](https://support.microsoft.com/en-us/windows/change-desktop-background-and-colors-176702ca-8e24-393b-15f2-b15b38f69de6#ID0EBF=Windows_11)
After switching the theme you might need to restart your browser.
## List of commands
You can use a variety of commands with Omni to perform actions or filter your results.
- **/tabs**: Search your tabs
- **/bookmarks**: Search your bookmarks
- **/history**: Search your browser history
- **/actions**: Search all available actions
- **/remove**: Remove a bookmark or close a tab
Feel free to suggest new commands for Omni by [making an issue](https://github.com/alyssaxuu/omni/issues/new).
## Self-hosting Omni
You can run Omni locally without having to install it from the Chrome Store or from Firefox Add-ons.
### Installing on Chrome
1. Download the code. In the web version of GitHub, you can do that by clicking the green "Code" button, and then "Download ZIP".
2. Go to chrome://extensions/ in your browser, and [enable developer mode](https://developer.chrome.com/docs/extensions/mv2/faq/#:~:text=You%20can%20start%20by%20turning,a%20packaged%20extension%2C%20and%20more.).
3. Drag the [src folder](https://github.com/alyssaxuu/omni/tree/master/src) (make sure it's a folder and not a ZIP file, so unzip first), or click on the "Load unpacked" button and locate the folder.
4. That's it, you will now be able to use Omni locally.
### Installing on Firefox
1. Download the code. In the web version of GitHub, you can do that by clicking the green "Code" button, and then "Download ZIP".
2. Open the about:debugging page in your browser, click the "This Firefox" option.
3. Click the "Load Temporary Add-on" button, and select any file inside the [firefox folder](https://github.com/alyssaxuu/omni/tree/master/firefox)
4. That's it, you will now be able to use Omni locally.
## Libraries used
- [jQuery](https://jquery.com/) - for better event handling and DOM manipulation
- [dom-focus-lock](https://github.com/theKashey/dom-focus-lock) - to keep focus on the input field
#
Feel free to reach out to me through email at hi@alyssax.com or [on Twitter](https://twitter.com/alyssaxuu) if you have any questions or feedback! Hope you find this useful 💜
================================================
FILE: firefox/assets/nice-select.css
================================================
.nice-select {
-webkit-tap-highlight-color: transparent;
background-color: #fff;
border-radius: 5px;
border: solid 1px #e8e8e8;
box-sizing: border-box;
clear: both;
cursor: pointer;
display: block;
float: left;
font-family: inherit;
font-size: 14px;
font-weight: normal;
height: 42px;
line-height: 40px;
outline: none;
padding-left: 18px;
padding-right: 30px;
position: relative;
text-align: left !important;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: auto; }
.nice-select:hover {
border-color: #dbdbdb; }
.nice-select:active, .nice-select.open, .nice-select:focus {
border-color: #999; }
.nice-select:after {
border-bottom: 2px solid #999;
border-right: 2px solid #999;
content: '';
display: block;
height: 5px;
margin-top: -4px;
pointer-events: none;
position: absolute;
right: 12px;
top: 50%;
-webkit-transform-origin: 66% 66%;
-ms-transform-origin: 66% 66%;
transform-origin: 66% 66%;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: all 0.15s ease-in-out;
transition: all 0.15s ease-in-out;
width: 5px; }
.nice-select.open:after {
-webkit-transform: rotate(-135deg);
-ms-transform: rotate(-135deg);
transform: rotate(-135deg); }
.nice-select.open .list {
opacity: 1;
pointer-events: auto;
-webkit-transform: scale(1) translateY(0);
-ms-transform: scale(1) translateY(0);
transform: scale(1) translateY(0); }
.nice-select.disabled {
border-color: #ededed;
color: #999;
pointer-events: none; }
.nice-select.disabled:after {
border-color: #cccccc; }
.nice-select.wide {
width: 100%; }
.nice-select.wide .list {
left: 0 !important;
right: 0 !important; }
.nice-select.right {
float: right; }
.nice-select.right .list {
left: auto;
right: 0; }
.nice-select.small {
font-size: 12px;
height: 36px;
line-height: 34px; }
.nice-select.small:after {
height: 4px;
width: 4px; }
.nice-select.small .option {
line-height: 34px;
min-height: 34px; }
.nice-select .list {
background-color: #fff;
border-radius: 5px;
box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
box-sizing: border-box;
margin-top: 4px;
opacity: 0;
overflow: hidden;
padding: 0;
pointer-events: none;
position: absolute;
top: 100%;
left: 0;
-webkit-transform-origin: 50% 0;
-ms-transform-origin: 50% 0;
transform-origin: 50% 0;
-webkit-transform: scale(0.75) translateY(-21px);
-ms-transform: scale(0.75) translateY(-21px);
transform: scale(0.75) translateY(-21px);
-webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
z-index: 9; }
.nice-select .list:hover .option:not(:hover) {
background-color: transparent !important; }
.nice-select .option {
cursor: pointer;
font-weight: 400;
line-height: 40px;
list-style: none;
min-height: 40px;
outline: none;
padding-left: 18px;
padding-right: 29px;
text-align: left;
-webkit-transition: all 0.2s;
transition: all 0.2s; }
.nice-select .option:hover, .nice-select .option.focus, .nice-select .option.selected.focus {
background-color: #f6f6f6; }
.nice-select .option.selected {
font-weight: bold; }
.nice-select .option.disabled {
background-color: transparent;
color: #999;
cursor: default; }
.no-csspointerevents .nice-select .list {
display: none; }
.no-csspointerevents .nice-select.open .list {
display: block; }
================================================
FILE: firefox/background.js
================================================
let actions = [];
let newtaburl = "";
// Clear actions and append default ones
const clearActions = () => {
getCurrentTab().then((response) => {
actions = [];
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
let muteaction = {title:"Mute tab", desc:"Mute the current tab", type:"action", action:"mute", emoji:true, emojiChar:"🔇", keycheck:true, keys:['⌥','⇧', 'M']};
let pinaction = {title:"Pin tab", desc:"Pin the current tab", type:"action", action:"pin", emoji:true, emojiChar:"📌", keycheck:true, keys:['⌥','⇧', 'P']};
if (response.mutedInfo.muted) {
muteaction = {title:"Unmute tab", desc:"Unmute the current tab", type:"action", action:"unmute", emoji:true, emojiChar:"🔈", keycheck:true, keys:['⌥','⇧', 'M']};
}
if (response.pinned) {
pinaction = {title:"Unpin tab", desc:"Unpin the current tab", type:"action", action:"unpin", emoji:true, emojiChar:"📌", keycheck:true, keys:['⌥','⇧', 'P']};
}
actions = [
{title:"New tab", desc:"Open a new tab", type:"action", action:"new-tab", emoji:true, emojiChar:"✨", keycheck:true, keys:['⌘','T']},
{title:"Bookmark", desc:"Create a bookmark", type:"action", action:"create-bookmark", emoji:true, emojiChar:"📕", keycheck:true, keys:['⌘','D']},
pinaction,
{title:"Fullscreen", desc:"Make the page fullscreen", type:"action", action:"fullscreen", emoji:true, emojiChar:"🖥", keycheck:true, keys:['⌘', 'Ctrl', 'F']},
muteaction,
{title:"Reload", desc:"Reload the page", type:"action", action:"reload", emoji:true, emojiChar:"♻️", keycheck:true, keys:['⌘','⇧', 'R']},
{title:"Help", desc:"Get help with Omni on GitHub", type:"action", action:"url", url:"https://github.com/alyssaxuu/omni", emoji:true, emojiChar:"🤔", keycheck:false},
{title:"Compose email", desc:"Compose a new email", type:"action", action:"email", emoji:true, emojiChar:"✉️", keycheck:true, keys:['⌥','⇧', 'C']},
{title:"Print page", desc:"Print the current page", type:"action", action:"print", emoji:true, emojiChar:"🖨️", keycheck:true, keys:['⌘', 'P']},
{title:"New Notion page", desc:"Create a new Notion page", type:"action", action:"url", url:"https://notion.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-notion.png"), keycheck:false},
{title:"New Sheets spreadsheet", desc:"Create a new Google Sheets spreadsheet", type:"action", action:"url", url:"https://sheets.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-sheets.png"), keycheck:false},
{title:"New Docs document", desc:"Create a new Google Docs document", type:"action", action:"url", emoji:false, url:"https://docs.new", favIconUrl:browser.runtime.getURL("assets/logo-docs.png"), keycheck:false},
{title:"New Slides presentation", desc:"Create a new Google Slides presentation", type:"action", action:"url", url:"https://slides.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-slides.png"), keycheck:false},
{title:"New form", desc:"Create a new Google Forms form", type:"action", action:"url", url:"https://forms.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-forms.png"), keycheck:false},
{title:"New Medium story", desc:"Create a new Medium story", type:"action", action:"url", url:"https://story.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-medium.png"), keycheck:false},
{title:"New GitHub repository", desc:"Create a new GitHub repository", type:"action", action:"url", url:"https://github.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-github.png"), keycheck:false},
{title:"New GitHub gist", desc:"Create a new GitHub gist", type:"action", action:"url", url:"https://gist.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-github.png"), keycheck:false},
{title:"New CodePen pen", desc:"Create a new CodePen pen", type:"action", action:"url", url:"https://pen.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-codepen.png"), keycheck:false},
{title:"New Excel spreadsheet", desc:"Create a new Excel spreadsheet", type:"action", action:"url", url:"https://excel.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-excel.png"), keycheck:false},
{title:"New PowerPoint presentation", desc:"Create a new PowerPoint presentation", type:"action", url:"https://powerpoint.new", action:"url", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-powerpoint.png"), keycheck:false},
{title:"New Word document", desc:"Create a new Word document", type:"action", action:"url", url:"https://word.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-word.png"), keycheck:false},
{title:"Create a whiteboard", desc:"Create a collaborative whiteboard", type:"action", action:"url", url:"https://whiteboard.new", emoji:true, emojiChar:"🧑🏫", keycheck:false},
{title:"Record a video", desc:"Record and edit a video", type:"action", action:"url", url:"https://recording.new", emoji:true, emojiChar:"📹", keycheck:false},
{title:"Create a Figma file", desc:"Create a new Figma file", type:"action", action:"url", url:"https://figma.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-figma.png"), keycheck:false},
{title:"Create a FigJam file", desc:"Create a new FigJam file", type:"action", action:"url", url:"https://figjam.new", emoji:true, emojiChar:"🖌", keycheck:false},
{title:"Hunt a product", desc:"Submit a product to Product Hunt", type:"action", action:"url", url:"https://www.producthunt.com/posts/new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-producthunt.png"), keycheck:false},
{title:"Make a tweet", desc:"Make a tweet on Twitter", type:"action", action:"url", url:"https://twitter.com/intent/tweet", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-twitter.png"), keycheck:false},
{title:"Create a playlist", desc:"Create a Spotify playlist", type:"action", action:"url", url:"https://playlist.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-spotify.png"), keycheck:false},
{title:"Create a Canva design", desc:"Create a new design with Canva", type:"action", action:"url", url:"https://design.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-canva.png"), keycheck:false},
{title:"Create a new podcast episode", desc:"Create a new podcast episode with Anchor", type:"action", action:"url", url:"https://episode.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-anchor.png"), keycheck:false},
{title:"Edit an image", desc:"Edit an image with Adobe Photoshop", type:"action", action:"url", url:"https://photo.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-photoshop.png"), keycheck:false},
{title:"Convert to PDF", desc:"Convert a file to PDF", type:"action", action:"url", url:"https://pdf.new", emoji:true, emojiChar:"📄", keycheck:false},
{title:"Scan a QR code", desc:"Scan a QR code with your camera", type:"action", action:"url", url:"https://scan.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-qr.png"), keycheck:false},
{title:"Add a task to Asana", desc:"Create a new task in Asana", type:"action", action:"url", url:"https://task.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-asana.png"), keycheck:false},
{title:"Add an issue to Linear", desc:"Create a new issue in Linear", type:"action", action:"url", url:"https://linear.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-linear.png"), keycheck:false},
{title:"Add a task to WIP", desc:"Create a new task in WIP", type:"action", action:"url", url:"https://todo.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-wip.png"), keycheck:false},
{title:"Create an event", desc:"Add an event to Google Calendar", type:"action", action:"url", url:"https://cal.new", emoji:false, favIconUrl:browser.runtime.getURL("assets/logo-calendar.png"), keycheck:false},
{title:"Add a note", desc:"Add a note to Google Keep", type:"action", action:"url", emoji:false, url:"https://note.new", favIconUrl:browser.runtime.getURL("assets/logo-keep.png"), keycheck:false},
{title:"New meeting", desc:"Start a Google Meet meeting", type:"action", action:"url", emoji:false, url:"https://meet.new", favIconUrl:browser.runtime.getURL("assets/logo-meet.png"), keycheck:false},
{title:"Browsing history", desc:"Browse through your browsing history", type:"action", action:"history", emoji:true, emojiChar:"🗂", keycheck:true, keys:['⌘','Y']},
{title:"Incognito mode", desc:"Open an incognito window", type:"action", action:"incognito", emoji:true, emojiChar:"🕵️", keycheck:true, keys:['⌘','⇧', 'N']},
{title:"Downloads", desc:"Browse through your downloads", type:"action", action:"downloads", emoji:true, emojiChar:"📦", keycheck:true, keys:['⌘','⇧', 'J']},
{title:"Extensions", desc:"Manage your browser Extensions", type:"action", action:"extensions", emoji:true, emojiChar:"🧩", keycheck:false, keys:['⌘','D']},
{title:"browser settings", desc:"Open the browser settings", type:"action", action:"settings", emoji:true, emojiChar:"⚙️", keycheck:true, keys:['⌘',',']},
{title:"Scroll to bottom", desc:"Scroll to the bottom of the page", type:"action", action:"scroll-bottom", emoji:true, emojiChar:"👇", keycheck:true, keys:['⌘','↓']},
{title:"Scroll to top", desc:"Scroll to the top of the page", type:"action", action:"scroll-top", emoji:true, emojiChar:"👆", keycheck:true, keys:['⌘','↑']},
{title:"Go back", desc:"Go back in history for the current tab", type:"action", action:"go-back", emoji:true, emojiChar:"👈", keycheck:true, keys:['⌘','←']},
{title:"Go forward", desc:"Go forward in history for the current tab", type:"action", action:"go-forward", emoji:true, emojiChar:"👉", keycheck:true, keys:['⌘','→']},
{title:"Duplicate tab", desc:"Make a copy of the current tab", type:"action", action:"duplicate-tab", emoji:true, emojiChar:"📋", keycheck:true, keys:['⌥','⇧', 'D']},
{title:"Close tab", desc:"Close the current tab", type:"action", action:"close-tab", emoji:true, emojiChar:"🗑", keycheck:true, keys:['⌘','W']},
{title:"Close window", desc:"Close the current window", type:"action", action:"close-window", emoji:true, emojiChar:"💥", keycheck:true, keys:['⌘','⇧', 'W']},
{title:"Manage browsing data", desc:"Manage your browsing data", type:"action", action:"manage-data", emoji:true, emojiChar:"🔬", keycheck:true, keys:['⌘','⇧', 'Delete']},
{title:"Clear all browsing data", desc:"Clear all of your browsing data", type:"action", action:"remove-all", emoji:true, emojiChar:"🧹", keycheck:false, keys:['⌘','D']},
{title:"Clear browsing history", desc:"Clear all of your browsing history", type:"action", action:"remove-history", emoji:true, emojiChar:"🗂", keycheck:false, keys:['⌘','D']},
{title:"Clear cookies", desc:"Clear all cookies", type:"action", action:"remove-cookies", emoji:true, emojiChar:"🍪", keycheck:false, keys:['⌘','D']},
{title:"Clear cache", desc:"Clear the cache", type:"action", action:"remove-cache", emoji:true, emojiChar:"🗄", keycheck:false, keys:['⌘','D']},
{title:"Clear local storage", desc:"Clear the local storage", type:"action", action:"remove-local-storage", emoji:true, emojiChar:"📦", keycheck:false, keys:['⌘','D']},
{title:"Clear passwords", desc:"Clear all saved passwords", type:"action", action:"remove-passwords", emoji:true, emojiChar:"🔑", keycheck:false, keys:['⌘','D']},
];
if (!isMac) {
for (action of actions) {
switch (action.action) {
case "reload":
action.keys = ['F5'];
break;
case "fullscreen":
action.keys = ['F11'];
break;
case "downloads":
action.keys = ['Ctrl', 'J'];
break;
case "settings":
action.keycheck = false;
break;
case "history":
action.keys = ['Ctrl', 'H'];
break;
case "go-back":
action.keys = ['Alt','←'];
break;
case "go-forward":
action.keys = ['Alt','→']
break;
case "scroll-top":
action.keys = ['Home'];
break;
case "scroll-bottom":
action.keys = ['End'];
break;
}
for (const key in action.keys) {
if (action.keys[key] === "⌘") {
action.keys[key] = "Ctrl";
} else if (action.keys[key] === "⌥") {
action.keys[key] = "Alt";
}
};
};
}
});
}
// Open on install
browser.runtime.onInstalled.addListener((object) => {
// Inject Omni on install
const manifest = browser.runtime.getManifest();
const injectIntoTab = (tab) => {
const scripts = manifest.content_scripts[0].js;
const s = scripts.length;
for (let i = 0; i < s; i++) {
browser.tabs.executeScript(tab.id, {
file: scripts[i]
});
}
browser.tabs.insertCSS(tab.id, {
file: manifest.content_scripts[0].css[0],
});
};
// Get all windows
browser.windows.getAll(
{
populate: true,
},
(windows) => {
let currentWindow;
const w = windows.length;
for (let i = 0; i < w; i++) {
currentWindow = windows[i];
let currentTab;
const t = currentWindow.tabs.length;
for (let j = 0; j < t; j++) {
currentTab = currentWindow.tabs[j];
if (!currentTab.url.includes("browser://") && !currentTab.url.includes("browser-extension://") && !currentTab.url.includes("browser.google.com")) {
injectIntoTab(currentTab);
}
}
}
}
);
if (object.reason === "install") {
browser.tabs.create({ url: "https://github.com/alyssaxuu/omni" });
}
});
// Check when the extension button is clicked
browser.browserAction.onClicked.addListener((tab) => {
browser.tabs.sendMessage(tab.id, {request: "open-omni"});
});
// Listen for the open omni shortcut
browser.commands.onCommand.addListener((command) => {
if (command === "open-omni") {
getCurrentTab().then((response) => {
if (!response.url.includes("browser://") && !response.url.includes("browser.google.com")) {
browser.tabs.sendMessage(response.id, {request: "open-omni"});
} else {
browser.tabs.create({
url: "./newtab.html"
}).then(() => {
newtaburl = response.url;
browser.tabs.remove(response.id);
})
}
});
}
});
// Get the current tab
const getCurrentTab = async () => {
const queryOptions = { active: true, currentWindow: true };
const [tab] = await browser.tabs.query(queryOptions);
return tab;
}
// Restore the new tab page (workaround to show Omni in new tab page)
function restoreNewTab() {
getCurrentTab().then((response) => {
browser.tabs.create({
url: newtaburl
}).then(() => {
browser.tabs.remove(response.id);
})
})
}
const resetOmni = () => {
clearActions();
getTabs();
getBookmarks();
var search = [
{title:"Search", desc:"Search for a query", type:"action", action:"search", emoji:true, emojiChar:"🔍", keycheck:false},
{title:"Search", desc:"Go to website", type:"action", action:"goto", emoji:true, emojiChar:"🔍", keycheck:false}
];
actions = search.concat(actions);
}
// Check if tabs have changed and actions need to be fetched again
browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => resetOmni());
browser.tabs.onCreated.addListener((tab) => resetOmni());
browser.tabs.onRemoved.addListener((tabId, changeInfo) => resetOmni());
// Get tabs to populate in the actions
const getTabs = () => {
browser.tabs.query({}, (tabs) => {
tabs.forEach((tab) => {
tab.desc = "browser tab";
tab.keycheck = false;
tab.action = "switch-tab";
tab.type = "tab";
})
actions = tabs.concat(actions);
});
}
// Get bookmarks to populate in the actions
const getBookmarks = () => {
const process_bookmark = (bookmarks) => {
for (const bookmark of bookmarks) {
if (bookmark.url) {
actions.push({title:bookmark.title, desc:"Bookmark", id:bookmark.id, url:bookmark.url, type:"bookmark", action:"bookmark", emoji:true, emojiChar:"⭐️", keycheck:false})
}
if (bookmark.children) {
process_bookmark(bookmark.children);
}
}
}
browser.bookmarks.getRecent(100, process_bookmark);
}
// Lots of different actions
const switchTab = (tab) => {
browser.tabs.highlight({
tabs: tab.index,
windowId: tab.windowId
})
browser.windows.update(
tab.windowId,
{ focused: true }
)
}
const goBack = (tab) => {
browser.tabs.goBack({
tabs: tab.index
})
}
const goForward = (tab) => {
browser.tabs.goForward({
tabs: tab.index
})
}
const duplicateTab = (tab) => {
getCurrentTab().then((response) => {
browser.tabs.duplicate(response.id);
})
}
const createBookmark = (tab) => {
getCurrentTab().then((response) => {
browser.bookmarks.create({
title: response.title,
url: response.url
});
})
}
const muteTab = (mute) =>{
getCurrentTab().then((response) => {
browser.tabs.update(response.id, {"muted": mute})
});
}
const reloadTab = () => {
browser.tabs.reload();
}
const pinTab = (pin) => {
getCurrentTab().then((response) => {
browser.tabs.update(response.id, {"pinned": pin})
});
}
const clearAllData = () => {
browser.browsingData.remove({
"since": (new Date()).getTime()
}, {
"appcache": true,
"cache": true,
"cacheStorage": true,
"cookies": true,
"downloads": true,
"fileSystems": true,
"formData": true,
"history": true,
"indexedDB": true,
"localStorage": true,
"passwords": true,
"serviceWorkers": true,
"webSQL": true
});
}
const clearBrowsingData = () => {
browser.browsingData.removeHistory({"since": 0});
}
const clearCookies = () =>{
browser.browsingData.removeCookies({"since": 0});
}
const clearCache = () => {
browser.browsingData.removeCache({"since": 0});
}
const clearLocalStorage = () => {
browser.browsingData.removeLocalStorage({"since": 0});
}
const clearPasswords = () => {
browser.browsingData.removePasswords({"since": 0});
}
const openbrowserUrl = (url) => {
browser.tabs.create({url: 'browser://'+url+'/'});
}
const openIncognito = () => {
browser.windows.create({"incognito": true});
}
const closeWindow = (id) => {
browser.windows.remove(id);
}
const closeTab = (tab) => {
browser.tabs.remove(tab.id);
}
const closeCurrentTab = () => {
getCurrentTab().then(closeTab)
}
const removeBookmark = (bookmark) => {
browser.bookmarks.remove(bookmark.id);
}
// Receive messages from any tab
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.request) {
case "get-actions":
resetOmni();
sendResponse({actions: actions});
break;
case "switch-tab":
switchTab(message.tab);
break;
case "go-back":
goBack(message.tab);
break;
case "go-forward":
goForward(message.tab);
break;
case "duplicate-tab":
duplicateTab(message.tab);
break;
case "create-bookmark":
createBookmark(message.tab);
break;
case "mute":
muteTab(true);
break;
case "unmute":
muteTab(false);
break;
case "reload":
reloadTab();
break;
case "pin":
pinTab(true);
break;
case "unpin":
pinTab(false);
break;
case "remove-all":
clearAllData();
break;
case "remove-history":
clearBrowsingData();
break;
case "remove-cookies":
clearCookies();
break;
case "remove-cache":
clearCache();
break;
case "remove-local-storage":
clearLocalStorage();
break;
case "remove-passwords":
clearPasswords();
case "history": // Fallthrough
case "downloads":
case "extensions":
case "settings":
case "extensions/shortcuts":
openbrowserUrl(message.request);
break;
case "manage-data":
openbrowserUrl("settings/clearBrowserData");
break;
case "incognito":
openIncognito();
break;
case "close-window":
closeWindow(sender.tab.windowId);
break;
case "close-tab":
closeCurrentTab();
break;
case "search-history":
browser.history.search({text:message.query, maxResults:9e9, startTime:0}).then((data) => {
data.forEach((action, index) => {
action.type = "history";
action.emoji = true;
action.emojiChar = "🏛";
action.action = "history";
action.keyCheck = false;
});
sendResponse({history:data});
})
return true;
case "search-bookmarks":
browser.bookmarks.search({query:message.query}).then((data) => {
// The index property of the bookmark appears to be causing issues, iterating separately...
data.filter(x => x.index == 0).forEach((action, index) => {
if (!action.url) {
data.splice(index, 1);
}
action.type = "bookmark";
action.emoji = true;
action.emojiChar = "⭐️";
action.action = "bookmark";
action.keyCheck = false;
})
data.forEach((action, index) => {
if (!action.url) {
data.splice(index, 1);
}
action.type = "bookmark";
action.emoji = true;
action.emojiChar = "⭐️";
action.action = "bookmark";
action.keyCheck = false;
})
sendResponse({bookmarks:data});
})
return true;
case "remove":
if (message.type == "bookmark") {
removeBookmark(message.action);
} else {
closeTab(message.action);
}
break;
case "search":
browser.search.search(
{query:message.query}
)
break;
case "restore-new-tab":
restoreNewTab();
break;
case "close-omni":
getCurrentTab().then((response) => {
browser.tabs.sendMessage(response.id, {request: "close-omni"});
});
break;
}
});
// Get actions
resetOmni();
================================================
FILE: firefox/content.css
================================================
.omni-extension {
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
font-smoothing: antialiased;
font-weight: 400;
}
/* Scrollbar size */
.omni-extension ::-webkit-scrollbar {
width: 10px;
height: 10px;
}
.omni-extension ::-webkit-scrollbar-thumb {
background-color: rgba(127, 127, 127, 0.6);
background-clip: padding-box;
border: 2px solid transparent;
border-radius: 5px;
}
.omni-extension ::-webkit-scrollbar-thumb:vertical:hover,
.omni-extension ::-webkit-scrollbar-thumb:horizontal:hover {
background-color: rgb(110, 110, 110);
}
.omni-extension ::-webkit-scrollbar-track {
background-color: transparent;
}
.omni-extension ::-webkit-scrollbar-thumb:vertical:active,
.omni-extension ::-webkit-scrollbar-thumb:horizontal:active {
background: rgba(95, 91, 91, 1);
}
.omni-extension ::-webkit-scrollbar-corner {
background: none;
}
@media (prefers-color-scheme: dark) {
.omni-extension {
--background: #1e2128;
--border: #35373e;
--text: #f1f1f1;
--text-2: #c5c6ca;
--text-3: #a5a5ae;
--select: #17191e;
--accent: #6068d2;
--accent-hover: #484fac;
--shortcut: #383e4a;
--placeholder: #63687b;
--background-2: #292d36;
}
}
@media (prefers-color-scheme: light) {
.omni-extension {
--background: #fafcff;
--border: #f2f3fb;
--text: #2b2d41;
--text-2: #2b2d41;
--text-3: #929db2;
--select: #eff3f9;
--accent: #6068d2;
--accent-hover: #484fac;
--shortcut: #dadeea;
--placeholder: #bac2d1;
--background-2: #292d36;
}
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 400;
src: url("moz-extension://__MSG_@@extension_id__/assets/Inter-Regular.ttf");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 500;
src: url("moz-extension://__MSG_@@extension_id__/assets/Inter-Medium.ttf");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 600;
src: url("moz-extension://__MSG_@@extension_id__/assets/Inter-SemiBold.ttf");
}
@font-face {
font-family: "Inter";
font-style: normal;
font-weight: 700;
src: url("moz-extension://__MSG_@@extension_id__/assets/Inter-Bold.ttf");
}
.omni-extension * {
display: block;
width: unset;
box-shadow: unset;
padding: unset;
margin: unset;
background-color: unset;
border-radius: unset;
}
.omni-extension .omni-item-details * {
line-height: normal;
}
.omni-extension {
font-family: Inter !important;
z-index: 99999999999;
}
.omni-extension #omni-wrap {
position: fixed;
width: 700px;
border: 1px solid transparent;
border-radius: 5px;
margin: auto;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
z-index: 9999999999;
height: 540px;
transition: all 0.2s cubic-bezier(0.05, 0.03, 0.35, 1);
pointer-events: all;
}
.omni-extension #omni {
position: absolute;
width: 100%;
background: var(--background);
border: 1px solid var(--border);
border-radius: 5px;
top: 0px;
left: 0px;
z-index: 9999999998;
height: fit-content;
transition: all 0.2s cubic-bezier(0.05, 0.03, 0.35, 1);
display: block;
}
.omni-closing #omni {
transform: scale(0.9);
opacity: 0;
}
.omni-closing {
pointer-events: none;
display: none !important;
}
.omni-extension #omni-overlay {
height: 100%;
width: 100%;
position: fixed;
top: 0px;
left: 0px;
background-color: #000;
z-index: 9999;
opacity: 0.6;
transition: all 0.1s cubic-bezier(0.05, 0.03, 0.35, 1);
}
.omni-closing #omni-overlay {
opacity: 0 !important;
}
.omni-extension #omni-head {
height: 50px;
line-height: 50px;
width: 95%;
margin-left: auto;
margin-right: auto;
border-bottom: 1px solid var(--border);
}
.omni-extension #omni-name {
color: var(--text);
font-size: 12px;
font-weight: 600;
float: left;
}
.omni-extension #omni-close {
color: var(--text-3);
float: right;
font-size: 12px;
font-weight: 500;
}
.omni-extension #omni-close span {
margin-left: 3px;
}
.omni-extension .omni-shortcut {
display: inline-block !important;
font-size: 13px;
border-radius: 5px;
background-color: var(--shortcut);
color: var(--text);
text-align: center;
height: 20px;
line-height: 20px;
min-width: 20px;
padding-left: 3px;
padding-right: 3px;
}
.omni-extension input {
background: transparent;
border: 0px;
outline: none;
font-size: 20px;
font-weight: 400;
height: 50px;
width: 92%;
margin-left: auto;
margin-right: auto;
display: block;
color: var(--text);
caret-color: var(--accent);
font-family: Inter !important;
margin-top: 5px;
margin-bottom: 5px;
box-sizing: border-box;
outline: none;
border: 0px;
box-shadow: none;
}
.omni-extension ::placeholder {
color: var(--placeholder);
opacity: 1;
}
.omni-extension :-ms-input-placeholder {
color: var(--placeholder);
}
.omni-extension ::-ms-input-placeholder {
color: var(--placeholder);
}
.omni-extension #omni-list {
width: 100%;
overflow: auto;
height: 100%;
max-height: 400px;
border-top: 1px solid var(--border);
position: relative;
}
.omni-extension .omni-item {
height: 60px;
width: 100%;
}
.omni-extension .omni-item:hover {
cursor: pointer;
}
.omni-extension .omni-item-active {
background-color: var(--select);
position: relative;
}
.omni-extension .omni-item-active:before {
height: 100%;
position: absolute;
display: block;
content: "";
width: 2px;
background-color: var(--accent);
}
.omni-extension .omni-select {
float: right;
vertical-align: middle;
color: var(--text-3);
font-size: 12px;
font-weight: 500;
display: none;
margin-top: 20px;
margin-right: 5%;
}
.omni-extension .omni-select span {
margin-left: 3px;
}
.omni-extension .omni-item-active .omni-select {
display: block !important;
}
.omni-extension .omni-icon {
width: 20px;
height: 20px;
margin-left: 5%;
display: inline-block;
vertical-align: middle;
margin-top: -12px;
}
.omni-extension .omni-emoji-action {
display: inline-block;
vertical-align: middle;
margin-top: -12px;
width: 20px;
height: 20px;
text-align: center;
margin-left: 5%;
font-size: 18px;
}
.omni-extension .omni-item-details {
display: inline-block !important;
margin-left: 10px;
vertical-align: middle;
margin-top: 10px;
}
.omni-extension .omni-item-name {
color: var(--text-2);
font-size: 14px;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 460px;
}
.omni-extension .omni-item-active .omni-item-name {
color: var(--text) !important;
}
.omni-extension .omni-item-desc {
color: var(--text-3);
margin-top: 5px;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 460px;
}
.omni-extension #omni-footer {
height: 45px;
line-height: 45px;
border-top: 1px solid var(--border);
width: 92%;
margin-left: auto;
margin-right: auto;
}
.omni-extension #omni-results {
color: var(--text-3);
font-size: 12px;
font-weight: 500;
float: left;
}
.omni-extension #omni-arrows {
color: var(--text-3);
font-size: 12px;
font-weight: 500;
float: right;
}
.omni-extension #omni-arrows span {
margin-left: 3px;
margin-right: 3px;
}
.omni-extension .omni-keys {
float: right;
vertical-align: middle;
font-weight: 500;
margin-top: 20px;
margin-right: 5%;
}
.omni-extension .omni-item-active .omni-keys {
display: none !important;
}
.omni-extension .omni-keys span {
margin-left: 3px;
}
#omni-extension-toast {
text-align: center;
font-family: Inter;
font-weight: 500;
font-size: 14px;
position: fixed;
width: -moz-max-content;
color: var(--text);
bottom: 10px;
left: 0px;
right: 0px;
margin: auto;
background: var(--background);
border-radius: 5px;
height: 40px;
line-height: 40px;
display: block;
padding-left: 10px;
padding-right: 10px;
visibility: hidden;
opacity: 0;
transition: all 0.2s cubic-bezier(0.05, 0.03, 0.35, 1);
z-index: 99999999;
display: block;
}
#omni-extension-toast img {
display: inline-block;
margin-right: 5px;
vertical-align: middle;
margin-bottom: 2px;
}
.omni-show-toast {
bottom: 20px !important;
opacity: 1 !important;
visibility: visible !important;
}
================================================
FILE: firefox/content.html
================================================
The action has been successful
================================================
FILE: firefox/content.js
================================================
// Workaround to capture Esc key on certain sites
var isOpen = false;
document.onkeyup = (e) => {
if (e.key == "Escape" && isOpen) {
browser.runtime.sendMessage({request:"close-omni"})
}
}
$(document).ready(() => {
var actions = [];
var isFiltered = false;
// Append the omni into the current page
$.get(browser.runtime.getURL('/content.html'), (data) => {
$(data).appendTo('body');
// Get checkmark image for toast
$("#omni-extension-toast img").attr("src", browser.runtime.getURL("assets/check.svg"));
// Request actions from the background
browser.runtime.sendMessage({request:"get-actions"}, (response) => {
actions = response.actions;
populateOmni();
});
// New tab page workaround
if (window.location.href == "browser-extension://mpanekjjajcabgnlbabmopeenljeoggm/newtab.html") {
isOpen = true;
$("#omni-extension").removeClass("omni-closing");
window.setTimeout(() => {
$("#omni-extension input").focus();
}, 100);
}
});
function renderAction(action, index, keys, img) {
var skip = "";
if (action.action == "search" || action.action == "goto") {
skip = "style='display:none'";
}
if (index != 0) {
$("#omni-extension #omni-list").append("