Commit fadd7245 authored by lpromero's avatar lpromero Committed by Commit bot

Upstream ios/showcase source code.

This is a dev-only, standalone app for Chrome for iOS development. It showcases
(and is restricted to) UI elements used and developed for Chrome for iOS.

BUG=653086
R=sdefresne@chromium.org

Review-Url: https://codereview.chromium.org/2592593003
Cr-Commit-Position: refs/heads/master@{#439773}
parent 1691bb10
...@@ -29,13 +29,14 @@ group("all") { ...@@ -29,13 +29,14 @@ group("all") {
# List all the targets that need to be build on iOS by default. # List all the targets that need to be build on iOS by default.
"//ios/chrome/app:chrome", "//ios/chrome/app:chrome",
"//ios/chrome/app:chrome_clean_skeleton", "//ios/chrome/app:chrome_clean_skeleton",
"//ios/showcase",
"//ios/web/shell:ios_web_shell", "//ios/web/shell:ios_web_shell",
# List all the test targets that need to be build on iOS by default. # List all the test targets that need to be build on iOS by default.
"//ios/chrome/test:all_tests", "//ios/chrome/test:all_tests",
"//ios/chrome/test/earl_grey:all_tests", "//ios/chrome/test/earl_grey:all_tests",
"//ios/net:all_tests", "//ios/net:all_tests",
"//ios/showcase/test:all_tests", "//ios/showcase:all_tests",
"//ios/testing:all_tests", "//ios/testing:all_tests",
"//ios/web:all_tests", "//ios/web:all_tests",
"//ios/web/shell/test:all_tests", "//ios/web/shell/test:all_tests",
......
# Copyright 2016 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("//build/config/ios/rules.gni")
import("//ios/build/chrome_build.gni")
import("//ios/build/config.gni")
import("//ios/third_party/earl_grey/ios_eg_test.gni")
ios_app_bundle("showcase") {
info_plist = "core/Info.plist"
extra_substitutions = [ "IOS_BUNDLE_ID_PREFIX=$ios_app_bundle_id_prefix" ]
output_name = "Showcase"
deps = [
":features",
"//ios/showcase/core:main",
# All shared libraries must have the sanitizer deps to properly link in
# asan mode (this target will be empty in other cases).
"//build/config/sanitizers:deps",
]
bundle_deps = [ ":launchscreen_storyboard" ]
assert_no_deps = ios_assert_no_deps
}
group("features") {
deps = [
"//ios/chrome/browser/ui/tools:tools_ui",
"//ios/showcase/settings",
"//ios/showcase/tab_grid",
"//ios/showcase/uikit_table_view_cell",
]
}
group("all_tests") {
testonly = true
deps = [
":ios_showcase_egtests",
]
}
ios_eg_test("ios_showcase_egtests") {
info_plist = "core/Info.plist"
extra_substitutions = [ "IOS_BUNDLE_ID_PREFIX=$ios_app_bundle_id_prefix" ]
deps = [
":features",
"//ios/showcase/core:main",
# Add all eg_tests targets below.
"//ios/showcase/core:eg_tests",
"//ios/showcase/tab_grid:eg_tests",
# All shared libraries must have the sanitizer deps to properly link in
# asan mode (this target will be empty in other cases).
"//build/config/sanitizers:deps",
]
bundle_deps = [ ":launchscreen_storyboard" ]
assert_no_deps = ios_assert_no_deps
}
bundle_data_ib_file("launchscreen_storyboard") {
source = "core/LaunchScreen.storyboard"
}
include_rules = [
"+ios/chrome",
]
lpromero@chromium.org
# Copyright 2016 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.
source_set("common") {
sources = [
"coordinator.h",
]
libs = [ "Foundation.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
// Copyright 2016 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_SHOWCASE_COMMON_COORDINATOR_H_
#define IOS_SHOWCASE_COMMON_COORDINATOR_H_
#import <Foundation/Foundation.h>
// This protocol is the common interface to the simple non-production
// coordinators that will initialize, set up and present production view
// controllers, usually with completely mocked data.
@protocol Coordinator<NSObject>
// The base view controller used to present the view controller that this
// coordinator drives.
@property(nonatomic, weak) UIViewController* baseViewController;
// Typically, this initializes a view controller, sets it up and presents it.
- (void)start;
@end
#endif // IOS_SHOWCASE_COMMON_COORDINATOR_H_
# Copyright 2016 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.
source_set("core") {
sources = [
"app_delegate.h",
"app_delegate.mm",
"showcase_model.h",
"showcase_model.mm",
"showcase_view_controller.h",
"showcase_view_controller.mm",
]
deps = [
"//base",
"//ios/showcase/common",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
source_set("main") {
sources = [
"main.mm",
]
deps = [
":core",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
source_set("eg_tests") {
testonly = true
sources = [
"showcase_egtest.mm",
]
deps = [
"//ios/showcase/test",
"//ios/third_party/earl_grey",
]
configs += [ "//build/config/compiler:enable_arc" ]
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${IOS_BUNDLE_ID_PREFIX}.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11542" systemVersion="16B2657" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="QI3-dQ-1cO">
<device id="retina5_5" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11524"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Navigation Controller-->
<scene sceneID="u0V-zC-FBB">
<objects>
<navigationController id="QI3-dQ-1cO" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="ha0-fg-3GF">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="54D-Ky-HgW" kind="relationship" relationship="rootViewController" id="sjH-IV-Bd0"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="QaL-p0-lQo" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-513" y="-62"/>
</scene>
<!--Showcase-->
<scene sceneID="9lb-oL-wGX">
<objects>
<viewController id="54D-Ky-HgW" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="trb-La-da6"/>
<viewControllerLayoutGuide type="bottom" id="MzX-hC-qOa"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="CAL-d9-rAz">
<rect key="frame" x="0.0" y="0.0" width="414" height="736"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
<navigationItem key="navigationItem" title="Showcase" id="9hL-yr-6we"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="o1d-CR-HVs" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="386" y="-60"/>
</scene>
</scenes>
</document>
// Copyright 2016 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_SHOWCASE_CORE_APP_DELEGATE_H_
#define IOS_SHOWCASE_CORE_APP_DELEGATE_H_
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder<UIApplicationDelegate>
@property(strong, nonatomic) UIWindow* window;
@end
#endif // IOS_SHOWCASE_CORE_APP_DELEGATE_H_
// Copyright 2016 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/showcase/core/app_delegate.h"
#import "ios/showcase/core/showcase_model.h"
#import "ios/showcase/core/showcase_view_controller.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation AppDelegate
@synthesize window = _window;
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ShowcaseViewController* viewController =
[[ShowcaseViewController alloc] initWithRows:[self rowsToDisplay]];
UINavigationController* navigationController = [[UINavigationController alloc]
initWithRootViewController:viewController];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
#pragma mark - Private
// Creates model data to display in the view controller.
- (NSArray<showcase::ModelRow*>*)rowsToDisplay {
NSArray<showcase::ModelRow*>* rows = [ShowcaseModel model];
NSSortDescriptor* sortDescriptor =
[NSSortDescriptor sortDescriptorWithKey:showcase::kClassForDisplayKey
ascending:YES];
return [rows sortedArrayUsingDescriptors:@[ sortDescriptor ]];
}
@end
// Copyright 2016 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 <UIKit/UIKit.h>
#import "ios/showcase/core/app_delegate.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
}
}
// Copyright 2016 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 <EarlGrey/EarlGrey.h>
#import "ios/showcase/test/showcase_test_case.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// Tests for the core of the Showcase app.
@interface ShowcaseCoreTestCase : ShowcaseTestCase
@end
@implementation ShowcaseCoreTestCase
// Tests that Showcase title appears after launch.
- (void)testLaunch {
[[EarlGrey selectElementWithMatcher:grey_text(@"Showcase")]
assertWithMatcher:grey_notNil()];
}
@end
// Copyright 2016 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_SHOWCASE_CORE_SHOWCASE_MODEL_H_
#define IOS_SHOWCASE_CORE_SHOWCASE_MODEL_H_
#import <Foundation/Foundation.h>
#import "ios/showcase/core/showcase_view_controller.h"
// Model object of rows to display in Showcase.
@interface ShowcaseModel : NSObject
+ (NSArray<showcase::ModelRow*>*)model;
@end
#endif // IOS_SHOWCASE_CORE_SHOWCASE_MODEL_H_
// Copyright 2016 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/showcase/core/showcase_model.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation ShowcaseModel
// Insert additional rows in this array. All rows will be sorted upon
// import into Showcase.
// |kShowcaseClassForDisplayKey| and |kShowcaseClassForInstantiationKey| are
// required. |kShowcaseUseCaseKey| is optional.
+ (NSArray<showcase::ModelRow*>*)model {
return @[
@{
showcase::kClassForDisplayKey : @"SettingsViewController",
showcase::kClassForInstantiationKey : @"SettingsCoordinator",
showcase::kUseCaseKey : @"Main settings screen",
},
@{
showcase::kClassForDisplayKey : @"MenuViewController",
showcase::kClassForInstantiationKey : @"MenuViewController",
showcase::kUseCaseKey : @"Tools menu",
},
@{
showcase::kClassForDisplayKey : @"UITableViewCell",
showcase::kClassForInstantiationKey : @"UIKitTableViewCellViewController",
showcase::kUseCaseKey : @"UIKit Table Cells",
},
@{
showcase::kClassForDisplayKey : @"TabGridViewController",
showcase::kClassForInstantiationKey : @"SCTabGridCoordinator",
showcase::kUseCaseKey : @"Tab grid",
},
];
}
@end
// Copyright 2016 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_SHOWCASE_CORE_SHOWCASE_VIEW_CONTROLLER_H_
#define IOS_SHOWCASE_CORE_SHOWCASE_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
namespace showcase {
// Required name for class that is intended to be tested.
extern NSString* const kClassForDisplayKey;
// Required name for class that will be instantiated.
extern NSString* const kClassForInstantiationKey;
// Optional description of the use case for the row.
extern NSString* const kUseCaseKey;
// Type for one row of model.
typedef NSDictionary<NSString*, NSString*> ModelRow;
} // namespace showcase
// TableViewController that displays a searchable list of rows.
@interface ShowcaseViewController : UITableViewController
// Initializes the tableView with a list of rows.
- (instancetype)initWithRows:(NSArray<showcase::ModelRow*>*)rows
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithNibName:(NSString*)nibNameOrNil
bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE;
- (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE;
@end
#endif // IOS_SHOWCASE_CORE_SHOWCASE_VIEW_CONTROLLER_H_
// Copyright 2016 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/showcase/core/showcase_view_controller.h"
#import "base/logging.h"
#import "ios/showcase/common/coordinator.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace showcase {
NSString* const kClassForDisplayKey = @"classForDisplay";
NSString* const kClassForInstantiationKey = @"classForInstantiation";
NSString* const kUseCaseKey = @"useCase";
} // namespace showcase
@interface ShowcaseViewController ()<UITableViewDataSource,
UITableViewDelegate,
UISearchResultsUpdating>
// Search controller that contains search bar.
@property(nonatomic, strong) UISearchController* searchController;
// Full data set displayed when tableView is not filtered.
@property(nonatomic, strong) NSArray<showcase::ModelRow*>* allRows;
// Displayed rows in tableView.
@property(nonatomic, strong) NSArray<showcase::ModelRow*>* displayedRows;
// Selected coordinator.
@property(nonatomic, strong) id<Coordinator> activeCoordinator;
@end
@implementation ShowcaseViewController
@synthesize searchController = _searchController;
@synthesize allRows = _allRows;
@synthesize displayedRows = _displayedRows;
@synthesize activeCoordinator = _activeCoordinator;
- (instancetype)initWithRows:(NSArray<showcase::ModelRow*>*)rows {
self = [super initWithStyle:UITableViewStylePlain];
if (self) {
self.allRows = [rows copy];
// Default to displaying all rows.
self.displayedRows = self.allRows;
}
return self;
}
#pragma mark - UIViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Showcase";
self.tableView.tableFooterView = [[UIView alloc] init];
self.tableView.rowHeight = 70.0;
self.searchController =
[[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.tableView.tableHeaderView = self.searchController.searchBar;
// Presentation of searchController will walk up the view controller hierarchy
// until it finds the root view controller or one that defines a presentation
// context. Make this class the presentation context so that the search
// controller does not present on top of the navigation controller.
self.definesPresentationContext = YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Resets the current coordinator whenever the navigation controller pops
// back to this view controller.
self.activeCoordinator = nil;
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {
return self.displayedRows.count;
}
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:@"cell"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
showcase::ModelRow* row = self.displayedRows[indexPath.row];
cell.textLabel.text = row[showcase::kClassForDisplayKey];
cell.detailTextLabel.text = row[showcase::kUseCaseKey];
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView*)tableView
didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
showcase::ModelRow* row = self.displayedRows[indexPath.row];
Class classForInstantiation =
NSClassFromString(row[showcase::kClassForInstantiationKey]);
if ([classForInstantiation isSubclassOfClass:[UIViewController class]]) {
UIViewController* viewController = [[classForInstantiation alloc] init];
viewController.title = row[showcase::kUseCaseKey];
[self.navigationController pushViewController:viewController animated:YES];
} else if ([classForInstantiation
conformsToProtocol:@protocol(Coordinator)]) {
self.activeCoordinator = [[classForInstantiation alloc] init];
self.activeCoordinator.baseViewController = self.navigationController;
[self.activeCoordinator start];
} else {
NOTREACHED();
}
}
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:
(UISearchController*)searchController {
[self filterContentForSearchText:searchController.searchBar.text];
}
#pragma mark - Private
// Filters |allRows| for |searchText| and reloads the tableView with
// animation. If |searchText| is empty, tableView will be loaded with |allRows|.
- (void)filterContentForSearchText:(NSString*)searchText {
NSArray<showcase::ModelRow*>* newFilteredRows = self.allRows;
if (![self.searchController.searchBar.text isEqualToString:@""]) {
// The search is case-insensitive and searches both displayed texts.
NSIndexSet* matchingRows =
[self.allRows indexesOfObjectsPassingTest:^BOOL(
showcase::ModelRow* row, NSUInteger idx, BOOL* stop) {
return [row[showcase::kClassForDisplayKey]
localizedCaseInsensitiveContainsString:searchText] ||
[row[showcase::kUseCaseKey]
localizedCaseInsensitiveContainsString:searchText];
}];
newFilteredRows = [self.allRows objectsAtIndexes:matchingRows];
}
NSArray<NSIndexPath*>* indexPathsToInsert =
[self indexPathsToInsertFromArray:self.displayedRows
toArray:newFilteredRows
indexPathSection:0];
NSArray<NSIndexPath*>* indexPathsToDelete =
[self indexPathsToDeleteFromArray:self.displayedRows
toArray:newFilteredRows
indexPathSection:0];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPathsToInsert
withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:indexPathsToDelete
withRowAnimation:UITableViewRowAnimationFade];
self.displayedRows = newFilteredRows;
[self.tableView endUpdates];
}
// Returns indexPaths that need to be inserted into the tableView.
- (NSArray<NSIndexPath*>*)indexPathsToInsertFromArray:(NSArray*)fromArray
toArray:(NSArray*)toArray
indexPathSection:(NSUInteger)section {
NSMutableArray<NSIndexPath*>* indexPathsToInsert =
[[NSMutableArray alloc] init];
for (NSUInteger row = 0; row < toArray.count; row++) {
if (![fromArray containsObject:toArray[row]]) {
[indexPathsToInsert
addObject:[NSIndexPath indexPathForRow:row inSection:section]];
}
}
return indexPathsToInsert;
}
// Returns indexPaths that need to be deleted from the tableView.
- (NSArray<NSIndexPath*>*)indexPathsToDeleteFromArray:(NSArray*)fromArray
toArray:(NSArray*)toArray
indexPathSection:(NSUInteger)section {
NSMutableArray<NSIndexPath*>* indexPathsToDelete =
[[NSMutableArray alloc] init];
for (NSUInteger row = 0; row < fromArray.count; row++) {
if (![toArray containsObject:fromArray[row]]) {
[indexPathsToDelete
addObject:[NSIndexPath indexPathForRow:row inSection:section]];
}
}
return indexPathsToDelete;
}
@end
# Copyright 2016 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.
source_set("settings") {
sources = [
"settings_coordinator.h",
"settings_coordinator.mm",
]
deps = [
"//base",
"//ios/showcase/common",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
// Copyright 2016 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_SHOWCASE_SETTINGS_SETTINGS_COORDINATOR_H_
#define IOS_SHOWCASE_SETTINGS_SETTINGS_COORDINATOR_H_
#import <UIKit/UIKit.h>
#import "ios/showcase/common/coordinator.h"
@interface SettingsCoordinator : NSObject<Coordinator>
// Redefined to be a UINavigationController.
@property(nonatomic, weak) UINavigationController* baseViewController;
@end
#endif // IOS_SHOWCASE_SETTINGS_SETTINGS_COORDINATOR_H_
// Copyright 2016 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/showcase/settings/settings_coordinator.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation SettingsCoordinator
@synthesize baseViewController;
- (void)start {
UIViewController* settings = [[UIViewController alloc] init];
settings.title = @"Settings";
settings.view.backgroundColor = [UIColor grayColor];
[self.baseViewController pushViewController:settings animated:YES];
}
@end
# Copyright 2016 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.
source_set("tab_grid") {
sources = [
"sc_tab_grid_coordinator.h",
"sc_tab_grid_coordinator.mm",
]
deps = [
"//base",
"//ios/chrome/browser/ui/tab_grid:tab_grid_ui",
"//ios/showcase/common",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
source_set("eg_tests") {
testonly = true
sources = [
"sc_tab_grid_egtest.mm",
]
deps = [
"//ios/showcase/test",
"//ios/third_party/earl_grey",
]
configs += [ "//build/config/compiler:enable_arc" ]
}
// Copyright 2016 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_SHOWCASE_TAB_GRID_SC_TAB_GRID_COORDINATOR_H_
#define IOS_SHOWCASE_TAB_GRID_SC_TAB_GRID_COORDINATOR_H_
#import <UIKit/UIKit.h>
#import "ios/showcase/common/coordinator.h"
@interface SCTabGridCoordinator : NSObject<Coordinator>
// Redefined to be a UINavigationController.
@property(nonatomic, weak) UINavigationController* baseViewController;
@end
#endif // IOS_SHOWCASE_TAB_GRID_SC_TAB_GRID_COORDINATOR_H_
// Copyright 2016 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/showcase/tab_grid/sc_tab_grid_coordinator.h"
#import "base/format_macros.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@interface SCTabGridCoordinator ()<TabGridDataSource, TabGridActionDelegate>
@property(nonatomic, strong) TabGridViewController* viewController;
@end
@implementation SCTabGridCoordinator
@synthesize baseViewController = _baseViewController;
@synthesize viewController = _viewController;
- (void)start {
self.viewController = [[TabGridViewController alloc] init];
self.viewController.title = @"Tab Grid";
self.viewController.dataSource = self;
self.viewController.actionDelegate = self;
[self.baseViewController setHidesBarsOnSwipe:YES];
[self.baseViewController pushViewController:self.viewController animated:YES];
}
#pragma mark - TabGridDataSource
- (NSUInteger)numberOfTabsInTabGrid {
return 3;
}
- (NSString*)titleAtIndex:(NSInteger)index {
return [NSString stringWithFormat:@"Tab %" PRIdNS, index];
}
#pragma mark - TabGridActionDelegate
- (void)showTabAtIndexPath:(NSIndexPath*)indexPath {
[self
showAlertWithTitle:NSStringFromProtocol(@protocol(TabGridActionDelegate))
message:[NSString
stringWithFormat:@"showTabAtIndexPath:%" PRIdNS,
indexPath.item]];
}
- (void)showTabGrid {
[self
showAlertWithTitle:NSStringFromProtocol(@protocol(TabGridActionDelegate))
message:NSStringFromSelector(_cmd)];
}
- (void)showSettings {
[self
showAlertWithTitle:NSStringFromProtocol(@protocol(TabGridActionDelegate))
message:NSStringFromSelector(_cmd)];
}
#pragma mark - Private
// Helper to show simple alert.
- (void)showAlertWithTitle:(NSString*)title message:(NSString*)message {
UIAlertController* alertController =
[UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* action =
[UIAlertAction actionWithTitle:@"Done"
style:UIAlertActionStyleCancel
handler:nil];
[alertController addAction:action];
[self.baseViewController presentViewController:alertController
animated:YES
completion:nil];
}
@end
// Copyright 2016 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 <EarlGrey/EarlGrey.h>
#import "ios/showcase/test/showcase_test_case.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
// Tests for the tab grid view controller.
@interface SCTabGridTestCase : ShowcaseTestCase
@end
@implementation SCTabGridTestCase
// Tests launching TabGridViewController and tapping a cell.
- (void)testLaunchAndTappingCell {
[[EarlGrey selectElementWithMatcher:grey_text(@"TabGridViewController")]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:grey_text(@"Tab 0")]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:grey_text(@"TabGridActionDelegate")]
assertWithMatcher:grey_notNil()];
[[EarlGrey selectElementWithMatcher:grey_text(@"Done")]
performAction:grey_tap()];
}
@end
...@@ -2,9 +2,18 @@ ...@@ -2,9 +2,18 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
# This empty target is there to help with upstreaming by removing a manual source_set("test") {
# step from the process (updating the //ios:all target). It will be changed
# to a real target as part of upstreaming.
group("all_tests") {
testonly = true testonly = true
sources = [
"showcase_test_case.h",
"showcase_test_case.mm",
]
deps = [
"//base",
"//ios/third_party/earl_grey",
]
public_deps = [
"//build/config/ios:xctest",
]
configs += [ "//build/config/compiler:enable_arc" ]
} }
// Copyright 2016 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_SHOWCASE_TEST_SHOWCASE_TEST_CASE_H_
#define IOS_SHOWCASE_TEST_SHOWCASE_TEST_CASE_H_
#import <XCTest/XCTest.h>
// Base class for all Showcase Earl Grey tests.
@interface ShowcaseTestCase : XCTestCase
@end
#endif // IOS_SHOWCASE_TEST_SHOWCASE_TEST_CASE_H_
// Copyright 2016 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/showcase/test/showcase_test_case.h"
#import <EarlGrey/EarlGrey.h>
#import "base/logging.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation ShowcaseTestCase
// Overrides testInvocations so the set of tests run can be modified, as
// necessary.
+ (NSArray*)testInvocations {
NSError* error = nil;
[[EarlGrey selectElementWithMatcher:grey_systemAlertViewShown()]
assertWithMatcher:grey_nil()
error:&error];
if (error != nil) {
LOG(ERROR) << "System alert view is present, so skipping all tests.";
return @[];
}
return [super testInvocations];
}
@end
# Copyright 2016 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.
source_set("uikit_table_view_cell") {
sources = [
"uikit_table_view_cell_view_controller.h",
"uikit_table_view_cell_view_controller.mm",
]
libs = [ "UIKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
// Copyright 2016 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_SHOWCASE_UIKIT_TABLE_VIEW_CELL_UIKIT_TABLE_VIEW_CELL_VIEW_CONTROLLER_H_
#define IOS_SHOWCASE_UIKIT_TABLE_VIEW_CELL_UIKIT_TABLE_VIEW_CELL_VIEW_CONTROLLER_H_
#import <UIKit/UIKit.h>
@interface UIKitTableViewCellViewController : UITableViewController
@end
#endif // IOS_SHOWCASE_UIKIT_TABLE_VIEW_CELL_UIKIT_TABLE_VIEW_CELL_VIEW_CONTROLLER_H_
// Copyright 2016 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/showcase/uikit_table_view_cell/uikit_table_view_cell_view_controller.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation UIKitTableViewCellViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.tableFooterView = [[UIView alloc] init];
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
return 4;
}
- (NSInteger)tableView:(UITableView*)tableView
numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (NSString*)tableView:(UITableView*)tableView
titleForHeaderInSection:(NSInteger)section {
switch ([self styleForSection:section]) {
case UITableViewCellStyleDefault:
return @"Default Style";
case UITableViewCellStyleValue1:
return @"Value 1 Style";
case UITableViewCellStyleValue2:
return @"Value 2 Style";
case UITableViewCellStyleSubtitle:
return @"Subtitle Style";
}
}
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCellStyle style = [self styleForSection:indexPath.section];
NSString* reuseIdentifier = @(style).stringValue;
UITableViewCell* cell =
[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:style
reuseIdentifier:reuseIdentifier];
}
cell.textLabel.text = @"Text";
cell.detailTextLabel.text = @"Detail Text";
return cell;
}
#pragma mark - Private
- (UITableViewCellStyle)styleForSection:(NSInteger)section {
NSAssert(section >= 0, @"");
NSAssert(section < 4, @"");
return (UITableViewCellStyle)section;
}
@end
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