From 8502e674bba49f0e5d8a0177855df702e95ee14c Mon Sep 17 00:00:00 2001 From: cefsharp-ms Date: Tue, 30 Aug 2016 13:44:58 +0200 Subject: [PATCH] Added example for separated bound objects --- CefSharp.Example/CefExample.cs | 1 + CefSharp.Example/CefSharp.Example.csproj | 2 + CefSharp.Example/CefSharpSchemeHandler.cs | 1 + .../Properties/Resources.Designer.cs | 25 +++ CefSharp.Example/Properties/Resources.resx | 3 + .../Resources/MultitenantTest.html | 77 +++++++++ CefSharp.Example/UniqueBoundObject.cs | 24 +++ CefSharp.Wpf.Example/App.xaml.cs | 4 +- .../Handlers/LifespanHandler.cs | 148 +++++++++--------- CefSharp.Wpf.Example/MainWindow.xaml | 1 + .../Views/BrowserTabView.xaml.cs | 1 + 11 files changed, 212 insertions(+), 75 deletions(-) create mode 100644 CefSharp.Example/Resources/MultitenantTest.html create mode 100644 CefSharp.Example/UniqueBoundObject.cs diff --git a/CefSharp.Example/CefExample.cs b/CefSharp.Example/CefExample.cs index 0a74bd922b..804b88feed 100644 --- a/CefSharp.Example/CefExample.cs +++ b/CefSharp.Example/CefExample.cs @@ -24,6 +24,7 @@ public static class CefExample public const string BasicSchemeTestUrl = "custom://cefsharp/SchemeTest.html"; public const string ResponseFilterTestUrl = "custom://cefsharp/ResponseFilterTest.html"; public const string DraggableRegionTestUrl = "custom://cefsharp/DraggableRegionTest.html"; + public const string MultitenantTestUrl = "custom://cefsharp/MultitenantTest.html"; public const string TestResourceUrl = "http://test/resource/load"; public const string RenderProcessCrashedUrl = "http://processcrashed"; public const string TestUnicodeResourceUrl = "http://test/resource/loadUnicode"; diff --git a/CefSharp.Example/CefSharp.Example.csproj b/CefSharp.Example/CefSharp.Example.csproj index 3c653489d7..aaee8d4f6f 100644 --- a/CefSharp.Example/CefSharp.Example.csproj +++ b/CefSharp.Example/CefSharp.Example.csproj @@ -102,6 +102,7 @@ + @@ -128,6 +129,7 @@ + diff --git a/CefSharp.Example/CefSharpSchemeHandler.cs b/CefSharp.Example/CefSharpSchemeHandler.cs index 9e4119dd75..1fd6461239 100644 --- a/CefSharp.Example/CefSharpSchemeHandler.cs +++ b/CefSharp.Example/CefSharpSchemeHandler.cs @@ -40,6 +40,7 @@ static CefSharpSchemeHandler() { "/bootstrap/bootstrap.min.js", Resources.bootstrap_min_js }, { "/BindingTest.html", Resources.BindingTest }, + { "/MultitenantTest.html", Resources.MultitenantTest }, { "/ExceptionTest.html", Resources.ExceptionTest }, { "/PopupTest.html", Resources.PopupTest }, { "/SchemeTest.html", Resources.SchemeTest }, diff --git a/CefSharp.Example/Properties/Resources.Designer.cs b/CefSharp.Example/Properties/Resources.Designer.cs index a0565671af..30a18bb559 100644 --- a/CefSharp.Example/Properties/Resources.Designer.cs +++ b/CefSharp.Example/Properties/Resources.Designer.cs @@ -466,6 +466,31 @@ internal static string MultiBindingTest { } } + /// + /// Looks up a localized string similar to <!DOCTYPE html> + ///<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> + ///<head> + /// <meta charset="utf-8" /> + /// <title>Multitenant Test</title> + /// <script> + /// function onLoad() + /// { + /// var p = document.getElementById('p'); + /// var btn = document.getElementById('btn'); + /// if (window.opener) + /// { + /// btn.parentElement.removeChild(btn); + /// } + /// uniqueObject.id().then(function(res) { + /// p.innerText = res; + /// [rest of string was truncated]";. + /// + internal static string MultitenantTest { + get { + return ResourceManager.GetString("MultitenantTest", resourceCulture); + } + } + /// /// Looks up a localized string similar to <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ///<html> diff --git a/CefSharp.Example/Properties/Resources.resx b/CefSharp.Example/Properties/Resources.resx index 195d75e65a..765f02ca93 100644 --- a/CefSharp.Example/Properties/Resources.resx +++ b/CefSharp.Example/Properties/Resources.resx @@ -187,4 +187,7 @@ ..\Resources\DraggableRegionTest.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + + ..\resources\multitenanttest.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + \ No newline at end of file diff --git a/CefSharp.Example/Resources/MultitenantTest.html b/CefSharp.Example/Resources/MultitenantTest.html new file mode 100644 index 0000000000..cb3a6a8c3f --- /dev/null +++ b/CefSharp.Example/Resources/MultitenantTest.html @@ -0,0 +1,77 @@ + + + + + Multitenant Test + + + + +

