Emoji favicons for the web
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: use bext

- use bext
- remove browser extension boilerplate
- add emoji-selector

+190 -1521
-17
Makefile
··· 1 - # Note: deno.json config and import_map.json are used by Deno.emit. 2 - # They are intentionally NOT used by this file 3 - 4 - build: 5 - deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts 6 - 7 - chrome: 8 - deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts chrome 9 - 10 - firefox: 11 - deno run --allow-env --allow-net --allow-read --allow-write --allow-run bundler.ts firefox 12 - 13 - test: 14 - deno fmt 15 - deno lint 16 - deno test 17 - deno check source/background.ts source/content_script.ts source/options.tsx source/popup.tsx
+11 -17
README.md
··· 18 18 19 19 You need to download [Deno](https://deno.land/) in order to build this app. 20 20 21 - > 1. Need to use Deno version PRE v1.22.0 22 - > 23 - > - Deno.emit is not supported in v1.22.0 24 - > - We will transition to v1.22.0 when we can make a stable configuration for the userland [deno_emit](https://github.com/denoland/deno_emit) module 25 - > - To use unstable Deno v1.21.3: `deno upgrade --version 1.21.3` 26 - > 27 - > 2. This application uses the unstable Deno api [`Deno.emit`](https://doc.deno.land/deno/unstable@v1.21.3/~/Deno.emit) 28 - > 3. `chrome` and `browser` globals are currently `any` type 21 + After, we want to install [bext](https://github.com/bpevs/bext): 29 22 30 - | Commands | What they Do | 31 - | -------------------- | ------------------------------------------ | 32 - | `make` | bundles extension | 33 - | `make chrome` | bundles extension only for chrome | 34 - | `make firefox` | bundles extension only for firefox | 35 - | `make watch` | watch for js changes, and bundle on change | 36 - | `make watch-chrome` | watch only for chrome | 37 - | `make watch-firefox` | watch only for firefox | 38 - | `make test` | run code formatter, then unit tests | 23 + ```sh 24 + deno install --name=bext --allow-read --allow-write --allow-run --allow-env -f https://deno.land/x/bext/main.ts 25 + ``` 26 + 27 + | Commands | What they Do | 28 + | ---------------- | ----------------------------------- | 29 + | `bext` | bundles extension and watch code | 30 + | `bext chrome` | bundles extension only for chrome | 31 + | `bext firefox` | bundles extension only for firefox | 32 + | `deno task test` | run code formatter, then unit tests | 39 33 40 34 If you have bundled using make commands, you should be able to load your 41 35 unpacked extension using a browser.
-101
bundler.ts
··· 1 - /** 2 - * Compile and bundle all the distributables into dist. 3 - * 4 - * Note: This file does NOT use deno.json as a config file for itself. 5 - * That config file is specifically for use in Deno.emit. 6 - * 7 - * Probably move to esbuild: 8 - * - https://deno.land/x/esbuild_deno_loader@0.5.0 9 - */ 10 - import * as esbuild from 'https://deno.land/x/esbuild@v0.14.39/mod.js'; 11 - import { denoPlugin } from 'https://raw.githubusercontent.com/ivebencrazy/esbuild_deno_loader/main/mod.ts'; 12 - import { copySync, ensureDir } from 'fs'; 13 - import { resolve } from 'https://deno.land/std@0.142.0/path/mod.ts'; 14 - 15 - const importMapURL = new URL('file://' + resolve('./import_map.json')); 16 - 17 - interface BrowserManifestSettings { 18 - color: string; 19 - omits: string[]; 20 - // deno-lint-ignore no-explicit-any 21 - overrides?: { [id: string]: any }; 22 - } 23 - 24 - interface BrowserManifests { 25 - [id: string]: BrowserManifestSettings; 26 - } 27 - 28 - const browsers: BrowserManifests = { 29 - chrome: { 30 - color: '\x1b[32m', 31 - omits: ['applications', 'options_ui', 'browser_action'], 32 - }, 33 - firefox: { 34 - color: '\x1b[91m', 35 - overrides: { 36 - manifest_version: 2, 37 - background: { 38 - scripts: ['background.js'], 39 - }, 40 - }, 41 - omits: ['options_page', 'host_permissions', 'action'], 42 - }, 43 - }; 44 - 45 - if (Deno.args[0] === 'chrome') delete browsers.firefox; 46 - if (Deno.args[0] === 'firefox') delete browsers.chrome; 47 - 48 - console.log('\x1b[37mPackager\n========\x1b[0m'); 49 - 50 - Object.keys(browsers).forEach(async (browserId) => { 51 - const distDir = `dist/${browserId}`; 52 - 53 - // Copy JS/HTML/CSS/ICONS 54 - ensureDir(`${distDir}/static`); 55 - 56 - const options = { overwrite: true }; 57 - copySync('source/static', distDir, options); 58 - 59 - const browserManifestSettings = browsers[browserId]; 60 - 61 - // Transform Manifest 62 - const manifest = { 63 - ...JSON.parse(Deno.readTextFileSync('source/manifest.json')), 64 - ...browserManifestSettings.overrides, 65 - }; 66 - browserManifestSettings.omits.forEach((omit) => delete manifest[omit]); 67 - 68 - Deno.writeTextFileSync( 69 - distDir + '/manifest.json', 70 - JSON.stringify(manifest, null, 2), 71 - ); 72 - 73 - const color = browserManifestSettings.color || ''; 74 - const browserName = browserId.toUpperCase(); 75 - const colorizedBrowserName = `\x1b[1m${color}${browserName}\x1b[0m`; 76 - 77 - console.log(`Initializing ${colorizedBrowserName} build...`); 78 - 79 - await esbuild.build({ 80 - plugins: [denoPlugin({ importMapURL })], 81 - entryPoints: [ 82 - 'source/options.tsx', 83 - 'source/content_script.ts', 84 - 'source/background.ts', 85 - 'source/popup.tsx', 86 - ], 87 - outdir: `dist/${browserId}/`, 88 - bundle: true, 89 - watch: { 90 - onRebuild(error) { 91 - if (error) { 92 - console.error(`Rebuild for ${colorizedBrowserName} failed:`, error); 93 - } else console.log(`Rebuilt for ${colorizedBrowserName}`); 94 - }, 95 - }, 96 - format: 'esm', 97 - logLevel: 'verbose', 98 - }); 99 - 100 - console.log(`Build complete for ${colorizedBrowserName}`); 101 - });
+4
deno.json
··· 21 21 "files": { 22 22 "exclude": ["dist"] 23 23 } 24 + }, 25 + "tasks": { 26 + "test": "deno fmt && deno lint && deno task check && deno test source", 27 + "check": "deno check source/background.ts && deno check source/content_script.ts && deno check source/options.tsx && deno check source/popup.tsx" 24 28 } 25 29 }
+1 -1
import_map.json
··· 2 2 "imports": { 3 3 "asserts": "https://deno.land/std@0.138.0/testing/asserts.ts", 4 4 "bdd": "https://deno.land/std@0.138.0/testing/bdd.ts", 5 - "browser": "./source/browser_api/mod.ts", 5 + "browser": "https://deno.land/x/bext/mod.ts", 6 6 "emoji": "https://deno.land/x/emoji@0.2.0/mod.ts", 7 7 "fs": "https://deno.land/std@0.138.0/fs/mod.ts", 8 8 "mock": "https://deno.land/std@0.138.0/testing/mock.ts",
-36
source/browser_api/mod.ts
··· 1 - // deno-lint-ignore-file 2 - 3 - /** 4 - * API for more platform-agnostic access to browser extension apis. 5 - * Since browers ext API is kind of shifting sands, let's not do too much 6 - * work to try and make 100% stable. But we can use this for the more stable 7 - * APIs to avoid putting (chrome || browser) everywhere 8 - * 9 - * @reference https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions 10 - * @reference https://developer.chrome.com/docs/extensions/reference 11 - * @reference https://docs.microsoft.com/en-us/microsoft-edge/extensions-chromium/developer-guide/api-support 12 - * 13 - * @todo Borrows heavily from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/chrome 14 - */ 15 - import { isChrome } from '../utilities/predicates.ts'; 16 - 17 - import type { PermissionsModule } from './modules/permissions.ts'; 18 - import type { RuntimeModule } from './modules/runtime.ts'; 19 - import type { StorageModule } from './modules/storage.ts'; 20 - import type { TabsModule } from './modules/tabs.ts'; 21 - export * from './modules/tabs.ts'; 22 - 23 - export interface BrowserAPI { 24 - permissions: PermissionsModule; 25 - runtime: RuntimeModule; 26 - storage: StorageModule; 27 - tabs: TabsModule; 28 - } 29 - 30 - const browserAPI: BrowserAPI = isChrome() 31 - // deno-lint-ignore no-explicit-any 32 - ? (globalThis as any).chrome 33 - : // deno-lint-ignore no-explicit-any 34 - (globalThis as any).browser; 35 - 36 - export default browserAPI;
-56
source/browser_api/modules/event.ts
··· 1 - // deno-lint-ignore-file no-explicit-any 2 - 3 - import type { RequestFilter } from './web_request.ts'; 4 - 5 - export type Function = (...args: any[]) => any | void; 6 - 7 - export interface UrlFilter { 8 - schemes?: string[] | undefined; 9 - urlMatches?: string | undefined; 10 - pathContains?: string | undefined; 11 - hostSuffix?: string | undefined; 12 - hostPrefix?: string | undefined; 13 - hostContains?: string | undefined; 14 - urlContains?: string | undefined; 15 - querySuffix?: string | undefined; 16 - urlPrefix?: string | undefined; 17 - hostEquals?: string | undefined; 18 - urlEquals?: string | undefined; 19 - queryContains?: string | undefined; 20 - pathPrefix?: string | undefined; 21 - pathEquals?: string | undefined; 22 - pathSuffix?: string | undefined; 23 - queryEquals?: string | undefined; 24 - queryPrefix?: string | undefined; 25 - urlSuffix?: string | undefined; 26 - ports?: (number | number[])[] | undefined; 27 - originAndPathMatches?: string | undefined; 28 - } 29 - 30 - export interface BaseEvent<T extends Function> { 31 - addListener(callback: T, filter?: RequestFilter): void; 32 - getRules(callback: (rules: Rule[]) => void): void; 33 - getRules(ruleIdentifiers: string[], callback: (rules: Rule[]) => void): void; 34 - hasListener(callback: T): boolean; 35 - removeRules(ruleIdentifiers?: string[], callback?: () => void): void; 36 - removeRules(callback?: () => void): void; 37 - addRules(rules: Rule[], callback?: (rules: Rule[]) => void): void; 38 - removeListener(callback: T): void; 39 - hasListeners(): boolean; 40 - } 41 - 42 - export interface Event<T extends Function> extends BaseEvent<T> { 43 - addListener(callback: T): void; 44 - } 45 - export interface EventWithRequiredFilterInAddListener<T extends Function> 46 - extends BaseEvent<T> { 47 - addListener(callback: T, filter: RequestFilter): void; 48 - } 49 - 50 - export interface Rule { 51 - priority?: number | undefined; 52 - conditions: any[]; 53 - id?: string | undefined; 54 - actions: any[]; 55 - tags?: string[] | undefined; 56 - }
-340
source/browser_api/modules/manifest.ts
··· 1 - // deno-lint-ignore-file no-explicit-any 2 - 3 - export interface PageStateUrlDetails { 4 - hostContains?: string | undefined; 5 - hostEquals?: string | undefined; 6 - hostPrefix?: string | undefined; 7 - hostSuffix?: string | undefined; 8 - pathContains?: string | undefined; 9 - pathEquals?: string | undefined; 10 - pathPrefix?: string | undefined; 11 - pathSuffix?: string | undefined; 12 - queryContains?: string | undefined; 13 - queryEquals?: string | undefined; 14 - queryPrefix?: string | undefined; 15 - querySuffix?: string | undefined; 16 - urlContains?: string | undefined; 17 - urlEquals?: string | undefined; 18 - urlMatches?: string | undefined; 19 - originAndPathMatches?: string | undefined; 20 - urlPrefix?: string | undefined; 21 - urlSuffix?: string | undefined; 22 - schemes?: string[] | undefined; 23 - ports?: (number | number[])[] | undefined; 24 - } 25 - 26 - export class PageStateMatcherProperties { 27 - pageUrl?: PageStateUrlDetails | undefined; 28 - css?: string[] | undefined; 29 - isBookmarked?: boolean | undefined; 30 - } 31 - 32 - export interface SearchProvider { 33 - name?: string | undefined; 34 - keyword?: string | undefined; 35 - favicon_url?: string | undefined; 36 - search_url: string; 37 - encoding?: string | undefined; 38 - suggest_url?: string | undefined; 39 - instant_url?: string | undefined; 40 - image_url?: string | undefined; 41 - search_url_post_params?: string | undefined; 42 - suggest_url_post_params?: string | undefined; 43 - instant_url_post_params?: string | undefined; 44 - image_url_post_params?: string | undefined; 45 - alternate_urls?: string[] | undefined; 46 - prepopulated_id?: number | undefined; 47 - is_default?: boolean | undefined; 48 - } 49 - 50 - export interface ManifestIcons { 51 - [size: number]: string; 52 - } 53 - 54 - export interface ManifestAction { 55 - default_icon?: ManifestIcons | undefined; 56 - default_title?: string | undefined; 57 - default_popup?: string | undefined; 58 - } 59 - 60 - // Source: https://developer.chrome.com/docs/extensions/mv3/declare_permissions/ 61 - export type ManifestPermissions = 62 - | 'activeTab' 63 - | 'alarms' 64 - | 'background' 65 - | 'bookmarks' 66 - | 'browsingData' 67 - | 'certificateProvider' 68 - | 'clipboardRead' 69 - | 'clipboardWrite' 70 - | 'contentSettings' 71 - | 'contextMenus' 72 - | 'cookies' 73 - | 'debugger' 74 - | 'declarativeContent' 75 - | 'declarativeNetRequest' 76 - | 'declarativeNetRequestFeedback' 77 - | 'declarativeWebRequest' 78 - | 'desktopCapture' 79 - | 'documentScan' 80 - | 'downloads' 81 - | 'enterprise.deviceAttributes' 82 - | 'enterprise.hardwarePlatform' 83 - | 'enterprise.networkingAttributes' 84 - | 'enterprise.platformKeys' 85 - | 'experimental' 86 - | 'fileBrowserHandler' 87 - | 'fileSystemProvider' 88 - | 'fontSettings' 89 - | 'gcm' 90 - | 'geolocation' 91 - | 'history' 92 - | 'identity' 93 - | 'idle' 94 - | 'loginState' 95 - | 'management' 96 - | 'nativeMessaging' 97 - | 'notifications' 98 - | 'pageCapture' 99 - | 'platformKeys' 100 - | 'power' 101 - | 'printerProvider' 102 - | 'printing' 103 - | 'printingMetrics' 104 - | 'privacy' 105 - | 'processes' 106 - | 'proxy' 107 - | 'scripting' 108 - | 'search' 109 - | 'sessions' 110 - | 'signedInDevices' 111 - | 'storage' 112 - | 'system.cpu' 113 - | 'system.display' 114 - | 'system.memory' 115 - | 'system.storage' 116 - | 'tabCapture' 117 - | 'tabGroups' 118 - | 'tabs' 119 - | 'topSites' 120 - | 'tts' 121 - | 'ttsEngine' 122 - | 'unlimitedStorage' 123 - | 'vpnProvider' 124 - | 'wallpaper' 125 - | 'webNavigation' 126 - | 'webRequest' 127 - | 'webRequestBlocking'; 128 - 129 - export interface ManifestBase { 130 - // Required 131 - manifest_version: number; 132 - name: string; 133 - version: string; 134 - 135 - // Recommended 136 - default_locale?: string | undefined; 137 - description?: string | undefined; 138 - icons?: ManifestIcons | undefined; 139 - 140 - // Optional 141 - author?: string | undefined; 142 - background_page?: string | undefined; 143 - chrome_settings_overrides?: { 144 - homepage?: string | undefined; 145 - search_provider?: SearchProvider | undefined; 146 - startup_pages?: string[] | undefined; 147 - } | undefined; 148 - chrome_ui_overrides?: { 149 - bookmarks_ui?: { 150 - remove_bookmark_shortcut?: boolean | undefined; 151 - remove_button?: boolean | undefined; 152 - } | undefined; 153 - } | undefined; 154 - chrome_url_overrides?: { 155 - bookmarks?: string | undefined; 156 - history?: string | undefined; 157 - newtab?: string | undefined; 158 - } | undefined; 159 - commands?: { 160 - [name: string]: { 161 - suggested_key?: { 162 - default?: string | undefined; 163 - windows?: string | undefined; 164 - mac?: string | undefined; 165 - chromeos?: string | undefined; 166 - linux?: string | undefined; 167 - } | undefined; 168 - description?: string | undefined; 169 - global?: boolean | undefined; 170 - }; 171 - } | undefined; 172 - content_capabilities?: { 173 - matches?: string[] | undefined; 174 - permissions?: string[] | undefined; 175 - } | undefined; 176 - content_scripts?: { 177 - matches?: string[] | undefined; 178 - exclude_matches?: string[] | undefined; 179 - css?: string[] | undefined; 180 - js?: string[] | undefined; 181 - run_at?: string | undefined; 182 - all_frames?: boolean | undefined; 183 - match_about_blank?: boolean | undefined; 184 - include_globs?: string[] | undefined; 185 - exclude_globs?: string[] | undefined; 186 - }[] | undefined; 187 - converted_from_user_script?: boolean | undefined; 188 - current_locale?: string | undefined; 189 - devtools_page?: string | undefined; 190 - event_rules?: { 191 - event?: string | undefined; 192 - actions?: { 193 - type: string; 194 - }[] | undefined; 195 - conditions?: 196 - | PageStateMatcherProperties[] 197 - | undefined; 198 - }[] | undefined; 199 - externally_connectable?: { 200 - ids?: string[] | undefined; 201 - matches?: string[] | undefined; 202 - accepts_tls_channel_id?: boolean | undefined; 203 - } | undefined; 204 - file_browser_handlers?: { 205 - id?: string | undefined; 206 - default_title?: string | undefined; 207 - file_filters?: string[] | undefined; 208 - }[] | undefined; 209 - file_system_provider_capabilities?: { 210 - configurable?: boolean | undefined; 211 - watchable?: boolean | undefined; 212 - multiple_mounts?: boolean | undefined; 213 - source?: string | undefined; 214 - } | undefined; 215 - homepage_url?: string | undefined; 216 - import?: { 217 - id: string; 218 - minimum_version?: string | undefined; 219 - }[] | undefined; 220 - export?: { 221 - whitelist?: string[] | undefined; 222 - } | undefined; 223 - incognito?: string | undefined; 224 - input_components?: { 225 - name?: string | undefined; 226 - type?: string | undefined; 227 - id?: string | undefined; 228 - description?: string | undefined; 229 - language?: string | undefined; 230 - layouts?: string[] | undefined; 231 - }[] | undefined; 232 - key?: string | undefined; 233 - minimum_chrome_version?: string | undefined; 234 - nacl_modules?: { 235 - path: string; 236 - mime_type: string; 237 - }[] | undefined; 238 - oauth2?: { 239 - client_id: string; 240 - scopes?: string[] | undefined; 241 - } | undefined; 242 - offline_enabled?: boolean | undefined; 243 - omnibox?: { 244 - keyword: string; 245 - } | undefined; 246 - options_page?: string | undefined; 247 - options_ui?: { 248 - page?: string | undefined; 249 - chrome_style?: boolean | undefined; 250 - open_in_tab?: boolean | undefined; 251 - } | undefined; 252 - platforms?: { 253 - nacl_arch?: string | undefined; 254 - sub_package_path: string; 255 - }[] | undefined; 256 - plugins?: { 257 - path: string; 258 - }[] | undefined; 259 - requirements?: { 260 - '3D'?: { 261 - features?: string[] | undefined; 262 - } | undefined; 263 - plugins?: { 264 - npapi?: boolean | undefined; 265 - } | undefined; 266 - } | undefined; 267 - sandbox?: { 268 - pages: string[]; 269 - content_security_policy?: string | undefined; 270 - } | undefined; 271 - short_name?: string | undefined; 272 - spellcheck?: { 273 - dictionary_language?: string | undefined; 274 - dictionary_locale?: string | undefined; 275 - dictionary_format?: string | undefined; 276 - dictionary_path?: string | undefined; 277 - } | undefined; 278 - storage?: { 279 - managed_schema: string; 280 - } | undefined; 281 - tts_engine?: { 282 - voices: { 283 - voice_name: string; 284 - lang?: string | undefined; 285 - gender?: string | undefined; 286 - event_types?: string[] | undefined; 287 - }[]; 288 - } | undefined; 289 - update_url?: string | undefined; 290 - version_name?: string | undefined; 291 - [key: string]: any; 292 - } 293 - 294 - export interface ManifestV2 extends ManifestBase { 295 - // Required 296 - manifest_version: 2; 297 - 298 - // Pick one (or none) 299 - browser_action?: ManifestAction | undefined; 300 - page_action?: ManifestAction | undefined; 301 - 302 - // Optional 303 - background?: 304 - | { 305 - scripts?: string[] | undefined; 306 - page?: string | undefined; 307 - persistent?: boolean | undefined; 308 - } 309 - | undefined; 310 - content_security_policy?: string | undefined; 311 - optional_permissions?: string[] | undefined; 312 - permissions?: string[] | undefined; 313 - web_accessible_resources?: string[] | undefined; 314 - } 315 - 316 - export interface ManifestV3 extends ManifestBase { 317 - // Required 318 - manifest_version: 3; 319 - 320 - // Optional 321 - action?: ManifestAction | undefined; 322 - background?: 323 - | { 324 - service_worker: string; 325 - type?: 'module'; // If the service worker uses ES modules 326 - } 327 - | undefined; 328 - content_security_policy?: { 329 - extension_pages?: string; 330 - sandbox?: string; 331 - }; 332 - host_permissions?: string[] | undefined; 333 - optional_permissions?: ManifestPermissions[] | undefined; 334 - permissions?: ManifestPermissions[] | undefined; 335 - web_accessible_resources?: 336 - | { resources: string[]; matches: string[] }[] 337 - | undefined; 338 - } 339 - 340 - export type Manifest = ManifestV2 | ManifestV3;
-26
source/browser_api/modules/permissions.ts
··· 1 - interface Permissions { 2 - permissions?: string[]; 3 - origins?: string[]; 4 - } 5 - 6 - export interface PermissionsModule { 7 - contains: ( 8 - permissions: Permissions, 9 - callback: (result: boolean) => void, 10 - ) => void; 11 - request: ( 12 - permissions: Permissions, 13 - callback?: (granted: boolean) => void, 14 - ) => void; 15 - getAll: (callback: (permissions: Permissions) => void) => void; 16 - remove: ( 17 - permissions: Permissions, 18 - callback?: (removed: boolean) => void, 19 - ) => void; 20 - onRemoved: { 21 - addListener: (callback: (permissions: Permissions) => void) => void; 22 - }; 23 - onAdded: { 24 - addListener: (callback: (permissions: Permissions) => void) => void; 25 - }; 26 - }
-35
source/browser_api/modules/platform.ts
··· 1 - /** https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformOs */ 2 - export type PlatformOs = 3 - | 'mac' 4 - | 'win' 5 - | 'android' 6 - | 'cros' 7 - | 'linux' 8 - | 'openbsd'; 9 - 10 - /** https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformArch */ 11 - export type PlatformArch = 12 - | 'arm' 13 - | 'arm64' 14 - | 'x86-32' 15 - | 'x86-64' 16 - | 'mips' 17 - | 'mips64'; 18 - 19 - /** https://developer.chrome.com/docs/extensions/reference/runtime/#type-PlatformNaclArch */ 20 - export type PlatformNaclArch = 'arm' | 'x86-32' | 'x86-64' | 'mips' | 'mips64'; 21 - 22 - export interface PlatformInfo { 23 - /** 24 - * The operating system chrome is running on. 25 - */ 26 - os: PlatformOs; 27 - /** 28 - * The machine's processor architecture. 29 - */ 30 - arch: PlatformArch; 31 - /** 32 - * The native client architecture. This may be different from arch on some platforms. 33 - */ 34 - nacl_arch: PlatformNaclArch; 35 - }
-141
source/browser_api/modules/runtime.ts
··· 1 - // deno-lint-ignore-file no-explicit-any 2 - 3 - import type { Manifest } from './manifest.ts'; 4 - import type { PlatformInfo } from './platform.ts'; 5 - import type { Tab } from './tabs.ts'; 6 - import type { Event } from './event.ts'; 7 - 8 - interface Object { 9 - [name: string]: any; 10 - } 11 - 12 - /** https://developer.chrome.com/docs/extensions/reference/runtime/#type-OnInstalledReason */ 13 - export enum OnInstalledReason { 14 - INSTALL = 'install', 15 - UPDATE = 'update', 16 - CHROME_UPDATE = 'chrome_update', 17 - SHARED_MODULE_UPDATE = 'shared_module_update', 18 - } 19 - 20 - export interface LastError { 21 - message?: string | undefined; 22 - } 23 - 24 - export interface ConnectInfo { 25 - name?: string | undefined; 26 - includeTlsChannelId?: boolean | undefined; 27 - } 28 - 29 - export interface InstalledDetails { 30 - reason: OnInstalledReason; 31 - previousVersion?: string | undefined; 32 - id?: string | undefined; 33 - } 34 - 35 - export interface MessageOptions { 36 - /** Whether the TLS channel ID will be passed into onMessageExternal for processes that are listening for the connection event. */ 37 - includeTlsChannelId?: boolean | undefined; 38 - } 39 - 40 - export interface MessageSender { 41 - id?: string | undefined; 42 - tab?: Tab | undefined; 43 - nativeApplication?: string | undefined; 44 - frameId?: number | undefined; 45 - url?: string | undefined; 46 - tlsChannelId?: string | undefined; 47 - origin?: string | undefined; 48 - } 49 - 50 - export interface Port { 51 - postMessage: (message: any) => void; 52 - disconnect: () => void; 53 - sender?: MessageSender | undefined; 54 - onDisconnect: PortDisconnectEvent; 55 - onMessage: PortMessageEvent; 56 - name: string; 57 - } 58 - 59 - export interface UpdateAvailableDetails { 60 - version: string; 61 - } 62 - 63 - export interface UpdateCheckDetails { 64 - version: string; 65 - } 66 - 67 - export type RequestUpdateCheckStatus = 68 - | 'throttled' 69 - | 'no_update' 70 - | 'update_available'; 71 - 72 - export type PortDisconnectEvent = Event<(port: Port) => void>; 73 - 74 - export type PortMessageEvent = Event< 75 - (message: any, port: Port) => void 76 - >; 77 - 78 - export type ExtensionMessageEvent = Event< 79 - ( 80 - message: any, 81 - sender: MessageSender, 82 - sendResponse: (response?: any) => void, 83 - ) => void 84 - >; 85 - 86 - export type ExtensionConnectEvent = Event<(port: Port) => void>; 87 - export type RuntimeEvent = Event<() => void>; 88 - export type RuntimeRestartRequiredEvent = Event< 89 - (reason: string) => void 90 - >; 91 - export type RuntimeUpdateAvailableEvent = Event< 92 - (details: UpdateAvailableDetails) => void 93 - >; 94 - 95 - export interface RuntimeModule { 96 - lastError: LastError | undefined; 97 - id: string; 98 - 99 - onConnect: ExtensionConnectEvent; 100 - onConnectExternal: ExtensionConnectEvent; 101 - onSuspend: RuntimeEvent; 102 - onStartup: RuntimeEvent; 103 - onInstalled: RuntimeEvent; 104 - onSuspendCanceled: RuntimeEvent; 105 - onMessage: ExtensionMessageEvent; 106 - onMessageExternal: ExtensionMessageEvent; 107 - onRestartRequired: RuntimeRestartRequiredEvent; 108 - onUpdateAvailable: RuntimeUpdateAvailableEvent; 109 - onBrowserUpdateAvailable: RuntimeEvent; 110 - 111 - connect: (connectInfo?: ConnectInfo) => Port; 112 - connectNative: (application: string) => Port; 113 - getBackgroundPage: (callback: (backgroundPage?: Window) => void) => void; 114 - getManifest: () => Manifest; 115 - getPackageDirectoryEntry: ( 116 - callback: (directoryEntry: any) => void, 117 - ) => void; 118 - getPlatformInfo: () => Promise<PlatformInfo>; 119 - getURL: (path: string) => string; 120 - reload: () => void; 121 - requestUpdateCheck: ( 122 - callback: ( 123 - status: RequestUpdateCheckStatus, 124 - details?: UpdateCheckDetails, 125 - ) => void, 126 - ) => void; 127 - restart: () => void; 128 - restartAfterDelay: (seconds: number, callback?: () => void) => void; 129 - sendMessage: <M, R>( 130 - message: M, 131 - options: MessageOptions, 132 - responseCallback: (response: R) => void, 133 - ) => void; 134 - sendNativeMessage: ( 135 - application: string, 136 - message: Object, 137 - responseCallback: (response: any) => void, 138 - ) => void; 139 - setUninstallURL: (url: string, callback?: () => void) => void; 140 - openOptionsPage: (callback?: () => void) => void; 141 - }
-43
source/browser_api/modules/storage.ts
··· 1 - // deno-lint-ignore-file no-explicit-any no-empty-interface 2 - import { Event } from './event.ts'; 3 - 4 - export interface StorageArea { 5 - getBytesInUse(keys?: string | string[] | null): Promise<number>; 6 - clear(): Promise<void>; 7 - set(items: { [key: string]: any }): Promise<void>; 8 - remove(keys: string | string[]): Promise<void>; 9 - get( 10 - keys?: string | string[] | { [key: string]: any } | null, 11 - ): Promise<{ [key: string]: any }>; 12 - } 13 - 14 - export interface StorageChange { 15 - newValue?: any; 16 - oldValue?: any; 17 - } 18 - 19 - export interface LocalStorageArea extends StorageArea { 20 - QUOTA_BYTES: number; 21 - } 22 - 23 - export interface SyncStorageArea extends StorageArea { 24 - MAX_SUSTAINED_WRITE_OPERATIONS_PER_MINUTE: number; 25 - QUOTA_BYTES: number; 26 - QUOTA_BYTES_PER_ITEM: number; 27 - MAX_ITEMS: number; 28 - MAX_WRITE_OPERATIONS_PER_HOUR: number; 29 - MAX_WRITE_OPERATIONS_PER_MINUTE: number; 30 - } 31 - 32 - type AreaName = 'sync' | 'local' | 'managed'; 33 - export interface StorageChangedEvent extends 34 - Event< 35 - (changes: { [key: string]: StorageChange }, areaName: AreaName) => void 36 - > {} 37 - 38 - export interface StorageModule { 39 - local: LocalStorageArea; 40 - sync: SyncStorageArea; 41 - managed: StorageArea; 42 - onChanged: StorageChangedEvent; 43 - }
-287
source/browser_api/modules/tabs.ts
··· 1 - // deno-lint-ignore-file no-explicit-any 2 - 3 - import type { Window } from './windows.ts'; 4 - import type { Event } from './event.ts'; 5 - import type { Port } from './runtime.ts'; 6 - 7 - export interface MutedInfo { 8 - muted: boolean; 9 - reason?: string | undefined; 10 - extensionId?: string | undefined; 11 - } 12 - 13 - export interface Tab { 14 - status?: string | undefined; 15 - index: number; 16 - openerTabId?: number | undefined; 17 - title?: string | undefined; 18 - url?: string | undefined; 19 - pendingUrl?: string | undefined; 20 - pinned: boolean; 21 - highlighted: boolean; 22 - windowId: number; 23 - active: boolean; 24 - favIconUrl?: string | undefined; 25 - id?: number | undefined; 26 - incognito: boolean; 27 - selected: boolean; 28 - audible?: boolean | undefined; 29 - discarded: boolean; 30 - autoDiscardable: boolean; 31 - mutedInfo?: MutedInfo | undefined; 32 - width?: number | undefined; 33 - height?: number | undefined; 34 - sessionId?: string | undefined; 35 - groupId: number; 36 - } 37 - 38 - export interface ZoomSettings { 39 - mode?: string | undefined; 40 - scope?: string | undefined; 41 - defaultZoomFactor?: number | undefined; 42 - } 43 - 44 - export interface InjectDetails { 45 - allFrames?: boolean | undefined; 46 - code?: string | undefined; 47 - runAt?: string | undefined; 48 - file?: string | undefined; 49 - frameId?: number | undefined; 50 - matchAboutBlank?: boolean | undefined; 51 - cssOrigin?: string | undefined; 52 - } 53 - 54 - export interface CreateProperties { 55 - index?: number | undefined; 56 - openerTabId?: number | undefined; 57 - url?: string | undefined; 58 - pinned?: boolean | undefined; 59 - windowId?: number | undefined; 60 - active?: boolean | undefined; 61 - selected?: boolean | undefined; 62 - } 63 - 64 - export interface MoveProperties { 65 - index: number; 66 - windowId?: number | undefined; 67 - } 68 - 69 - export interface UpdateProperties { 70 - pinned?: boolean | undefined; 71 - openerTabId?: number | undefined; 72 - url?: string | undefined; 73 - highlighted?: boolean | undefined; 74 - active?: boolean | undefined; 75 - selected?: boolean | undefined; 76 - muted?: boolean | undefined; 77 - autoDiscardable?: boolean | undefined; 78 - } 79 - 80 - export interface CaptureVisibleTabOptions { 81 - quality?: number | undefined; 82 - format?: string | undefined; 83 - } 84 - 85 - export interface ReloadProperties { 86 - bypassCache?: boolean | undefined; 87 - } 88 - 89 - export interface ConnectInfo { 90 - name?: string | undefined; 91 - frameId?: number | undefined; 92 - } 93 - 94 - export interface MessageSendOptions { 95 - frameId?: number | undefined; 96 - } 97 - 98 - export interface GroupOptions { 99 - createProperties?: { 100 - windowId?: number | undefined; 101 - } | undefined; 102 - groupId?: number | undefined; 103 - tabIds?: number | number[] | undefined; 104 - } 105 - 106 - export interface HighlightInfo { 107 - tabs: number | number[]; 108 - windowId?: number | undefined; 109 - } 110 - 111 - export interface QueryInfo { 112 - status?: 'loading' | 'complete' | undefined; 113 - lastFocusedWindow?: boolean | undefined; 114 - windowId?: number | undefined; 115 - windowType?: 'normal' | 'popup' | 'panel' | 'app' | 'devtools' | undefined; 116 - active?: boolean | undefined; 117 - index?: number | undefined; 118 - title?: string | undefined; 119 - url?: string | string[] | undefined; 120 - currentWindow?: boolean | undefined; 121 - highlighted?: boolean | undefined; 122 - discarded?: boolean | undefined; 123 - autoDiscardable?: boolean | undefined; 124 - pinned?: boolean | undefined; 125 - audible?: boolean | undefined; 126 - muted?: boolean | undefined; 127 - groupId?: number | undefined; 128 - } 129 - 130 - export interface TabHighlightInfo { 131 - windowId: number; 132 - tabIds: number[]; 133 - } 134 - 135 - export interface TabRemoveInfo { 136 - windowId: number; 137 - isWindowClosing: boolean; 138 - } 139 - 140 - export interface TabAttachInfo { 141 - newPosition: number; 142 - newWindowId: number; 143 - } 144 - 145 - export interface TabChangeInfo { 146 - status?: string | undefined; 147 - pinned?: boolean | undefined; 148 - url?: string | undefined; 149 - audible?: boolean | undefined; 150 - discarded?: boolean | undefined; 151 - autoDiscardable?: boolean | undefined; 152 - groupId?: number | undefined; 153 - mutedInfo?: MutedInfo | undefined; 154 - favIconUrl?: string | undefined; 155 - title?: string | undefined; 156 - } 157 - 158 - export interface TabMoveInfo { 159 - toIndex: number; 160 - windowId: number; 161 - fromIndex: number; 162 - } 163 - 164 - export interface TabDetachInfo { 165 - oldWindowId: number; 166 - oldPosition: number; 167 - } 168 - 169 - export interface TabActiveInfo { 170 - tabId: number; 171 - windowId: number; 172 - } 173 - 174 - export interface TabWindowInfo { 175 - windowId: number; 176 - } 177 - 178 - export interface ZoomChangeInfo { 179 - tabId: number; 180 - oldZoomFactor: number; 181 - newZoomFactor: number; 182 - zoomSettings: ZoomSettings; 183 - } 184 - 185 - export type TabHighlightedEvent = Event< 186 - (highlightInfo: TabHighlightInfo) => void 187 - >; 188 - export type TabRemovedEvent = Event< 189 - (tabId: number, removeInfo: TabRemoveInfo) => void 190 - >; 191 - export type TabUpdatedEvent = Event< 192 - (tabId: number, changeInfo: TabChangeInfo, tab: Tab) => void 193 - >; 194 - export type TabAttachedEvent = Event< 195 - (tabId: number, attachInfo: TabAttachInfo) => void 196 - >; 197 - export type TabMovedEvent = Event< 198 - (tabId: number, moveInfo: TabMoveInfo) => void 199 - >; 200 - export type TabDetachedEvent = Event< 201 - (tabId: number, detachInfo: TabDetachInfo) => void 202 - >; 203 - export type TabCreatedEvent = Event<(tab: Tab) => void>; 204 - export type TabActivatedEvent = Event<(activeInfo: TabActiveInfo) => void>; 205 - export type TabReplacedEvent = Event< 206 - (addedTabId: number, removedTabId: number) => void 207 - >; 208 - export type TabSelectedEvent = Event< 209 - (tabId: number, selectInfo: TabWindowInfo) => void 210 - >; 211 - export type TabZoomChangeEvent = Event< 212 - (ZoomChangeInfo: ZoomChangeInfo) => void 213 - >; 214 - 215 - export interface TabsModule { 216 - onHighlighted: TabHighlightedEvent; 217 - onRemoved: TabRemovedEvent; 218 - onUpdated: TabUpdatedEvent; 219 - onAttached: TabAttachedEvent; 220 - onMoved: TabMovedEvent; 221 - onDetached: TabDetachedEvent; 222 - onCreated: TabCreatedEvent; 223 - onActivated: TabActivatedEvent; 224 - onReplaced: TabReplacedEvent; 225 - onSelectionChanged: TabSelectedEvent; 226 - onActiveChanged: TabSelectedEvent; 227 - onHighlightChanged: TabHighlightedEvent; 228 - onZoomChange: TabZoomChangeEvent; 229 - TAB_ID_NONE: -1; 230 - 231 - executeScript: ( 232 - tabId: number, 233 - details: InjectDetails, 234 - ) => Promise<any[]>; 235 - get: (tabId: number) => Promise<Tab>; 236 - getAllInWindow: (windowId: number) => Promise<Tab>; 237 - getCurrent: () => Promise<Tab>; 238 - getSelected: (windowId: number) => Promise<Tab>; 239 - create: (createProperties: CreateProperties) => Promise<Tab>; 240 - move: ( 241 - tabIds: number[], 242 - moveProperties: MoveProperties, 243 - ) => Promise<Tab[]>; 244 - update: ( 245 - tabId: number, 246 - updateProperties: UpdateProperties, 247 - ) => Promise<Tab>; 248 - remove: (tabIds: number[]) => Promise<void>; 249 - captureVisibleTab: ( 250 - windowId: number, 251 - options: CaptureVisibleTabOptions, 252 - ) => Promise<string>; 253 - reload: ( 254 - tabId: number, 255 - reloadProperties?: ReloadProperties, 256 - ) => Promise<void>; 257 - duplicate: (tabId: number, callback?: (tab?: Tab) => void) => void; 258 - connect: (tabId: number, connectInfo?: ConnectInfo) => Port; 259 - insertCSS: (tabId: number, details: InjectDetails) => Promise<void>; 260 - highlight: ( 261 - highlightInfo: HighlightInfo, 262 - ) => Promise<Window>; 263 - query: (queryInfo: QueryInfo) => Promise<Tab[]>; 264 - detectLanguage: (tabId: number) => Promise<string>; 265 - getZoom: (tabId: number) => Promise<number>; 266 - setZoomSettings: ( 267 - tabId: number, 268 - zoomSettings: ZoomSettings, 269 - ) => Promise<void>; 270 - getZoomSettings: (tabId: number) => Promise<ZoomSettings>; 271 - discard: (tabId?: number) => Promise<Tab>; 272 - goForward: (tabId: number) => Promise<void>; 273 - goBack: (tabId: number) => Promise<void>; 274 - group: (options: GroupOptions) => Promise<number>; 275 - ungroup: (tabIds: number | number[]) => Promise<void>; 276 - sendMessage: <M = any, R = any>( 277 - tabId: number, 278 - message: M, 279 - options?: MessageSendOptions, 280 - responseCallback?: (response: R) => void, 281 - ) => void; 282 - sendRequest: <Request = any, Response = any>( 283 - tabId: number, 284 - request: Request, 285 - responseCallback?: (response: Response) => void, 286 - ) => void; 287 - }
-287
source/browser_api/modules/web_request.ts
··· 1 - // deno-lint-ignore-file no-empty-interface 2 - 3 - import { EventWithRequiredFilterInAddListener, Function } from './event.ts'; 4 - 5 - export type ResourceType = 6 - | 'main_frame' 7 - | 'sub_frame' 8 - | 'stylesheet' 9 - | 'script' 10 - | 'image' 11 - | 'font' 12 - | 'object' 13 - | 'xmlhttprequest' 14 - | 'ping' 15 - | 'csp_report' 16 - | 'media' 17 - | 'websocket' 18 - | 'other'; 19 - 20 - export interface AuthCredentials { 21 - username: string; 22 - password: string; 23 - } 24 - 25 - export interface HttpHeader { 26 - name: string; 27 - value?: string | undefined; 28 - binaryValue?: ArrayBuffer | undefined; 29 - } 30 - 31 - /** Returns value for event handlers that have the 'blocking' extraInfoSpec applied. Allows the event handler to modify network requests. */ 32 - export interface BlockingResponse { 33 - /** Optional. If true, the request is cancelled. Used in onBeforeRequest, this prevents the request from being sent. */ 34 - cancel?: boolean | undefined; 35 - /** 36 - * Optional. 37 - * Only used as a response to the onBeforeRequest and onHeadersReceived events. If set, the original request is prevented from being sent/completed and is instead redirected to the given URL. Redirections to non-HTTP schemes such as data: are allowed. Redirects initiated by a redirect action use the original request method for the redirect, with one exception: If the redirect is initiated at the onHeadersReceived stage, then the redirect will be issued using the GET method. 38 - */ 39 - redirectUrl?: string | undefined; 40 - /** 41 - * Optional. 42 - * Only used as a response to the onHeadersReceived event. If set, the server is assumed to have responded with these response headers instead. Only return responseHeaders if you really want to modify the headers in order to limit the number of conflicts (only one extension may modify responseHeaders for each request). 43 - */ 44 - responseHeaders?: HttpHeader[] | undefined; 45 - /** Optional. Only used as a response to the onAuthRequired event. If set, the request is made using the supplied credentials. */ 46 - authCredentials?: AuthCredentials | undefined; 47 - /** 48 - * Optional. 49 - * Only used as a response to the onBeforeSendHeaders event. If set, the request is made with these request headers instead. 50 - */ 51 - requestHeaders?: HttpHeader[] | undefined; 52 - } 53 - 54 - /** An object describing filters to apply to webRequest events. */ 55 - export interface RequestFilter { 56 - /** Optional. */ 57 - tabId?: number | undefined; 58 - /** 59 - * A list of request types. Requests that cannot match any of the types will be filtered out. 60 - */ 61 - types?: ResourceType[] | undefined; 62 - /** A list of URLs or URL patterns. Requests that cannot match any of the URLs will be filtered out. */ 63 - urls: string[]; 64 - 65 - /** Optional. */ 66 - windowId?: number | undefined; 67 - } 68 - 69 - /** 70 - * Contains data uploaded in a URL request. 71 - * @since Chrome 23. 72 - */ 73 - export interface UploadData { 74 - /** Optional. An ArrayBuffer with a copy of the data. */ 75 - bytes?: ArrayBuffer | undefined; 76 - /** Optional. A string with the file's path and name. */ 77 - file?: string | undefined; 78 - } 79 - 80 - export interface WebRequestBody { 81 - /** Optional. Errors when obtaining request body data. */ 82 - error?: string | undefined; 83 - /** 84 - * Optional. 85 - * If the request method is POST and the body is a sequence of key-value pairs encoded in UTF8, encoded as either multipart/form-data, or application/x-www-form-urlencoded, this dictionary is present and for each key contains the list of all values for that key. If the data is of another media type, or if it is malformed, the dictionary is not present. An example value of this dictionary is {'key': ['value1', 'value2']}. 86 - */ 87 - formData?: { [key: string]: string[] } | undefined; 88 - /** 89 - * Optional. 90 - * If the request method is PUT or POST, and the body is not already parsed in formData, then the unparsed request body elements are contained in this array. 91 - */ 92 - raw?: UploadData[] | undefined; 93 - } 94 - 95 - export interface WebAuthChallenger { 96 - host: string; 97 - port: number; 98 - } 99 - 100 - export interface ResourceRequest { 101 - url: string; 102 - /** The ID of the request. Request IDs are unique within a browser session. As a result, they could be used to relate different events of the same request. */ 103 - requestId: string; 104 - /** The value 0 indicates that the request happens in the main frame; a positive value indicates the ID of a subframe in which the request happens. If the document of a (sub-)frame is loaded (type is main_frame or sub_frame), frameId indicates the ID of this frame, not the ID of the outer frame. Frame IDs are unique within a tab. */ 105 - frameId: number; 106 - /** ID of frame that wraps the frame which sent the request. Set to -1 if no parent frame exists. */ 107 - parentFrameId: number; 108 - /** The ID of the tab in which the request takes place. Set to -1 if the request isn't related to a tab. */ 109 - tabId: number; 110 - /** 111 - * How the requested resource will be used. 112 - */ 113 - type: ResourceType; 114 - /** The time when this signal is triggered, in milliseconds since the epoch. */ 115 - timeStamp: number; 116 - /** The origin where the request was initiated. This does not change through redirects. If this is an opaque origin, the string 'null' will be used. 117 - * @since Since Chrome 63. 118 - */ 119 - initiator?: string | undefined; 120 - } 121 - 122 - export interface WebRequestDetails extends ResourceRequest { 123 - /** Standard HTTP method. */ 124 - method: string; 125 - } 126 - 127 - export interface WebRequestHeadersDetails extends WebRequestDetails { 128 - /** Optional. The HTTP request headers that are going to be sent out with this request. */ 129 - requestHeaders?: HttpHeader[] | undefined; 130 - } 131 - 132 - export interface WebRequestBodyDetails extends WebRequestDetails { 133 - /** 134 - * Contains the HTTP request body data. Only provided if extraInfoSpec contains 'requestBody'. 135 - * @since Chrome 23. 136 - */ 137 - requestBody: WebRequestBody | null; 138 - } 139 - 140 - export interface WebRequestFullDetails 141 - extends WebRequestHeadersDetails, WebRequestBodyDetails {} 142 - 143 - export interface WebResponseDetails extends ResourceRequest { 144 - /** HTTP status line of the response or the 'HTTP/0.9 200 OK' string for HTTP/0.9 responses (i.e., responses that lack a status line). */ 145 - statusLine: string; 146 - /** 147 - * Standard HTTP status code returned by the server. 148 - * @since Chrome 43. 149 - */ 150 - statusCode: number; 151 - } 152 - 153 - export interface WebResponseHeadersDetails extends WebResponseDetails { 154 - /** Optional. The HTTP response headers that have been received with this response. */ 155 - responseHeaders?: HttpHeader[] | undefined; 156 - method: string /** standard HTTP method i.e. GET, POST, PUT, etc. */; 157 - } 158 - 159 - export interface WebResponseCacheDetails extends WebResponseHeadersDetails { 160 - /** 161 - * Optional. 162 - * The server IP address that the request was actually sent to. Note that it may be a literal IPv6 address. 163 - */ 164 - ip?: string | undefined; 165 - /** Indicates if this response was fetched from disk cache. */ 166 - fromCache: boolean; 167 - } 168 - 169 - export interface WebRedirectionResponseDetails extends WebResponseCacheDetails { 170 - /** The new URL. */ 171 - redirectUrl: string; 172 - } 173 - 174 - export interface WebAuthenticationChallengeDetails 175 - extends WebResponseHeadersDetails { 176 - /** The authentication scheme, e.g. Basic or Digest. */ 177 - scheme: string; 178 - /** The authentication realm provided by the server, if there is one. */ 179 - realm?: string | undefined; 180 - /** The server requesting authentication. */ 181 - challenger: WebAuthChallenger; 182 - /** True for Proxy-Authenticate, false for WWW-Authenticate. */ 183 - isProxy: boolean; 184 - } 185 - 186 - export interface WebResponseErrorDetails extends WebResponseCacheDetails { 187 - /** The error description. This string is not guaranteed to remain backwards compatible between releases. You must not parse and act based upon its content. */ 188 - error: string; 189 - } 190 - 191 - export interface WebRequestBodyEvent 192 - extends 193 - EventWithRequiredFilterInAddListener< 194 - (details: WebRequestBodyDetails) => BlockingResponse | void 195 - > { 196 - addListener( 197 - callback: (details: WebRequestBodyDetails) => BlockingResponse | void, 198 - filter: RequestFilter, 199 - opt_extraInfoSpec?: string[], 200 - ): void; 201 - } 202 - 203 - export interface WebRequestHeadersSynchronousEvent 204 - extends 205 - EventWithRequiredFilterInAddListener< 206 - (details: WebRequestHeadersDetails) => BlockingResponse | void 207 - > { 208 - addListener( 209 - callback: (details: WebRequestHeadersDetails) => BlockingResponse | void, 210 - filter: RequestFilter, 211 - opt_extraInfoSpec?: string[], 212 - ): void; 213 - } 214 - 215 - export interface WebRequestHeadersEvent 216 - extends 217 - EventWithRequiredFilterInAddListener< 218 - (details: WebRequestHeadersDetails) => void 219 - > { 220 - addListener( 221 - callback: (details: WebRequestHeadersDetails) => void, 222 - filter: RequestFilter, 223 - opt_extraInfoSpec?: string[], 224 - ): void; 225 - } 226 - 227 - export interface _WebResponseHeadersEvent<T extends WebResponseHeadersDetails> 228 - extends EventWithRequiredFilterInAddListener<(details: T) => void> { 229 - addListener( 230 - callback: (details: T) => void, 231 - filter: RequestFilter, 232 - opt_extraInfoSpec?: string[], 233 - ): void; 234 - } 235 - 236 - export interface WebResponseHeadersEvent 237 - extends 238 - EventWithRequiredFilterInAddListener< 239 - (details: WebResponseHeadersDetails) => BlockingResponse | void 240 - > { 241 - addListener( 242 - callback: (details: WebResponseHeadersDetails) => BlockingResponse | void, 243 - filter: RequestFilter, 244 - opt_extraInfoSpec?: string[], 245 - ): void; 246 - } 247 - 248 - export interface WebResponseCacheEvent 249 - extends _WebResponseHeadersEvent<WebResponseCacheDetails> {} 250 - 251 - export interface WebRedirectionResponseEvent 252 - extends _WebResponseHeadersEvent<WebRedirectionResponseDetails> {} 253 - 254 - export interface WebAuthenticationChallengeEvent 255 - extends 256 - EventWithRequiredFilterInAddListener< 257 - ( 258 - details: WebAuthenticationChallengeDetails, 259 - callback?: (response: BlockingResponse) => void, 260 - ) => void 261 - > { 262 - addListener( 263 - callback: ( 264 - details: WebAuthenticationChallengeDetails, 265 - callback?: (response: BlockingResponse) => void, 266 - ) => void, 267 - filter: RequestFilter, 268 - opt_extraInfoSpec?: string[], 269 - ): void; 270 - } 271 - 272 - export interface WebResponseErrorEvent 273 - extends _WebResponseHeadersEvent<WebResponseErrorDetails> {} 274 - 275 - export interface WebRequest { 276 - MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES: number; 277 - handlerBehaviorChanged: (callback?: Function) => void; 278 - onBeforeRequest: WebRequestBodyEvent; 279 - onBeforeSendHeaders: WebRequestHeadersSynchronousEvent; 280 - onSendHeaders: WebRequestHeadersEvent; 281 - onHeadersReceived: WebResponseHeadersEvent; 282 - onAuthRequired: WebAuthenticationChallengeEvent; 283 - onResponseStarted: WebResponseCacheEvent; 284 - onBeforeRedirect: WebRedirectionResponseEvent; 285 - onCompleted: WebResponseCacheEvent; 286 - onErrorOccurred: WebResponseErrorEvent; 287 - }
-100
source/browser_api/modules/windows.ts
··· 1 - import type { Tab } from './tabs.ts'; 2 - import type { Event } from './event.ts'; 3 - 4 - export interface Window { 5 - tabs?: Tab[] | undefined; 6 - top?: number | undefined; 7 - height?: number | undefined; 8 - width?: number | undefined; 9 - state?: windowStateEnum | undefined; 10 - focused: boolean; 11 - alwaysOnTop: boolean; 12 - incognito: boolean; 13 - type?: windowTypeEnum | undefined; 14 - id?: number | undefined; 15 - left?: number | undefined; 16 - sessionId?: string | undefined; 17 - } 18 - 19 - export interface QueryOptions { 20 - populate?: boolean | undefined; 21 - windowTypes?: windowTypeEnum[] | undefined; 22 - } 23 - 24 - export interface CreateData { 25 - tabId?: number | undefined; 26 - url?: string | string[] | undefined; 27 - top?: number | undefined; 28 - height?: number | undefined; 29 - width?: number | undefined; 30 - focused?: boolean | undefined; 31 - incognito?: boolean | undefined; 32 - type?: createTypeEnum | undefined; 33 - left?: number | undefined; 34 - state?: windowStateEnum | undefined; 35 - setSelfAsOpener?: boolean | undefined; 36 - } 37 - 38 - export interface UpdateInfo { 39 - top?: number | undefined; 40 - drawAttention?: boolean | undefined; 41 - height?: number | undefined; 42 - width?: number | undefined; 43 - state?: windowStateEnum | undefined; 44 - focused?: boolean | undefined; 45 - left?: number | undefined; 46 - } 47 - 48 - export interface WindowEventFilter { 49 - windowTypes: windowTypeEnum[]; 50 - } 51 - 52 - export interface WindowIdEvent extends Event<(windowId: number) => void> { 53 - addListener( 54 - callback: (windowId: number) => void, 55 - filters?: WindowEventFilter, 56 - ): void; 57 - } 58 - 59 - export interface WindowReferenceEvent extends Event<(window: Window) => void> { 60 - addListener( 61 - callback: (window: Window) => void, 62 - filters?: WindowEventFilter, 63 - ): void; 64 - } 65 - export type createTypeEnum = 'normal' | 'popup' | 'panel'; 66 - export type windowStateEnum = 67 - | 'normal' 68 - | 'minimized' 69 - | 'maximized' 70 - | 'fullscreen' 71 - | 'locked-fullscreen'; 72 - export type windowTypeEnum = 'normal' | 'popup' | 'panel' | 'app' | 'devtools'; 73 - 74 - export interface WindowsModule { 75 - WINDOW_ID_CURRENT: -2; 76 - WINDOW_ID_NONE: -1; 77 - onRemoved: WindowIdEvent; 78 - onCreated: WindowReferenceEvent; 79 - onFocusChanged: WindowIdEvent; 80 - onBoundsChanged: WindowReferenceEvent; 81 - get: ( 82 - windowId: number, 83 - queryOptions?: QueryOptions, 84 - ) => Promise<Window>; 85 - getCurrent: ( 86 - queryOptions?: QueryOptions, 87 - ) => Promise<Window>; 88 - create: (createData?: CreateData) => Promise<Window>; 89 - getAll: ( 90 - queryOptions?: QueryOptions, 91 - ) => Promise<Window[]>; 92 - update: ( 93 - windowId: number, 94 - updateInfo: UpdateInfo, 95 - ) => Promise<Window>; 96 - remove: (windowId: number) => Promise<void>; 97 - getLastFocused: ( 98 - queryOptions: QueryOptions, 99 - ) => Promise<Window>; 100 - }
+1 -13
source/components/checkbox.tsx
··· 19 19 label, 20 20 ...props 21 21 }: CheckboxProps) { 22 - const [isFocused, setFocused] = useState(false); 23 - 24 - const onBlur = useCallback(() => { 25 - setFocused(false); 26 - }, [setFocused]); 27 - 28 - const onFocus = useCallback(() => { 29 - setFocused(true); 30 - }, [setFocused]); 31 - 32 22 const onChange = useCallback((e: Event) => { 33 23 const { name, checked } = (e?.target as HTMLInputElement); 34 24 if (props.onChange && name && typeof checked === 'boolean') { ··· 37 27 }, [props.onChange]); 38 28 39 29 return ( 40 - <div className={`checkbox ${isFocused ? 'focused' : ''}`}> 30 + <div className='checkbox'> 41 31 <label className='help'>{label}</label> 42 32 <input 43 33 id='flag' ··· 45 35 tabIndex={0} 46 36 name={name} 47 37 checked={checked} 48 - onBlur={onBlur} 49 - onFocus={onFocus} 50 38 onChange={onChange} 51 39 /> 52 40 <div className='checkmark' />
-12
source/components/emoji_picker.tsx
··· 1 - /* @jsx h */ 2 - 3 - import { h } from 'preact'; 4 - 5 - interface EmojiPickerProps { 6 - // deno-lint-ignore no-explicit-any 7 - [name: string]: any; 8 - } 9 - 10 - export default function EmojiPicker(props: EmojiPickerProps) { 11 - return <div />; 12 - }
+164
source/components/emoji_selector.tsx
··· 1 + /* @jsx h */ 2 + 3 + import { Fragment, h } from 'preact'; 4 + import { useCallback, useMemo, useState } from 'preact/hooks'; 5 + import * as emoji from 'emoji'; 6 + import type { Emoji } from 'https://deno.land/x/emoji@0.2.0/types.ts'; 7 + 8 + const emojis = emoji.all(); 9 + const emojiGroups = {}; 10 + 11 + // create emojiGroups 12 + emojiGroups.All = emojis; 13 + // emojiGroups.frequentlyUsed = []; 14 + // emojiGroups.custom = []; 15 + emojis.forEach((emoji) => { 16 + if (!emojiGroups[emoji.group]) { 17 + emojiGroups[emoji.group] = []; 18 + } 19 + emojiGroups[emoji.group].push(emoji); 20 + }); 21 + 22 + interface EmojiSelectorProps { 23 + // deno-lint-ignore no-explicit-any 24 + [name: string]: any; 25 + } 26 + 27 + export default function EmojiSelector(props: EmojiSelectorProps) { 28 + const [isOpen, setIsOpen] = useState<boolean>(false); 29 + const [selected, setSelected] = useState<Emoji>( 30 + emoji.infoByAlias('grinning_face'), 31 + ); 32 + const onEmojiSelected = useCallback((emoji) => { 33 + if (isOpen) { 34 + props.onEmojiSelected(emoji); 35 + setSelected(emoji); 36 + setIsOpen(false); 37 + } 38 + }, [isOpen, setIsOpen]); 39 + 40 + return ( 41 + <Fragment> 42 + <Button isOpen={isOpen} setIsOpen={setIsOpen} emoji={selected} /> 43 + <Selector isOpen={isOpen} onEmojiSelected={onEmojiSelected} /> 44 + </Fragment> 45 + ); 46 + 47 + return; 48 + } 49 + 50 + function Button({ isOpen, setIsOpen, emoji }) { 51 + const onClick = useCallback(() => { 52 + setIsOpen(!isOpen); 53 + }, [isOpen]); 54 + 55 + return ( 56 + <button 57 + type='button' 58 + onClick={onClick} 59 + > 60 + {emoji.emoji} 61 + </button> 62 + ); 63 + } 64 + 65 + function Selector({ isOpen, onEmojiSelected }) { 66 + const [currGroup, setCurrGroup] = useState(Object.keys(emojiGroups)[0]); 67 + const [filter, setFilter] = useState(''); 68 + 69 + if (!isOpen) return null; 70 + 71 + return ( 72 + <div style='width: 500px; height: 500px; background-color: grey; z-index: 1000; overflow: scroll;' /* onlosefocus */> 73 + <input 74 + type='text' 75 + spellcheck={false} 76 + placeholder='smile' 77 + value={filter} 78 + onChange={(e) => { 79 + setFilter(e.target.value); 80 + }} 81 + onInput={(e) => { 82 + setFilter(e.target.value); 83 + }} 84 + /> 85 + <ColorSelector /> 86 + <GroupSelector 87 + emojiGroups={Object.keys(emojiGroups).map((name) => { 88 + const emojis = emojiGroups[name]; 89 + const representativeEmoji = emojis[0].emoji; 90 + return { name, emojis, representativeEmoji }; 91 + })} 92 + setGroup={setCurrGroup} 93 + /> 94 + <Group 95 + onSelect={onEmojiSelected} 96 + name={currGroup} 97 + emojis={emojiGroups[currGroup] 98 + .filter((emoji) => { 99 + if (!emoji) return false; 100 + if (!filter) return true; 101 + return new RegExp(filter).test( 102 + emoji.tags.concat(emoji.aliases).concat([ 103 + emoji.group, 104 + emoji.subgroup, 105 + ]).join(' '), 106 + ); 107 + })} 108 + /> 109 + </div> 110 + ); 111 + } 112 + 113 + function ColorSelector() { 114 + return ( 115 + <button type='button' className='color-selector'> 116 + {'🤯'} 117 + </button> 118 + ); 119 + } 120 + 121 + interface EmojiGroup { 122 + name: string; 123 + representativeEmoji: string; 124 + emojis: Emoji[]; 125 + } 126 + 127 + // Group Name + Representative 128 + function GroupSelector( 129 + { emojiGroups = [], setGroup }: { emojiGroups: EmojiGroup[]; setGroup: any }, 130 + ) { 131 + const groupButtons = useMemo(() => 132 + emojiGroups.map((emojiGroup) => { 133 + return ( 134 + <button type='button' onClick={() => setGroup(emojiGroup.name)}> 135 + {emojiGroup.representativeEmoji} 136 + </button> 137 + ); 138 + }), [emojiGroups]); 139 + 140 + return ( 141 + <div className='group-selector'> 142 + {groupButtons} 143 + </div> 144 + ); 145 + } 146 + 147 + function Group({ name, emojis, onSelect }) { 148 + const selectionButtons = emojis.map((emoji) => ( 149 + <button 150 + type='button' 151 + onClick={(e) => { onSelect(emoji) }} 152 + > 153 + {emoji.emoji} 154 + </button> 155 + )); 156 + 157 + return ( 158 + <div> 159 + <h1>{name}</h1> 160 + {selectionButtons} 161 + <button type="button">add custom emoji</button> 162 + </div> 163 + ); 164 + }
+2
source/components/list.tsx
··· 5 5 import { h } from 'preact'; 6 6 import { useRef } from 'preact/hooks'; 7 7 8 + import EmojiSelector from './emoji_selector.tsx'; 8 9 import ListInput from './list_input.tsx'; 9 10 10 11 export interface ListProps<Type> { ··· 42 43 return ( 43 44 <div className='list' ref={listRef}> 44 45 {listInputs.concat(newItemInput)} 46 + {/*<EmojiSelector onEmojiSelected={(emoji) => console.log(emoji)} />*/} 45 47 </div> 46 48 ); 47 49 }
+2 -2
source/pages/favicons_page.tsx
··· 41 41 42 42 return ( 43 43 <form onSubmit={save}> 44 - <h1>Override Favicons on these Sites</h1> 44 + <h1>{t('faviconListTitle')}</h1> 45 45 <List type='EMOJI' state={siteListState} /> 46 46 47 47 <Only if={Boolean(enableSiteIgnore || hasIgnores)}> 48 48 <Fragment> 49 49 <h1> 50 - Ignore These Sites 50 + {t('ignoreListTitle')} 51 51 <Only if={!enableSiteIgnore}> 52 52 <span style={{ opacity: 0.5 }}>(Disabled)</span> 53 53 </Only>
source/static/icons/128.png static/icons/128.png
source/static/icons/256.png static/icons/256.png
source/static/icons/32.png static/icons/32.png
source/static/icons/48.png static/icons/48.png
source/static/icons/64.png static/icons/64.png
source/static/options.html static/options.html
source/static/popup.html static/popup.html
source/static/screenshots/comparison.png static/screenshots/comparison.png
source/static/screenshots/default.png static/screenshots/default.png
source/static/screenshots/load-chrome-favioli.png static/screenshots/load-chrome-favioli.png
source/static/screenshots/load-ff-favioli.png static/screenshots/load-ff-favioli.png
source/static/screenshots/overrides.png static/screenshots/overrides.png
-5
source/static/styles/options.css static/styles/options.css
··· 165 165 -moz-user-select: none; 166 166 } 167 167 168 - .checkbox.focused .checkmark { 169 - outline-color: Highlight; 170 - outline-style: auto; 171 - } 172 - 173 168 .checkbox input { 174 169 cursor: pointer; 175 170 font-size: 24px;
source/static/styles/popup.css static/styles/popup.css
source/static/styles/shared.css static/styles/shared.css
+2 -1
source/utilities/autoselector.ts
··· 1 1 import type { Favicon } from '../types.ts'; 2 2 3 3 import * as emoji from 'emoji'; 4 + import type { Emoji } from 'https://deno.land/x/emoji@0.2.0/types.ts'; 4 5 import LEGACY_EMOJI_SET from '../config/legacy_autoselect_set.ts'; 5 6 6 7 const emojis = emoji.all(); 7 8 8 - type EmojiMap = { [alias: string]: emoji.Emoji }; 9 + type EmojiMap = { [alias: string]: Emoji }; 9 10 10 11 const NON_SPACING_MARK = String.fromCharCode(65039); // 65039 - '️' - 0xFE0F; 11 12 const reNonSpacing = new RegExp(NON_SPACING_MARK, 'g');
+2
source/utilities/i18n.ts
··· 15 15 enableFaviconAutofillPopup: broadPermissionsWarning, 16 16 enableSiteIgnoreDesc: 'Select sites that autofill should ignore', 17 17 enableSiteIgnoreLabel: 'Enable Ignore List', 18 + faviconListTitle: 'Override Favicons on these Sites', 19 + ignoreListTitle: 'Ignore These Sites', 18 20 saveLabel: 'Save', 19 21 }; 20 22
+1 -1
source/utilities/permissions.ts
··· 1 1 // https://developer.chrome.com/docs/extensions/reference/permissions/ 2 - import browserAPI from './browser_api.ts'; 2 + import browserAPI from 'bext'; 3 3 const { contains, request } = browserAPI.permissions; 4 4 5 5 const permissions = ['tabs'];