Skip to content

Commit b0a2e73

Browse files
authored
Add FavIcon API: Merge pull request #1500 from MicrosoftEdge/api-get-favicon-draft
Added the API for the Favicon with example code
2 parents 623787d + b9a7480 commit b0a2e73

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

specs/GetFavicon.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Background
2+
A favicon (favorite icon) is a tiny icon included along with a website, which is displayed in places like the browser's address bar, page tabs and bookmarks menu. Developers would like to have an API which allows them to retrieve the Favicon of a webpage, if it has been set, as well as get an update whenever the favicon has changed.
3+
4+
# Description
5+
We propose a new Webview2 event which would allow developers to access the current Favicon of a page and be notified when the favicon changes. This means when a page first loads, it would raise the FaviconChanged event since before parsing the HTML document there is no known favicon. DOM or JavaScript may change the Favicon, causing the event to be raised again for the same document.
6+
7+
# Examples
8+
## Win32 C++ Registering a listener for favicon changes
9+
```cpp
10+
CHECK_FAILURE(m_webView->add_FaviconChanged(
11+
Callback<ICoreWebView2FaviconChangedEventHandler>(
12+
[this](ICoreWebView2* sender, IUnknown* args) -> HRESULT {
13+
14+
wil::com_ptr<IStream> iconStream = SHCreateMemStream(nullptr, 0);
15+
16+
sender->GetFavicon(COREWEBVIEW2_FAVICON_IMAGE_FORMAT_PNG, iconStream.get(),
17+
Callback<ICoreWebView2ExperimentalGetFaviconCompletedHandler>(
18+
[iconStream, this](HRESULT error_code) -> HRESULT
19+
{
20+
if (error_code == S_OK)
21+
{
22+
Gdiplus::Bitmap* iconBitmap =
23+
new Gdiplus::Bitmap(iconStream.get());
24+
HICON icon;
25+
if (!iconBitmap->GetHICON(&icon))
26+
{
27+
SendMessage(
28+
m_appWindow->GetMainWindow(), WM_SETICON,
29+
ICON_SMALL, (LPARAM)icon);
30+
}
31+
}
32+
33+
return S_OK;
34+
}).Get());
35+
36+
return S_OK;
37+
}).Get(), &m_faviconChangedToken));
38+
```
39+
## .NET / WinRT Registering a listener for favicon changes
40+
```c#
41+
webView.CoreWebView2.FaviconChanged += (CoreWebView2 sender, Object arg) =>
42+
{
43+
System.IO.Stream stream = new System.IO.MemoryStream();
44+
await webView.CoreWebView2.GetFaviconAsync(
45+
CoreWebView2FaviconImageFormat.Png,
46+
stream);
47+
// setting the window Icon to the bitmap
48+
this.Icon = BitmapFrame.Create(stream);
49+
50+
};
51+
```
52+
# API Notes
53+
Note that even if a web page does not have a Favicon, the FaviconChanged event
54+
is raised when the page is navigated to. The Favicon would be an
55+
empty image stream and empty Uri for the lack of a favicon. The end developer is expected to handle this scenario.
56+
Otherwise, we raise the FaviconChanged with an observed change to the
57+
Favicon. In that scenario, the CoreWebView2 has an updated value for the FaviconUri property, and the GetFavicon method to match the updated favicon.
58+
See [API Details](#api-details) Section below for API reference
59+
# API Details
60+
## Win32 C++
61+
```cpp
62+
/// This interface is a handler for when the `Favicon` is changed.
63+
/// The sender is the ICoreWebView2 object the top-level document of
64+
/// which has changed favicon and the eventArgs is nullptr. Use the
65+
/// FaviconUri property and GetFavicon method to obtain the favicon
66+
/// data. The second argument is always null.
67+
/// For more information see `add_FaviconChanged`.
68+
[uuid(2913DA94-833D-4DE0-8DCA-900FC524A1A4), object, pointer_default(unique)]
69+
interface ICoreWebView2FaviconChangedEventHandler : IUnknown {
70+
/// Called to notify the favicon changed.
71+
HRESULT Invoke(
72+
[in] ICoreWebView2* sender,
73+
[in] IUnknown* args);
74+
}
75+
76+
/// This interface is a handler for the completion of the copying for the`imageStream`.
77+
/// The 'error_code` is E_NOT_SET if the there is no image. Otherwise error_code
78+
/// is the result from the image write operation.
79+
/// For more details, see the `GetFavicon` API.
80+
[uuid(A2508329-7DA8-49D7-8C05-FA125E4AEE8D), object, pointer_default(unique)]
81+
interface ICoreWebView2GetFaviconCompletedHandler : IUnknown {
82+
/// Called to notify the favicon has been retrieved.
83+
HRESULT Invoke([in] HRESULT error_code);
84+
}
85+
86+
/// This is the ICoreWebView2 Experimental Favicon interface.
87+
[uuid(DC838C64-F64B-4DC7-98EC-0992108E2157), object, pointer_default(unique)]
88+
interface ICoreWebView2_10 : ICoreWebView2_9 {
89+
/// Add an event handler for the `FaviconChanged` event.
90+
/// The `FaviconChanged` event is raised when the
91+
/// [favicon](https://developer.mozilla.org/en-US/docs/Glossary/Favicon)
92+
/// of the top-level document changes or if script dynamically changes the favicon.
93+
/// The FaviconChanged event will be raised for first navigating to a new
94+
/// document, whether or not a document declares a Favicon in HTML. The event will
95+
/// be raised again if a favicon is declared in its HTML or has script
96+
/// to set its favicon. The favicon information can then be retrieved with
97+
/// `GetFavicon` and `FaviconUri`.
98+
HRESULT add_FaviconChanged(
99+
[in] ICoreWebViewFaviconChangedEventHandler* eventHandler,
100+
[out] EventRegistrationToken* token);
101+
102+
/// Remove the event handler for `FaviconChanged` event.
103+
HRESULT remove_FaviconChanged(
104+
[in] EventRegistrationToken token);
105+
106+
/// Get the current Uri of the favicon as a string.
107+
/// If the value is null, then the return value is `E_POINTER`, otherwise it is `S_OK`.
108+
/// If a page has no favicon then the value is an empty string.
109+
[propget] HRESULT FaviconUri([out, retval] LPWSTR* value);
110+
111+
/// Async function for getting the actual image data of the favicon.
112+
/// If the `imageStream` is null, the `HRESULT` will be `E_POINTER`, otherwise
113+
/// it is `S_OK`.
114+
/// The image is copied to the `imageStream` object. If there is no image then
115+
/// no data would be copied into the imageStream.
116+
/// In either scenario the `completedHandler` is executed at the end of the operation.
117+
HRESULT GetFavicon(
118+
[in] COREWEBVIEW2_FAVICON_IMAGE_FORMAT format,
119+
[in] IStream* imageStream,
120+
[in] ICoreWebView2GetFaviconCompletedHandler* completedHandler);
121+
}
122+
123+
[v1_enum]
124+
typedef enum COREWEBVIEW2_FAVICON_IMAGE_FORMAT {
125+
/// Indicates that CoreWebView2.GetFaviconAsync should return the favicon in PNG format.
126+
COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT_PNG,
127+
128+
/// Indicates that CoreWebView2.GetFaviconAsync should return the favicon in JPG format.
129+
COREWEBVIEW2_CAPTURE_PREVIEW_IMAGE_FORMAT_JPEG,
130+
}
131+
```
132+
133+
## .Net/ WinRT
134+
```c#
135+
namespace Microsoft.Web.WebView2.Core
136+
{
137+
enum CoreWebView2FaviconImageFormat
138+
{
139+
Png = 0,
140+
Jpeg = 1,
141+
};
142+
143+
runtimeclass CoreWebView2
144+
{
145+
[interface_name("Microsoft.Web.WebView2.Core.ICoreWebView2_10")]
146+
{
147+
String FaviconUri { get; };
148+
149+
event Windows.Foundation.TypedEventHandler<CoreWebView2, Object> FaviconChanged;
150+
151+
Windows.Foundation.IAsyncAction GetFaviconAsync(CoreWebView2FaviconImageFormat format, Windows.Storage.Streams.IRandomAccessStream imageStream);
152+
}
153+
}
154+
}
155+
```

0 commit comments

Comments
 (0)