This repository contains open-source code snippets for programmable buttons in Orion browser.
Orion is modern, high performance, WebKit based, zero-telemetry browser for Apple devices.
Download Orion browser by Kagi.
Usage:
Import a button from URL
- Control-click (right-click) a button link, then choose Copy Link.
- Control-click the Orion toolbar and select "Import Button from URL".
- Paste the copied URL, then click Import.
Import a button from file
- Prepare button.plist file (download one below, export from another Orion instance).
- Control-click Orion toolbar and select "Import Button from File".
- Choose the file, then click Open.
- Dark Mode: Attempts to enable Dark Mode on the page. Uses Orion's dark mode snippet.
- Kill Sticky: Remove sticky elements and restore scrolling to web pages. Uses this kill sticky snippet.
- Translate with Google: Re-loads the page in Google Translate for automatic translation.
- Modern CSS: Applies modern CSS to the page. Useful for pages with no styles. Test here. Uses Water.css stylesheet.
- Classic CSS: Applies classic web era CSS to the page. Useful for pages with no styles. Test here. Uses 'old style' W3C stylesheet.
You will need to input your OpenAI API key in the code for these to work. When you import the button, right click it, select edit, switch to code, and then replace OpenAI API key on the top of the code.
- Unbiased News: Uses OpenAI API to produce unbiased rewrite of the news article. Make sure to replace apiKey in the code after importing.
- Summarize: Uses OpenAI API to produce summary of the page. Make sure to replace apiKey in the code after importing. This is just a proof of concept and will not work with all pages. For a more robust summarization API, consider using Universal Summarizer.
- Stock Analysis: Uses OpenAI API to produce stock analysis based on the content of the page. Works best on financial sites like seekingalpha.com. Make sure to replace apiKey in the code after importing.
Community members are welcome to contribute their own programmable buttons in the Community Buttons folder.
Currently available are:
- Copy page link as Markdown: Copies the page link as a Markdown link.
- Discuss document or page: Ask questions or discuss a document or page via AI chat.
- Remove YT playlist URL: Remove the playlist part of the YouTube video URL.
- Open in Internet Archive: Open current page in Internet Archive.
- Text to Speech: Read highlighted text using Mac native Speech.
- Send Tabs to Firefox: Open all Orion Browser tabs in Firefox.
- Save page link to Raindrop.io: Save page link to your Raindrop.io account with working keyboard shortcut.
Cick the thumbnail to watch the video.
You can inspect the code, icons and options used in the button by converting the file into a more readable format like xml.
For example:
plutil -convert xml1 -o Summarize.xml Summarize.plist
The code will call an external API and display result in Orion sidebar.
(async () => {
const apiKey = 'your_api_key';
const text = document.title + ' ' + Array.from(document.querySelectorAll('p')).map(p => p.innerText).join(' ');
const requestBody = {
'model': 'gpt-3.5-turbo',
'messages': [
{ 'role': 'system', 'content': 'Your task is to summarise the text I have given you in up to seven concise bullet points, starting with a short highlight. \nYour output should use the following template: \nSummary \nHighlights \n- Bulletpoint \n"' },
{ 'role': 'user', 'content': `${text}` }
],
'max_tokens': 800,
'temperature': 0
};
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(requestBody)
});
if (response.ok) {
const data = await response.json();
const summary = data.choices[0].message.content;
OrionInternals.setSidebarContent(summary)
} else {
console.error('API request failed:', await response.text());
}
})();
The following is a demonstration of the code used to power the 'Summarize' button.
The code connects to OpenAI API (change apiKey with your own) and sends a prompt that will summarizes the text on the page. It uses OrionInternals.setSidebarContent(summary) method to update Orions sidebar.
(async () => {
const apiKey = 'your_api_key';
const text = document.title + ' ' + Array.from(document.querySelectorAll('p')).map(p => p.innerText).join(' ');
const requestBody = {
'model': 'gpt-3.5-turbo',
'messages': [
{ 'role': 'system', 'content': 'Your task is to summarise the text I have given you in up to seven concise bullet points, starting with a short highlight. \nYour output should use the following template: \nSummary \nHighlights \n- Bulletpoint \n"' },
{ 'role': 'user', 'content': `${text}` }
],
'max_tokens': 800,
'temperature': 0,
'stream': true
};
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify(requestBody)
});
if (response.ok) {
const reader = response.body.getReader();
const decoder = new TextDecoder('utf-8');
let summary = '';
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
const lines = decoder.decode(value).split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
const message = line.replace(/^data: /, '');
if (message === '[DONE]') {
break;
}
try {
const parsed = JSON.parse(message);
const content = parsed.choices && parsed.choices[0] && parsed.choices[0].delta && parsed.choices[0].delta.content;
if (content) {
summary += content;
OrionInternals.setSidebarContent(summary);
}
} catch (error) {
console.error('Could not JSON parse stream message', message, error);
}
}
}
} else {
console.error('API request failed:', await response.text());
}
})();