Skip to content

Commit

Permalink
added jscallback support for new evaluatescript implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
arsher committed Jun 27, 2015
1 parent cc8a07c commit 762d949
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CefSharp.Core/Internals/ClientAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ namespace CefSharp
if (static_cast<IBrowserAdapter^>(_browserAdapter) != nullptr)
{
_browserAdapter->OnAfterBrowserCreated(browser->GetIdentifier());
//save callback factory for this browser
//it's only going to be present after browseradapter is initialized
_javascriptCallbackFactories->Add(browser->GetIdentifier(), _browserAdapter->JavascriptCallbackFactory);
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions CefSharp.Core/Internals/ClientAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ namespace CefSharp
gcroot<IBrowserAdapter^> _browserAdapter;
//contains in-progress eval script tasks
gcroot<PendingTaskRepository<JavascriptResponse^>^> _pendingTaskRepository;

//contains js callback factories for each browser
gcroot<Dictionary<int, IJavascriptCallbackFactory^>^> _javascriptCallbackFactories;

void ThrowUnknownPopupBrowser(String^ context)
{
Expand All @@ -62,16 +63,21 @@ namespace CefSharp
_browserControl(browserControl),
_popupBrowsers(gcnew Dictionary<int, IBrowser^>()),
_pendingTaskRepository(gcnew PendingTaskRepository<JavascriptResponse^>()),
_javascriptCallbackFactories(gcnew Dictionary<int, IJavascriptCallbackFactory^>()),
_browserAdapter(browserAdapter)
{
//create eval script message handler
_evalScriptDoneDelegate = new EvaluateScriptDoneDelegate(_pendingTaskRepository);
_evalScriptDoneDelegate = new EvaluateScriptDoneDelegate(_pendingTaskRepository, _javascriptCallbackFactories);
AddProcessMessageDelegate(_evalScriptDoneDelegate);
}

~ClientAdapter()
{
CloseAllPopups(true);

//this will dispose the repository and cancel all pending tasks
delete _pendingTaskRepository;

_browserControl = nullptr;
_browserHwnd = nullptr;
_cefBrowser = NULL;
Expand Down
18 changes: 10 additions & 8 deletions CefSharp.Core/Internals/Messaging/EvaluateScriptDoneDelegate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ namespace CefSharp

namespace Messaging
{
EvaluateScriptDoneDelegate::EvaluateScriptDoneDelegate(PendingTaskRepository<JavascriptResponse^>^ pendingTasks)
:_pendingTasks(pendingTasks)
EvaluateScriptDoneDelegate::EvaluateScriptDoneDelegate(PendingTaskRepository<JavascriptResponse^>^ pendingTasks, Dictionary<int, IJavascriptCallbackFactory^>^ callbackFactories)
:_pendingTasks(pendingTasks), _callbackFactories(callbackFactories)
{

}
Expand Down Expand Up @@ -51,32 +51,34 @@ namespace CefSharp
auto success = argList->GetBool(0);
auto callbackId = GetInt64(argList, 1);

FinishTask(callbackId, success, argList);
IJavascriptCallbackFactory^ callbackFactory;
_callbackFactories->TryGetValue(browser->GetIdentifier(), callbackFactory);

FinishTask(callbackId, success, argList, callbackFactory);

handled = true;
}

return handled;
}

void EvaluateScriptDoneDelegate::FinishTask(int64 callbackId, bool success, CefRefPtr<CefListValue> message)
void EvaluateScriptDoneDelegate::FinishTask(int64 callbackId, bool success, CefRefPtr<CefListValue> message, IJavascriptCallbackFactory^ callbackFactory)
{
auto pendingTask = _pendingTasks->RemovePendingTask(callbackId);
if (pendingTask != nullptr)
{
pendingTask->SetResult(CreateResponse(success, message));
pendingTask->SetResult(CreateResponse(success, message, callbackFactory));
}
}

JavascriptResponse^ EvaluateScriptDoneDelegate::CreateResponse(bool success, CefRefPtr<CefListValue> message)
JavascriptResponse^ EvaluateScriptDoneDelegate::CreateResponse(bool success, CefRefPtr<CefListValue> message, IJavascriptCallbackFactory^ callbackFactory)
{
auto result = gcnew JavascriptResponse();
result->Success = success;

if (success)
{
//pass null as IJavascriptCallbackFactory for now
result->Result = DeserializeV8Object(message, 2, nullptr);
result->Result = DeserializeV8Object(message, 2, callbackFactory);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ namespace CefSharp
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(EvaluateScriptDoneDelegate);

gcroot<Dictionary<int, IJavascriptCallbackFactory^>^> _callbackFactories;
gcroot<PendingTaskRepository<JavascriptResponse^>^> _pendingTasks;

void FinishTask(int64 callbackId, bool success, CefRefPtr<CefListValue> message);
JavascriptResponse^ CreateResponse(bool success, CefRefPtr<CefListValue> message);
void FinishTask(int64 callbackId, bool success, CefRefPtr<CefListValue> message, IJavascriptCallbackFactory^ callbackFactory);
JavascriptResponse^ CreateResponse(bool success, CefRefPtr<CefListValue> message, IJavascriptCallbackFactory^ callbackFactory);
public:
EvaluateScriptDoneDelegate(PendingTaskRepository<JavascriptResponse^>^ pendingTasks);
EvaluateScriptDoneDelegate(PendingTaskRepository<JavascriptResponse^>^ pendingTasks, Dictionary<int, IJavascriptCallbackFactory^>^ callbackFactories);
Task<JavascriptResponse^>^ EvaluateScriptAsync(CefRefPtr<CefBrowser> cefBrowser, int browserId, int frameId, String^ script, Nullable<TimeSpan> timeout);
virtual bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser, CefProcessId source_process, CefRefPtr<CefProcessMessage> message) override;
};
Expand Down
12 changes: 12 additions & 0 deletions CefSharp.Core/ManagedCefBrowserAdapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void ManagedCefBrowserAdapter::LoadUrl(String^ address)

void ManagedCefBrowserAdapter::OnAfterBrowserCreated(int browserId)
{
_wcfEnabled = Cef::WcfEnabled;

if (_wcfEnabled)
{
_browserProcessServiceHost = gcnew BrowserProcessServiceHost(_javaScriptObjectRepository, Process::GetCurrentProcess()->Id, browserId);
Expand Down Expand Up @@ -559,3 +561,13 @@ IBrowser^ ManagedCefBrowserAdapter::GetBrowser()
{
return _browserWrapper;
}

IJavascriptCallbackFactory^ ManagedCefBrowserAdapter::JavascriptCallbackFactory::get()
{
IJavascriptCallbackFactory^ result = nullptr;
if (_browserProcessServiceHost != nullptr)
{
result = _browserProcessServiceHost->JavascriptCallbackFactory;
}
return result;
}
5 changes: 5 additions & 0 deletions CefSharp.Core/ManagedCefBrowserAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,5 +165,10 @@ namespace CefSharp
/// </summary>
/// <returns>Gets the current instance or null</returns>
virtual IBrowser^ GetBrowser();

virtual property IJavascriptCallbackFactory^ JavascriptCallbackFactory
{
CefSharp::Internals::IJavascriptCallbackFactory^ get();
}
};
}
1 change: 1 addition & 0 deletions CefSharp/CefSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
<Compile Include="CefCursorType.cs" />
<Compile Include="Internals\IJavascriptCallbackFactory.cs" />
<Compile Include="Internals\IntPtrExtensions.cs" />
<Compile Include="Internals\JavascriptCallbackFactory.cs" />
<Compile Include="Internals\JavascriptCallbackProxy.cs" />
<Compile Include="Internals\JavascriptCallback.cs" />
<Compile Include="Internals\JavascriptCallbackEndpointBehavior.cs" />
Expand Down
2 changes: 2 additions & 0 deletions CefSharp/Internals/BrowserProcessServiceHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ public class BrowserProcessServiceHost : ServiceHost
{
private const long OneHundredAndTwentyEightMegaBytesInBytes = 128*1024*1024;

public IJavascriptCallbackFactory JavascriptCallbackFactory { get; private set; }
public JavascriptObjectRepository JavascriptObjectRepository { get; private set; }
private TaskCompletionSource<OperationContext> operationContextTaskCompletionSource = new TaskCompletionSource<OperationContext>();

public BrowserProcessServiceHost(JavascriptObjectRepository javascriptObjectRepository, int parentProcessId, int browserId)
: base(typeof(BrowserProcessService), new Uri[0])
{
JavascriptObjectRepository = javascriptObjectRepository;
JavascriptCallbackFactory = new JavascriptCallbackFactory(new WeakReference(this));

var serviceName = RenderprocessClientFactory.GetServiceName(parentProcessId, browserId);

Expand Down
1 change: 1 addition & 0 deletions CefSharp/Internals/IBrowserAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace CefSharp.Internals
/// </summary>
public interface IBrowserAdapter
{
IJavascriptCallbackFactory JavascriptCallbackFactory { get; }
Task<JavascriptResponse> EvaluateScriptAsync(string script, TimeSpan? timeout);
Task<JavascriptResponse> EvaluateScriptAsync(int browserId, Int64 frameId, string script, TimeSpan? timeout);
void OnAfterBrowserCreated(int browserId);
Expand Down
19 changes: 19 additions & 0 deletions CefSharp/Internals/JavascriptCallbackFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace CefSharp.Internals
{
public class JavascriptCallbackFactory : IJavascriptCallbackFactory
{
private readonly WeakReference browserProcessServiceHost;

public JavascriptCallbackFactory(WeakReference browserProcessServiceHost)
{
this.browserProcessServiceHost = browserProcessServiceHost;
}

public IJavascriptCallback Create(JavascriptCallback callback)
{
return new JavascriptCallbackProxy(callback.Id, callback.BrowserId, browserProcessServiceHost);
}
}
}
8 changes: 3 additions & 5 deletions CefSharp/Internals/JavascriptCallbackSurrogate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@

namespace CefSharp.Internals
{
internal sealed class JavascriptCallbackSurrogate : IDataContractSurrogate
internal sealed class JavascriptCallbackSurrogate : JavascriptCallbackFactory, IDataContractSurrogate
{
private readonly WeakReference browserProcessWeakReference;

public JavascriptCallbackSurrogate(WeakReference browserProcessWeakReference)
:base(browserProcessWeakReference)
{
this.browserProcessWeakReference = browserProcessWeakReference;
}

public Type GetDataContractType(Type type)
Expand All @@ -39,7 +37,7 @@ public object GetDeserializedObject(object obj, Type targetType)
var dto = obj as JavascriptCallback;
if (dto != null)
{
result = new JavascriptCallbackProxy(dto.Id, dto.BrowserId, browserProcessWeakReference);
result = Create(dto);
}
return result;
}
Expand Down

0 comments on commit 762d949

Please sign in to comment.