├── LICENSE ├── README.md ├── buttons ├── Classic CSS.plist ├── Dark Mode.plist ├── Kill Sticky.plist ├── Modern CSS.plist ├── README.md ├── Stock Analysis.plist ├── Summarize.plist ├── Translate with Google.plist └── Unbiased News.plist └── community_buttons ├── Copy page link as Markdown.plist ├── Discuss doc or page.plist ├── Kagi Summarize.plist ├── Open in Internet Archive.plist ├── README.md ├── Remove YT Playlist URL.plist ├── Save to Raindrop.io.plist ├── Send RC tabs to Firefox.plist ├── Send Tabs to Firefox.plist └── Text to Speech.plist /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Orion 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Programmable Buttons 2 | 3 | [![](https://dcbadge.vercel.app/api/server/gKh5E6ys6D?compact=true&style=flat)](https://discord.gg/gKh5E6ys6D) [![Twitter](https://img.shields.io/twitter/follow/KagiHQ?style=social)](https://twitter.com/KagiHQ) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/license/mit/) 4 | 5 | This repository contains open-source code snippets for programmable buttons in Orion browser. 6 | 7 | Orion is modern, high performance, WebKit based, zero-telemetry browser for Apple devices. 8 | 9 | [Download Orion browser by Kagi](https://browser.kagi.com). 10 | 11 | ## Programmable Button demos 12 | 13 | Usage: 14 | 15 | Import a button from URL 16 | - Control-click (right-click) a button link, then choose Copy Link. 17 | - Control-click the Orion toolbar and select "Import Button from URL". 18 | - Paste the copied URL, then click Import. 19 | 20 | Import a button from file 21 | - Prepare button.plist file (download one below, export from another Orion instance). 22 | - Control-click Orion toolbar and select "Import Button from File". 23 | - Choose the file, then click Open. 24 | 25 | ### Browser interaction buttons 26 | 27 | - [Dark Mode](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Dark%20Mode.plist): Attempts to enable Dark Mode on the page. Uses Orion's [dark mode snippet](https://github.com/OrionBrowser/DarkMode). 28 | - [Kill Sticky](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Kill%20Sticky.plist): Remove sticky elements and restore scrolling to web pages. Uses this [kill sticky snippet](https://github.com/t-mart/kill-sticky). 29 | - [Translate with Google](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Translate%20with%20Google.plist): Re-loads the page in Google Translate for automatic translation. 30 | - [Modern CSS](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Modern%20CSS.plist): Applies modern CSS to the page. Useful for pages with no styles. Test [here](https://danluu.com/futurist-predictions/). Uses [Water.css stylesheet](https://watercss.kognise.dev/). 31 | - [Classic CSS](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Classic%20CSS.plist): Applies classic web era CSS to the page. Useful for pages with no styles. Test [here](https://danluu.com/futurist-predictions/). Uses ['old style' W3C stylesheet](https://www.w3.org/StyleSheets/Core/preview). 32 | 33 | ### AI buttons 34 | 35 | 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. 36 | 37 | - [Unbiased News](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Unbiased%20News.plist): Uses OpenAI API to produce unbiased rewrite of the news article. Make sure to replace apiKey in the code after importing. 38 | - [Summarize](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Summarize.plist): 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](https://kagi.com/summarizer). 39 | - [Stock Analysis](https://github.com/OrionBrowser/ProgrammableButtons/raw/main/buttons/Unbiased%20News.plist): 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. 40 | 41 | ### Community Buttons 42 | Community members are welcome to contribute their own programmable buttons in the [Community Buttons folder](https://github.com/OrionBrowser/ProgrammableButtons/tree/main/community_buttons/). 43 | 44 | Currently available are: 45 | - [Copy page link as Markdown](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Copy%20page%20link%20as%20Markdown.plist): Copies the page link as a Markdown link. 46 | - [Discuss document or page](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Discuss%20doc%20or%20page.plist): Ask questions or discuss a document or page via AI chat. 47 | - [Remove YT playlist URL](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Remove%20YT%20Playlist%20URL.plist): Remove the playlist part of the YouTube video URL. 48 | - [Open in Internet Archive](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Open%20in%20Internet%20Archive.plist): Open current page in Internet Archive. 49 | - [Text to Speech](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Text%20to%20Speech.plist): Read highlighted text using Mac native Speech. 50 | - [Send Tabs to Firefox](https://github.com/OrionBrowser/ProgrammableButtons/blob/main/community_buttons/Send%20Tabs%20to%20Firefox.plist): Open all Orion Browser tabs in Firefox. 51 | - [Save page link to Raindrop.io](Save%20to%20Raindrop.io.plist): Save page link to your Raindrop.io account with working keyboard shortcut. 52 | ## Demo 53 | 54 | Cick the thumbnail to watch the video. 55 | 56 | [![Watch the video](https://img.youtube.com/vi/xoJliN5Pwv8/hqdefault.jpg)](https://www.youtube.com/watch?v=xoJliN5Pwv8) 57 | 58 | ## Pro tip 59 | 60 | You can inspect the code, icons and options used in the button by converting the file into a more readable format like xml. 61 | 62 | For example: 63 | ``` 64 | plutil -convert xml1 -o Summarize.xml Summarize.plist 65 | ``` 66 | 67 | ## Example 68 | 69 | ### External API call 70 | 71 | The code will call an external API and display result in Orion sidebar. 72 | 73 | ``` 74 | (async () => { 75 | const apiKey = 'your_api_key'; 76 | const text = document.title + ' ' + Array.from(document.querySelectorAll('p')).map(p => p.innerText).join(' '); 77 | const requestBody = { 78 | 'model': 'gpt-3.5-turbo', 79 | 'messages': [ 80 | { '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"' }, 81 | { 'role': 'user', 'content': `${text}` } 82 | ], 83 | 'max_tokens': 800, 84 | 'temperature': 0 85 | }; 86 | 87 | const response = await fetch('https://api.openai.com/v1/chat/completions', { 88 | method: 'POST', 89 | headers: { 90 | 'Content-Type': 'application/json', 91 | 'Authorization': `Bearer ${apiKey}` 92 | }, 93 | body: JSON.stringify(requestBody) 94 | }); 95 | 96 | if (response.ok) { 97 | const data = await response.json(); 98 | const summary = data.choices[0].message.content; 99 | OrionInternals.setSidebarContent(summary) 100 | } else { 101 | console.error('API request failed:', await response.text()); 102 | } 103 | })(); 104 | ``` 105 | 106 | ### Streaming response from OpenAI API 107 | The following is a demonstration of the code used to power the 'Summarize' button. 108 | 109 | The code connects to OpenAI API (change apiKey with [your own](https://platform.openai.com/account/api-keys)) and sends a prompt that will summarizes the text on the page. It uses OrionInternals.setSidebarContent(summary) method to update Orions sidebar. 110 | 111 | 112 | ``` 113 | (async () => { 114 | const apiKey = 'your_api_key'; 115 | const text = document.title + ' ' + Array.from(document.querySelectorAll('p')).map(p => p.innerText).join(' '); 116 | const requestBody = { 117 | 'model': 'gpt-3.5-turbo', 118 | 'messages': [ 119 | { '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"' }, 120 | { 'role': 'user', 'content': `${text}` } 121 | ], 122 | 'max_tokens': 800, 123 | 'temperature': 0, 124 | 'stream': true 125 | }; 126 | 127 | const response = await fetch('https://api.openai.com/v1/chat/completions', { 128 | method: 'POST', 129 | headers: { 130 | 'Content-Type': 'application/json', 131 | 'Authorization': `Bearer ${apiKey}` 132 | }, 133 | body: JSON.stringify(requestBody) 134 | }); 135 | 136 | if (response.ok) { 137 | const reader = response.body.getReader(); 138 | const decoder = new TextDecoder('utf-8'); 139 | let summary = ''; 140 | 141 | while (true) { 142 | const { value, done } = await reader.read(); 143 | if (done) { 144 | break; 145 | } 146 | const lines = decoder.decode(value).split('\n').filter(line => line.trim() !== ''); 147 | for (const line of lines) { 148 | const message = line.replace(/^data: /, ''); 149 | if (message === '[DONE]') { 150 | break; 151 | } 152 | try { 153 | const parsed = JSON.parse(message); 154 | const content = parsed.choices && parsed.choices[0] && parsed.choices[0].delta && parsed.choices[0].delta.content; 155 | if (content) { 156 | summary += content; 157 | OrionInternals.setSidebarContent(summary); 158 | } 159 | } catch (error) { 160 | console.error('Could not JSON parse stream message', message, error); 161 | } 162 | } 163 | } 164 | 165 | } else { 166 | console.error('API request failed:', await response.text()); 167 | } 168 | })(); 169 | 170 | 171 | 172 | ``` 173 | -------------------------------------------------------------------------------- /buttons/Classic CSS.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Classic CSS.plist -------------------------------------------------------------------------------- /buttons/Dark Mode.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Dark Mode.plist -------------------------------------------------------------------------------- /buttons/Kill Sticky.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Kill Sticky.plist -------------------------------------------------------------------------------- /buttons/Modern CSS.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Modern CSS.plist -------------------------------------------------------------------------------- /buttons/README.md: -------------------------------------------------------------------------------- 1 | These are official programmable button examples for Orion browser. 2 | 3 | We welcome contributions - please upload your button to community_buttons directory. 4 | -------------------------------------------------------------------------------- /buttons/Stock Analysis.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Stock Analysis.plist -------------------------------------------------------------------------------- /buttons/Summarize.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Summarize.plist -------------------------------------------------------------------------------- /buttons/Translate with Google.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Translate with Google.plist -------------------------------------------------------------------------------- /buttons/Unbiased News.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/buttons/Unbiased News.plist -------------------------------------------------------------------------------- /community_buttons/Copy page link as Markdown.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Copy page link as Markdown.plist -------------------------------------------------------------------------------- /community_buttons/Discuss doc or page.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Discuss doc or page.plist -------------------------------------------------------------------------------- /community_buttons/Kagi Summarize.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Kagi Summarize.plist -------------------------------------------------------------------------------- /community_buttons/Open in Internet Archive.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Open in Internet Archive.plist -------------------------------------------------------------------------------- /community_buttons/README.md: -------------------------------------------------------------------------------- 1 | This folder is for community-made programmable buttons. Use at your own risk. 2 | 3 | We welcome contributions! 4 | 5 | - [Copy page link as Markdown](Copy%20page%20link%20as%20Markdown.plist): Copies the page's URL as a Markdown link to your clipboard. 6 | - [Discuss doc or page](Discuss%20doc%20or%20page.plist): Discuss document/page content via AI chat. 7 | - [Remove YT Playlist URL](Remove%20YT%20Playlist%20URL.plist): YT playlist removal from URL button. 8 | - [Kagi Summarize](Kagi%20Summarize.plist): Open current page in Kagi Universal Summarizer. 9 | - [Open in Internet Archive](Open%20in%20Internet%20Archive.plist): Open current page in Internet Archive. 10 | - [Text to Speech](Text%20to%20Speech.plist): Read highlighted text using Mac native Speech. 11 | - [Send Tabs to Firefox](Send%20Tabs%20to%20Firefox.plist): Open all Orion Browser tabs in Firefox. 12 | - [Send RC Tabs to Firefox](Send%20Tabs%20to%20Firefox.plist): Open all Orion RC Browser tabs in Firefox. 13 | - [Save page link to Raindrop.io](Save%20to%20Raindrop.io.plist): Save page link to Raindrop.io. Tap button or press (⌃⌥s) to save bookmark. 14 | - Edit keyboard shortcut: right-click button choose Edit, click "Keyboard Shorctus" and add your combination, then click Save. 15 | - It might be easier to login through website or official extension before use. 16 | - Use alone or with official Raindrop Firefox extension. -------------------------------------------------------------------------------- /community_buttons/Remove YT Playlist URL.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Remove YT Playlist URL.plist -------------------------------------------------------------------------------- /community_buttons/Save to Raindrop.io.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Save to Raindrop.io.plist -------------------------------------------------------------------------------- /community_buttons/Send RC tabs to Firefox.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Send RC tabs to Firefox.plist -------------------------------------------------------------------------------- /community_buttons/Send Tabs to Firefox.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Send Tabs to Firefox.plist -------------------------------------------------------------------------------- /community_buttons/Text to Speech.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrionBrowser/ProgrammableButtons/bba66fe50331cbfe59846899f859f57e14123920/community_buttons/Text to Speech.plist --------------------------------------------------------------------------------