Skip to content

Commit 84bbe8e

Browse files
author
Eain Chen
committed
Propose new naming
1 parent 8e0d604 commit 84bbe8e

File tree

1 file changed

+68
-88
lines changed

1 file changed

+68
-88
lines changed

specs/ProgrammaticSaveAs.md

Lines changed: 68 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ The context menu has the "Save as" item to manually save the html page, image,
77
pdf, or other content through a save as dialog. We provide more flexiable ways
88
to do the save as programmatically in WebView2. You can bring up the default
99
save as dialog easily. And you will be able to block default dialog, save the
10-
content silently, by providing the path and save as type programmatically or
10+
content silently, by providing the path and save as kind programmatically or
1111
even build your own save as UI.
1212

1313
In this document we describe the API. We'd appreciate your feedback.
1414

1515
# Description
1616

17-
We propose the `SaveContentAs` method WebView2, which allows you to trigger
18-
the save as programmatically. By using this method alone, the system default
19-
will popup.
17+
We propose the `RequestSaveAs` method WebView2, which allows you to trigger
18+
the save as programmatically. By using this method, the system default dialog,
19+
or your own ui will popup.
2020

21-
Additionally, we propose the `SaveAsRequested` event. You can register this
22-
event to block the default dialog and use the `SaveAsRequestedEventArgs`
23-
instead, to set your preferred save as path, save as type, and duplicate file
24-
replacement rule. In your client app, you can design your own UI to input
25-
these parameters. For HTML documents, we support 3 save as types: HTML_ONLY,
26-
SINGLE_FILE and COMPLETE. Non-HTML documents, must use DEFAULT, which will
27-
save the content as it is. This API has default values for all parameters,
28-
to perform the common save as operation.
21+
We propose the `SaveAsRequested` event. You can register this event to block
22+
the default dialog and use the `SaveAsRequestedEventArgs` instead, to set
23+
your preferred save as path, save as kind, and duplicate file replacement rule.
24+
In your client app, you can design your own UI to input these parameters.
25+
For HTML documents, we support 3 save as kinds: HTML_ONLY, SINGLE_FILE and
26+
COMPLETE. Non-HTML documents, must use DEFAULT, which will save the content as
27+
it is. This API has default values for all parameters, to perform the common
28+
save as operation.
2929

3030
# Examples
3131
## Win32 C++
@@ -66,25 +66,22 @@ bool ScenarioSaveAs::ToggleEventHandler()
6666
//
6767
// This is a customized dialog example, the constructor returns after the
6868
// dialog interaction is completed by the end user.
69-
SaveAsDialog dialog(m_appWindow->GetMainWindow(), contentSaveTypes);
69+
SaveAsDialog dialog(m_appWindow->GetMainWindow(), saveKinds);
7070
if (dialog.confirmed)
7171
{
72-
// Setting the ResultFilePath, SaveAsType, AllowReplace for the event
72+
// Setting the ResultFilePath, Kind, AllowReplace for the event
7373
// args from this customized dialog inputs is optional.
7474
// The event args has default values based on the document to save.
7575
CHECK_FAILURE(
7676
args->put_ResultFilePath((LPCWSTR)dialog.path.c_str()));
77-
CHECK_FAILURE(args->put_SaveAsType(dialog.selectedType));
77+
CHECK_FAILURE(args->put_Kind(dialog.selectedKind));
7878
CHECK_FAILURE(args->put_AllowReplace(dialog.allowReplace));
7979
}
8080
else
8181
{
8282
// Save As cancelled from this customized dialog
8383
CHECK_FAILURE(args->put_Cancel(TRUE));
8484
}
85-
86-
// Indicate out parameters have been set.
87-
CHECK_FAILURE(args->put_Handled(TRUE));
8885
};
8986

9087
wil::com_ptr<ICoreWebView2Deferral> deferral;
@@ -110,26 +107,21 @@ bool ScenarioSaveAs::ToggleEventHandler()
110107
}
111108
```
112109
### Programmatic Save As
113-
Call SaveContentAs method to trigger the programmatic save as.
110+
Call RequestSaveAs method to trigger the programmatic save as.
114111
```c++
115112

116113
bool ScenarioSaveAs::ProgrammaticSaveAs()
117114
{
118115
if (!m_webView2Staging20)
119116
return false;
120-
m_webView2Staging20->SaveContentAs(
121-
Callback<ICoreWebView2StagingSaveContentAsCompletedHandler>(
122-
[this](HRESULT errorCode, COREWEBVIEW2_SAVE_CONTENT_AS_RESULTS result) -> HRESULT
117+
m_webView2Staging20->RequestSaveAs(
118+
Callback<ICoreWebView2StagingRequestSaveAsCompletedHandler>(
119+
[this](HRESULT errorCode, COREWEBVIEW2_SAVE_AS_REQUESTED_RESULTS result) -> HRESULT
123120
{
124-
// Show SaveContentAs returned result, optional
125-
// Skip message box when the result is COREWEBVIEW2_SAVE_AS_OPEN_SYSTEM_DIALOG (0),
126-
// to prevent it deactivates save as modal dialog focus on the window
127-
if (result > 0)
128-
{
129-
MessageBox(
130-
m_appWindow->GetMainWindow(),
131-
(L"Save As " + saveAsResultString[result]).c_str(), L"Info", MB_OK);
132-
}
121+
// Show RequestSaveAs returned result, optional
122+
MessageBox(
123+
m_appWindow->GetMainWindow(),
124+
(L"Save As " + saveAsResultString[result]).c_str(), L"Info", MB_OK);
133125
return S_OK;
134126
})
135127
.Get());
@@ -140,36 +132,34 @@ bool ScenarioSaveAs::ProgrammaticSaveAs()
140132
# API Details
141133
## Win32 C++
142134
```c++
143-
/// Specifies save as type selection options for `ICoreWebView2Staging20`,
135+
/// Specifies save as requested kind selection options for `ICoreWebView2Staging20`,
144136
/// used in `SaveAsRequestedEventArgs`
145137
///
146138
/// When the source is a html page, supports to select `HTML_ONLY`,
147139
/// `SINGLE_FILE`, `COMPLETE`; when the source is a non-html,
148140
/// only allows to select `DEFAULT`; otherwise, will deny the download
149-
/// and return `COREWEBVIEW2_SAVE_AS_TYPE_NOT_SUPPORTED`.
141+
/// and return `COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_NOT_SUPPORTED`.
150142
///
151143
/// The content type/format is a MIME type, indicated by the source
152144
/// server side and identified by the browser. It’s not related to the
153145
/// file’s type or extension. MIME type of `text/html`,
154146
/// `application/xhtml+xml` are considered as html page.
155-
[v1_enum] typedef enum COREWEBVIEW2_SAVE_AS_TYPE {
147+
[v1_enum] typedef enum COREWEBVIEW2_SAVE_AS_REQUESTED_KIND {
156148
/// Default to save for a non-html content. If it is selected for a html
157149
/// page, it’s same as HTML_ONLY option.
158-
COREWEBVIEW2_SAVE_AS_TYPE_DEFAULT,
150+
COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_DEFAULT,
159151
/// Save the page as html
160-
COREWEBVIEW2_SAVE_AS_TYPE_HTML_ONLY,
152+
COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_HTML_ONLY,
161153
/// Save the page as mhtml
162-
COREWEBVIEW2_SAVE_AS_TYPE_SINGLE_FILE,
154+
COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_SINGLE_FILE,
163155
/// Save the page as html, plus, download the page related source files in
164156
/// a same name directory
165-
COREWEBVIEW2_SAVE_AS_TYPE_COMPLETE,
166-
} COREWEBVIEW2_SAVE_AS_TYPE;
157+
COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_COMPLETE,
158+
} COREWEBVIEW2_SAVE_AS_REQUESTED_KIND;
167159

168160
/// Status of a programmatic save as call, indicates the result
169-
/// for method `SaveContentAs`
170-
[v1_enum] typedef enum COREWEBVIEW2_SAVE_CONTENT_AS_RESULTS {
171-
/// Programmatically open a system default save as dialog
172-
COREWEBVIEW2_SAVE_AS_OPEN_SYSTEM_DIALOG,
161+
/// for method `RequestSaveAs`
162+
[v1_enum] typedef enum COREWEBVIEW2_SAVE_AS_REQUESTED_RESULTS {
173163
/// Could not perform Save As because the destination file path is an invalid path.
174164
///
175165
/// It is considered as invalid when:
@@ -178,38 +168,39 @@ bool ScenarioSaveAs::ProgrammaticSaveAs()
178168
///
179169
/// Parent directory can be itself, if the path is root directory, or
180170
/// root disk. When the root doesn't exist, the path is invalid.
181-
COREWEBVIEW2_SAVE_AS_INVALID_PATH,
171+
COREWEBVIEW2_SAVE_AS_REQUESTED_INVALID_PATH,
182172
/// Could not perform Save As because the destination file path already exists and
183-
/// replacing files was not allowed by the AllowReplace property.
184-
COREWEBVIEW2_SAVE_AS_FILE_ALREADY_EXISTS,
185-
/// Save as downloading not start as the `SAVE_AS_TYPE` selection not
173+
/// replacing files was not allowed by the `AllowReplace` property.
174+
COREWEBVIEW2_SAVE_AS_REQUESTED_FILE_ALREADY_EXISTS,
175+
/// Could not perform Save As when the `Kind` property selection not
186176
/// supported because of the content MIME type or system limits
187177
///
188-
/// MIME type limits please see the emun `COREWEBVIEW2_SAVE_AS_TYPE`
178+
/// MIME type limits please see the emun `COREWEBVIEW2_SAVE_AS_REQUESTED_KIND`
189179
///
190180
/// System limits might happen when select `HTML_ONLY` for an error page,
191181
/// select `COMPLETE` and WebView running in an App Container, etc.
192-
COREWEBVIEW2_SAVE_AS_TYPE_NOT_SUPPORTED,
182+
COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_NOT_SUPPORTED,
193183
/// Did not perform Save As because the client side decided to cancel.
194-
COREWEBVIEW2_SAVE_AS_CANCELLED,
195-
/// Save as request complete, the downloading started
196-
COREWEBVIEW2_SAVE_AS_STARTED
197-
} COREWEBVIEW2_SAVE_CONTENT_AS_RESULTS;
184+
COREWEBVIEW2_SAVE_AS_REQUESTED_CANCELLED,
185+
/// Save as requested completeed, the downloading would start
186+
COREWEBVIEW2_SAVE_AS_REQUESTED_STARTED
187+
} COREWEBVIEW2_SAVE_AS_REQUESTED_RESULTS;
198188

199189

200190
[uuid(15e1c6a3-c72a-4df3-91d7-d097fbec3bfd), object, pointer_default(unique)]
201191
interface ICoreWebView2Staging20 : IUnknown {
202-
/// Programmatically trigger a save as action for current content.
192+
/// Programmatically trigger a save as action for current content. `SaveAsRequested`
193+
/// event will be raised.
203194
///
204-
/// Opens a system modal dialog by default. Returns COREWEBVIEW2_SAVE_AS_OPEN_SYSTEM_DIALOG.
205-
/// If it was already opened, this method would not open another one
195+
/// Opens a system modal dialog by default. If it was already opened, this method
196+
/// would not open another one. If the `SuppressDefaultDialog` is TRUE, won't open
197+
/// the system dialog.
206198
///
207-
/// If the silent save as option is enabled, won't open the system dialog, will
208-
/// raise the `SaveAsRequested` event instead and process through its event args. The method can return
209-
/// a detailed info to indicate the call's result. Please see COREWEBVIEW2_SAVE_CONTENT_AS_RESULTS
199+
/// The method can return a detailed info to indicate the call's result.
200+
/// Please see COREWEBVIEW2_SAVE_AS_REQUESTED_RESULTS
210201
///
211202
/// \snippet ScenarioSaveAs.cpp ProgrammaticSaveAs
212-
HRESULT SaveContentAs([in] ICoreWebView2StagingSaveContentAsCompletedHandler* handler);
203+
HRESULT SaveContentAs([in] ICoreWebView2StagingRequestSaveAsCompletedHandler* handler);
213204

214205
/// Add an event handler for the `SaveAsRequested` event. This event is raised
215206
/// when save as is triggered, programmatically or manually.
@@ -226,8 +217,7 @@ interface ICoreWebView2Staging20 : IUnknown {
226217
[in] EventRegistrationToken token);
227218
}
228219

229-
/// The event handler for the `SaveAsRequested` event, when the handler
230-
/// exists, the silent save as enables.
220+
/// The event handler for the `SaveAsRequested` event.
231221
[uuid(55b86cd2-adfd-47f1-9cef-cdfb8c414ed3), object, pointer_default(unique)]
232222
interface ICoreWebView2StagingSaveAsRequestedEventHandler : IUnknown {
233223
HRESULT Invoke(
@@ -241,16 +231,6 @@ interface ICoreWebView2StagingSaveAsRequestedEventArgs : IUnknown {
241231
/// Get the Mime type of content to be saved
242232
[propget] HRESULT ContentMimeType([out, retval] LPWSTR* value);
243233

244-
/// Indicates if pramameters in the event args has been set, TRUE means been set.
245-
///
246-
/// The default value is FALSE.
247-
///
248-
/// Set the `Handled` for save as
249-
[propput] HRESULT Handled ([in] BOOL value);
250-
251-
/// Get the `Handled` for save as
252-
[propget] HRESULT Handled ([out, retval] BOOL* value);
253-
254234
/// Indicates if client side cancelled the silent save as, TRUE means cancelled.
255235
/// When the event is invoked, the download won't start. A programmatic call will
256236
/// return COREWEBVIEW2_SAVE_AS_CANCELLED as well.
@@ -284,9 +264,9 @@ interface ICoreWebView2StagingSaveAsRequestedEventArgs : IUnknown {
284264
/// not exist, save as will be denied and return COREWEBVIEW2_SAVE_AS_INVALID_PATH.
285265
///
286266
/// When the download complete and success, a target file will be saved at this
287-
/// location. If the SAVE_AS_TYPE is `COMPLETE`, will be an additional directory
288-
/// with resources files. The directory has the same name as filename, at the same
289-
/// location.
267+
/// location. If the select `COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_COMPLETE`, will be
268+
/// an additional directory with resources files. The directory has the same name
269+
/// as filename, at the same location.
290270
///
291271
/// The default value is a system suggested path, based on users' local environment.
292272
///
@@ -304,29 +284,29 @@ interface ICoreWebView2StagingSaveAsRequestedEventArgs : IUnknown {
304284
///
305285
/// The default value is FALSE
306286
///
307-
/// Set if allowed to replace the old file if duplicate happens in the save as job
287+
/// Set if allowed to replace the old file if duplicate happens in the save as
308288
[propput] HRESULT AllowReplace ([in] BOOL value);
309289

310290
/// Get the duplicates replace rule for save as
311291
[propget] HRESULT AllowReplace ([out, retval] BOOL* value);
312292

313-
/// How to save documents with different types. See the enum
314-
/// COREWEBVIEW2_SAVE_AS_TYPE for a description of the different options.
315-
/// If the type isn't allowed for the current document,
316-
/// COREWEBVIEW2_SAVE_AS_TYPE_NOT_SUPPORT will be returned from SaveContentAs.
293+
/// How to save documents with different kind. See the enum
294+
/// COREWEBVIEW2_SAVE_AS_REQUESTED_KIND for a description of the different options.
295+
/// If the kind isn't allowed for the current document,
296+
/// COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_NOT_SUPPORT will be returned from RequestSaveAs.
317297
///
318-
/// The default value is COREWEBVIEW2_SAVE_AS_TYPE_DEFAULT
298+
/// The default value is COREWEBVIEW2_SAVE_AS_REQUESTED_KIND_DEFAULT
319299
///
320-
/// Set the content save as type for save as job
321-
[propput] HRESULT SaveAsType ([in] COREWEBVIEW2_SAVE_AS_TYPE value);
300+
/// Set the kind for save as
301+
[propput] HRESULT Kind ([in] COREWEBVIEW2_SAVE_AS_REQUESTED_KIND value);
322302

323-
/// Get the content save as type for save as job
324-
[propget] HRESULT SaveAsType ([out, retval] COREWEBVIEW2_SAVE_AS_TYPE* value);
303+
/// Get the kind for save as
304+
[propget] HRESULT Kind ([out, retval] COREWEBVIEW2_SAVE_AS_REQUESTED_KIND* value);
325305
}
326306

327-
/// Receive the result for `SaveContentAs` method
307+
/// Receive the result for `RequestSaveAs` method
328308
[uuid(1a02e9d9-14d3-41c6-9581-8d6e1e6f50fe), object, pointer_default(unique)]
329-
interface ICoreWebView2StagingSaveContentAsCompletedHandler : IUnknown {
330-
HRESULT Invoke([in] HRESULT errorCode, [in] COREWEBVIEW2_SAVE_CONTENT_AS_RESULTS result);
309+
interface ICoreWebView2StagingRequestSaveAsCompletedHandler : IUnknown {
310+
HRESULT Invoke([in] HRESULT errorCode, [in] COREWEBVIEW2_REQUEST_SAVE_RESULTS result);
331311
}
332312
```

0 commit comments

Comments
 (0)