Add project

This commit is contained in:
Diamond Creeper 2023-02-20 23:24:10 +13:00
commit 7fcb279842
961 changed files with 370491 additions and 0 deletions

View file

@ -0,0 +1,30 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
using namespace CefSharp;
[assembly:AssemblyTitle("CefSharp.Core.Runtime")];
[assembly:AssemblyDescription("CefSharp Core Runtime Library (VC++)")];
[assembly:AssemblyCompany(AssemblyInfo::AssemblyCompany)];
[assembly:AssemblyProduct(AssemblyInfo::AssemblyProduct)];
[assembly:AssemblyCopyright(AssemblyInfo::AssemblyCopyright)];
[assembly:AssemblyVersion(AssemblyInfo::AssemblyVersion)];
[assembly:ComVisible(AssemblyInfo::ComVisible)];
[assembly:CLSCompliant(AssemblyInfo::ClsCompliant)];
[assembly:AssemblyConfiguration("")];
[assembly:AssemblyTrademark("")];
[assembly:AssemblyCulture("")];
[assembly:InternalsVisibleTo(AssemblyInfo::CefSharpBrowserSubprocessCoreProject)];
[assembly:InternalsVisibleTo(AssemblyInfo::CefSharpBrowserSubprocessProject)];
[assembly:InternalsVisibleTo(AssemblyInfo::CefSharpTestProject)];

View file

@ -0,0 +1,418 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\internal\cef_types_wrappers.h"
namespace CefSharp
{
namespace Core
{
/// <summary>
/// Browser initialization settings. Specify NULL or 0 to get the recommended
/// default values. The consequences of using custom values may not be well
/// tested. Many of these and other settings can also configured using command-
/// line switches.
/// </summary>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class BrowserSettings : IBrowserSettings
{
private:
bool _isDisposed = false;
bool _ownsPointer = false;
bool _autoDispose = false;
internal:
CefBrowserSettings* _browserSettings;
/// <summary>
/// Internal Constructor
/// </summary>
BrowserSettings(CefBrowserSettings* browserSettings)
{
_browserSettings = browserSettings;
}
public:
/// <summary>
/// Default Constructor
/// </summary>
BrowserSettings() : _browserSettings(new CefBrowserSettings())
{
_ownsPointer = true;
}
BrowserSettings(bool autoDispose) : _browserSettings(new CefBrowserSettings())
{
_ownsPointer = true;
_autoDispose = autoDispose;
}
/// <summary>
/// Finalizer.
/// </summary>
!BrowserSettings()
{
if (_ownsPointer)
{
delete _browserSettings;
}
_browserSettings = NULL;
_isDisposed = true;
}
/// <summary>
/// Destructor.
/// </summary>
~BrowserSettings()
{
this->!BrowserSettings();
}
/// <summary>
/// StandardFontFamily
/// </summary>
virtual property String^ StandardFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->standard_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->standard_font_family, value); }
}
/// <summary>
/// FixedFontFamily
/// </summary>
virtual property String^ FixedFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->fixed_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->fixed_font_family, value); }
}
/// <summary>
/// SerifFontFamily
/// </summary>
virtual property String^ SerifFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->serif_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->serif_font_family, value); }
}
/// <summary>
/// SansSerifFontFamily
/// </summary>
virtual property String^ SansSerifFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->sans_serif_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->sans_serif_font_family, value); }
}
/// <summary>
/// CursiveFontFamily
/// </summary>
virtual property String^ CursiveFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->cursive_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->cursive_font_family, value); }
}
/// <summary>
/// FantasyFontFamily
/// </summary>
virtual property String^ FantasyFontFamily
{
String^ get() { return StringUtils::ToClr(_browserSettings->fantasy_font_family); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->fantasy_font_family, value); }
}
/// <summary>
/// DefaultFontSize
/// </summary>
virtual property int DefaultFontSize
{
int get() { return _browserSettings->default_font_size; }
void set(int value) { _browserSettings->default_font_size = value; }
}
/// <summary>
/// DefaultFixedFontSize
/// </summary>
virtual property int DefaultFixedFontSize
{
int get() { return _browserSettings->default_fixed_font_size; }
void set(int value) { _browserSettings->default_fixed_font_size = value; }
}
/// <summary>
/// MinimumFontSize
/// </summary>
virtual property int MinimumFontSize
{
int get() { return _browserSettings->minimum_font_size; }
void set(int value) { _browserSettings->minimum_font_size = value; }
}
/// <summary>
/// MinimumLogicalFontSize
/// </summary>
virtual property int MinimumLogicalFontSize
{
int get() { return _browserSettings->minimum_logical_font_size; }
void set(int value) { _browserSettings->minimum_logical_font_size = value; }
}
/// <summary>
/// Default encoding for Web content. If empty "ISO-8859-1" will be used. Also
/// configurable using the "default-encoding" command-line switch.
/// </summary>
virtual property String^ DefaultEncoding
{
String^ get() { return StringUtils::ToClr(_browserSettings->default_encoding); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->default_encoding, value); }
}
/// <summary>
/// Controls the loading of fonts from remote sources. Also configurable using
/// the "disable-remote-fonts" command-line switch.
/// </summary>
virtual property CefState RemoteFonts
{
CefState get() { return (CefState)_browserSettings->remote_fonts; }
void set(CefState value) { _browserSettings->remote_fonts = (cef_state_t)value; }
}
/// <summary>
/// Controls whether JavaScript can be executed. (Used to Enable/Disable javascript)
/// Also configurable using the "disable-javascript" command-line switch.
/// </summary>
virtual property CefState Javascript
{
CefState get() { return (CefState)_browserSettings->javascript; }
void set(CefState value) { _browserSettings->javascript = (cef_state_t)value; }
}
/// <summary>
/// Controls whether JavaScript can be used to close windows that were not
/// opened via JavaScript. JavaScript can still be used to close windows that
/// were opened via JavaScript. Also configurable using the
/// "disable-javascript-close-windows" command-line switch.
/// </summary>
virtual property CefState JavascriptCloseWindows
{
CefState get() { return (CefState)_browserSettings->javascript_close_windows; }
void set(CefState value) { _browserSettings->javascript_close_windows = (cef_state_t)value; }
}
/// <summary>
/// Controls whether JavaScript can access the clipboard. Also configurable
/// using the "disable-javascript-access-clipboard" command-line switch.
/// </summary>
virtual property CefState JavascriptAccessClipboard
{
CefState get() { return (CefState)_browserSettings->javascript_access_clipboard; }
void set(CefState value) { _browserSettings->javascript_access_clipboard = (cef_state_t)value; }
}
/// <summary>
/// Controls whether DOM pasting is supported in the editor via
/// execCommand("paste"). The |javascript_access_clipboard| setting must also
/// be enabled. Also configurable using the "disable-javascript-dom-paste"
/// command-line switch.
/// </summary>
virtual property CefState JavascriptDomPaste
{
CefState get() { return (CefState)_browserSettings->javascript_dom_paste; }
void set(CefState value) { _browserSettings->javascript_dom_paste = (cef_state_t)value; }
}
/// <summary>
/// Controls whether any plugins will be loaded. Also configurable using the
/// "disable-plugins" command-line switch.
/// </summary>
virtual property CefState Plugins
{
CefState get() { return (CefState)_browserSettings->plugins; }
void set(CefState value) { _browserSettings->plugins = (cef_state_t)value; }
}
/// <summary>
/// Controls whether file URLs will have access to all URLs. Also configurable
/// using the "allow-universal-access-from-files" command-line switch.
/// </summary>
virtual property CefState UniversalAccessFromFileUrls
{
CefState get() { return (CefState)_browserSettings->universal_access_from_file_urls; }
void set(CefState value) { _browserSettings->universal_access_from_file_urls = (cef_state_t)value; }
}
/// <summary>
/// Controls whether file URLs will have access to other file URLs. Also
/// configurable using the "allow-access-from-files" command-line switch.
/// </summary>
virtual property CefState FileAccessFromFileUrls
{
CefState get() { return (CefState)_browserSettings->file_access_from_file_urls; }
void set(CefState value) { _browserSettings->file_access_from_file_urls = (cef_state_t)value; }
}
/// <summary>
/// Controls whether web security restrictions (same-origin policy) will be
/// enforced. Disabling this setting is not recommend as it will allow risky
/// security behavior such as cross-site scripting (XSS). Also configurable
/// using the "disable-web-security" command-line switch.
/// </summary>
virtual property CefState WebSecurity
{
CefState get() { return (CefState)_browserSettings->web_security; }
void set(CefState value) { _browserSettings->web_security = (cef_state_t)value; }
}
/// <summary>
/// Controls whether image URLs will be loaded from the network. A cached image
/// will still be rendered if requested. Also configurable using the
/// "disable-image-loading" command-line switch.
/// </summary>
virtual property CefState ImageLoading
{
CefState get() { return (CefState)_browserSettings->image_loading; }
void set(CefState value) { _browserSettings->image_loading = (cef_state_t)value; }
}
/// <summary>
/// Controls whether standalone images will be shrunk to fit the page. Also
/// configurable using the "image-shrink-standalone-to-fit" command-line
/// switch.
/// </summary>
virtual property CefState ImageShrinkStandaloneToFit
{
CefState get() { return (CefState)_browserSettings->image_shrink_standalone_to_fit; }
void set(CefState value) { _browserSettings->image_shrink_standalone_to_fit = (cef_state_t)value; }
}
/// <summary>
/// Controls whether text areas can be resized. Also configurable using the
/// "disable-text-area-resize" command-line switch.
/// </summary>
virtual property CefState TextAreaResize
{
CefState get() { return (CefState)_browserSettings->text_area_resize; }
void set(CefState value) { _browserSettings->text_area_resize = (cef_state_t)value; }
}
/// <summary>
/// Controls whether the tab key can advance focus to links. Also configurable
/// using the "disable-tab-to-links" command-line switch.
/// </summary>
virtual property CefState TabToLinks
{
CefState get() { return (CefState)_browserSettings->tab_to_links; }
void set(CefState value) { _browserSettings->tab_to_links = (cef_state_t)value; }
}
/// <summary>
/// Controls whether local storage can be used. Also configurable using the
/// "disable-local-storage" command-line switch.
/// </summary>
virtual property CefState LocalStorage
{
CefState get() { return (CefState)_browserSettings->local_storage; }
void set(CefState value) { _browserSettings->local_storage = (cef_state_t)value; }
}
/// <summary>
/// Controls whether databases can be used. Also configurable using the
/// "disable-databases" command-line switch.
/// </summary>
virtual property CefState Databases
{
CefState get() { return (CefState)_browserSettings->databases; }
void set(CefState value) { _browserSettings->databases = (cef_state_t)value; }
}
/// <summary>
/// Controls whether the application cache can be used. Also configurable using
/// the "disable-application-cache" command-line switch.
/// </summary>
virtual property CefState ApplicationCache
{
CefState get() { return (CefState)_browserSettings->application_cache; }
void set(CefState value) { _browserSettings->application_cache = (cef_state_t)value; }
}
/// <summary>
/// Controls whether WebGL can be used. Note that WebGL requires hardware
/// support and may not work on all systems even when enabled. Also
/// configurable using the "disable-webgl" command-line switch.
/// </summary>
virtual property CefState WebGl
{
CefState get() { return (CefState)_browserSettings->webgl; }
void set(CefState value) { _browserSettings->webgl = (cef_state_t)value; }
}
/// <summary>
/// Background color used for the browser before a document is loaded and when no document color
/// is specified. The alpha component must be either fully opaque (0xFF) or fully transparent (0x00).
/// If the alpha component is fully opaque then the RGB components will be used as the background
/// color. If the alpha component is fully transparent for a WinForms browser then the
/// CefSettings.BackgroundColor value will be used. If the alpha component is fully transparent
/// for a windowless (WPF/OffScreen) browser then transparent painting will be enabled.
/// </summary>
virtual property uint32 BackgroundColor
{
uint32 get() { return _browserSettings->background_color; }
void set(uint32 value) { _browserSettings->background_color = value; }
}
/// <summary>
/// Comma delimited ordered list of language codes without any whitespace that
/// will be used in the "Accept-Language" HTTP header. May be overridden on a
/// per-browser basis using the CefBrowserSettings.AcceptLanguageList value.
/// If both values are empty then "en-US,en" will be used. Can be overridden
/// for individual RequestContext instances via the
/// RequestContextSettings.AcceptLanguageList value.
/// </summary>
virtual property String^ AcceptLanguageList
{
String^ get() { return StringUtils::ToClr(_browserSettings->accept_language_list); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_browserSettings->accept_language_list, value); }
}
/// <summary>
/// The maximum rate in frames per second (fps) that CefRenderHandler::OnPaint
/// will be called for a windowless browser. The actual fps may be lower if
/// the browser cannot generate frames at the requested rate. The minimum
/// value is 1 and the maximum value is 60 (default 30). This value can also be
/// changed dynamically via IBrowserHost.SetWindowlessFrameRate.
/// </summary>
virtual property int WindowlessFrameRate
{
int get() { return _browserSettings->windowless_frame_rate; }
void set(int value) { _browserSettings->windowless_frame_rate = value; }
}
/// <summary>
/// Gets a value indicating if the browser settings has been disposed.
/// </summary>
virtual property bool IsDisposed
{
bool get() { return _isDisposed; }
}
/// <summary>
/// True if dispose should be called after this object is used
/// </summary>
virtual property bool AutoDispose
{
bool get() { return _autoDispose; }
}
virtual IBrowserSettings^ UnWrap()
{
return this;
}
};
}
}

View file

@ -0,0 +1,916 @@
// Copyright © 2013 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEFSHARP_CORE_CEF_H_
#define CEFSHARP_CORE_CEF_H_
#pragma once
#include "Stdafx.h"
#include <msclr/lock.h>
#include <msclr/marshal.h>
#include <include/cef_version.h>
#include <include/cef_origin_whitelist.h>
#include <include/cef_web_plugin.h>
#include <include/cef_crash_util.h>
#include <include/cef_parser.h>
#include <include/internal/cef_types.h>
#include "Internals/CefSharpApp.h"
#include "Internals/CefWebPluginInfoVisitorAdapter.h"
#include "Internals/CefTaskScheduler.h"
#include "Internals/CefRegisterCdmCallbackAdapter.h"
#include "CookieManager.h"
#include "CefSettingsBase.h"
#include "RequestContext.h"
using namespace System::Collections::Generic;
using namespace System::Linq;
using namespace System::Reflection;
using namespace msclr::interop;
namespace CefSharp
{
namespace Core
{
/// <summary>
/// Global CEF methods are exposed through this class. e.g. CefInitalize maps to Cef.Initialize
/// CEF API Doc https://magpcss.org/ceforum/apidocs3/projects/(default)/(_globals).html
/// This class cannot be inherited.
/// </summary>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class Cef sealed
{
private:
static Object^ _sync;
static bool _initialized = false;
static HashSet<IDisposable^>^ _disposables;
static int _initializedThreadId;
static bool _multiThreadedMessageLoop = true;
static bool _waitForBrowsersToCloseEnabled = false;
static Cef()
{
_sync = gcnew Object();
_disposables = gcnew HashSet<IDisposable^>();
}
static bool CurrentOnUiThread()
{
return CefCurrentlyOn(CefThreadId::TID_UI);
}
public:
static property TaskFactory^ UIThreadTaskFactory;
static property TaskFactory^ IOThreadTaskFactory;
static property TaskFactory^ FileThreadTaskFactory;
static void AddDisposable(IDisposable^ item)
{
msclr::lock l(_sync);
_disposables->Add(item);
}
static void RemoveDisposable(IDisposable^ item)
{
msclr::lock l(_sync);
_disposables->Remove(item);
}
/// <summary>Gets a value that indicates whether CefSharp is initialized.</summary>
/// <value>true if CefSharp is initialized; otherwise, false.</value>
static property bool IsInitialized
{
bool get()
{
return _initialized;
}
private:
void set(bool value)
{
_initialized = value;
}
}
/// <summary>Gets a value that indicates the version of CefSharp currently being used.</summary>
/// <value>The CefSharp version.</value>
static property String^ CefSharpVersion
{
String^ get()
{
Assembly^ assembly = Assembly::GetAssembly(Cef::typeid);
return assembly->GetName()->Version->ToString();
}
}
/// <summary>Gets a value that indicates the CEF version currently being used.</summary>
/// <value>The CEF Version</value>
static property String^ CefVersion
{
String^ get()
{
return String::Format("r{0}", CEF_VERSION);
}
}
/// <summary>Gets a value that indicates the Chromium version currently being used.</summary>
/// <value>The Chromium version.</value>
static property String^ ChromiumVersion
{
String^ get()
{
// Need explicit cast here to avoid C4965 warning when the minor version is zero.
return String::Format("{0}.{1}.{2}.{3}",
CHROME_VERSION_MAJOR, (Object^)CHROME_VERSION_MINOR,
CHROME_VERSION_BUILD, CHROME_VERSION_PATCH);
}
}
/// <summary>
/// Gets a value that indicates the Git Hash for CEF version currently being used.
/// </summary>
/// <value>The Git Commit Hash</value>
static property String^ CefCommitHash
{
String^ get()
{
return CEF_COMMIT_HASH;
}
}
/// <summary>
/// Initializes CefSharp with user-provided settings.
/// It's important to note that Initialize and Shutdown <strong>MUST</strong> be called on your main
/// application thread (typically the UI thread). If you call them on different
/// threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
/// </summary>
/// <param name="cefSettings">CefSharp configuration settings.</param>
/// <returns>true if successful; otherwise, false.</returns>
static bool Initialize(CefSettingsBase^ cefSettings)
{
auto cefApp = gcnew DefaultApp(nullptr, cefSettings->CefCustomSchemes);
return Initialize(cefSettings, false, cefApp);
}
/// <summary>
/// Initializes CefSharp with user-provided settings.
/// It's important to note that Initialize/Shutdown <strong>MUST</strong> be called on your main
/// application thread (typically the UI thread). If you call them on different
/// threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
/// </summary>
/// <param name="cefSettings">CefSharp configuration settings.</param>
/// <param name="performDependencyCheck">Check that all relevant dependencies avaliable, throws exception if any are missing</param>
/// <returns>true if successful; otherwise, false.</returns>
static bool Initialize(CefSettingsBase^ cefSettings, bool performDependencyCheck)
{
auto cefApp = gcnew DefaultApp(nullptr, cefSettings->CefCustomSchemes);
return Initialize(cefSettings, performDependencyCheck, cefApp);
}
/// <summary>
/// Initializes CefSharp with user-provided settings.
/// It's important to note that Initialize/Shutdown <strong>MUST</strong> be called on your main
/// applicaiton thread (Typically the UI thead). If you call them on different
/// threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
/// </summary>
/// <param name="cefSettings">CefSharp configuration settings.</param>
/// <param name="performDependencyCheck">Check that all relevant dependencies avaliable, throws exception if any are missing</param>
/// <param name="browserProcessHandler">The handler for functionality specific to the browser process. Null if you don't wish to handle these events</param>
/// <returns>true if successful; otherwise, false.</returns>
static bool Initialize(CefSettingsBase^ cefSettings, bool performDependencyCheck, IBrowserProcessHandler^ browserProcessHandler)
{
auto cefApp = gcnew DefaultApp(browserProcessHandler, cefSettings->CefCustomSchemes);
return Initialize(cefSettings, performDependencyCheck, cefApp);
}
/// <summary>
/// Initializes CefSharp with user-provided settings.
/// It's important to note that Initialize/Shutdown <strong>MUST</strong> be called on your main
/// application thread (typically the UI thread). If you call them on different
/// threads, your application will hang. See the documentation for Cef.Shutdown() for more details.
/// </summary>
/// <param name="cefSettings">CefSharp configuration settings.</param>
/// <param name="performDependencyCheck">Check that all relevant dependencies avaliable, throws exception if any are missing</param>
/// <param name="cefApp">Implement this interface to provide handler implementations. Null if you don't wish to handle these events</param>
/// <returns>true if successful; otherwise, false.</returns>
static bool Initialize(CefSettingsBase^ cefSettings, bool performDependencyCheck, IApp^ cefApp)
{
if (IsInitialized)
{
// NOTE: Can only initialize Cef once, to make this explicitly clear throw exception on subsiquent attempts
throw gcnew Exception("CEF can only be initialized once per process. This is a limitation of the underlying " +
"CEF/Chromium framework. You can change many (not all) settings at runtime through RequestContext.SetPreference. " +
"See https://github.com/cefsharp/CefSharp/wiki/General-Usage#request-context-browser-isolation " +
"Use Cef.IsInitialized to guard against this exception. If you are seeing this unexpectedly then you are likely " +
"calling Cef.Initialize after you've created an instance of ChromiumWebBrowser, it must be before the first instance is created.");
}
//Empty string is acceptable, the main application executable will be used
if (cefSettings->BrowserSubprocessPath == nullptr)
{
throw gcnew Exception("CefSettings BrowserSubprocessPath cannot be null.");
}
PathCheck::AssertAbsolute(cefSettings->RootCachePath, "CefSettings.RootCachePath");
PathCheck::AssertAbsolute(cefSettings->CachePath, "CefSettings.CachePath");
PathCheck::AssertAbsolute(cefSettings->LocalesDirPath, "CefSettings.LocalesDirPath");
PathCheck::AssertAbsolute(cefSettings->BrowserSubprocessPath, "CefSettings.BrowserSubprocessPath");
if (performDependencyCheck)
{
DependencyChecker::AssertAllDependenciesPresent(cefSettings->Locale, cefSettings->LocalesDirPath, cefSettings->ResourcesDirPath, cefSettings->PackLoadingDisabled, cefSettings->BrowserSubprocessPath);
}
else if (!File::Exists(cefSettings->BrowserSubprocessPath))
{
throw gcnew FileNotFoundException("CefSettings.BrowserSubprocessPath not found.", cefSettings->BrowserSubprocessPath);
}
UIThreadTaskFactory = gcnew TaskFactory(gcnew CefTaskScheduler(TID_UI));
IOThreadTaskFactory = gcnew TaskFactory(gcnew CefTaskScheduler(TID_IO));
FileThreadTaskFactory = gcnew TaskFactory(gcnew CefTaskScheduler(TID_FILE));
//Allows us to execute Tasks on the CEF UI thread in CefSharp.dll
CefThread::Initialize(UIThreadTaskFactory, gcnew Func<bool>(&CurrentOnUiThread));
//To allow FolderSchemeHandlerFactory to access GetMimeType we pass in a Func
CefSharp::SchemeHandler::FolderSchemeHandlerFactory::GetMimeTypeDelegate = gcnew Func<String^, String^>(&GetMimeType);
CefRefPtr<CefSharpApp> app(new CefSharpApp(cefSettings->ExternalMessagePump,
cefSettings->CommandLineArgsDisabled,
cefSettings->CefCommandLineArgs,
cefSettings->CefCustomSchemes,
cefApp));
CefMainArgs main_args;
auto success = CefInitialize(main_args, *(cefSettings->_cefSettings), app.get(), NULL);
_initialized = success;
_multiThreadedMessageLoop = cefSettings->MultiThreadedMessageLoop;
_initializedThreadId = Thread::CurrentThread->ManagedThreadId;
return success;
}
/// <summary>
/// Run the CEF message loop. Use this function instead of an application-
/// provided message loop to get the best balance between performance and CPU
/// usage. This function should only be called on the main application thread and
/// only if Cef.Initialize() is called with a
/// CefSettings.MultiThreadedMessageLoop value of false. This function will
/// block until a quit message is received by the system.
/// </summary>
static void RunMessageLoop()
{
CefRunMessageLoop();
}
/// <summary>
/// Quit the CEF message loop that was started by calling Cef.RunMessageLoop().
/// This function should only be called on the main application thread and only
/// if Cef.RunMessageLoop() was used.
/// </summary>
static void QuitMessageLoop()
{
CefQuitMessageLoop();
}
/// <summary>
/// Perform a single iteration of CEF message loop processing.This function is
/// provided for cases where the CEF message loop must be integrated into an
/// existing application message loop. Use of this function is not recommended
/// for most users; use CefSettings.MultiThreadedMessageLoop if possible (the default).
/// When using this function care must be taken to balance performance
/// against excessive CPU usage. It is recommended to enable the
/// CefSettings.ExternalMessagePump option when using
/// this function so that IBrowserProcessHandler.OnScheduleMessagePumpWork()
/// callbacks can facilitate the scheduling process. This function should only be
/// called on the main application thread and only if Cef.Initialize() is called
/// with a CefSettings.MultiThreadedMessageLoop value of false. This function
/// will not block.
/// </summary>
static void DoMessageLoopWork()
{
CefDoMessageLoopWork();
}
/// <summary>
/// This function should be called from the application entry point function to execute a secondary process.
/// It can be used to run secondary processes from the browser client executable (default behavior) or
/// from a separate executable specified by the CefSettings.browser_subprocess_path value.
/// If called for the browser process (identified by no "type" command-line value) it will return immediately with a value of -1.
/// If called for a recognized secondary process it will block until the process should exit and then return the process exit code.
/// The |application| parameter may be empty. The |windows_sandbox_info| parameter is only used on Windows and may be NULL (see cef_sandbox_win.h for details).
/// </summary>
static int ExecuteProcess()
{
auto hInstance = Process::GetCurrentProcess()->Handle;
CefMainArgs cefMainArgs((HINSTANCE)hInstance.ToPointer());
//TODO: Look at ways to expose an instance of CefApp
//CefRefPtr<CefSharpApp> app(new CefSharpApp(nullptr, nullptr));
return CefExecuteProcess(cefMainArgs, NULL, NULL);
}
/// <summary>Add an entry to the cross-origin whitelist.</summary>
/// <param name="sourceOrigin">The origin allowed to be accessed by the target protocol/domain.</param>
/// <param name="targetProtocol">The target protocol allowed to access the source origin.</param>
/// <param name="targetDomain">The optional target domain allowed to access the source origin.</param>
/// <param name="allowTargetSubdomains">If set to true would allow a blah.example.com if the
/// <paramref name="targetDomain"/> was set to example.com
/// </param>
/// <returns>Returns false if is invalid or the whitelist cannot be accessed.</returns>
/// <remarks>
/// The same-origin policy restricts how scripts hosted from different origins
/// (scheme + domain + port) can communicate. By default, scripts can only access
/// resources with the same origin. Scripts hosted on the HTTP and HTTPS schemes
/// (but no other schemes) can use the "Access-Control-Allow-Origin" header to
/// allow cross-origin requests. For example, https://source.example.com can make
/// XMLHttpRequest requests on http://target.example.com if the
/// http://target.example.com request returns an "Access-Control-Allow-Origin:
/// https://source.example.com" response header.
//
/// Scripts in separate frames or iframes and hosted from the same protocol and
/// domain suffix can execute cross-origin JavaScript if both pages set the
/// document.domain value to the same domain suffix. For example,
/// scheme://foo.example.com and scheme://bar.example.com can communicate using
/// JavaScript if both domains set document.domain="example.com".
//
/// This method is used to allow access to origins that would otherwise violate
/// the same-origin policy. Scripts hosted underneath the fully qualified
/// <paramref name="sourceOrigin"/> URL (like http://www.example.com) will be allowed access to
/// all resources hosted on the specified <paramref name="targetProtocol"/> and <paramref name="targetDomain"/>.
/// If <paramref name="targetDomain"/> is non-empty and <paramref name="allowTargetSubdomains"/> if false only
/// exact domain matches will be allowed. If <paramref name="targetDomain"/> contains a top-
/// level domain component (like "example.com") and <paramref name="allowTargetSubdomains"/> is
/// true sub-domain matches will be allowed. If <paramref name="targetDomain"/> is empty and
/// <paramref name="allowTargetSubdomains"/> if true all domains and IP addresses will be
/// allowed.
//
/// This method cannot be used to bypass the restrictions on local or display
/// isolated schemes. See the comments on <see cref="CefCustomScheme"/> for more
/// information.
///
/// This function may be called on any thread. Returns false if <paramref name="sourceOrigin"/>
/// is invalid or the whitelist cannot be accessed.
/// </remarks>
static bool AddCrossOriginWhitelistEntry(
String^ sourceOrigin,
String^ targetProtocol,
String^ targetDomain,
bool allowTargetSubdomains)
{
return CefAddCrossOriginWhitelistEntry(
StringUtils::ToNative(sourceOrigin),
StringUtils::ToNative(targetProtocol),
StringUtils::ToNative(targetDomain),
allowTargetSubdomains);
}
/// <summary>Remove entry from cross-origin whitelist</summary>
/// <param name="sourceOrigin">The origin allowed to be accessed by the target protocol/domain.</param>
/// <param name="targetProtocol">The target protocol allowed to access the source origin.</param>
/// <param name="targetDomain">The optional target domain allowed to access the source origin.</param>
/// <param name="allowTargetSubdomains">If set to true would allow a blah.example.com if the
/// <paramref name="targetDomain"/> was set to example.com
/// </param>
/// <remarks>
/// Remove an entry from the cross-origin access whitelist. Returns false if
/// <paramref name="sourceOrigin"/> is invalid or the whitelist cannot be accessed.
/// </remarks>
static bool RemoveCrossOriginWhitelistEntry(String^ sourceOrigin,
String^ targetProtocol,
String^ targetDomain,
bool allowTargetSubdomains)
{
return CefRemoveCrossOriginWhitelistEntry(
StringUtils::ToNative(sourceOrigin),
StringUtils::ToNative(targetProtocol),
StringUtils::ToNative(targetDomain),
allowTargetSubdomains);
}
/// <summary>Remove all entries from the cross-origin access whitelist.</summary>
/// <remarks>
/// Remove all entries from the cross-origin access whitelist. Returns false if
/// the whitelist cannot be accessed.
/// </remarks>
static bool ClearCrossOriginWhitelist()
{
return CefClearCrossOriginWhitelist();
}
/// <summary>
/// Returns the global cookie manager. By default data will be stored at CefSettings.CachePath if specified or in memory otherwise.
/// Using this method is equivalent to calling Cef.GetGlobalRequestContext().GetCookieManager()
/// The cookie managers storage is created in an async fashion, whilst this method may return a cookie manager instance,
/// there may be a short delay before you can Get/Write cookies.
/// To be sure the cookie manager has been initialized use one of the following
/// - Use the GetGlobalCookieManager(ICompletionCallback) overload and access the ICookieManager after
/// ICompletionCallback.OnComplete has been called.
/// - Access the ICookieManager instance in IBrowserProcessHandler.OnContextInitialized.
/// - Use the ChromiumWebBrowser BrowserInitialized (OffScreen) or IsBrowserInitializedChanged (WinForms/WPF) events.
/// </summary>
/// <returns>A the global cookie manager or null if the RequestContext has not yet been initialized.</returns>
static ICookieManager^ GetGlobalCookieManager()
{
return GetGlobalCookieManager(nullptr);
}
/// <summary>
/// Returns the global cookie manager. By default data will be stored at CefSettings.CachePath if specified or in memory otherwise.
/// Using this method is equivalent to calling Cef.GetGlobalRequestContext().GetCookieManager()
/// The cookie managers storage is created in an async fashion, whilst this method may return a cookie manager instance,
/// there may be a short delay before you can Get/Write cookies.
/// To be sure the cookie manager has been initialized use one of the following
/// - Access the ICookieManager after ICompletionCallback.OnComplete has been called
/// - Access the ICookieManager instance in IBrowserProcessHandler.OnContextInitialized.
/// - Use the ChromiumWebBrowser BrowserInitialized (OffScreen) or IsBrowserInitializedChanged (WinForms/WPF) events.
/// </summary>
/// <param name="callback">If non-NULL it will be executed asnychronously on the CEF UI thread after the manager's storage has been initialized.</param>
/// <returns>A the global cookie manager or null if the RequestContext has not yet been initialized.</returns>
static ICookieManager^ GetGlobalCookieManager(ICompletionCallback^ callback)
{
CefRefPtr<CefCompletionCallback> c = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
auto cookieManager = CefCookieManager::GetGlobalManager(c);
if (cookieManager.get())
{
return gcnew CookieManager(cookieManager);
}
return nullptr;
}
/// <summary>
/// Called prior to calling Cef.Shutdown, this diposes of any remaning
/// ChromiumWebBrowser instances. In WPF this is used from Dispatcher.ShutdownStarted
/// to release the unmanaged resources held by the ChromiumWebBrowser instances.
/// Generally speaking you don't need to call this yourself.
/// </summary>
static void PreShutdown()
{
msclr::lock l(_sync);
for each(IDisposable^ diposable in Enumerable::ToList(_disposables))
{
delete diposable;
}
_disposables->Clear();
GC::Collect();
GC::WaitForPendingFinalizers();
}
/// <summary>
/// Shuts down CefSharp and the underlying CEF infrastructure. This method is safe to call multiple times; it will only
/// shut down CEF on the first call (all subsequent calls will be ignored).
/// This method should be called on the main application thread to shut down the CEF browser process before the application exits.
/// If you are Using CefSharp.OffScreen then you must call this explicitly before your application exits or it will hang.
/// This method must be called on the same thread as Initialize. If you don't call Shutdown explicitly then CefSharp.Wpf and CefSharp.WinForms
/// versions will do their best to call Shutdown for you, if your application is having trouble closing then call thus explicitly.
/// </summary>
static void Shutdown()
{
if (IsInitialized)
{
msclr::lock l(_sync);
if (IsInitialized)
{
if (_initializedThreadId != Thread::CurrentThread->ManagedThreadId)
{
throw gcnew Exception("Cef.Shutdown must be called on the same thread that Cef.Initialize was called - typically your UI thread. " +
"If you called Cef.Initialize on a Thread other than the UI thread then you will need to call Cef.Shutdown on the same thread. " +
"Cef.Initialize was called on ManagedThreadId: " + _initializedThreadId + "where Cef.Shutdown is being called on " +
"ManagedThreadId: " + Thread::CurrentThread->ManagedThreadId);
}
UIThreadTaskFactory = nullptr;
IOThreadTaskFactory = nullptr;
FileThreadTaskFactory = nullptr;
CefThread::Shutdown();
for each(IDisposable^ diposable in Enumerable::ToList(_disposables))
{
delete diposable;
}
GC::Collect();
GC::WaitForPendingFinalizers();
if (!_multiThreadedMessageLoop)
{
// We need to run the message pump until it is idle. However we don't have
// that information here so we run the message loop "for a while".
// See https://github.com/cztomczak/cefpython/issues/245 for an excellent description
for (int i = 0; i < 10; i++)
{
DoMessageLoopWork();
// Sleep to allow the CEF proc to do work.
Sleep(50);
}
}
CefShutdown();
IsInitialized = false;
}
}
}
/// <summary>
/// This method should only be used by advanced users, if you're unsure then use Cef.Shutdown().
/// This function should be called on the main application thread to shut down
/// the CEF browser process before the application exits. This method simply obtains a lock
/// and calls the native CefShutdown method, only IsInitialized is checked. All ChromiumWebBrowser
/// instances MUST be Disposed of before calling this method. If calling this method results in a crash
/// or hangs then you're likely hanging on to some unmanaged resources or haven't closed all of your browser
/// instances
/// </summary>
static void ShutdownWithoutChecks()
{
if (IsInitialized)
{
msclr::lock l(_sync);
if (IsInitialized)
{
CefShutdown();
IsInitialized = false;
}
}
}
/// <summary>
/// Clear all scheme handler factories registered with the global request context.
/// Returns false on error. This function may be called on any thread in the browser process.
/// Using this function is equivalent to calling Cef.GetGlobalRequestContext().ClearSchemeHandlerFactories().
/// </summary>
/// <returns>Returns false on error.</returns>
static bool ClearSchemeHandlerFactories()
{
return CefClearSchemeHandlerFactories();
}
/// <summary>
/// Visit web plugin information. Can be called on any thread in the browser process.
/// </summary>
static void VisitWebPluginInfo(IWebPluginInfoVisitor^ visitor)
{
CefVisitWebPluginInfo(new CefWebPluginInfoVisitorAdapter(visitor));
}
/// <summary>
/// Async returns a list containing Plugin Information
/// (Wrapper around CefVisitWebPluginInfo)
/// </summary>
/// <returns>Returns List of <see cref="WebPluginInfo"/> structs.</returns>
static Task<List<WebPluginInfo^>^>^ GetPlugins()
{
auto taskVisitor = gcnew TaskWebPluginInfoVisitor();
CefRefPtr<CefWebPluginInfoVisitorAdapter> visitor = new CefWebPluginInfoVisitorAdapter(taskVisitor);
CefVisitWebPluginInfo(visitor);
return taskVisitor->Task;
}
/// <summary>
/// Cause the plugin list to refresh the next time it is accessed regardless of whether it has already been loaded.
/// </summary>
static void RefreshWebPlugins()
{
CefRefreshWebPlugins();
}
/// <summary>
/// Unregister an internal plugin. This may be undone the next time RefreshWebPlugins() is called.
/// </summary>
/// <param name="path">Path (directory + file).</param>
static void UnregisterInternalWebPlugin(String^ path)
{
CefUnregisterInternalWebPlugin(StringUtils::ToNative(path));
}
/// <summary>
/// Call during process startup to enable High-DPI support on Windows 7 or newer.
/// Older versions of Windows should be left DPI-unaware because they do not
/// support DirectWrite and GDI fonts are kerned very badly.
/// </summary>
static void EnableHighDPISupport()
{
CefEnableHighDPISupport();
}
/// <summary>
/// Returns true if called on the specified CEF thread.
/// </summary>
/// <returns>Returns true if called on the specified thread.</returns>
static bool CurrentlyOnThread(CefThreadIds threadId)
{
return CefCurrentlyOn((CefThreadId)threadId);
}
/// <summary>
/// Gets the Global Request Context. Make sure to Dispose of this object when finished.
/// The earlier possible place to access the IRequestContext is in IBrowserProcessHandler.OnContextInitialized.
/// Alternative use the ChromiumWebBrowser BrowserInitialized (OffScreen) or IsBrowserInitializedChanged (WinForms/WPF) events.
/// </summary>
/// <returns>Returns the global request context or null if the RequestContext has not been initialized yet.</returns>
static IRequestContext^ GetGlobalRequestContext()
{
auto context = CefRequestContext::GetGlobalContext();
if (context.get())
{
return gcnew RequestContext(context);
}
return nullptr;
}
/// <summary>
/// Helper function (wrapper around the CefColorSetARGB macro) which combines
/// the 4 color components into an uint32 for use with BackgroundColor property
/// </summary>
/// <param name="a">Alpha</param>
/// <param name="r">Red</param>
/// <param name="g">Green</param>
/// <param name="b">Blue</param>
/// <returns>Returns the color.</returns>
static uint32 ColorSetARGB(uint32 a, uint32 r, uint32 g, uint32 b)
{
return CefColorSetARGB(a, r, g, b);
}
/// <summary>
/// Crash reporting is configured using an INI-style config file named
/// crash_reporter.cfg. This file must be placed next to
/// the main application executable. File contents are as follows:
///
/// # Comments start with a hash character and must be on their own line.
///
/// [Config]
/// ProductName=&lt;Value of the &quot;prod&quot; crash key; defaults to &quot;cef&quot;&gt;
/// ProductVersion=&lt;Value of the &quot;ver&quot; crash key; defaults to the CEF version&gt;
/// AppName=&lt;Windows only; App-specific folder name component for storing crash
/// information; default to &quot;CEF&quot;&gt;
/// ExternalHandler=&lt;Windows only; Name of the external handler exe to use
/// instead of re-launching the main exe; default to empty>
/// ServerURL=&lt;crash server URL; default to empty&gt;
/// RateLimitEnabled=&lt;True if uploads should be rate limited; default to true&gt;
/// MaxUploadsPerDay=&lt;Max uploads per 24 hours, used if rate limit is enabled;
/// default to 5&gt;
/// MaxDatabaseSizeInMb=&lt;Total crash report disk usage greater than this value
/// will cause older reports to be deleted; default to 20&gt;
/// MaxDatabaseAgeInDays=&lt;Crash reports older than this value will be deleted;
/// default to 5&gt;
///
/// [CrashKeys]
/// my_key1=&lt;small|medium|large&gt;
/// my_key2=&lt;small|medium|large&gt;
///
/// Config section:
///
/// If &quot;ProductName&quot; and/or &quot;ProductVersion&quot; are set then the specified values
/// will be included in the crash dump metadata.
///
/// If &quot;AppName&quot; is set on Windows then crash report information (metrics,
/// database and dumps) will be stored locally on disk under the
/// &quot;C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data&quot; folder.
///
/// If &quot;ExternalHandler&quot; is set on Windows then the specified exe will be
/// launched as the crashpad-handler instead of re-launching the main process
/// exe. The value can be an absolute path or a path relative to the main exe
/// directory.
///
/// If &quot;ServerURL&quot; is set then crashes will be uploaded as a multi-part POST
/// request to the specified URL. Otherwise, reports will only be stored locally
/// on disk.
///
/// If &quot;RateLimitEnabled&quot; is set to true then crash report uploads will be rate
/// limited as follows:
/// 1. If &quot;MaxUploadsPerDay&quot; is set to a positive value then at most the
/// specified number of crashes will be uploaded in each 24 hour period.
/// 2. If crash upload fails due to a network or server error then an
/// incremental backoff delay up to a maximum of 24 hours will be applied for
/// retries.
/// 3. If a backoff delay is applied and &quot;MaxUploadsPerDay&quot; is > 1 then the
/// &quot;MaxUploadsPerDay&quot; value will be reduced to 1 until the client is
/// restarted. This helps to avoid an upload flood when the network or
/// server error is resolved.
///
/// If &quot;MaxDatabaseSizeInMb&quot; is set to a positive value then crash report storage
/// on disk will be limited to that size in megabytes. For example, on Windows
/// each dump is about 600KB so a &quot;MaxDatabaseSizeInMb&quot; value of 20 equates to
/// about 34 crash reports stored on disk.
///
/// If &quot;MaxDatabaseAgeInDays&quot; is set to a positive value then crash reports older
/// than the specified age in days will be deleted.
///
/// CrashKeys section:
///
/// Any number of crash keys can be specified for use by the application. Crash
/// key values will be truncated based on the specified size (small = 63 bytes,
/// medium = 252 bytes, large = 1008 bytes). The value of crash keys can be set
/// from any thread or process using the Cef.SetCrashKeyValue function. These
/// key/value pairs will be sent to the crash server along with the crash dump
/// file. Medium and large values will be chunked for submission. For example,
/// if your key is named &quot;mykey&quot; then the value will be broken into ordered
/// chunks and submitted using keys named &quot;mykey-1&quot;, &quot;mykey-2&quot;, etc.
/// </summary>
/// <returns>Returns true if crash reporting is enabled.</returns>
static property bool CrashReportingEnabled
{
bool get()
{
return CefCrashReportingEnabled();
}
}
/// <summary>
/// Sets or clears a specific key-value pair from the crash metadata.
/// </summary>
static void SetCrashKeyValue(String^ key, String^ value)
{
CefSetCrashKeyValue(StringUtils::ToNative(key), StringUtils::ToNative(value));
}
static int GetMinLogLevel()
{
return cef_get_min_log_level();
}
/// <summary>
/// Register the Widevine CDM plugin.
///
/// The client application is responsible for downloading an appropriate
/// platform-specific CDM binary distribution from Google, extracting the
/// contents, and building the required directory structure on the local machine.
/// The <see cref="CefSharp::IBrowserHost::StartDownload"/> method class can be used
/// to implement this functionality in CefSharp. Contact Google via
/// https://www.widevine.com/contact.html for details on CDM download.
///
///
/// path is a directory that must contain the following files:
/// 1. manifest.json file from the CDM binary distribution (see below).
/// 2. widevinecdm file from the CDM binary distribution (e.g.
/// widevinecdm.dll on Windows).
/// 3. widevidecdmadapter file from the CEF binary distribution (e.g.
/// widevinecdmadapter.dll on Windows).
///
/// If any of these files are missing or if the manifest file has incorrect
/// contents the registration will fail and callback will receive an ErrorCode
/// value of <see cref="CefSharp::CdmRegistrationErrorCode::IncorrectContents"/>.
///
/// The manifest.json file must contain the following keys:
/// A. "os": Supported OS (e.g. "mac", "win" or "linux").
/// B. "arch": Supported architecture (e.g. "ia32" or "x64").
/// C. "x-cdm-module-versions": Module API version (e.g. "4").
/// D. "x-cdm-interface-versions": Interface API version (e.g. "8").
/// E. "x-cdm-host-versions": Host API version (e.g. "8").
/// F. "version": CDM version (e.g. "1.4.8.903").
/// G. "x-cdm-codecs": List of supported codecs (e.g. "vp8,vp9.0,avc1").
///
/// A through E are used to verify compatibility with the current Chromium
/// version. If the CDM is not compatible the registration will fail and
/// callback will receive an ErrorCode value of <see cref="CdmRegistrationErrorCode::Incompatible"/>.
///
/// If registration is not supported at the time that Cef.RegisterWidevineCdm() is called then callback
/// will receive an ErrorCode value of <see cref="CdmRegistrationErrorCode::NotSupported"/>.
/// </summary>
/// <param name="path"> is a directory that contains the Widevine CDM files</param>
/// <param name="callback">optional callback - <see cref="IRegisterCdmCallback::OnRegistrationComplete"/>
/// will be executed asynchronously once registration is complete</param>
static void RegisterWidevineCdm(String^ path, [Optional] IRegisterCdmCallback^ callback)
{
CefRefPtr<CefRegisterCdmCallbackAdapter> adapter = NULL;
if (callback != nullptr)
{
adapter = new CefRegisterCdmCallbackAdapter(callback);
}
CefRegisterWidevineCdm(StringUtils::ToNative(path), adapter);
}
/// <summary>
/// Register the Widevine CDM plugin.
///
/// See <see cref="RegisterWidevineCdm(String, IRegisterCdmCallback)"/> for more details.
/// </summary>
/// <param name="path"> is a directory that contains the Widevine CDM files</param>
/// <returns>Returns a Task that can be awaited to receive the <see cref="CdmRegistration"/> response.</returns>
static Task<CdmRegistration^>^ RegisterWidevineCdmAsync(String^ path)
{
auto callback = gcnew TaskRegisterCdmCallback();
RegisterWidevineCdm(path, callback);
return callback->Task;
}
/// <summary>
/// Returns the mime type for the specified file extension or an empty string if unknown.
/// </summary>
/// <param name="extension">file extension</param>
/// <returns>Returns the mime type for the specified file extension or an empty string if unknown.</returns>
static String^ GetMimeType(String^ extension)
{
if (extension == nullptr)
{
throw gcnew ArgumentNullException("extension");
}
if (extension->StartsWith("."))
{
extension = extension->Substring(1, extension->Length - 1);
}
auto mimeType = StringUtils::ToClr(CefGetMimeType(StringUtils::ToNative(extension)));
//Lookup to see if we have a custom mapping
//MimeTypeMapping::GetCustomMapping will Fallback
//to application/octet-stream if no mapping found
if (String::IsNullOrEmpty(mimeType))
{
return MimeTypeMapping::GetCustomMapping(extension);
}
return mimeType;
}
/// <summary>
/// WaitForBrowsersToClose is not enabled by default, call this method
/// before Cef.Initialize to enable. If you aren't calling Cef.Initialize
/// explicitly then this should be called before creating your first
/// ChromiumWebBrowser instance.
/// </summary>
static void EnableWaitForBrowsersToClose()
{
if (_waitForBrowsersToCloseEnabled)
{
return;
}
if (IsInitialized)
{
throw gcnew Exception("Must be enabled before Cef.Initialize is called. ");
}
_waitForBrowsersToCloseEnabled = true;
BrowserRefCounter::Instance = gcnew BrowserRefCounter();
}
/// <summary>
/// Helper method to ensure all ChromiumWebBrowser instances have been
/// closed/disposed, should be called before Cef.Shutdown.
/// Disposes all remaning ChromiumWebBrowser instances
/// then waits for CEF to release it's remaning CefBrowser instances.
/// Finally a small delay of 50ms to allow for CEF to finish it's cleanup.
/// Should only be called when MultiThreadedMessageLoop = true;
/// (Hasn't been tested when when CEF integrates into main message loop).
/// </summary>
static void WaitForBrowsersToClose()
{
if (!_waitForBrowsersToCloseEnabled)
{
throw gcnew Exception("This feature is currently disabled. Call Cef.EnableWaitForBrowsersToClose before calling Cef.Initialize to enable.");
}
//Dispose of any remaining browser instances
for each(IDisposable^ diposable in Enumerable::ToList(_disposables))
{
delete diposable;
}
//Clear the list as we've disposed of them all now.
_disposables->Clear();
//Wait for the browsers to close
BrowserRefCounter::Instance->WaitForBrowsersToClose(500);
//A few extra ms to allow for CEF to finish
Thread::Sleep(50);
}
};
}
}
#endif // CEFSHARP_CORE_CEF_H_

View file

@ -0,0 +1,390 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
using namespace System::Collections::Generic;
using namespace System::IO;
namespace CefSharp
{
namespace Core
{
/// <summary>
/// Initialization settings. Many of these and other settings can also configured using command-line switches.
/// WPF/WinForms/OffScreen each have their own CefSettings implementation that sets
/// relevant settings e.g. OffScreen starts with audio muted.
/// </summary>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class CefSettingsBase sealed
{
private:
/// <summary>
/// Command Line Arguments Dictionary.
/// </summary>
CommandLineArgDictionary^ _cefCommandLineArgs;
internal:
/// <summary>
/// CefSettings unmanaged pointer
/// </summary>
::CefSettings* _cefSettings;
/// <summary>
/// CefCustomScheme collection
/// </summary>
List<CefCustomScheme^>^ _cefCustomSchemes;
public:
/// <summary>
/// Default Constructor.
/// </summary>
CefSettingsBase() : _cefSettings(new ::CefSettings())
{
_cefSettings->multi_threaded_message_loop = true;
_cefSettings->no_sandbox = true;
BrowserSubprocessPath = Path::Combine(Path::GetDirectoryName(CefSettingsBase::typeid->Assembly->Location), "CefSharp.BrowserSubprocess.exe");
_cefCustomSchemes = gcnew List<CefCustomScheme^>();
_cefCommandLineArgs = gcnew CommandLineArgDictionary();
//Disable site isolation trials as this causes problems with frames
//being hosted in different render processes.
//https://github.com/cefsharp/CefSharp/issues/2967
_cefCommandLineArgs->Add("disable-site-isolation-trials");
//Disable Windows Spellchecker as CEF doesn't support yet
//https://bitbucket.org/chromiumembedded/cef/issues/3055/windows-spell-checker-not-working-add
_cefCommandLineArgs->Add("disable-features", "CalculateNativeWinOcclusion,WinUseBrowserSpellChecker");
}
/// <summary>
/// Finalizer.
/// </summary>
!CefSettingsBase()
{
delete _cefSettings;
}
/// <summary>
/// Destructor.
/// </summary>
~CefSettingsBase()
{
this->!CefSettingsBase();
}
/// <summary>
/// Add Customs schemes to this collection.
/// </summary>
property IEnumerable<CefCustomScheme^>^ CefCustomSchemes
{
IEnumerable<CefCustomScheme^>^ get() { return _cefCustomSchemes; }
}
/// <summary>
/// Add custom command line argumens to this collection, they will be added in OnBeforeCommandLineProcessing. The
/// CefSettings.CommandLineArgsDisabled value can be used to start with an empty command-line object. Any values specified in
/// CefSettings that equate to command-line arguments will be set before this method is called.
/// </summary>
property CommandLineArgDictionary^ CefCommandLineArgs
{
CommandLineArgDictionary^ get() { return _cefCommandLineArgs; }
}
/// <summary>
/// Set to true to disable configuration of browser process features using standard CEF and Chromium command-line arguments.
/// Configuration can still be specified using CEF data structures or by adding to CefCommandLineArgs.
/// </summary>
property bool CommandLineArgsDisabled
{
bool get() { return _cefSettings->command_line_args_disabled == 1; }
void set(bool value) { _cefSettings->command_line_args_disabled = value; }
}
/// <summary>
/// Set to true to control browser process main (UI) thread message pump scheduling via the
/// IBrowserProcessHandler.OnScheduleMessagePumpWork callback. This option is recommended for use in combination with the
/// Cef.DoMessageLoopWork() function in cases where the CEF message loop must be integrated into an existing application message
/// loop (see additional comments and warnings on Cef.DoMessageLoopWork). Enabling this option is not recommended for most users;
/// leave this option disabled and use either MultiThreadedMessageLoop (the default) if possible.
/// </summary>
property bool ExternalMessagePump
{
bool get() { return _cefSettings->external_message_pump == 1; }
void set(bool value) { _cefSettings->external_message_pump = value; }
}
/// <summary>
/// Set to true to have the browser process message loop run in a separate thread. If false than the CefDoMessageLoopWork()
/// function must be called from your application message loop. This option is only supported on Windows. The default value is
/// true.
/// </summary>
property bool MultiThreadedMessageLoop
{
bool get() { return _cefSettings->multi_threaded_message_loop == 1; }
void set(bool value) { _cefSettings->multi_threaded_message_loop = value; }
}
/// <summary>
/// The path to a separate executable that will be launched for sub-processes. By default the browser process executable is used.
/// See the comments on Cef.ExecuteProcess() for details. If this value is non-empty then it must be an absolute path.
/// Also configurable using the "browser-subprocess-path" command-line switch.
/// Defaults to using the provided CefSharp.BrowserSubprocess.exe instance
/// </summary>
property String^ BrowserSubprocessPath
{
String^ get() { return StringUtils::ToClr(_cefSettings->browser_subprocess_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->browser_subprocess_path, value); }
}
/// <summary>
/// The location where data for the global browser cache will be stored on disk. In this value is non-empty then it must be
/// an absolute path that is must be either equal to or a child directory of CefSettings.RootCachePath (if RootCachePath is
/// empty it will default to this value). If the value is empty then browsers will be created in "incognito mode" where
/// in-memory caches are used for storage and no data is persisted to disk. HTML5 databases such as localStorage will only
/// persist across sessions if a cache path is specified. Can be overridden for individual RequestContext instances via the
/// RequestContextSettings.CachePath value.
/// </summary>
property String^ CachePath
{
String^ get() { return StringUtils::ToClr(_cefSettings->cache_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->cache_path, value); }
}
/// <summary>
/// The root directory that all CefSettings.CachePath and RequestContextSettings.CachePath values must have in common. If this
/// value is empty and CefSettings.CachePath is non-empty then it will default to the CefSettings.CachePath value.
/// If this value is non-empty then it must be an absolute path. Failure to set this value correctly may result in the sandbox
/// blocking read/write access to the CachePath directory. NOTE: CefSharp does not implement the CHROMIUM SANDBOX. A non-empty
/// RootCachePath can be used in conjuncation with an empty CefSettings.CachePath in instances where you would like browsers
/// attached to the Global RequestContext (the default) created in "incognito mode" and instances created with a custom
/// RequestContext using a disk based cache.
/// </summary>
property String^ RootCachePath
{
String^ get() { return StringUtils::ToClr(_cefSettings->root_cache_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->root_cache_path, value); }
}
/// <summary>
/// The location where user data such as spell checking dictionary files will be stored on disk. If this value is empty then the
/// default user data directory will be used ("Local Settings\Application Data\CEF\User Data" directory under the user
/// profile directory on Windows). If this value is non-empty then it must be an absolute path.
/// </summary>
property String^ UserDataPath
{
String^ get() { return StringUtils::ToClr(_cefSettings->user_data_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->user_data_path, value); }
}
/// <summary>
/// Set to true in order to completely ignore SSL certificate errors. This is NOT recommended.
/// </summary>
property bool IgnoreCertificateErrors
{
bool get() { return _cefSettings->ignore_certificate_errors == 1; }
void set(bool value) { _cefSettings->ignore_certificate_errors = value; }
}
/// <summary>
/// The locale string that will be passed to WebKit. If empty the default locale of "en-US" will be used. Also configurable using
/// the "lang" command-line switch.
/// </summary>
property String^ Locale
{
String^ get() { return StringUtils::ToClr(_cefSettings->locale); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->locale, value); }
}
/// <summary>
/// The fully qualified path for the locales directory. If this value is empty the locales directory must be located in the
/// module directory. If this value is non-empty then it must be an absolute path. Also configurable using the "locales-dir-path"
/// command-line switch.
/// </summary>
property String^ LocalesDirPath
{
String^ get() { return StringUtils::ToClr(_cefSettings->locales_dir_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->locales_dir_path, value); }
}
/// <summary>
/// The fully qualified path for the resources directory. If this value is empty the cef.pak and/or devtools_resources.pak files
/// must be located in the module directory. Also configurable using the "resources-dir-path" command-line switch.
/// </summary>
property String^ ResourcesDirPath
{
String^ get() { return StringUtils::ToClr(_cefSettings->resources_dir_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->resources_dir_path, value); }
}
/// <summary>
/// The directory and file name to use for the debug log. If empty a default log file name and location will be used. On Windows
/// a "debug.log" file will be written in the main executable directory. Also configurable using the"log-file" command- line
/// switch.
/// </summary>
property String^ LogFile
{
String^ get() { return StringUtils::ToClr(_cefSettings->log_file); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->log_file, value); }
}
/// <summary>
/// The log severity. Only messages of this severity level or higher will be logged. When set to
/// <see cref="CefSharp::LogSeverity::Disable"/> no messages will be written to the log file, but Fatal messages will still be
/// output to stderr. Also configurable using the "log-severity" command-line switch with a value of "verbose", "info", "warning",
/// "error", "fatal", "error-report" or "disable".
/// </summary>
property CefSharp::LogSeverity LogSeverity
{
CefSharp::LogSeverity get() { return (CefSharp::LogSeverity)_cefSettings->log_severity; }
void set(CefSharp::LogSeverity value) { _cefSettings->log_severity = (cef_log_severity_t)value; }
}
/// <summary>
/// Custom flags that will be used when initializing the V8 JavaScript engine. The consequences of using custom flags may not be
/// well tested. Also configurable using the "js-flags" command-line switch.
/// </summary>
property String^ JavascriptFlags
{
String^ get() { return StringUtils::ToClr(_cefSettings->javascript_flags); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->javascript_flags, value); }
}
/// <summary>
/// Set to true to disable loading of pack files for resources and locales. A resource bundle handler must be provided for the
/// browser and render processes via CefApp::GetResourceBundleHandler() if loading of pack files is disabled. Also configurable
/// using the "disable-pack-loading" command- line switch.
/// </summary>
property bool PackLoadingDisabled
{
bool get() { return _cefSettings->pack_loading_disabled == 1; }
void set(bool value) { _cefSettings->pack_loading_disabled = value; }
}
/// <summary>
/// Value that will be inserted as the product portion of the default User-Agent string. If empty the Chromium product version
/// will be used. If UserAgent is specified this value will be ignored. Also configurable using the "product-version" command-
/// line switch.
/// </summary>
property String^ ProductVersion
{
String^ get() { return StringUtils::ToClr(_cefSettings->product_version); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->product_version, value); }
}
/// <summary>
/// Set to a value between 1024 and 65535 to enable remote debugging on the specified port. For example, if 8080 is specified the
/// remote debugging URL will be http://localhost:8080. CEF can be remotely debugged from any CEF or Chrome browser window. Also
/// configurable using the "remote-debugging-port" command-line switch.
/// </summary>
property int RemoteDebuggingPort
{
int get() { return _cefSettings->remote_debugging_port; }
void set(int value) { _cefSettings->remote_debugging_port = value; }
}
/// <summary>
/// The number of stack trace frames to capture for uncaught exceptions. Specify a positive value to enable the
/// CefRenderProcessHandler:: OnUncaughtException() callback. Specify 0 (default value) and OnUncaughtException() will not be
/// called. Also configurable using the "uncaught-exception-stack-size" command-line switch.
/// </summary>
property int UncaughtExceptionStackSize
{
int get() { return _cefSettings->uncaught_exception_stack_size; }
void set(int value) { _cefSettings->uncaught_exception_stack_size = value; }
}
/// <summary>
/// Value that will be returned as the User-Agent HTTP header. If empty the default User-Agent string will be used. Also
/// configurable using the "user-agent" command-line switch.
/// </summary>
property String^ UserAgent
{
String^ get() { return StringUtils::ToClr(_cefSettings->user_agent); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->user_agent, value); }
}
/// <summary>
/// Set to true (1) to enable windowless (off-screen) rendering support. Do not enable this value if the application does not use
/// windowless rendering as it may reduce rendering performance on some systems.
/// </summary>
property bool WindowlessRenderingEnabled
{
bool get() { return _cefSettings->windowless_rendering_enabled == 1; }
void set(bool value) { _cefSettings->windowless_rendering_enabled = value; }
}
/// <summary>
/// To persist session cookies (cookies without an expiry date or validity interval) by default when using the global cookie
/// manager set this value to true. Session cookies are generally intended to be transient and most Web browsers do not persist
/// them. A CachePath value must also be specified to enable this feature. Also configurable using the "persist-session-cookies"
/// command-line switch. Can be overridden for individual RequestContext instances via the
/// RequestContextSettings.PersistSessionCookies value.
/// </summary>
property bool PersistSessionCookies
{
bool get() { return _cefSettings->persist_session_cookies == 1; }
void set(bool value) { _cefSettings->persist_session_cookies = value; }
}
/// <summary>
/// To persist user preferences as a JSON file in the cache path directory set this value to true. A CachePath value must also be
/// specified to enable this feature. Also configurable using the "persist-user-preferences" command-line switch. Can be
/// overridden for individual RequestContext instances via the RequestContextSettings.PersistUserPreferences value.
/// </summary>
property bool PersistUserPreferences
{
bool get() { return _cefSettings->persist_user_preferences == 1; }
void set(bool value) { _cefSettings->persist_user_preferences = value; }
}
/// <summary>
/// Comma delimited ordered list of language codes without any whitespace that will be used in the "Accept-Language" HTTP header.
/// May be set globally using the CefSettings.AcceptLanguageList value. If both values are empty then "en-US,en" will be used.
///
/// </summary>
property String^ AcceptLanguageList
{
String^ get() { return StringUtils::ToClr(_cefSettings->accept_language_list); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->accept_language_list, value); }
}
/// <summary>
/// Background color used for the browser before a document is loaded and when no document color is specified. The alpha
/// component must be either fully opaque (0xFF) or fully transparent (0x00). If the alpha component is fully opaque then the RGB
/// components will be used as the background color. If the alpha component is fully transparent for a WinForms browser then the
/// default value of opaque white be used. If the alpha component is fully transparent for a windowless (WPF/OffScreen) browser
/// then transparent painting will be enabled.
/// </summary>
property uint32 BackgroundColor
{
uint32 get() { return _cefSettings->background_color; }
void set(uint32 value) { _cefSettings->background_color = value; }
}
/// <summary>
/// GUID string used for identifying the application. This is passed to the system AV function for scanning downloaded files. By
/// default, the GUID will be an empty string and the file will be treated as an untrusted file when the GUID is empty.
/// </summary>
property String^ ApplicationClientIdForFileScanning
{
String^ get() { return StringUtils::ToClr(_cefSettings->application_client_id_for_file_scanning); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_cefSettings->application_client_id_for_file_scanning, value); }
}
/// <summary>
/// Registers a custom scheme using the provided settings.
/// </summary>
/// <param name="cefCustomScheme">The CefCustomScheme which provides the details about the scheme.</param>
void RegisterScheme(CefCustomScheme^ cefCustomScheme)
{
//Scheme names are converted to lowercase
cefCustomScheme->SchemeName = cefCustomScheme->SchemeName->ToLower();
_cefCustomSchemes->Add(cefCustomScheme);
}
};
}
}

View file

@ -0,0 +1,97 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CookieManager.h"
#include "Internals\CefCookieVisitorAdapter.h"
#include "Internals\CefCompletionCallbackAdapter.h"
#include "Internals\CefSetCookieCallbackAdapter.h"
#include "Internals\CefDeleteCookiesCallbackAdapter.h"
using namespace CefSharp::Internals;
namespace CefSharp
{
void CookieManager::ThrowIfDisposed()
{
if (_cookieManager.get() == nullptr)
{
throw gcnew ObjectDisposedException("CookieManager");
}
}
bool CookieManager::DeleteCookies(String^ url, String^ name, IDeleteCookiesCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefDeleteCookiesCallback> wrapper = callback == nullptr ? NULL : new CefDeleteCookiesCallbackAdapter(callback);
return _cookieManager->DeleteCookies(StringUtils::ToNative(url), StringUtils::ToNative(name), wrapper);
}
bool CookieManager::SetCookie(String^ url, Cookie^ cookie, ISetCookieCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefSetCookieCallback> wrapper = callback == nullptr ? NULL : new CefSetCookieCallbackAdapter(callback);
CefCookie c;
StringUtils::AssignNativeFromClr(c.name, cookie->Name);
StringUtils::AssignNativeFromClr(c.value, cookie->Value);
StringUtils::AssignNativeFromClr(c.domain, cookie->Domain);
StringUtils::AssignNativeFromClr(c.path, cookie->Path);
c.secure = cookie->Secure;
c.httponly = cookie->HttpOnly;
c.has_expires = cookie->Expires.HasValue;
if (cookie->Expires.HasValue)
{
auto expires = cookie->Expires.Value;
c.expires = CefTime(DateTimeUtils::ToCefTime(expires));
}
c.creation = CefTime(DateTimeUtils::ToCefTime(cookie->Creation));
c.last_access = CefTime(DateTimeUtils::ToCefTime(cookie->LastAccess));
c.same_site = (cef_cookie_same_site_t)cookie->SameSite;
c.priority = (cef_cookie_priority_t)cookie->Priority;
return _cookieManager->SetCookie(StringUtils::ToNative(url), c, wrapper);
}
void CookieManager::SetSupportedSchemes(cli::array<String^>^ schemes, bool includeDefaults, ICompletionCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
_cookieManager->SetSupportedSchemes(StringUtils::ToNative(schemes), includeDefaults, wrapper);
}
bool CookieManager::VisitAllCookies(ICookieVisitor^ visitor)
{
ThrowIfDisposed();
CefRefPtr<CefCookieVisitorAdapter> cookieVisitor = new CefCookieVisitorAdapter(visitor);
return _cookieManager->VisitAllCookies(cookieVisitor);
}
bool CookieManager::VisitUrlCookies(String^ url, bool includeHttpOnly, ICookieVisitor^ visitor)
{
ThrowIfDisposed();
CefRefPtr<CefCookieVisitorAdapter> cookieVisitor = new CefCookieVisitorAdapter(visitor);
return _cookieManager->VisitUrlCookies(StringUtils::ToNative(url), includeHttpOnly, cookieVisitor);
}
bool CookieManager::FlushStore(ICompletionCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
return _cookieManager->FlushStore(wrapper);
}
}

View file

@ -0,0 +1,65 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_cookie.h"
#include "internals\CefCompletionCallbackAdapter.h"
namespace CefSharp
{
//TODO: No longer possible for users to create a CookieManager, can be made private now
/// <exclude />
private ref class CookieManager : public ICookieManager
{
private:
MCefRefPtr<CefCookieManager> _cookieManager;
void ThrowIfDisposed();
internal:
CookieManager(const CefRefPtr<CefCookieManager> &cookieManager)
:_cookieManager(cookieManager.get())
{
}
operator CefRefPtr<CefCookieManager>()
{
if (this == nullptr)
{
return NULL;
}
return _cookieManager.get();
}
public:
!CookieManager()
{
this->_cookieManager = nullptr;
}
~CookieManager()
{
this->!CookieManager();
}
virtual bool DeleteCookies(String^ url, String^ name, IDeleteCookiesCallback^ callback);
virtual bool SetCookie(String^ url, Cookie^ cookie, ISetCookieCallback^ callback);
virtual void SetSupportedSchemes(cli::array<String^>^ schemes, bool includeDefaults, ICompletionCallback^ callback);
virtual bool VisitAllCookies(ICookieVisitor^ visitor);
virtual bool VisitUrlCookies(String^ url, bool includeHttpOnly, ICookieVisitor^ visitor);
virtual bool FlushStore(ICompletionCallback^ callback);
virtual property bool IsDisposed
{
bool get()
{
return !_cookieManager.get();
}
}
};
}

View file

@ -0,0 +1,224 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_drag_data.h"
#include "Internals\CefWrapper.h"
#include "Internals\CefImageWrapper.h"
#include "Internals\CefWriteHandlerWrapper.h"
using namespace std;
using namespace System::IO;
namespace CefSharp
{
namespace Core
{
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class DragData : public IDragData, public CefWrapper
{
private:
MCefRefPtr<CefDragData> _wrappedDragData;
internal:
DragData(CefRefPtr<CefDragData> &dragData) :
_wrappedDragData(dragData)
{
IsReadOnly = dragData->IsReadOnly();
FileName = StringUtils::ToClr(dragData->GetFileName());
IsFile = dragData->IsFile();
IsFragment = dragData->IsFragment();
IsLink = dragData->IsLink();
}
!DragData()
{
_wrappedDragData = nullptr;
}
~DragData()
{
this->!DragData();
_disposed = true;
}
operator CefRefPtr<CefDragData>()
{
if (this == nullptr)
{
return NULL;
}
return _wrappedDragData.get();
}
public:
virtual property bool IsReadOnly;
virtual property String^ FileName;
virtual property bool IsFile;
virtual property bool IsFragment;
virtual property bool IsLink;
virtual IDragData^ Clone()
{
return gcnew DragData(_wrappedDragData->Clone());
}
///
// Create a new CefDragData object.
///
/*--cef()--*/
static IDragData^ Create()
{
return gcnew DragData(CefDragData::Create());
}
//TODO: Vector is a pointer, so can potentially be updated (items may be possibly removed)
virtual property IList<String^>^ FileNames
{
IList<String^>^ get()
{
auto names = vector<CefString>();
_wrappedDragData->GetFileNames(names);
return StringUtils::ToClr(names);
}
}
virtual property String^ FragmentBaseUrl
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetFragmentBaseURL());
}
void set(String^ fragmentBaseUrl)
{
_wrappedDragData->SetFragmentBaseURL(StringUtils::ToNative(fragmentBaseUrl));
}
}
virtual property String^ FragmentHtml
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetFragmentHtml());
}
void set(String^ fragmentHtml)
{
_wrappedDragData->SetFragmentHtml(StringUtils::ToNative(fragmentHtml));
}
}
virtual property String^ FragmentText
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetFragmentText());
}
void set(String^ fragmentText)
{
_wrappedDragData->SetFragmentText(StringUtils::ToNative(fragmentText));
}
}
virtual property bool HasImage
{
bool get()
{
return _wrappedDragData->HasImage();
}
}
/// <summary>
/// Get the image representation of drag data.
/// May return NULL if no image representation is available.
/// </summary>
virtual property IImage^ Image
{
IImage^ get()
{
if (_wrappedDragData->HasImage())
{
return gcnew CefImageWrapper(_wrappedDragData->GetImage());
}
return nullptr;
}
}
/// <summary>
/// Get the image hotspot (drag start location relative to image dimensions).
/// </summary>
virtual property CefSharp::Structs::Point ImageHotspot
{
CefSharp::Structs::Point get()
{
return CefSharp::Structs::Point(0, 0);
}
}
virtual property String^ LinkMetaData
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetLinkMetadata());
}
void set(String^ linkMetaData)
{
_wrappedDragData->SetLinkMetadata(StringUtils::ToNative(linkMetaData));
}
}
virtual property String^ LinkTitle
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetLinkTitle());
}
void set(String^ linkTitle)
{
_wrappedDragData->SetLinkTitle(StringUtils::ToNative(linkTitle));
}
}
virtual property String^ LinkUrl
{
String^ get()
{
return StringUtils::ToClr(_wrappedDragData->GetLinkURL());
}
void set(String^ linkUrl)
{
_wrappedDragData->SetLinkURL(StringUtils::ToNative(linkUrl));
}
}
virtual void AddFile(String^ path, String^ displayName)
{
_wrappedDragData->AddFile(StringUtils::ToNative(path), StringUtils::ToNative(displayName));
}
virtual void ResetFileContents()
{
_wrappedDragData->ResetFileContents();
}
virtual Int64 GetFileContents(Stream^ stream)
{
if (stream == nullptr)
{
return (Int64)_wrappedDragData->GetFileContents(NULL);
}
auto writeHandler = new CefWriteHandlerWrapper(stream);
auto writer = CefStreamWriter::CreateForHandler(writeHandler);
return (Int64)_wrappedDragData->GetFileContents(writer);
}
};
}
}

View file

@ -0,0 +1,59 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_auth_callback.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefAuthCallbackWrapper : public IAuthCallback, public CefWrapper
{
private:
MCefRefPtr<CefAuthCallback> _callback;
public:
CefAuthCallbackWrapper(CefRefPtr<CefAuthCallback> &callback)
: _callback(callback)
{
}
!CefAuthCallbackWrapper()
{
_callback = NULL;
}
~CefAuthCallbackWrapper()
{
this->!CefAuthCallbackWrapper();
_disposed = true;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
virtual void Continue(String^ username, String^ password)
{
ThrowIfDisposed();
_callback->Continue(StringUtils::ToNative(username), StringUtils::ToNative(password));
delete this;
}
};
}
}

View file

@ -0,0 +1,51 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_download_handler.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefBeforeDownloadCallbackWrapper : public IBeforeDownloadCallback, public CefWrapper
{
private:
MCefRefPtr<CefBeforeDownloadCallback> _callback;
public:
CefBeforeDownloadCallbackWrapper(CefRefPtr<CefBeforeDownloadCallback> &callback)
: _callback(callback)
{
}
!CefBeforeDownloadCallbackWrapper()
{
_callback = NULL;
}
~CefBeforeDownloadCallbackWrapper()
{
this->!CefBeforeDownloadCallbackWrapper();
_disposed = true;
}
virtual void Continue(String^ downloadPath, bool showDialog)
{
ThrowIfDisposed();
_callback->Continue(StringUtils::ToNative(downloadPath), showDialog);
delete this;
}
};
}
}

View file

@ -0,0 +1,780 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CefBrowserHostWrapper.h"
#include "include\cef_client.h"
#include "include\cef_parser.h"
#include "Cef.h"
#include "CefExtensionWrapper.h"
#include "CefTaskScheduler.h"
#include "DragData.h"
#include "CefRunFileDialogCallbackAdapter.h"
#include "CefPdfPrintCallbackWrapper.h"
#include "CefNavigationEntryVisitorAdapter.h"
#include "CefRegistrationWrapper.h"
#include "CefDevToolsMessageObserverAdapter.h"
#include "RequestContext.h"
#include "WindowInfo.h"
using namespace CefSharp::Core;
void CefBrowserHostWrapper::DragTargetDragEnter(IDragData^ dragData, MouseEvent mouseEvent, DragOperationsMask allowedOperations)
{
ThrowIfDisposed();
auto dragDataWrapper = static_cast<CefSharp::Core::DragData^>(dragData);
dragDataWrapper->ResetFileContents(); // Recommended by documentation to reset before calling DragEnter
_browserHost->DragTargetDragEnter(static_cast<CefRefPtr<CefDragData>>(dragDataWrapper), GetCefMouseEvent(mouseEvent), (CefBrowserHost::DragOperationsMask) allowedOperations);
}
void CefBrowserHostWrapper::DragTargetDragOver(MouseEvent mouseEvent, DragOperationsMask allowedOperations)
{
ThrowIfDisposed();
_browserHost->DragTargetDragOver(GetCefMouseEvent(mouseEvent), (CefBrowserHost::DragOperationsMask) allowedOperations);
}
void CefBrowserHostWrapper::DragTargetDragDrop(MouseEvent mouseEvent)
{
ThrowIfDisposed();
_browserHost->DragTargetDrop(GetCefMouseEvent(mouseEvent));
}
void CefBrowserHostWrapper::DragSourceEndedAt(int x, int y, DragOperationsMask op)
{
ThrowIfDisposed();
_browserHost->DragSourceEndedAt(x, y, (CefBrowserHost::DragOperationsMask)op);
}
void CefBrowserHostWrapper::DragTargetDragLeave()
{
ThrowIfDisposed();
_browserHost->DragTargetDragLeave();
}
void CefBrowserHostWrapper::DragSourceSystemDragEnded()
{
ThrowIfDisposed();
_browserHost->DragSourceSystemDragEnded();
}
void CefBrowserHostWrapper::StartDownload(String^ url)
{
ThrowIfDisposed();
_browserHost->StartDownload(StringUtils::ToNative(url));
}
void CefBrowserHostWrapper::Print()
{
ThrowIfDisposed();
_browserHost->Print();
}
void CefBrowserHostWrapper::PrintToPdf(String^ path, PdfPrintSettings^ settings, IPrintToPdfCallback^ callback)
{
ThrowIfDisposed();
CefPdfPrintSettings nativeSettings;
if (settings != nullptr)
{
StringUtils::AssignNativeFromClr(nativeSettings.header_footer_title, settings->HeaderFooterTitle);
StringUtils::AssignNativeFromClr(nativeSettings.header_footer_url, settings->HeaderFooterUrl);
nativeSettings.backgrounds_enabled = settings->BackgroundsEnabled ? 1 : 0;
nativeSettings.header_footer_enabled = settings->HeaderFooterEnabled ? 1 : 0;
nativeSettings.landscape = settings->Landscape ? 1 : 0;
nativeSettings.selection_only = settings->SelectionOnly ? 1 : 0;
nativeSettings.margin_bottom = settings->MarginBottom;
nativeSettings.margin_top = settings->MarginTop;
nativeSettings.margin_left = settings->MarginLeft;
nativeSettings.margin_right = settings->MarginRight;
nativeSettings.scale_factor = settings->ScaleFactor;
nativeSettings.page_height = settings->PageHeight;
nativeSettings.page_width = settings->PageWidth;
nativeSettings.margin_type = static_cast<cef_pdf_print_margin_type_t>(settings->MarginType);
}
_browserHost->PrintToPDF(StringUtils::ToNative(path), nativeSettings, new CefPdfPrintCallbackWrapper(callback));
}
void CefBrowserHostWrapper::SetZoomLevel(double zoomLevel)
{
ThrowIfDisposed();
_browserHost->SetZoomLevel(zoomLevel);
}
double CefBrowserHostWrapper::GetZoomLevel()
{
ThrowIfDisposed();
if (CefCurrentlyOn(TID_UI))
{
return _browserHost->GetZoomLevel();
}
throw gcnew InvalidOperationException("This method can only be called directly on the CEF UI Thread. Use GetZoomLevelAsync or use Cef.UIThreadTaskFactory to marshal the call onto the CEF UI Thread.");
}
Task<double>^ CefBrowserHostWrapper::GetZoomLevelAsync()
{
ThrowIfDisposed();
if (CefCurrentlyOn(TID_UI))
{
auto taskSource = gcnew TaskCompletionSource<double>();
CefSharp::Internals::TaskExtensions::TrySetResultAsync<double>(taskSource, GetZoomLevelOnUI());
return taskSource->Task;
}
return Cef::UIThreadTaskFactory->StartNew(gcnew Func<double>(this, &CefBrowserHostWrapper::GetZoomLevelOnUI));
}
IntPtr CefBrowserHostWrapper::GetWindowHandle()
{
ThrowIfDisposed();
return IntPtr(_browserHost->GetWindowHandle());
}
void CefBrowserHostWrapper::CloseBrowser(bool forceClose)
{
ThrowIfDisposed();
_browserHost->CloseBrowser(forceClose);
}
bool CefBrowserHostWrapper::TryCloseBrowser()
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _browserHost->TryCloseBrowser();
}
void CefBrowserHostWrapper::ShowDevTools(IWindowInfo^ windowInfo, int inspectElementAtX, int inspectElementAtY)
{
ThrowIfDisposed();
CefBrowserSettings settings;
CefWindowInfo nativeWindowInfo;
if (windowInfo == nullptr)
{
nativeWindowInfo.SetAsPopup(NULL, "DevTools");
}
else
{
//Get the inner instance then case that
auto cefWindowInfoWrapper = static_cast<WindowInfo^>(windowInfo->UnWrap());
nativeWindowInfo = *cefWindowInfoWrapper->GetWindowInfo();
}
_browserHost->ShowDevTools(nativeWindowInfo, _browserHost->GetClient(), settings, CefPoint(inspectElementAtX, inspectElementAtY));
}
void CefBrowserHostWrapper::CloseDevTools()
{
ThrowIfDisposed();
_browserHost->CloseDevTools();
}
bool CefBrowserHostWrapper::HasDevTools::get()
{
ThrowIfDisposed();
return _browserHost->HasDevTools();
}
bool CefBrowserHostWrapper::SendDevToolsMessage(String^ messageAsJson)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
if (String::IsNullOrEmpty(messageAsJson))
{
throw gcnew ArgumentNullException("messageAsJson");
}
//NOTE: Prefix with cli:: namespace as VS2015 gets confused with std::array
cli::array<Byte>^ buffer = System::Text::Encoding::UTF8->GetBytes(messageAsJson);
pin_ptr<Byte> src = &buffer[0];
return _browserHost->SendDevToolsMessage(static_cast<void*>(src), buffer->Length);
}
int CefBrowserHostWrapper::ExecuteDevToolsMethod(int messageId, String^ method, IDictionary<String^, Object^>^ paramaters)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
if (paramaters == nullptr)
{
return _browserHost->ExecuteDevToolsMethod(messageId, StringUtils::ToNative(method), NULL);
}
auto val = TypeConversion::ToNative(paramaters);
if (val && val->GetType() == VTYPE_DICTIONARY)
{
return _browserHost->ExecuteDevToolsMethod(messageId, StringUtils::ToNative(method), val->GetDictionary());
}
throw gcnew Exception("Unable to convert paramaters to CefDictionaryValue.");
}
int CefBrowserHostWrapper::ExecuteDevToolsMethod(int messageId, String^ method, String^ paramsAsJson)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
if (String::IsNullOrEmpty(paramsAsJson))
{
return _browserHost->ExecuteDevToolsMethod(messageId, StringUtils::ToNative(method), NULL);
}
auto val = CefParseJSON(StringUtils::ToNative(paramsAsJson), cef_json_parser_options_t::JSON_PARSER_RFC);
if (val && val->GetType() == VTYPE_DICTIONARY)
{
return _browserHost->ExecuteDevToolsMethod(messageId, StringUtils::ToNative(method), val->GetDictionary());
}
throw gcnew Exception("Unable to parse paramsAsJson with CefParseJSON method");
}
IRegistration^ CefBrowserHostWrapper::AddDevToolsMessageObserver(IDevToolsMessageObserver^ observer)
{
ThrowIfDisposed();
auto registration = _browserHost->AddDevToolsMessageObserver(new CefDevToolsMessageObserverAdapter(observer));
return gcnew CefRegistrationWrapper(registration);
}
void CefBrowserHostWrapper::AddWordToDictionary(String^ word)
{
ThrowIfDisposed();
_browserHost->AddWordToDictionary(StringUtils::ToNative(word));
}
void CefBrowserHostWrapper::ReplaceMisspelling(String^ word)
{
ThrowIfDisposed();
_browserHost->ReplaceMisspelling(StringUtils::ToNative(word));
}
IExtension^ CefBrowserHostWrapper::Extension::get()
{
ThrowIfDisposed();
auto extension = _browserHost->GetExtension();
if (extension.get())
{
return gcnew CefExtensionWrapper(_browserHost->GetExtension());
}
return nullptr;
}
void CefBrowserHostWrapper::RunFileDialog(CefFileDialogMode mode, String^ title, String^ defaultFilePath, IList<String^>^ acceptFilters, int selectedAcceptFilter, IRunFileDialogCallback^ callback)
{
ThrowIfDisposed();
_browserHost->RunFileDialog((CefBrowserHost::FileDialogMode)mode,
StringUtils::ToNative(title),
StringUtils::ToNative(defaultFilePath),
StringUtils::ToNative(acceptFilters),
selectedAcceptFilter,
new CefRunFileDialogCallbackAdapter(callback));
}
void CefBrowserHostWrapper::Find(int identifier, String^ searchText, bool forward, bool matchCase, bool findNext)
{
ThrowIfDisposed();
_browserHost->Find(identifier, StringUtils::ToNative(searchText), forward, matchCase, findNext);
}
void CefBrowserHostWrapper::StopFinding(bool clearSelection)
{
ThrowIfDisposed();
_browserHost->StopFinding(clearSelection);
}
void CefBrowserHostWrapper::SetFocus(bool focus)
{
ThrowIfDisposed();
_browserHost->SetFocus(focus);
}
void CefBrowserHostWrapper::SendFocusEvent(bool setFocus)
{
ThrowIfDisposed();
_browserHost->SendFocusEvent(setFocus);
}
void CefBrowserHostWrapper::SendKeyEvent(KeyEvent keyEvent)
{
ThrowIfDisposed();
CefKeyEvent nativeKeyEvent;
nativeKeyEvent.focus_on_editable_field = keyEvent.FocusOnEditableField == 1;
nativeKeyEvent.is_system_key = keyEvent.IsSystemKey == 1;
nativeKeyEvent.modifiers = (uint32)keyEvent.Modifiers;
nativeKeyEvent.type = (cef_key_event_type_t)keyEvent.Type;
nativeKeyEvent.native_key_code = keyEvent.NativeKeyCode;
nativeKeyEvent.windows_key_code = keyEvent.WindowsKeyCode;
_browserHost->SendKeyEvent(nativeKeyEvent);
}
void CefBrowserHostWrapper::SendKeyEvent(int message, int wParam, int lParam)
{
ThrowIfDisposed();
CefKeyEvent keyEvent;
keyEvent.windows_key_code = wParam;
keyEvent.native_key_code = lParam;
keyEvent.is_system_key = message == WM_SYSCHAR ||
message == WM_SYSKEYDOWN ||
message == WM_SYSKEYUP;
keyEvent.modifiers = GetCefKeyboardModifiers(wParam, lParam);
if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
{
keyEvent.type = KEYEVENT_RAWKEYDOWN;
}
else if (message == WM_KEYUP || message == WM_SYSKEYUP)
{
keyEvent.type = KEYEVENT_KEYUP;
}
else
{
keyEvent.type = KEYEVENT_CHAR;
// mimic alt-gr check behaviour from
// src/ui/events/win/events_win_utils.cc: GetModifiersFromKeyState
if (IsKeyDown(VK_RMENU))
{
// reverse AltGr detection taken from PlatformKeyMap::UsesAltGraph
// instead of checking all combination for ctrl-alt, just check current char
HKL current_layout = ::GetKeyboardLayout(0);
// https://docs.microsoft.com/en-gb/windows/win32/api/winuser/nf-winuser-vkkeyscanexw
// ... high-order byte contains the shift state,
// which can be a combination of the following flag bits.
// 2 Either CTRL key is pressed.
// 4 Either ALT key is pressed.
SHORT scan_res = ::VkKeyScanExW(wParam, current_layout);
if (((scan_res >> 8) & 0xFF) == (2 | 4)) // ctrl-alt pressed
{
keyEvent.modifiers &= ~(EVENTFLAG_CONTROL_DOWN | EVENTFLAG_ALT_DOWN);
keyEvent.modifiers |= EVENTFLAG_ALTGR_DOWN;
}
}
}
_browserHost->SendKeyEvent(keyEvent);
}
double CefBrowserHostWrapper::GetZoomLevelOnUI()
{
if (_disposed)
{
return 0.0;
}
CefTaskScheduler::EnsureOn(TID_UI, "CefBrowserHostWrapper::GetZoomLevel");
//Don't throw exception if no browser host here as it's not easy to handle
if (_browserHost.get())
{
return _browserHost->GetZoomLevel();
}
return 0.0;
}
void CefBrowserHostWrapper::SendMouseWheelEvent(MouseEvent mouseEvent, int deltaX, int deltaY)
{
ThrowIfDisposed();
if (_browserHost.get())
{
CefMouseEvent m;
m.x = mouseEvent.X;
m.y = mouseEvent.Y;
m.modifiers = (uint32)mouseEvent.Modifiers;
_browserHost->SendMouseWheelEvent(m, deltaX, deltaY);
}
}
void CefBrowserHostWrapper::SendTouchEvent(TouchEvent evt)
{
ThrowIfDisposed();
if (_browserHost.get())
{
CefTouchEvent e;
e.id = evt.Id;
e.modifiers = (uint32)evt.Modifiers;
e.pointer_type = (cef_pointer_type_t)evt.PointerType;
e.pressure = evt.Pressure;
e.radius_x = evt.RadiusX;
e.radius_y = evt.RadiusY;
e.rotation_angle = evt.RotationAngle;
e.type = (cef_touch_event_type_t)evt.Type;
e.x = evt.X;
e.y = evt.Y;
_browserHost->SendTouchEvent(e);
}
}
void CefBrowserHostWrapper::SetAccessibilityState(CefState accessibilityState)
{
ThrowIfDisposed();
_browserHost->SetAccessibilityState((cef_state_t)accessibilityState);
}
void CefBrowserHostWrapper::SetAutoResizeEnabled(bool enabled, Size minSize, Size maxSize)
{
ThrowIfDisposed();
_browserHost->SetAutoResizeEnabled(enabled, CefSize(minSize.Width, minSize.Height), CefSize(maxSize.Width, maxSize.Height));
}
void CefBrowserHostWrapper::Invalidate(PaintElementType type)
{
ThrowIfDisposed();
_browserHost->Invalidate((CefBrowserHost::PaintElementType)type);
}
bool CefBrowserHostWrapper::IsBackgroundHost::get()
{
ThrowIfDisposed();
return _browserHost->IsBackgroundHost();
}
void CefBrowserHostWrapper::ImeSetComposition(String^ text, cli::array<CompositionUnderline>^ underlines, Nullable<CefSharp::Structs::Range> replacementRange, Nullable<CefSharp::Structs::Range> selectionRange)
{
ThrowIfDisposed();
std::vector<CefCompositionUnderline> underlinesVector = std::vector<CefCompositionUnderline>();
CefRange repRange;
CefRange selRange;
if (underlines != nullptr && underlines->Length > 0)
{
for each (CompositionUnderline underline in underlines)
{
auto c = CefCompositionUnderline();
c.range = CefRange(underline.Range.From, underline.Range.To);
c.color = underline.Color;
c.background_color = underline.BackgroundColor;
c.thick = (int)underline.Thick;
c.style = (cef_composition_underline_style_t)underline.Style;
underlinesVector.push_back(c);
}
}
if (replacementRange.HasValue)
{
repRange = CefRange(replacementRange.Value.From, replacementRange.Value.To);
}
if (selectionRange.HasValue)
{
selRange = CefRange(selectionRange.Value.From, selectionRange.Value.To);
}
_browserHost->ImeSetComposition(StringUtils::ToNative(text), underlinesVector, repRange, selRange);
}
void CefBrowserHostWrapper::ImeCommitText(String^ text, Nullable<CefSharp::Structs::Range> replacementRange, int relativeCursorPos)
{
ThrowIfDisposed();
CefRange repRange;
if (replacementRange.HasValue)
{
repRange = CefRange(replacementRange.Value.From, replacementRange.Value.To);
}
_browserHost->ImeCommitText(StringUtils::ToNative(text), repRange, relativeCursorPos);
}
void CefBrowserHostWrapper::ImeFinishComposingText(bool keepSelection)
{
ThrowIfDisposed();
_browserHost->ImeFinishComposingText(keepSelection);
}
void CefBrowserHostWrapper::ImeCancelComposition()
{
ThrowIfDisposed();
_browserHost->ImeCancelComposition();
}
void CefBrowserHostWrapper::SendMouseClickEvent(MouseEvent mouseEvent, MouseButtonType mouseButtonType, bool mouseUp, int clickCount)
{
ThrowIfDisposed();
CefMouseEvent m;
m.x = mouseEvent.X;
m.y = mouseEvent.Y;
m.modifiers = (uint32)mouseEvent.Modifiers;
_browserHost->SendMouseClickEvent(m, (CefBrowserHost::MouseButtonType) mouseButtonType, mouseUp, clickCount);
}
void CefBrowserHostWrapper::SendMouseMoveEvent(MouseEvent mouseEvent, bool mouseLeave)
{
ThrowIfDisposed();
CefMouseEvent m;
m.x = mouseEvent.X;
m.y = mouseEvent.Y;
m.modifiers = (uint32)mouseEvent.Modifiers;
_browserHost->SendMouseMoveEvent(m, mouseLeave);
}
void CefBrowserHostWrapper::WasResized()
{
ThrowIfDisposed();
_browserHost->WasResized();
}
void CefBrowserHostWrapper::WasHidden(bool hidden)
{
ThrowIfDisposed();
_browserHost->WasHidden(hidden);
}
void CefBrowserHostWrapper::GetNavigationEntries(INavigationEntryVisitor^ visitor, bool currentOnly)
{
ThrowIfDisposed();
auto navEntryVisitor = new CefNavigationEntryVisitorAdapter(visitor);
_browserHost->GetNavigationEntries(navEntryVisitor, currentOnly);
}
NavigationEntry^ CefBrowserHostWrapper::GetVisibleNavigationEntry()
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
auto entry = _browserHost->GetVisibleNavigationEntry();
return TypeConversion::FromNative(entry, true);
}
void CefBrowserHostWrapper::NotifyMoveOrResizeStarted()
{
ThrowIfDisposed();
_browserHost->NotifyMoveOrResizeStarted();
}
void CefBrowserHostWrapper::NotifyScreenInfoChanged()
{
ThrowIfDisposed();
_browserHost->NotifyScreenInfoChanged();
}
int CefBrowserHostWrapper::WindowlessFrameRate::get()
{
ThrowIfDisposed();
return _browserHost->GetWindowlessFrameRate();
}
void CefBrowserHostWrapper::WindowlessFrameRate::set(int val)
{
ThrowIfDisposed();
_browserHost->SetWindowlessFrameRate(val);
}
bool CefBrowserHostWrapper::WindowRenderingDisabled::get()
{
ThrowIfDisposed();
return _browserHost->IsWindowRenderingDisabled();
}
bool CefBrowserHostWrapper::IsAudioMuted::get()
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _browserHost->IsAudioMuted();
}
void CefBrowserHostWrapper::SetAudioMuted(bool mute)
{
ThrowIfDisposed();
_browserHost->SetAudioMuted(mute);
}
IntPtr CefBrowserHostWrapper::GetOpenerWindowHandle()
{
ThrowIfDisposed();
return IntPtr(_browserHost->GetOpenerWindowHandle());
}
void CefBrowserHostWrapper::SendExternalBeginFrame()
{
ThrowIfDisposed();
_browserHost->SendExternalBeginFrame();
}
void CefBrowserHostWrapper::SendCaptureLostEvent()
{
ThrowIfDisposed();
_browserHost->SendCaptureLostEvent();
}
IRequestContext^ CefBrowserHostWrapper::RequestContext::get()
{
ThrowIfDisposed();
return gcnew CefSharp::Core::RequestContext(_browserHost->GetRequestContext());
}
CefMouseEvent CefBrowserHostWrapper::GetCefMouseEvent(MouseEvent mouseEvent)
{
CefMouseEvent cefMouseEvent;
cefMouseEvent.x = mouseEvent.X;
cefMouseEvent.y = mouseEvent.Y;
cefMouseEvent.modifiers = (uint32)mouseEvent.Modifiers;
return cefMouseEvent;
}
//Code imported from
//https://bitbucket.org/chromiumembedded/branches-2062-cef3/src/a073e92426b3967f1fc2f1d3fd7711d809eeb03a/tests/cefclient/cefclient_osr_widget_win.cpp?at=master#cl-361
int CefBrowserHostWrapper::GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam)
{
int modifiers = 0;
if (IsKeyDown(VK_SHIFT))
modifiers |= EVENTFLAG_SHIFT_DOWN;
if (IsKeyDown(VK_CONTROL))
modifiers |= EVENTFLAG_CONTROL_DOWN;
if (IsKeyDown(VK_MENU))
modifiers |= EVENTFLAG_ALT_DOWN;
// Low bit set from GetKeyState indicates "toggled".
if (::GetKeyState(VK_NUMLOCK) & 1)
modifiers |= EVENTFLAG_NUM_LOCK_ON;
if (::GetKeyState(VK_CAPITAL) & 1)
modifiers |= EVENTFLAG_CAPS_LOCK_ON;
switch (wparam)
{
case VK_RETURN:
if ((lparam >> 16) & KF_EXTENDED)
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_INSERT:
case VK_DELETE:
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
if (!((lparam >> 16) & KF_EXTENDED))
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_NUMLOCK:
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
case VK_DIVIDE:
case VK_MULTIPLY:
case VK_SUBTRACT:
case VK_ADD:
case VK_DECIMAL:
case VK_CLEAR:
modifiers |= EVENTFLAG_IS_KEY_PAD;
break;
case VK_SHIFT:
if (IsKeyDown(VK_LSHIFT))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RSHIFT))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_CONTROL:
if (IsKeyDown(VK_LCONTROL))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RCONTROL))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_MENU:
if (IsKeyDown(VK_LMENU))
modifiers |= EVENTFLAG_IS_LEFT;
else if (IsKeyDown(VK_RMENU))
modifiers |= EVENTFLAG_IS_RIGHT;
break;
case VK_LWIN:
modifiers |= EVENTFLAG_IS_LEFT;
break;
case VK_RWIN:
modifiers |= EVENTFLAG_IS_RIGHT;
break;
}
return modifiers;
}

View file

@ -0,0 +1,174 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "CefWrapper.h"
using namespace System::Threading::Tasks;
using namespace CefSharp::Structs;
using namespace CefSharp::Enums;
using namespace CefSharp::Callback;
namespace CefSharp
{
namespace Internals
{
private ref class CefBrowserHostWrapper : public IBrowserHost, public CefWrapper
{
private:
MCefRefPtr<CefBrowserHost> _browserHost;
double GetZoomLevelOnUI();
internal:
CefBrowserHostWrapper(CefRefPtr<CefBrowserHost> &browserHost) : _browserHost(browserHost)
{
}
!CefBrowserHostWrapper()
{
_browserHost = NULL;
}
~CefBrowserHostWrapper()
{
this->!CefBrowserHostWrapper();
_disposed = true;
}
public:
virtual void StartDownload(String^ url);
virtual void Print();
virtual void PrintToPdf(String^ path, PdfPrintSettings^ settings, IPrintToPdfCallback^ callback);
virtual void SetZoomLevel(double zoomLevel);
virtual double GetZoomLevel();
virtual Task<double>^ GetZoomLevelAsync();
virtual IntPtr GetWindowHandle();
virtual void CloseBrowser(bool forceClose);
virtual bool TryCloseBrowser();
virtual void DragTargetDragEnter(IDragData^ dragData, MouseEvent mouseEvent, DragOperationsMask allowedOperations);
virtual void DragTargetDragOver(MouseEvent mouseEvent, DragOperationsMask allowedOperations);
virtual void DragTargetDragDrop(MouseEvent mouseEvent);
virtual void DragSourceEndedAt(int x, int y, DragOperationsMask op);
virtual void DragTargetDragLeave();
virtual void DragSourceSystemDragEnded();
virtual void ShowDevTools(IWindowInfo^ windowInfo, int inspectElementAtX, int inspectElementAtY);
virtual void CloseDevTools();
///
// Returns true if this browser currently has an associated DevTools browser.
// Must be called on the browser process UI thread.
///
/*--cef()--*/
virtual property bool HasDevTools
{
bool get();
}
virtual bool SendDevToolsMessage(String^ messageAsJson);
virtual int ExecuteDevToolsMethod(int messageId, String^ method, String^ paramsAsJson);
virtual int ExecuteDevToolsMethod(int messageId, String^ method, IDictionary<String^, Object^>^ paramaters);
virtual IRegistration^ AddDevToolsMessageObserver(IDevToolsMessageObserver^ observer);
virtual void AddWordToDictionary(String^ word);
virtual void ReplaceMisspelling(String^ word);
virtual property IExtension^ Extension
{
IExtension^ get();
}
virtual void RunFileDialog(CefFileDialogMode mode, String^ title, String^ defaultFilePath, IList<String^>^ acceptFilters, int selectedAcceptFilter, IRunFileDialogCallback^ callback);
virtual void Find(int identifier, String^ searchText, bool forward, bool matchCase, bool findNext);
virtual void StopFinding(bool clearSelection);
virtual void SetFocus(bool focus);
virtual void SendFocusEvent(bool setFocus);
virtual void SendKeyEvent(KeyEvent keyEvent);
virtual void SendKeyEvent(int message, int wParam, int lParam);
virtual void SendMouseWheelEvent(MouseEvent mouseEvent, int deltaX, int deltaY);
virtual void SendTouchEvent(TouchEvent evt);
virtual void Invalidate(PaintElementType type);
virtual property bool IsBackgroundHost
{
bool get();
}
virtual void ImeSetComposition(String^ text, cli::array<CompositionUnderline>^ underlines, Nullable<CefSharp::Structs::Range> replacementRange, Nullable<CefSharp::Structs::Range> selectionRange);
virtual void ImeCommitText(String^ text, Nullable<CefSharp::Structs::Range> replacementRange, int relativeCursorPos);
virtual void ImeFinishComposingText(bool keepSelection);
virtual void ImeCancelComposition();
virtual void SendMouseClickEvent(MouseEvent mouseEvent, MouseButtonType mouseButtonType, bool mouseUp, int clickCount);
virtual void SendMouseMoveEvent(MouseEvent mouseEvent, bool mouseLeave);
virtual void SetAccessibilityState(CefState accessibilityState);
virtual void SetAutoResizeEnabled(bool enabled, Size minSize, Size maxSize);
virtual void NotifyMoveOrResizeStarted();
virtual void NotifyScreenInfoChanged();
virtual void WasResized();
virtual void WasHidden(bool hidden);
virtual void GetNavigationEntries(INavigationEntryVisitor^ visitor, bool currentOnly);
virtual NavigationEntry^ GetVisibleNavigationEntry();
virtual property int WindowlessFrameRate
{
int get();
void set(int val);
}
virtual property bool WindowRenderingDisabled
{
bool get();
}
virtual property bool IsAudioMuted
{
bool get();
}
virtual void SetAudioMuted(bool mute);
virtual IntPtr GetOpenerWindowHandle();
virtual void SendExternalBeginFrame();
virtual void SendCaptureLostEvent();
virtual property IRequestContext^ RequestContext
{
IRequestContext^ get();
}
// Misc. private functions:
CefMouseEvent GetCefMouseEvent(MouseEvent mouseEvent);
int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
// Private keyboard functions:
bool IsKeyDown(WPARAM wparam)
{
return (GetKeyState(wparam) & 0x8000) != 0;
}
};
}
}

View file

@ -0,0 +1,251 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "Internals\CefFrameWrapper.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\CefBrowserHostWrapper.h"
///
// Returns the browser host object. This method can only be called in the
// browser process.
///
/*--cef()--*/
IBrowserHost^ CefBrowserWrapper::GetHost()
{
ThrowIfDisposed();
if (_browserHost == nullptr)
{
_browserHost = gcnew CefBrowserHostWrapper(_browser->GetHost());
}
return _browserHost;
}
///
// Returns true if the browser can navigate backwards.
///
/*--cef()--*/
bool CefBrowserWrapper::CanGoBack::get()
{
ThrowIfDisposed();
return _browser->CanGoBack();
}
///
// Navigate backwards.
///
/*--cef()--*/
void CefBrowserWrapper::GoBack()
{
ThrowIfDisposed();
_browser->GoBack();
}
///
// Returns true if the browser can navigate forwards.
///
/*--cef()--*/
bool CefBrowserWrapper::CanGoForward::get()
{
ThrowIfDisposed();
return _browser->CanGoForward();
}
///
// Navigate forwards.
///
/*--cef()--*/
void CefBrowserWrapper::GoForward()
{
ThrowIfDisposed();
_browser->GoForward();
}
///
// Returns true if the browser is currently loading.
///
/*--cef()--*/
bool CefBrowserWrapper::IsLoading::get()
{
ThrowIfDisposed();
return _browser->IsLoading();
}
void CefBrowserWrapper::CloseBrowser(bool forceClose)
{
ThrowIfDisposed();
_browser->GetHost()->CloseBrowser(forceClose);
}
///
// Reload the current page.
///
/*--cef()--*/
void CefBrowserWrapper::Reload(bool ignoreCache)
{
ThrowIfDisposed();
if (ignoreCache)
{
_browser->ReloadIgnoreCache();
}
else
{
_browser->Reload();
}
}
///
// Stop loading the page.
///
/*--cef()--*/
void CefBrowserWrapper::StopLoad()
{
ThrowIfDisposed();
_browser->StopLoad();
}
///
// Returns the globally unique identifier for this browser.
///
/*--cef()--*/
int CefBrowserWrapper::Identifier::get()
{
ThrowIfDisposed();
return _browser->GetIdentifier();
}
///
// Returns true if this object is pointing to the same handle as |that|
// object.
///
/*--cef()--*/
bool CefBrowserWrapper::IsSame(IBrowser^ that)
{
ThrowIfDisposed();
return _browser->IsSame(dynamic_cast<CefBrowserWrapper^>(that)->_browser.get());
}
///
// Returns true if the window is a popup window.
///
/*--cef()--*/
bool CefBrowserWrapper::IsPopup::get()
{
ThrowIfDisposed();
return _browser->IsPopup();
}
///
// Returns true if a document has been loaded in the browser.
///
/*--cef()--*/
bool CefBrowserWrapper::HasDocument::get()
{
ThrowIfDisposed();
return _browser->HasDocument();
}
IFrame^ CefBrowserWrapper::MainFrame::get()
{
ThrowIfDisposed();
auto frame = _browser->GetMainFrame();
return gcnew CefFrameWrapper(frame);
}
///
// Returns the focused frame for the browser window.
///
/*--cef()--*/
IFrame^ CefBrowserWrapper::FocusedFrame::get()
{
ThrowIfDisposed();
return gcnew CefFrameWrapper(_browser->GetFocusedFrame());
}
///
// Returns the frame with the specified identifier, or NULL if not found.
///
/*--cef(capi_name=get_frame_byident)--*/
IFrame^ CefBrowserWrapper::GetFrame(Int64 identifier)
{
ThrowIfDisposed();
auto frame = _browser->GetFrame(identifier);
if (frame.get())
{
return gcnew CefFrameWrapper(frame);
}
return nullptr;
}
///
// Returns the frame with the specified name, or NULL if not found.
///
/*--cef(optional_param=name)--*/
IFrame^ CefBrowserWrapper::GetFrame(String^ name)
{
ThrowIfDisposed();
auto frame = _browser->GetFrame(StringUtils::ToNative(name));
if (frame.get())
{
return gcnew CefFrameWrapper(frame);
}
return nullptr;
}
///
// Returns the number of frames that currently exist.
///
/*--cef()--*/
int CefBrowserWrapper::GetFrameCount()
{
ThrowIfDisposed();
return static_cast<int>(_browser->GetFrameCount());
}
///
// Returns the identifiers of all existing frames.
///
/*--cef(count_func=identifiers:GetFrameCount)--*/
List<Int64>^ CefBrowserWrapper::GetFrameIdentifiers()
{
ThrowIfDisposed();
std::vector<Int64> identifiers;
_browser->GetFrameIdentifiers(identifiers);
List<Int64>^ results = gcnew List<Int64>(static_cast<int>(identifiers.size()));
for (UINT i = 0; i < identifiers.size(); i++)
{
results->Add(identifiers[i]);
}
return results;
}
///
// Returns the names of all existing frames.
///
/*--cef()--*/
List<String^>^ CefBrowserWrapper::GetFrameNames()
{
ThrowIfDisposed();
std::vector<CefString> names;
_browser->GetFrameNames(names);
return StringUtils::ToClr(names);
}
MCefRefPtr<CefBrowser> CefBrowserWrapper::Browser::get()
{
return _browser;
}

View file

@ -0,0 +1,191 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include <include/cef_browser.h>
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefBrowserWrapper : public IBrowser, public CefWrapper
{
private:
MCefRefPtr<CefBrowser> _browser;
IBrowserHost^ _browserHost;
internal:
CefBrowserWrapper::CefBrowserWrapper(CefRefPtr<CefBrowser> &browser)
: _browser(browser), _browserHost(nullptr)
{
}
!CefBrowserWrapper()
{
// Release the reference.
_browser = nullptr;
}
~CefBrowserWrapper()
{
this->!CefBrowserWrapper();
delete _browserHost;
_browserHost = nullptr;
_disposed = true;
}
virtual property MCefRefPtr<CefBrowser> Browser
{
MCefRefPtr<CefBrowser> get();
}
public:
///
// Returns the browser host object. This method can only be called in the
// browser process.
///
/*--cef()--*/
virtual IBrowserHost^ GetHost();
///
// Returns true if the browser can navigate backwards.
///
/*--cef()--*/
virtual property bool CanGoBack
{
bool get();
}
///
// Navigate backwards.
///
/*--cef()--*/
virtual void GoBack();
///
// Returns true if the browser can navigate forwards.
///
/*--cef()--*/
virtual property bool CanGoForward
{
bool get();
}
///
// Navigate forwards.
///
/*--cef()--*/
virtual void GoForward();
///
// Returns true if the browser is currently loading.
///
/*--cef()--*/
virtual property bool IsLoading
{
bool get();
}
virtual void CloseBrowser(bool forceClose);
///
// Reload the current page.
///
/*--cef()--*/
virtual void Reload(bool ignoreCache);
///
// Stop loading the page.
///
/*--cef()--*/
virtual void StopLoad();
///
// Returns the globally unique identifier for this browser.
///
/*--cef()--*/
virtual property int Identifier
{
int get();
}
///
// Returns true if this object is pointing to the same handle as |that|
// object.
///
/*--cef()--*/
virtual bool IsSame(IBrowser^ that);
///
// Returns true if the window is a popup window.
///
/*--cef()--*/
virtual property bool IsPopup
{
bool get();
}
///
// Returns true if a document has been loaded in the browser.
///
/*--cef()--*/
virtual property bool HasDocument
{
bool get();
}
///
// Returns the main (top-level) frame for the browser window.
///
/*--cef()--*/
virtual property IFrame^ MainFrame
{
IFrame^ get();
}
///
// Returns the focused frame for the browser window.
///
/*--cef()--*/
virtual property IFrame^ FocusedFrame
{
IFrame^ get();
}
///
// Returns the frame with the specified identifier, or NULL if not found.
///
/*--cef(capi_name=get_frame_byident)--*/
virtual IFrame^ GetFrame(Int64 identifier);
///
// Returns the frame with the specified name, or NULL if not found.
///
/*--cef(optional_param=name)--*/
virtual IFrame^ GetFrame(String^ name);
///
// Returns the number of frames that currently exist.
///
/*--cef()--*/
virtual int GetFrameCount();
///
// Returns the identifiers of all existing frames.
///
/*--cef(count_func=identifiers:GetFrameCount)--*/
virtual List<Int64>^ GetFrameIdentifiers();
///
// Returns the names of all existing frames.
///
/*--cef()--*/
virtual List<String^>^ GetFrameNames();
};
}
}

View file

@ -0,0 +1,59 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_callback.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefCallbackWrapper : public ICallback, public CefWrapper
{
private:
MCefRefPtr<CefCallback> _callback;
public:
CefCallbackWrapper(CefRefPtr<CefCallback> &callback) :
_callback(callback)
{
}
!CefCallbackWrapper()
{
_callback = NULL;
}
~CefCallbackWrapper()
{
this->!CefCallbackWrapper();
_disposed = true;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
virtual void Continue()
{
ThrowIfDisposed();
_callback->Continue();
delete this;
}
};
}
}

View file

@ -0,0 +1,98 @@
// Copyright © 2016 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request_handler.h"
#include "CefWrapper.h"
using namespace System::Security::Cryptography::X509Certificates;
namespace CefSharp
{
namespace Internals
{
private ref class CefCertificateCallbackWrapper : public ISelectClientCertificateCallback, public CefWrapper
{
private:
MCefRefPtr<CefSelectClientCertificateCallback> _callback;
const CefRequestHandler::X509CertificateList& _certificateList;
public:
CefCertificateCallbackWrapper(CefRefPtr<CefSelectClientCertificateCallback>& callback, const CefRequestHandler::X509CertificateList& certificates)
: _callback(callback), _certificateList(certificates)
{
}
!CefCertificateCallbackWrapper()
{
_callback = NULL;
}
~CefCertificateCallbackWrapper()
{
this->!CefCertificateCallbackWrapper();
_disposed = true;
}
virtual void Select(X509Certificate2^ cert)
{
ThrowIfDisposed();
if (cert == nullptr)
{
_callback->Select(NULL);
}
else
{
auto certSerial = cert->SerialNumber;
std::vector<CefRefPtr<CefX509Certificate>>::const_iterator it =
_certificateList.begin();
for (; it != _certificateList.end(); ++it)
{
// TODO: Need to make this logic of comparing serial number of the certificate (*it)
// with the selected certificate returned by the user selection (cert).
// Better and more performant way would be to read the serial number from
// (*it) and convert it into System::String, so that it can directly compared
// with certSerial. This is how I tried it but the Encoding class garbled up
// the string when converting it from CefRefPtr<CefBinaryValue> to System::String
// Try to find a better way to do this
//
//auto serialNum((*it)->GetSerialNumber());
//auto byteSize = serialNum->GetSize();
//auto bufferByte = gcnew cli::array<Byte>(byteSize);
//pin_ptr<Byte> src = &bufferByte[0]; // pin pointer to first element in arr
//serialNum->GetData(static_cast<void*>(src), byteSize, 0);
//UTF8Encoding^ encoding = gcnew UTF8Encoding;
//auto serialStr(encoding->GetString(bufferByte));
auto bytes((*it)->GetDEREncoded());
auto byteSize = bytes->GetSize();
auto bufferByte = gcnew cli::array<Byte>(byteSize);
pin_ptr<Byte> src = &bufferByte[0]; // pin pointer to first element in arr
bytes->GetData(static_cast<void*>(src), byteSize, 0);
auto newcert = gcnew System::Security::Cryptography::X509Certificates::X509Certificate2(bufferByte);
auto serialStr = newcert->SerialNumber;
if (certSerial == serialStr)
{
_callback->Select(*it);
break;
}
}
}
delete this;
}
};
}
}

View file

@ -0,0 +1,39 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_callback.h"
namespace CefSharp
{
namespace Internals
{
private class CefCompletionCallbackAdapter : public CefCompletionCallback
{
private:
gcroot<ICompletionCallback^> _handler;
public:
CefCompletionCallbackAdapter(ICompletionCallback^ handler)
{
_handler = handler;
}
~CefCompletionCallbackAdapter()
{
delete _handler;
_handler = nullptr;
}
void OnComplete() OVERRIDE
{
_handler->OnComplete();
}
IMPLEMENT_REFCOUNTING(CefCompletionCallbackAdapter);
};
}
}

View file

@ -0,0 +1,155 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CefContextMenuParamsWrapper.h"
namespace CefSharp
{
namespace Internals
{
int CefContextMenuParamsWrapper::YCoord::get()
{
ThrowIfDisposed();
return _wrappedInfo->GetYCoord();
}
int CefContextMenuParamsWrapper::XCoord::get()
{
ThrowIfDisposed();
return _wrappedInfo->GetXCoord();
}
ContextMenuType CefContextMenuParamsWrapper::TypeFlags::get()
{
ThrowIfDisposed();
return (ContextMenuType)_wrappedInfo->GetTypeFlags();
}
String^ CefContextMenuParamsWrapper::LinkUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetLinkUrl());
}
String^ CefContextMenuParamsWrapper::UnfilteredLinkUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetUnfilteredLinkUrl());
}
String^ CefContextMenuParamsWrapper::SourceUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetSourceUrl());
}
bool CefContextMenuParamsWrapper::HasImageContents::get()
{
ThrowIfDisposed();
return _wrappedInfo->HasImageContents();
}
String^ CefContextMenuParamsWrapper::PageUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetPageUrl());
}
String^ CefContextMenuParamsWrapper::FrameUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetFrameUrl());
}
String^ CefContextMenuParamsWrapper::FrameCharset::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetFrameCharset());
}
ContextMenuMediaType CefContextMenuParamsWrapper::MediaType::get()
{
ThrowIfDisposed();
return (ContextMenuMediaType)_wrappedInfo->GetMediaType();
}
ContextMenuMediaState CefContextMenuParamsWrapper::MediaStateFlags::get()
{
ThrowIfDisposed();
return (ContextMenuMediaState)_wrappedInfo->GetMediaStateFlags();
}
String^ CefContextMenuParamsWrapper::SelectionText::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetSelectionText());
}
String^ CefContextMenuParamsWrapper::MisspelledWord::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_wrappedInfo->GetMisspelledWord());
}
List<String^>^ CefContextMenuParamsWrapper::DictionarySuggestions::get()
{
ThrowIfDisposed();
std::vector<CefString>& dictionarySuggestions = std::vector<CefString>();
bool result = _wrappedInfo->GetDictionarySuggestions(dictionarySuggestions);
return StringUtils::ToClr(dictionarySuggestions);
}
bool CefContextMenuParamsWrapper::IsEditable::get()
{
ThrowIfDisposed();
return _wrappedInfo->IsEditable();
}
bool CefContextMenuParamsWrapper::IsSpellCheckEnabled::get()
{
ThrowIfDisposed();
return _wrappedInfo->IsSpellCheckEnabled();
}
ContextMenuEditState CefContextMenuParamsWrapper::EditStateFlags::get()
{
ThrowIfDisposed();
return (ContextMenuEditState)_wrappedInfo->GetEditStateFlags();
}
bool CefContextMenuParamsWrapper::IsCustomMenu::get()
{
ThrowIfDisposed();
return _wrappedInfo->IsCustomMenu();
}
bool CefContextMenuParamsWrapper::IsPepperMenu::get()
{
ThrowIfDisposed();
return _wrappedInfo->IsPepperMenu();
}
}
}

View file

@ -0,0 +1,63 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "CefWrapper.h"
#include "include\cef_context_menu_handler.h"
using namespace System::Collections::Generic;
namespace CefSharp
{
namespace Internals
{
private ref class CefContextMenuParamsWrapper : public IContextMenuParams, public CefWrapper
{
MCefRefPtr<CefContextMenuParams> _wrappedInfo;
internal:
CefContextMenuParamsWrapper(CefRefPtr<CefContextMenuParams> &cefParams) :
_wrappedInfo(cefParams)
{
}
!CefContextMenuParamsWrapper()
{
_wrappedInfo = NULL;
}
~CefContextMenuParamsWrapper()
{
this->!CefContextMenuParamsWrapper();
_disposed = true;
}
public:
virtual property int YCoord { int get(); }
virtual property int XCoord { int get(); }
virtual property ContextMenuType TypeFlags { ContextMenuType get(); }
virtual property String^ LinkUrl { String^ get(); }
virtual property String^ UnfilteredLinkUrl { String^ get(); }
virtual property String^ SourceUrl { String^ get(); }
virtual property bool HasImageContents { bool get(); }
virtual property String^ PageUrl { String^ get(); }
virtual property String^ FrameUrl { String^ get(); }
virtual property String^ FrameCharset { String^ get(); }
virtual property ContextMenuMediaType MediaType { ContextMenuMediaType get(); }
virtual property ContextMenuMediaState MediaStateFlags { ContextMenuMediaState get(); }
virtual property String^ SelectionText { String^ get(); }
virtual property String^ MisspelledWord { String^ get(); }
virtual property List<String^>^ DictionarySuggestions { List<String^>^ get(); }
virtual property bool IsEditable { bool get(); }
virtual property bool IsSpellCheckEnabled { bool get(); }
virtual property ContextMenuEditState EditStateFlags { ContextMenuEditState get(); }
virtual property bool IsCustomMenu { bool get(); }
virtual property bool IsPepperMenu { bool get(); }
};
}
}

View file

@ -0,0 +1,82 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_resource_request_handler.h"
#include "CefResponseWrapper.h"
#include "Request.h"
#include "CefFrameWrapper.h"
#include "CefBrowserWrapper.h"
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
private class CefCookieAccessFilterAdapter : public CefCookieAccessFilter
{
private:
gcroot<ICookieAccessFilter^> _handler;
gcroot<IWebBrowser^> _browserControl;
public:
CefCookieAccessFilterAdapter(ICookieAccessFilter^ handler, IWebBrowser^ browserControl)
{
_handler = handler;
_browserControl = browserControl;
}
~CefCookieAccessFilterAdapter()
{
delete _handler;
_handler = nullptr;
_browserControl = nullptr;
}
bool CanSendCookie(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, const CefCookie& cookie) OVERRIDE
{
Request requestWrapper(request);
auto managedCookie = TypeConversion::FromNative(cookie);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
return _handler->CanSendCookie(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, managedCookie);
}
return _handler->CanSendCookie(_browserControl, nullptr, nullptr, %requestWrapper, managedCookie);
}
bool CanSaveCookie(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response, const CefCookie& cookie) OVERRIDE
{
Request requestWrapper(request);
CefResponseWrapper responseWrapper(response);
auto managedCookie = TypeConversion::FromNative(cookie);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
return _handler->CanSaveCookie(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, %responseWrapper, managedCookie);
}
return _handler->CanSaveCookie(_browserControl, nullptr, nullptr, %requestWrapper, %responseWrapper, managedCookie);
}
IMPLEMENT_REFCOUNTING(CefCookieAccessFilterAdapter);
};
}
}

View file

@ -0,0 +1,43 @@
// Copyright © 2012 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "TypeConversion.h"
#include "include/cef_cookie.h"
namespace CefSharp
{
namespace Internals
{
private class CefCookieVisitorAdapter : public CefCookieVisitor
{
private:
gcroot<ICookieVisitor^> _visitor;
public:
CefCookieVisitorAdapter(ICookieVisitor^ visitor) :
_visitor(visitor)
{
}
~CefCookieVisitorAdapter()
{
delete _visitor;
_visitor = nullptr;
}
virtual bool Visit(const CefCookie& cefCookie, int count, int total, bool& deleteCookie) OVERRIDE
{
auto cookie = TypeConversion::FromNative(cefCookie);
return _visitor->Visit(cookie, count, total, deleteCookie);
}
IMPLEMENT_REFCOUNTING(CefCookieVisitorAdapter);
};
}
}

View file

@ -0,0 +1,40 @@
// Copyright © 2017 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_cookie.h"
namespace CefSharp
{
namespace Internals
{
private class CefDeleteCookiesCallbackAdapter : public CefDeleteCookiesCallback
{
private:
gcroot<IDeleteCookiesCallback^> _handler;
public:
CefDeleteCookiesCallbackAdapter(IDeleteCookiesCallback^ handler)
{
_handler = handler;
}
~CefDeleteCookiesCallbackAdapter()
{
delete _handler;
_handler = nullptr;
}
void OnComplete(int numDeleted) OVERRIDE
{
_handler->OnComplete(numDeleted);
}
IMPLEMENT_REFCOUNTING(CefDeleteCookiesCallbackAdapter);
};
}
}

View file

@ -0,0 +1,82 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_callback.h"
#include "CefBrowserWrapper.h"
#include "StringUtils.h"
using namespace CefSharp::Callback;
using namespace System::IO;
namespace CefSharp
{
namespace Internals
{
private class CefDevToolsMessageObserverAdapter : public CefDevToolsMessageObserver
{
private:
gcroot<IDevToolsMessageObserver^> _handler;
public:
CefDevToolsMessageObserverAdapter(IDevToolsMessageObserver^ handler)
{
_handler = handler;
}
~CefDevToolsMessageObserverAdapter()
{
delete _handler;
_handler = nullptr;
}
virtual bool OnDevToolsMessage(CefRefPtr<CefBrowser> browser, const void* message, size_t message_size)
{
CefBrowserWrapper browserWrapper(browser);
UnmanagedMemoryStream messageStream((Byte*)message, (Int64)message_size, (Int64)message_size, FileAccess::Read);
return _handler->OnDevToolsMessage(%browserWrapper, %messageStream);
}
virtual void OnDevToolsMethodResult(CefRefPtr<CefBrowser> browser,
int message_id,
bool success,
const void* result,
size_t result_size) OVERRIDE
{
CefBrowserWrapper browserWrapper(browser);
UnmanagedMemoryStream resultStream((Byte*)result, (Int64)result_size, (Int64)result_size, FileAccess::Read);
_handler->OnDevToolsMethodResult(%browserWrapper, message_id, success, %resultStream);
}
virtual void OnDevToolsEvent(CefRefPtr<CefBrowser> browser, const CefString& method, const void* params, size_t params_size) OVERRIDE
{
CefBrowserWrapper browserWrapper(browser);
UnmanagedMemoryStream paramsStream((Byte*)params, (Int64)params_size, (Int64)params_size, FileAccess::Read);
_handler->OnDevToolsEvent(%browserWrapper, StringUtils::ToClr(method), %paramsStream);
}
void OnDevToolsAgentAttached(CefRefPtr<CefBrowser> browser) OVERRIDE
{
CefBrowserWrapper browserWrapper(browser);
_handler->OnDevToolsAgentAttached(%browserWrapper);
}
void OnDevToolsAgentDetached(CefRefPtr<CefBrowser> browser) OVERRIDE
{
CefBrowserWrapper browserWrapper(browser);
_handler->OnDevToolsAgentDetached(%browserWrapper);
}
IMPLEMENT_REFCOUNTING(CefDevToolsMessageObserverAdapter);
};
}
}

View file

@ -0,0 +1,69 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_download_handler.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefDownloadItemCallbackWrapper : public IDownloadItemCallback, public CefWrapper
{
private:
MCefRefPtr<CefDownloadItemCallback> _callback;
public:
CefDownloadItemCallbackWrapper(CefRefPtr<CefDownloadItemCallback> &callback)
: _callback(callback)
{
}
!CefDownloadItemCallbackWrapper()
{
_callback = NULL;
}
~CefDownloadItemCallbackWrapper()
{
this->!CefDownloadItemCallbackWrapper();
_disposed = true;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
virtual void Pause()
{
ThrowIfDisposed();
//Only free the callback when cancel called
//Need to be able to pause/resume #3145
_callback->Pause();
}
virtual void Resume()
{
ThrowIfDisposed();
//Only free the callback when cancel called
//Need to be able to pause/resume #3145
_callback->Resume();
}
};
}
}

View file

@ -0,0 +1,214 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_extension.h"
#include "include\cef_extension_handler.h"
#include "BrowserSettings.h"
#include "CefExtensionWrapper.h"
#include "CefBrowserWrapper.h"
#include "CefGetExtensionResourceCallbackWrapper.h"
#include "WindowInfo.h"
using namespace CefSharp;
namespace CefSharp
{
namespace Internals
{
private class CefExtensionHandlerAdapter : public CefExtensionHandler
{
gcroot<IExtensionHandler^> _handler;
public:
CefExtensionHandlerAdapter(IExtensionHandler^ handler)
: _handler(handler)
{
}
~CefExtensionHandlerAdapter()
{
delete _handler;
_handler = nullptr;
}
///
// Called if the CefRequestContext::LoadExtension request fails. |result| will
// be the error code.
///
/*--cef()--*/
void OnExtensionLoadFailed(cef_errorcode_t result) OVERRIDE
{
_handler->OnExtensionLoadFailed((CefErrorCode)result);
}
///
// Called if the CefRequestContext::LoadExtension request succeeds.
// |extension| is the loaded extension.
///
/*--cef()--*/
void OnExtensionLoaded(CefRefPtr<CefExtension> extension) OVERRIDE
{
//TODO: Should this be auto disposed?
_handler->OnExtensionLoaded(gcnew CefExtensionWrapper(extension));
}
///
// Called after the CefExtension::Unload request has completed.
///
/*--cef()--*/
void OnExtensionUnloaded(CefRefPtr<CefExtension> extension) OVERRIDE
{
//TODO: Add comment to interface saying extension is only valid within the scope
//of this method as it's auto disposed
CefExtensionWrapper wrapper(extension);
_handler->OnExtensionUnloaded(%wrapper);
}
///
// Called when an extension needs a browser to host a background script
// specified via the "background" manifest key. The browser will have no
// visible window and cannot be displayed. |extension| is the extension that
// is loading the background script. |url| is an internally generated
// reference to an HTML page that will be used to load the background script
// via a <script> src attribute. To allow creation of the browser optionally
// modify |client| and |settings| and return false. To cancel creation of the
// browser (and consequently cancel load of the background script) return
// true. Successful creation will be indicated by a call to
// CefLifeSpanHandler::OnAfterCreated, and CefBrowserHost::IsBackgroundHost
// will return true for the resulting browser. See
// https://developer.chrome.com/extensions/event_pages for more information
// about extension background script usage.
///
/*--cef()--*/
bool OnBeforeBackgroundBrowser(CefRefPtr<CefExtension> extension,
const CefString& url,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE
{
BrowserSettings browserSettingsWrapper(&settings);
return _handler->OnBeforeBackgroundBrowser(gcnew CefExtensionWrapper(extension),
StringUtils::ToClr(url),
%browserSettingsWrapper);
}
///
// Called when an extension API (e.g. chrome.tabs.create) requests creation of
// a new browser. |extension| and |browser| are the source of the API call.
// |active_browser| may optionally be specified via the windowId property or
// returned via the GetActiveBrowser() callback and provides the default
// |client| and |settings| values for the new browser. |index| is the position
// value optionally specified via the index property. |url| is the URL that
// will be loaded in the browser. |active| is true if the new browser should
// be active when opened. To allow creation of the browser optionally modify
// |windowInfo|, |client| and |settings| and return false. To cancel creation
// of the browser return true. Successful creation will be indicated by a call
// to CefLifeSpanHandler::OnAfterCreated. Any modifications to |windowInfo|
// will be ignored if |active_browser| is wrapped in a CefBrowserView.
///
/*--cef()--*/
bool OnBeforeBrowser(CefRefPtr<CefExtension> extension,
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefBrowser> active_browser,
int index,
const CefString& url,
bool active,
CefWindowInfo& windowInfo,
CefRefPtr<CefClient>& client,
CefBrowserSettings& settings) OVERRIDE
{
BrowserSettings browserSettingsWrapper(&settings);
return _handler->OnBeforeBrowser(gcnew CefExtensionWrapper(extension),
gcnew CefBrowserWrapper(browser),
gcnew CefBrowserWrapper(active_browser),
index,
StringUtils::ToClr(url),
active,
gcnew WindowInfo(&windowInfo),
%browserSettingsWrapper);
}
///
// Called when no tabId is specified to an extension API call that accepts a
// tabId parameter (e.g. chrome.tabs.*). |extension| and |browser| are the
// source of the API call. Return the browser that will be acted on by the API
// call or return NULL to act on |browser|. The returned browser must share
// the same CefRequestContext as |browser|. Incognito browsers should not be
// considered unless the source extension has incognito access enabled, in
// which case |include_incognito| will be true.
///
/*--cef()--*/
CefRefPtr<CefBrowser> GetActiveBrowser(
CefRefPtr<CefExtension> extension,
CefRefPtr<CefBrowser> browser,
bool includeIncognito) OVERRIDE
{
//TODO: Should extension be auto disposed?
auto activeBrowser = _handler->GetActiveBrowser(gcnew CefExtensionWrapper(extension),
gcnew CefBrowserWrapper(browser),
includeIncognito);
if (activeBrowser == nullptr)
{
return NULL;
}
//TODO: CLean this up
auto wrapper = static_cast<CefBrowserWrapper^>(activeBrowser);
return wrapper->Browser.get();
}
///
// Called when the tabId associated with |target_browser| is specified to an
// extension API call that accepts a tabId parameter (e.g. chrome.tabs.*).
// |extension| and |browser| are the source of the API call. Return true
// to allow access of false to deny access. Access to incognito browsers
// should not be allowed unless the source extension has incognito access
// enabled, in which case |include_incognito| will be true.
///
/*--cef()--*/
bool CanAccessBrowser(CefRefPtr<CefExtension> extension,
CefRefPtr<CefBrowser> browser,
bool includeIncognito,
CefRefPtr<CefBrowser> target_browser) OVERRIDE
{
return _handler->CanAccessBrowser(gcnew CefExtensionWrapper(extension),
gcnew CefBrowserWrapper(browser),
includeIncognito,
gcnew CefBrowserWrapper(target_browser));
}
///
// Called to retrieve an extension resource that would normally be loaded from
// disk (e.g. if a file parameter is specified to chrome.tabs.executeScript).
// |extension| and |browser| are the source of the resource request. |file| is
// the requested relative file path. To handle the resource request return
// true and execute |callback| either synchronously or asynchronously. For the
// default behavior which reads the resource from the extension directory on
// disk return false. Localization substitutions will not be applied to
// resources handled via this method.
///
/*--cef()--*/
bool GetExtensionResource(
CefRefPtr<CefExtension> extension,
CefRefPtr<CefBrowser> browser,
const CefString& file,
CefRefPtr<CefGetExtensionResourceCallback> callback) OVERRIDE
{
return _handler->GetExtensionResource(gcnew CefExtensionWrapper(extension),
gcnew CefBrowserWrapper(browser),
StringUtils::ToClr(file),
gcnew CefGetExtensionResourceCallbackWrapper(callback));
}
IMPLEMENT_REFCOUNTING(CefExtensionHandlerAdapter);
};
}
}

View file

@ -0,0 +1,87 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CefExtensionWrapper.h"
#include "CefValueWrapper.h"
#include "RequestContext.h"
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
String^ CefExtensionWrapper::Identifier::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_extension->GetIdentifier());
}
String^ CefExtensionWrapper::Path::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_extension->GetPath());
}
IDictionary<String^, IValue^>^ CefExtensionWrapper::Manifest::get()
{
ThrowIfDisposed();
auto dictionary = _extension->GetManifest();;
if (!dictionary.get() || (int)dictionary->GetSize() == 0)
{
return nullptr;
}
auto result = gcnew Dictionary<String^, IValue^>();
CefDictionaryValue::KeyList keys;
dictionary->GetKeys(keys);
for (size_t i = 0; i < keys.size(); i++)
{
auto key = keys[i];
auto keyValue = StringUtils::ToClr(key);
auto valueWrapper = gcnew CefValueWrapper(dictionary->GetValue(keys[i]));
result->Add(keyValue, valueWrapper);
}
return result;
}
bool CefExtensionWrapper::IsSame(IExtension^ that)
{
ThrowIfDisposed();
return _extension->IsSame(((CefExtensionWrapper^)that)->_extension.get());
}
IRequestContext^ CefExtensionWrapper::LoaderContext::get()
{
ThrowIfDisposed();
return gcnew RequestContext(_extension->GetLoaderContext());
}
bool CefExtensionWrapper::IsLoaded::get()
{
ThrowIfDisposed();
return _extension->IsLoaded();
}
void CefExtensionWrapper::Unload()
{
ThrowIfDisposed();
_extension->Unload();
}
}
}

View file

@ -0,0 +1,55 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_extension.h"
#include "Internals\TypeConversion.h"
#include "CefValueWrapper.h"
#include "CefWrapper.h"
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
namespace CefSharp
{
namespace Internals
{
private ref class CefExtensionWrapper : public IExtension, public CefWrapper
{
MCefRefPtr<CefExtension> _extension;
internal:
CefExtensionWrapper(CefRefPtr<CefExtension> &extension) :
_extension(extension)
{
}
!CefExtensionWrapper()
{
_extension = nullptr;
}
~CefExtensionWrapper()
{
this->!CefExtensionWrapper();
_disposed = true;
}
public:
virtual property String^ Identifier { String^ get(); }
virtual property String^ Path { String^ get(); }
virtual property IDictionary<String^, IValue^>^ Manifest { IDictionary<String^, IValue^>^ get(); }
virtual bool IsSame(IExtension^ that);
virtual property IRequestContext^ LoaderContext { IRequestContext^ get(); }
virtual property bool IsLoaded { bool get(); }
virtual void Unload();
};
}
}

View file

@ -0,0 +1,59 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_dialog_handler.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefFileDialogCallbackWrapper : public IFileDialogCallback, public CefWrapper
{
private:
MCefRefPtr<CefFileDialogCallback> _callback;
public:
CefFileDialogCallbackWrapper(CefRefPtr<CefFileDialogCallback> &callback) :
_callback(callback)
{
}
!CefFileDialogCallbackWrapper()
{
_callback = NULL;
}
~CefFileDialogCallbackWrapper()
{
this->!CefFileDialogCallbackWrapper();
_disposed = true;
}
virtual void Continue(int selectedAcceptFilter, List<String^>^ filePaths)
{
ThrowIfDisposed();
_callback->Continue(selectedAcceptFilter, StringUtils::ToNative(filePaths));
delete this;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
};
}
}

View file

@ -0,0 +1,431 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include <msclr/lock.h>
#include "UrlRequest.h"
#include "Request.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\CefFrameWrapper.h"
#include "Internals\CefStringVisitorAdapter.h"
#include "Internals\ClientAdapter.h"
#include "Internals\Serialization\Primitives.h"
#include "Internals\Messaging\Messages.h"
#include "Internals\CefURLRequestClientAdapter.h"
using namespace CefSharp::Core;
using namespace CefSharp::Internals::Messaging;
using namespace CefSharp::Internals::Serialization;
///
// True if this object is currently attached to a valid frame.
///
/*--cef()--*/
bool CefFrameWrapper::IsValid::get()
{
ThrowIfDisposed();
return _frame->IsValid();
}
///
// Execute undo in this frame.
///
/*--cef()--*/
void CefFrameWrapper::Undo()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Undo();
}
///
// Execute redo in this frame.
///
/*--cef()--*/
void CefFrameWrapper::Redo()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Redo();
}
///
// Execute cut in this frame.
///
/*--cef()--*/
void CefFrameWrapper::Cut()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Cut();
}
///
// Execute copy in this frame.
///
/*--cef()--*/
void CefFrameWrapper::Copy()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Copy();
}
///
// Execute paste in this frame.
///
/*--cef()--*/
void CefFrameWrapper::Paste()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Paste();
}
///
// Execute delete in this frame.
///
/*--cef(capi_name=del)--*/
void CefFrameWrapper::Delete()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->Delete();
}
///
// Execute select all in this frame.
///
/*--cef()--*/
void CefFrameWrapper::SelectAll()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->SelectAll();
}
///
// Save this frame's HTML source to a temporary file and open it in the
// default text viewing application. This method can only be called from the
// browser process.
///
/*--cef()--*/
void CefFrameWrapper::ViewSource()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->ViewSource();
}
///
// Retrieve this frame's HTML source as a string sent to the specified
// visitor.
///
/*--cef()--*/
Task<String^>^ CefFrameWrapper::GetSourceAsync()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
auto taskStringVisitor = gcnew TaskStringVisitor();
_frame->GetSource(new CefStringVisitorAdapter(taskStringVisitor));
return taskStringVisitor->Task;
}
///
// Retrieve this frame's HTML source as a string sent to the specified
// visitor.
///
/*--cef()--*/
void CefFrameWrapper::GetSource(IStringVisitor^ visitor)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->GetSource(new CefStringVisitorAdapter(visitor));
}
///
// Retrieve this frame's display text as a string sent to the specified
// visitor.
///
/*--cef()--*/
Task<String^>^ CefFrameWrapper::GetTextAsync()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
auto taskStringVisitor = gcnew TaskStringVisitor();
_frame->GetText(new CefStringVisitorAdapter(taskStringVisitor));
return taskStringVisitor->Task;
}
///
// Retrieve this frame's display text as a string sent to the specified
// visitor.
///
/*--cef()--*/
void CefFrameWrapper::GetText(IStringVisitor^ visitor)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->GetText(new CefStringVisitorAdapter(visitor));
}
///
// Load the request represented by the |request| object.
///
/*--cef()--*/
void CefFrameWrapper::LoadRequest(IRequest^ request)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
auto requestWrapper = (Request^)request->UnWrap();
_frame->LoadRequest(requestWrapper);
}
///
// Load the specified |url|.
///
/*--cef()--*/
void CefFrameWrapper::LoadUrl(String^ url)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->LoadURL(StringUtils::ToNative(url));
}
///
// Execute a string of JavaScript code in this frame. The |script_url|
// parameter is the URL where the script in question can be found, if any.
// The renderer may request this URL to show the developer the source of the
// error. The |start_line| parameter is the base line number to use for error
// reporting.
///
/*--cef(optional_param=script_url)--*/
void CefFrameWrapper::ExecuteJavaScriptAsync(String^ code, String^ scriptUrl, int startLine)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
_frame->ExecuteJavaScript(StringUtils::ToNative(code), StringUtils::ToNative(scriptUrl), startLine);
}
Task<JavascriptResponse^>^ CefFrameWrapper::EvaluateScriptAsync(String^ script, String^ scriptUrl, int startLine, Nullable<TimeSpan> timeout, bool useImmediatelyInvokedFuncExpression)
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
auto browser = _frame->GetBrowser();
auto host = browser->GetHost();
//If we're unable to get the underlying browser/browserhost then return null
if (!browser.get() || !host.get())
{
return nullptr;
}
auto client = static_cast<ClientAdapter*>(host->GetClient().get());
auto pendingTaskRepository = client->GetPendingTaskRepository();
//create a new taskcompletionsource
auto idAndComplectionSource = pendingTaskRepository->CreatePendingTask(timeout);
if (useImmediatelyInvokedFuncExpression)
{
script = "(function() { let cefSharpInternalCallbackId = " + idAndComplectionSource.Key + "; " + script + " })();";
}
auto message = CefProcessMessage::Create(kEvaluateJavascriptRequest);
auto argList = message->GetArgumentList();
SetInt64(argList, 0, idAndComplectionSource.Key);
argList->SetString(1, StringUtils::ToNative(script));
argList->SetString(2, StringUtils::ToNative(scriptUrl));
argList->SetInt(3, startLine);
_frame->SendProcessMessage(CefProcessId::PID_RENDERER, message);
return idAndComplectionSource.Value->Task;
}
///
// Returns true if this is the main (top-level) frame.
///
/*--cef()--*/
bool CefFrameWrapper::IsMain::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
return _frame->IsMain();
}
///
// Returns true if this is the focused frame.
///
/*--cef()--*/
bool CefFrameWrapper::IsFocused::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
return _frame->IsFocused();
}
///
// Returns the name for this frame. If the frame has an assigned name (for
// example, set via the iframe "name" attribute) then that value will be
// returned. Otherwise a unique name will be constructed based on the frame
// parent hierarchy. The main (top-level) frame will always have an empty name
// value.
///
/*--cef()--*/
String^ CefFrameWrapper::Name::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
return StringUtils::ToClr(_frame->GetName());
}
///
// Returns the globally unique identifier for this frame.
///
/*--cef()--*/
Int64 CefFrameWrapper::Identifier::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
return _frame->GetIdentifier();
}
///
// Returns the parent of this frame or NULL if this is the main (top-level)
// frame.
///
/*--cef()--*/
IFrame^ CefFrameWrapper::Parent::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
if (_parentFrame != nullptr)
{
return _parentFrame;
}
// Be paranoid about creating the cached IFrame.
msclr::lock sync(_syncRoot);
if (_parentFrame != nullptr)
{
return _parentFrame;
}
auto parent = _frame->GetParent();
if (parent == nullptr)
{
return nullptr;
}
_parentFrame = gcnew CefFrameWrapper(parent);
return _parentFrame;
}
///
// Returns the URL currently loaded in this frame.
///
/*--cef()--*/
String^ CefFrameWrapper::Url::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
return StringUtils::ToClr(_frame->GetURL());
}
///
// Returns the browser that this frame belongs to.
///
/*--cef()--*/
IBrowser^ CefFrameWrapper::Browser::get()
{
ThrowIfDisposed();
ThrowIfFrameInvalid();
if (_owningBrowser != nullptr)
{
return _owningBrowser;
}
// Be paranoid about creating the cached IBrowser.
msclr::lock sync(_syncRoot);
if (_owningBrowser != nullptr)
{
return _owningBrowser;
}
_owningBrowser = gcnew CefBrowserWrapper(_frame->GetBrowser());
return _owningBrowser;
}
IRequest^ CefFrameWrapper::CreateRequest(bool initializePostData)
{
auto request = CefRequest::Create();
if (initializePostData)
{
request->SetPostData(CefPostData::Create());
}
return gcnew Request(request);
}
IUrlRequest^ CefFrameWrapper::CreateUrlRequest(IRequest^ request, IUrlRequestClient^ client)
{
ThrowIfDisposed();
if (request == nullptr)
{
throw gcnew ArgumentNullException("request");
}
if (client == nullptr)
{
throw gcnew ArgumentNullException("client");
}
auto urlRequest = _frame->CreateURLRequest(
(Request^)request->UnWrap(),
new CefUrlRequestClientAdapter(client));
return gcnew UrlRequest(urlRequest);
}
void CefFrameWrapper::ThrowIfFrameInvalid()
{
if (_frame->IsValid() == false)
{
throw gcnew Exception(L"The underlying frame is no longer valid - please check the IsValid property before calling!");
}
}

View file

@ -0,0 +1,277 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_frame.h"
#include "include\cef_v8.h"
#include "CefWrapper.h"
using namespace System::Threading::Tasks;
namespace CefSharp
{
namespace Internals
{
///
// Class used to represent a frame in the browser window. When used in the
// browser process the methods of this class may be called on any thread unless
// otherwise indicated in the comments. When used in the render process the
// methods of this class may only be called on the main thread.
///
/*--cef(source=library)--*/
private ref class CefFrameWrapper : public IFrame, public CefWrapper
{
private:
MCefRefPtr<CefFrame> _frame;
IFrame^ _parentFrame;
IBrowser^ _owningBrowser;
Object^ _syncRoot;
internal:
CefFrameWrapper::CefFrameWrapper(CefRefPtr<CefFrame> &frame)
: _frame(frame), _parentFrame(nullptr),
_owningBrowser(nullptr), _syncRoot(gcnew Object())
{
}
!CefFrameWrapper()
{
_frame = NULL;
}
~CefFrameWrapper()
{
this->!CefFrameWrapper();
delete _parentFrame;
delete _owningBrowser;
_parentFrame = nullptr;
_owningBrowser = nullptr;
_syncRoot = nullptr;
_disposed = true;
}
public:
///
// True if this object is currently attached to a valid frame.
///
/*--cef()--*/
virtual property bool IsValid
{
bool get();
}
///
// Execute undo in this frame.
///
/*--cef()--*/
virtual void Undo();
///
// Execute redo in this frame.
///
/*--cef()--*/
virtual void Redo();
///
// Execute cut in this frame.
///
/*--cef()--*/
virtual void Cut();
///
// Execute copy in this frame.
///
/*--cef()--*/
virtual void Copy();
///
// Execute paste in this frame.
///
/*--cef()--*/
virtual void Paste();
///
// Execute delete in this frame.
///
/*--cef(capi_name=del)--*/
virtual void Delete();
///
// Execute select all in this frame.
///
/*--cef()--*/
virtual void SelectAll();
///
// Save this frame's HTML source to a temporary file and open it in the
// default text viewing application. This method can only be called from the
// browser process.
///
/*--cef()--*/
virtual void ViewSource();
///
// Retrieve this frame's HTML source as a string sent to the specified
// visitor.
///
/*--cef()--*/
virtual Task<String^>^ GetSourceAsync();
///
// Retrieve this frame's HTML source as a string sent to the specified
// visitor.
///
/*--cef()--*/
virtual void GetSource(IStringVisitor^ visitor);
///
// Retrieve this frame's display text as a string sent to the specified
// visitor.
///
/*--cef()--*/
virtual Task<String^>^ GetTextAsync();
///
// Retrieve this frame's display text as a string sent to the specified
// visitor.
///
/*--cef()--*/
virtual void GetText(IStringVisitor^ visitor);
///
/// Load the request represented by the |request| object.
///
/*--cef()--*/
virtual void LoadRequest(IRequest^ request);
///
// Load the specified |url|.
///
/*--cef()--*/
virtual void LoadUrl(String^ url);
///
// Execute a string of JavaScript code in this frame. The |script_url|
// parameter is the URL where the script in question can be found, if any.
// The renderer may request this URL to show the developer the source of the
// error. The |start_line| parameter is the base line number to use for error
// reporting.
///
/*--cef(optional_param=script_url)--*/
virtual void ExecuteJavaScriptAsync(String^ code, String^ scriptUrl, int startLine);
virtual Task<JavascriptResponse^>^ EvaluateScriptAsync(String^ script, String^ scriptUrl, int startLine, Nullable<TimeSpan> timeout, bool useImmediatelyInvokedFuncExpression);
///
// Returns true if this is the main (top-level) frame.
///
/*--cef()--*/
virtual property bool IsMain
{
bool get();
}
///
// Returns true if this is the focused frame.
///
/*--cef()--*/
virtual property bool IsFocused
{
bool get();
}
///
// Returns the name for this frame. If the frame has an assigned name (for
// example, set via the iframe "name" attribute) then that value will be
// returned. Otherwise a unique name will be constructed based on the frame
// parent hierarchy. The main (top-level) frame will always have an empty name
// value.
///
/*--cef()--*/
virtual property String^ Name
{
String^ get();
}
///
// Returns the globally unique identifier for this frame.
///
/*--cef()--*/
virtual property Int64 Identifier
{
Int64 get();
}
///
// Returns the parent of this frame or NULL if this is the main (top-level)
// frame.
///
/*--cef()--*/
virtual property IFrame^ Parent
{
IFrame^ get();
}
///
// Returns the URL currently loaded in this frame.
///
/*--cef()--*/
virtual property String^ Url
{
String^ get();
}
///
// Returns the browser that this frame belongs to.
///
/*--cef()--*/
virtual property IBrowser^ Browser
{
IBrowser^ get();
}
///
// Get the V8 context associated with the frame. This method can only be
// called from the render process.
///
/*--cef()--*/
virtual CefRefPtr<CefV8Context> GetV8Context()
{
return _frame->GetV8Context();
}
virtual IRequest^ CreateRequest(bool initializePostData);
///
// Create a new URL request that will be treated as originating from this
// frame and the associated browser. This request may be intercepted by the
// client via CefResourceRequestHandler or CefSchemeHandlerFactory. Use
// CefURLRequest::Create instead if you do not want the request to have this
// association, in which case it may be handled differently (see documentation
// on that method). Requests may originate from both the browser process and
// the render process.
//
// For requests originating from the browser process:
// - POST data may only contain a single element of type PDE_TYPE_FILE or
// PDE_TYPE_BYTES.
// For requests originating from the render process:
// - POST data may only contain a single element of type PDE_TYPE_BYTES.
// - If the response contains Content-Disposition or Mime-Type header values
// that would not normally be rendered then the response may receive
// special handling inside the browser (for example, via the file download
// code path instead of the URL request code path).
//
// The |request| object will be marked as read-only after calling this method.
///
/*--cef()--*/
virtual IUrlRequest^ CreateUrlRequest(IRequest^ request, IUrlRequestClient^ client);
void ThrowIfFrameInvalid();
};
}
}

View file

@ -0,0 +1,74 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_download_handler.h"
#include "CefWrapper.h"
using namespace System::IO;
namespace CefSharp
{
namespace Internals
{
private ref class CefGetExtensionResourceCallbackWrapper : public IGetExtensionResourceCallback, public CefWrapper
{
private:
MCefRefPtr<CefGetExtensionResourceCallback> _callback;
public:
CefGetExtensionResourceCallbackWrapper(CefRefPtr<CefGetExtensionResourceCallback> &callback)
: _callback(callback)
{
}
!CefGetExtensionResourceCallbackWrapper()
{
_callback = NULL;
}
~CefGetExtensionResourceCallbackWrapper()
{
this->!CefGetExtensionResourceCallbackWrapper();
_disposed = true;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
virtual void Continue(Stream^ stream)
{
ThrowIfDisposed();
throw gcnew NotImplementedException();
delete this;
}
virtual void Continue(cli::array<Byte>^ data)
{
ThrowIfDisposed();
pin_ptr<Byte> src = &data[0];
auto streamReader = CefStreamReader::CreateForData(static_cast<void*>(src), data->Length);
_callback->Continue(streamReader);
delete this;
}
};
}
}

View file

@ -0,0 +1,222 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_image.h"
#include "CefWrapper.h"
using namespace System::IO;
using namespace CefSharp::Enums;
namespace CefSharp
{
namespace Internals
{
private ref class CefImageWrapper : public IImage, public CefWrapper
{
internal:
MCefRefPtr<CefImage> _image;
CefImageWrapper::CefImageWrapper(CefRefPtr<CefImage> &image)
: _image(image)
{
}
!CefImageWrapper()
{
_image = NULL;
}
~CefImageWrapper()
{
this->!CefImageWrapper();
_disposed = true;
}
public:
/// <summary>
/// Returns the bitmap representation that most closely matches scaleFactor.
/// </summary>
/// <param name="scaleFactor">scale factor</param>
/// <param name="colorType">color type</param>
/// <param name="alphaType">alpha type</param>
/// <param name="pixelWidth">pixel width</param>
/// <param name="pixelHeight">pixel height</param>
/// <returns>A stream represending the bitmap or null.</returns>
virtual cli::array<Byte>^ GetAsBitmap(float scaleFactor, ColorType colorType, AlphaType alphaType, int% pixelWidth, int% pixelHeight)
{
int width;
int height;
auto binary = _image->GetAsBitmap(scaleFactor, (cef_color_type_t)colorType, (cef_alpha_type_t)alphaType, width, height);
if (binary.get())
{
pixelWidth = width;
pixelHeight = height;
auto binarySize = binary->GetSize();
auto buffer = gcnew cli::array<Byte>(binarySize);
pin_ptr<Byte> src = &buffer[0]; // pin pointer to first element in arr
binary->GetData(static_cast<void*>(src), binarySize, 0);
return buffer;
}
return nullptr;
}
/// <summary>
/// Returns the JPEG representation that most closely matches scaleFactor.
/// </summary>
/// <param name="scaleFactor">scale factor</param>
/// <param name="quality">image quality</param>
/// <param name="pixelWidth">pixel width</param>
/// <param name="pixelHeight">pixel height</param>
/// <returns>A stream representing the JPEG or null.</returns>
virtual cli::array<Byte>^ GetAsJPEG(float scaleFactor, int quality, int% pixelWidth, int% pixelHeight)
{
int width;
int height;
auto binary = _image->GetAsJPEG(scaleFactor, quality, width, height);
if (binary.get())
{
pixelWidth = width;
pixelHeight = height;
auto binarySize = binary->GetSize();
auto buffer = gcnew cli::array<Byte>(binarySize);
pin_ptr<Byte> src = &buffer[0]; // pin pointer to first element in arr
binary->GetData(static_cast<void*>(src), binarySize, 0);
return buffer;
}
return nullptr;
}
/// <summary>
/// Returns the PNG representation that most closely matches scaleFactor.
/// </summary>
/// <param name="scaleFactor">scale factor</param>
/// <param name="withTransparency">is the PNG transparent</param>
/// <param name="pixelWidth">pixel width</param>
/// <param name="pixelHeight">pixel height</param>
/// <returns>A stream represending the PNG or null.</returns>
virtual cli::array<Byte>^ GetAsPNG(float scaleFactor, bool withTransparency, int% pixelWidth, int% pixelHeight)
{
int width;
int height;
auto binary = _image->GetAsPNG(scaleFactor, withTransparency, width, height);
if (binary.get())
{
pixelWidth = width;
pixelHeight = height;
auto binarySize = binary->GetSize();
auto buffer = gcnew cli::array<Byte>(binarySize);
pin_ptr<Byte> src = &buffer[0]; // pin pointer to first element in arr
binary->GetData(static_cast<void*>(src), binarySize, 0);
return buffer;
}
return nullptr;
}
/// <summary>
/// Returns information for the representation that most closely matches scaleFactor.
/// </summary>
/// <param name="scaleFactor">scale factor</param>
/// <param name="actualScaleFactor">actual scale factor</param>
/// <param name="pixelWidth">pixel width</param>
/// <param name="pixelHeight">pixel height</param>
/// <returns>return if information found for scale factor</returns>
virtual bool GetRepresentationInfo(float scaleFactor, float% actualScaleFactor, int% pixelWidth, int% pixelHeight)
{
float actualScale;
int width;
int height;
auto success = _image->GetRepresentationInfo(scaleFactor, actualScale, width, height);
actualScaleFactor = actualScale;
pixelWidth = width;
pixelHeight = height;
return success;
}
/// <summary>
/// Returns the image height in density independent pixel(DIP) units.
/// </summary>
virtual property int Height
{
int get() { return _image->GetHeight(); }
}
/// <summary>
/// Returns true if this image contains a representation for scaleFactor.
/// </summary>
/// <param name="scaleFactor"></param>
/// <returns></returns>
virtual bool HasRepresentation(float scaleFactor)
{
return _image->HasRepresentation(scaleFactor);
}
/// <summary>
/// Returns true if this Image is empty.
/// </summary>
/// <returns></returns>
virtual property bool IsEmpty
{
bool get() { return _image->IsEmpty(); }
}
/// <summary>
/// Returns true if this Image and that Image share the same underlying storage.
/// </summary>
/// <param name="that">image to compare</param>
/// <returns>returns true if share same underlying storage</returns>
virtual bool IsSame(IImage^ that)
{
return _image->IsSame(((CefImageWrapper^)that)->_image.get());
}
/// <summary>
/// Removes the representation for scaleFactor.
/// </summary>
/// <param name="scaleFactor"></param>
/// <returns>true for success</returns>
virtual bool RemoveRepresentation(float scaleFactor)
{
return _image->RemoveRepresentation(scaleFactor);
}
/// <summary>
/// Returns the image width in density independent pixel(DIP) units.
/// </summary>
virtual property int Width
{
int get() { return _image->GetWidth(); }
}
};
}
}

View file

@ -0,0 +1,56 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefJSDialogCallbackWrapper : public IJsDialogCallback, public CefWrapper
{
MCefRefPtr<CefJSDialogCallback> _callback;
internal:
CefJSDialogCallbackWrapper(CefRefPtr<CefJSDialogCallback> &callback)
: _callback(callback)
{
}
!CefJSDialogCallbackWrapper()
{
_callback = NULL;
}
~CefJSDialogCallbackWrapper()
{
this->!CefJSDialogCallbackWrapper();
_disposed = true;
}
public:
virtual void Continue(bool success, String^ userInput)
{
ThrowIfDisposed();
_callback->Continue(success, StringUtils::ToNative(userInput));
delete this;
}
virtual void Continue(bool success)
{
ThrowIfDisposed();
_callback->Continue(success, CefString());
delete this;
}
};
}
}

View file

@ -0,0 +1,440 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_menu_model.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefMenuModelWrapper : public IMenuModel, public CefWrapper
{
private:
MCefRefPtr<CefMenuModel> _menu;
public:
CefMenuModelWrapper(CefRefPtr<CefMenuModel> &menu) :
_menu(menu)
{
}
!CefMenuModelWrapper()
{
_menu = NULL;
}
~CefMenuModelWrapper()
{
this->!CefMenuModelWrapper();
_disposed = true;
}
virtual property int Count
{
int get()
{
ThrowIfDisposed();
return _menu->GetCount();
}
}
virtual bool Clear()
{
ThrowIfDisposed();
return _menu->Clear();
}
virtual String^ GetLabelAt(int index)
{
ThrowIfDisposed();
return StringUtils::ToClr(_menu->GetLabelAt(index));
}
virtual CefMenuCommand GetCommandIdAt(int index)
{
ThrowIfDisposed();
return (CefMenuCommand)_menu->GetCommandIdAt(index);
}
virtual bool Remove(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->Remove((int)commandId);
}
virtual bool AddSeparator()
{
ThrowIfDisposed();
return _menu->AddSeparator();
}
virtual bool AddItem(CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
return _menu->AddItem((int)commandId, StringUtils::ToNative(label));
}
virtual bool AddCheckItem(CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
return _menu->AddCheckItem((int)commandId, StringUtils::ToNative(label));
}
virtual bool AddRadioItem(CefMenuCommand commandId, String^ label, int groupId)
{
ThrowIfDisposed();
return _menu->AddRadioItem((int)commandId, StringUtils::ToNative(label), groupId);
}
virtual IMenuModel^ AddSubMenu(CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
auto subMenu = _menu->AddSubMenu((int)commandId, StringUtils::ToNative(label));
if (subMenu.get())
{
return gcnew CefMenuModelWrapper(subMenu);
}
return nullptr;
}
virtual bool InsertSeparatorAt(int index)
{
ThrowIfDisposed();
return _menu->InsertSeparatorAt(index);
}
virtual bool InsertItemAt(int index, CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
return _menu->InsertItemAt(index, (int)commandId, StringUtils::ToNative(label));
}
virtual bool InsertCheckItemAt(int index, CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
return _menu->InsertCheckItemAt(index, (int)commandId, StringUtils::ToNative(label));
}
virtual bool InsertRadioItemAt(int index, CefMenuCommand commandId, String^ label, int groupId)
{
ThrowIfDisposed();
return _menu->InsertRadioItemAt(index, (int)commandId, StringUtils::ToNative(label), groupId);
}
virtual IMenuModel^ InsertSubMenuAt(int index, CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
auto subMenu = _menu->InsertSubMenuAt(index, (int)commandId, StringUtils::ToNative(label));
if (subMenu.get())
{
return gcnew CefMenuModelWrapper(subMenu);
}
return nullptr;
}
virtual bool RemoveAt(int index)
{
ThrowIfDisposed();
return _menu->RemoveAt(index);
}
virtual int GetIndexOf(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->GetIndexOf((int)commandId);
}
virtual bool SetCommandIdAt(int index, CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->SetCommandIdAt(index, (int)commandId);
}
virtual String^ GetLabel(CefMenuCommand commandId)
{
ThrowIfDisposed();
return StringUtils::ToClr(_menu->GetLabel((int)commandId));
}
virtual bool SetLabel(CefMenuCommand commandId, String^ label)
{
ThrowIfDisposed();
return _menu->SetLabel((int)commandId, StringUtils::ToNative(label));
}
virtual bool SetLabelAt(int index, String^ label)
{
ThrowIfDisposed();
return _menu->SetLabelAt(index, StringUtils::ToNative(label));
}
virtual MenuItemType GetType(CefMenuCommand commandId)
{
ThrowIfDisposed();
return (CefSharp::MenuItemType)_menu->GetType((int)commandId);
}
virtual MenuItemType GetTypeAt(int index)
{
ThrowIfDisposed();
return (MenuItemType)_menu->GetTypeAt(index);
}
virtual int GetGroupId(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->GetGroupId((int)commandId);
}
virtual int GetGroupIdAt(int index)
{
ThrowIfDisposed();
return _menu->GetGroupIdAt(index);
}
virtual bool SetGroupId(CefMenuCommand commandId, int groupId)
{
ThrowIfDisposed();
return _menu->SetGroupId((int)commandId, groupId);
}
virtual bool SetGroupIdAt(int index, int groupId)
{
ThrowIfDisposed();
return _menu->SetGroupIdAt(index, groupId);
}
virtual IMenuModel^ GetSubMenu(CefMenuCommand commandId)
{
ThrowIfDisposed();
auto subMenu = _menu->GetSubMenu((int)commandId);
if (subMenu.get())
{
return gcnew CefMenuModelWrapper(subMenu);
}
return nullptr;
}
virtual IMenuModel^ GetSubMenuAt(int index)
{
ThrowIfDisposed();
auto subMenu = _menu->GetSubMenuAt(index);
if (subMenu.get())
{
return gcnew CefMenuModelWrapper(subMenu);
}
return nullptr;
}
virtual bool IsVisible(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->IsVisible((int)commandId);
}
virtual bool IsVisibleAt(int index)
{
ThrowIfDisposed();
return _menu->IsVisibleAt(index);
}
virtual bool SetVisible(CefMenuCommand commandId, bool visible)
{
ThrowIfDisposed();
return _menu->SetVisible((int)commandId, visible);
}
virtual bool SetVisibleAt(int index, bool visible)
{
ThrowIfDisposed();
return _menu->SetVisibleAt(index, visible);
}
virtual bool IsEnabled(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->IsEnabled((int)commandId);
}
virtual bool IsEnabledAt(int index)
{
ThrowIfDisposed();
return _menu->IsEnabledAt(index);
}
virtual bool SetEnabled(CefMenuCommand commandId, bool enabled)
{
ThrowIfDisposed();
return _menu->SetEnabled((int)commandId, enabled);
}
virtual bool SetEnabledAt(int index, bool enabled)
{
ThrowIfDisposed();
return _menu->SetEnabledAt(index, enabled);
}
virtual bool IsChecked(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->IsChecked((int)commandId);
}
virtual bool IsCheckedAt(int index)
{
ThrowIfDisposed();
return _menu->IsCheckedAt(index);
}
virtual bool SetChecked(CefMenuCommand commandId, bool isChecked)
{
ThrowIfDisposed();
return _menu->SetChecked((int)commandId, isChecked);
}
virtual bool SetCheckedAt(int index, bool isChecked)
{
ThrowIfDisposed();
return _menu->SetCheckedAt(index, isChecked);
}
virtual bool HasAccelerator(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->HasAccelerator((int)commandId);
}
virtual bool HasAcceleratorAt(int index)
{
ThrowIfDisposed();
return _menu->HasAcceleratorAt(index);
}
virtual bool SetAccelerator(CefMenuCommand commandId, int keyCode, bool shiftPressed, bool ctrlPressed, bool altPressed)
{
ThrowIfDisposed();
return _menu->SetAccelerator((int)commandId, keyCode, shiftPressed, ctrlPressed, altPressed);
}
virtual bool SetAcceleratorAt(int index, int keyCode, bool shiftPressed, bool ctrlPressed, bool altPressed)
{
ThrowIfDisposed();
return _menu->SetAcceleratorAt(index, keyCode, shiftPressed, ctrlPressed, altPressed);
}
virtual bool RemoveAccelerator(CefMenuCommand commandId)
{
ThrowIfDisposed();
return _menu->RemoveAccelerator((int)commandId);
}
virtual bool RemoveAcceleratorAt(int index)
{
ThrowIfDisposed();
return _menu->RemoveAcceleratorAt(index);
}
virtual bool GetAccelerator(CefMenuCommand commandId, int% keyCode, bool% shiftPressed, bool% ctrlPressed, bool% altPressed)
{
ThrowIfDisposed();
int key;
bool shift;
bool ctrl;
bool alt;
auto result = _menu->GetAccelerator((int)commandId, key, shift, ctrl, alt);
keyCode = key;
shiftPressed = shift;
ctrlPressed = ctrl;
altPressed = alt;
return result;
}
virtual bool GetAcceleratorAt(int index, int% keyCode, bool% shiftPressed, bool% ctrlPressed, bool% altPressed)
{
ThrowIfDisposed();
int key;
bool shift;
bool ctrl;
bool alt;
auto result = _menu->GetAcceleratorAt(index, key, shift, ctrl, alt);
keyCode = key;
shiftPressed = shift;
ctrlPressed = ctrl;
altPressed = alt;
return result;
}
};
}
}

View file

@ -0,0 +1,45 @@
// Copyright © 2016 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_browser.h"
namespace CefSharp
{
namespace Internals
{
private class CefNavigationEntryVisitorAdapter : public CefNavigationEntryVisitor
{
private:
gcroot<INavigationEntryVisitor^> _handler;
public:
CefNavigationEntryVisitorAdapter(INavigationEntryVisitor^ handler)
{
_handler = handler;
}
~CefNavigationEntryVisitorAdapter()
{
delete _handler;
_handler = nullptr;
}
bool Visit(CefRefPtr<CefNavigationEntry> entry,
bool current,
int index,
int total) OVERRIDE
{
auto navEntry = TypeConversion::FromNative(entry, current);
return _handler->Visit(navEntry, current, index, total);
}
IMPLEMENT_REFCOUNTING(CefNavigationEntryVisitorAdapter);
};
}
}

View file

@ -0,0 +1,43 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_browser.h"
namespace CefSharp
{
namespace Internals
{
private class CefPdfPrintCallbackWrapper : public CefPdfPrintCallback
{
private:
gcroot<IPrintToPdfCallback^> _callback;
public:
CefPdfPrintCallbackWrapper(IPrintToPdfCallback^ callback)
:_callback(callback)
{
}
~CefPdfPrintCallbackWrapper()
{
delete _callback;
_callback = nullptr;
}
virtual void OnPdfPrintFinished(const CefString& path, bool ok) OVERRIDE
{
if (static_cast<IPrintToPdfCallback^>(_callback) != nullptr)
{
_callback->OnPdfPrintFinished(StringUtils::ToClr(path), ok);
}
}
IMPLEMENT_REFCOUNTING(CefPdfPrintCallbackWrapper);
};
}
}

View file

@ -0,0 +1,48 @@
// Copyright © 2017 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private class CefRegisterCdmCallbackAdapter : public CefRegisterCdmCallback
{
private:
gcroot<IRegisterCdmCallback^> _callback;
public:
CefRegisterCdmCallbackAdapter(IRegisterCdmCallback^ callback)
{
_callback = callback;
}
~CefRegisterCdmCallbackAdapter()
{
delete _callback;
_callback = nullptr;
}
/// <summary>
/// Method that will be called when CDM registration is complete. |result|
/// will be CEF_CDM_REGISTRATION_ERROR_NONE if registration completed
/// successfully. Otherwise, |result| and |error_message| will contain
/// additional information about why registration failed.
/// </summary>
virtual void OnCdmRegistrationComplete(cef_cdm_registration_error_t result,
const CefString& error_message) OVERRIDE
{
auto r = gcnew CdmRegistration((CdmRegistrationErrorCode)result, StringUtils::ToClr(error_message));
_callback->OnRegistrationComplete(r);
}
IMPLEMENT_REFCOUNTING(CefRegisterCdmCallbackAdapter);
};
}
}

View file

@ -0,0 +1,41 @@
// Copyright © 2020 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_registration.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefRegistrationWrapper : public IRegistration, public CefWrapper
{
private:
MCefRefPtr<CefRegistration> _callback;
public:
CefRegistrationWrapper(CefRefPtr<CefRegistration> &callback)
: _callback(callback)
{
}
!CefRegistrationWrapper()
{
_callback = NULL;
}
~CefRegistrationWrapper()
{
this->!CefRegistrationWrapper();
_disposed = true;
}
};
}
}

View file

@ -0,0 +1,71 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefRequestCallbackWrapper : public IRequestCallback, public CefWrapper
{
private:
MCefRefPtr<CefRequestCallback> _callback;
IFrame^ _frame;
IRequest^ _request;
internal:
CefRequestCallbackWrapper(CefRefPtr<CefRequestCallback> &callback)
: _callback(callback), _frame(nullptr), _request(nullptr)
{
}
CefRequestCallbackWrapper(
CefRefPtr<CefRequestCallback> &callback,
IFrame^ frame,
IRequest^ request)
: _callback(callback), _frame(frame), _request(request)
{
}
!CefRequestCallbackWrapper()
{
_callback = NULL;
}
~CefRequestCallbackWrapper()
{
this->!CefRequestCallbackWrapper();
delete _request;
_request = nullptr;
delete _frame;
_frame = nullptr;
_disposed = true;
}
public:
virtual void Continue(bool allow)
{
ThrowIfDisposed();
_callback->Continue(allow);
delete this;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
};
}
}

View file

@ -0,0 +1,91 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CefRequestContextHandlerAdapter.h"
#include "CookieManager.h"
#include "Request.h"
#include "RequestContext.h"
#include "Internals\ReportUnhandledExceptions.h"
#include "Internals\TypeConversion.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\CefFrameWrapper.h"
#include "Internals\CefResourceRequestHandlerAdapter.h"
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
bool CefRequestContextHandlerAdapter::OnBeforePluginLoad(const CefString& mime_type,
const CefString& plugin_url,
bool is_main_frame,
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
CefRequestContextHandler::PluginPolicy* plugin_policy)
{
if (Object::ReferenceEquals(_requestContextHandler, nullptr))
{
return false;
}
auto pluginInfo = TypeConversion::FromNative(plugin_info);
auto pluginPolicy = (CefSharp::PluginPolicy)*plugin_policy;
auto result = _requestContextHandler->OnBeforePluginLoad(StringUtils::ToClr(mime_type),
StringUtils::ToClr(plugin_url),
is_main_frame,
StringUtils::ToClr(top_origin_url),
pluginInfo,
pluginPolicy);
*plugin_policy = (CefRequestContextHandler::PluginPolicy)pluginPolicy;
return result;
}
void CefRequestContextHandlerAdapter::OnRequestContextInitialized(CefRefPtr<CefRequestContext> requestContext)
{
if (!Object::ReferenceEquals(_requestContextHandler, nullptr))
{
RequestContext ctx(requestContext);
_requestContextHandler->OnRequestContextInitialized(%ctx);
}
}
CefRefPtr<CefResourceRequestHandler> CefRequestContextHandlerAdapter::GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling)
{
if (Object::ReferenceEquals(_requestContextHandler, nullptr))
{
return NULL;
}
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
Request requestWrapper(request);
auto handler = _requestContextHandler->GetResourceRequestHandler(%browserWrapper, %frameWrapper, %requestWrapper, is_navigation, is_download, StringUtils::ToClr(request_initiator), disable_default_handling);
if (Object::ReferenceEquals(handler, nullptr))
{
return NULL;
}
//CefRequestContext is not associated with a specific browser
//so browserControl param is always nullptr.
return new CefResourceRequestHandlerAdapter(nullptr, handler);
}
}
}

View file

@ -0,0 +1,56 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEFSHARP_CORE_INTERNALS_CEFREQUESTCONTEXTHANDLERADAPTER_H_
#define CEFSHARP_CORE_INTERNALS_CEFREQUESTCONTEXTHANDLERADAPTER_H_
#pragma once
#include "Stdafx.h"
#include "include\cef_request_context.h"
#include "include\cef_request_context_handler.h"
namespace CefSharp
{
namespace Internals
{
private class CefRequestContextHandlerAdapter : public CefRequestContextHandler
{
gcroot<IRequestContextHandler^> _requestContextHandler;
public:
CefRequestContextHandlerAdapter(IRequestContextHandler^ requestContextHandler)
: _requestContextHandler(requestContextHandler)
{
}
~CefRequestContextHandlerAdapter()
{
_requestContextHandler = nullptr;
}
virtual bool OnBeforePluginLoad(const CefString& mime_type,
const CefString& plugin_url,
bool is_main_frame,
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
CefRequestContextHandler::PluginPolicy* plugin_policy) OVERRIDE;
virtual void OnRequestContextInitialized(CefRefPtr<CefRequestContext> requestContext) OVERRIDE;
virtual CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
bool is_navigation,
bool is_download,
const CefString& request_initiator,
bool& disable_default_handling) OVERRIDE;
IMPLEMENT_REFCOUNTING(CefRequestContextHandlerAdapter);
};
}
}
#endif // CEFSHARP_CORE_INTERNALS_CEFREQUESTCONTEXTHANDLERADAPTER_H_

View file

@ -0,0 +1,39 @@
// Copyright © 2016 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_request_context.h"
namespace CefSharp
{
namespace Internals
{
private class CefResolveCallbackAdapter : public CefResolveCallback
{
private:
gcroot<IResolveCallback^> _handler;
public:
CefResolveCallbackAdapter(IResolveCallback^ handler)
{
_handler = handler;
}
~CefResolveCallbackAdapter()
{
delete _handler;
_handler = nullptr;
}
void OnResolveCompleted(cef_errorcode_t result, const std::vector<CefString>& resolvedIps) OVERRIDE
{
_handler->OnResolveCompleted((CefErrorCode)result, StringUtils::ToClr(resolvedIps));
}
IMPLEMENT_REFCOUNTING(CefResolveCallbackAdapter);
};
}
}

View file

@ -0,0 +1,83 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "Request.h"
#include "CefResourceHandlerAdapter.h"
#include "Internals/CefResponseWrapper.h"
#include "Internals/CefCallbackWrapper.h"
#include "Internals/CefResourceReadCallbackWrapper.h"
#include "Internals/CefResourceSkipCallbackWrapper.h"
#include "Internals/TypeConversion.h"
using namespace System::Runtime::InteropServices;
using namespace System::IO;
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
bool CefResourceHandlerAdapter::Open(CefRefPtr<CefRequest> request, bool& handleRequest, CefRefPtr<CefCallback> callback)
{
auto callbackWrapper = gcnew CefCallbackWrapper(callback);
_request = gcnew Request(request);
return _handler->Open(_request, handleRequest, callbackWrapper);
}
void CefResourceHandlerAdapter::GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl)
{
String^ newRedirectUrl;
CefResponseWrapper responseWrapper(response);
_handler->GetResponseHeaders(% responseWrapper, response_length, newRedirectUrl);
redirectUrl = StringUtils::ToNative(newRedirectUrl);
}
bool CefResourceHandlerAdapter::Skip(int64 bytesToSkip, int64& bytesSkipped, CefRefPtr<CefResourceSkipCallback> callback)
{
auto callbackWrapper = gcnew CefResourceSkipCallbackWrapper(callback);
return _handler->Skip(bytesToSkip, bytesSkipped, callbackWrapper);
}
bool CefResourceHandlerAdapter::Read(void* dataOut, int bytesToRead, int& bytesRead, CefRefPtr<CefResourceReadCallback> callback)
{
auto writeStream = gcnew UnmanagedMemoryStream((Byte*)dataOut, (Int64)bytesToRead, (Int64)bytesToRead, FileAccess::Write);
auto callbackWrapper = gcnew CefResourceReadCallbackWrapper(callback);
return _handler->Read(writeStream, bytesRead, callbackWrapper);
}
void CefResourceHandlerAdapter::Cancel()
{
_handler->Cancel();
delete _request;
_request = nullptr;
}
//Deprecated
bool CefResourceHandlerAdapter::ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback)
{
auto callbackWrapper = gcnew CefCallbackWrapper(callback);
_request = gcnew Request(request);
return _handler->ProcessRequest(_request, callbackWrapper);
}
bool CefResourceHandlerAdapter::ReadResponse(void* dataOut, int bytesToRead, int& bytesRead, CefRefPtr<CefCallback> callback)
{
auto writeStream = gcnew UnmanagedMemoryStream((Byte*)dataOut, (Int64)bytesToRead, (Int64)bytesToRead, FileAccess::Write);
auto callbackWrapper = gcnew CefCallbackWrapper(callback);
return _handler->ReadResponse(writeStream, bytesRead, callbackWrapper);
}
}
}

View file

@ -0,0 +1,50 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_scheme.h"
using namespace System::IO;
using namespace System::Collections::Specialized;
namespace CefSharp
{
namespace Internals
{
private class CefResourceHandlerAdapter : public CefResourceHandler
{
private:
gcroot<IResourceHandler^> _handler;
gcroot<IRequest^> _request;
public:
CefResourceHandlerAdapter(IResourceHandler^ handler)
: _handler(handler)
{
}
~CefResourceHandlerAdapter()
{
delete _handler;
_handler = nullptr;
delete _request;
_request = nullptr;
}
virtual bool Open(CefRefPtr<CefRequest> request, bool& handle_request, CefRefPtr<CefCallback> callback) OVERRIDE;
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl) OVERRIDE;
virtual bool Skip(int64 bytesToSkip, int64& bytesSkipped, CefRefPtr<CefResourceSkipCallback> callback) OVERRIDE;
virtual bool Read(void* dataOut, int bytesToRead, int& bytesRead, CefRefPtr<CefResourceReadCallback> callback) OVERRIDE;
virtual void Cancel() OVERRIDE;
//Depricated
virtual bool ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefCallback> callback) OVERRIDE;
virtual bool ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr<CefCallback> callback) OVERRIDE;
IMPLEMENT_REFCOUNTING(CefResourceHandlerAdapter);
};
}
}

View file

@ -0,0 +1,52 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_resource_handler.h"
#include "CefWrapper.h"
using namespace CefSharp::Callback;
namespace CefSharp
{
namespace Internals
{
private ref class CefResourceReadCallbackWrapper : public IResourceReadCallback, public CefWrapper
{
private:
MCefRefPtr<CefResourceReadCallback> _callback;
public:
CefResourceReadCallbackWrapper(CefRefPtr<CefResourceReadCallback> &callback) :
_callback(callback)
{
}
!CefResourceReadCallbackWrapper()
{
_callback = NULL;
}
~CefResourceReadCallbackWrapper()
{
this->!CefResourceReadCallbackWrapper();
_disposed = true;
}
virtual void Continue(int bytesRead)
{
ThrowIfDisposed();
_callback->Continue(bytesRead);
delete this;
}
};
}
}

View file

@ -0,0 +1,263 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_resource_request_handler.h"
#include "include\wrapper\cef_stream_resource_handler.h"
#include "CefResponseWrapper.h"
#include "Request.h"
#include "CefFrameWrapper.h"
#include "CefBrowserWrapper.h"
#include "CefResourceHandlerAdapter.h"
#include "CefResponseFilterAdapter.h"
#include "CefRequestCallbackWrapper.h"
#include "CefCookieAccessFilterAdapter.h"
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
//TODO: NetworkService - Code duplication should be improved
//going with the simplest and easiest option now
private class CefResourceRequestHandlerAdapter : public CefResourceRequestHandler
{
private:
gcroot<IResourceRequestHandler^> _handler;
gcroot<IWebBrowser^> _browserControl;
public:
CefResourceRequestHandlerAdapter(IWebBrowser^ browserControl, IResourceRequestHandler^ handler) :
_handler(handler), _browserControl(browserControl)
{
}
~CefResourceRequestHandlerAdapter()
{
delete _handler;
_handler = nullptr;
}
CefRefPtr<CefCookieAccessFilter> GetCookieAccessFilter(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request) OVERRIDE
{
ICookieAccessFilter^ accessFilter;
Request requestWrapper(request);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
accessFilter = _handler->GetCookieAccessFilter(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper);
}
else
{
accessFilter = _handler->GetCookieAccessFilter(_browserControl, nullptr, nullptr, %requestWrapper);
}
if (accessFilter == nullptr)
{
return NULL;
}
return new CefCookieAccessFilterAdapter(accessFilter, _browserControl);
}
cef_return_value_t OnBeforeResourceLoad(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefRequestCallback> callback) OVERRIDE
{
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
//TODO: We previously used GetBrowserWrapper - investigate passing in reference to this adapter
CefBrowserWrapper browserWrapper(browser);
//We pass the frame and request wrappers to CefRequestCallbackWrapper so they can be disposed of
//when the callback is executed
auto frameWrapper = gcnew CefFrameWrapper(frame);
auto requestWrapper = gcnew Request(request);
auto requestCallback = gcnew CefRequestCallbackWrapper(callback, frameWrapper, requestWrapper);
return (cef_return_value_t)_handler->OnBeforeResourceLoad(_browserControl, %browserWrapper, frameWrapper, requestWrapper, requestCallback);
}
auto requestWrapper = gcnew Request(request);
auto requestCallback = gcnew CefRequestCallbackWrapper(callback, nullptr, requestWrapper);
return (cef_return_value_t)_handler->OnBeforeResourceLoad(_browserControl, nullptr, nullptr, requestWrapper, requestCallback);
}
CefRefPtr<CefResourceHandler> GetResourceHandler(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request) OVERRIDE
{
IResourceHandler^ resourceHandler;
Request requestWrapper(request);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
resourceHandler = _handler->GetResourceHandler(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper);
}
else
{
resourceHandler = _handler->GetResourceHandler(_browserControl, nullptr, nullptr, %requestWrapper);
}
if (resourceHandler == nullptr)
{
return NULL;
}
if (resourceHandler->GetType() == FileResourceHandler::typeid)
{
auto fileResourceHandler = static_cast<FileResourceHandler^>(resourceHandler);
auto streamReader = CefStreamReader::CreateForFile(StringUtils::ToNative(fileResourceHandler->FilePath));
if (streamReader.get())
{
return new CefStreamResourceHandler(StringUtils::ToNative(fileResourceHandler->MimeType), streamReader);
}
else
{
auto msg = "Unable to load resource CefStreamReader::CreateForFile returned NULL for file:" + fileResourceHandler->FilePath;
LOG(ERROR) << StringUtils::ToNative(msg).ToString();
return NULL;
}
}
else if (resourceHandler->GetType() == ByteArrayResourceHandler::typeid)
{
auto byteArrayResourceHandler = static_cast<ByteArrayResourceHandler^>(resourceHandler);
//NOTE: Prefix with cli:: namespace as VS2015 gets confused with std::array
cli::array<Byte>^ buffer = byteArrayResourceHandler->Data;
pin_ptr<Byte> src = &buffer[0];
auto streamReader = CefStreamReader::CreateForData(static_cast<void*>(src), buffer->Length);
return new CefStreamResourceHandler(StringUtils::ToNative(byteArrayResourceHandler->MimeType), streamReader);
}
return new CefResourceHandlerAdapter(resourceHandler);
}
void OnResourceRedirect(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response, CefString& newUrl) OVERRIDE
{
auto managedNewUrl = StringUtils::ToClr(newUrl);
Request requestWrapper(request);
CefResponseWrapper responseWrapper(response);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
_handler->OnResourceRedirect(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, %responseWrapper, managedNewUrl);
}
else
{
_handler->OnResourceRedirect(_browserControl, nullptr, nullptr, %requestWrapper, %responseWrapper, managedNewUrl);
}
newUrl = StringUtils::ToNative(managedNewUrl);
}
bool OnResourceResponse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response) OVERRIDE
{
Request requestWrapper(request);
CefResponseWrapper responseWrapper(response);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
return _handler->OnResourceResponse(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, %responseWrapper);
}
return _handler->OnResourceResponse(_browserControl, nullptr, nullptr, %requestWrapper, %responseWrapper);
}
CefRefPtr<CefResponseFilter> GetResourceResponseFilter(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response) OVERRIDE
{
IResponseFilter^ responseFilter;
Request requestWrapper(request);
CefResponseWrapper responseWrapper(response);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
responseFilter = _handler->GetResourceResponseFilter(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, %responseWrapper);
}
else
{
responseFilter = _handler->GetResourceResponseFilter(_browserControl, nullptr, nullptr, %requestWrapper, %responseWrapper);
}
if (responseFilter == nullptr)
{
return NULL;
}
return new CefResponseFilterAdapter(responseFilter);
}
void OnResourceLoadComplete(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, CefRefPtr<CefResponse> response, URLRequestStatus status, int64 receivedContentLength) OVERRIDE
{
Request requestWrapper(request);
CefResponseWrapper responseWrapper(response);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
_handler->OnResourceLoadComplete(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper, %responseWrapper, (UrlRequestStatus)status, receivedContentLength);
}
else
{
_handler->OnResourceLoadComplete(_browserControl, nullptr, nullptr, %requestWrapper, %responseWrapper, (UrlRequestStatus)status, receivedContentLength);
}
}
void OnProtocolExecution(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool& allowOSExecution) OVERRIDE
{
Request requestWrapper(request);
//For ServiceWorker browser and frame will be null
if (browser.get() && frame.get())
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
allowOSExecution = _handler->OnProtocolExecution(_browserControl, %browserWrapper, %frameWrapper, %requestWrapper);
}
else
{
allowOSExecution = _handler->OnProtocolExecution(_browserControl, nullptr, nullptr, %requestWrapper);
}
}
IMPLEMENT_REFCOUNTING(CefResourceRequestHandlerAdapter);
};
}
}

View file

@ -0,0 +1,52 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_resource_handler.h"
#include "CefWrapper.h"
using namespace CefSharp::Callback;
namespace CefSharp
{
namespace Internals
{
private ref class CefResourceSkipCallbackWrapper : public IResourceSkipCallback, public CefWrapper
{
private:
MCefRefPtr<CefResourceSkipCallback> _callback;
public:
CefResourceSkipCallbackWrapper(CefRefPtr<CefResourceSkipCallback> &callback) :
_callback(callback)
{
}
!CefResourceSkipCallbackWrapper()
{
_callback = NULL;
}
~CefResourceSkipCallbackWrapper()
{
this->!CefResourceSkipCallbackWrapper();
_disposed = true;
}
virtual void Continue(Int64 bytesSkipped)
{
ThrowIfDisposed();
_callback->Continue(bytesSkipped);
delete this;
}
};
}
}

View file

@ -0,0 +1,85 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_response_filter.h"
using namespace System::IO;
namespace CefSharp
{
namespace Internals
{
private class CefResponseFilterAdapter : public CefResponseFilter
{
private:
gcroot<IResponseFilter^> _filter;
public:
CefResponseFilterAdapter(IResponseFilter^ filter) :
_filter(filter)
{
}
~CefResponseFilterAdapter()
{
delete _filter;
_filter = nullptr;
}
virtual bool InitFilter() OVERRIDE
{
return _filter->InitFilter();
}
// Called to filter a chunk of data. |data_in| is the input buffer containing
// |data_in_size| bytes of pre-filter data (|data_in| will be NULL if
// |data_in_size| is zero). |data_out| is the output buffer that can accept up
// to |data_out_size| bytes of filtered output data. Set |data_in_read| to the
// number of bytes that were read from |data_in|. Set |data_out_written| to
// the number of bytes that were written into |data_out|. If some or all of
// the pre-filter data was read successfully but more data is needed in order
// to continue filtering (filtered output is pending) return
// RESPONSE_FILTER_NEED_MORE_DATA. If some or all of the pre-filter data was
// read successfully and all available filtered output has been written return
// RESPONSE_FILTER_DONE. If an error occurs during filtering return
// RESPONSE_FILTER_ERROR. This method will be called repeatedly until there is
// no more data to filter (resource response is complete), |data_in_read|
// matches |data_in_size| (all available pre-filter bytes have been read), and
// the method returns RESPONSE_FILTER_DONE or RESPONSE_FILTER_ERROR. Do not
// keep a reference to the buffers passed to this method.
/*--cef(optional_param=data_in,default_retval=RESPONSE_FILTER_ERROR)--*/
virtual FilterStatus Filter(void* dataIn, size_t dataInSize, size_t& dataInRead, void* dataOut, size_t dataOutSize, size_t& dataOutWritten) OVERRIDE
{
Int64 dataInReadPtr = 0;
Int64 dataOutWrittenPtr = 0;
CefSharp::FilterStatus status;
UnmanagedMemoryStream writeStream((Byte*)dataOut, (Int64)dataOutSize, (Int64)dataOutSize, FileAccess::Write);
if (dataInSize > 0)
{
UnmanagedMemoryStream readStream((Byte*)dataIn, (Int64)dataInSize, (Int64)dataInSize, FileAccess::Read);
status = _filter->Filter(%readStream, dataInReadPtr, %writeStream, dataOutWrittenPtr);
}
else
{
status = _filter->Filter(nullptr, dataInReadPtr, %writeStream, dataOutWrittenPtr);
}
dataInRead = dataInReadPtr;
dataOutWritten = dataOutWrittenPtr;
return (FilterStatus)status;
}
IMPLEMENT_REFCOUNTING(CefResponseFilterAdapter);
};
}
}

View file

@ -0,0 +1,207 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "TypeConversion.h"
#include "CefWrapper.h"
using namespace System::Collections::Specialized;
namespace CefSharp
{
namespace Internals
{
private ref class CefResponseWrapper : public IResponse, public CefWrapper
{
MCefRefPtr<CefResponse> _response;
internal:
CefResponseWrapper(CefRefPtr<CefResponse> &response) :
_response(response)
{
}
!CefResponseWrapper()
{
_response = nullptr;
}
~CefResponseWrapper()
{
this->!CefResponseWrapper();
_disposed = true;
}
public:
virtual property String^ Charset
{
String^ get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_response->GetCharset());
}
void set(String^ val)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetCharset(StringUtils::ToNative(val));
}
}
virtual property bool IsReadOnly
{
bool get()
{
ThrowIfDisposed();
return _response->IsReadOnly();
}
}
virtual property CefErrorCode ErrorCode
{
CefErrorCode get()
{
ThrowIfDisposed();
return (CefErrorCode)_response->GetError();
}
void set(CefErrorCode val)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetError((cef_errorcode_t)val);
}
}
virtual property int StatusCode
{
int get()
{
ThrowIfDisposed();
return _response->GetStatus();
}
void set(int val)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetStatus(val);
}
}
virtual property String^ StatusText
{
String^ get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_response->GetStatusText());
}
void set(String^ val)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetStatusText(StringUtils::ToNative(val));
}
}
virtual property String^ MimeType
{
String^ get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_response->GetMimeType());
}
void set(String^ val)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetMimeType(StringUtils::ToNative(val));
}
}
virtual property NameValueCollection^ Headers
{
NameValueCollection^ get()
{
ThrowIfDisposed();
//TODO: Extract this code out as it's duplicated in CefRequestWrapper
CefRequest::HeaderMap hm;
_response->GetHeaderMap(hm);
auto headers = gcnew HeaderNameValueCollection();
for (CefRequest::HeaderMap::iterator it = hm.begin(); it != hm.end(); ++it)
{
String^ name = StringUtils::ToClr(it->first);
String^ value = StringUtils::ToClr(it->second);
headers->Add(name, value);
}
if (_response->IsReadOnly())
{
headers->SetReadOnly();
}
return headers;
}
void set(NameValueCollection^ headers)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetHeaderMap(TypeConversion::ToNative(headers));
}
}
virtual property NameValueCollection^ ResponseHeaders
{
NameValueCollection^ get()
{
return Headers;
}
void set(NameValueCollection^ headers)
{
Headers = headers;
}
}
virtual String^ GetHeaderByName(String^ name)
{
ThrowIfDisposed();
return StringUtils::ToClr(_response->GetHeaderByName(StringUtils::ToNative(name)));
}
virtual void SetHeaderByName(String^ name, String^ value, bool overwrite)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_response->SetHeaderByName(StringUtils::ToNative(name), StringUtils::ToNative(value), overwrite);
}
void ThrowIfReadOnly()
{
if (_response->IsReadOnly())
{
throw gcnew NotSupportedException("IResponse is read-only and cannot be modified. Check IResponse.IsReadOnly to guard against this exception.");
}
}
};
}
}

View file

@ -0,0 +1,59 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_context_menu_handler.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefRunContextMenuCallbackWrapper : public IRunContextMenuCallback, public CefWrapper
{
private:
MCefRefPtr< CefRunContextMenuCallback> _callback;
public:
CefRunContextMenuCallbackWrapper(CefRefPtr< CefRunContextMenuCallback> &callback) :
_callback(callback)
{
}
!CefRunContextMenuCallbackWrapper()
{
_callback = NULL;
}
~CefRunContextMenuCallbackWrapper()
{
this->!CefRunContextMenuCallbackWrapper();
_disposed = true;
}
virtual void Cancel()
{
ThrowIfDisposed();
_callback->Cancel();
delete this;
}
virtual void Continue(CefMenuCommand commandId, CefEventFlags eventFlags)
{
ThrowIfDisposed();
_callback->Continue((int)commandId, (CefRunContextMenuCallback::EventFlags) eventFlags);
delete this;
}
};
}
}

View file

@ -0,0 +1,45 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_browser.h"
namespace CefSharp
{
namespace Internals
{
private class CefRunFileDialogCallbackAdapter : public CefRunFileDialogCallback
{
private:
gcroot<IRunFileDialogCallback^> _callback;
public:
CefRunFileDialogCallbackAdapter(IRunFileDialogCallback^ callback) :
_callback(callback)
{
}
~CefRunFileDialogCallbackAdapter()
{
delete _callback;
_callback = nullptr;
}
virtual void OnFileDialogDismissed(int selectedAcceptFilter, const std::vector<CefString>& filePaths) OVERRIDE
{
if (static_cast<IRunFileDialogCallback^>(_callback) != nullptr)
{
_callback->OnFileDialogDismissed(selectedAcceptFilter, StringUtils::ToClr(filePaths));
}
}
IMPLEMENT_REFCOUNTING(CefRunFileDialogCallbackAdapter);
};
}
}

View file

@ -0,0 +1,90 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_scheme.h"
#include "include\wrapper\cef_stream_resource_handler.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\CefFrameWrapper.h"
#include "Request.h"
#include "CefResourceHandlerAdapter.h"
using namespace System::IO;
using namespace System::Collections::Specialized;
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
private class CefSchemeHandlerFactoryAdapter : public CefSchemeHandlerFactory
{
gcroot<ISchemeHandlerFactory^> _factory;
public:
CefSchemeHandlerFactoryAdapter(ISchemeHandlerFactory^ factory)
: _factory(factory)
{
}
~CefSchemeHandlerFactoryAdapter()
{
_factory = nullptr;
}
virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& schemeName, CefRefPtr<CefRequest> request) OVERRIDE
{
CefBrowserWrapper browserWrapper(browser);
CefFrameWrapper frameWrapper(frame);
Request requestWrapper(request);
auto handler = _factory->Create(%browserWrapper, %frameWrapper, StringUtils::ToClr(schemeName), %requestWrapper);
if (handler == nullptr)
{
return NULL;
}
if (handler->GetType() == FileResourceHandler::typeid)
{
auto resourceHandler = static_cast<FileResourceHandler^>(handler);
auto streamReader = CefStreamReader::CreateForFile(StringUtils::ToNative(resourceHandler->FilePath));
if (streamReader.get())
{
return new CefStreamResourceHandler(StringUtils::ToNative(resourceHandler->MimeType), streamReader);
}
else
{
auto msg = "Unable to load resource CefStreamReader::CreateForFile returned NULL for file:" + resourceHandler->FilePath;
LOG(ERROR) << StringUtils::ToNative(msg).ToString();
return NULL;
}
}
else if (handler->GetType() == ByteArrayResourceHandler::typeid)
{
auto resourceHandler = static_cast<ByteArrayResourceHandler^>(handler);
//NOTE: Prefix with cli:: namespace as VS2015 gets confused with std::array
cli::array<Byte>^ buffer = resourceHandler->Data;
pin_ptr<Byte> src = &buffer[0];
auto streamReader = CefStreamReader::CreateForData(static_cast<void*>(src), buffer->Length);
return new CefStreamResourceHandler(StringUtils::ToNative(resourceHandler->MimeType), streamReader);
}
return new CefResourceHandlerAdapter(handler);
}
IMPLEMENT_REFCOUNTING(CefSchemeHandlerFactoryAdapter);
};
}
}

View file

@ -0,0 +1,48 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_scheme.h"
#include "CefWrapper.h"
using namespace CefSharp::Enums;
namespace CefSharp
{
namespace Internals
{
private ref class CefSchemeRegistrarWrapper : public ISchemeRegistrar, public CefWrapper
{
private:
CefSchemeRegistrar* _registra;
public:
CefSchemeRegistrarWrapper(CefRawPtr<CefSchemeRegistrar> &registra) :
_registra(registra)
{
}
!CefSchemeRegistrarWrapper()
{
_registra = NULL;
}
~CefSchemeRegistrarWrapper()
{
this->!CefSchemeRegistrarWrapper();
_disposed = true;
}
virtual bool AddCustomScheme(String^ schemeName, CefSharp::Enums::SchemeOptions schemeOptions)
{
return _registra->AddCustomScheme(StringUtils::ToNative(schemeName), (int)schemeOptions);
}
};
}
}

View file

@ -0,0 +1,42 @@
// Copyright © 2017 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_cookie.h"
namespace CefSharp
{
namespace Internals
{
private class CefSetCookieCallbackAdapter : public CefSetCookieCallback
{
private:
gcroot<ISetCookieCallback^> _handler;
public:
CefSetCookieCallbackAdapter(ISetCookieCallback^ handler)
{
_handler = handler;
}
~CefSetCookieCallbackAdapter()
{
delete _handler;
_handler = nullptr;
}
void OnComplete(bool success) OVERRIDE
{
_handler->OnComplete(success);
}
IMPLEMENT_REFCOUNTING(CefSetCookieCallbackAdapter);
};
}
}

View file

@ -0,0 +1,214 @@
// Copyright © 2013 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_app.h"
#include "include\cef_scheme.h"
#include "CefSettingsBase.h"
#include "CefSchemeHandlerFactoryAdapter.h"
#include "Internals\CefSchemeRegistrarWrapper.h"
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
private class CefSharpApp : public CefApp,
public CefBrowserProcessHandler
{
gcroot<IEnumerable<CefCustomScheme^>^> _customSchemes;
gcroot<CommandLineArgDictionary^> _commandLineArgs;
gcroot<IApp^> _app;
bool _commandLineDisabled;
bool _hasCustomScheme;
gcroot<String^> _customSchemeArg;
public:
CefSharpApp(bool externalMessagePump, bool commandLineDisabled, CommandLineArgDictionary^ commandLineArgs, IEnumerable<CefCustomScheme^>^ customSchemes, IApp^ app) :
_commandLineDisabled(commandLineDisabled),
_commandLineArgs(commandLineArgs),
_customSchemes(customSchemes),
_app(app),
_hasCustomScheme(false)
{
auto isMissingHandler = Object::ReferenceEquals(app, nullptr) || Object::ReferenceEquals(app->BrowserProcessHandler, nullptr);
if (externalMessagePump && isMissingHandler)
{
throw gcnew Exception("browserProcessHandler cannot be null when using cefSettings.ExternalMessagePump");
}
if (System::Linq::Enumerable::Count(customSchemes) > 0)
{
String^ argument = "=";
auto registeredSchemes = gcnew List<String^>();
for each (CefCustomScheme ^ scheme in customSchemes)
{
//We don't need to register http or https in the render process
if (scheme->SchemeName == "http" ||
scheme->SchemeName == "https")
{
continue;
}
//We've already registered this scheme name
if (registeredSchemes->Contains(scheme->SchemeName))
{
continue;
}
_hasCustomScheme = true;
registeredSchemes->Add(scheme->SchemeName);
argument += scheme->SchemeName + "|";
argument += ((int)scheme->Options).ToString() + ";";
}
if (_hasCustomScheme)
{
_customSchemeArg = argument->TrimEnd(';');
}
}
}
~CefSharpApp()
{
_customSchemes = nullptr;
_commandLineArgs = nullptr;
delete _app;
_app = nullptr;
}
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler() OVERRIDE
{
return this;
}
virtual void OnContextInitialized() OVERRIDE
{
if (!Object::ReferenceEquals(_app, nullptr) && !Object::ReferenceEquals(_app->BrowserProcessHandler, nullptr))
{
_app->BrowserProcessHandler->OnContextInitialized();
}
auto customSchemes = (IEnumerable<CefCustomScheme^>^)_customSchemes;
//CefRegisterSchemeHandlerFactory requires access to the Global CefRequestContext
for each (CefCustomScheme^ cefCustomScheme in customSchemes)
{
if (!Object::ReferenceEquals(cefCustomScheme->SchemeHandlerFactory, nullptr))
{
auto domainName = cefCustomScheme->DomainName ? cefCustomScheme->DomainName : String::Empty;
CefRefPtr<CefSchemeHandlerFactory> wrapper = new CefSchemeHandlerFactoryAdapter(cefCustomScheme->SchemeHandlerFactory);
CefRegisterSchemeHandlerFactory(StringUtils::ToNative(cefCustomScheme->SchemeName), StringUtils::ToNative(domainName), wrapper);
}
}
}
virtual void OnScheduleMessagePumpWork(int64 delay_ms) OVERRIDE
{
//We rely on previous checks to make sure _app and _app->BrowserProcessHandler aren't null
_app->BrowserProcessHandler->OnScheduleMessagePumpWork(delay_ms);
}
virtual void OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> commandLine) OVERRIDE
{
#ifndef NETCOREAPP
if (CefSharpSettings::WcfEnabled)
{
commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::WcfEnabledArgument));
}
#endif
if (CefSharpSettings::SubprocessExitIfParentProcessClosed)
{
commandLine->AppendSwitch(StringUtils::ToNative(CefSharpArguments::ExitIfParentProcessClosed));
}
//ChannelId was removed in https://bitbucket.org/chromiumembedded/cef/issues/1912/notreached-in-logchannelidandcookiestores
//We need to know the process Id to establish WCF communication and for monitoring of parent process exit
commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::HostProcessIdArgument + "=" + Process::GetCurrentProcess()->Id));
if (_hasCustomScheme)
{
commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::CustomSchemeArgument + _customSchemeArg));
}
if (CefSharpSettings::FocusedNodeChangedEnabled)
{
commandLine->AppendArgument(StringUtils::ToNative(CefSharpArguments::FocusedNodeChangedEnabledArgument));
}
}
virtual void OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr<CefCommandLine> command_line) OVERRIDE
{
if (CefSharpSettings::Proxy != nullptr && !_commandLineDisabled)
{
command_line->AppendSwitchWithValue("proxy-server", StringUtils::ToNative(CefSharpSettings::Proxy->IP + ":" + CefSharpSettings::Proxy->Port));
if (!String::IsNullOrEmpty(CefSharpSettings::Proxy->BypassList))
{
command_line->AppendSwitchWithValue("proxy-bypass-list", StringUtils::ToNative(CefSharpSettings::Proxy->BypassList));
}
}
if (_commandLineArgs->Count > 0)
{
auto commandLine = command_line.get();
// Not clear what should happen if we
// * already have some command line flags given (is this possible? Perhaps from globalCommandLine)
// * have no flags given (-> call SetProgramm() with first argument?)
auto args = (CommandLineArgDictionary^)_commandLineArgs;
for each(KeyValuePair<String^, String^>^ kvp in args)
{
CefString name = StringUtils::ToNative(kvp->Key);
CefString value = StringUtils::ToNative(kvp->Value);
if (kvp->Key == "disable-features" || kvp->Key == "enable-features")
{
//Temp workaround so we can set the disable-features/enable-features command line argument
// See https://github.com/cefsharp/CefSharp/issues/2408
commandLine->AppendSwitchWithValue(name, value);
}
// Right now the command line args handed to the application (global command line) have higher
// precedence than command line args provided by the app
else if (!commandLine->HasSwitch(name))
{
if (String::IsNullOrEmpty(kvp->Value))
{
commandLine->AppendSwitch(name);
}
else
{
commandLine->AppendSwitchWithValue(name, value);
}
}
}
}
}
virtual void OnRegisterCustomSchemes(CefRawPtr<CefSchemeRegistrar> registrar) OVERRIDE
{
if (!Object::ReferenceEquals(_app, nullptr))
{
CefSchemeRegistrarWrapper wrapper(registrar);
_app->OnRegisterCustomSchemes(%wrapper);
}
};
IMPLEMENT_REFCOUNTING(CefSharpApp);
};
}
}

View file

@ -0,0 +1,82 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "TypeConversion.h"
#include "CefWrapper.h"
#include "include\cef_ssl_info.h"
using namespace System::Security::Cryptography::X509Certificates;
namespace CefSharp
{
namespace Internals
{
private ref class CefSslInfoWrapper : public ISslInfo, public CefWrapper
{
private:
MCefRefPtr<CefSSLInfo> _sslInfo;
public:
CefSslInfoWrapper(CefRefPtr<CefSSLInfo> &sslInfo)
: _sslInfo(sslInfo)
{
}
!CefSslInfoWrapper()
{
_sslInfo = NULL;
}
~CefSslInfoWrapper()
{
this->!CefSslInfoWrapper();
_disposed = true;
}
virtual property CertStatus CertStatus
{
CefSharp::CertStatus get()
{
ThrowIfDisposed();
return (CefSharp::CertStatus)_sslInfo->GetCertStatus();
}
}
virtual property X509Certificate2^ X509Certificate
{
X509Certificate2^ get()
{
ThrowIfDisposed();
auto certificate = _sslInfo->GetX509Certificate();
if (certificate.get())
{
auto derEncodedCertificate = certificate->GetDEREncoded();
auto byteCount = derEncodedCertificate->GetSize();
if (byteCount == 0)
{
return nullptr;
}
auto bytes = gcnew cli::array<Byte>(byteCount);
pin_ptr<Byte> src = &bytes[0]; // pin pointer to first element in arr
derEncodedCertificate->GetData(static_cast<void*>(src), byteCount, 0);
return gcnew X509Certificate2(bytes);
}
return nullptr;
}
}
};
}
}

View file

@ -0,0 +1,39 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_string_visitor.h"
namespace CefSharp
{
namespace Internals
{
private class CefStringVisitorAdapter : public CefStringVisitor
{
private:
gcroot<IStringVisitor^> _visitor;
public:
CefStringVisitorAdapter(IStringVisitor^ visitor) :
_visitor(visitor)
{
}
~CefStringVisitorAdapter()
{
delete _visitor;
_visitor = nullptr;
}
virtual void Visit(const CefString& string) OVERRIDE
{
_visitor->Visit(StringUtils::ToClr(string));
}
IMPLEMENT_REFCOUNTING(CefStringVisitorAdapter);
};
}
}

View file

@ -0,0 +1,79 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_task.h"
#include "CefTaskWrapper.h"
using namespace System::Threading::Tasks;
using namespace System::Runtime::InteropServices;
namespace CefSharp
{
namespace Internals
{
private ref class CefTaskScheduler : TaskScheduler, ITaskScheduler
{
public:
CefThreadId _thread;
CefTaskScheduler(CefThreadId thread) :
_thread(thread)
{
};
virtual void QueueTask(Task^ task) override
{
CefRefPtr<CefTask> taskWrapper = new CefTaskWrapper(task, this);
CefPostTask(_thread, taskWrapper);
};
virtual void ExecuteTask(Task^ task)
{
TryExecuteTask(task);
};
static bool CurrentlyOnThread(CefThreadId threadId)
{
return CefCurrentlyOn(threadId);
}
static void EnsureOn(CefThreadId threadId, String^ context)
{
if (!CefCurrentlyOn(threadId))
{
throw gcnew InvalidOperationException(String::Format("Executed '{0}' on incorrect thread. This method expects to run on the CEF {1} thread!", context, ((CefThreadIds)threadId).ToString()));
}
}
static void EnsureOn(CefThreadIds threadId, String^ context)
{
EnsureOn((CefThreadId)threadId, context);
}
protected:
virtual bool TryExecuteTaskInline(Task^ task, bool taskWasPreviouslyQueued) override
{
// You might think this method might not get called,
// but a .ContinueWith(..., TaskContinuationOpation.ExecuteSyncronously)
// will probably end up calling this method,
// so assume the callers know what they're doing and execute the task
// inline on this thread (if the current thread is correct for this scheduler)
if (CefCurrentlyOn(_thread))
{
return TryExecuteTask(task);
}
return false;
};
virtual IEnumerable<Task^>^ GetScheduledTasks() override
{
return nullptr;
};
};
}
}

View file

@ -0,0 +1,51 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_task.h"
#include "ReportUnhandledExceptions.h"
using namespace System::Threading::Tasks;
using namespace System::Runtime::InteropServices;
namespace CefSharp
{
namespace Internals
{
private class CefTaskWrapper : public CefTask
{
private:
gcroot<Task^> _task;
gcroot<ITaskScheduler^> _scheduler;
public:
CefTaskWrapper(Task^ task, ITaskScheduler^ scheduler) :
_task(task),
_scheduler(scheduler)
{
};
virtual void Execute() OVERRIDE
{
try
{
_scheduler->ExecuteTask(_task);
}
catch (Exception^ e)
{
// This should never ever happen.
// If this occurs then someone has broken a .Net ThreadScheduler/Task invariant
// i.e. trying to run a task on the wrong scheduler, or some
// weird exception during task completion.
auto msg = gcnew String(L"CefTaskWrapper caught an unexpected exception. This should never happen, please contact CefSharp for assistance");
ReportUnhandledExceptions::Report(msg, e);
}
};
IMPLEMENT_REFCOUNTING(CefTaskWrapper);
};
}
}

View file

@ -0,0 +1,54 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "CefUrlRequestClientAdapter.h"
#include "UrlRequest.h"
#include "CefAuthCallbackWrapper.h"
using namespace System::IO;
using namespace CefSharp::Core;
void CefUrlRequestClientAdapter::OnRequestComplete(CefRefPtr<CefURLRequest> request)
{
_client->OnRequestComplete(gcnew UrlRequest(request));
}
void CefUrlRequestClientAdapter::OnUploadProgress(CefRefPtr<CefURLRequest> request, int64 current, int64 total)
{
_client->OnUploadProgress(gcnew UrlRequest(request), current, total);
}
void CefUrlRequestClientAdapter::OnDownloadProgress(CefRefPtr<CefURLRequest> request, int64 current, int64 total)
{
_client->OnDownloadProgress(gcnew UrlRequest(request), current, total);
}
void CefUrlRequestClientAdapter::OnDownloadData(CefRefPtr<CefURLRequest> request, const void* data, size_t data_length)
{
UnmanagedMemoryStream readStream((Byte*)data, (Int64)data_length, (Int64)data_length, FileAccess::Read);
_client->OnDownloadData(
gcnew UrlRequest(request),
%readStream
);
}
bool CefUrlRequestClientAdapter::GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback)
{
return _client->GetAuthCredentials(
isProxy,
StringUtils::ToClr(host),
port,
StringUtils::ToClr(realm),
StringUtils::ToClr(scheme),
gcnew CefAuthCallbackWrapper(callback));
}

View file

@ -0,0 +1,94 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "Include\cef_urlrequest.h"
namespace CefSharp
{
namespace Internals
{
/// Interface that should be implemented by the CefUrlRequest client.
/// The methods of this class will be called on the same thread that created
/// the request unless otherwise documented.
private class CefUrlRequestClientAdapter : public CefURLRequestClient
{
private:
gcroot<IUrlRequestClient^> _client;
public:
CefUrlRequestClientAdapter(IUrlRequestClient^ client)
{
_client = client;
}
~CefUrlRequestClientAdapter()
{
delete _client;
_client = nullptr;
}
// Notifies the client that the request has completed. Use the
// CefURLRequest::GetRequestStatus method to determine if the request was
// successful or not.
///
/*--cef()--*/
virtual void OnRequestComplete(CefRefPtr<CefURLRequest> request) OVERRIDE;
///
// Notifies the client of upload progress. |current| denotes the number of
// bytes sent so far and |total| is the total size of uploading data (or -1 if
// chunked upload is enabled). This method will only be called if the
// UR_FLAG_REPORT_UPLOAD_PROGRESS flag is set on the request.
///
/*--cef()--*/
virtual void OnUploadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE;
///ref
// Notifies the client of download progress. |current| denotes the number of
// bytes received up to the call and |total| is the expected total size of the
// response (or -1 if not determined).
///
/*--cef()--*/
virtual void OnDownloadProgress(CefRefPtr<CefURLRequest> request,
int64 current,
int64 total) OVERRIDE;
///
// Called when some part of the response is read. |data| contains the current
// bytes received since the last call. This method will not be called if the
// UR_FLAG_NO_DOWNLOAD_DATA flag is set on the request.
///
/*--cef()--*/
virtual void OnDownloadData(CefRefPtr<CefURLRequest> request,
const void* data,
size_t data_length) OVERRIDE;
///
// Called on the IO thread when the browser needs credentials from the user.
// |isProxy| indicates whether the host is a proxy server. |host| contains the
// hostname and |port| contains the port number. Return true to continue the
// request and call CefAuthCallback::Continue() when the authentication
// information is available. If the request has an associated browser/frame
// then returning false will result in a call to GetAuthCredentials on the
// CefRequestHandler associated with that browser, if any. Otherwise,
// returning false will cancel the request immediately. This method will only
// be called for requests initiated from the browser process.
///
/*--cef(optional_param=realm)--*/
virtual bool GetAuthCredentials(bool isProxy,
const CefString& host,
int port,
const CefString& realm,
const CefString& scheme,
CefRefPtr<CefAuthCallback> callback) OVERRIDE;
IMPLEMENT_REFCOUNTING(CefUrlRequestClientAdapter);
};
}
}

View file

@ -0,0 +1,86 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "TypeConversion.h"
#include "CefValueWrapper.h"
bool CefValueWrapper::GetBool()
{
ThrowIfDisposed();
return _cefValue->GetBool();
}
double CefValueWrapper::GetDouble()
{
ThrowIfDisposed();
return _cefValue->GetDouble();
}
int CefValueWrapper::GetInt()
{
ThrowIfDisposed();
return _cefValue->GetInt();
}
String^ CefValueWrapper::GetString()
{
ThrowIfDisposed();
return StringUtils::ToClr(_cefValue->GetString());
}
IDictionary<String^, IValue^>^ CefValueWrapper::GetDictionary()
{
ThrowIfDisposed();
auto dictionary = _cefValue->GetDictionary();
if (!dictionary.get() || dictionary->GetSize() == 0)
{
return nullptr;
}
auto result = gcnew Dictionary<String^, IValue^>();
CefDictionaryValue::KeyList keys;
dictionary->GetKeys(keys);
for (size_t i = 0; i < keys.size(); i++)
{
auto key = keys[i];
auto keyValue = StringUtils::ToClr(key);
auto valueWrapper = gcnew CefValueWrapper(dictionary->GetValue(keys[i]));
result->Add(keyValue, valueWrapper);
}
return result;
}
IList<IValue^>^ CefValueWrapper::GetList()
{
ThrowIfDisposed();
auto list = _cefValue->GetList();
auto result = gcnew List<IValue^>(list->GetSize());
for (size_t i = 0; i < list->GetSize(); i++)
{
result->Add(gcnew CefValueWrapper(list->GetValue(i)));
}
return result;
}
Object^ CefValueWrapper::GetObject()
{
ThrowIfDisposed();
return TypeConversion::FromNative(_cefValue.get());
}

View file

@ -0,0 +1,58 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_values.h"
#include "CefWrapper.h"
namespace CefSharp
{
namespace Internals
{
private ref class CefValueWrapper : public IValue, public CefWrapper
{
private:
MCefRefPtr<CefValue> _cefValue;
internal:
CefValueWrapper(CefRefPtr<CefValue> &cefValue) : _cefValue(cefValue)
{
}
!CefValueWrapper()
{
_cefValue = NULL;
}
~CefValueWrapper()
{
this->!CefValueWrapper();
_disposed = true;
}
public:
virtual bool GetBool();
virtual double GetDouble();
virtual int GetInt();
virtual String^ GetString();
virtual IDictionary<String^, IValue^>^ GetDictionary();
virtual IList<IValue^>^ GetList();
virtual Object^ GetObject();
virtual property Enums::ValueType Type
{
Enums::ValueType get()
{
ThrowIfDisposed();
return (Enums::ValueType)_cefValue->GetType();
}
}
};
}
}

View file

@ -0,0 +1,44 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_web_plugin.h"
namespace CefSharp
{
namespace Internals
{
private class CefWebPluginInfoVisitorAdapter : public CefWebPluginInfoVisitor
{
private:
gcroot<IWebPluginInfoVisitor^> _visitor;
public:
CefWebPluginInfoVisitorAdapter(IWebPluginInfoVisitor^ visitor) : _visitor(visitor)
{
}
~CefWebPluginInfoVisitorAdapter()
{
delete _visitor;
_visitor = nullptr;
}
virtual bool Visit(CefRefPtr<CefWebPluginInfo> info, int count, int total) OVERRIDE
{
auto plugin = gcnew WebPluginInfo(StringUtils::ToClr(info->GetName()),
StringUtils::ToClr(info->GetDescription()),
StringUtils::ToClr(info->GetPath()),
StringUtils::ToClr(info->GetVersion()));
return _visitor->Visit(plugin, count, total);
}
IMPLEMENT_REFCOUNTING(CefWebPluginInfoVisitorAdapter);
};
}
}

View file

@ -0,0 +1,59 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
using namespace System::Diagnostics;
namespace CefSharp
{
namespace Internals
{
public ref class CefWrapper abstract
{
protected:
bool _disposed;
void ThrowIfDisposed()
{
if (_disposed)
{
auto type = GetType();
throw gcnew ObjectDisposedException(gcnew String(L"This instance of " + type->GetInterfaces()[0]->FullName + " been disposed!"));
}
}
void ThrowIfExecutedOnNonCefUiThread()
{
if (!CefCurrentlyOn(CefThreadId::TID_UI))
{
auto st = gcnew StackTrace(gcnew StackFrame(1));
auto method = st->GetFrame(0)->GetMethod();
throw gcnew Exception(gcnew String(method->Name + L" must be called on the CEF UI Thread, by default this is different " +
"to your applications UI Thread. You can use Cef.UIThreadTaskFactory to execute code on the CEF UI Thread. " +
"IBrowserProcessHandler.OnContextInitialized/IRequestContextHandler.OnRequestContextInitialized/ILifeSpanHandler.OnAfterCreated are called directly on the CEF UI Thread."));
}
}
internal:
CefWrapper() : _disposed(false)
{
};
public:
virtual property bool IsDisposed
{
bool get()
{
return _disposed;
}
}
};
}
}

View file

@ -0,0 +1,115 @@
// Copyright © 2018 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
using namespace System;
using namespace System::IO;
namespace CefSharp
{
namespace Internals
{
private class CefWriteHandlerWrapper : public CefWriteHandler
{
gcroot<Stream^> _stream;
bool _isMemoryStream;
public:
CefWriteHandlerWrapper(Stream^ stream) : _stream(stream)
{
//Reset stream position
stream->Position = 0;
_isMemoryStream = stream->GetType() == MemoryStream::typeid;
}
~CefWriteHandlerWrapper()
{
//Remove the reference to the stream, must be kept open
_stream = nullptr;
}
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE
{
try
{
array<Byte>^ buffer = gcnew array<Byte>(n * size);
pin_ptr<Byte> src = &buffer[0];
memcpy(static_cast<void*>(src), ptr, n);
_stream->Write(buffer, 0, n);
return n / size;
}
catch (Exception^)
{
return -1;
}
}
virtual int Seek(int64 offset, int whence) OVERRIDE
{
System::IO::SeekOrigin seekOrigin;
if (!_stream->CanSeek)
{
return -1;
}
switch (whence)
{
case SEEK_CUR:
{
seekOrigin = System::IO::SeekOrigin::Current;
break;
}
case SEEK_END:
{
seekOrigin = System::IO::SeekOrigin::End;
break;
}
case SEEK_SET:
{
seekOrigin = System::IO::SeekOrigin::Begin;
break;
}
default:
{
return -1;
}
}
try
{
_stream->Seek(offset, seekOrigin);
}
catch (Exception^)
{
return -1;
}
return 0;
}
virtual int64 Tell() OVERRIDE
{
return static_cast<int64>(_stream->Position);
}
virtual int Flush() OVERRIDE
{
_stream->Flush();
return 0;
}
virtual bool MayBlock() OVERRIDE
{
return !_isMemoryStream;
}
IMPLEMENT_REFCOUNTING(CefWriteHandlerWrapper);
};
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,208 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEFSHARP_CORE_INTERNALS_CLIENTADAPTER_H_
#define CEFSHARP_CORE_INTERNALS_CLIENTADAPTER_H_
#pragma once
#include "Stdafx.h"
#include "include/cef_app.h"
#include "include/cef_client.h"
#include "include/cef_render_process_handler.h"
#include "include/internal/cef_types.h"
using namespace System::Threading::Tasks;
namespace CefSharp
{
namespace Internals
{
private class ClientAdapter : public CefClient,
public CefLifeSpanHandler,
public CefLoadHandler,
public CefRequestHandler,
public CefDisplayHandler,
public CefContextMenuHandler,
public CefFocusHandler,
public CefKeyboardHandler,
public CefJSDialogHandler,
public CefDialogHandler,
public CefDragHandler,
public CefDownloadHandler,
public CefFindHandler,
public CefAudioHandler
{
private:
gcroot<IWebBrowserInternal^> _browserControl;
HWND _browserHwnd;
CefRefPtr<CefBrowser> _cefBrowser;
bool _disposed;
gcroot<IBrowser^> _browser;
gcroot<Dictionary<int, IBrowser^>^> _popupBrowsers;
gcroot<String^> _tooltip;
gcroot<IBrowserAdapter^> _browserAdapter;
//contains in-progress eval script tasks
gcroot<PendingTaskRepository<JavascriptResponse^>^> _pendingTaskRepository;
//contains js callback factories for each browser
IBrowser^ GetBrowserWrapper(int browserId, bool isPopup);
public:
ClientAdapter(IWebBrowserInternal^ browserControl, IBrowserAdapter^ browserAdapter) :
_browserControl(browserControl),
_popupBrowsers(gcnew Dictionary<int, IBrowser^>()),
_pendingTaskRepository(gcnew PendingTaskRepository<JavascriptResponse^>()),
_browserAdapter(browserAdapter),
_browserHwnd(NULL),
_disposed(false)
{
}
~ClientAdapter()
{
_disposed = true;
CloseAllPopups(true);
//this will dispose the repository and cancel all pending tasks
delete _pendingTaskRepository;
_browser = nullptr;
_browserControl = nullptr;
_browserHwnd = nullptr;
_cefBrowser = NULL;
_tooltip = nullptr;
_browserAdapter = nullptr;
_popupBrowsers = nullptr;
}
HWND GetBrowserHwnd() { return _browserHwnd; }
PendingTaskRepository<JavascriptResponse^>^ GetPendingTaskRepository();
void CloseAllPopups(bool forceClose);
void MethodInvocationComplete(MethodInvocationResult^ result);
IBrowser^ GetBrowserWrapper(int browserId);
// CefClient
virtual DECL CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefLoadHandler> GetLoadHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefRequestHandler> GetRequestHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefDownloadHandler> GetDownloadHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefFocusHandler> GetFocusHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefDragHandler> GetDragHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefFindHandler> GetFindHandler() OVERRIDE { return this; }
virtual DECL CefRefPtr<CefAudioHandler> GetAudioHandler() OVERRIDE { return this; }
virtual DECL bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) OVERRIDE;
// CefLifeSpanHandler
virtual DECL bool OnBeforePopup(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
const CefString& target_url, const CefString& target_frame_name,
CefLifeSpanHandler::WindowOpenDisposition target_disposition, bool user_gesture,
const CefPopupFeatures& popupFeatures,
CefWindowInfo& windowInfo, CefRefPtr<CefClient>& client, CefBrowserSettings& settings, CefRefPtr<CefDictionaryValue>& extraInfo, bool* no_javascript_access) OVERRIDE;
virtual DECL void OnAfterCreated(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL bool DoClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL void OnBeforeClose(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefLoadHandler
virtual DECL void OnLoadStart(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, TransitionType transitionType) OVERRIDE;
virtual DECL void OnLoadEnd(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, int httpStatusCode) OVERRIDE;
virtual DECL void OnLoadError(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, ErrorCode errorCode, const CefString& errorText, const CefString& failedUrl) OVERRIDE;
// CefRequestHandler
virtual DECL bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool userGesture, bool isRedirect) OVERRIDE;
virtual DECL bool OnOpenURLFromTab(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& targetUrl,
CefRequestHandler::WindowOpenDisposition targetDisposition, bool userGesture) OVERRIDE;
virtual DECL CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefRequest> request, bool isNavigation, bool isDownload, const CefString& requestInitiator, bool& disableDefaultHandling) OVERRIDE;
virtual DECL bool GetAuthCredentials(CefRefPtr<CefBrowser> browser, const CefString& originUrl, bool isProxy,
const CefString& host, int port, const CefString& realm, const CefString& scheme, CefRefPtr<CefAuthCallback> callback) OVERRIDE;
virtual DECL bool OnQuotaRequest(CefRefPtr<CefBrowser> browser, const CefString& originUrl, int64 newSize, CefRefPtr<CefRequestCallback> callback) OVERRIDE;
virtual DECL bool OnCertificateError(CefRefPtr<CefBrowser> browser, cef_errorcode_t cert_error, const CefString& request_url, CefRefPtr<CefSSLInfo> ssl_info, CefRefPtr<CefRequestCallback> callback) OVERRIDE;
virtual DECL bool OnSelectClientCertificate(CefRefPtr<CefBrowser> browser, bool isProxy, const CefString& host, int port,
const CefRequestHandler::X509CertificateList& certificates, CefRefPtr<CefSelectClientCertificateCallback> callback) OVERRIDE;
virtual DECL void OnPluginCrashed(CefRefPtr<CefBrowser> browser, const CefString& plugin_path) OVERRIDE;
virtual DECL void OnRenderViewReady(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL void OnRenderProcessTerminated(CefRefPtr<CefBrowser> browser, TerminationStatus status) OVERRIDE;
virtual DECL void OnDocumentAvailableInMainFrame(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefDisplayHandler
virtual DECL void OnLoadingStateChange(CefRefPtr<CefBrowser> browser, bool isLoading, bool canGoBack, bool canGoForward) OVERRIDE;
virtual DECL void OnAddressChange(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const CefString& url) OVERRIDE;
virtual DECL bool OnAutoResize(CefRefPtr< CefBrowser > browser, const CefSize& new_size) OVERRIDE;
virtual DECL bool OnCursorChange(CefRefPtr<CefBrowser> browser, CefCursorHandle cursor, cef_cursor_type_t type, const CefCursorInfo & custom_cursor_info) OVERRIDE;
virtual DECL void OnTitleChange(CefRefPtr<CefBrowser> browser, const CefString& title) OVERRIDE;
virtual DECL void OnFaviconURLChange(CefRefPtr<CefBrowser> browser, const std::vector<CefString>& iconUrls) OVERRIDE;
virtual DECL void OnFullscreenModeChange(CefRefPtr<CefBrowser> browser, bool fullscreen) OVERRIDE;
virtual DECL void OnLoadingProgressChange(CefRefPtr<CefBrowser> browser, double progress) OVERRIDE;
virtual DECL bool OnTooltip(CefRefPtr<CefBrowser> browser, CefString& text) OVERRIDE;
virtual DECL bool OnConsoleMessage(CefRefPtr<CefBrowser> browser, cef_log_severity_t level, const CefString& message, const CefString& source, int line) OVERRIDE;
virtual DECL void OnStatusMessage(CefRefPtr<CefBrowser> browser, const CefString& message) OVERRIDE;
virtual DECL void InternalCursorChange(CefRefPtr<CefBrowser> browser, CefCursorHandle cursor, cef_cursor_type_t type, const CefCursorInfo& custom_cursor_info);
// CefContextMenuHandler
virtual DECL void OnBeforeContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model) OVERRIDE;
virtual DECL bool OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame,
CefRefPtr<CefContextMenuParams> params, int commandId, EventFlags eventFlags) OVERRIDE;
virtual DECL void OnContextMenuDismissed(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) OVERRIDE;
virtual DECL bool RunContextMenu(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, CefRefPtr<CefMenuModel> model, CefRefPtr<CefRunContextMenuCallback> callback) OVERRIDE;
// CefFocusHandler
virtual DECL void OnGotFocus(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL bool OnSetFocus(CefRefPtr<CefBrowser> browser, FocusSource source) OVERRIDE;
virtual DECL void OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) OVERRIDE;
// CefKeyboardHandler
virtual DECL bool OnKeyEvent(CefRefPtr<CefBrowser> browser, const CefKeyEvent& event, CefEventHandle os_event) OVERRIDE;
virtual DECL bool OnPreKeyEvent(CefRefPtr<CefBrowser> browser, const CefKeyEvent& event, CefEventHandle os_event, bool* is_keyboard_shortcut) OVERRIDE;
// CefJSDialogHandler
virtual DECL bool OnJSDialog(CefRefPtr<CefBrowser> browser, const CefString& origin_url,
JSDialogType dialog_type, const CefString& message_text, const CefString& default_prompt_text,
CefRefPtr<CefJSDialogCallback> callback, bool& suppress_message) OVERRIDE;
virtual DECL bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser, const CefString& message_text, bool is_reload,
CefRefPtr<CefJSDialogCallback> callback) OVERRIDE;
virtual DECL void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL void OnDialogClosed(CefRefPtr<CefBrowser> browser) OVERRIDE;
// CefDialogHandler
virtual DECL bool OnFileDialog(CefRefPtr<CefBrowser> browser, FileDialogMode mode, const CefString& title,
const CefString& default_file_path, const std::vector<CefString>& accept_filters, int selected_accept_filter,
CefRefPtr<CefFileDialogCallback> callback) OVERRIDE;
//CefDragHandler
virtual DECL bool OnDragEnter(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDragData> dragData, DragOperationsMask mask) OVERRIDE;
virtual DECL void OnDraggableRegionsChanged(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, const std::vector<CefDraggableRegion>& regions) OVERRIDE;
//CefDownloadHandler
virtual DECL void OnBeforeDownload(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item,
const CefString& suggested_name, CefRefPtr<CefBeforeDownloadCallback> callback) OVERRIDE;
virtual DECL void OnDownloadUpdated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDownloadItem> download_item,
CefRefPtr<CefDownloadItemCallback> callback) OVERRIDE;
//CefFindHandler
virtual DECL void OnFindResult(CefRefPtr<CefBrowser> browser, int identifier, int count, const CefRect& selectionRect, int activeMatchOrdinal, bool finalUpdate) OVERRIDE;
//CefAudioHandler
virtual DECL bool GetAudioParameters(CefRefPtr<CefBrowser> browser, CefAudioParameters & params) OVERRIDE;
virtual DECL void OnAudioStreamStarted(CefRefPtr<CefBrowser> browser, const CefAudioParameters& params, int channels) OVERRIDE;
virtual DECL void OnAudioStreamPacket(CefRefPtr<CefBrowser> browser, const float** data, int frames, int64 pts) OVERRIDE;
virtual DECL void OnAudioStreamStopped(CefRefPtr<CefBrowser> browser) OVERRIDE;
virtual DECL void OnAudioStreamError(CefRefPtr<CefBrowser> browser, const CefString& message) OVERRIDE;
IMPLEMENT_REFCOUNTING(ClientAdapter);
};
}
}
#endif // CEFSHARP_CORE_INTERNALS_CLIENTADAPTER_H_

View file

@ -0,0 +1,18 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "JavascriptCallbackProxy.h"
#include "JavascriptCallbackFactory.h"
namespace CefSharp
{
namespace Internals
{
IJavascriptCallback^ JavascriptCallbackFactory::Create(JavascriptCallback^ callback)
{
return gcnew JavascriptCallbackProxy(callback, _pendingTasks, BrowserAdapter);
}
}
}

View file

@ -0,0 +1,26 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
namespace CefSharp
{
namespace Internals
{
private ref class JavascriptCallbackFactory : public IJavascriptCallbackFactory
{
private:
PendingTaskRepository<JavascriptResponse^>^ _pendingTasks;
public:
JavascriptCallbackFactory(PendingTaskRepository<JavascriptResponse^>^ pendingTasks)
:_pendingTasks(pendingTasks)
{
}
property WeakReference<IBrowserAdapter^>^ BrowserAdapter;
virtual IJavascriptCallback^ Create(JavascriptCallback^ callback);
};
}
}

View file

@ -0,0 +1,146 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "JavascriptCallbackProxy.h"
#include "Messaging/Messages.h"
#include "Serialization/Primitives.h"
#include "Serialization/V8Serialization.h"
using namespace CefSharp::Internals::Messaging;
using namespace CefSharp::Internals::Serialization;
namespace CefSharp
{
namespace Internals
{
Task<JavascriptResponse^>^ JavascriptCallbackProxy::ExecuteAsync(cli::array<Object^>^ parameters)
{
return ExecuteWithTimeoutAsync(Nullable<TimeSpan>(), parameters);
}
Task<JavascriptResponse^>^ JavascriptCallbackProxy::ExecuteWithTimeoutAsync(Nullable<TimeSpan> timeout, cli::array<Object^>^ parameters)
{
DisposedGuard();
auto browser = GetBrowser();
if (browser == nullptr)
{
throw gcnew InvalidOperationException("Browser instance is null. Check CanExecute before calling this method.");
}
auto browserWrapper = static_cast<CefBrowserWrapper^>(browser);
auto javascriptNameConverter = GetJavascriptNameConverter();
auto doneCallback = _pendingTasks->CreatePendingTask(timeout);
auto callbackMessage = CefProcessMessage::Create(kJavascriptCallbackRequest);
auto argList = callbackMessage->GetArgumentList();
SetInt64(argList, 0, doneCallback.Key);
SetInt64(argList, 1, _callback->Id);
auto paramList = CefListValue::Create();
for (int i = 0; i < parameters->Length; i++)
{
auto param = parameters[i];
SerializeV8Object(paramList, i, param, javascriptNameConverter);
}
argList->SetList(2, paramList);
auto frame = browserWrapper->Browser->GetFrame(_callback->FrameId);
if (frame.get() && frame->IsValid())
{
frame->SendProcessMessage(CefProcessId::PID_RENDERER, callbackMessage);
return doneCallback.Value->Task;
}
auto invalidFrameResponse = gcnew JavascriptResponse();
invalidFrameResponse->Success = false;
invalidFrameResponse->Message = "Frame with Id:" + _callback->FrameId + " is no longer valid.";
return Task::FromResult(invalidFrameResponse);
}
CefRefPtr<CefProcessMessage> JavascriptCallbackProxy::CreateDestroyMessage()
{
auto result = CefProcessMessage::Create(kJavascriptCallbackDestroyRequest);
auto argList = result->GetArgumentList();
SetInt64(argList, 0, _callback->Id);
return result;
}
//TODO: Reduce code duplication
IBrowser^ JavascriptCallbackProxy::GetBrowser()
{
IBrowser^ result = nullptr;
IBrowserAdapter^ browserAdapter;
if (_browserAdapter->TryGetTarget(browserAdapter))
{
if (!browserAdapter->IsDisposed)
{
result = browserAdapter->GetBrowser(_callback->BrowserId);
}
}
return result;
}
IJavascriptNameConverter^ JavascriptCallbackProxy::GetJavascriptNameConverter()
{
IJavascriptNameConverter^ result = nullptr;
IBrowserAdapter^ browserAdapter;
if (_browserAdapter->TryGetTarget(browserAdapter))
{
if (!browserAdapter->IsDisposed && browserAdapter->JavascriptObjectRepository != nullptr)
{
result = browserAdapter->JavascriptObjectRepository->NameConverter;
}
}
return result;
}
Int64 JavascriptCallbackProxy::Id::get()
{
DisposedGuard();
return _callback->Id;
}
bool JavascriptCallbackProxy::IsDisposed::get()
{
return _disposed;
}
bool JavascriptCallbackProxy::CanExecute::get()
{
if (_disposed)
{
return false;
}
auto browser = GetBrowser();
if (browser == nullptr)
{
return false;
}
//If the frame Id is still valid then we can attemp to execute the callback
auto frame = browser->GetFrame(_callback->FrameId);
if (frame == nullptr)
{
return false;
}
return frame->IsValid;
}
void JavascriptCallbackProxy::DisposedGuard()
{
if (_disposed)
{
throw gcnew ObjectDisposedException("JavascriptCallbackProxy");
}
}
}
}

View file

@ -0,0 +1,79 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_app.h"
#include "..\ManagedCefBrowserAdapter.h"
#include "Internals\CefBrowserWrapper.h"
using namespace System::Threading::Tasks;
using namespace CefSharp::JavascriptBinding;
namespace CefSharp
{
namespace Internals
{
private ref class JavascriptCallbackProxy : public IJavascriptCallback
{
private:
WeakReference<IBrowserAdapter^>^ _browserAdapter;
JavascriptCallback^ _callback;
PendingTaskRepository<JavascriptResponse^>^ _pendingTasks;
bool _disposed;
CefRefPtr<CefProcessMessage> CreateDestroyMessage();
IBrowser^ GetBrowser();
IJavascriptNameConverter^ GetJavascriptNameConverter();
void DisposedGuard();
public:
JavascriptCallbackProxy(JavascriptCallback^ callback, PendingTaskRepository<JavascriptResponse^>^ pendingTasks, WeakReference<IBrowserAdapter^>^ browserAdapter)
:_callback(callback), _pendingTasks(pendingTasks), _disposed(false)
{
_browserAdapter = browserAdapter;
}
~JavascriptCallbackProxy()
{
this->!JavascriptCallbackProxy();
}
!JavascriptCallbackProxy()
{
auto browser = GetBrowser();
if (browser != nullptr && !browser->IsDisposed)
{
auto browserWrapper = static_cast<CefBrowserWrapper^>(browser)->Browser;
auto frame = browserWrapper->GetFrame(_callback->FrameId);
if (frame.get() && frame->IsValid())
{
frame->SendProcessMessage(CefProcessId::PID_RENDERER, CreateDestroyMessage());
}
}
_disposed = true;
}
virtual Task<JavascriptResponse^>^ ExecuteAsync(cli::array<Object^>^ parameters);
virtual Task<JavascriptResponse^>^ ExecuteWithTimeoutAsync(Nullable<TimeSpan> timeout, cli::array<Object^>^ parameters);
virtual property Int64 Id
{
Int64 get();
}
virtual property bool IsDisposed
{
bool get();
}
virtual property bool CanExecute
{
bool get();
}
};
}
}

View file

@ -0,0 +1,146 @@
// Copyright © 2013 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
namespace CefSharp
{
namespace Internals
{
// This class appears to be required in order
// to continue reference counting in managed classes
// that the compiler won't let contain CefRefPtr<...>
template <typename T>
ref class MCefRefPtr sealed
{
private:
T* _ptr;
public:
MCefRefPtr() : _ptr(NULL) {}
MCefRefPtr(T* p) : _ptr(p)
{
if (_ptr)
{
_ptr->AddRef();
}
}
MCefRefPtr(const MCefRefPtr<T>% r) : _ptr(r._ptr)
{
if (_ptr)
{
_ptr->AddRef();
}
}
MCefRefPtr(const CefRefPtr<T>& r) : _ptr(r.get())
{
if (_ptr)
{
_ptr->AddRef();
}
}
!MCefRefPtr()
{
if (_ptr)
{
_ptr->Release();
// Be paranoid about preventing a double release
// from this managed instance.
_ptr = nullptr;
}
}
~MCefRefPtr()
{
// Normally, we would invoke the finalizer method here
// via !classname, however... the overloaded -> operator
// prevents that from being feasible.
if (_ptr)
{
_ptr->Release();
// Be paranoid about preventing a double release
// from this managed instance.
_ptr = nullptr;
}
}
T* get()
{
return _ptr;
}
/*
* commented out for now as this operator interferes with the
* return statement of MCefRefPtr<T>% operator=(T* p)
operator T*()
{
return _ptr;
}
*/
T* operator->()
{
return _ptr;
}
MCefRefPtr<T>% operator=(T* p)
{
// AddRef first so that self assignment should work
if (p)
{
p->AddRef();
}
if (_ptr)
{
_ptr->Release();
}
_ptr = p;
return *this;
}
MCefRefPtr<T>% operator=(const MCefRefPtr<T>% r)
{
return %this = r._ptr;
}
void swap(T** pp)
{
T* p = _ptr;
_ptr = *pp;
*pp = p;
}
void swap(MCefRefPtr<T>% r)
{
swap(%r._ptr);
}
virtual bool Equals(Object^ obj) override
{
if (obj->GetType() == GetType())
{
MCefRefPtr^ other = safe_cast<MCefRefPtr^>(obj);
return (*other)._ptr == _ptr;
}
return false;
}
//TODO: Is this used? Disable warnings for now though code can likely be removed
#pragma warning( push )
#pragma warning(disable:4302)
#pragma warning(disable:4311)
virtual int GetHashCode() override
{
return (int)_ptr;
}
#pragma warning( pop )
};
}
}

View file

@ -0,0 +1,53 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "include/cef_base.h"
namespace CefSharp
{
namespace Internals
{
namespace Messaging
{
//contains process message names for all handled messages
//Message containing a script to be evaluated
const CefString kEvaluateJavascriptRequest = "EvaluateJavascriptRequest";
//Message containing the result for a given evaluation
const CefString kEvaluateJavascriptResponse = "EvaluateJavascriptDoneResponse";
//Message to invoke a stored js function
const CefString kJavascriptCallbackRequest = "JavascriptCallbackRequest";
//Message to dereference a stored js function
const CefString kJavascriptCallbackDestroyRequest = "JavascriptCallbackDestroyRequest";
//Message containing the result of a given js function call
const CefString kJavascriptCallbackResponse = "JavascriptCallbackDoneResponse";
//Message containing a request JSB root objects
const CefString kJavascriptRootObjectRequest = "JavascriptRootObjectRequest";
//Message containing the response for the JSB root objects
const CefString kJavascriptRootObjectResponse = "JavascriptRootObjectResponse";
//Message from the render process to request a method invocation on a bound object
const CefString kJavascriptAsyncMethodCallRequest = "JavascriptAsyncMethodCallRequest";
//Message from the browser process containing the result of a bound method invocation
const CefString kJavascriptAsyncMethodCallResponse = "JavascriptAsyncMethodCallResponse";
//Message that signals a new V8Context has been created
const CefString kOnContextCreatedRequest = "OnContextCreated";
//Message that signals a new V8Context has been released
const CefString kOnContextReleasedRequest = "OnContextReleased";
// Message from the render process that an element (or nothing) has
// gotten focus. This message is only sent if specified as an
// optional message via command line argument when the subprocess is
// created.
const CefString kOnFocusedNodeChanged = "OnFocusedNodeChanged";
//Message that signals an uncaught exception has occurred
const CefString kOnUncaughtException = "OnUncaughtException";
//Message containing a request/notification that JSB objects have been bound
const CefString kJavascriptObjectsBoundInJavascript = "JavascriptObjectsBoundInJavascript";
//Message containing the CefSharp.PostMessage request
const CefString kJavascriptMessageReceived = "JavascriptMessageReceived";
}
}
}

View file

@ -0,0 +1,251 @@
// Copyright © 2012 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include <msclr/lock.h>
#include "DragData.h"
#include "ClientAdapter.h"
#include "CefValueWrapper.h"
using namespace msclr;
using namespace CefSharp::Structs;
using namespace CefSharp::Core;
namespace CefSharp
{
namespace Internals
{
private class RenderClientAdapter : public ClientAdapter,
public CefRenderHandler,
public CefAccessibilityHandler
{
private:
gcroot<IRenderWebBrowser^> _renderWebBrowser;
public:
RenderClientAdapter(IWebBrowserInternal^ webBrowserInternal, IBrowserAdapter^ browserAdapter) :
ClientAdapter(webBrowserInternal, browserAdapter)
{
_renderWebBrowser = dynamic_cast<IRenderWebBrowser^>(webBrowserInternal);
}
~RenderClientAdapter()
{
_renderWebBrowser = nullptr;
}
// CefClient
virtual DECL CefRefPtr<CefRenderHandler> GetRenderHandler() OVERRIDE { return this; };
// CefRenderHandler
virtual DECL CefRefPtr<CefAccessibilityHandler> GetAccessibilityHandler() OVERRIDE { return this; }
// CefRenderHandler
virtual DECL bool GetScreenInfo(CefRefPtr<CefBrowser> browser, CefScreenInfo& screen_info) OVERRIDE
{
if ((IRenderWebBrowser^)_renderWebBrowser == nullptr)
{
return false;
}
auto screenInfo = _renderWebBrowser->GetScreenInfo();
//NOTE: If ScreenInfo is returned as null, the screen_info available and rect structs would remain default (0,0,0,0). If so, the underlying CEF library would use
// GetViewRect to populate values in the window.screen object (javascript).
//https://bitbucket.org/chromiumembedded/cef/src/47e6d4bf84444eb6cb4d4509231a8c9ee878a584/include/cef_render_handler.h?at=2357#cef_render_handler.h-90
if (screenInfo.HasValue == false)
{
return false;
}
screen_info.device_scale_factor = screenInfo.Value.DeviceScaleFactor;
screen_info.depth = screenInfo.Value.Depth;
screen_info.depth_per_component = screenInfo.Value.DepthPerComponent;
screen_info.is_monochrome = screenInfo.Value.IsMonochrome ? 1 : 0;
//NOTE: If rect values remain (0,0,0,0) then the underlying CEF library will use
// GetViewRect to populate values in the window.screen object (javascript).
auto rect = screenInfo.Value.Rect;
if (rect.HasValue)
{
screen_info.rect.width = rect.Value.Width;
screen_info.rect.height = rect.Value.Height;
screen_info.rect.x = rect.Value.X;
screen_info.rect.y = rect.Value.Y;
}
auto availableRect = screenInfo.Value.Rect;
if (availableRect.HasValue)
{
screen_info.available_rect.width = availableRect.Value.Width;
screen_info.available_rect.height = availableRect.Value.Height;
screen_info.available_rect.x = availableRect.Value.X;
screen_info.available_rect.y = availableRect.Value.Y;
}
return true;
}
// CefRenderHandler
virtual DECL void GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) OVERRIDE
{
if ((IRenderWebBrowser^)_renderWebBrowser == nullptr)
{
//CEF doesn't like a 0 width or 0 height, cefclient
//defaults these to 1, so we'll do the same
rect = CefRect(0, 0, 1, 1);
}
else
{
auto viewRect = _renderWebBrowser->GetViewRect();
rect = CefRect(viewRect.X, viewRect.Y, viewRect.Width, viewRect.Height);
//Cefclient defaults these to 1 instead of 0, we'll do the same
if (rect.height <= 0)
{
rect.height = 1;
}
if (rect.width <= 0)
{
rect.width = 1;
}
}
};
///
// Called to retrieve the translation from view coordinates to actual screen
// coordinates. Return true if the screen coordinates were provided.
///
/*--cef()--*/
virtual DECL bool GetScreenPoint(CefRefPtr<CefBrowser> browser, int viewX, int viewY, int& screenX, int& screenY) OVERRIDE
{
return _renderWebBrowser->GetScreenPoint(viewX, viewY, screenX, screenY);
}
///
// Called when the browser wants to show or hide the popup widget. The popup
// should be shown if |show| is true and hidden if |show| is false.
///
/*--cef()--*/
virtual DECL void OnPopupShow(CefRefPtr<CefBrowser> browser, bool show) OVERRIDE
{
_renderWebBrowser->OnPopupShow(show);
};
///
// Called when the browser wants to move or resize the popup widget. |rect|
// contains the new location and size.
///
/*--cef()--*/
virtual DECL void OnPopupSize(CefRefPtr<CefBrowser> browser, const CefRect& rect) OVERRIDE
{
_renderWebBrowser->OnPopupSize(Rect(rect.x, rect.y, rect.width, rect.height));
};
virtual DECL void OnAcceleratedPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirtyRects, void* shared_handle) OVERRIDE
{
CefRect r = dirtyRects.front();
_renderWebBrowser->OnAcceleratedPaint((CefSharp::PaintElementType)type, CefSharp::Structs::Rect(r.x, r.y, r.width, r.height), IntPtr((void *)shared_handle));
}
virtual DECL void OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirtyRects,
const void* buffer, int width, int height) OVERRIDE
{
CefRect r = dirtyRects.front();
_renderWebBrowser->OnPaint((CefSharp::PaintElementType)type, CefSharp::Structs::Rect(r.x, r.y, r.width, r.height), IntPtr((void *)buffer), width, height);
};
virtual DECL void InternalCursorChange(CefRefPtr<CefBrowser> browser, CefCursorHandle cursor, cef_cursor_type_t type, const CefCursorInfo& custom_cursor_info) OVERRIDE
{
CursorInfo customCursorInfo;
//Only create the struct when we actually have a custom cursor
if (type == cef_cursor_type_t::CT_CUSTOM)
{
Point hotspot = Point(custom_cursor_info.hotspot.x, custom_cursor_info.hotspot.y);
Size size = Size(custom_cursor_info.size.width, custom_cursor_info.size.height);
customCursorInfo = CursorInfo(IntPtr((void *)custom_cursor_info.buffer), hotspot, custom_cursor_info.image_scale_factor, size);
}
_renderWebBrowser->OnCursorChange((IntPtr)cursor, (CefSharp::Enums::CursorType)type, customCursorInfo);
}
virtual DECL bool StartDragging(CefRefPtr<CefBrowser> browser, CefRefPtr<CefDragData> dragData,
CefRenderHandler::DragOperationsMask allowedOps, int x, int y) OVERRIDE
{
DragData dragDataWrapper(dragData);
return _renderWebBrowser->StartDragging(%dragDataWrapper, (CefSharp::Enums::DragOperationsMask)allowedOps, x, y);
}
///
// Called when the web view wants to update the mouse cursor during a
// drag & drop operation. |operation| describes the allowed operation
// (none, move, copy, link).
///
/*--cef()--*/
virtual DECL void UpdateDragCursor(CefRefPtr<CefBrowser> browser, CefRenderHandler::DragOperation operation) OVERRIDE
{
return _renderWebBrowser->UpdateDragCursor((CefSharp::Enums::DragOperationsMask)operation);
}
///
// Called when the IME composition range has changed. |selected_range| is the
// range of characters that have been selected. |character_bounds| is the
// bounds of each character in view coordinates.
///
/*--cef()--*/
virtual DECL void OnImeCompositionRangeChanged(CefRefPtr<CefBrowser> browser, const CefRange& selectedRange, const RectList& characterBounds) OVERRIDE
{
auto charBounds = gcnew cli::array<Rect>((int)characterBounds.size());
std::vector<CefRect>::const_iterator it = characterBounds.begin();
for (int index = 0; it != characterBounds.end(); ++it, index++)
{
charBounds[index] = Rect((*it).x, (*it).y, (*it).width, (*it).height);
}
_renderWebBrowser->OnImeCompositionRangeChanged(CefSharp::Structs::Range(selectedRange.from, selectedRange.to), charBounds);
}
//CefAccessibilityHandler
virtual DECL void OnAccessibilityLocationChange(CefRefPtr<CefValue> value) OVERRIDE
{
auto handler = _renderWebBrowser->AccessibilityHandler;
if (handler != nullptr)
{
auto valueWrapper = gcnew CefValueWrapper(value);
handler->OnAccessibilityLocationChange(valueWrapper);
}
}
virtual DECL void OnAccessibilityTreeChange(CefRefPtr<CefValue> value) OVERRIDE
{
auto handler = _renderWebBrowser->AccessibilityHandler;
if (handler != nullptr)
{
auto valueWrapper = gcnew CefValueWrapper(value);
handler->OnAccessibilityTreeChange(valueWrapper);
}
}
virtual DECL void OnVirtualKeyboardRequested(CefRefPtr<CefBrowser> browser, cef_text_input_mode_t input_mode) OVERRIDE
{
_renderWebBrowser->OnVirtualKeyboardRequested(GetBrowserWrapper(browser->GetIdentifier()), (CefSharp::Enums::TextInputMode)input_mode);
}
IMPLEMENT_REFCOUNTING(RenderClientAdapter);
};
}
}

View file

@ -0,0 +1,44 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include <include/base/cef_logging.h>
using namespace System::Threading;
namespace CefSharp
{
namespace Internals
{
private class ReportUnhandledExceptions
{
public:
static void Report(String^ str, Exception^ exception)
{
auto msg = String::Format(gcnew String(L"{0}: {1}"), str, exception->ToString());
LOG(ERROR) << StringUtils::ToNative(str).ToString();
// Throw the exception from a threadpool thread so that
// AppDomain::UnhandledException event handler will get called
// with the exception.
ThreadPool::UnsafeQueueUserWorkItem(
gcnew WaitCallback(&ReportUnhandledExceptions::ThrowUnhandledException),
gcnew Tuple<String^, Exception^>(str, exception));
}
private:
// Throw the exception, this method executes on the thread pool
// in order to report a .net exception from a CEF thread.
static void ThrowUnhandledException(Object ^state)
{
Tuple<String^, Exception^>^ params = dynamic_cast<Tuple<String^, Exception^>^>(state);
throw gcnew InvalidOperationException(params->Item1, params->Item2);
}
};
}
}

View file

@ -0,0 +1,84 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "Primitives.h"
#include "JsObjectsSerialization.h"
#include "V8Serialization.h"
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
void SerializeJsObject(JavascriptObject^ jsObject, const CefRefPtr<CefListValue> &list, int index)
{
auto objList = CefListValue::Create();
SetInt64(objList, 0, jsObject->Id);
objList->SetString(1, StringUtils::ToNative(jsObject->Name));
objList->SetString(2, StringUtils::ToNative(jsObject->JavascriptName));
objList->SetBool(3, jsObject->IsAsync);
auto methodList = CefListValue::Create();
auto j = 0;
methodList->SetInt(j++, jsObject->Methods->Count);
for each (JavascriptMethod^ jsMethod in jsObject->Methods)
{
SetInt64(methodList, j++, jsMethod->Id);
methodList->SetString(j++, StringUtils::ToNative(jsMethod->ManagedName));
methodList->SetString(j++, StringUtils::ToNative(jsMethod->JavascriptName));
methodList->SetInt(j++, jsMethod->ParameterCount);
}
objList->SetList(4, methodList);
auto propertyList = CefListValue::Create();
j = 0;
propertyList->SetInt(j++, jsObject->Properties->Count);
for each(JavascriptProperty^ jsProperty in jsObject->Properties)
{
SetInt64(propertyList, j++, jsProperty->Id);
propertyList->SetString(j++, StringUtils::ToNative(jsProperty->ManagedName));
propertyList->SetString(j++, StringUtils::ToNative(jsProperty->JavascriptName));
propertyList->SetBool(j++, jsProperty->IsComplexType);
propertyList->SetBool(j++, jsProperty->IsReadOnly);
if (jsProperty->JsObject != nullptr)
{
SerializeJsObject(jsProperty->JsObject, propertyList, j++);
}
else
{
propertyList->SetNull(j++);
}
//TODO: Can we remove this safely? It doesn't appear to actually be used as PropertyValue
//should only be set when using Sync Binding
if (jsProperty->PropertyValue != nullptr)
{
SerializeV8Object(propertyList, j++, jsProperty->PropertyValue, nullptr);
}
else
{
propertyList->SetNull(j++);
}
}
objList->SetList(5, propertyList);
list->SetList(index, objList);
}
void SerializeJsObjects(List<JavascriptObject^>^ objects, const CefRefPtr<CefListValue> &list, int index)
{
auto subList = CefListValue::Create();
auto i = 0;
for each (JavascriptObject^ jsObject in objects)
{
SerializeJsObject(jsObject, subList, i++);
}
list->SetList(index, subList);
}
}
}
}

View file

@ -0,0 +1,20 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_values.h"
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
void SerializeJsObjects(List<JavascriptObject^>^ objects, const CefRefPtr<CefListValue> &list, int index);
}
}
}

View file

@ -0,0 +1,96 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "ObjectsSerialization.h"
#include "Primitives.h"
using namespace System::Collections::Generic;
using namespace System::Dynamic;
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
template<typename TList, typename TIndex>
Object^ DeserializeObject(const CefRefPtr<TList>& list, TIndex index, IJavascriptCallbackFactory^ javascriptCallbackFactory)
{
Object^ result = nullptr;
auto type = list->GetType(index);
if (type == VTYPE_BOOL)
{
result = list->GetBool(index);
}
else if (type == VTYPE_INT)
{
result = list->GetInt(index);
}
else if (IsInt64(list, index))
{
result = GetInt64(list, index);
}
else if (IsCefTime(list, index))
{
auto cefTime = GetCefTime(list, index);
result = ConvertCefTimeToDateTime(cefTime);
}
else if (IsJsCallback(list, index) && javascriptCallbackFactory != nullptr)
{
auto jsCallbackDto = GetJsCallback(list, index);
result = javascriptCallbackFactory->Create(jsCallbackDto);
}
else if (type == VTYPE_DOUBLE)
{
result = list->GetDouble(index);
}
else if (type == VTYPE_STRING)
{
result = StringUtils::ToClr(list->GetString(index));
}
else if (type == VTYPE_LIST)
{
auto subList = list->GetList(index);
auto array = gcnew List<Object^>(subList->GetSize());
for (size_t i = 0; i < subList->GetSize(); i++)
{
array->Add(DeserializeObject(subList, i, javascriptCallbackFactory));
}
result = array;
}
else if (type == VTYPE_DICTIONARY)
{
IDictionary<String^, Object^>^ expandoObj = gcnew ExpandoObject();
auto subDict = list->GetDictionary(index);
std::vector<CefString> keys;
subDict->GetKeys(keys);
for (size_t i = 0; i < keys.size(); i++)
{
auto key = StringUtils::ToClr(keys[i]);
auto value = DeserializeObject(subDict, keys[i], javascriptCallbackFactory);
expandoObj->Add(key, value);
}
result = expandoObj;
}
return result;
}
DateTime ConvertCefTimeToDateTime(CefTime time)
{
auto epoch = time.GetDoubleT();
if (epoch == 0)
{
return DateTime::MinValue;
}
return DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(epoch).ToLocalTime();
}
}
}
}

View file

@ -0,0 +1,31 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/cef_values.h"
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
//separate file because it's needed in the subprocess too at the moment
//Deserializes data into Object from a given index of a CefListValue or CefDictionaryValue
//IJavascriptCallbackFactory implementation should be passed to allow creation of valid javascript callbacks
template<typename TList, typename TIndex>
Object^ DeserializeObject(const CefRefPtr<TList>& list, TIndex index, IJavascriptCallbackFactory^ javascriptCallbackFactory);
//Converts CefTime to DateTime
DateTime ConvertCefTimeToDateTime(CefTime time);
template Object^ DeserializeObject(const CefRefPtr<CefListValue>& list, int index, IJavascriptCallbackFactory^ javascriptCallbackFactory);
template Object^ DeserializeObject(const CefRefPtr<CefDictionaryValue>& list, CefString index, IJavascriptCallbackFactory^ javascriptCallbackFactory);
}
}
}

View file

@ -0,0 +1,139 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "Primitives.h"
#include "include/cef_app.h"
using namespace std;
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
enum class PrimitiveType : unsigned char
{
INT64,
CEFTIME,
JSCALLBACK
};
template<typename TList, typename TIndex>
bool IsType(PrimitiveType type, const CefRefPtr<TList>& list, TIndex index)
{
auto result = list->GetType(index) == VTYPE_BINARY;
if (result)
{
underlying_type<PrimitiveType>::type typeRead;
auto binaryValue = list->GetBinary(index);
binaryValue->GetData(&typeRead, sizeof(underlying_type<PrimitiveType>::type), 0);
result = typeRead == static_cast<underlying_type<PrimitiveType>::type>(type);
}
return result;
}
template<typename TList, typename TIndex>
void SetInt64(const CefRefPtr<TList>& list, TIndex index, const int64 &value)
{
unsigned char mem[1 + sizeof(int64)];
mem[0] = static_cast<unsigned char>(PrimitiveType::INT64);
memcpy(reinterpret_cast<void*>(mem + 1), &value, sizeof(int64));
auto binaryValue = CefBinaryValue::Create(mem, sizeof(mem));
list->SetBinary(index, binaryValue);
}
template<typename TList, typename TIndex>
int64 GetInt64(const CefRefPtr<TList>& list, TIndex index)
{
int64 result;
auto binaryValue = list->GetBinary(index);
binaryValue->GetData(&result, sizeof(int64), 1);
return result;
}
template<typename TList, typename TIndex>
bool IsInt64(const CefRefPtr<TList>& list, TIndex index)
{
return IsType(PrimitiveType::INT64, list, index);
}
template<typename TList, typename TIndex>
void SetCefTime(const CefRefPtr<TList>& list, TIndex index, const CefTime &value)
{
auto doubleT = value.GetDoubleT();
unsigned char mem[1 + sizeof(double)];
mem[0] = static_cast<unsigned char>(PrimitiveType::CEFTIME);
memcpy(reinterpret_cast<void*>(mem + 1), &doubleT, sizeof(double));
auto binaryValue = CefBinaryValue::Create(mem, sizeof(mem));
list->SetBinary(index, binaryValue);
}
template<typename TList, typename TIndex>
CefTime GetCefTime(const CefRefPtr<TList>& list, TIndex index)
{
double doubleT;
auto binaryValue = list->GetBinary(index);
binaryValue->GetData(&doubleT, sizeof(double), 1);
return CefTime(doubleT);
}
template<typename TList, typename TIndex>
bool IsCefTime(const CefRefPtr<TList>& list, TIndex index)
{
return IsType(PrimitiveType::CEFTIME, list, index);
}
template<typename TList, typename TIndex>
void SetJsCallback(const CefRefPtr<TList>& list, TIndex index, JavascriptCallback^ value)
{
auto id = value->Id;
auto browserId = value->BrowserId;
auto frameId = value->FrameId;
unsigned char mem[1 + sizeof(int) + sizeof(int64) + sizeof(int64)];
mem[0] = static_cast<unsigned char>(PrimitiveType::JSCALLBACK);
memcpy(reinterpret_cast<void*>(mem + 1), &browserId, sizeof(int));
memcpy(reinterpret_cast<void*>(mem + 1 + sizeof(int)), &id, sizeof(int64));
memcpy(reinterpret_cast<void*>(mem + 1 + sizeof(int) + sizeof(int64)), &frameId, sizeof(int64));
auto binaryValue = CefBinaryValue::Create(mem, sizeof(mem));
list->SetBinary(index, binaryValue);
}
template<typename TList, typename TIndex>
JavascriptCallback^ GetJsCallback(const CefRefPtr<TList>& list, TIndex index)
{
auto result = gcnew JavascriptCallback();
int64 id;
int browserId;
int64 frameId;
auto binaryValue = list->GetBinary(index);
binaryValue->GetData(&browserId, sizeof(int), 1);
binaryValue->GetData(&id, sizeof(int64), 1 + sizeof(int));
binaryValue->GetData(&frameId, sizeof(int64), 1 + sizeof(int) + sizeof(int64));
result->Id = id;
result->BrowserId = browserId;
result->FrameId = frameId;
return result;
}
template<typename TList, typename TIndex>
bool IsJsCallback(const CefRefPtr<TList>& list, TIndex index)
{
return IsType(PrimitiveType::JSCALLBACK, list, index);
}
}
}
}

View file

@ -0,0 +1,67 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
//Functions to serialize/deserialize specific types into CefBinaryValue
template<typename TList, typename TIndex>
void SetInt64(const CefRefPtr<TList>& list, TIndex index, const int64 &value);
template<typename TList, typename TIndex>
int64 GetInt64(const CefRefPtr<TList>& list, TIndex index);
template<typename TList, typename TIndex>
bool IsInt64(const CefRefPtr<TList>& list, TIndex index);
template<typename TList, typename TIndex>
void SetCefTime(const CefRefPtr<TList>& list, TIndex index, const CefTime &value);
template<typename TList, typename TIndex>
CefTime GetCefTime(const CefRefPtr<TList>& list, TIndex index);
template<typename TList, typename TIndex>
bool IsCefTime(const CefRefPtr<TList>& list, TIndex index);
template<typename TList, typename TIndex>
void SetJsCallback(const CefRefPtr<TList>& list, TIndex index, JavascriptCallback^ value);
template<typename TList, typename TIndex>
JavascriptCallback^ GetJsCallback(const CefRefPtr<TList>& list, TIndex index);
template<typename TList, typename TIndex>
bool IsJsCallback(const CefRefPtr<TList>& list, TIndex index);
template void SetInt64(const CefRefPtr<CefListValue>& list, int index, const int64 &value);
template void SetInt64(const CefRefPtr<CefListValue>& list, size_t index, const int64 &value);
template void SetInt64(const CefRefPtr<CefDictionaryValue>& list, CefString index, const int64 &value);
template int64 GetInt64(const CefRefPtr<CefListValue>& list, int index);
template int64 GetInt64(const CefRefPtr<CefListValue>& list, size_t index);
template int64 GetInt64(const CefRefPtr<CefDictionaryValue>& list, CefString index);
template bool IsInt64(const CefRefPtr<CefListValue>& list, int index);
template bool IsInt64(const CefRefPtr<CefListValue>& list, size_t index);
template bool IsInt64(const CefRefPtr<CefDictionaryValue>& list, CefString index);
template void SetCefTime(const CefRefPtr<CefListValue>& list, int index, const CefTime &value);
template void SetCefTime(const CefRefPtr<CefListValue>& list, size_t index, const CefTime &value);
template void SetCefTime(const CefRefPtr<CefDictionaryValue>& list, CefString index, const CefTime &value);
template CefTime GetCefTime(const CefRefPtr<CefListValue>& list, int index);
template CefTime GetCefTime(const CefRefPtr<CefListValue>& list, size_t index);
template CefTime GetCefTime(const CefRefPtr<CefDictionaryValue>& list, CefString index);
template bool IsCefTime(const CefRefPtr<CefListValue>& list, size_t index);
template bool IsCefTime(const CefRefPtr<CefListValue>& list, int index);
template bool IsCefTime(const CefRefPtr<CefDictionaryValue>& list, CefString index);
template void SetJsCallback(const CefRefPtr<CefListValue>& list, int index, JavascriptCallback^ value);
template void SetJsCallback(const CefRefPtr<CefListValue>& list, size_t index, JavascriptCallback^ value);
template void SetJsCallback(const CefRefPtr<CefDictionaryValue>& list, CefString index, JavascriptCallback^ value);
template JavascriptCallback^ GetJsCallback(const CefRefPtr<CefListValue>& list, int index);
template JavascriptCallback^ GetJsCallback(const CefRefPtr<CefListValue>& list, size_t index);
template JavascriptCallback^ GetJsCallback(const CefRefPtr<CefDictionaryValue>& list, CefString index);
template bool IsJsCallback(const CefRefPtr<CefListValue>& list, int index);
template bool IsJsCallback(const CefRefPtr<CefListValue>& list, size_t index);
template bool IsJsCallback(const CefRefPtr<CefDictionaryValue>& list, CefString index);
}
}
}

View file

@ -0,0 +1,226 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "include\cef_values.h"
#include "include\cef_parser.h"
#include "V8Serialization.h"
#include "Primitives.h"
using namespace System::Collections::Generic;
namespace
{
String^ GetJavascriptName(System::Reflection::MemberInfo^ memberInfo, IJavascriptNameConverter^ nameConverter)
{
if (nameConverter == nullptr)
{
return memberInfo->Name;
}
return nameConverter->ConvertReturnedObjectPropertyAndFieldToNameJavascript(memberInfo);
}
}
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
template<typename TList, typename TIndex>
void SerializeV8Object(const CefRefPtr<TList>& list, const TIndex& index, Object^ obj, IJavascriptNameConverter^ nameConverter)
{
// Collection of ancestors to currently serialised object.
// This enables prevention of endless loops due to cycles in graphs where
// a child references one of its ancestors.
auto ancestors = gcnew HashSet<Object^>();
SerializeV8SimpleObject(list, index, obj, ancestors, nameConverter);
}
template<typename TList, typename TIndex>
void SerializeV8SimpleObject(const CefRefPtr<TList>& list, const TIndex& index, Object^ obj, HashSet<Object^>^ ancestors, IJavascriptNameConverter^ nameConverter)
{
list->SetNull(index);
if (obj == nullptr || ancestors->Contains(obj))
{
return;
}
ancestors->Add(obj);
auto type = obj->GetType();
Type^ underlyingType = Nullable::GetUnderlyingType(type);
if (underlyingType != nullptr) type = underlyingType;
if (type == Boolean::typeid)
{
list->SetBool(index, safe_cast<bool>(obj));
}
else if (type == Int32::typeid)
{
list->SetInt(index, safe_cast<int>(obj));
}
else if (type == String::typeid)
{
list->SetString(index, StringUtils::ToNative(safe_cast<String^>(obj)));
}
else if (type == Double::typeid)
{
list->SetDouble(index, safe_cast<double>(obj));
}
else if (type == Decimal::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else if (type == SByte::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (type == Int16::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (type == Int64::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else if (type == Byte::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (type == UInt16::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (type == UInt32::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else if (type == UInt64::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else if (type == Single::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else if (type == Char::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (type == DateTime::typeid)
{
SetCefTime(list, index, ConvertDateTimeToCefTime(safe_cast<DateTime>(obj)));
}
// Serialize enum to sbyte, short, int, long, byte, ushort, uint, ulong (check type of enum)
else if (type->IsEnum)
{
auto subType = System::Enum::GetUnderlyingType(type);
if (subType == SByte::typeid ||
subType == Int16::typeid ||
subType == Int32::typeid ||
subType == Byte::typeid ||
subType == UInt16::typeid)
{
list->SetInt(index, Convert::ToInt32(obj));
}
else if (subType == Int64::typeid ||
subType == UInt32::typeid ||
subType == UInt64::typeid)
{
list->SetDouble(index, Convert::ToDouble(obj));
}
else
{
//Unexpected type, just convert it to a string
list->SetString(index, StringUtils::ToNative(Convert::ToString(obj)));
}
}
// Serialize dictionary to CefDictionary (key,value pairs)
else if (System::Collections::IDictionary::typeid->IsAssignableFrom(type))
{
auto subDict = CefDictionaryValue::Create();
auto dict = (System::Collections::IDictionary^) obj;
for each (System::Collections::DictionaryEntry kvp in dict)
{
auto fieldName = StringUtils::ToNative(Convert::ToString(kvp.Key));
SerializeV8SimpleObject(subDict, fieldName, kvp.Value, ancestors, nameConverter);
}
list->SetDictionary(index, subDict);
}
else if (System::Collections::IEnumerable::typeid->IsAssignableFrom(type))
{
auto subList = CefListValue::Create();
auto enumerable = (System::Collections::IEnumerable^) obj;
int i = 0;
for each (Object^ arrObj in enumerable)
{
SerializeV8SimpleObject(subList, i, arrObj, ancestors, nameConverter);
i++;
}
list->SetList(index, subList);
}
else if (CefSharp::Web::JsonString::typeid->IsAssignableFrom(type))
{
auto jsonString = (CefSharp::Web::JsonString^) obj;
//Tried to use CefParseJSONAndReturnError, keeps returning error when
//CefParseJson works for the same string, so must be a CEF bug
auto jsonValue = CefParseJSON(StringUtils::ToNative(jsonString->Json),
cef_json_parser_options_t::JSON_PARSER_ALLOW_TRAILING_COMMAS);
if (jsonValue.get())
{
list->SetValue(index, jsonValue);
}
else
{
list->SetString(index, CefString("V8Serialization - Unable to parse JSON"));
}
}
// Serialize class/structs to CefDictionary (key,value pairs)
else if (!type->IsPrimitive && !type->IsEnum)
{
auto fields = type->GetFields();
auto subDict = CefDictionaryValue::Create();
for (int i = 0; i < fields->Length; i++)
{
auto fieldName = GetJavascriptName(fields[i], nameConverter);
auto fieldValue = fields[i]->GetValue(obj);
SerializeV8SimpleObject(subDict, StringUtils::ToNative(fieldName), fieldValue, ancestors, nameConverter);
}
auto properties = type->GetProperties();
for (int i = 0; i < properties->Length; i++)
{
auto propertyName = GetJavascriptName(properties[i], nameConverter);
auto propertyValue = properties[i]->GetValue(obj);
SerializeV8SimpleObject(subDict, StringUtils::ToNative(propertyName), propertyValue, ancestors, nameConverter);
}
list->SetDictionary(index, subDict);
}
else
{
list->SetString(index, StringUtils::ToNative("Unable to serialize Type - " + obj->GetType()->ToString()));
}
ancestors->Remove(obj);
}
CefTime ConvertDateTimeToCefTime(DateTime dateTime)
{
auto timeSpan = dateTime.ToUniversalTime() - DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind::Utc);
return CefTime(timeSpan.TotalSeconds);
}
}
}
}

View file

@ -0,0 +1,29 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
using namespace CefSharp::JavascriptBinding;
namespace CefSharp
{
namespace Internals
{
namespace Serialization
{
//Functions to serialize/deserialize data returned/sent from/to the render process.
//Serializes data into a given position in a CefListValue or CefDictionaryValue
template<typename TList, typename TIndex>
void SerializeV8Object(const CefRefPtr<TList>& list, const TIndex& index, Object^ obj, IJavascriptNameConverter^ nameConverter);
template<typename TList, typename TIndex>
void SerializeV8SimpleObject(const CefRefPtr<TList>& list, const TIndex& index, Object^ obj, HashSet<Object^>^ seen, IJavascriptNameConverter^ nameConverter);
template void SerializeV8Object(const CefRefPtr<CefListValue>& list, const int& index, Object^ obj, IJavascriptNameConverter^ nameConverter);
template void SerializeV8Object(const CefRefPtr<CefListValue>& list, const size_t& index, Object^ obj, IJavascriptNameConverter^ nameConverter);
template void SerializeV8Object(const CefRefPtr<CefDictionaryValue>& list, const CefString& index, Object^ obj, IJavascriptNameConverter^ nameConverter);
}
}
}

View file

@ -0,0 +1,145 @@
// Copyright © 2013 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include <vector>
#include <sstream>
#include "vcclr_local.h"
#include "include\cef_v8.h"
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Diagnostics;
namespace CefSharp
{
namespace Internals
{
private class StringUtils
{
public:
/// <summary>
/// Converts an unmanaged string to a (managed) .NET string.
/// </summary>
/// <param name="cefStr">The string that should be converted.</param>
/// <returns>A .NET string.</returns>
[DebuggerStepThrough]
static String^ StringUtils::ToClr(const cef_string_t& cefStr)
{
return gcnew String(cefStr.str);
}
/// <summary>
/// Converts an unmanaged string to a (managed) .NET string.
/// </summary>
/// <param name="cefStr">The string that should be converted.</param>
/// <returns>A .NET string.</returns>
[DebuggerStepThrough]
static String^ StringUtils::ToClr(const CefString& cefStr)
{
return gcnew String(cefStr.c_str());
}
/// <summary>
/// Converts an unmanaged vector of strings to a (managed) .NET List of strings.
/// </summary>
/// <param name="cefStr">The vector of strings that should be converted.</param>
/// <returns>A .NET List of strings.</returns>
[DebuggerStepThrough]
static List<String^>^ ToClr(const std::vector<CefString>& cefStr)
{
auto result = gcnew List<String^>();
for each(CefString s in cefStr)
{
result->Add(StringUtils::ToClr(s));
}
return result;
}
/// <summary>
/// Converts a .NET string to native (unmanaged) format. Note that this method does not allocate a new copy of the
// string, but rather returns a pointer to the memory in the existing managed String object.
/// </summary>
/// <param name="str">The string that should be converted.</param>
/// <returns>An unmanaged representation of the provided string, or an empty string if the input string is a nullptr.</returns>
[DebuggerStepThrough]
static CefString ToNative(String^ str)
{
if (str == nullptr)
{
return CefString();
}
pin_ptr<const wchar_t> pStr = PtrToStringChars(str);
CefString cefStr(pStr);
return cefStr;
}
/// <summary>
/// Converts a .NET List of strings to native (unmanaged) format.
/// </summary>
/// <param name="str">The List of strings that should be converted.</param>
/// <returns>An unmanaged representation of the provided List of strings, or an empty List if the input is a nullptr.</returns>
[DebuggerStepThrough]
static std::vector<CefString> ToNative(IEnumerable<String^>^ str)
{
if (str == nullptr)
{
return std::vector<CefString>();
}
std::vector<CefString> result = std::vector<CefString>();
for each (String^ s in str)
{
result.push_back(StringUtils::ToNative(s));
}
return result;
}
/// <summary>
/// Assigns the provided cef_string_t object from the given .NET string.
/// </summary>
/// <param name="cefStr">The cef_string_t that should be updated.</param>
/// <param name="str">The .NET string whose value should be used to update cefStr.</param>
[DebuggerStepThrough]
static void StringUtils::AssignNativeFromClr(cef_string_t& cefStr, String^ str)
{
cef_string_clear(&cefStr);
if (str != nullptr)
{
pin_ptr<const wchar_t> pStr = PtrToStringChars(str);
cef_string_copy(pStr, str->Length, &cefStr);
}
}
/// <summary>
/// Creates a detailed expection string from a provided Cef V8 exception.
/// </summary>
/// <param name="exception">The exception which will be used as base for the message</param>
[DebuggerStepThrough]
static CefString CreateExceptionString(CefRefPtr<CefV8Exception> exception)
{
if (exception.get())
{
std::wstringstream logMessageBuilder;
logMessageBuilder << exception->GetMessage().c_str() << L"\n@ ";
if (!exception->GetScriptResourceName().empty())
{
logMessageBuilder << exception->GetScriptResourceName().c_str();
}
logMessageBuilder << L":" << exception->GetLineNumber() << L":" << exception->GetStartColumn();
return CefString(logMessageBuilder.str());
}
return "Exception occured but the Cef V8 exception is null";
}
};
}
}

View file

@ -0,0 +1,351 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include/internal/cef_ptr.h"
#include "include\cef_download_item.h"
#include "include\cef_response.h"
#include "include\cef_web_plugin.h"
#include "Serialization\ObjectsSerialization.h"
#include "Serialization\V8Serialization.h"
using namespace System::Collections::Generic;
using namespace System::Collections::Specialized;
using namespace System::Security::Cryptography::X509Certificates;
using namespace CefSharp::Internals::Serialization;
namespace CefSharp
{
namespace Internals
{
//Static class for converting to/from Cef classes
private ref class TypeConversion abstract sealed
{
public:
//Convert from NameValueCollection to HeaderMap
static CefResponse::HeaderMap ToNative(NameValueCollection^ headers)
{
CefResponse::HeaderMap result;
if (headers == nullptr)
{
return result;
}
for each (String^ key in headers)
{
for each(String^ value in headers->GetValues(key))
{
result.insert(std::pair<CefString, CefString>(StringUtils::ToNative(key), StringUtils::ToNative(value)));
}
}
return result;
}
//ConvertFrom CefDownload to DownloadItem
static DownloadItem^ FromNative(CefRefPtr<CefDownloadItem> downloadItem)
{
auto item = gcnew CefSharp::DownloadItem();
item->IsValid = downloadItem->IsValid();
//NOTE: Description for IsValid says `Do not call any other methods if this function returns false.` so only load if IsValid = true
if (item->IsValid)
{
item->IsInProgress = downloadItem->IsInProgress();
item->IsComplete = downloadItem->IsComplete();
item->IsCancelled = downloadItem->IsCanceled();
item->CurrentSpeed = downloadItem->GetCurrentSpeed();
item->PercentComplete = downloadItem->GetPercentComplete();
item->TotalBytes = downloadItem->GetTotalBytes();
item->ReceivedBytes = downloadItem->GetReceivedBytes();
item->StartTime = FromNative(downloadItem->GetStartTime());
item->EndTime = FromNative(downloadItem->GetEndTime());
item->FullPath = StringUtils::ToClr(downloadItem->GetFullPath());
item->Id = downloadItem->GetId();
item->Url = StringUtils::ToClr(downloadItem->GetURL());
item->OriginalUrl = StringUtils::ToClr(downloadItem->GetOriginalUrl());
item->SuggestedFileName = StringUtils::ToClr(downloadItem->GetSuggestedFileName());
item->ContentDisposition = StringUtils::ToClr(downloadItem->GetContentDisposition());
item->MimeType = StringUtils::ToClr(downloadItem->GetMimeType());
}
return item;
}
//Convert from CefTime to Nullable<DateTime>
static Nullable<DateTime> FromNative(CefTime time)
{
auto epoch = time.GetDoubleT();
if (epoch == 0)
{
return Nullable<DateTime>();
}
return Nullable<DateTime>(DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(epoch).ToLocalTime());
}
static WebPluginInfo^ FromNative(CefRefPtr<CefWebPluginInfo> webPluginInfo)
{
return gcnew WebPluginInfo(StringUtils::ToClr(webPluginInfo->GetName()),
StringUtils::ToClr(webPluginInfo->GetDescription()),
StringUtils::ToClr(webPluginInfo->GetPath()),
StringUtils::ToClr(webPluginInfo->GetVersion()));
}
static IList<DraggableRegion>^ FromNative(const std::vector<CefDraggableRegion>& regions)
{
if (regions.size() == 0)
{
return nullptr;
}
auto list = gcnew List<DraggableRegion>();
for each (CefDraggableRegion region in regions)
{
list->Add(DraggableRegion(region.bounds.width, region.bounds.height, region.bounds.x, region.bounds.y, region.draggable == 1));
}
return list;
}
static CefRefPtr<CefValue> ToNative(Object^ value)
{
auto cefValue = CefValue::Create();
if (value == nullptr)
{
cefValue->SetNull();
return cefValue;
}
auto type = value->GetType();
Type^ underlyingType = Nullable::GetUnderlyingType(type);
if (underlyingType != nullptr)
{
type = underlyingType;
}
if (type == Boolean::typeid)
{
cefValue->SetBool(safe_cast<bool>(value));
}
else if (type == Int32::typeid)
{
cefValue->SetInt(safe_cast<int>(value));
}
else if (type == String::typeid)
{
cefValue->SetString(StringUtils::ToNative(safe_cast<String^>(value)));
}
else if (type == Double::typeid)
{
cefValue->SetDouble(safe_cast<double>(value));
}
else if (type == Decimal::typeid)
{
cefValue->SetDouble(Convert::ToDouble(value));
}
else if (System::Collections::IDictionary::typeid->IsAssignableFrom(type))
{
auto dictionary = (System::Collections::IDictionary^) value;
auto cefDictionary = CefDictionaryValue::Create();
for each (System::Collections::DictionaryEntry entry in dictionary)
{
auto key = StringUtils::ToNative(Convert::ToString(entry.Key));
auto entryValue = entry.Value;
//We don't pass a nameConverter here as the keys should
//remain unchanged
SerializeV8Object(cefDictionary, key, entryValue, nullptr);
}
cefValue->SetDictionary(cefDictionary);
}
else if (System::Collections::IEnumerable::typeid->IsAssignableFrom(type))
{
auto enumerable = (System::Collections::IEnumerable^) value;
auto cefList = CefListValue::Create();
int i = 0;
for each (Object^ arrObj in enumerable)
{
//We don't pass a nameConverter here as the keys should
//remain unchanged
SerializeV8Object(cefList, i, arrObj, nullptr);
i++;
}
cefValue->SetList(cefList);
}
return cefValue;
}
static Object^ FromNative(const CefRefPtr<CefValue>& value)
{
if (!value.get())
{
return nullptr;
}
auto type = value->GetType();
if (type == CefValueType::VTYPE_BOOL)
{
return value->GetBool();
}
if (type == CefValueType::VTYPE_DOUBLE)
{
return value->GetDouble();
}
if (type == CefValueType::VTYPE_INT)
{
return value->GetInt();
}
if (type == CefValueType::VTYPE_STRING)
{
return StringUtils::ToClr(value->GetString());
}
if (type == CefValueType::VTYPE_DICTIONARY)
{
return FromNative(value->GetDictionary());
}
if (type == CefValueType::VTYPE_LIST)
{
return FromNative(value->GetList());
}
return nullptr;
}
static IDictionary<String^, Object^>^ FromNative(const CefRefPtr<CefDictionaryValue>& dictionary)
{
if (!dictionary.get() || dictionary->GetSize() == 0)
{
return nullptr;
}
auto dict = gcnew Dictionary<String^, Object^>();
CefDictionaryValue::KeyList keys;
dictionary->GetKeys(keys);
for (size_t i = 0; i < keys.size(); i++)
{
auto key = StringUtils::ToClr(keys[i]);
auto value = DeserializeObject(dictionary, keys[i], nullptr);
dict->Add(key, value);
}
return dict;
}
static List<Object^>^ FromNative(const CefRefPtr<CefListValue>& list)
{
auto result = gcnew List<Object^>(list->GetSize());
for (size_t i = 0; i < list->GetSize(); i++)
{
result->Add(DeserializeObject(list, i, nullptr));
}
return result;
}
// Copied from CefSharp.BrowserSubprocess.Core\TypeUtils.h since it can't be included
static DateTime ConvertCefTimeToDateTime(CefTime time)
{
return DateTimeUtils::FromCefTime(time.year,
time.month,
time.day_of_month,
time.hour,
time.minute,
time.second,
time.millisecond);
}
static Cookie^ FromNative(const CefCookie& cefCookie)
{
auto cookie = gcnew Cookie();
auto cookieName = StringUtils::ToClr(cefCookie.name);
if (!String::IsNullOrEmpty(cookieName))
{
cookie->Name = cookieName;
cookie->Value = StringUtils::ToClr(cefCookie.value);
cookie->Domain = StringUtils::ToClr(cefCookie.domain);
cookie->Path = StringUtils::ToClr(cefCookie.path);
cookie->Secure = cefCookie.secure == 1;
cookie->HttpOnly = cefCookie.httponly == 1;
cookie->Creation = ConvertCefTimeToDateTime(cefCookie.creation);
cookie->LastAccess = ConvertCefTimeToDateTime(cefCookie.last_access);
cookie->SameSite = (CefSharp::Enums::CookieSameSite)cefCookie.same_site;
cookie->Priority = (CefSharp::Enums::CookiePriority)cefCookie.priority;
if (cefCookie.has_expires)
{
cookie->Expires = ConvertCefTimeToDateTime(cefCookie.expires);
}
}
return cookie;
}
static NavigationEntry^ FromNative(const CefRefPtr<CefNavigationEntry> entry, bool current)
{
SslStatus^ sslStatus;
if (!entry.get())
{
return nullptr;
}
if (!entry->IsValid())
{
return gcnew NavigationEntry(current, DateTime::MinValue, nullptr, -1, nullptr, nullptr, (TransitionType)-1, nullptr, false, false, sslStatus);
}
auto time = entry->GetCompletionTime();
DateTime completionTime = CefTimeUtils::ConvertCefTimeToDateTime(time.GetDoubleT());
auto ssl = entry->GetSSLStatus();
X509Certificate2^ sslCertificate;
if (ssl.get())
{
auto certificate = ssl->GetX509Certificate();
if (certificate.get())
{
auto derEncodedCertificate = certificate->GetDEREncoded();
auto byteCount = derEncodedCertificate->GetSize();
if (byteCount > 0)
{
auto bytes = gcnew cli::array<Byte>(byteCount);
pin_ptr<Byte> src = &bytes[0]; // pin pointer to first element in arr
derEncodedCertificate->GetData(static_cast<void*>(src), byteCount, 0);
sslCertificate = gcnew X509Certificate2(bytes);
}
}
sslStatus = gcnew SslStatus(ssl->IsSecureConnection(), (CertStatus)ssl->GetCertStatus(), (SslVersion)ssl->GetSSLVersion(), (SslContentStatus)ssl->GetContentStatus(), sslCertificate);
}
return gcnew NavigationEntry(current, completionTime, StringUtils::ToClr(entry->GetDisplayURL()), entry->GetHttpStatusCode(),
StringUtils::ToClr(entry->GetOriginalURL()), StringUtils::ToClr(entry->GetTitle()), (TransitionType)entry->GetTransitionType(),
StringUtils::ToClr(entry->GetURL()), entry->HasPostData(), true, sslStatus);
}
};
}
}

View file

@ -0,0 +1,219 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "ManagedCefBrowserAdapter.h"
#include "WindowInfo.h"
#include "Internals\Messaging\Messages.h"
#include "Internals\CefFrameWrapper.h"
#include "Internals\CefBrowserWrapper.h"
#include "Internals\Serialization\Primitives.h"
#include "Internals\Serialization\JsObjectsSerialization.h"
using namespace CefSharp::Internals::Serialization;
using namespace CefSharp::Internals::Messaging;
namespace CefSharp
{
namespace Core
{
bool ManagedCefBrowserAdapter::IsDisposed::get()
{
return _isDisposed;
}
void ManagedCefBrowserAdapter::CreateBrowser(IWindowInfo^ windowInfo, IBrowserSettings^ browserSettings, IRequestContext^ requestContext, String^ address)
{
auto cefWindowInfoWrapper = static_cast<WindowInfo^>(windowInfo);
CefString addressNative = StringUtils::ToNative(address);
if (browserSettings == nullptr)
{
throw gcnew ArgumentNullException("browserSettings", "cannot be null");
}
if (browserSettings->IsDisposed)
{
throw gcnew ObjectDisposedException("browserSettings", "browser settings has already been disposed. " +
"BrowserSettings created by CefSharp are automatically disposed, to control the lifecycle create and set your own instance.");
}
auto objectRepository = _javaScriptObjectRepository;
//It's no longer possible to change these settings
objectRepository->Settings->Freeze();
CefRefPtr<CefDictionaryValue> extraInfo = CefDictionaryValue::Create();
auto legacyBindingEnabled = false;
if (objectRepository->Settings->LegacyBindingEnabled)
{
auto legacyBoundObjects = objectRepository->GetLegacyBoundObjects();
legacyBindingEnabled = objectRepository->HasBoundObjects;
//For legacy binding we only add values if we have bond objects.
if (legacyBindingEnabled)
{
auto listValue = CefListValue::Create();
SerializeJsObjects(legacyBoundObjects, listValue, 0);
extraInfo->SetList("LegacyBindingObjects", listValue);
}
}
extraInfo->SetBool("LegacyBindingEnabled", legacyBindingEnabled);
if (!String::IsNullOrEmpty(objectRepository->Settings->JavascriptBindingApiGlobalObjectName))
{
auto globalObjName = objectRepository->Settings->JavascriptBindingApiGlobalObjectName;
if (StringCheck::IsFirstCharacterLowercase(globalObjName))
{
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(globalObjName));
}
else
{
extraInfo->SetString("JsBindingPropertyName", StringUtils::ToNative(globalObjName));
}
}
CefRefPtr<CefRequestContext> requestCtx;
if (requestContext != nullptr)
{
auto managedRequestCtx = (RequestContext^)requestContext->UnWrap();
requestCtx = static_cast<CefRefPtr<CefRequestContext>>(managedRequestCtx);
}
auto bSettings = (BrowserSettings^)browserSettings->UnWrap();
if (!CefBrowserHost::CreateBrowser(*cefWindowInfoWrapper->GetWindowInfo(), _clientAdapter.get(), addressNative,
*bSettings->_browserSettings, extraInfo, requestCtx))
{
throw gcnew InvalidOperationException("CefBrowserHost::CreateBrowser call failed, review the CEF log file for more details.");
}
delete windowInfo;
}
#ifndef NETCOREAPP
// NOTE: This was moved out of OnAfterBrowserCreated to prevent the System.ServiceModel assembly from being loaded when WCF is not enabled.
__declspec(noinline) void ManagedCefBrowserAdapter::InitializeBrowserProcessServiceHost(IBrowser^ browser)
{
_browserProcessServiceHost = gcnew BrowserProcessServiceHost(_javaScriptObjectRepository, Process::GetCurrentProcess()->Id, browser->Identifier, _javascriptCallbackFactory);
//NOTE: Attempt to solve timing issue where browser is opened and rapidly disposed. In some cases a call to Open throws
// an exception about the process already being closed. Two relevant issues are #862 and #804.
if (_browserProcessServiceHost->State == CommunicationState::Created)
{
try
{
_browserProcessServiceHost->Open();
}
catch (Exception^)
{
//Ignore exception as it's likely cause when the browser is closing
}
}
}
// NOTE: This was moved out of ~ManagedCefBrowserAdapter to prevent the System.ServiceModel assembly from being loaded when WCF is not enabled.
__declspec(noinline) void ManagedCefBrowserAdapter::DisposeBrowserProcessServiceHost()
{
if (_browserProcessServiceHost != nullptr)
{
if (CefSharpSettings::WcfTimeout > TimeSpan::Zero)
{
_browserProcessServiceHost->Close(CefSharpSettings::WcfTimeout);
}
else
{
_browserProcessServiceHost->Abort();
}
_browserProcessServiceHost = nullptr;
}
}
#endif
void ManagedCefBrowserAdapter::OnAfterBrowserCreated(IBrowser^ browser)
{
if (!_isDisposed)
{
_browserWrapper = browser;
_javascriptCallbackFactory->BrowserAdapter = gcnew WeakReference<IBrowserAdapter^>(this);
//Browser has been initialized, it's now too late to register a sync JSB object if Wcf wasn't enabled
_javaScriptObjectRepository->IsBrowserInitialized = true;
#ifndef NETCOREAPP
if (CefSharpSettings::WcfEnabled)
{
InitializeBrowserProcessServiceHost(browser);
}
#endif
if (_webBrowserInternal != nullptr)
{
_webBrowserInternal->OnAfterBrowserCreated(browser);
}
}
}
void ManagedCefBrowserAdapter::Resize(int width, int height)
{
HWND browserHwnd = _clientAdapter->GetBrowserHwnd();
if (browserHwnd)
{
if (width == 0 && height == 0)
{
// For windowed browsers when the frame window is minimized set the
// browser window size to 0x0 to reduce resource usage.
SetWindowPos(browserHwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
else
{
SetWindowPos(browserHwnd, NULL, 0, 0, width, height, SWP_NOZORDER);
}
}
}
IBrowser^ ManagedCefBrowserAdapter::GetBrowser(int browserId)
{
return _clientAdapter->GetBrowserWrapper(browserId);
}
IJavascriptCallbackFactory^ ManagedCefBrowserAdapter::JavascriptCallbackFactory::get()
{
return _javascriptCallbackFactory;
}
IJavascriptObjectRepositoryInternal^ ManagedCefBrowserAdapter::JavascriptObjectRepository::get()
{
return _javaScriptObjectRepository;
}
IMethodRunnerQueue^ ManagedCefBrowserAdapter::MethodRunnerQueue::get()
{
return _methodRunnerQueue;
}
void ManagedCefBrowserAdapter::MethodInvocationComplete(Object^ sender, MethodInvocationCompleteArgs^ e)
{
auto result = e->Result;
if (result->CallbackId.HasValue)
{
_clientAdapter->MethodInvocationComplete(result);
}
}
MCefRefPtr<ClientAdapter> ManagedCefBrowserAdapter::GetClientAdapter()
{
return _clientAdapter;
}
}
}

View file

@ -0,0 +1,155 @@
// Copyright © 2013 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEFSHARP_CORE_MANAGEDCEFBROWSERADAPTER_H_
#define CEFSHARP_CORE_MANAGEDCEFBROWSERADAPTER_H_
#pragma once
#include "Stdafx.h"
#include "include\cef_client.h"
#include "BrowserSettings.h"
#include "RequestContext.h"
#include "Internals/ClientAdapter.h"
#include "Internals/RenderClientAdapter.h"
#include "Internals/JavascriptCallbackFactory.h"
using namespace System::Diagnostics;
#ifndef NETCOREAPP
using namespace System::ServiceModel;
using namespace CefSharp::Internals::Wcf;
#endif
using namespace System::Threading;
using namespace System::Threading::Tasks;
namespace CefSharp
{
namespace Core
{
/// <exclude />
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class ManagedCefBrowserAdapter : public IBrowserAdapter
{
MCefRefPtr<ClientAdapter> _clientAdapter;
#ifndef NETCOREAPP
BrowserProcessServiceHost^ _browserProcessServiceHost;
#endif
IWebBrowserInternal^ _webBrowserInternal;
IJavascriptObjectRepositoryInternal^ _javaScriptObjectRepository;
JavascriptCallbackFactory^ _javascriptCallbackFactory;
IMethodRunnerQueue^ _methodRunnerQueue;
IBrowser^ _browserWrapper;
bool _isDisposed;
private:
void MethodInvocationComplete(Object^ sender, MethodInvocationCompleteArgs^ e);
#ifndef NETCOREAPP
void InitializeBrowserProcessServiceHost(IBrowser^ browser);
void DisposeBrowserProcessServiceHost();
#endif
internal:
MCefRefPtr<ClientAdapter> GetClientAdapter();
public:
ManagedCefBrowserAdapter(IWebBrowserInternal^ webBrowserInternal, bool offScreenRendering)
: _isDisposed(false)
{
if (offScreenRendering)
{
_clientAdapter = new RenderClientAdapter(webBrowserInternal, this);
}
else
{
_clientAdapter = new ClientAdapter(webBrowserInternal, this);
}
_webBrowserInternal = webBrowserInternal;
_javaScriptObjectRepository = gcnew CefSharp::Internals::JavascriptObjectRepository();
_javascriptCallbackFactory = gcnew CefSharp::Internals::JavascriptCallbackFactory(_clientAdapter->GetPendingTaskRepository());
if (CefSharpSettings::ConcurrentTaskExecution)
{
_methodRunnerQueue = gcnew CefSharp::Internals::ConcurrentMethodRunnerQueue(_javaScriptObjectRepository);
}
else
{
_methodRunnerQueue = gcnew CefSharp::Internals::MethodRunnerQueue(_javaScriptObjectRepository);
}
_methodRunnerQueue->MethodInvocationComplete += gcnew EventHandler<MethodInvocationCompleteArgs^>(this, &ManagedCefBrowserAdapter::MethodInvocationComplete);
}
!ManagedCefBrowserAdapter()
{
_clientAdapter = nullptr;
}
~ManagedCefBrowserAdapter()
{
_isDisposed = true;
// Stop the method runner before releasing browser adapter and browser wrapper (#2529)
if (_methodRunnerQueue != nullptr)
{
_methodRunnerQueue->MethodInvocationComplete -= gcnew EventHandler<MethodInvocationCompleteArgs^>(this, &ManagedCefBrowserAdapter::MethodInvocationComplete);
delete _methodRunnerQueue;
_methodRunnerQueue = nullptr;
}
// Release the MCefRefPtr<ClientAdapter> reference
// before calling _browserWrapper->CloseBrowser(true)
this->!ManagedCefBrowserAdapter();
if (_browserWrapper != nullptr)
{
_browserWrapper->CloseBrowser(true);
delete _browserWrapper;
_browserWrapper = nullptr;
}
#ifndef NETCOREAPP
if (CefSharpSettings::WcfEnabled)
{
DisposeBrowserProcessServiceHost();
}
#endif
_webBrowserInternal = nullptr;
delete _javaScriptObjectRepository;
_javaScriptObjectRepository = nullptr;
}
virtual property bool IsDisposed
{
bool get();
}
virtual void OnAfterBrowserCreated(IBrowser^ browser);
virtual void CreateBrowser(IWindowInfo^ windowInfo, IBrowserSettings^ browserSettings, IRequestContext^ requestContext, String^ address);
virtual void Resize(int width, int height);
virtual IBrowser^ GetBrowser(int browserId);
virtual property IJavascriptCallbackFactory^ JavascriptCallbackFactory
{
CefSharp::Internals::IJavascriptCallbackFactory^ get();
}
virtual property IJavascriptObjectRepositoryInternal^ JavascriptObjectRepository
{
CefSharp::Internals::IJavascriptObjectRepositoryInternal^ get();
}
virtual property IMethodRunnerQueue^ MethodRunnerQueue
{
CefSharp::Internals::IMethodRunnerQueue^ get();
}
};
}
}
#endif // CEFSHARP_CORE_INTERNALS_CLIENTADAPTER_H_

View file

@ -0,0 +1,64 @@
// Copyright © 2014 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "NativeMethodWrapper.h"
namespace CefSharp
{
namespace Core
{
void NativeMethodWrapper::MemoryCopy(IntPtr dest, IntPtr src, int numberOfBytes)
{
RtlCopyMemory(dest.ToPointer(), src.ToPointer(), numberOfBytes);
}
bool NativeMethodWrapper::IsFocused(IntPtr handle)
{
// Ask Windows which control has the focus and then check if it's one of our children
auto focusControl = GetFocus();
return focusControl != 0 && (IsChild((HWND)handle.ToPointer(), focusControl) == 1);
}
void NativeMethodWrapper::SetWindowPosition(IntPtr handle, int x, int y, int width, int height)
{
HWND browserHwnd = static_cast<HWND>(handle.ToPointer());
if (browserHwnd)
{
if (width == 0 && height == 0)
{
// For windowed browsers when the frame window is minimized set the
// browser window size to 0x0 to reduce resource usage.
SetWindowPos(browserHwnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
}
else
{
SetWindowPos(browserHwnd, NULL, x, y, width, height, SWP_NOZORDER);
}
}
}
void NativeMethodWrapper::SetWindowParent(IntPtr child, IntPtr newParent)
{
HWND childHwnd = static_cast<HWND>(child.ToPointer());
HWND newParentHwnd = static_cast<HWND>(newParent.ToPointer());
SetParent(childHwnd, newParentHwnd);
}
void NativeMethodWrapper::RemoveExNoActivateStyle(IntPtr browserHwnd)
{
HWND hwnd = static_cast<HWND>(browserHwnd.ToPointer());
auto exStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
if (exStyle & WS_EX_NOACTIVATE)
{
//Remove WS_EX_NOACTIVATE
SetWindowLongPtr(hwnd, GWL_EXSTYLE, exStyle & ~WS_EX_NOACTIVATE);
}
}
}
}

View file

@ -0,0 +1,28 @@
// Copyright © 2012 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
namespace CefSharp
{
namespace Core
{
/// <exclude />
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class NativeMethodWrapper sealed
{
public:
//Method cannot be called CopyMemory/RtlCopyMemroy as that's a macro name
//Length is currently int, update if required to handle larger data structures
//(int is plenty big enough for our current use case)
static void MemoryCopy(IntPtr dest, IntPtr src, int numberOfBytes);
static bool IsFocused(IntPtr handle);
static void SetWindowPosition(IntPtr handle, int x, int y, int width, int height);
static void SetWindowParent(IntPtr child, IntPtr newParent);
static void RemoveExNoActivateStyle(IntPtr browserHwnd);
};
}
}

View file

@ -0,0 +1,85 @@
// Copyright © 2016 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
namespace CefSharp
{
namespace Core
{
/// <summary>
/// Class representing popup window features.
/// </summary>
/// <exclude />
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class PopupFeatures : IPopupFeatures
{
private:
const CefPopupFeatures* _popupFeatures;
internal:
/// <summary>
/// Constructor.
/// </summary>
/// <param name="popupFeatures">The popup features.</param>
PopupFeatures(const CefPopupFeatures* popupFeatures)
{
_popupFeatures = popupFeatures;
}
public:
!PopupFeatures()
{
_popupFeatures = NULL;
}
~PopupFeatures()
{
this->!PopupFeatures();
}
virtual property System::Nullable<int> X
{
System::Nullable<int> get() { return _popupFeatures->xSet ? _popupFeatures->x : Nullable<int>(); }
}
virtual property System::Nullable<int> Y
{
System::Nullable<int> get() { return _popupFeatures->ySet ? _popupFeatures->y : Nullable<int>(); }
}
virtual property System::Nullable<int> Width
{
System::Nullable<int> get() { return _popupFeatures->widthSet ? _popupFeatures->width : Nullable<int>(); }
}
virtual property System::Nullable<int> Height
{
System::Nullable<int> get() { return _popupFeatures->heightSet ? _popupFeatures->height : Nullable<int>(); }
}
virtual property bool MenuBarVisible
{
bool get() { return _popupFeatures->menuBarVisible == 1; }
}
virtual property bool StatusBarVisible
{
bool get() { return _popupFeatures->statusBarVisible == 1; }
}
virtual property bool ToolBarVisible
{
bool get() { return _popupFeatures->toolBarVisible == 1; }
}
virtual property bool ScrollbarsVisible
{
bool get() { return _popupFeatures->scrollbarsVisible == 1; }
}
};
}
}

View file

@ -0,0 +1,243 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request.h"
#include "PostDataElement.h"
#include "Internals\TypeConversion.h"
#include "Internals\CefWrapper.h"
using namespace System::Collections::Generic;
using namespace System::Collections::ObjectModel;
namespace CefSharp
{
namespace Core
{
/// <summary>
/// Form Post Data
/// </summary>
/// <seealso cref="T:IPostData"/>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class PostData : public IPostData, public CefWrapper
{
MCefRefPtr<CefPostData> _postData;
List<IPostDataElement^>^ _postDataElements;
internal:
PostData(CefRefPtr<CefPostData> &postData) :
_postData(postData)
{
}
/// <summary>
/// Finalizer.
/// </summary>
!PostData()
{
_postData = nullptr;
}
/// <summary>
/// Destructor.
/// </summary>
~PostData()
{
this->!PostData();
if (_postDataElements != nullptr)
{
//Make sure the unmanaged resources are handled
for each (IPostDataElement^ element in _postDataElements)
{
delete element;
}
_postDataElements = nullptr;
}
_disposed = true;
}
/// <summary>
/// Throw exception if Readonly
/// </summary>
/// <exception cref="Exception">Thrown when an exception error condition occurs.</exception>
void ThrowIfReadOnly()
{
if (IsReadOnly)
{
throw gcnew Exception(gcnew String(L"This IPostDataWrapper is readonly and cannot be modified."));
}
}
operator CefRefPtr<CefPostData>()
{
if (this == nullptr)
{
return NULL;
}
return _postData.get();
}
public:
/// <summary>
/// Default constructor.
/// </summary>
PostData()
{
_postData = CefPostData::Create();
}
/// <summary>
/// Returns true if this object is read-only.
/// </summary>
virtual property bool IsReadOnly
{
bool get()
{
ThrowIfDisposed();
return _postData->IsReadOnly();
}
}
/// <summary>
/// Retrieve the post data elements.
/// </summary>
virtual property IList<IPostDataElement^>^ Elements
{
IList<IPostDataElement^>^ get()
{
ThrowIfDisposed();
if (_postDataElements == nullptr)
{
_postDataElements = gcnew List<IPostDataElement^>();
auto elementCount = _postData.get() ? _postData->GetElementCount() : 0;
if (elementCount == 0)
{
return gcnew ReadOnlyCollection<IPostDataElement^>(_postDataElements);
}
CefPostData::ElementVector ev;
_postData->GetElements(ev);
for (CefPostData::ElementVector::iterator it = ev.begin(); it != ev.end(); ++it)
{
CefPostDataElement *el = it->get();
_postDataElements->Add(gcnew PostDataElement(el));
}
}
return gcnew ReadOnlyCollection<IPostDataElement^>(_postDataElements);
}
}
/// <summary>
/// Add the specified <see cref="IPostDataElement"/>.
/// </summary>
/// <param name="element">element to be added.</param>
/// <returns>Returns true if the add succeeds.</returns>
virtual bool AddElement(IPostDataElement^ element)
{
ThrowIfDisposed();
ThrowIfReadOnly();
//Access the Elements collection to initialize the underlying _postDataElements collection
auto elements = Elements;
//If the element has already been added then don't add it again
if (elements->Contains(element))
{
return false;
}
_postDataElements->Add(element);
auto elementWrapper = (PostDataElement^)element->UnWrap();
return _postData->AddElement(elementWrapper);
}
/// <summary>
/// Remove the specified <see cref="IPostDataElement"/>.
/// </summary>
/// <param name="element">element to be removed.</param>
/// <returns> Returns true if the add succeeds.</returns>
virtual bool RemoveElement(IPostDataElement^ element)
{
ThrowIfDisposed();
ThrowIfReadOnly();
//Access the Elements collection to initialize the underlying _postDataElements collection
auto elements = Elements;
if (!elements->Contains(element))
{
return false;
}
_postDataElements->Remove(element);
auto elementWrapper = (PostDataElement^)element->UnWrap();
return _postData->RemoveElement(elementWrapper);
}
/// <summary>
/// Remove all existing post data elements.
/// </summary>
virtual void RemoveElements()
{
ThrowIfDisposed();
ThrowIfReadOnly();
_postData->RemoveElements();
}
/// <summary>
/// Create a new <see cref="IPostDataElement"/> instance
/// </summary>
/// <returns>PostDataElement</returns>
virtual IPostDataElement^ CreatePostDataElement()
{
auto element = CefPostDataElement::Create();
return gcnew PostDataElement(element);
}
/// <summary>
/// Returns true if the underlying POST data includes elements that are not
/// represented by this IPostData object (for example, multi-part file upload
/// data). Modifying IPostData objects with excluded elements may result in
/// the request failing.
/// </summary>
virtual property bool HasExcludedElements
{
bool get()
{
ThrowIfDisposed();
return _postData->HasExcludedElements();
}
}
virtual IPostData^ UnWrap()
{
return this;
}
};
}
}

View file

@ -0,0 +1,134 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request.h"
#include "Internals\TypeConversion.h"
#include "Internals\CefWrapper.h"
using namespace System::Collections::Specialized;
namespace CefSharp
{
namespace Core
{
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class PostDataElement : public IPostDataElement, public CefWrapper
{
MCefRefPtr<CefPostDataElement> _postDataElement;
internal:
PostDataElement(CefRefPtr<CefPostDataElement> postDataElement) :
_postDataElement(postDataElement)
{
}
!PostDataElement()
{
_postDataElement = nullptr;
}
~PostDataElement()
{
this->!PostDataElement();
_disposed = true;
}
operator CefRefPtr<CefPostDataElement>()
{
if (this == nullptr)
{
return NULL;
}
return _postDataElement.get();
}
public:
PostDataElement()
{
_postDataElement = CefPostDataElement::Create();
}
virtual property bool IsReadOnly
{
bool get()
{
ThrowIfDisposed();
return _postDataElement->IsReadOnly();
}
}
virtual property String^ File
{
String^ get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_postDataElement->GetFile());
}
void set(String^ val)
{
ThrowIfDisposed();
_postDataElement->SetToFile(StringUtils::ToNative(val));
}
}
virtual void SetToEmpty()
{
ThrowIfDisposed();
_postDataElement->SetToEmpty();
}
virtual property PostDataElementType Type
{
PostDataElementType get()
{
ThrowIfDisposed();
return (PostDataElementType)_postDataElement->GetType();
}
}
virtual property cli::array<Byte>^ Bytes
{
cli::array<Byte>^ get()
{
ThrowIfDisposed();
auto byteCount = _postDataElement->GetBytesCount();
if (byteCount == 0)
{
return nullptr;
}
auto bytes = gcnew cli::array<Byte>(byteCount);
pin_ptr<Byte> src = &bytes[0]; // pin pointer to first element in arr
_postDataElement->GetBytes(byteCount, static_cast<void*>(src));
return bytes;
}
void set(cli::array<Byte>^ val)
{
ThrowIfDisposed();
pin_ptr<Byte> src = &val[0];
_postDataElement->SetToBytes(val->Length, static_cast<void*>(src));
}
}
virtual IPostDataElement^ UnWrap()
{
return this;
}
};
}
}

View file

@ -0,0 +1,213 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "Request.h"
#include "PostData.h"
using namespace System::Text;
namespace CefSharp
{
namespace Core
{
UrlRequestFlags Request::Flags::get()
{
ThrowIfDisposed();
return (UrlRequestFlags)_request->GetFlags();
}
void Request::Flags::set(UrlRequestFlags flags)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetFlags((int)flags);
}
String^ Request::Url::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_request->GetURL());
}
void Request::Url::set(String^ url)
{
if (url == nullptr)
{
throw gcnew System::ArgumentException("cannot be null", "url");
}
ThrowIfDisposed();
ThrowIfReadOnly();
CefString str = StringUtils::ToNative(url);
_request->SetURL(str);
}
String^ Request::Method::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_request->GetMethod());
}
void Request::Method::set(String^ method)
{
if (method == nullptr)
{
throw gcnew System::ArgumentException("cannot be null", "method");
}
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetMethod(StringUtils::ToNative(method));
}
UInt64 Request::Identifier::get()
{
ThrowIfDisposed();
return _request->GetIdentifier();
}
void Request::SetReferrer(String^ referrerUrl, CefSharp::ReferrerPolicy policy)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetReferrer(StringUtils::ToNative(referrerUrl), (cef_referrer_policy_t)policy);
}
String^ Request::ReferrerUrl::get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_request->GetReferrerURL());
}
CefSharp::ResourceType Request::ResourceType::get()
{
ThrowIfDisposed();
return (CefSharp::ResourceType)_request->GetResourceType();
}
CefSharp::ReferrerPolicy Request::ReferrerPolicy::get()
{
ThrowIfDisposed();
return (CefSharp::ReferrerPolicy)_request->GetReferrerPolicy();
}
NameValueCollection^ Request::Headers::get()
{
ThrowIfDisposed();
CefRequest::HeaderMap hm;
_request->GetHeaderMap(hm);
auto headers = gcnew HeaderNameValueCollection();
for (CefRequest::HeaderMap::iterator it = hm.begin(); it != hm.end(); ++it)
{
String^ name = StringUtils::ToClr(it->first);
String^ value = StringUtils::ToClr(it->second);
headers->Add(name, value);
}
if (_request->IsReadOnly())
{
headers->SetReadOnly();
}
return headers;
}
void Request::Headers::set(NameValueCollection^ headers)
{
ThrowIfDisposed();
ThrowIfReadOnly();
CefRequest::HeaderMap hm;
for each(String^ key in headers)
{
CefString name = StringUtils::ToNative(key);
for each(String^ element in headers->GetValues(key))
{
CefString value = StringUtils::ToNative(element);
hm.insert(std::make_pair(name, value));
}
}
_request->SetHeaderMap(hm);
}
TransitionType Request::TransitionType::get()
{
ThrowIfDisposed();
return (CefSharp::TransitionType) _request->GetTransitionType();
}
IPostData^ Request::PostData::get()
{
ThrowIfDisposed();
if (_postData == nullptr)
{
auto postData = _request->GetPostData();
if (postData.get())
{
_postData = gcnew CefSharp::Core::PostData(postData);
}
}
return _postData;
}
void Request::PostData::set(IPostData^ postData)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetPostData((CefSharp::Core::PostData^)postData->UnWrap());
}
bool Request::IsReadOnly::get()
{
ThrowIfDisposed();
return _request->IsReadOnly();
}
void Request::InitializePostData()
{
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetPostData(CefPostData::Create());
}
String^ Request::GetHeaderByName(String^ name)
{
ThrowIfDisposed();
return StringUtils::ToClr(_request->GetHeaderByName(StringUtils::ToNative(name)));
}
void Request::SetHeaderByName(String^ name, String^ value, bool overwrite)
{
ThrowIfDisposed();
ThrowIfReadOnly();
_request->SetHeaderByName(StringUtils::ToNative(name), StringUtils::ToNative(value), overwrite);
}
}
}

View file

@ -0,0 +1,89 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request.h"
#include "Internals\CefWrapper.h"
using namespace System::Collections::Specialized;
namespace CefSharp
{
namespace Core
{
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class Request : public IRequest, public CefWrapper
{
MCefRefPtr<CefRequest> _request;
IPostData^ _postData;
internal:
Request(CefRefPtr<CefRequest> &cefRequest) :
_request(cefRequest), _postData(nullptr)
{
}
!Request()
{
_request = nullptr;
}
~Request()
{
this->!Request();
delete _postData;
_disposed = true;
}
operator CefRefPtr<CefRequest>()
{
if (this == nullptr)
{
return NULL;
}
return _request.get();
}
void ThrowIfReadOnly()
{
if (_request->IsReadOnly())
{
throw gcnew NotSupportedException("IRequest is read-only and cannot be modified. Check IRequest.IsReadOnly to guard against this exception.");
}
}
public:
Request()
{
_request = CefRequest::Create();
}
virtual property UrlRequestFlags Flags { UrlRequestFlags get(); void set(UrlRequestFlags flags); }
virtual property String^ Url { String^ get(); void set(String^ url); }
virtual property String^ Method { String^ get(); void set(String^ method); }
virtual property UInt64 Identifier { UInt64 get(); }
virtual void SetReferrer(String^ referrerUrl, CefSharp::ReferrerPolicy policy);
virtual property String^ ReferrerUrl { String^ get(); }
virtual property ResourceType ResourceType { CefSharp::ResourceType get(); }
virtual property ReferrerPolicy ReferrerPolicy { CefSharp::ReferrerPolicy get(); }
virtual property NameValueCollection^ Headers { NameValueCollection^ get(); void set(NameValueCollection^ url); }
virtual property TransitionType TransitionType { CefSharp::TransitionType get(); }
virtual property IPostData^ PostData { IPostData^ get(); void set(IPostData^ postData); }
virtual property bool IsReadOnly { bool get(); }
virtual void InitializePostData();
virtual String^ GetHeaderByName(String^ name);
virtual void SetHeaderByName(String^ name, String^ value, bool overwrite);
virtual IRequest^ UnWrap()
{
return this;
}
};
}
}

View file

@ -0,0 +1,277 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "RequestContext.h"
#include "include\cef_parser.h"
//For the x86 version we define and undefine CEF_INCLUDE_BASE_INTERNAL_CEF_BIND_INTERNAL_WIN_H_
//as the /clr compliation option attempts to be helpful and convers all the __fastcall versions
//to __stdcall which already exist, so we just use the standard calling convention and ignore
//the optimised ones. The original error is
//warning C4561: '__fastcall' incompatible with the '/clr' option: converting to '__stdcall'
//(compiling source file RequestContext.cpp)
#define CEF_INCLUDE_BASE_INTERNAL_CEF_BIND_INTERNAL_WIN_H_
#include "include\base\cef_bind.h"
#undef CEF_INCLUDE_BASE_INTERNAL_CEF_BIND_INTERNAL_WIN_H_
#include "include\wrapper\cef_closure_task.h"
#include "CookieManager.h"
#include "Internals\CefSchemeHandlerFactoryAdapter.h"
#include "Internals\CefCompletionCallbackAdapter.h"
#include "Internals\CefExtensionWrapper.h"
#include "Internals\CefExtensionHandlerAdapter.h"
#include "Internals\CefResolveCallbackAdapter.h"
#include "Internals\TypeConversion.h"
using namespace System::Runtime::InteropServices;
namespace CefSharp
{
namespace Core
{
bool RequestContext::IsSame(IRequestContext^ context)
{
ThrowIfDisposed();
auto requestContext = (RequestContext^)context->UnWrap();
return _requestContext->IsSame(requestContext);
}
bool RequestContext::IsSharingWith(IRequestContext^ context)
{
ThrowIfDisposed();
auto requestContext = (RequestContext^)context->UnWrap();
return _requestContext->IsSharingWith(requestContext);
}
ICookieManager^ RequestContext::GetCookieManager(ICompletionCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
auto cookieManager = _requestContext->GetCookieManager(wrapper);
if (cookieManager.get())
{
return gcnew CookieManager(cookieManager);
}
return nullptr;
}
bool RequestContext::RegisterSchemeHandlerFactory(String^ schemeName, String^ domainName, ISchemeHandlerFactory^ factory)
{
ThrowIfDisposed();
auto wrapper = new CefSchemeHandlerFactoryAdapter(factory);
return _requestContext->RegisterSchemeHandlerFactory(StringUtils::ToNative(schemeName), StringUtils::ToNative(domainName), wrapper);
}
bool RequestContext::ClearSchemeHandlerFactories()
{
ThrowIfDisposed();
return _requestContext->ClearSchemeHandlerFactories();
}
void RequestContext::PurgePluginListCache(bool reloadPages)
{
ThrowIfDisposed();
_requestContext->PurgePluginListCache(reloadPages);
}
bool RequestContext::HasPreference(String^ name)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _requestContext->HasPreference(StringUtils::ToNative(name));
}
Object^ RequestContext::GetPreference(String^ name)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return TypeConversion::FromNative(_requestContext->GetPreference(StringUtils::ToNative(name)));
}
IDictionary<String^, Object^>^ RequestContext::GetAllPreferences(bool includeDefaults)
{
ThrowIfDisposed();
auto preferences = _requestContext->GetAllPreferences(includeDefaults);
return TypeConversion::FromNative(preferences);
}
bool RequestContext::CanSetPreference(String^ name)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _requestContext->CanSetPreference(StringUtils::ToNative(name));
}
bool RequestContext::SetPreference(String^ name, Object^ value, [Out] String^ %error)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
CefString cefError;
auto success = _requestContext->SetPreference(StringUtils::ToNative(name), TypeConversion::ToNative(value), cefError);
error = StringUtils::ToClr(cefError);
return success;
}
void RequestContext::ClearCertificateExceptions(ICompletionCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
_requestContext->ClearCertificateExceptions(wrapper);
}
void RequestContext::ClearHttpAuthCredentials(ICompletionCallback^ callback)
{
ThrowIfDisposed();
//TODO: Remove this once CEF Issue has been resolved
//ClearHttpAuthCredentials crashes when no callback specified
if (callback == nullptr)
{
callback = gcnew CefSharp::Callback::NoOpCompletionCallback();
}
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
_requestContext->ClearHttpAuthCredentials(wrapper);
}
void RequestContext::CloseAllConnections(ICompletionCallback^ callback)
{
ThrowIfDisposed();
CefRefPtr<CefCompletionCallback> wrapper = callback == nullptr ? NULL : new CefCompletionCallbackAdapter(callback);
_requestContext->CloseAllConnections(wrapper);
}
Task<ResolveCallbackResult>^ RequestContext::ResolveHostAsync(Uri^ origin)
{
ThrowIfDisposed();
auto callback = gcnew TaskResolveCallback();
CefRefPtr<CefResolveCallback> callbackWrapper = new CefResolveCallbackAdapter(callback);
_requestContext->ResolveHost(StringUtils::ToNative(origin->AbsoluteUri), callbackWrapper);
return callback->Task;
}
bool RequestContext::DidLoadExtension(String^ extensionId)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _requestContext->DidLoadExtension(StringUtils::ToNative(extensionId));
}
IExtension^ RequestContext::GetExtension(String^ extensionId)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
auto extension = _requestContext->GetExtension(StringUtils::ToNative(extensionId));
if (extension.get())
{
return gcnew CefExtensionWrapper(extension);
}
return nullptr;
}
bool RequestContext::GetExtensions([Out] IList<String^>^ %extensionIds)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
std::vector<CefString> extensions;
auto success = _requestContext->GetExtensions(extensions);
extensionIds = StringUtils::ToClr(extensions);
return success;
}
bool RequestContext::HasExtension(String^ extensionId)
{
ThrowIfDisposed();
ThrowIfExecutedOnNonCefUiThread();
return _requestContext->HasExtension(StringUtils::ToNative(extensionId));
}
void RequestContext::LoadExtension(String^ rootDirectory, String^ manifestJson, IExtensionHandler^ handler)
{
ThrowIfDisposed();
CefRefPtr<CefDictionaryValue> manifest;
if (!String::IsNullOrEmpty(manifestJson))
{
CefString errorMessage;
auto value = CefParseJSONAndReturnError(StringUtils::ToNative(manifestJson),
cef_json_parser_options_t::JSON_PARSER_ALLOW_TRAILING_COMMAS,
errorMessage);
if (value.get())
{
manifest = value->GetDictionary();
}
else
{
throw gcnew Exception("Unable to parse JSON - ErrorMessage:" + StringUtils::ToClr(errorMessage));
}
}
CefRefPtr<CefExtensionHandler> extensionHandler = handler == nullptr ? NULL : new CefExtensionHandlerAdapter(handler);
if (CefCurrentlyOn(CefThreadId::TID_UI))
{
_requestContext->LoadExtension(StringUtils::ToNative(rootDirectory), manifest, extensionHandler);
}
else
{
CefPostTask(TID_UI, base::Bind(&CefRequestContext::LoadExtension, _requestContext.get(), StringUtils::ToNative(rootDirectory), manifest, extensionHandler));
}
}
IRequestContext^ RequestContext::UnWrap()
{
return this;
}
}
}

View file

@ -0,0 +1,408 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#ifndef CEFSHARP_CORE_REQUESTCONTEXT_H_
#define CEFSHARP_CORE_REQUESTCONTEXT_H_
#pragma once
#include "Stdafx.h"
#include "include\cef_request_context.h"
#include "RequestContextSettings.h"
#include "Internals\CefRequestContextHandlerAdapter.h"
#include "Internals\CefWrapper.h"
using namespace System::Runtime::InteropServices;
using namespace System::Threading::Tasks;
namespace CefSharp
{
namespace Core
{
/// <summary>
/// A request context provides request handling for a set of related browser objects.
/// A request context is specified when creating a new browser object via the CefBrowserHost
/// static factory methods. Browser objects with different request contexts will never be
/// hosted in the same render process. Browser objects with the same request context may or
/// may not be hosted in the same render process depending on the process model.
/// Browser objects created indirectly via the JavaScript window.open function or targeted
/// links will share the same render process and the same request context as the source browser.
/// When running in single-process mode there is only a single render process (the main process)
/// and so all browsers created in single-process mode will share the same request context.
/// This will be the first request context passed into a CefBrowserHost static factory method
/// and all other request context objects will be ignored.
/// </summary>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class RequestContext : public IRequestContext, public CefWrapper
{
private:
MCefRefPtr<CefRequestContext> _requestContext;
RequestContextSettings^ _settings;
internal:
RequestContext(CefRefPtr<CefRequestContext>& context)
{
_requestContext = context;
_settings = nullptr;
}
operator CefRefPtr<CefRequestContext>()
{
if (this == nullptr)
{
return NULL;
}
return _requestContext.get();
}
public:
RequestContext()
{
CefRequestContextSettings settings;
_requestContext = CefRequestContext::CreateContext(settings, NULL);
}
RequestContext(RequestContextSettings^ settings) : _settings(settings)
{
PathCheck::AssertAbsolute(settings->CachePath, "RequestContextSettings.CachePath");
_requestContext = CefRequestContext::CreateContext(settings, NULL);
}
RequestContext(IRequestContextHandler^ requestContextHandler)
{
CefRequestContextSettings settings;
_requestContext = CefRequestContext::CreateContext(settings, new CefRequestContextHandlerAdapter(requestContextHandler));
}
RequestContext(RequestContextSettings^ settings, IRequestContextHandler^ requestContextHandler) : _settings(settings)
{
PathCheck::AssertAbsolute(settings->CachePath, "RequestContextSettings.CachePath");
_requestContext = CefRequestContext::CreateContext(settings, new CefRequestContextHandlerAdapter(requestContextHandler));
}
///Creates a new context object that shares storage with | other | and uses an optional | handler | .
RequestContext(IRequestContext^ otherRequestContext)
{
_requestContext = CefRequestContext::CreateContext((RequestContext^)otherRequestContext->UnWrap(), NULL);
}
RequestContext(IRequestContext^ otherRequestContext, IRequestContextHandler^ requestContextHandler)
{
_requestContext = CefRequestContext::CreateContext((RequestContext^)otherRequestContext->UnWrap(), new CefRequestContextHandlerAdapter(requestContextHandler));
}
!RequestContext()
{
_requestContext = NULL;
}
~RequestContext()
{
this->!RequestContext();
delete _settings;
_disposed = true;
}
/// <summary>
/// Creates a new context object that shares storage with other and uses an
/// optional handler.
/// </summary>
/// <param name="other">shares storage with this RequestContext</param>
/// <param name="requestContextHandler">optional requestContext handler</param>
/// <returns>Returns a new RequestContext</returns>
static IRequestContext^ CreateContext(IRequestContext^ other, IRequestContextHandler^ requestContextHandler)
{
auto otherRequestContext = static_cast<RequestContext^>(other);
CefRefPtr<CefRequestContextHandler> handler = requestContextHandler == nullptr ? NULL : new CefRequestContextHandlerAdapter(requestContextHandler);
auto newContext = CefRequestContext::CreateContext(otherRequestContext, handler);
return gcnew RequestContext(newContext);
}
/// <summary>
/// Returns true if this object is pointing to the same context object.
/// </summary>
/// <param name="context">context to compare</param>
/// <returns>Returns true if the same</returns>
virtual bool IsSame(IRequestContext^ context);
/// <summary>
/// Returns true if this object is sharing the same storage as the specified context.
/// </summary>
/// <param name="context">context to compare</param>
/// <returns>Returns true if same storage</returns>
virtual bool IsSharingWith(IRequestContext^ context);
/// <summary>
/// Returns the default cookie manager for this object. This will be the global
/// cookie manager if this object is the global request context.
/// </summary>
/// <param name="callback">If callback is non-NULL it will be executed asnychronously on the CEF IO thread
/// after the manager's storage has been initialized.</param>
/// <returns>Returns the default cookie manager for this object</returns>
virtual ICookieManager^ GetCookieManager(ICompletionCallback^ callback);
/// <summary>
/// Returns true if this object is the global context. The global context is
/// used by default when creating a browser or URL request with a NULL context
/// argument.
/// </summary>
virtual property bool IsGlobal
{
bool get()
{
ThrowIfDisposed();
return _requestContext->IsGlobal();
}
}
/// <summary>
/// Register a scheme handler factory for the specified schemeName and optional domainName.
/// An empty domainName value for a standard scheme will cause the factory to match all domain
/// names. The domainName value will be ignored for non-standard schemes. If schemeName is
/// a built-in scheme and no handler is returned by factory then the built-in scheme handler
/// factory will be called. If schemeName is a custom scheme then you must also implement the
/// IApp.OnRegisterCustomSchemes() method in all processes. This function may be called multiple
/// times to change or remove the factory that matches the specified schemeName and optional
/// domainName.
/// </summary>
/// <param name="schemeName">Scheme Name</param>
/// <param name="domainName">Optional domain name</param>
/// <param name="factory">Scheme handler factory</param>
/// <returns>Returns false if an error occurs.</returns>
virtual bool RegisterSchemeHandlerFactory(String^ schemeName, String^ domainName, ISchemeHandlerFactory^ factory);
/// <summary>
/// Clear all registered scheme handler factories.
/// </summary>
/// <returns>Returns false on error.</returns>
virtual bool ClearSchemeHandlerFactories();
/// <summary>
/// Returns the cache path for this object. If empty an "incognito mode"
/// in-memory cache is being used.
/// </summary>
virtual property String^ CachePath
{
String^ get()
{
ThrowIfDisposed();
return StringUtils::ToClr(_requestContext->GetCachePath());
}
}
/// <summary>
/// Tells all renderer processes associated with this context to throw away
/// their plugin list cache. If reloadPages is true they will also reload
/// all pages with plugins. RequestContextHandler.OnBeforePluginLoad may
/// be called to rebuild the plugin list cache.
/// </summary>
/// <param name="reloadPages">reload any pages with pluginst</param>
virtual void PurgePluginListCache(bool reloadPages);
/// <summary>
/// Returns true if a preference with the specified name exists. This method
/// must be called on the CEF UI thread.
/// </summary>
/// <param name="name">name of preference</param>
/// <returns>bool if the preference exists</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool HasPreference(String^ name);
/// <summary>
/// Returns the value for the preference with the specified name. Returns
/// NULL if the preference does not exist. The returned object contains a copy
/// of the underlying preference value and modifications to the returned object
/// will not modify the underlying preference value. This method must be called
/// on the CEF UI thread.
/// </summary>
/// <param name="name">preference name</param>
/// <returns>Returns the value for the preference with the specified name</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual Object^ GetPreference(String^ name);
/// <summary>
/// Returns all preferences as a dictionary. The returned
/// object contains a copy of the underlying preference values and
/// modifications to the returned object will not modify the underlying
/// preference values. This method must be called on the browser process UI
/// thread.
/// </summary>
/// <param name="includeDefaults">If true then
/// preferences currently at their default value will be included.</param>
/// <returns>Preferences (dictionary can have sub dictionaries)</returns>
virtual IDictionary<String^, Object^>^ GetAllPreferences(bool includeDefaults);
/// <summary>
/// Returns true if the preference with the specified name can be modified
/// using SetPreference. As one example preferences set via the command-line
/// usually cannot be modified. This method must be called on the CEF UI thread.
/// </summary>
/// <param name="name">preference key</param>
/// <returns>Returns true if the preference with the specified name can be modified
/// using SetPreference</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool CanSetPreference(String^ name);
/// <summary>
/// Set the value associated with preference name. If value is null the
/// preference will be restored to its default value. If setting the preference
/// fails then error will be populated with a detailed description of the
/// problem. This method must be called on the CEF UI thread.
/// Preferences set via the command-line usually cannot be modified.
/// </summary>
/// <param name="name">preference key</param>
/// <param name="value">preference value</param>
/// <param name="error">out error</param>
/// <returns>Returns true if the value is set successfully and false otherwise.</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool SetPreference(String^ name, Object^ value, [Out] String^ %error);
/// <summary>
/// Clears all certificate exceptions that were added as part of handling
/// <see cref="IRequestHandler::OnCertificateError"/>. If you call this it is
/// recommended that you also call <see cref="IRequestContext::CloseAllConnections"/> or you risk not
/// being prompted again for server certificates if you reconnect quickly.
/// </summary>
/// <param name="callback">If is non-NULL it will be executed on the CEF UI thread after
/// completion. This param is optional</param>
virtual void ClearCertificateExceptions(ICompletionCallback^ callback);
/// <summary>
/// Clears all HTTP authentication credentials that were added as part of handling
/// <see cref="IRequestHandler::GetAuthCredentials"/>.
/// </summary>
/// <param name="callback">If is non-NULL it will be executed on the CEF UI thread after
/// completion. This param is optional</param>
virtual void ClearHttpAuthCredentials(ICompletionCallback^ callback);
/// <summary>
/// Clears all active and idle connections that Chromium currently has.
/// This is only recommended if you have released all other CEF objects but
/// don't yet want to call Cef.Shutdown().
/// </summary>
/// <param name="callback">If is non-NULL it will be executed on the CEF UI thread after
/// completion. This param is optional</param>
virtual void CloseAllConnections(ICompletionCallback^ callback);
/// <summary>
/// Attempts to resolve origin to a list of associated IP addresses.
/// </summary>
/// <param name="origin">host name to resolve</param>
/// <returns>A task that represents the Resoolve Host operation. The value of the TResult parameter contains ResolveCallbackResult.</returns>
virtual Task<ResolveCallbackResult>^ ResolveHostAsync(Uri^ origin);
/// <summary>
/// Returns true if this context was used to load the extension identified by extensionId. Other contexts sharing the same storage will also have access to the extension (see HasExtension).
/// This method must be called on the CEF UI thread.
/// </summary>
/// <returns>Returns true if this context was used to load the extension identified by extensionId</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool DidLoadExtension(String^ extensionId);
/// <summary>
/// Returns the extension matching extensionId or null if no matching extension is accessible in this context (see HasExtension).
/// This method must be called on the CEF UI thread.
/// </summary>
/// <param name="extensionId">extension Id</param>
/// <returns>Returns the extension matching extensionId or null if no matching extension is accessible in this context</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual IExtension^ GetExtension(String^ extensionId);
/// <summary>
/// Retrieve the list of all extensions that this context has access to (see HasExtension).
/// <paramref name="extensionIds"/> will be populated with the list of extension ID values.
/// This method must be called on the CEF UI thread.
/// </summary>
/// <param name="extensionIds">output a list of extensions Ids</param>
/// <returns>returns true on success otherwise false</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool GetExtensions([Out] IList<String^>^ %extensionIds);
/// <summary>
/// Returns true if this context has access to the extension identified by extensionId.
/// This may not be the context that was used to load the extension (see DidLoadExtension).
/// This method must be called on the CEF UI thread.
/// </summary>
/// <param name="extensionId">extension id</param>
/// <returns>Returns true if this context has access to the extension identified by extensionId</returns>
/// <remarks>Use Cef.UIThreadTaskFactory to execute this method if required,
/// <see cref="IBrowserProcessHandler::OnContextInitialized"/> and ChromiumWebBrowser.IsBrowserInitializedChanged are both
/// executed on the CEF UI thread, so can be called directly.
/// When CefSettings.MultiThreadedMessageLoop == false (the default is true) then the main
/// application thread will be the CEF UI thread.</remarks>
virtual bool HasExtension(String^ extensionId);
/// <summary>
/// Load an extension. If extension resources will be read from disk using the default load implementation then rootDirectoy
/// should be the absolute path to the extension resources directory and manifestJson should be null.
/// If extension resources will be provided by the client (e.g. via IRequestHandler and/or IExtensionHandler) then rootDirectory
/// should be a path component unique to the extension (if not absolute this will be internally prefixed with the PK_DIR_RESOURCES path)
/// and manifestJson should contain the contents that would otherwise be read from the "manifest.json" file on disk.
/// The loaded extension will be accessible in all contexts sharing the same storage (HasExtension returns true).
/// However, only the context on which this method was called is considered the loader (DidLoadExtension returns true) and only the
/// loader will receive IRequestContextHandler callbacks for the extension. <see cref="IExtensionHandler::OnExtensionLoaded"/> will be
/// called on load success or <see cref="IExtensionHandler::OnExtensionLoadFailed"/> will be called on load failure.
/// If the extension specifies a background script via the "background" manifest key then <see cref="IExtensionHandler::OnBeforeBackgroundBrowser"/>
/// will be called to create the background browser. See that method for additional information about background scripts.
/// For visible extension views the client application should evaluate the manifest to determine the correct extension URL to load and then pass
/// that URL to the IBrowserHost.CreateBrowser* function after the extension has loaded. For example, the client can look for the "browser_action"
/// manifest key as documented at https://developer.chrome.com/extensions/browserAction. Extension URLs take the form "chrome-extension:///".
/// Browsers that host extensions differ from normal browsers as follows: - Can access chrome.* JavaScript APIs if allowed by the manifest.
/// Visit chrome://extensions-support for the list of extension APIs currently supported by CEF. - Main frame navigation to non-extension
/// content is blocked.
/// - Pinch-zooming is disabled.
/// - <see cref="IBrowserHost::Extension"/> returns the hosted extension.
/// - CefBrowserHost::IsBackgroundHost returns true for background hosts. See https://developer.chrome.com/extensions for extension implementation and usage documentation.
/// </summary>
/// <param name="rootDirectory">If extension resources will be read from disk using the default load implementation then rootDirectoy
/// should be the absolute path to the extension resources directory and manifestJson should be null</param>
/// <param name="manifestJson">If extension resources will be provided by the client then rootDirectory should be a path component unique to the extension
/// and manifestJson should contain the contents that would otherwise be read from the manifest.json file on disk</param>
/// <param name="handler">handle events related to browser extensions</param>
virtual void LoadExtension(String^ rootDirectory, String^ manifestJson, IExtensionHandler^ handler);
/// <summary>
/// Gets the inner most instance
/// </summary>
/// <returns>current instance</returns>
virtual IRequestContext^ UnWrap();
};
}
}
#endif // CEFSHARP_CORE_REQUESTCONTEXT_H_

View file

@ -0,0 +1,118 @@
// Copyright © 2015 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#include "Stdafx.h"
#include "include\cef_request_context.h"
namespace CefSharp
{
namespace Core
{
/// <summary>
/// RequestContextSettings
/// </summary>
[System::ComponentModel::EditorBrowsableAttribute(System::ComponentModel::EditorBrowsableState::Never)]
public ref class RequestContextSettings
{
private:
CefRequestContextSettings* _settings;
internal:
operator CefRequestContextSettings()
{
return *_settings;
}
public:
/// <summary>
/// Default constructor
/// </summary>
RequestContextSettings() : _settings(new CefRequestContextSettings())
{
}
!RequestContextSettings()
{
delete _settings;
}
~RequestContextSettings()
{
this->!RequestContextSettings();
}
/// <summary>
/// To persist session cookies (cookies without an expiry date or validity
/// interval) by default when using the global cookie manager set this value to
/// true. Session cookies are generally intended to be transient and most
/// Web browsers do not persist them. Can be set globally using the
/// CefSettings.PersistSessionCookies value. This value will be ignored if
/// CachePath is empty or if it matches the CefSettings.CachePath value.
/// </summary>
property bool PersistSessionCookies
{
bool get() { return _settings->persist_session_cookies == 1; }
void set(bool value) { _settings->persist_session_cookies = value; }
}
/// <summary>
/// To persist user preferences as a JSON file in the cache path directory set
/// this value to true. Can be set globally using the
/// CefSettings.PersistUserPreferences value. This value will be ignored if
/// CachePath is empty or if it matches the CefSettings.CachePath value.
/// </summary>
property bool PersistUserPreferences
{
bool get() { return _settings->persist_user_preferences == 1; }
void set(bool value) { _settings->persist_user_preferences = value; }
}
/// <summary>
/// The location where cache data for this request context will be stored on
/// disk. If this value is non-empty then it must be an absolute path that is
/// either equal to or a child directory of CefSettings.RootCachePath.
/// If the value is empty then browsers will be created in "incognito mode"
/// where in-memory caches are used for storage and no data is persisted to disk.
/// HTML5 databases such as localStorage will only persist across sessions if a
/// cache path is specified. To share the global browser cache and related
/// configuration set this value to match the CefSettings.CachePath value.
/// </summary>
property String^ CachePath
{
String^ get() { return StringUtils::ToClr(_settings->cache_path); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_settings->cache_path, value); }
}
/// <summary>
/// Comma delimited ordered list of language codes without any whitespace that
/// will be used in the "Accept-Language" HTTP header. Can be set globally
/// using the CefSettings.accept_language_list value or overridden on a per-
/// browser basis using the BrowserSettings.AcceptLanguageList value. If
/// all values are empty then "en-US,en" will be used. This value will be
/// ignored if CachePath matches the CefSettings.CachePath value.
/// </summary>
property String^ AcceptLanguageList
{
String^ get() { return StringUtils::ToClr(_settings->accept_language_list); }
void set(String^ value) { StringUtils::AssignNativeFromClr(_settings->accept_language_list, value); }
}
/// <summary>
/// Set to true to ignore errors related to invalid SSL certificates.
/// Enabling this setting can lead to potential security vulnerabilities like
/// "man in the middle" attacks. Applications that load content from the
/// internet should not enable this setting. Can be set globally using the
/// CefSettings.IgnoreCertificateErrors value. This value will be ignored if
/// CachePath matches the CefSettings.cache_path value.
/// </summary>
property bool IgnoreCertificateErrors
{
bool get() { return _settings->ignore_certificate_errors == 1; }
void set(bool value) { _settings->ignore_certificate_errors = value; }
}
};
}
}

View file

@ -0,0 +1,5 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"

View file

@ -0,0 +1,24 @@
// Copyright © 2010 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#pragma once
#ifdef EXPORT
#define DECL __declspec(dllexport)
#else
#define DECL __declspec(dllimport)
#endif
#include <vector>
#include <list>
#include <include/cef_base.h>
#include "Internals\MCefRefPtr.h"
#include "Internals\StringUtils.h"
#include "vcclr_local.h"
using namespace CefSharp;
using namespace CefSharp::Internals;
using namespace System;

View file

@ -0,0 +1,35 @@
// Copyright © 2019 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "Stdafx.h"
#include "UrlRequest.h"
#include "Internals\CefResponseWrapper.h"
namespace CefSharp
{
namespace Core
{
bool UrlRequest::ResponseWasCached::get()
{
ThrowIfDisposed();
return _urlRequest->ResponseWasCached();
}
IResponse^ UrlRequest::Response::get()
{
ThrowIfDisposed();
return gcnew CefResponseWrapper(_urlRequest->GetResponse());
}
UrlRequestStatus UrlRequest::RequestStatus::get()
{
ThrowIfDisposed();
return (UrlRequestStatus)_urlRequest->GetRequestStatus();
}
}
}

Some files were not shown because too many files have changed in this diff Show more