|
1 | | -The purpose of this spec is to describe a new WebView2 feature - Support for UA Strings - and its APIs. |
2 | | - |
3 | | -# Background |
4 | | - |
5 | | -A User Agent String is a client-side piece of information that the browser/webcontrol sends to the server/website a user visits. |
| 1 | +#Background |
| 2 | +The User Agent is a client-side piece of information that the browser/webcontrol sends to the server/website a user visits. |
6 | 3 | It contains information about user’s system and is modifiable by the user. |
7 | 4 |
|
8 | 5 | Currently, a developer can pass the --user-agent browser args to the CreateWebView2EnvironmentWithDetails function. |
9 | | - Ex. CreateWebView2EnvironmentWithDetails(nullptr, nullptr, L"--user-agent=\"myUA\"", ...); |
10 | | - For more info about the ‘—user-agent’ flag visit: https://peter.sh/experiments/chromium-command-line-switches/#user-agent. |
11 | | - |
12 | | -However, there is a limitation to this workaround, in that you cannot modify a command line switch at runtime. |
13 | | - |
14 | | -In this document we describe the new API. We'd appreciate your feedback. |
15 | | - |
16 | | - |
17 | | -# Description |
18 | | - |
19 | | -There are 2 locations for changing UA String in a WebView context: |
20 | | - |
21 | | -1. Settings – Changes UA per WebView2 via Chrome Developer Protocol. (CDP) |
22 | | -2. Environment Options – sets UA once at creation for the WebView2 environment. |
23 | | - |
24 | | -We wanted to create an API that handles #1?? or #2? //jason to update |
25 | | -We added an API that allows a user to ... |
26 | | - |
27 | | -# Examples |
28 | | -<!-- TEMPLATE |
29 | | - Use this section to explain the features of the API, showing |
30 | | - example code with each description in both C# (for our WinRT API or .NET API) and |
31 | | - in C++ for our COM API. Use snippets of the sample code you wrote for the sample apps. |
32 | | - |
33 | | - The general format is: |
34 | | - |
35 | | - ## FirstFeatureName |
36 | | - |
37 | | - Feature explanation text goes here, including why an app would use it, how it |
38 | | - replaces or supplements existing functionality. |
39 | | - |
40 | | - ```c# |
41 | | - void SampleMethod() |
42 | | - { |
43 | | - var show = new AnExampleOf(); |
44 | | - show.SomeMembers = AndWhyItMight(be, interesting) |
45 | | - } |
46 | | - ``` |
| 6 | + Ex. CreateWebView2EnvironmentWithDetails(nullptr, nullptr, L"--user-agent=\"myUA\"", ...); |
| 7 | +For more info about the ‘—user - agent’ flag visit : https |
| 8 | + : // peter.sh/experiments/chromium-command-line-switches/#user-agent. |
| 9 | + |
| 10 | + However, |
| 11 | + there are a couple limitations to this workaround-- you |
| 12 | + cannot modify a command line switch at runtime, |
| 13 | + nor can you change the user agent per webview |
| 14 | + . |
| 15 | + |
| 16 | + In this document we describe the new API |
| 17 | + .We'd appreciate your feedback. |
| 18 | + |
| 19 | +#Description |
| 20 | +The Settings component will change the UA per WebView2 via Chrome Developer |
| 21 | + Protocol command.(CDP) |
| 22 | + A key scenario is to allow end developers to get the current user |
| 23 | +agent from the webview and modify it based on some sort of event, |
| 24 | +such as navigating to a specific website and setting the user agent to |
| 25 | +emulate a different browser version |
| 26 | + . |
| 27 | + |
| 28 | +#Examples |
| 29 | + |
| 30 | +The following code snippet demonstrates how the environment APIs can be used |
| 31 | +: |
| 32 | + |
| 33 | +##Win32 C++ |
47 | 34 |
|
48 | | - ```cpp |
49 | | - void SampleClass::SampleMethod() |
50 | | - { |
51 | | - winrt::com_ptr<ICoreWebView2> webview2 = ... |
52 | | - } |
| 35 | + ```cpp m_webView->add_NavigationStarting( |
| 36 | + Callback<ICoreWebView2NavigationStartingEventHandler>( |
| 37 | + [this](ICoreWebView2 *sender, |
| 38 | + ICoreWebView2NavigationStartingEventArgs *args) -> HRESULT { |
| 39 | + static const PCWSTR url_compare_example = L"foo.org"; |
| 40 | + wil::unique_bstr domain = GetDomainOfUri(uri.get()); |
| 41 | + const wchar_t *domains = domain.get(); |
| 42 | + if (wcscmp(url_compare_example, domains) == 0) { |
| 43 | + wil::com_ptr<ICoreWebView2Settings> settings; |
| 44 | + CHECK_FAILURE(m_webView->get_Settings(&m_settings)); |
| 45 | + LPCWSTR mobile_ua = |
| 46 | + "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F Build/R16NW) " |
| 47 | + "AppleWebKit/537.36 (KHTML, like Gecko) " |
| 48 | + "Chrome/62.0.3202.84 Mobile Safari/537.36"; |
| 49 | + CHECK_FAILURE(settings->put_UserAgent(mobile_ua)); |
| 50 | + LPCWSTR received_ua; |
| 51 | + CHECK_FAILURE(settings->get_UserAgent(&received_ua)); |
| 52 | + EXPECT_EQ(base::Value(received_ua), base::Value(mobile_ua)) |
| 53 | + } |
| 54 | + return S_OK; |
| 55 | + }) |
| 56 | + .Get(), |
| 57 | + &m_navigationStartingToken); |
| 58 | +``` ##.NET and WinRT |
| 59 | + ```c #private void SetUserAgent(CoreWebView2 sender, |
| 60 | + CoreWebView2UserAgentArgs e) { |
| 61 | + var settings = webView2Control.CoreWebView2.Settings; |
| 62 | + settings.UserAgent = "Mozilla/5.0 (Linux; Android 8.0.0; SM-G960F " |
| 63 | + "Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) " |
| 64 | + "Chrome/62.0.3202.84 Mobile Safari/537.36"; |
| 65 | +} |
53 | 66 | ``` |
54 | 67 |
|
55 | | - ## SecondFeatureName |
| 68 | +#API Notes |
56 | 69 |
|
57 | | - Feature explanation text goes here, including why an app would use it, how it |
58 | | - replaces or supplements existing functionality. |
| 70 | +See [API Details](#api-details) section below for API reference. |
59 | 71 |
|
60 | | - ```c# |
61 | | - void SampleMethod() |
62 | | - { |
63 | | - var show = new AnExampleOf(); |
64 | | - show.SomeMembers = AndWhyItMight(be, interesting) |
65 | | - } |
66 | | - ``` |
67 | | - |
68 | | - ```cpp |
69 | | - void SampleClass::SampleMethod() |
70 | | - { |
71 | | - winrt::com_ptr<ICoreWebView2> webview2 = ... |
72 | | - } |
73 | | - ``` |
74 | | - |
75 | | - As an example of this section, see the Examples section for the PasswordBox |
76 | | - control (https://docs.microsoft.com/windows/uwp/design/controls-and-patterns/password-box#examples). |
77 | | ---> |
78 | | - |
79 | | - |
80 | | -# Remarks |
81 | | -<!-- TEMPLATE |
82 | | - Explanation and guidance that doesn't fit into the Examples section. |
83 | | - |
84 | | - APIs should only throw exceptions in exceptional conditions; basically, |
85 | | - only when there's a bug in the caller, such as argument exception. But if for some |
86 | | - reason it's necessary for a caller to catch an exception from an API, call that |
87 | | - out with an explanation either here or in the Examples |
88 | | ---> |
89 | | - |
90 | | - |
91 | | -# API Notes |
92 | | -<!-- TEMPLATE |
93 | | - Option 1: Give a one or two line description of each API (type and member), |
94 | | - or at least the ones that aren't obvious from their name. These |
95 | | - descriptions are what show up in IntelliSense. For properties, specify |
96 | | - the default value of the property if it isn't the type's default (for |
97 | | - example an int-typed property that doesn't default to zero.) |
98 | | - |
99 | | - Option 2: Put these descriptions in the below API Details section, |
100 | | - with a "///" comment above the member or type. |
101 | | ---> |
102 | | - |
103 | | - |
104 | | -# API Details |
105 | | -<!-- TEMPLATE |
106 | | - The exact API, in IDL format for our COM API and |
107 | | - in MIDL3 format (https://docs.microsoft.com/en-us/uwp/midl-3/) |
108 | | - when possible, or in C# if starting with an API sketch for our .NET and WinRT API. |
| 72 | +#API Details |
109 | 73 |
|
110 | | - Include every new or modified type but use // ... to remove any methods, |
111 | | - properties, or events that are unchanged. |
112 | | - |
113 | | - (GitHub's markdown syntax formatter does not (yet) know about MIDL3, so |
114 | | - use ```c# instead even when writing MIDL3.) |
115 | | - |
116 | | - Example: |
| 74 | +## Win32 C++ |
117 | 75 |
|
118 | | - ``` |
119 | | - /// Event args for the NewWindowRequested event. The event is fired when content |
120 | | - /// inside webview requested to open a new window (through window.open() and so on.) |
121 | | - [uuid(34acb11c-fc37-4418-9132-f9c21d1eafb9), object, pointer_default(unique)] |
122 | | - interface ICoreWebView2NewWindowRequestedEventArgs : IUnknown |
123 | | - { |
124 | | - // ... |
125 | | - |
126 | | - /// Window features specified by the window.open call. |
127 | | - /// These features can be considered for positioning and sizing of |
128 | | - /// new webview windows. |
129 | | - [propget] HRESULT WindowFeatures([out, retval] ICoreWebView2WindowFeatures** windowFeatures); |
| 76 | + ```IDL |
| 77 | + // This is the ICoreWebView2Settings Staging interface. |
| 78 | + [uuid(c79ba37e-9bd6-4b9e-b460-2ced163f231f), object, pointer_default(unique)] |
| 79 | + interface ICoreWebView2StagingSettings : IUnknown { |
| 80 | + /// `UserAgent` . Returns the User Agent. The default value is the |
| 81 | + /// default User Agent. |
| 82 | + [propget] HRESULT UserAgent([ out, retval ] LPCWSTR * userAgent); |
| 83 | + /// Sets the `UserAgentString` property. This property may be overriden if |
| 84 | + /// the User-Agent header is set in a request. |
| 85 | + [propput] HRESULT UserAgent([in] LPCWSTR userAgent); |
130 | 86 | } |
131 | | - ``` |
132 | | - |
133 | | - ```c# (but really MIDL3) |
134 | | - public class CoreWebView2NewWindowRequestedEventArgs |
135 | | - { |
136 | | - // ... |
137 | | - |
138 | | - public CoreWebView2WindowFeatures WindowFeatures { get; } |
| 87 | + ``` |
| 88 | + ## .NET and WinRT |
| 89 | + |
| 90 | + ```c #namespace Microsoft.Web.WebView2.Core { |
| 91 | + public |
| 92 | + partial class CoreWebView2 { |
| 93 | + // There are other API in this interface that we are not showing |
| 94 | + public |
| 95 | + CoreWebView2Settings UserAgent { |
| 96 | + get; |
| 97 | + set; |
| 98 | + }; |
| 99 | + } |
139 | 100 | } |
140 | 101 | ``` |
141 | | ---> |
142 | | - |
143 | | - |
144 | | -# Appendix |
145 | | -<!-- TEMPLATE |
146 | | - Anything else that you want to write down for posterity, but |
147 | | - that isn't necessary to understand the purpose and usage of the API. |
148 | | - For example, implementation details or links to other resources. |
149 | | ---> |
0 commit comments