bool CBrowerDialogContextMenu::RunContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model, CefRefPtr<CefRunContextMenuCallback> callback) { std::vector<std::pair<int, std::string>> entries; for (int i = 0; i < model->GetCount(); ++i) { int id = model->GetCommandIdAt(i); if (id < 0 || id == MENU_ID_PRINT || id == MENU_ID_VIEW_SOURCE || !model->IsEnabled(id)) { // ignored parts! continue; } cef_menu_item_type_t type = model->GetTypeAt(i); switch (type) { case MENUITEMTYPE_COMMAND: entries.push_back(std::pair<int, std::string>(id, kodi::GetLocalizedString(30000 + id))); break; // TODO add support for other formats e.g. boolean check case MENUITEMTYPE_CHECK: case MENUITEMTYPE_RADIO: case MENUITEMTYPE_SUBMENU: LOG_MESSAGE(ADDON_LOG_ERROR, "Context menu \"cef_menu_item_type_t '%i'\" currently not supported!", type); break; // TODO add support for separator case MENUITEMTYPE_SEPARATOR: break; case MENUITEMTYPE_NONE: default: break; } } if (!entries.empty()) { m_client->SetContextMenuOpen(true); /* Start the independent thread to prevent block on main thread */ std::thread(RunContextMenuProcess, m_client, entries, callback).detach(); } else { /* If no entries cancel the context menu */ callback->Cancel(); } /* Always true, otherwise Chromium's own context menu might be displayed. */ return true; }
JNIEXPORT void JNICALL Java_org_cef_callback_CefAuthCallback_1N_N_1Cancel (JNIEnv *env, jobject obj) { CefRefPtr<CefAuthCallback> callback = GetCefFromJNIObject<CefAuthCallback>(env, obj, "CefAuthCallback"); if (!callback.get()) return; callback->Cancel(); // Clear the reference added in RequestHandler::GetAuthCredentials SetCefForJNIObject<CefAuthCallback>(env, obj, NULL, "CefAuthCallback"); }
JNIEXPORT void JNICALL Java_org_cef_callback_CefDownloadItemCallback_1N_N_1Cancel (JNIEnv *env, jobject obj) { CefRefPtr<CefDownloadItemCallback> callback = GetCefFromJNIObject<CefDownloadItemCallback>(env, obj, "CefDownloadItemCallback"); if (!callback.get()) return; callback->Cancel(); // Clear the reference added in DownloadHandler::OnDownloadUpdated. SetCefForJNIObject<CefBeforeDownloadCallback>(env, obj, NULL, "CefBeforeDownloadCallback"); }
void CBrowerDialogContextMenu::RunContextMenuProcess(CWebBrowserClient* client, std::vector<std::pair<int, std::string>> entries, CefRefPtr<CefRunContextMenuCallback> callback) { int ret = kodi::gui::dialogs::ContextMenu::Show("", entries); if (ret >= 0) callback->Continue(entries[ret].first, EVENTFLAG_LEFT_MOUSE_BUTTON); else callback->Cancel(); client->SetContextMenuOpen(false); }
JNIEXPORT void JNICALL Java_org_cef_callback_CefFileDialogCallback_1N_N_1Cancel(JNIEnv* env, jobject obj) { CefRefPtr<CefFileDialogCallback> callback = GetCefFromJNIObject<CefFileDialogCallback>(env, obj, "CefFileDialogCallback"); if (!callback.get()) return; callback->Cancel(); // Clear the reference added in DialogHandler::OnFileDialog. SetCefForJNIObject<CefFileDialogCallback>(env, obj, NULL, "CefFileDialogCallback"); }
bool CaffeineClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser, FileDialogMode mode, const CefString& title, const CefString& default_file_name, const vector<CefString>& accept_types, CefRefPtr<CefFileDialogCallback> callback) { vector<CefString> files; if ( FileDlg(files, mode, title, default_file_name, accept_types) ) callback->Continue(files); else callback->Cancel(); return true; }
// First method called bool BrowserSchemeHandler::ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback) { CefURLParts parts; CefParseURL(request->GetURL(), parts); std::string path = CefString(&parts.path); fileName = path.substr(path.find_last_of("/") + 1); inputStream.open(path, std::ifstream::binary); if (!inputStream.is_open()) { callback->Cancel(); return false; } inputStream.seekg(0, std::ifstream::end); length = remaining = inputStream.tellg(); inputStream.seekg(0, std::ifstream::beg); callback->Continue(); return true; }
bool ClientAdapter::GetAuthCredentials(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, bool isProxy, const CefString& host, int port, const CefString& realm, const CefString& scheme, CefRefPtr<CefAuthCallback> callback) { IRequestHandler^ handler = _browserControl->RequestHandler; if (handler == nullptr) { return false; } String^ usernameString = nullptr; String^ passwordString = nullptr; bool handled = handler->GetAuthCredentials(_browserControl, isProxy, StringUtils::ToClr(host), port, StringUtils::ToClr(realm), StringUtils::ToClr(scheme), usernameString, passwordString); if (handled) { CefString username; CefString password; if (usernameString != nullptr) { username = StringUtils::ToNative(usernameString); } if (passwordString != nullptr) { password = StringUtils::ToNative(passwordString); } callback->Continue(username, password); } else { // TOOD: Should we call Cancel() here or not? At first glance, I believe we should since there will otherwise be no // way to cancel the auth request from an IRequestHandler. callback->Cancel(); } return handled; }
bool ClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser, FileDialogMode mode, const CefString& title, const CefString& default_file_name, const std::vector<CefString>& accept_types, CefRefPtr<CefFileDialogCallback> callback) { std::vector<CefString> files; GtkFileChooserAction action; const gchar* accept_button; if (mode == FILE_DIALOG_OPEN || mode == FILE_DIALOG_OPEN_MULTIPLE) { action = GTK_FILE_CHOOSER_ACTION_OPEN; accept_button = GTK_STOCK_OPEN; } else if (mode == FILE_DIALOG_SAVE) { action = GTK_FILE_CHOOSER_ACTION_SAVE; accept_button = GTK_STOCK_SAVE; } else { NOTREACHED(); return false; } std::string base_name; if (!default_file_name.empty()) { base_name = basename(const_cast<char*>(default_file_name.ToString().c_str())); } std::string title_str; if (!title.empty()) { title_str = title; } else { switch (mode) { case FILE_DIALOG_OPEN: title_str = "Open File"; break; case FILE_DIALOG_OPEN_MULTIPLE: title_str = "Open Files"; break; case FILE_DIALOG_SAVE: title_str = "Save File"; break; default: break; } } GtkWidget* window = gtk_widget_get_ancestor( GTK_WIDGET(GetMainWindowHandle()), GTK_TYPE_WINDOW); GtkWidget* dialog = gtk_file_chooser_dialog_new( title_str.c_str(), GTK_WINDOW(window), action, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, accept_button, GTK_RESPONSE_ACCEPT, NULL); if (mode == FILE_DIALOG_OPEN_MULTIPLE) { gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); } else if (mode == FILE_DIALOG_SAVE) { gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); } if (mode == FILE_DIALOG_SAVE && !base_name.empty()) { gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), base_name.c_str()); } AddFiltersForAcceptTypes(GTK_FILE_CHOOSER(dialog), accept_types, true); bool success = false; if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { if (mode == FILE_DIALOG_OPEN || mode == FILE_DIALOG_SAVE) { char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); files.push_back(std::string(filename)); success = true; } else if (mode == FILE_DIALOG_OPEN_MULTIPLE) { GSList* filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); if (filenames) { for (GSList* iter = filenames; iter != NULL; iter = g_slist_next(iter)) { std::string path(static_cast<char*>(iter->data)); g_free(iter->data); files.push_back(path); } g_slist_free(filenames); success = true; } } } gtk_widget_destroy(dialog); if (success) callback->Continue(files); else callback->Cancel(); return true; }
void WebRendererSchemeHandler::ProcessRequestInternal(CefRefPtr<CefRequest> p_Request, CefRefPtr<CefCallback> p_Callback) { boost::lock_guard<WebRendererSchemeHandler> s_Guard(*this); CefRequest::HeaderMap s_Headers; p_Request->GetHeaderMap(s_Headers); WriteLog("Processing request: %s", p_Request->GetURL().ToString().c_str()); //Logger(Util::LogLevel::Debug, "Headers:"); //for (auto it = s_Headers.begin(); it != s_Headers.end(); ++it) // Logger(Util::LogLevel::Debug, "%ls => %ls", it->first.c_str(), it->second.c_str()); // HACK: Replace spaces in the URL with %20 (this is the most common reason for a URI to be invalid) auto s_Url = p_Request->GetURL().ToString(); boost::replace_all(s_Url, " ", "%20"); // [scheme:][//authority][path][?query][#fragment] boost::network::uri::uri s_RequestURI(s_Url); if (!s_RequestURI.is_valid()) { p_Callback->Cancel(); return; } if (s_RequestURI.scheme() != m_Scheme) { p_Callback->Cancel(); return; } auto s_FinalPath = boost::network::uri::decoded(s_RequestURI.path()); if (s_FinalPath.size() == 0) s_FinalPath = "/"; if (s_FinalPath.substr(s_FinalPath.size() - 1) == "/") s_FinalPath += "index.html"; auto s_Host = s_RequestURI.host(); // Deny access to the internal pages from other frames? if (m_Scheme == "dew" && s_Host == "ui" && !m_Main) { p_Callback->Cancel(); return; } // Get the filename. boost::filesystem::path s_Path(s_FinalPath); m_TempFileName = s_Path.filename().string(); auto s_VFSPath = str(boost::format("/%s/%s/%s") % m_Scheme % s_RequestURI.host() % s_FinalPath.substr(1)); m_TempData.clear(); m_TempFileName.clear(); m_RequestedRange.clear(); m_ContentType = "application/octet-stream"; m_RequestedLength = 0; m_Offset = 0; m_Partial = false; m_ShouldCache = false; bool s_Result; m_CachedDataMutex.lock(); // Do we have the data the user is requesting in our cache? auto s_FirstIterator = m_CachedData.find(m_Frame->GetIdentifier()); if (s_FirstIterator == m_CachedData.end()) { s_Result = ReadLocalFile(s_Host, s_FinalPath, m_TempData); } else { auto s_DataIterator = s_FirstIterator->second.find(s_VFSPath); if (s_DataIterator == s_FirstIterator->second.end()) { s_Result = ReadLocalFile(s_Host, s_FinalPath, m_TempData); } else { m_TempData = s_DataIterator->second; s_Result = true; } } m_CachedDataMutex.unlock(); m_RequestedLength = m_TempData.size(); // Is this a partial request? auto s_RangeIt = s_Headers.find("Range"); if (s_Result && s_RangeIt != s_Headers.end()) { // Parse the range info. std::string s_Range = s_RangeIt->second.ToString(); auto s_Sep = s_Range.find("="); if (s_Sep != std::string::npos) { s_Range = s_Range.substr(s_Sep + 1); std::vector<std::string> s_Ranges; boost::split(s_Ranges, s_Range, boost::is_any_of(",")); // We only handle the first requested range for now. // TODO: Change that? m_RequestedRange = s_Ranges[0]; s_Ranges.clear(); boost::split(s_Ranges, m_RequestedRange, boost::is_any_of("-")); if (s_Ranges.size() == 2) { size_t s_Start = s_Ranges[0].size() == 0 ? 0 : boost::lexical_cast<size_t>(s_Ranges[0]); size_t s_End = s_Ranges[1].size() == 0 ? 0 : boost::lexical_cast<size_t>(s_Ranges[1]); if (s_Ranges[0].size() == 0) { s_Start = m_TempData.size() - s_End; s_End = m_TempData.size() - 1; } else if (s_Ranges[1].size() == 0) { s_End = m_TempData.size() - 1; } if (s_End > m_TempData.size() - 1) s_End = m_TempData.size() - 1; if (s_Start > 0 && s_Start <= s_End) { m_Partial = true; m_Offset = s_Start; m_RequestedLength = (s_End - s_Start) + 1; } } } } if (s_Result) { // Set the content type auto s_Extension = s_Path.has_extension() ? s_Path.extension().string() : ""; boost::to_lower(s_Extension); // TODO: Determine mimetype based on the first few bytes of the file, // and fall back to the extension-based method if that fails. if (s_Extension != "" && s_Extension != ".") { if (s_Extension == ".html" || s_Extension == ".htm") m_ContentType = "text/html"; if (s_Extension == ".png") { m_ShouldCache = true; m_ContentType = "image/png"; } if (s_Extension == ".jpg" || s_Extension == ".jpeg" || s_Extension == ".jpe") { m_ShouldCache = true; m_ContentType = "image/jpeg"; } if (s_Extension == ".gif") { m_ShouldCache = true; m_ContentType = "image/gif"; } if (s_Extension == ".bmp") { m_ShouldCache = true; m_ContentType = "image/bmp"; } if (s_Extension == ".ico") { m_ShouldCache = true; m_ContentType = "image/x-icon"; } if (s_Extension == ".css" || s_Extension == ".scss" || s_Extension == ".sass" || s_Extension == ".less") m_ContentType = "text/css"; if (s_Extension == ".js") m_ContentType = "application/javascript"; if (s_Extension == ".txt" || s_Extension == ".obj") m_ContentType = "text/plain"; if (s_Extension == ".svg") { m_ShouldCache = true; m_ContentType = "image/svg+xml"; } if (s_Extension == ".ttf" || s_Extension == ".otf") { m_ShouldCache = true; m_ContentType = "application/font-sfnt"; } if (s_Extension == ".woff") { m_ShouldCache = true; m_ContentType = "application/x-font-woff"; } if (s_Extension == ".ogv") { m_ShouldCache = true; m_ContentType = "video/ogg"; } if (s_Extension == ".ogg") { m_ShouldCache = true; m_ContentType = "audio/ogg"; } } if (m_ShouldCache) { m_CachedDataMutex.lock(); // Cache our data. auto s_Iterator = m_CachedData.find(m_Frame->GetIdentifier()); if (s_Iterator == m_CachedData.end()) m_CachedData[m_Frame->GetIdentifier()] = std::unordered_map<std::string, std::string>(); m_CachedData[m_Frame->GetIdentifier()][s_VFSPath] = m_TempData; m_CachedDataMutex.unlock(); } } if (s_Result) p_Callback->Continue(); else p_Callback->Cancel(); }