+ + \ No newline at end of file diff --git a/CefSharp.Example/UniqueBoundObject.cs b/CefSharp.Example/UniqueBoundObject.cs new file mode 100644 index 0000000000..49e28d874e --- /dev/null +++ b/CefSharp.Example/UniqueBoundObject.cs @@ -0,0 +1,24 @@ +// Copyright © 2010-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. + +using System.Threading; + +namespace CefSharp.Example +{ + public class UniqueBoundObject + { + private static int lastId = 0; + private int id; + + public UniqueBoundObject() + { + id = Interlocked.Increment(ref lastId); + } + + public int Id() + { + return id; + } + } +} diff --git a/CefSharp.Wpf.Example/App.xaml.cs b/CefSharp.Wpf.Example/App.xaml.cs index 8d66b29d1f..190adc1838 100644 --- a/CefSharp.Wpf.Example/App.xaml.cs +++ b/CefSharp.Wpf.Example/App.xaml.cs @@ -19,10 +19,10 @@ protected override void OnStartup(StartupEventArgs e) "please make sure you compile in `Release` mode.", "Warning"); } #endif - + CefSharpSettings.SeparateBoundObjects = true; CefExample.Init(true, multiThreadedMessageLoop: true, browserProcessHandler: new BrowserProcessHandler()); base.OnStartup(e); } } -} \ No newline at end of file +} diff --git a/CefSharp.Wpf.Example/Handlers/LifespanHandler.cs b/CefSharp.Wpf.Example/Handlers/LifespanHandler.cs index 8ddf0d341c..7d926a7766 100644 --- a/CefSharp.Wpf.Example/Handlers/LifespanHandler.cs +++ b/CefSharp.Wpf.Example/Handlers/LifespanHandler.cs @@ -5,6 +5,7 @@ using System; using System.Windows; using System.Windows.Interop; +using CefSharp.Example; namespace CefSharp.Wpf.Example.Handlers { @@ -14,79 +15,80 @@ bool ILifeSpanHandler.OnBeforePopup(IWebBrowser browserControl, IBrowser browser { newBrowser = null; - return false; +// return false; //NOTE: This is experimental - //var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; - - //ChromiumWebBrowser chromiumBrowser = null; - - //var windowX = (windowInfo.X == int.MinValue) ? double.NaN : windowInfo.X; - //var windowY = (windowInfo.Y == int.MinValue) ? double.NaN : windowInfo.Y; - //var windowWidth = (windowInfo.Width == int.MinValue) ? double.NaN : windowInfo.Width; - //var windowHeight = (windowInfo.Height == int.MinValue) ? double.NaN : windowInfo.Height; - - //chromiumWebBrowser.Dispatcher.Invoke(() => - //{ - // var owner = Window.GetWindow(chromiumWebBrowser); - // chromiumBrowser = new ChromiumWebBrowser - // { - // Address = targetUrl, - // }; - - // chromiumBrowser.SetAsPopup(); - // chromiumBrowser.LifeSpanHandler = this; - - // var popup = new Window - // { - // Left = windowX, - // Top = windowY, - // Width = windowWidth, - // Height = windowHeight, - // Content = chromiumBrowser, - // Owner = owner, - // Title = targetFrameName - // }; - - // var windowInteropHelper = new WindowInteropHelper(popup); - // //Create the handle Window handle (In WPF there's only one handle per window, not per control) - // var handle = windowInteropHelper.EnsureHandle(); - - // //The parentHandle value will be used to identify monitor info and to act as the parent window for dialogs, - // //context menus, etc. If parentHandle is not provided then the main screen monitor will be used and some - // //functionality that requires a parent window may not function correctly. - // windowInfo.SetAsWindowless(handle, true); - - // popup.Closed += (o, e) => - // { - // var w = o as Window; - // if (w != null && w.Content is IWebBrowser) - // { - // (w.Content as IWebBrowser).Dispose(); - // w.Content = null; - // } - // }; - //}); - - //newBrowser = chromiumBrowser; - - //return false; + var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; + + ChromiumWebBrowser chromiumBrowser = null; + + var windowX = (windowInfo.X == int.MinValue) ? double.NaN : windowInfo.X; + var windowY = (windowInfo.Y == int.MinValue) ? double.NaN : windowInfo.Y; + var windowWidth = (windowInfo.Width == int.MinValue) ? double.NaN : windowInfo.Width; + var windowHeight = (windowInfo.Height == int.MinValue) ? double.NaN : windowInfo.Height; + + chromiumWebBrowser.Dispatcher.Invoke(() => + { + var owner = Window.GetWindow(chromiumWebBrowser); + chromiumBrowser = new ChromiumWebBrowser + { + Address = targetUrl, + }; + chromiumBrowser.RegisterAsyncJsObject("uniqueObject", new UniqueBoundObject()); + + chromiumBrowser.SetAsPopup(); + chromiumBrowser.LifeSpanHandler = this; + + var popup = new Window + { + Left = windowX, + Top = windowY, + Width = windowWidth, + Height = windowHeight, + Content = chromiumBrowser, + Owner = owner, + Title = targetFrameName + }; + + var windowInteropHelper = new WindowInteropHelper(popup); + //Create the handle Window handle (In WPF there's only one handle per window, not per control) + var handle = windowInteropHelper.EnsureHandle(); + + //The parentHandle value will be used to identify monitor info and to act as the parent window for dialogs, + //context menus, etc. If parentHandle is not provided then the main screen monitor will be used and some + //functionality that requires a parent window may not function correctly. + windowInfo.SetAsWindowless(handle, true); + + popup.Closed += (o, e) => + { + var w = o as Window; + if (w != null && w.Content is IWebBrowser) + { + (w.Content as IWebBrowser).Dispose(); + w.Content = null; + } + }; + }); + + newBrowser = chromiumBrowser; + + return false; } void ILifeSpanHandler.OnAfterCreated(IWebBrowser browserControl, IBrowser browser) { //NOTE: This is experimental - //var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; + var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; - //chromiumWebBrowser.Dispatcher.Invoke(() => - //{ - // var owner = Window.GetWindow(chromiumWebBrowser); + chromiumWebBrowser.Dispatcher.Invoke(() => + { + var owner = Window.GetWindow(chromiumWebBrowser); - // if (owner != null && owner.Content == browserControl) - // { - // owner.Show(); - // } - //}); + if (owner != null && owner.Content == browserControl) + { + owner.Show(); + } + }); } bool ILifeSpanHandler.DoClose(IWebBrowser browserControl, IBrowser browser) @@ -97,17 +99,17 @@ bool ILifeSpanHandler.DoClose(IWebBrowser browserControl, IBrowser browser) void ILifeSpanHandler.OnBeforeClose(IWebBrowser browserControl, IBrowser browser) { //NOTE: This is experimental - //var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; + var chromiumWebBrowser = (ChromiumWebBrowser)browserControl; - //chromiumWebBrowser.Dispatcher.Invoke(() => - //{ - // var owner = Window.GetWindow(chromiumWebBrowser); + chromiumWebBrowser.Dispatcher.Invoke(() => + { + var owner = Window.GetWindow(chromiumWebBrowser); - // if (owner != null && owner.Content == browserControl) - // { - // owner.Close(); - // } - //}); + if (owner != null && owner.Content == browserControl) + { + owner.Close(); + } + }); } } } diff --git a/CefSharp.Wpf.Example/MainWindow.xaml b/CefSharp.Wpf.Example/MainWindow.xaml index f4e4df44c0..7362b226ba 100644 --- a/CefSharp.Wpf.Example/MainWindow.xaml +++ b/CefSharp.Wpf.Example/MainWindow.xaml @@ -21,6 +21,7 @@ + diff --git a/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs b/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs index d62d7a622d..e994d5678d 100644 --- a/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs +++ b/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs @@ -26,6 +26,7 @@ public BrowserTabView() browser.RequestHandler = new RequestHandler(); browser.RegisterJsObject("bound", new BoundObject(), BindingOptions.DefaultBinder); browser.RegisterAsyncJsObject("boundAsync", new AsyncBoundObject()); + browser.RegisterAsyncJsObject("uniqueObject", new UniqueBoundObject()); // Enable touch scrolling - once properly tested this will likely become the default //browser.IsManipulationEnabled = true;