WebKit Bugzilla
Attachment 339909 Details for
Bug 185459
: Download and present System Preview
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-185459-20180508182843.patch (text/plain), 20.49 KB, created by
Dean Jackson
on 2018-05-08 18:28:43 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Dean Jackson
Created:
2018-05-08 18:28:43 PDT
Size:
20.49 KB
patch
obsolete
>Subversion Revision: 231399 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 4e195ce4672edf3a28e042d9714604c7155d6e92..1cc7acc1b32d8a46fa9581eedb0d0c0d3c66a27b 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,65 @@ >+2018-05-08 Dean Jackson <dino@apple.com> >+ >+ Download and present System Preview >+ https://bugs.webkit.org/show_bug.cgi?id=185459 >+ <rdar://problem/40079228> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Extend DownloadClient so that it can handle the case where >+ the download was triggered by a System Preview. In this situation >+ the result (and progress) are piped into QuickLook via the SystemPreviewController. >+ >+ The DownloadProxy class is also extended to handle the destination >+ filename and the size of the content. >+ >+ Lastly, SystemPreviewController is updated to have a start(), show() >+ and hide() interface, and no longer adjusts page navigation. >+ >+ * UIProcess/Cocoa/DownloadClient.mm: Handle the SystemPreview case, which >+ doesn't have a download delegate, but instead needs to communicate with >+ the SystemPreviewController, if one exists. >+ (WebKit::DownloadClient::didStart): >+ (WebKit::DownloadClient::didReceiveResponse): >+ (WebKit::DownloadClient::didReceiveData): >+ (WebKit::DownloadClient::didCreateDestination): >+ (WebKit::DownloadClient::decideDestinationWithSuggestedFilename): >+ (WebKit::DownloadClient::didFinish): >+ >+ * UIProcess/Cocoa/SystemPreviewControllerCocoa.mm: Implement the new API. >+ (-[_WKPreviewControllerDataSource init]): >+ (-[_WKPreviewControllerDataSource previewController:previewItemAtIndex:]): >+ (-[_WKPreviewControllerDataSource setProgress:]): >+ (-[_WKPreviewControllerDataSource finish:]): >+ (-[_WKPreviewControllerDelegate previewControllerDidDismiss:]): >+ (WebKit::SystemPreviewController::start): >+ (WebKit::SystemPreviewController::updateProgress): >+ (WebKit::SystemPreviewController::finish): >+ (WebKit::SystemPreviewController::hide): >+ (-[_WKPreviewControllerDataSource initWithURL:]): Deleted. >+ (-[_WKPreviewControllerDelegate previewControllerWillDismiss:]): Deleted. >+ (WebKit::SystemPreviewController::showPreview): Deleted. >+ >+ * UIProcess/Downloads/DownloadProxy.h: Track the destination filename >+ and the size of the content. >+ (WebKit::DownloadProxy::destinationFilename const): >+ (WebKit::DownloadProxy::setDestinationFilename): >+ (WebKit::DownloadProxy::expectedContentLength const): >+ (WebKit::DownloadProxy::setExpectedContentLength): >+ (WebKit::DownloadProxy::bytesLoaded const): >+ (WebKit::DownloadProxy::setBytesLoaded): >+ >+ * UIProcess/SystemPreviewController.cpp: Update for new API. >+ (WebKit::SystemPreviewController::sendPageBack): Deleted. >+ (WebKit::SystemPreviewController::canPreview const): Deleted. >+ (WebKit::SystemPreviewController::showPreview): Deleted. >+ * UIProcess/SystemPreviewController.h: >+ * UIProcess/WebPageProxy.cpp: >+ (WebKit::m_configurationPreferenceValues): >+ (WebKit::WebPageProxy::reattachToWebProcess): >+ (WebKit::WebPageProxy::resetState): >+ * UIProcess/WebPageProxy.h: >+ > 2018-05-08 Dean Jackson <dino@apple.com> > > System Preview links should trigger a download >diff --git a/Source/WebKit/UIProcess/Cocoa/DownloadClient.mm b/Source/WebKit/UIProcess/Cocoa/DownloadClient.mm >index b65358e721f3f6ccbd658f2b4197d32bc753fa1e..adf80a512509c7521020b0a04aa044f2f0a7cff8 100644 >--- a/Source/WebKit/UIProcess/Cocoa/DownloadClient.mm >+++ b/Source/WebKit/UIProcess/Cocoa/DownloadClient.mm >@@ -32,11 +32,14 @@ > #import "AuthenticationDecisionListener.h" > #import "CompletionHandlerCallChecker.h" > #import "DownloadProxy.h" >+#import "SystemPreviewController.h" > #import "WKNSURLAuthenticationChallenge.h" > #import "WKNSURLExtras.h" > #import "WebCredential.h" >+#import "WebPageProxy.h" > #import "_WKDownloadDelegate.h" > #import "_WKDownloadInternal.h" >+#import <WebCore/FileSystem.h> > #import <WebCore/ResourceError.h> > #import <WebCore/ResourceResponse.h> > #import <wtf/BlockPtr.h> >@@ -69,20 +72,47 @@ DownloadClient::DownloadClient(id <_WKDownloadDelegate> delegate) > > void DownloadClient::didStart(WebProcessPool&, DownloadProxy& downloadProxy) > { >- if (m_delegateMethods.downloadDidStart) >- [m_delegate _downloadDidStart:wrapper(downloadProxy)]; >+ if (downloadProxy.request().isSystemPreview()) { >+#if USE(SYSTEM_PREVIEW) >+ WebPageProxy* webPage = downloadProxy.originatingPage(); >+ if (webPage) >+ webPage->systemPreviewController()->start(); >+#endif >+ } else { >+ if (m_delegateMethods.downloadDidStart) >+ [m_delegate _downloadDidStart:wrapper(downloadProxy)]; >+ } > } > > void DownloadClient::didReceiveResponse(WebProcessPool&, DownloadProxy& downloadProxy, const WebCore::ResourceResponse& response) > { >- if (m_delegateMethods.downloadDidReceiveResponse) >- [m_delegate _download:wrapper(downloadProxy) didReceiveResponse:response.nsURLResponse()]; >+ if (downloadProxy.request().isSystemPreview()) { >+#if USE(SYSTEM_PREVIEW) >+ downloadProxy.setExpectedContentLength(response.expectedContentLength()); >+ downloadProxy.setBytesLoaded(0); >+ WebPageProxy* webPage = downloadProxy.originatingPage(); >+ if (webPage) >+ webPage->systemPreviewController()->updateProgress(0); >+#endif >+ } else { >+ if (m_delegateMethods.downloadDidReceiveResponse) >+ [m_delegate _download:wrapper(downloadProxy) didReceiveResponse:response.nsURLResponse()]; >+ } > } > > void DownloadClient::didReceiveData(WebProcessPool&, DownloadProxy& downloadProxy, uint64_t length) > { >- if (m_delegateMethods.downloadDidReceiveData) >- [m_delegate _download:wrapper(downloadProxy) didReceiveData:length]; >+ if (downloadProxy.request().isSystemPreview()) { >+#if USE(SYSTEM_PREVIEW) >+ downloadProxy.setBytesLoaded(downloadProxy.bytesLoaded() + length); >+ WebPageProxy* webPage = downloadProxy.originatingPage(); >+ if (webPage) >+ webPage->systemPreviewController()->updateProgress(static_cast<float>(downloadProxy.bytesLoaded()) / downloadProxy.expectedContentLength()); >+#endif >+ } else { >+ if (m_delegateMethods.downloadDidReceiveData) >+ [m_delegate _download:wrapper(downloadProxy) didReceiveData:length]; >+ } > } > > void DownloadClient::didReceiveAuthenticationChallenge(WebProcessPool&, DownloadProxy& downloadProxy, AuthenticationChallengeProxy& authenticationChallenge) >@@ -126,8 +156,12 @@ void DownloadClient::didReceiveAuthenticationChallenge(WebProcessPool&, Download > > void DownloadClient::didCreateDestination(WebProcessPool&, DownloadProxy& downloadProxy, const String& destination) > { >- if (m_delegateMethods.downloadDidCreateDestination) >- [m_delegate _download:wrapper(downloadProxy) didCreateDestination:destination]; >+ if (downloadProxy.request().isSystemPreview()) >+ downloadProxy.setDestinationFilename(destination); >+ else { >+ if (m_delegateMethods.downloadDidCreateDestination) >+ [m_delegate _download:wrapper(downloadProxy) didCreateDestination:destination]; >+ } > } > > void DownloadClient::processDidCrash(WebProcessPool&, DownloadProxy& downloadProxy) >@@ -149,19 +183,35 @@ void DownloadClient::decideDestinationWithSuggestedFilename(WebProcessPool&, Dow > #pragma clang diagnostic pop > completionHandler(allowOverwrite ? AllowOverwrite::Yes : AllowOverwrite::No, destination); > } else { >- [m_delegate _download:wrapper(downloadProxy) decideDestinationWithSuggestedFilename:filename completionHandler:BlockPtr<void(BOOL, NSString *)>::fromCallable([checker = CompletionHandlerCallChecker::create(m_delegate.get().get(), @selector(_download:decideDestinationWithSuggestedFilename:completionHandler:)), completionHandler = WTFMove(completionHandler)] (BOOL allowOverwrite, NSString *destination) { >- if (checker->completionHandlerHasBeenCalled()) >- return; >- checker->didCallCompletionHandler(); >- completionHandler(allowOverwrite ? AllowOverwrite::Yes : AllowOverwrite::No, destination); >- }).get()]; >+ if (downloadProxy.request().isSystemPreview()) { >+ NSString *temporaryDirectory = WebCore::FileSystem::createTemporaryDirectory(@"SystemPreviews"); >+ NSString *destination = [temporaryDirectory stringByAppendingPathComponent:filename]; >+ completionHandler(AllowOverwrite::Yes, destination); >+ } else { >+ [m_delegate _download:wrapper(downloadProxy) decideDestinationWithSuggestedFilename:filename completionHandler:BlockPtr<void(BOOL, NSString *)>::fromCallable([checker = CompletionHandlerCallChecker::create(m_delegate.get().get(), @selector(_download:decideDestinationWithSuggestedFilename:completionHandler:)), completionHandler = WTFMove(completionHandler)] (BOOL allowOverwrite, NSString *destination) { >+ if (checker->completionHandlerHasBeenCalled()) >+ return; >+ checker->didCallCompletionHandler(); >+ completionHandler(allowOverwrite ? AllowOverwrite::Yes : AllowOverwrite::No, destination); >+ }).get()]; >+ } > } > } > > void DownloadClient::didFinish(WebProcessPool&, DownloadProxy& downloadProxy) > { >- if (m_delegateMethods.downloadDidFinish) >- [m_delegate _downloadDidFinish:wrapper(downloadProxy)]; >+ if (downloadProxy.request().isSystemPreview()) { >+#if USE(SYSTEM_PREVIEW) >+ WebPageProxy* webPage = downloadProxy.originatingPage(); >+ if (webPage) { >+ NSURL *destinationURL = [NSURL fileURLWithPath:(NSString *)downloadProxy.destinationFilename()]; >+ webPage->systemPreviewController()->finish(WebCore::URL(destinationURL)); >+ } >+#endif >+ } else { >+ if (m_delegateMethods.downloadDidFinish) >+ [m_delegate _downloadDidFinish:wrapper(downloadProxy)]; >+ } > } > > void DownloadClient::didFail(WebProcessPool&, DownloadProxy& downloadProxy, const WebCore::ResourceError& error) >diff --git a/Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm b/Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm >index d23a22e0cba31d3e5e29188ee1537442b5870e86..51cd0678f68f7fda591a7eb799dd1f98f102457f 100644 >--- a/Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm >+++ b/Source/WebKit/UIProcess/Cocoa/SystemPreviewControllerCocoa.mm >@@ -31,8 +31,10 @@ > #import "APIUIClient.h" > #import "WebPageProxy.h" > >+#import <MobileCoreServices/MobileCoreServices.h> > #import <QuickLook/QuickLook.h> > #import <UIKit/UIViewController.h> >+#import <pal/spi/ios/QuickLookSPI.h> > #import <wtf/SoftLinking.h> > > #if USE(APPLE_INTERNAL_SDK) >@@ -41,22 +43,24 @@ > > SOFT_LINK_FRAMEWORK(QuickLook) > SOFT_LINK_CLASS(QuickLook, QLPreviewController); >+SOFT_LINK_CLASS(QuickLook, QLItem); > > @interface _WKPreviewControllerDataSource : NSObject <QLPreviewControllerDataSource> { >+ RetainPtr<NSItemProvider> _itemProvider; >+ RetainPtr<QLItem> _item; > }; > >-@property (nonatomic) WebCore::URL url; >+@property (strong) NSItemProviderCompletionHandler completionHandler; > > @end > > @implementation _WKPreviewControllerDataSource > >-- (id)initWithURL:(const WebCore::URL&)url >+- (id)init > { > if (!(self = [super init])) > return nil; > >- self.url = url; > return self; > } > >@@ -67,7 +71,30 @@ SOFT_LINK_CLASS(QuickLook, QLPreviewController); > > - (id<QLPreviewItem>)previewController:(QLPreviewController *)controller previewItemAtIndex:(NSInteger)index > { >- return (NSURL*)self.url; >+ if (!_item) { >+ _itemProvider = adoptNS([[NSItemProvider alloc] init]); >+ NSString *contentType = @"com.pixar.universal-scene-description-mobile"; >+ _item = adoptNS([allocQLItemInstance() initWithPreviewItemProvider:_itemProvider.get() contentType:contentType previewTitle:@"Preview" fileSize:@(0)]); >+ [_item setUseLoadingTimeout:NO]; >+ >+ [_itemProvider registerItemForTypeIdentifier:contentType loadHandler:^(NSItemProviderCompletionHandler _Null_unspecified completionHandler, Class _Null_unspecified __unsafe_unretained expectedValueClass, NSDictionary * _Null_unspecified options) { >+ // This will get called once the download completes. >+ self.completionHandler = completionHandler; >+ }]; >+ } >+ return _item.get(); >+} >+ >+- (void)setProgress:(float)progress >+{ >+ if (_item) >+ [_item setPreviewItemProviderProgress:@(progress)]; >+} >+ >+- (void)finish:(WebCore::URL)url >+{ >+ if (self.completionHandler) >+ self.completionHandler((NSURL*)url, nil); > } > > @end >@@ -88,10 +115,10 @@ SOFT_LINK_CLASS(QuickLook, QLPreviewController); > return self; > } > >-- (void)previewControllerWillDismiss:(QLPreviewController *)controller >+- (void)previewControllerDidDismiss:(QLPreviewController *)controller > { > if (_previewController) >- _previewController->sendPageBack(); >+ _previewController->hide(); > } > @end > >@@ -107,7 +134,7 @@ bool SystemPreviewController::canPreview(const String& mimeType) const > #endif > } > >-void SystemPreviewController::showPreview(const WebCore::URL& url) >+void SystemPreviewController::start() > { > // FIXME: Make sure you can't show a preview if we're already previewing. > >@@ -122,14 +149,30 @@ void SystemPreviewController::showPreview(const WebCore::URL& url) > m_qlPreviewControllerDelegate = adoptNS([[_WKPreviewControllerDelegate alloc] initWithSystemPreviewController:this]); > [m_qlPreviewController setDelegate:m_qlPreviewControllerDelegate.get()]; > >- m_qlPreviewControllerDataSource = adoptNS([[_WKPreviewControllerDataSource alloc] initWithURL:url]); >+ m_qlPreviewControllerDataSource = adoptNS([[_WKPreviewControllerDataSource alloc] init]); > [m_qlPreviewController setDataSource:m_qlPreviewControllerDataSource.get()]; >- } else >- m_qlPreviewControllerDataSource.get().url = url; > >- [m_qlPreviewController reloadData]; >+ [presentingViewController presentViewController:m_qlPreviewController.get() animated:YES completion:nullptr]; >+ } >+} >+ >+void SystemPreviewController::updateProgress(float progress) >+{ >+ if (m_qlPreviewControllerDataSource) >+ [m_qlPreviewControllerDataSource setProgress:progress]; >+} > >- [presentingViewController presentViewController:m_qlPreviewController.get() animated:YES completion:nullptr]; >+void SystemPreviewController::finish(WebCore::URL url) >+{ >+ if (m_qlPreviewControllerDataSource) >+ [m_qlPreviewControllerDataSource finish:url]; >+} >+ >+void SystemPreviewController::hide() >+{ >+ m_qlPreviewControllerDelegate = nullptr; >+ m_qlPreviewControllerDataSource = nullptr; >+ m_qlPreviewController = nullptr; > } > > } >diff --git a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h >index f258633c60fa67329307162965920d57cc838ed6..0de3644e287a874305ba8b51c96a5078baa4dcfa 100644 >--- a/Source/WebKit/UIProcess/Downloads/DownloadProxy.h >+++ b/Source/WebKit/UIProcess/Downloads/DownloadProxy.h >@@ -80,6 +80,15 @@ public: > void setWasUserInitiated(bool value) { m_wasUserInitiated = value; } > bool wasUserInitiated() const { return m_wasUserInitiated; } > >+ String destinationFilename() const { return m_destinationFilename; } >+ void setDestinationFilename(const String& d) { m_destinationFilename = d; } >+ >+ uint64_t expectedContentLength() const { return m_expectedContentLength; } >+ void setExpectedContentLength(uint64_t expectedContentLength) { m_expectedContentLength = expectedContentLength; } >+ >+ uint64_t bytesLoaded() const { return m_bytesLoaded; } >+ void setBytesLoaded(uint64_t bytesLoaded) { m_bytesLoaded = bytesLoaded; } >+ > private: > explicit DownloadProxy(DownloadProxyMap&, WebProcessPool&, const WebCore::ResourceRequest&); > >@@ -106,6 +115,9 @@ private: > RefPtr<API::Data> m_resumeData; > WebCore::ResourceRequest m_request; > String m_suggestedFilename; >+ String m_destinationFilename; >+ uint64_t m_expectedContentLength { 0 }; >+ uint64_t m_bytesLoaded { 0 }; > > WeakPtr<WebPageProxy> m_originatingPage; > Vector<WebCore::URL> m_redirectChain; >diff --git a/Source/WebKit/UIProcess/SystemPreviewController.cpp b/Source/WebKit/UIProcess/SystemPreviewController.cpp >index d45b819cd4b073902251690dc5f26d17767af69a..2d75d2a938e126eef856ca72c682461586f0fdb1 100644 >--- a/Source/WebKit/UIProcess/SystemPreviewController.cpp >+++ b/Source/WebKit/UIProcess/SystemPreviewController.cpp >@@ -26,6 +26,8 @@ > #include "config.h" > #include "SystemPreviewController.h" > >+#if USE(SYSTEM_PREVIEW) >+ > #include "WebPageProxy.h" > > namespace WebKit { >@@ -35,20 +37,6 @@ SystemPreviewController::SystemPreviewController(WebPageProxy& webPageProxy) > { > } > >-void SystemPreviewController::sendPageBack() >-{ >- m_webPageProxy.goBack(); >-} >- >-#if !PLATFORM(IOS) || !USE(QUICK_LOOK) >-bool SystemPreviewController::canPreview(const String&) const >-{ >- return false; > } > >-void SystemPreviewController::showPreview(const WebCore::URL&) >-{ >-} > #endif >- >-} >diff --git a/Source/WebKit/UIProcess/SystemPreviewController.h b/Source/WebKit/UIProcess/SystemPreviewController.h >index 8141810702e6f0d0ce7e4750b01d11c54ac27274..b0b8e801c281c4900ae195106a140a44c119e292 100644 >--- a/Source/WebKit/UIProcess/SystemPreviewController.h >+++ b/Source/WebKit/UIProcess/SystemPreviewController.h >@@ -25,14 +25,14 @@ > > #pragma once > >+#if USE(SYSTEM_PREVIEW) >+ > #include <WebCore/URL.h> > #include <wtf/RetainPtr.h> > >-#if PLATFORM(IOS) && USE(QUICK_LOOK) > OBJC_CLASS QLPreviewController; > OBJC_CLASS _WKPreviewControllerDataSource; > OBJC_CLASS _WKPreviewControllerDelegate; >-#endif > > namespace WebKit { > >@@ -43,19 +43,19 @@ public: > explicit SystemPreviewController(WebPageProxy&); > > bool canPreview(const String& mimeType) const; >- void showPreview(const WebCore::URL&); > >- void sendPageBack(); >+ void start(); >+ void updateProgress(float); >+ void finish(WebCore::URL); >+ void hide(); > > private: > WebPageProxy& m_webPageProxy; >- >-#if PLATFORM(IOS) && USE(QUICK_LOOK) > RetainPtr<QLPreviewController> m_qlPreviewController; > RetainPtr<_WKPreviewControllerDelegate> m_qlPreviewControllerDelegate; > RetainPtr<_WKPreviewControllerDataSource> m_qlPreviewControllerDataSource; >-#endif > }; > > } > >+#endif >diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp >index f49a4f824557fbee9fc5239d100fce39878b298c..6340b2b6bad671243b8511b931681273c2691d4a 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.cpp >+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp >@@ -434,7 +434,9 @@ WebPageProxy::WebPageProxy(PageClient& pageClient, WebProcessProxy& process, uin > m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this); > #endif > >+#if USE(SYSTEM_PREVIEW) > m_systemPreviewController = std::make_unique<SystemPreviewController>(*this); >+#endif > > #if ENABLE(WEB_AUTHN) > m_credentialsMessenger = std::make_unique<WebCredentialsMessengerProxy>(*this); >@@ -746,7 +748,9 @@ void WebPageProxy::reattachToWebProcess(Ref<WebProcessProxy>&& process, API::Nav > m_paymentCoordinator = std::make_unique<WebPaymentCoordinatorProxy>(*this); > #endif > >+#if USE(SYSTEM_PREVIEW) > m_systemPreviewController = std::make_unique<SystemPreviewController>(*this); >+#endif > > #if ENABLE(WEB_AUTHN) > m_credentialsMessenger = std::make_unique<WebCredentialsMessengerProxy>(*this); >@@ -5914,7 +5918,9 @@ void WebPageProxy::resetState(ResetStateReason resetStateReason) > m_paymentCoordinator = nullptr; > #endif > >+#if USE(SYSTEM_PREVIEW) > m_systemPreviewController = nullptr; >+#endif > > #if ENABLE(WEB_AUTHN) > m_credentialsMessenger = nullptr; >diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h >index 9d1355d0cd7c9daebbb837176d747f3df57ebaed..4bce953d479fba69a71940f9ce792393b00548c6 100644 >--- a/Source/WebKit/UIProcess/WebPageProxy.h >+++ b/Source/WebKit/UIProcess/WebPageProxy.h >@@ -388,7 +388,9 @@ public: > void setAllowsMediaDocumentInlinePlayback(bool); > #endif > >+#if USE(SYSTEM_PREVIEW) > SystemPreviewController* systemPreviewController() { return m_systemPreviewController.get(); } >+#endif > > #if ENABLE(CONTEXT_MENUS) > API::ContextMenuClient& contextMenuClient() { return *m_contextMenuClient; } >@@ -1846,7 +1848,9 @@ private: > std::unique_ptr<WebPaymentCoordinatorProxy> m_paymentCoordinator; > #endif > >+#if USE(SYSTEM_PREVIEW) > std::unique_ptr<SystemPreviewController> m_systemPreviewController; >+#endif > > #if ENABLE(WEB_AUTHN) > std::unique_ptr<WebCredentialsMessengerProxy> m_credentialsMessenger;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 185459
:
339909
|
340378
|
340400