diff --git a/extensions/extensions.json b/extensions/extensions.json new file mode 100644 index 0000000..7010d75 --- /dev/null +++ b/extensions/extensions.json @@ -0,0 +1,28 @@ +{ + "ublock": { + "name": "uBlock Origin", + "logo": "https://lh3.googleusercontent.com/rrgyVBVte7CfjjeTU-rCHDKba7vtq-yn3o8-10p5b6QOj_2VCDAO3VdggV5fUnugbG2eDGPPjoJ9rsiU_tUZBExgLGc=s60", + "description": "uBlock Origin is not just an “ad blocker“, it's a wide-spectrum content blocker with CPU and memory efficiency as a primary feature.", + "types": ["Browser Extension", "other"], + "behaviorHints": { + "configurable": true, + "configurationRequired": false, + "adult": false, + "p2p": false + }, + "page": "dashboard.html" + }, + "premid": { + "name": "PreMiD", + "logo": "https://premid.app/_ipx/loading_lazy,f_webp,s_450x150/images/logo-wordmark-blue.png", + "description": "PreMiD is a simple, configurable utility that allows you to show what you're doing on the web in your Discord now playing status / Discord Rich Presence ", + "types": ["Browser Extension", "other"], + "behaviorHints": { + "configurable": true, + "configurationRequired": false, + "adult": false, + "p2p": false + }, + "page": "popup.html" + } +} \ No newline at end of file diff --git a/src/core/globals.cpp b/src/core/globals.cpp index 5a211a3..93eabbf 100644 --- a/src/core/globals.cpp +++ b/src/core/globals.cpp @@ -83,6 +83,9 @@ std::wstring g_launchProtocol; std::atomic g_isAppReady = false; std::atomic g_waitStarted(false); +// Extensions +std::map g_extensionMap; + // Updater std::atomic_bool g_updaterRunning = false; std::filesystem::path g_installerPath; diff --git a/src/core/globals.h b/src/core/globals.h index 17feaed..cd7ea81 100644 --- a/src/core/globals.h +++ b/src/core/globals.h @@ -129,6 +129,9 @@ extern std::wstring g_launchProtocol; extern std::atomic g_isAppReady; extern std::atomic g_waitStarted; +// Extensions +extern std::map g_extensionMap; + // Updater extern std::atomic_bool g_updaterRunning; extern std::filesystem::path g_installerPath; diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index c91202f..d02943a 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -219,6 +219,9 @@ void HandleEvent(const std::string &ev, std::vector &args) } else if (ev=="open-external") { std::wstring uri(args[0].begin(), args[0].end()); ShellExecuteW(nullptr, L"open", uri.c_str(), nullptr, nullptr, SW_SHOWNORMAL); + } else if (ev=="navigate") { + std::wstring uri(args[0].begin(), args[0].end()); + g_webview->Navigate(uri.c_str()); } else { std::cout<<"Unknown event="<add_ContextMenuRequested( Microsoft::WRL::Callback( [](ICoreWebView2* sender, ICoreWebView2ContextMenuRequestedEventArgs* args) -> HRESULT { + // Existing variable declarations wil::com_ptr items; HRESULT hr = args->get_MenuItems(&items); - if (FAILED(hr) || !items) { - return hr; - } + if (FAILED(hr) || !items) return hr; - #ifdef DEBUG_BUILD - return S_OK; //DEV TOOLS DEBUG ONLY - #endif + + // Get current URL + wil::unique_cotaskmem_string currentUri; + sender->get_Source(¤tUri); + std::wstring uri(currentUri.get()); + bool isExtensionUrl = uri.starts_with(L"chrome-extension://"); + + // Get context menu target wil::com_ptr target; hr = args->get_ContextMenuTarget(&target); BOOL isEditable = FALSE; if (SUCCEEDED(hr) && target) { - hr = target->get_IsEditable(&isEditable); - } - if (FAILED(hr)) { - return hr; + target->get_IsEditable(&isEditable); } UINT count = 0; items->get_Count(&count); if (!isEditable) { - while(count > 0) { + // Allow only Back command (ID 33000) for extension URLs + std::set allowedCommands = isExtensionUrl ? + std::set{33000} : + std::set{}; + + for (UINT i = 0; i < count;) { wil::com_ptr item; - items->GetValueAtIndex(0, &item); - if(item) { - items->RemoveValueAtIndex(0); + hr = items->GetValueAtIndex(i, &item); + if (FAILED(hr)) { + i++; + continue; + } + + INT32 commandId; + item->get_CommandId(&commandId); + + if (allowedCommands.find(commandId) == allowedCommands.end()) { + items->RemoveValueAtIndex(i); + items->get_Count(&count); + } else { + i++; } - items->get_Count(&count); } return S_OK; } @@ -334,38 +350,26 @@ static void SetupWebMessageHandler() 50156 // Select all }; - for (UINT i = 0; i < count; ) - { + for (UINT i = 0; i < count;) { wil::com_ptr item; hr = items->GetValueAtIndex(i, &item); - if (FAILED(hr) || !item) { - ++i; - continue; - } - - INT32 commandId = 0; - hr = item->get_CommandId(&commandId); if (FAILED(hr)) { - ++i; + i++; continue; } - // If the commandId is not in the allowed list, remove the item + INT32 commandId; + item->get_CommandId(&commandId); + if (allowedCommandIds.find(commandId) == allowedCommandIds.end()) { - hr = items->RemoveValueAtIndex(i); - if (FAILED(hr)) { - std::wcerr << L"Failed to remove item at index " << i << std::endl; - return hr; - } - // After removal, the collection size reduces, so update count and don't increment i + items->RemoveValueAtIndex(i); items->get_Count(&count); - continue; + } else { + i++; } - ++i; } return S_OK; - } - ).Get(), + }).Get(), &contextMenuToken ); @@ -459,13 +463,24 @@ static void SetupExtensions() try { for(const auto& entry : std::filesystem::directory_iterator(extensionsRoot)) { if(entry.is_directory()) { + std::wstring folderName = entry.path().filename().wstring(); HRESULT hr = g_webviewProfile->AddBrowserExtension( entry.path().wstring().c_str(), Microsoft::WRL::Callback( - [extPath=entry.path().wstring()](HRESULT result, ICoreWebView2BrowserExtension* extension)->HRESULT + [folderName](HRESULT result, ICoreWebView2BrowserExtension* extension)->HRESULT { - if(SUCCEEDED(result)) { - std::wcout<get_Id(&extId); + if (SUCCEEDED(hrId) && extId) + { + // Store extension ID in the global map + g_extensionMap[folderName] = extId.get(); + std::wcout << L"[EXTENSIONS]: " << folderName + << L" => " << extId.get() << std::endl; + } + std::wcout << L"[EXTENSIONS]: Added extension " << folderName << std::endl; } else { std::wstring err = L"[EXTENSIONS]: Failed to add extension => " + std::to_wstring(result); AppendToCrashLog(err);