Plugin
ReplaceGoogleSearch
Replaces the Google search with different Engine(s)
1
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";2
import { definePluginSettings } from "@api/Settings";3
import { Flex } from "@components/Flex";4
import { Devs } from "@utils/constants";5
import definePlugin, { OptionType } from "@utils/types";6
import { Menu } from "@webpack/common";7
8
const DefaultEngines = {9
Google: "https:class="ts-cmt">//www.google.com/search?q=",10
DuckDuckGo: "https:class="ts-cmt">//duckduckgo.com/?q=",11
Brave: "https:class="ts-cmt">//search.brave.com/search?q=",12
Bing: "https:class="ts-cmt">//www.bing.com/search?q=",13
Yahoo: "https:class="ts-cmt">//search.yahoo.com/search?p=",14
Yandex: "https:class="ts-cmt">//yandex.com/search/?text=",15
GitHub: "https:class="ts-cmt">//github.com/search?q=",16
Reddit: "https:class="ts-cmt">//www.reddit.com/search?q=",17
Wikipedia: "https:class="ts-cmt">//wikipedia.org/w/index.php?search=",18
Startpage: "https:class="ts-cmt">//www.startpage.com/sp/search?query="19
} as const;20
21
const enum ReplacementEngineValue {22
OFF = "off",23
CUSTOM = "custom",24
}25
26
const settings = definePluginSettings({27
customEngineName: {28
description: "Name of the custom search engine",29
type: OptionType.STRING,30
placeholder: "Google"31
},32
customEngineURL: {33
displayName: "Custom Engine URL",34
description: "The URL of your Engine",35
type: OptionType.STRING,36
placeholder: "https:class="ts-cmt">//google.com/search?q="37
},38
replacementEngine: {39
description: "Replace with a specific search engine instead of adding a menu",40
type: OptionType.SELECT,41
options: [42
{ label: "Off", value: ReplacementEngineValue.OFF, default: true },43
{ label: "Custom Engine", value: ReplacementEngineValue.CUSTOM },44
...Object.keys(DefaultEngines).map(engine => ({ label: engine, value: engine }))45
]46
}47
});48
49
function search(src: string, engine: string) {50
open(engine + encodeURIComponent(src.trim()), "_blank");51
}52
53
function makeSearchItem(src: string) {54
const { customEngineName, customEngineURL, replacementEngine } = settings.store;55
56
const hasCustomEngine = Boolean(customEngineName && customEngineURL);57
const hasValidReplacementEngine = replacementEngine !== ReplacementEngineValue.OFF && !(replacementEngine === ReplacementEngineValue.CUSTOM && !hasCustomEngine);58
59
const Engines = { ...DefaultEngines };60
61
if (hasCustomEngine) {62
Engines[customEngineName!] = customEngineURL;63
}64
65
if (hasValidReplacementEngine) {66
const name = replacementEngine === ReplacementEngineValue.CUSTOM && hasCustomEngine67
? customEngineName68
: replacementEngine;69
70
return (71
<Menu.MenuItem72
label={`Search with ${name}`}73
key="search-custom-engine"74
id="vc-search-custom-engine"75
action={() => search(src, Engines[name!])}76
/>77
);78
}79
80
return (81
<Menu.MenuItem82
label="Search Text"83
key="search-text"84
id="vc-search-text"85
>86
{Object.keys(Engines).map(engine => {87
const key = "vc-search-content-" + engine;88
return (89
<Menu.MenuItem90
key={key}91
id={key}92
label={93
<Flex gap="0.5em" alignItems="center">94
<img95
style={{96
borderRadius: "50%"97
}}98
aria-hidden="true"99
height={16}100
width={16}101
src={`https:class="ts-cmt">//icons.duckduckgo.com/ip3/${new URL(Engines[engine]).hostname}.ico`}102
/>103
{engine}104
</Flex>105
}106
action={() => search(src, Engines[engine])}107
/>108
);109
})}110
</Menu.MenuItem>111
);112
}113
114
const messageContextMenuPatch: NavContextMenuPatchCallback = (children, _props) => {115
const selection = document.getSelection()?.toString();116
if (!selection) return;117
118
const group = findGroupChildrenByChildId("search-google", children);119
if (group) {120
const idx = group.findIndex(c => c?.props?.id === "search-google");121
if (idx !== -1) group[idx] = makeSearchItem(selection);122
}123
};124
125
export default definePlugin({126
name: "ReplaceGoogleSearch",127
description: "Replaces the Google search with different Engine(s)",128
tags: ["Utility", "Customisation"],129
authors: [Devs.Moxxie, Devs.Ethan],130
131
settings,132
133
contextMenus: {134
"message": messageContextMenuPatch135
}136
});137