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");
}
예제 #6
0
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;
}
예제 #7
0
// 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;
}
예제 #8
0
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();
}