Commit ed0a36c4 authored by stkhapugin@chromium.org's avatar stkhapugin@chromium.org Committed by Commit Bot

Create OmniboxPopupMediator.

Creates OmniboxPopupMediator and AutocompleteResultsWrapper, moves
logic to these classes form OmniboxPopupMaterialVC.

Bug: 
Change-Id: I753b37f4831d43956a146ac025cf6d166bf46500
Reviewed-on: https://chromium-review.googlesource.com/608242Reviewed-by: default avatarRohit Rao (ping after 24h) <rohitrao@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Commit-Queue: Stepan Khapugin <stkhapugin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#501276}
parent 06292acc
......@@ -18,14 +18,21 @@ source_set("omnibox") {
source_set("omnibox_internal") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
"autocomplete_match_formatter.h",
"autocomplete_match_formatter.mm",
"autocomplete_result_consumer.h",
"autocomplete_suggestion.h",
"chrome_omnibox_client_ios.h",
"chrome_omnibox_client_ios.mm",
"image_retriever.h",
"location_bar_controller_impl.h",
"location_bar_controller_impl.mm",
"omnibox_popup_material_row.h",
"omnibox_popup_material_row.mm",
"omnibox_popup_material_view_controller.h",
"omnibox_popup_material_view_controller.mm",
"omnibox_popup_mediator.h",
"omnibox_popup_mediator.mm",
"omnibox_popup_positioner.h",
"omnibox_popup_presenter.h",
"omnibox_popup_presenter.mm",
......
// Copyright 2017 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_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_MATCH_FORMATTER_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_MATCH_FORMATTER_H_
#import "ios/chrome/browser/ui/omnibox/autocomplete_suggestion.h"
struct AutocompleteMatch;
@interface AutocompleteMatchFormatter : NSObject<AutocompleteSuggestion>
// This is a temporary solution for coloring strings.
@property(nonatomic, assign, getter=isIncognito) BOOL incognito;
@property(nonatomic, assign, getter=isStarred) BOOL starred;
- (instancetype)initWithMatch:(const AutocompleteMatch&)match
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
// Convenience constuctor.
+ (instancetype)formatterWithMatch:(const AutocompleteMatch&)match;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_MATCH_FORMATTER_H_
This diff is collapsed.
// Copyright 2017 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_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_RESULT_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_RESULT_CONSUMER_H_
#import "ios/chrome/browser/ui/omnibox/autocomplete_suggestion.h"
@protocol AutocompleteResultConsumer;
// Delegate for AutocompleteResultConsumer.
@protocol AutocompleteResultConsumerDelegate<NSObject>
// Tells the delegate when a row containing a suggestion is clicked.
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRow:(NSUInteger)row;
// Tells the delegate when a suggestion in|row| was chosen for appending to
// omnibox.
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRowForAppending:(NSUInteger)row;
// Tells the delegate when a suggestion in |row| was removed.
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRowForDeletion:(NSUInteger)row;
// Tells the delegate on scroll.
- (void)autocompleteResultConsumerDidScroll:
(id<AutocompleteResultConsumer>)sender;
@end
// An abstract consumer of autocomplete results.
@protocol AutocompleteResultConsumer<NSObject>
// Updates the current data and forces a redraw. If animation is YES, adds
// CALayer animations to fade the OmniboxPopupMaterialRows in.
- (void)updateMatches:(NSArray<id<AutocompleteSuggestion>>*)result
withAnimation:(BOOL)animation;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_RESULT_CONSUMER_H_
// Copyright 2017 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_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_SUGGESTION_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_SUGGESTION_H_
#import <UIKit/UIKit.h>
class GURL;
// Represents an autocomplete suggestion in UI.
@protocol AutocompleteSuggestion<NSObject>
// Some suggestions can be deleted with a swipe-to-delete gesture.
- (BOOL)supportsDeletion;
// Some suggestions are answers that are displayed inline, such as for weather
// or calculator.
- (BOOL)hasAnswer;
// Some suggestions represent a URL, for example the ones from history.
- (BOOL)isURL;
// Some suggestions can be appended to omnibox text in order to refine the
// query.
- (BOOL)isAppendable;
// The leading image for this suggestion type (loupe, globe, etc). Values are
// described in AutocompleteMatchType enum.
- (int)imageID;
// Text of the suggestion.
- (NSAttributedString*)text;
// Second line of text.
- (NSAttributedString*)detailText;
// Suggested number of lines to format |detailText|.
- (NSInteger)numberOfLines;
// Wether the suggestion has a downloadable image.
- (BOOL)hasImage;
// URL of the image, if |hasImage| is true.
- (GURL)imageURL;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_AUTOCOMPLETE_SUGGESTION_H_
// Copyright 2017 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_CHROME_BROWSER_UI_OMNIBOX_IMAGE_RETRIEVER_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_IMAGE_RETRIEVER_H_
@protocol ImageRetriever<NSObject>
- (void)fetchImage:(GURL)imageURL completion:(void (^)(UIImage*))completion;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_IMAGE_RETRIEVER_H_
......@@ -6,39 +6,25 @@
#define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MATERIAL_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/omnibox/autocomplete_result_consumer.h"
#import "ios/chrome/browser/ui/omnibox/image_retriever.h"
#include "components/omnibox/browser/autocomplete_result.h"
namespace image_fetcher {
class IOSImageDataFetcherWrapper;
}
class OmniboxPopupMaterialViewControllerDelegate {
public:
virtual bool IsStarredMatch(const AutocompleteMatch& match) const = 0;
virtual void OnMatchSelected(const AutocompleteMatch& match, size_t row) = 0;
virtual void OnMatchSelectedForAppending(const AutocompleteMatch& match) = 0;
virtual void OnMatchSelectedForDeletion(const AutocompleteMatch& match) = 0;
virtual void OnScroll() = 0;
};
@protocol ImageRetriever;
// View controller used to display a list of omnibox autocomplete matches in the
// omnibox popup.
@interface OmniboxPopupMaterialViewController : UITableViewController
@interface OmniboxPopupMaterialViewController
: UITableViewController<AutocompleteResultConsumer>
@property(nonatomic, assign) BOOL incognito;
// Designated initializer. Creates a table view with UITableViewStylePlain.
// Takes ownership of |imageFetcher|.
- (instancetype)
initWithFetcher:
(std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper>)imageFetcher
delegate:(OmniboxPopupMaterialViewControllerDelegate*)delegate;
// Updates the current data and forces a redraw. If animation is YES, adds
// CALayer animations to fade the OmniboxPopupMaterialRows in.
- (void)updateMatches:(const AutocompleteResult&)result
withAnimation:(BOOL)animation;
@property(nonatomic, weak) id<AutocompleteResultConsumerDelegate> delegate;
@property(nonatomic, weak) id<ImageRetriever> imageRetriever;
- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
- (instancetype)initWithNibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
// Set text alignment for popup cells.
- (void)setTextAlignment:(NSTextAlignment)alignment;
......
// Copyright 2017 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_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MEDIATOR_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MEDIATOR_H_
#import <UIKit/UIKit.h>
#include "components/omnibox/browser/autocomplete_result.h"
#import "ios/chrome/browser/ui/omnibox/autocomplete_result_consumer.h"
#import "ios/chrome/browser/ui/omnibox/image_retriever.h"
namespace image_fetcher {
class IOSImageDataFetcherWrapper;
} // namespace
class OmniboxPopupMediatorDelegate {
public:
virtual bool IsStarredMatch(const AutocompleteMatch& match) const = 0;
virtual void OnMatchSelected(const AutocompleteMatch& match, size_t row) = 0;
virtual void OnMatchSelectedForAppending(const AutocompleteMatch& match) = 0;
virtual void OnMatchSelectedForDeletion(const AutocompleteMatch& match) = 0;
virtual void OnScroll() = 0;
};
@interface OmniboxPopupMediator
: NSObject<AutocompleteResultConsumerDelegate, ImageRetriever>
// Designated initializer. Takes ownership of |imageFetcher|.
- (instancetype)initWithFetcher:
(std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper>)
imageFetcher
delegate:(OmniboxPopupMediatorDelegate*)delegate;
- (void)updateMatches:(const AutocompleteResult&)result
withAnimation:(BOOL)animated;
@property(nonatomic, weak) id<AutocompleteResultConsumer> consumer;
@property(nonatomic, assign, getter=isIncognito) BOOL incognito;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_MEDIATOR_H_
// Copyright 2017 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/chrome/browser/ui/omnibox/omnibox_popup_mediator.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#import "components/image_fetcher/ios/ios_image_data_fetcher_wrapper.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/autocomplete_result.h"
#import "ios/chrome/browser/ui/omnibox/autocomplete_match_formatter.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation OmniboxPopupMediator {
// Fetcher for Answers in Suggest images.
std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper> _imageFetcher;
OmniboxPopupMediatorDelegate* _delegate; // weak
AutocompleteResult _currentResult;
}
@synthesize consumer = _consumer;
@synthesize incognito = _incognito;
- (instancetype)initWithFetcher:
(std::unique_ptr<image_fetcher::IOSImageDataFetcherWrapper>)
imageFetcher
delegate:(OmniboxPopupMediatorDelegate*)delegate {
self = [super init];
if (self) {
DCHECK(delegate);
_delegate = delegate;
_imageFetcher = std::move(imageFetcher);
}
return self;
}
- (void)updateMatches:(const AutocompleteResult&)result
withAnimation:(BOOL)animation {
AutocompleteResult oldResults;
AutocompleteInput emptyInput;
oldResults.Swap(&_currentResult);
_currentResult.CopyOldMatches(emptyInput, result, nil);
[self.consumer updateMatches:[self wrappedMatches] withAnimation:animation];
}
- (NSArray<id<AutocompleteSuggestion>>*)wrappedMatches {
NSMutableArray<id<AutocompleteSuggestion>>* wrappedMatches =
[[NSMutableArray alloc] init];
size_t size = _currentResult.size();
for (size_t i = 0; i < size; i++) {
const AutocompleteMatch& match =
((const AutocompleteResult&)_currentResult).match_at((NSUInteger)i);
AutocompleteMatchFormatter* formatter =
[AutocompleteMatchFormatter formatterWithMatch:match];
formatter.starred = _delegate->IsStarredMatch(match);
formatter.incognito = _incognito;
[wrappedMatches addObject:formatter];
}
return wrappedMatches;
}
#pragma mark - AutocompleteResultConsumerDelegate
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRow:(NSUInteger)row {
// OpenMatch() may close the popup, which will clear the result set and, by
// extension, |match| and its contents. So copy the relevant match out to
// make sure it stays alive until the call completes.
const AutocompleteMatch& match =
((const AutocompleteResult&)_currentResult).match_at(row);
_delegate->OnMatchSelected(match, row);
}
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRowForAppending:(NSUInteger)row {
const AutocompleteMatch& match =
((const AutocompleteResult&)_currentResult).match_at(row);
if (AutocompleteMatch::IsSearchType(match.type)) {
base::RecordAction(
base::UserMetricsAction("MobileOmniboxRefineSuggestion.Search"));
} else {
base::RecordAction(
base::UserMetricsAction("MobileOmniboxRefineSuggestion.Url"));
}
_delegate->OnMatchSelectedForAppending(match);
}
- (void)autocompleteResultConsumer:(id<AutocompleteResultConsumer>)sender
didSelectRowForDeletion:(NSUInteger)row {
const AutocompleteMatch& match =
((const AutocompleteResult&)_currentResult).match_at(row);
_delegate->OnMatchSelectedForDeletion(match);
}
- (void)autocompleteResultConsumerDidScroll:
(id<AutocompleteResultConsumer>)sender {
_delegate->OnScroll();
}
#pragma mark - ImageFetcher
- (void)fetchImage:(GURL)imageURL completion:(void (^)(UIImage*))completion {
image_fetcher::IOSImageDataFetcherCallback callback =
^(NSData* data, const image_fetcher::RequestMetadata& metadata) {
if (data) {
UIImage* image =
[UIImage imageWithData:data scale:[UIScreen mainScreen].scale];
completion(image);
} else {
completion(nil);
}
};
_imageFetcher->FetchImageDataWebpDecoded(imageURL, callback);
}
@end
......@@ -13,6 +13,7 @@
#include "base/strings/string16.h"
#include "components/omnibox/browser/omnibox_popup_view.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_popup_mediator.h"
class OmniboxEditModel;
@class OmniboxPopupMaterialViewController;
......@@ -28,7 +29,7 @@ class ChromeBrowserState;
// iOS implementation of AutocompletePopupView.
class OmniboxPopupViewIOS : public OmniboxPopupView,
public OmniboxPopupMaterialViewControllerDelegate {
public OmniboxPopupMediatorDelegate {
public:
OmniboxPopupViewIOS(ios::ChromeBrowserState* browser_state,
OmniboxEditModel* edit_model,
......@@ -59,6 +60,7 @@ class OmniboxPopupViewIOS : public OmniboxPopupView,
private:
std::unique_ptr<OmniboxPopupModel> model_;
OmniboxPopupViewSuggestionsDelegate* delegate_; // weak
base::scoped_nsobject<OmniboxPopupMediator> mediator_;
base::scoped_nsobject<OmniboxPopupPresenter> presenter_;
base::scoped_nsobject<OmniboxPopupMaterialViewController> popup_controller_;
bool is_open_;
......
......@@ -20,6 +20,7 @@
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#import "ios/chrome/browser/experimental_flags.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_popup_material_view_controller.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_popup_mediator.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_popup_presenter.h"
#include "ios/chrome/browser/ui/omnibox/omnibox_popup_view_suggestions_delegate.h"
#include "ios/chrome/browser/ui/omnibox/omnibox_util.h"
......@@ -52,10 +53,17 @@ OmniboxPopupViewIOS::OmniboxPopupViewIOS(
base::MakeUnique<image_fetcher::IOSImageDataFetcherWrapper>(
browser_state->GetRequestContext());
popup_controller_.reset([[OmniboxPopupMaterialViewController alloc]
mediator_.reset([[OmniboxPopupMediator alloc]
initWithFetcher:std::move(imageFetcher)
delegate:this]);
popup_controller_.reset([[OmniboxPopupMaterialViewController alloc] init]);
[popup_controller_ setIncognito:browser_state->IsOffTheRecord()];
[mediator_ setIncognito:browser_state->IsOffTheRecord()];
[mediator_ setConsumer:popup_controller_];
[popup_controller_ setImageRetriever:mediator_];
[popup_controller_ setDelegate:mediator_];
presenter_.reset([[OmniboxPopupPresenter alloc]
initWithPopupPositioner:positioner
popupViewController:popup_controller_]);
......@@ -79,14 +87,15 @@ void OmniboxPopupViewIOS::UpdateEditViewIcon() {
void OmniboxPopupViewIOS::UpdatePopupAppearance() {
const AutocompleteResult& result = model_->result();
// TODO(crbug.com/762597): this logic should move to PopupCoordinator.
if (!is_open_ && !result.empty()) {
// The popup is not currently open and there are results to display. Update
// and animate the cells
[popup_controller_ updateMatches:result withAnimation:YES];
[mediator_ updateMatches:result withAnimation:YES];
} else {
// The popup is already displayed or there are no results to display. Update
// the cells without animating.
[popup_controller_ updateMatches:result withAnimation:NO];
[mediator_ updateMatches:result withAnimation:NO];
}
is_open_ = !result.empty();
......
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