Hook up IDC_SAVEPAGE to the PDF plugin.
Implement the plumbing from the PDF plugin out to MimeHandlerViewGuest, so the plugin can let the browser know whether it is able to handle PDF saving internally. On the browser side, add WebContentsDelegate::GuestSaveFrame(). When the user asks the browser to save a PDF, the request reaches WebContentsImpl::SaveFrameWithHeaders(). Here, the embedder WebContents can check for the existance of a guest WebContents and use GuestSaveFrame() to ask the guest to perform the save. GuestSaveFrame() calls into MimeHandlerViewGuest, which knows whether the plugin can or not. When the plugin can save, MimeHandlerViewGuest will dispatch an event to the PDF Viewer to trigger the same code as when the user presses the Save button in the PDF Viewer. The PDF Viewer already knows how to talk to the plugin to save PDFs via its own Save button. BUG=61248 Change-Id: I11fc00dec99445faaeb1771ea071dbffc99b6c14 Reviewed-on: https://chromium-review.googlesource.com/c/1447264 Reviewed-by: Ehsan Karamad <ekaramad@chromium.org> Reviewed-by: Avi Drissman <avi@chromium.org> Reviewed-by: Raymes Khoury <raymes@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Devlin <rdevlin.cronin@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/master@{#633448}
This commit is contained in:
chrome/browser
resources
ui
components/pdf
browser
common
renderer
content
extensions
pdf
ppapi
c
private
cpp
proxy
thunk
third_party/closure_compiler/externs
tools/metrics/histograms
@ -315,6 +315,11 @@ function PDFViewer(browserApi) {
|
||||
|
||||
// Request translated strings.
|
||||
chrome.resourcesPrivate.getStrings('pdf', this.handleStrings_.bind(this));
|
||||
|
||||
// Listen for save commands from the browser.
|
||||
if (chrome.mimeHandlerPrivate && chrome.mimeHandlerPrivate.onSave) {
|
||||
chrome.mimeHandlerPrivate.onSave.addListener(this.onSave.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
PDFViewer.prototype = {
|
||||
@ -1123,6 +1128,21 @@ PDFViewer.prototype = {
|
||||
this.isFormFieldFocused_ = focused;
|
||||
},
|
||||
|
||||
/**
|
||||
* An event handler for when the browser tells the PDF Viewer to perform a
|
||||
* save.
|
||||
*
|
||||
* @param {string} streamUrl unique identifier for a PDF Viewer instance.
|
||||
* @private
|
||||
*/
|
||||
onSave: async function(streamUrl) {
|
||||
if (streamUrl != this.browserApi_.getStreamInfo().streamUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.save();
|
||||
},
|
||||
|
||||
/**
|
||||
* Saves the current PDF document to disk.
|
||||
*/
|
||||
|
@ -205,6 +205,7 @@
|
||||
#include "extensions/browser/extension_prefs.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/extension_system.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
|
||||
#include "extensions/buildflags/buildflags.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/extension.h"
|
||||
@ -1575,6 +1576,12 @@ content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager(
|
||||
return JavaScriptDialogTabHelper::FromWebContents(source);
|
||||
}
|
||||
|
||||
bool Browser::GuestSaveFrame(content::WebContents* guest_web_contents) {
|
||||
auto* guest_view =
|
||||
extensions::MimeHandlerViewGuest::FromWebContents(guest_web_contents);
|
||||
return guest_view && guest_view->PluginDoSave();
|
||||
}
|
||||
|
||||
content::ColorChooser* Browser::OpenColorChooser(
|
||||
WebContents* web_contents,
|
||||
SkColor initial_color,
|
||||
|
@ -688,6 +688,7 @@ class Browser : public TabStripModelObserver,
|
||||
content::WebContents* web_contents) override;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) override;
|
||||
bool GuestSaveFrame(content::WebContents* guest_web_contents) override;
|
||||
content::ColorChooser* OpenColorChooser(
|
||||
content::WebContents* web_contents,
|
||||
SkColor color,
|
||||
|
@ -51,3 +51,12 @@ void ChromePDFWebContentsHelperClient::OnSaveURL(
|
||||
content::WebContents* contents) {
|
||||
RecordDownloadSource(DOWNLOAD_INITIATED_BY_PDF_SAVE);
|
||||
}
|
||||
|
||||
void ChromePDFWebContentsHelperClient::SetPluginCanSave(
|
||||
content::WebContents* contents,
|
||||
bool can_save) {
|
||||
auto* guest_view =
|
||||
extensions::MimeHandlerViewGuest::FromWebContents(contents);
|
||||
if (guest_view)
|
||||
guest_view->SetPluginCanSave(can_save);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class ChromePDFWebContentsHelperClient
|
||||
int content_restrictions) override;
|
||||
void OnPDFHasUnsupportedFeature(content::WebContents* contents) override;
|
||||
void OnSaveURL(content::WebContents* contents) override;
|
||||
void SetPluginCanSave(content::WebContents* contents, bool can_save) override;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ChromePDFWebContentsHelperClient);
|
||||
};
|
||||
|
@ -81,6 +81,10 @@ void PDFWebContentsHelper::SelectionChanged(const gfx::PointF& left,
|
||||
DidScroll();
|
||||
}
|
||||
|
||||
void PDFWebContentsHelper::SetPluginCanSave(bool can_save) {
|
||||
client_->SetPluginCanSave(web_contents(), can_save);
|
||||
}
|
||||
|
||||
void PDFWebContentsHelper::DidScroll() {
|
||||
if (!touch_selection_controller_client_manager_)
|
||||
InitTouchSelectionClientManager();
|
||||
|
@ -83,6 +83,7 @@ class PDFWebContentsHelper
|
||||
int32_t left_height,
|
||||
const gfx::PointF& right,
|
||||
int32_t right_height) override;
|
||||
void SetPluginCanSave(bool can_save) override;
|
||||
|
||||
content::WebContentsFrameBindingSet<mojom::PdfService> pdf_service_bindings_;
|
||||
std::unique_ptr<PDFWebContentsHelperClient> const client_;
|
||||
|
@ -21,6 +21,10 @@ class PDFWebContentsHelperClient {
|
||||
virtual void OnPDFHasUnsupportedFeature(content::WebContents* contents) = 0;
|
||||
|
||||
virtual void OnSaveURL(content::WebContents* contents) = 0;
|
||||
|
||||
// Sets whether the PDF plugin can handle file saving internally.
|
||||
virtual void SetPluginCanSave(content::WebContents* contents,
|
||||
bool can_save) = 0;
|
||||
};
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -36,4 +36,7 @@ interface PdfService {
|
||||
// current selection.
|
||||
SelectionChanged(gfx.mojom.PointF left, int32 left_height,
|
||||
gfx.mojom.PointF right, int32 right_height);
|
||||
|
||||
// Notifies the embedder know the plugin can handle save commands internally.
|
||||
SetPluginCanSave(bool can_save);
|
||||
};
|
||||
|
@ -111,6 +111,8 @@ int32_t PepperPDFHost::OnResourceMessageReceived(
|
||||
OnHostMsgSetAccessibilityPageInfo)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SelectionChanged,
|
||||
OnHostMsgSelectionChanged)
|
||||
PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_PDF_SetPluginCanSave,
|
||||
OnHostMsgSetPluginCanSave)
|
||||
PPAPI_END_MESSAGE_MAP()
|
||||
return PP_ERROR_FAILED;
|
||||
}
|
||||
@ -300,6 +302,17 @@ int32_t PepperPDFHost::OnHostMsgSelectionChanged(
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
int32_t PepperPDFHost::OnHostMsgSetPluginCanSave(
|
||||
ppapi::host::HostMessageContext* context,
|
||||
bool can_save) {
|
||||
mojom::PdfService* service = GetRemotePdfService();
|
||||
if (!service)
|
||||
return PP_ERROR_FAILED;
|
||||
|
||||
service->SetPluginCanSave(can_save);
|
||||
return PP_OK;
|
||||
}
|
||||
|
||||
void PepperPDFHost::CreatePdfAccessibilityTreeIfNeeded() {
|
||||
if (!pdf_accessibility_tree_) {
|
||||
pdf_accessibility_tree_ =
|
||||
|
@ -123,6 +123,8 @@ class PepperPDFHost : public ppapi::host::ResourceHost,
|
||||
int32_t left_height,
|
||||
const PP_FloatPoint& right,
|
||||
int32_t right_height);
|
||||
int32_t OnHostMsgSetPluginCanSave(ppapi::host::HostMessageContext* context,
|
||||
bool can_save);
|
||||
|
||||
void CreatePdfAccessibilityTreeIfNeeded();
|
||||
|
||||
|
@ -3814,6 +3814,21 @@ void WebContentsImpl::SaveFrameWithHeaders(
|
||||
const Referrer& referrer,
|
||||
const std::string& headers,
|
||||
const base::string16& suggested_filename) {
|
||||
// Check and see if the guest can handle this.
|
||||
if (delegate_) {
|
||||
WebContents* guest_web_contents = nullptr;
|
||||
if (browser_plugin_embedder_) {
|
||||
BrowserPluginGuest* guest = browser_plugin_embedder_->GetFullPageGuest();
|
||||
if (guest)
|
||||
guest_web_contents = guest->GetWebContents();
|
||||
} else if (browser_plugin_guest_) {
|
||||
guest_web_contents = this;
|
||||
}
|
||||
|
||||
if (guest_web_contents && delegate_->GuestSaveFrame(guest_web_contents))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetLastCommittedURL().is_valid())
|
||||
return;
|
||||
if (delegate_ && delegate_->SaveFrame(url, referrer))
|
||||
|
@ -246,6 +246,10 @@ bool WebContentsDelegate::IsNeverVisible(WebContents* web_contents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebContentsDelegate::GuestSaveFrame(WebContents* guest_web_contents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebContentsDelegate::SaveFrame(const GURL& url, const Referrer& referrer) {
|
||||
return false;
|
||||
}
|
||||
|
@ -539,6 +539,10 @@ class CONTENT_EXPORT WebContentsDelegate {
|
||||
// Returns true if the WebContents is never visible.
|
||||
virtual bool IsNeverVisible(WebContents* web_contents);
|
||||
|
||||
// Askss |guest_web_contents| to perform the same. If this returns true, the
|
||||
// default behavior is suppressed.
|
||||
virtual bool GuestSaveFrame(WebContents* guest_web_contents);
|
||||
|
||||
// Called in response to a request to save a frame. If this returns true, the
|
||||
// default behavior is suppressed.
|
||||
virtual bool SaveFrame(const GURL& url, const Referrer& referrer);
|
||||
|
@ -454,6 +454,7 @@ enum HistogramValue {
|
||||
AUTOFILL_PRIVATE_ON_LOCAL_CREDIT_CARD_LIST_CHANGED = 433,
|
||||
AUTOFILL_PRIVATE_ON_SERVER_CREDIT_CARD_LIST_CHANGED = 434,
|
||||
ACCESSIBILITY_PRIVATE_ON_ANNOUNCE_FOR_ACCESSIBILITY = 435,
|
||||
MIME_HANDLER_PRIVATE_SAVE = 436,
|
||||
// Last entry: Add new entries above, then run:
|
||||
// python tools/metrics/histograms/update_extension_histograms.py
|
||||
ENUM_BOUNDARY
|
||||
|
@ -6,6 +6,10 @@
|
||||
|
||||
namespace mime_handler_view {
|
||||
|
||||
// API namespace.
|
||||
const char kAPINamespace[] = "mimeHandlerViewGuestInternal";
|
||||
|
||||
// Other.
|
||||
const char kViewId[] = "viewId";
|
||||
|
||||
} // namespace mime_handler_view
|
||||
|
@ -2,13 +2,17 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Constants used by MimeHandlerView..
|
||||
// Constants used by MimeHandlerView.
|
||||
|
||||
#ifndef EXTENSIONS_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_MIME_HANDLER_VIEW_CONSTANTS_H_
|
||||
#define EXTENSIONS_BROWSER_GUEST_VIEW_MIME_HANDLER_VIEW_MIME_HANDLER_VIEW_CONSTANTS_H_
|
||||
|
||||
namespace mime_handler_view {
|
||||
|
||||
// API namespace.
|
||||
extern const char kAPINamespace[];
|
||||
|
||||
// Other.
|
||||
extern const char kViewId[];
|
||||
|
||||
} // namespace mime_handler_view
|
||||
|
@ -22,12 +22,14 @@
|
||||
#include "content/public/common/web_preferences.h"
|
||||
#include "extensions/browser/api/extensions_api_client.h"
|
||||
#include "extensions/browser/api/mime_handler_private/mime_handler_private.h"
|
||||
#include "extensions/browser/event_router.h"
|
||||
#include "extensions/browser/extension_registry.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_stream_manager.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
|
||||
#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
|
||||
#include "extensions/browser/process_manager.h"
|
||||
#include "extensions/browser/view_type_utils.h"
|
||||
#include "extensions/common/api/mime_handler_private.h"
|
||||
#include "extensions/common/constants.h"
|
||||
#include "extensions/common/guest_view/extensions_guest_view_messages.h"
|
||||
#include "extensions/strings/grit/extensions_strings.h"
|
||||
@ -156,7 +158,7 @@ void MimeHandlerViewGuest::SetBeforeUnloadController(
|
||||
}
|
||||
|
||||
const char* MimeHandlerViewGuest::GetAPINamespace() const {
|
||||
return "mimeHandlerViewGuestInternal";
|
||||
return mime_handler_view::kAPINamespace;
|
||||
}
|
||||
|
||||
int MimeHandlerViewGuest::GetTaskPrefix() const {
|
||||
@ -316,6 +318,29 @@ MimeHandlerViewGuest::GetJavaScriptDialogManager(
|
||||
owner_web_contents());
|
||||
}
|
||||
|
||||
bool MimeHandlerViewGuest::PluginDoSave() {
|
||||
if (!attached() || !plugin_can_save_)
|
||||
return false;
|
||||
|
||||
base::ListValue::ListStorage args;
|
||||
args.emplace_back(stream_->stream_url().spec());
|
||||
|
||||
auto event = std::make_unique<Event>(
|
||||
events::MIME_HANDLER_PRIVATE_SAVE,
|
||||
api::mime_handler_private::OnSave::kEventName,
|
||||
std::make_unique<base::ListValue>(std::move(args)), browser_context());
|
||||
EventRouter* event_router = EventRouter::Get(browser_context());
|
||||
event_router->DispatchEventToExtension(extension_misc::kPdfExtensionId,
|
||||
std::move(event));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MimeHandlerViewGuest::GuestSaveFrame(
|
||||
content::WebContents* guest_web_contents) {
|
||||
MimeHandlerViewGuest* guest_view = FromWebContents(guest_web_contents);
|
||||
return guest_view == this && PluginDoSave();
|
||||
}
|
||||
|
||||
bool MimeHandlerViewGuest::SaveFrame(const GURL& url,
|
||||
const content::Referrer& referrer) {
|
||||
if (!attached())
|
||||
|
@ -94,6 +94,11 @@ class MimeHandlerViewGuest
|
||||
void SetBeforeUnloadController(
|
||||
mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control);
|
||||
|
||||
void SetPluginCanSave(bool can_save) { plugin_can_save_ = can_save; }
|
||||
|
||||
// Asks the plugin to do save.
|
||||
bool PluginDoSave();
|
||||
|
||||
content::RenderFrameHost* GetEmbedderFrame() const;
|
||||
|
||||
protected:
|
||||
@ -126,6 +131,7 @@ class MimeHandlerViewGuest
|
||||
const blink::WebGestureEvent& event) final;
|
||||
content::JavaScriptDialogManager* GetJavaScriptDialogManager(
|
||||
content::WebContents* source) final;
|
||||
bool GuestSaveFrame(content::WebContents* guest_web_contents) final;
|
||||
bool SaveFrame(const GURL& url, const content::Referrer& referrer) final;
|
||||
void OnRenderFrameHostDeleted(int process_id, int routing_id) final;
|
||||
void EnterFullscreenModeForTab(
|
||||
@ -176,6 +182,7 @@ class MimeHandlerViewGuest
|
||||
|
||||
bool is_guest_fullscreen_ = false;
|
||||
bool is_embedder_fullscreen_ = false;
|
||||
bool plugin_can_save_ = false;
|
||||
|
||||
mime_handler::BeforeUnloadControlPtrInfo pending_before_unload_control_;
|
||||
|
||||
|
@ -45,4 +45,10 @@
|
||||
boolean showDialog,
|
||||
optional SetShowBeforeUnloadDialogCallback callback);
|
||||
};
|
||||
|
||||
interface Events {
|
||||
// Fired when the browser wants the listener to perform a save.
|
||||
// |streamUrl|: Unique ID for the instance that should perform the save.
|
||||
static void onSave(DOMString streamUrl);
|
||||
};
|
||||
};
|
||||
|
@ -1928,6 +1928,7 @@ void OutOfProcessInstance::IsSelectingChanged(bool is_selecting) {
|
||||
|
||||
void OutOfProcessInstance::IsEditModeChanged(bool is_edit_mode) {
|
||||
edit_mode_ = is_edit_mode;
|
||||
pp::PDF::SetPluginCanSave(this, ShouldSaveEdits());
|
||||
}
|
||||
|
||||
float OutOfProcessInstance::GetToolbarHeightInScreenCoords() {
|
||||
|
@ -173,6 +173,9 @@ struct PPB_PDF {
|
||||
const struct PP_FloatPoint* right,
|
||||
int32_t right_height);
|
||||
|
||||
// Sets whether the PDF viewer can handle save commands internally.
|
||||
void (*SetPluginCanSave)(PP_Instance instance, bool can_save);
|
||||
|
||||
// Displays an alert dialog.
|
||||
void (*ShowAlertDialog)(PP_Instance instance, const char* message);
|
||||
|
||||
|
@ -233,4 +233,12 @@ void PDF::SelectionChanged(const InstanceHandle& instance,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void PDF::SetPluginCanSave(const InstanceHandle& instance, bool can_save) {
|
||||
if (has_interface<PPB_PDF>()) {
|
||||
get_interface<PPB_PDF>()->SetPluginCanSave(instance.pp_instance(),
|
||||
can_save);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace pp
|
||||
|
@ -83,6 +83,7 @@ class PDF {
|
||||
int32_t left_height,
|
||||
const PP_FloatPoint& right,
|
||||
int32_t right_height);
|
||||
static void SetPluginCanSave(const InstanceHandle& instance, bool can_save);
|
||||
};
|
||||
|
||||
} // namespace pp
|
||||
|
@ -240,5 +240,9 @@ void PDFResource::SelectionChanged(const PP_FloatPoint& left,
|
||||
right_height));
|
||||
}
|
||||
|
||||
void PDFResource::SetPluginCanSave(bool can_save) {
|
||||
Post(RENDERER, PpapiHostMsg_PDF_SetPluginCanSave(can_save));
|
||||
}
|
||||
|
||||
} // namespace proxy
|
||||
} // namespace ppapi
|
||||
|
@ -69,6 +69,7 @@ class PPAPI_PROXY_EXPORT PDFResource
|
||||
int32_t left_height,
|
||||
const PP_FloatPoint& right,
|
||||
int32_t right_height) override;
|
||||
void SetPluginCanSave(bool can_save) override;
|
||||
|
||||
private:
|
||||
std::string locale_;
|
||||
|
@ -138,5 +138,16 @@ TEST_F(PDFResourceTest, SelectionChanged) {
|
||||
PpapiHostMsg_PDF_SelectionChanged::ID, ¶ms, &msg));
|
||||
}
|
||||
|
||||
TEST_F(PDFResourceTest, SetPluginCanSave) {
|
||||
const PPB_PDF* pdf_iface = thunk::GetPPB_PDF_Thunk();
|
||||
|
||||
pdf_iface->SetPluginCanSave(pp_instance(), true);
|
||||
|
||||
ResourceMessageCallParams params;
|
||||
IPC::Message msg;
|
||||
ASSERT_TRUE(sink().GetFirstResourceCallMatching(
|
||||
PpapiHostMsg_PDF_SetPluginCanSave::ID, ¶ms, &msg));
|
||||
}
|
||||
|
||||
} // namespace proxy
|
||||
} // namespace ppapi
|
||||
|
@ -2376,6 +2376,11 @@ IPC_MESSAGE_CONTROL4(PpapiHostMsg_PDF_SelectionChanged,
|
||||
PP_FloatPoint /* right */,
|
||||
int32_t /* right_height */)
|
||||
|
||||
// Lets the renderer know that the PDF plugin can handle save commands
|
||||
// internally. i.e. It will provide the data to save and trigger the download
|
||||
// dialog.
|
||||
IPC_MESSAGE_CONTROL1(PpapiHostMsg_PDF_SetPluginCanSave, bool /* can_save */)
|
||||
|
||||
// VideoCapture ----------------------------------------------------------------
|
||||
|
||||
// VideoCapture_Dev, plugin -> host
|
||||
|
@ -49,6 +49,7 @@ class PPB_PDF_API {
|
||||
int32_t left_height,
|
||||
const PP_FloatPoint& right,
|
||||
int32_t right_height) = 0;
|
||||
virtual void SetPluginCanSave(bool can_save) = 0;
|
||||
|
||||
static const SingletonResourceID kSingletonResourceID = PDF_SINGLETON_ID;
|
||||
};
|
||||
|
@ -202,6 +202,13 @@ void SelectionChanged(PP_Instance instance,
|
||||
enter.functions()->SelectionChanged(*left, left_height, *right, right_height);
|
||||
}
|
||||
|
||||
void SetPluginCanSave(PP_Instance instance, bool can_save) {
|
||||
EnterInstanceAPI<PPB_PDF_API> enter(instance);
|
||||
if (enter.failed())
|
||||
return;
|
||||
enter.functions()->SetPluginCanSave(can_save);
|
||||
}
|
||||
|
||||
const PPB_PDF g_ppb_pdf_thunk = {
|
||||
&GetFontFileWithFallback,
|
||||
&GetFontTableForPrivateFontFile,
|
||||
@ -222,6 +229,7 @@ const PPB_PDF g_ppb_pdf_thunk = {
|
||||
&SetAccessibilityPageInfo,
|
||||
&SetCrashData,
|
||||
&SelectionChanged,
|
||||
&SetPluginCanSave,
|
||||
&ShowAlertDialog,
|
||||
&ShowConfirmDialog,
|
||||
&ShowPromptDialog,
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2018 The Chromium Authors. All rights reserved.
|
||||
// Copyright 2019 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
@ -47,3 +47,9 @@ chrome.mimeHandlerPrivate.abortStream = function(callback) {};
|
||||
* @param {function():void=} callback
|
||||
*/
|
||||
chrome.mimeHandlerPrivate.setShowBeforeUnloadDialog = function(showDialog, callback) {};
|
||||
|
||||
/**
|
||||
* Fired when the browser wants the listener to perform a save.
|
||||
* @type {!ChromeEvent}
|
||||
*/
|
||||
chrome.mimeHandlerPrivate.onSave;
|
||||
|
@ -16541,6 +16541,7 @@ Called by update_net_error_codes.py.-->
|
||||
<int value="433" label="AUTOFILL_PRIVATE_ON_LOCAL_CREDIT_CARD_LIST_CHANGED"/>
|
||||
<int value="434" label="AUTOFILL_PRIVATE_ON_SERVER_CREDIT_CARD_LIST_CHANGED"/>
|
||||
<int value="435" label="ACCESSIBILITY_PRIVATE_ON_ANNOUNCE_FOR_ACCESSIBILITY"/>
|
||||
<int value="436" label="MIME_HANDLER_PRIVATE_SAVE"/>
|
||||
</enum>
|
||||
|
||||
<enum name="ExtensionFileWriteResult">
|
||||
|
Reference in New Issue
Block a user