Commit 35f4decd authored by John Z Wu's avatar John Z Wu Committed by Commit Bot

Add method to CWVUIDelegate to notify of favicon changes.

Clients of //ios/web_view may display a favicon as a UIImageView.

Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: I85da27ac6fbcd4b8a0244d468daf17cb8c619499
Reviewed-on: https://chromium-review.googlesource.com/1089644Reviewed-by: default avatarNico Weber <thakis@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Commit-Queue: John Wu <jzw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565381}
parent 7b5e3742
......@@ -45,6 +45,7 @@ config("config") {
# These are defined as vars so they can be shared with different targets below.
ios_web_view_public_headers = [
"public/cwv_export.h",
"public/cwv_favicon.h",
"public/cwv_html_element.h",
"public/cwv_navigation_action.h",
"public/cwv_navigation_delegate.h",
......@@ -96,6 +97,8 @@ ios_web_view_sources = [
"internal/content_settings/web_view_cookie_settings_factory.h",
"internal/content_settings/web_view_host_content_settings_map_factory.cc",
"internal/content_settings/web_view_host_content_settings_map_factory.h",
"internal/cwv_favicon.mm",
"internal/cwv_favicon_internal.h",
"internal/cwv_html_element.mm",
"internal/cwv_html_element_internal.h",
"internal/cwv_navigation_action.mm",
......@@ -315,6 +318,7 @@ test("ios_web_view_unittests") {
"internal/autofill/cwv_autofill_suggestion_unittest.mm",
"internal/autofill/cwv_credit_card_unittest.mm",
"internal/autofill/cwv_credit_card_verifier_unittest.mm",
"internal/cwv_favicon_unittest.mm",
"internal/cwv_html_element_unittest.mm",
"internal/cwv_preferences_unittest.mm",
"internal/cwv_preview_element_info_unittest.mm",
......
......@@ -31,4 +31,5 @@ include_rules = [
"+services/network/public/cpp",
"+third_party/ocmock",
"+ui/base",
"+ui/gfx",
]
// Copyright 2018 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.
#import "ios/web_view/internal/cwv_favicon_internal.h"
#import <UIKit/UIKit.h>
#import "net/base/mac/url_conversions.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace ios_web_view {
// Converts web::FaviconURL::IconType to CWVFaviconType.
CWVFaviconType ConvertIconTypeFromWebToCWV(web::FaviconURL::IconType iconType) {
switch (iconType) {
case web::FaviconURL::IconType::kInvalid:
return CWVFaviconTypeInvalid;
case web::FaviconURL::IconType::kFavicon:
return CWVFaviconTypeFavicon;
case web::FaviconURL::IconType::kTouchIcon:
return CWVFaviconTypeTouchIcon;
case web::FaviconURL::IconType::kTouchPrecomposedIcon:
return CWVFaviconTypeTouchPrecomposedIcon;
case web::FaviconURL::IconType::kWebManifestIcon:
return CWVFaviconTypeWebManifestIcon;
}
}
} // namespace ios_web_view
@implementation CWVFavicon
@synthesize URL = _URL;
@synthesize type = _type;
@synthesize sizes = _sizes;
+ (NSArray<CWVFavicon*>*)faviconsFromFaviconURLs:
(const std::vector<web::FaviconURL>&)faviconURLs {
NSMutableArray<CWVFavicon*>* favicons = [NSMutableArray array];
for (const auto& faviconURL : faviconURLs) {
CWVFavicon* favicon = [[CWVFavicon alloc] initWithFaviconURL:faviconURL];
[favicons addObject:favicon];
}
return [favicons copy];
}
- (instancetype)initWithFaviconURL:(web::FaviconURL)faviconURL {
self = [super init];
if (self) {
_URL = net::NSURLWithGURL(faviconURL.icon_url);
_type = ios_web_view::ConvertIconTypeFromWebToCWV(faviconURL.icon_type);
NSMutableArray<NSValue*>* sizes = [NSMutableArray array];
for (const auto& size : faviconURL.icon_sizes) {
NSValue* value =
[NSValue valueWithCGSize:CGSizeMake(size.width(), size.height())];
[sizes addObject:value];
}
_sizes = [sizes copy];
}
return self;
}
@end
// Copyright 2018 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.
#ifndef IOS_WEB_VIEW_INTERNAL_CWV_FAVICON_INTERNAL_H_
#define IOS_WEB_VIEW_INTERNAL_CWV_FAVICON_INTERNAL_H_
#include <vector>
#include "ios/web/public/favicon_url.h"
#import "ios/web_view/public/cwv_favicon.h"
NS_ASSUME_NONNULL_BEGIN
@interface CWVFavicon ()
// Use to convert a vector of web::FaviconURL into a NSArray of CWVFavicon.
+ (NSArray<CWVFavicon*>*)faviconsFromFaviconURLs:
(const std::vector<web::FaviconURL>&)faviconURLs;
- (instancetype)initWithFaviconURL:(web::FaviconURL)faviconURL
NS_DESIGNATED_INITIALIZER;
@end
NS_ASSUME_NONNULL_END
#endif // IOS_WEB_VIEW_INTERNAL_CWV_FAVICON_INTERNAL_H_
// Copyright 2018 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.
#import "ios/web_view/internal/cwv_favicon_internal.h"
#import <UIKit/UIKit.h>
#include <vector>
#include "ios/web/public/favicon_url.h"
#import "net/base/mac/url_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#import "testing/gtest_mac.h"
#include "testing/platform_test.h"
#include "ui/gfx/geometry/size.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace ios_web_view {
using CWVFaviconTest = PlatformTest;
// Tests CWVFavicon factory initialization.
TEST_F(CWVFaviconTest, FactoryInitialization) {
NSURL* url = [NSURL URLWithString:@"https://chromium.org/static/fav.ico"];
CWVFaviconType type = CWVFaviconTypeFavicon;
web::FaviconURL::IconType web_type = web::FaviconURL::IconType::kFavicon;
NSArray<NSValue*>* sizes = @[
[NSValue valueWithCGSize:CGSizeMake(16, 16)],
[NSValue valueWithCGSize:CGSizeMake(32, 32)]
];
std::vector<gfx::Size> gfx_sizes = {gfx::Size(16, 16), gfx::Size(32, 32)};
web::FaviconURL favicon_url(net::GURLWithNSURL(url), web_type, gfx_sizes);
NSURL* url2 = [NSURL URLWithString:@"https://chromium.org/static/fav.png"];
CWVFaviconType type2 = CWVFaviconTypeTouchIcon;
web::FaviconURL::IconType web_type2 = web::FaviconURL::IconType::kTouchIcon;
NSArray<NSValue*>* sizes2 = @[ [NSValue valueWithCGSize:CGSizeMake(48, 48)] ];
std::vector<gfx::Size> gfx_sizes2 = {gfx::Size(48, 48)};
web::FaviconURL favicon_url2(net::GURLWithNSURL(url2), web_type2, gfx_sizes2);
std::vector<web::FaviconURL> favicon_urls = {favicon_url, favicon_url2};
NSArray<CWVFavicon*>* favicons =
[CWVFavicon faviconsFromFaviconURLs:favicon_urls];
CWVFavicon* favicon = favicons.firstObject;
EXPECT_NSEQ(url, favicon.URL);
EXPECT_EQ(type, favicon.type);
EXPECT_NSEQ(sizes, favicon.sizes);
CWVFavicon* favicon2 = favicons.lastObject;
EXPECT_NSEQ(url2, favicon2.URL);
EXPECT_EQ(type2, favicon2.type);
EXPECT_NSEQ(sizes2, favicon2.sizes);
}
} // namespace ios_web_view
......@@ -15,6 +15,7 @@
#import "components/autofill/ios/browser/js_autofill_manager.h"
#import "components/autofill/ios/browser/js_suggestion_manager.h"
#include "google_apis/google_api_keys.h"
#include "ios/web/public/favicon_url.h"
#include "ios/web/public/load_committed_details.h"
#import "ios/web/public/navigation_manager.h"
#include "ios/web/public/referrer.h"
......@@ -30,6 +31,7 @@
#import "ios/web/public/web_state/web_state_observer_bridge.h"
#include "ios/web_view/cwv_web_view_features.h"
#import "ios/web_view/internal/autofill/cwv_autofill_controller_internal.h"
#import "ios/web_view/internal/cwv_favicon_internal.h"
#import "ios/web_view/internal/cwv_html_element_internal.h"
#import "ios/web_view/internal/cwv_navigation_action_internal.h"
#import "ios/web_view/internal/cwv_script_command_internal.h"
......@@ -417,6 +419,15 @@ static NSString* gUserAgentProduct = nil;
}
}
- (void)webState:(web::WebState*)webState
didUpdateFaviconURLCandidates:
(const std::vector<web::FaviconURL>&)candidates {
if ([_UIDelegate respondsToSelector:@selector(webView:didLoadFavicons:)]) {
[_UIDelegate webView:self
didLoadFavicons:[CWVFavicon faviconsFromFaviconURLs:candidates]];
}
}
- (void)addScriptCommandHandler:(id<CWVScriptCommandHandler>)handler
commandPrefix:(NSString*)commandPrefix {
CWVWebView* __weak weakSelf = self;
......
// Copyright 2018 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.
#ifndef IOS_WEB_VIEW_PUBLIC_CWV_FAVICON_H_
#define IOS_WEB_VIEW_PUBLIC_CWV_FAVICON_H_
#import <Foundation/Foundation.h>
#import "cwv_export.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, CWVFaviconType) {
// Invalid icon type.
CWVFaviconTypeInvalid = 0,
// <link rel="icon" ...>.
CWVFaviconTypeFavicon,
// <link rel="apple-touch-icon" ...>.
CWVFaviconTypeTouchIcon,
// <link rel="apple-touch-icon-precomposed" ...>.
CWVFaviconTypeTouchPrecomposedIcon,
// Icon listed in a web manifest.
CWVFaviconTypeWebManifestIcon,
};
// Encapsulates information about a fav icon.
CWV_EXPORT
@interface CWVFavicon : NSObject
// URL of the icon.
@property(nonatomic, copy, readonly) NSURL* URL;
// Type of icon.
@property(nonatomic, readonly) CWVFaviconType type;
// Boxed values of CGSizes.
// There may be multiple sizes if the |type| is CWVFaviconTypeFavicon.
@property(nonatomic, readonly) NSArray<NSValue*>* sizes;
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END
#endif // IOS_WEB_VIEW_PUBLIC_CWV_FAVICON_H_
......@@ -12,6 +12,7 @@
NS_ASSUME_NONNULL_BEGIN
@class CWVFavicon;
@class CWVHTMLElement;
@class CWVPreviewElementInfo;
@class CWVWebView;
......@@ -84,6 +85,10 @@ CWV_EXPORT
- (void)webView:(CWVWebView*)webView
commitPreviewingViewController:(UIViewController*)previewingViewController;
// Called when favicons become available in the current page.
- (void)webView:(CWVWebView*)webView
didLoadFavicons:(NSArray<CWVFavicon*>*)favIcons;
@end
NS_ASSUME_NONNULL_END
......
......@@ -444,6 +444,11 @@ NSString* const kWebViewShellJavaScriptDialogTextFieldAccessibiltyIdentifier =
[self presentViewController:alert animated:YES completion:nil];
}
- (void)webView:(CWVWebView*)webView
didLoadFavicons:(NSArray<CWVFavicon*>*)favIcons {
NSLog(@"%@", NSStringFromSelector(_cmd));
}
#pragma mark CWVNavigationDelegate methods
- (BOOL)webView:(CWVWebView*)webView
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment