Add a test harness for running UI tests on the iOS Simulator
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Aug 2016 23:28:59 +0000 (23:28 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Aug 2016 23:28:59 +0000 (23:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161265

.:

Add the new MobileMiniBrowser project to the WebKit workspace.

Reviewed by Simon Fraser.

* WebKit.xcworkspace/contents.xcworkspacedata:

Tools:

Reviewed by Simon Fraser.

Add a new iOS Simulator application which uses WKWebView to implement a basic browser, and which
can serve as a test harness for WebKit UI tests.

Also add a basic media playback test which verifies that a <video> element will begin playing in
fullscreen on an iPhone device, but will play inline on an iPad device.

* Makefile: Add MobileMiniBrowser as a Module for iOS builds.
* MobileMiniBrowser/Configurations/Base.xcconfig: Added.
* MobileMiniBrowser/Configurations/DebugRelease.xcconfig: Added.
* MobileMiniBrowser/Configurations/MobileMiniBrowser.xcconfig: Added.
* MobileMiniBrowser/Makefile: Added.
* MobileMiniBrowser/MobileMiniBrowser.xcodeproj/project.pbxproj: Added.
* MobileMiniBrowser/MobileMiniBrowser/AppDelegate.h: Added.
* MobileMiniBrowser/MobileMiniBrowser/AppDelegate.m: Added.
(-[AppDelegate application:didFinishLaunchingWithOptions:]):
(-[AppDelegate applicationWillResignActive:]):
(-[AppDelegate applicationDidEnterBackground:]):
(-[AppDelegate applicationWillEnterForeground:]):
(-[AppDelegate applicationDidBecomeActive:]):
(-[AppDelegate applicationWillTerminate:]):
* MobileMiniBrowser/MobileMiniBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json: Added.
* MobileMiniBrowser/MobileMiniBrowser/Base.lproj/LaunchScreen.storyboard: Added.
* MobileMiniBrowser/MobileMiniBrowser/Base.lproj/Main.storyboard: Added.
* MobileMiniBrowser/MobileMiniBrowser/Info.plist: Added.
* MobileMiniBrowser/MobileMiniBrowser/TabViewController.h: Added.
* MobileMiniBrowser/MobileMiniBrowser/TabViewController.m: Added.
(-[TabViewController dealloc]):
(-[TabViewController viewDidLoad]):
(-[TabViewController observeValueForKeyPath:ofObject:change:context:]):
(-[TabViewController tableView:cellForRowAtIndexPath:]):
(-[TabViewController tableView:numberOfRowsInSection:]):
(-[TabViewController numberOfSectionsInTableView:]):
(-[TabViewController tableView:canEditRowAtIndexPath:]):
(-[TabViewController tableView:canMoveRowAtIndexPath:]):
(-[TabViewController tableView:commitEditingStyle:forRowAtIndexPath:]):
(-[TabViewController tableView:didSelectRowAtIndexPath:]):
* MobileMiniBrowser/MobileMiniBrowser/WebViewController.h: Added.
* MobileMiniBrowser/MobileMiniBrowser/WebViewController.m: Added.
(-[WebViewController viewDidLoad]):
(-[WebViewController didReceiveMemoryWarning]):
(-[WebViewController reload:]):
(-[WebViewController goBack:]):
(-[WebViewController goForward:]):
(-[WebViewController urlFieldEditingBegan:]):
(-[WebViewController navigateTo:]):
(-[WebViewController showTabs:]):
(-[WebViewController selectWebViewAtIndex:]):
(-[WebViewController removeWebViewAtIndex:]):
(-[WebViewController addWebView]):
(-[WebViewController createWebView]):
(-[WebViewController removeWebView:]):
(-[WebViewController setCurrentWebView:]):
(-[WebViewController webView:didFailNavigation:withError:]):
(-[WebViewController observeValueForKeyPath:ofObject:change:context:]):
* MobileMiniBrowser/MobileMiniBrowser/main.m: Added.
(main):
* MobileMiniBrowser/MobileMiniBrowserUITests/Info.plist: Added.
* MobileMiniBrowser/MobileMiniBrowserUITests/MobileMiniBrowserUITests.m: Added.
(-[MobileMiniBrowserUITests setUp]):
(-[MobileMiniBrowserUITests tearDown]):
(-[MobileMiniBrowserUITests testBasicVideoPlayback]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205057 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
ChangeLog
Tools/ChangeLog
Tools/Makefile
Tools/MobileMiniBrowser/Configurations/Base.xcconfig [new file with mode: 0644]
Tools/MobileMiniBrowser/Configurations/DebugRelease.xcconfig [new file with mode: 0644]
Tools/MobileMiniBrowser/Configurations/MobileMiniBrowser.xcconfig [new file with mode: 0644]
Tools/MobileMiniBrowser/Makefile [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser.xcodeproj/project.pbxproj [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.h [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.m [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/LaunchScreen.storyboard [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/Main.storyboard [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/Info.plist [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.h [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.m [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.h [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.m [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowser/main.m [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowserUITests/Info.plist [new file with mode: 0644]
Tools/MobileMiniBrowser/MobileMiniBrowserUITests/MobileMiniBrowserUITests.m [new file with mode: 0644]
WebKit.xcworkspace/contents.xcworkspacedata

index 3c9eebb..c6ce9c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2016-08-26  Jer Noble  <jer.noble@apple.com>
+
+        Add a test harness for running UI tests on the iOS Simulator
+        https://bugs.webkit.org/show_bug.cgi?id=161265
+
+        Add the new MobileMiniBrowser project to the WebKit workspace.
+
+        Reviewed by Simon Fraser.
+
+        * WebKit.xcworkspace/contents.xcworkspacedata:
+
 2016-08-24  Alexey Proskuryakov  <ap@apple.com>
 
         Add svn:global-ignores to the root to ignore *.pyc files everythere in the repository.
index ab03be8..69a49a6 100644 (file)
@@ -1,3 +1,72 @@
+2016-08-26  Jer Noble  <jer.noble@apple.com>
+
+        Add a test harness for running UI tests on the iOS Simulator
+        https://bugs.webkit.org/show_bug.cgi?id=161265
+
+        Reviewed by Simon Fraser.
+
+        Add a new iOS Simulator application which uses WKWebView to implement a basic browser, and which
+        can serve as a test harness for WebKit UI tests.
+
+        Also add a basic media playback test which verifies that a <video> element will begin playing in
+        fullscreen on an iPhone device, but will play inline on an iPad device.
+
+        * Makefile: Add MobileMiniBrowser as a Module for iOS builds.
+        * MobileMiniBrowser/Configurations/Base.xcconfig: Added.
+        * MobileMiniBrowser/Configurations/DebugRelease.xcconfig: Added.
+        * MobileMiniBrowser/Configurations/MobileMiniBrowser.xcconfig: Added.
+        * MobileMiniBrowser/Makefile: Added.
+        * MobileMiniBrowser/MobileMiniBrowser.xcodeproj/project.pbxproj: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/AppDelegate.h: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/AppDelegate.m: Added.
+        (-[AppDelegate application:didFinishLaunchingWithOptions:]):
+        (-[AppDelegate applicationWillResignActive:]):
+        (-[AppDelegate applicationDidEnterBackground:]):
+        (-[AppDelegate applicationWillEnterForeground:]):
+        (-[AppDelegate applicationDidBecomeActive:]):
+        (-[AppDelegate applicationWillTerminate:]):
+        * MobileMiniBrowser/MobileMiniBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/Base.lproj/LaunchScreen.storyboard: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/Base.lproj/Main.storyboard: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/Info.plist: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/TabViewController.h: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/TabViewController.m: Added.
+        (-[TabViewController dealloc]):
+        (-[TabViewController viewDidLoad]):
+        (-[TabViewController observeValueForKeyPath:ofObject:change:context:]):
+        (-[TabViewController tableView:cellForRowAtIndexPath:]):
+        (-[TabViewController tableView:numberOfRowsInSection:]):
+        (-[TabViewController numberOfSectionsInTableView:]):
+        (-[TabViewController tableView:canEditRowAtIndexPath:]):
+        (-[TabViewController tableView:canMoveRowAtIndexPath:]):
+        (-[TabViewController tableView:commitEditingStyle:forRowAtIndexPath:]):
+        (-[TabViewController tableView:didSelectRowAtIndexPath:]):
+        * MobileMiniBrowser/MobileMiniBrowser/WebViewController.h: Added.
+        * MobileMiniBrowser/MobileMiniBrowser/WebViewController.m: Added.
+        (-[WebViewController viewDidLoad]):
+        (-[WebViewController didReceiveMemoryWarning]):
+        (-[WebViewController reload:]):
+        (-[WebViewController goBack:]):
+        (-[WebViewController goForward:]):
+        (-[WebViewController urlFieldEditingBegan:]):
+        (-[WebViewController navigateTo:]):
+        (-[WebViewController showTabs:]):
+        (-[WebViewController selectWebViewAtIndex:]):
+        (-[WebViewController removeWebViewAtIndex:]):
+        (-[WebViewController addWebView]):
+        (-[WebViewController createWebView]):
+        (-[WebViewController removeWebView:]):
+        (-[WebViewController setCurrentWebView:]):
+        (-[WebViewController webView:didFailNavigation:withError:]):
+        (-[WebViewController observeValueForKeyPath:ofObject:change:context:]):
+        * MobileMiniBrowser/MobileMiniBrowser/main.m: Added.
+        (main):
+        * MobileMiniBrowser/MobileMiniBrowserUITests/Info.plist: Added.
+        * MobileMiniBrowser/MobileMiniBrowserUITests/MobileMiniBrowserUITests.m: Added.
+        (-[MobileMiniBrowserUITests setUp]):
+        (-[MobileMiniBrowserUITests tearDown]):
+        (-[MobileMiniBrowserUITests testBasicVideoPlayback]):
+
 2016-08-26  Aakash Jain  <aakash_jain@apple.com>
 
         webkit-queues queue-status page should should list more recent statuses
index 55e89ea..a2a76ce 100644 (file)
@@ -2,7 +2,7 @@ MODULES = DumpRenderTree WebKitTestRunner MiniBrowser ../Source/ThirdParty/gtest
 
 ifneq (,$(SDKROOT))
        ifeq (,$(findstring macosx,$(SDKROOT)))
-               MODULES = DumpRenderTree WebKitTestRunner ../Source/ThirdParty/gtest/xcode TestWebKitAPI
+               MODULES = DumpRenderTree WebKitTestRunner MobileMiniBrowser ../Source/ThirdParty/gtest/xcode TestWebKitAPI
        endif
        ifeq (,$(DO_NOT_BUILD_LAYOUT_TEST_RELAY))
                MODULES += LayoutTestRelay
diff --git a/Tools/MobileMiniBrowser/Configurations/Base.xcconfig b/Tools/MobileMiniBrowser/Configurations/Base.xcconfig
new file mode 100644 (file)
index 0000000..f88c726
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (C) 2016 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+#include "../../../../Internal/Configurations/HaveInternalSDK.xcconfig"
+
+SDKROOT = iphoneos;
+
+TARGETED_DEVICE_FAMILY = 1,2;
+
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym;
+
+GCC_C_LANGUAGE_STANDARD = gnu99;
+
+GCC_PREPROCESSOR_DEFINITIONS = $(ENGINEERING_BUILD_DEFINES) $(inherited);
+
+GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+
+CLANG_WARN_BOOL_CONVERSION = YES;
+CLANG_WARN_CONSTANT_CONVERSION = YES;
+CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+CLANG_WARN_EMPTY_BODY = YES;
+CLANG_WARN_ENUM_CONVERSION = YES;
+CLANG_WARN_INT_CONVERSION = YES;
+CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+CLANG_ENABLE_OBJC_ARC = YES;
+
+GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
+GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+GCC_WARN_ABOUT_RETURN_TYPE = YES;
+GCC_WARN_UNDECLARED_SELECTOR = YES;
+GCC_WARN_UNINITIALIZED_AUTOS = YES;
+GCC_WARN_UNUSED_FUNCTION = YES;
+GCC_WARN_UNUSED_VARIABLE = YES;
+
+WARNING_CFLAGS = -Wall -Wundef -Wformat-security -Wimplicit-fallthrough -Wmissing-format-attribute -Wpointer-arith -Wexit-time-destructors -Wglobal-constructors -Woverriding-method-mismatch -Wmethod-signatures;
+
+OTHER_CFLAGS = -iframework $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks $(inherited);
+
+ALWAYS_SEARCH_USER_PATHS = NO;
diff --git a/Tools/MobileMiniBrowser/Configurations/DebugRelease.xcconfig b/Tools/MobileMiniBrowser/Configurations/DebugRelease.xcconfig
new file mode 100644 (file)
index 0000000..998f198
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+#include "Base.xcconfig"
+
+ARCHS = $(ARCHS_STANDARD_32_64_BIT);
+
+ONLY_ACTIVE_ARCH = YES;
+
+GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES;
+
+SDKROOT = $(SDKROOT_$(PLATFORM_NAME));
+SDKROOT_iphoneos = $(SDKROOT);
+SDKROOT_iphonesimulator = $(SDKROOT);
diff --git a/Tools/MobileMiniBrowser/Configurations/MobileMiniBrowser.xcconfig b/Tools/MobileMiniBrowser/Configurations/MobileMiniBrowser.xcconfig
new file mode 100644 (file)
index 0000000..5117d63
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+//    notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+//    notice, this list of conditions and the following disclaimer in the
+//    documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+
+PRODUCT_NAME = MiniBrowser
+EXCLUDED_SOURCE_FILE_NAMES[sdk=macosx*] = *
diff --git a/Tools/MobileMiniBrowser/Makefile b/Tools/MobileMiniBrowser/Makefile
new file mode 100644 (file)
index 0000000..7a02f52
--- /dev/null
@@ -0,0 +1,12 @@
+
+SCRIPTS_PATH = ../Scripts
+include ../../Makefile.shared
+
+test-iphone: all
+       ( $(SET_COLOR_DIAGNOSTICS_ARG); xcodebuild $(OTHER_OPTIONS) $(XCODE_OPTIONS) -scheme MobileMiniBrowserUITests -destination 'platform=iOS Simulator,name=iPhone 5s For WebKit Development' test | $(OUTPUT_FILTER) && exit $${PIPESTATUS[0]} )
+
+test-ipad: all
+       ( $(SET_COLOR_DIAGNOSTICS_ARG); xcodebuild $(OTHER_OPTIONS) $(XCODE_OPTIONS) -scheme MobileMiniBrowserUITests -destination 'platform=iOS Simulator,name=iPad Retina' test | $(OUTPUT_FILTER) && exit $${PIPESTATUS[0]} )
+
+test: test-iphone test-ipad
+       
\ No newline at end of file
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser.xcodeproj/project.pbxproj b/Tools/MobileMiniBrowser/MobileMiniBrowser.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..930cb0a
--- /dev/null
@@ -0,0 +1,445 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 46;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               CD1DAF971D709E3600017CF0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CD1DAF961D709E3600017CF0 /* main.m */; };
+               CD1DAF9A1D709E3600017CF0 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CD1DAF991D709E3600017CF0 /* AppDelegate.m */; };
+               CD1DAFA01D709E3600017CF0 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD1DAF9E1D709E3600017CF0 /* Main.storyboard */; };
+               CD1DAFA21D709E3600017CF0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CD1DAFA11D709E3600017CF0 /* Assets.xcassets */; };
+               CD1DAFA51D709E3600017CF0 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CD1DAFA31D709E3600017CF0 /* LaunchScreen.storyboard */; };
+               CD1DAFB01D709E3600017CF0 /* MobileMiniBrowserUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = CD1DAFAF1D709E3600017CF0 /* MobileMiniBrowserUITests.m */; };
+               CD1DAFBE1D709EF200017CF0 /* TabViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD1DAFBB1D709EF200017CF0 /* TabViewController.m */; };
+               CD1DAFBF1D709EF200017CF0 /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CD1DAFBD1D709EF200017CF0 /* WebViewController.m */; };
+               CD1DAFC21D70E12D00017CF0 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD1DAFC11D70E12D00017CF0 /* WebKit.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+               CD1DAFAC1D709E3600017CF0 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = CD1DAF8A1D709E3600017CF0 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = CD1DAF911D709E3600017CF0;
+                       remoteInfo = MobileMiniBrowser;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+               CD1DAF921D709E3600017CF0 /* MobileMiniBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MobileMiniBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; };
+               CD1DAF961D709E3600017CF0 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+               CD1DAF981D709E3600017CF0 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+               CD1DAF991D709E3600017CF0 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+               CD1DAF9F1D709E3600017CF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+               CD1DAFA11D709E3600017CF0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+               CD1DAFA41D709E3600017CF0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
+               CD1DAFA61D709E3600017CF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               CD1DAFAB1D709E3600017CF0 /* MobileMiniBrowserUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MobileMiniBrowserUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+               CD1DAFAF1D709E3600017CF0 /* MobileMiniBrowserUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MobileMiniBrowserUITests.m; sourceTree = "<group>"; };
+               CD1DAFB11D709E3600017CF0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+               CD1DAFBA1D709EF200017CF0 /* TabViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TabViewController.h; sourceTree = "<group>"; };
+               CD1DAFBB1D709EF200017CF0 /* TabViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TabViewController.m; sourceTree = "<group>"; };
+               CD1DAFBC1D709EF200017CF0 /* WebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewController.h; sourceTree = "<group>"; };
+               CD1DAFBD1D709EF200017CF0 /* WebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewController.m; sourceTree = "<group>"; };
+               CD1DAFC11D70E12D00017CF0 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = "../../WebKitBuild/Debug-iphonesimulator/WebKit.framework"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               CD1DAF8F1D709E3600017CF0 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CD1DAFC21D70E12D00017CF0 /* WebKit.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CD1DAFA81D709E3600017CF0 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               CD1DAF891D709E3600017CF0 = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAF941D709E3600017CF0 /* MobileMiniBrowser */,
+                               CD1DAFAE1D709E3600017CF0 /* MobileMiniBrowserUITests */,
+                               CD1DAF931D709E3600017CF0 /* Products */,
+                               CD1DAFC01D70E12D00017CF0 /* Frameworks */,
+                       );
+                       sourceTree = "<group>";
+               };
+               CD1DAF931D709E3600017CF0 /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAF921D709E3600017CF0 /* MobileMiniBrowser.app */,
+                               CD1DAFAB1D709E3600017CF0 /* MobileMiniBrowserUITests.xctest */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               CD1DAF941D709E3600017CF0 /* MobileMiniBrowser */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAFBA1D709EF200017CF0 /* TabViewController.h */,
+                               CD1DAFBB1D709EF200017CF0 /* TabViewController.m */,
+                               CD1DAFBC1D709EF200017CF0 /* WebViewController.h */,
+                               CD1DAFBD1D709EF200017CF0 /* WebViewController.m */,
+                               CD1DAF981D709E3600017CF0 /* AppDelegate.h */,
+                               CD1DAF991D709E3600017CF0 /* AppDelegate.m */,
+                               CD1DAF9E1D709E3600017CF0 /* Main.storyboard */,
+                               CD1DAFA11D709E3600017CF0 /* Assets.xcassets */,
+                               CD1DAFA31D709E3600017CF0 /* LaunchScreen.storyboard */,
+                               CD1DAFA61D709E3600017CF0 /* Info.plist */,
+                               CD1DAF951D709E3600017CF0 /* Supporting Files */,
+                       );
+                       path = MobileMiniBrowser;
+                       sourceTree = "<group>";
+               };
+               CD1DAF951D709E3600017CF0 /* Supporting Files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAF961D709E3600017CF0 /* main.m */,
+                       );
+                       name = "Supporting Files";
+                       sourceTree = "<group>";
+               };
+               CD1DAFAE1D709E3600017CF0 /* MobileMiniBrowserUITests */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAFAF1D709E3600017CF0 /* MobileMiniBrowserUITests.m */,
+                               CD1DAFB11D709E3600017CF0 /* Info.plist */,
+                       );
+                       path = MobileMiniBrowserUITests;
+                       sourceTree = "<group>";
+               };
+               CD1DAFC01D70E12D00017CF0 /* Frameworks */ = {
+                       isa = PBXGroup;
+                       children = (
+                               CD1DAFC11D70E12D00017CF0 /* WebKit.framework */,
+                       );
+                       name = Frameworks;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+               CD1DAF911D709E3600017CF0 /* MobileMiniBrowser */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = CD1DAFB41D709E3600017CF0 /* Build configuration list for PBXNativeTarget "MobileMiniBrowser" */;
+                       buildPhases = (
+                               CD1DAF8E1D709E3600017CF0 /* Sources */,
+                               CD1DAF8F1D709E3600017CF0 /* Frameworks */,
+                               CD1DAF901D709E3600017CF0 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = MobileMiniBrowser;
+                       productName = MobileMiniBrowser;
+                       productReference = CD1DAF921D709E3600017CF0 /* MobileMiniBrowser.app */;
+                       productType = "com.apple.product-type.application";
+               };
+               CD1DAFAA1D709E3600017CF0 /* MobileMiniBrowserUITests */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = CD1DAFB71D709E3600017CF0 /* Build configuration list for PBXNativeTarget "MobileMiniBrowserUITests" */;
+                       buildPhases = (
+                               CD1DAFA71D709E3600017CF0 /* Sources */,
+                               CD1DAFA81D709E3600017CF0 /* Frameworks */,
+                               CD1DAFA91D709E3600017CF0 /* Resources */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                               CD1DAFAD1D709E3600017CF0 /* PBXTargetDependency */,
+                       );
+                       name = MobileMiniBrowserUITests;
+                       productName = MobileMiniBrowserUITests;
+                       productReference = CD1DAFAB1D709E3600017CF0 /* MobileMiniBrowserUITests.xctest */;
+                       productType = "com.apple.product-type.bundle.ui-testing";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               CD1DAF8A1D709E3600017CF0 /* Project object */ = {
+                       isa = PBXProject;
+                       attributes = {
+                               LastUpgradeCheck = 0800;
+                               ORGANIZATIONNAME = WebKit;
+                               TargetAttributes = {
+                                       CD1DAF911D709E3600017CF0 = {
+                                               CreatedOnToolsVersion = 8.0;
+                                               ProvisioningStyle = Automatic;
+                                       };
+                                       CD1DAFAA1D709E3600017CF0 = {
+                                               CreatedOnToolsVersion = 8.0;
+                                               ProvisioningStyle = Automatic;
+                                               TestTargetID = CD1DAF911D709E3600017CF0;
+                                       };
+                               };
+                       };
+                       buildConfigurationList = CD1DAF8D1D709E3600017CF0 /* Build configuration list for PBXProject "MobileMiniBrowser" */;
+                       compatibilityVersion = "Xcode 3.2";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 0;
+                       knownRegions = (
+                               en,
+                               Base,
+                       );
+                       mainGroup = CD1DAF891D709E3600017CF0;
+                       productRefGroup = CD1DAF931D709E3600017CF0 /* Products */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               CD1DAF911D709E3600017CF0 /* MobileMiniBrowser */,
+                               CD1DAFAA1D709E3600017CF0 /* MobileMiniBrowserUITests */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               CD1DAF901D709E3600017CF0 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CD1DAFA51D709E3600017CF0 /* LaunchScreen.storyboard in Resources */,
+                               CD1DAFA21D709E3600017CF0 /* Assets.xcassets in Resources */,
+                               CD1DAFA01D709E3600017CF0 /* Main.storyboard in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CD1DAFA91D709E3600017CF0 /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               CD1DAF8E1D709E3600017CF0 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CD1DAFBE1D709EF200017CF0 /* TabViewController.m in Sources */,
+                               CD1DAF9A1D709E3600017CF0 /* AppDelegate.m in Sources */,
+                               CD1DAF971D709E3600017CF0 /* main.m in Sources */,
+                               CD1DAFBF1D709EF200017CF0 /* WebViewController.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               CD1DAFA71D709E3600017CF0 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               CD1DAFB01D709E3600017CF0 /* MobileMiniBrowserUITests.m in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               CD1DAFAD1D709E3600017CF0 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = CD1DAF911D709E3600017CF0 /* MobileMiniBrowser */;
+                       targetProxy = CD1DAFAC1D709E3600017CF0 /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+               CD1DAF9E1D709E3600017CF0 /* Main.storyboard */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               CD1DAF9F1D709E3600017CF0 /* Base */,
+                       );
+                       name = Main.storyboard;
+                       sourceTree = "<group>";
+               };
+               CD1DAFA31D709E3600017CF0 /* LaunchScreen.storyboard */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               CD1DAFA41D709E3600017CF0 /* Base */,
+                       );
+                       name = LaunchScreen.storyboard;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               CD1DAFB21D709E3600017CF0 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_SUSPICIOUS_MOVES = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               ENABLE_TESTABILITY = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "DEBUG=1",
+                                       "$(inherited)",
+                               );
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+                               MTL_ENABLE_DEBUG_INFO = YES;
+                               ONLY_ACTIVE_ARCH = YES;
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                       };
+                       name = Debug;
+               };
+               CD1DAFB31D709E3600017CF0 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ALWAYS_SEARCH_USER_PATHS = NO;
+                               CLANG_ANALYZER_NONNULL = YES;
+                               CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+                               CLANG_CXX_LIBRARY = "libc++";
+                               CLANG_ENABLE_MODULES = YES;
+                               CLANG_ENABLE_OBJC_ARC = YES;
+                               CLANG_WARN_BOOL_CONVERSION = YES;
+                               CLANG_WARN_CONSTANT_CONVERSION = YES;
+                               CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+                               CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+                               CLANG_WARN_EMPTY_BODY = YES;
+                               CLANG_WARN_ENUM_CONVERSION = YES;
+                               CLANG_WARN_INFINITE_RECURSION = YES;
+                               CLANG_WARN_INT_CONVERSION = YES;
+                               CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+                               CLANG_WARN_SUSPICIOUS_MOVES = YES;
+                               CLANG_WARN_UNREACHABLE_CODE = YES;
+                               CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+                               "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+                               COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               ENABLE_NS_ASSERTIONS = NO;
+                               ENABLE_STRICT_OBJC_MSGSEND = YES;
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_NO_COMMON_BLOCKS = YES;
+                               GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+                               GCC_WARN_UNDECLARED_SELECTOR = YES;
+                               GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+                               GCC_WARN_UNUSED_FUNCTION = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+                               MTL_ENABLE_DEBUG_INFO = NO;
+                               SDKROOT = iphoneos;
+                               TARGETED_DEVICE_FAMILY = "1,2";
+                               VALIDATE_PRODUCT = YES;
+                       };
+                       name = Release;
+               };
+               CD1DAFB51D709E3600017CF0 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+                               INFOPLIST_FILE = MobileMiniBrowser/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+                               PRODUCT_BUNDLE_IDENTIFIER = org.webkit.MobileMiniBrowser;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               CD1DAFB61D709E3600017CF0 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+                               INFOPLIST_FILE = MobileMiniBrowser/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+                               PRODUCT_BUNDLE_IDENTIFIER = org.webkit.MobileMiniBrowser;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               CD1DAFB81D709E3600017CF0 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               INFOPLIST_FILE = MobileMiniBrowserUITests/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+                               PRODUCT_BUNDLE_IDENTIFIER = org.webkit.MobileMiniBrowserUITests;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               TEST_TARGET_NAME = MobileMiniBrowser;
+                       };
+                       name = Debug;
+               };
+               CD1DAFB91D709E3600017CF0 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               INFOPLIST_FILE = MobileMiniBrowserUITests/Info.plist;
+                               LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+                               PRODUCT_BUNDLE_IDENTIFIER = org.webkit.MobileMiniBrowserUITests;
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                               TEST_TARGET_NAME = MobileMiniBrowser;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               CD1DAF8D1D709E3600017CF0 /* Build configuration list for PBXProject "MobileMiniBrowser" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               CD1DAFB21D709E3600017CF0 /* Debug */,
+                               CD1DAFB31D709E3600017CF0 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               CD1DAFB41D709E3600017CF0 /* Build configuration list for PBXNativeTarget "MobileMiniBrowser" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               CD1DAFB51D709E3600017CF0 /* Debug */,
+                               CD1DAFB61D709E3600017CF0 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               CD1DAFB71D709E3600017CF0 /* Build configuration list for PBXNativeTarget "MobileMiniBrowserUITests" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               CD1DAFB81D709E3600017CF0 /* Debug */,
+                               CD1DAFB91D709E3600017CF0 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = CD1DAF8A1D709E3600017CF0 /* Project object */;
+}
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.h b/Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.h
new file mode 100644 (file)
index 0000000..030228a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property (strong, nonatomic) UIWindow *window;
+
+@end
+
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.m b/Tools/MobileMiniBrowser/MobileMiniBrowser/AppDelegate.m
new file mode 100644 (file)
index 0000000..7ef0577
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+    // Override point for customization after application launch.
+    return YES;
+}
+
+
+- (void)applicationWillResignActive:(UIApplication *)application
+{
+    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
+    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
+}
+
+
+- (void)applicationDidEnterBackground:(UIApplication *)application
+{
+    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
+    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
+}
+
+
+- (void)applicationWillEnterForeground:(UIApplication *)application
+{
+    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
+}
+
+
+- (void)applicationDidBecomeActive:(UIApplication *)application
+{
+    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
+}
+
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
+}
+
+
+@end
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json b/Tools/MobileMiniBrowser/MobileMiniBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644 (file)
index 0000000..1d060ed
--- /dev/null
@@ -0,0 +1,93 @@
+{
+  "images" : [
+    {
+      "idiom" : "iphone",
+      "size" : "20x20",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "20x20",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "29x29",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "40x40",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "iphone",
+      "size" : "60x60",
+      "scale" : "3x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "20x20",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "20x20",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "29x29",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "40x40",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "76x76",
+      "scale" : "2x"
+    },
+    {
+      "idiom" : "ipad",
+      "size" : "83.5x83.5",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/LaunchScreen.storyboard b/Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/LaunchScreen.storyboard
new file mode 100644 (file)
index 0000000..ac5e8ba
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11191" systemVersion="16A291" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11156"/>
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--View Controller-->
+        <scene sceneID="EHf-IW-A2E">
+            <objects>
+                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
+                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="9qo-7e-hd1">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F7I-Hn-oUR">
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="44" id="h95-xh-m8y"/>
+                                </constraints>
+                                <items>
+                                    <barButtonItem systemItem="rewind" id="8Pu-Rs-yse"/>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="doJ-Vc-vZ3"/>
+                                    <barButtonItem systemItem="refresh" id="bIK-RP-sM4"/>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="yOZ-bO-eX0"/>
+                                    <barButtonItem systemItem="fastForward" id="pex-sq-K9U"/>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="TNA-EK-FAX"/>
+                                    <barButtonItem title="Tabs" id="dXJ-Pm-BgJ"/>
+                                </items>
+                            </toolbar>
+                            <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Vg-6f-OBr" userLabel="URL Field Container">
+                                <subviews>
+                                    <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nX4-D6-AXV">
+                                        <items/>
+                                    </toolbar>
+                                    <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="L4i-oL-VFG">
+                                        <nil key="textColor"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                        <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" returnKeyType="go" enablesReturnKeyAutomatically="YES"/>
+                                    </textField>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1CE-0G-4aC">
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="45.999999999999886" id="Az8-yd-X45"/>
+                                        </constraints>
+                                        <state key="normal" title="Go"/>
+                                    </button>
+                                    <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vYP-Mc-B8q"/>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstItem="nX4-D6-AXV" firstAttribute="top" secondItem="7Vg-6f-OBr" secondAttribute="top" constant="-1" id="2rs-N5-Hdo"/>
+                                    <constraint firstItem="L4i-oL-VFG" firstAttribute="leading" secondItem="7Vg-6f-OBr" secondAttribute="leadingMargin" id="8OB-r0-Zz8"/>
+                                    <constraint firstItem="nX4-D6-AXV" firstAttribute="trailing" secondItem="7Vg-6f-OBr" secondAttribute="trailing" id="Ayk-kB-MMm"/>
+                                    <constraint firstItem="1CE-0G-4aC" firstAttribute="centerY" secondItem="7Vg-6f-OBr" secondAttribute="centerY" id="YJk-vh-AbN"/>
+                                    <constraint firstItem="vYP-Mc-B8q" firstAttribute="leading" secondItem="7Vg-6f-OBr" secondAttribute="leading" id="aUi-4X-ez0"/>
+                                    <constraint firstAttribute="bottom" secondItem="nX4-D6-AXV" secondAttribute="bottom" id="ahZ-0P-mR5"/>
+                                    <constraint firstItem="vYP-Mc-B8q" firstAttribute="trailing" secondItem="7Vg-6f-OBr" secondAttribute="trailing" id="bW0-cj-Sn2"/>
+                                    <constraint firstItem="nX4-D6-AXV" firstAttribute="leading" secondItem="7Vg-6f-OBr" secondAttribute="leading" id="geM-gQ-1Xr"/>
+                                    <constraint firstItem="vYP-Mc-B8q" firstAttribute="bottom" secondItem="7Vg-6f-OBr" secondAttribute="bottom" id="hdw-IM-B7w"/>
+                                    <constraint firstItem="L4i-oL-VFG" firstAttribute="trailing" secondItem="1CE-0G-4aC" secondAttribute="leading" constant="8" id="sUN-jB-d7h"/>
+                                    <constraint firstAttribute="height" constant="44" id="tlF-kP-qBq"/>
+                                    <constraint firstItem="L4i-oL-VFG" firstAttribute="centerY" secondItem="7Vg-6f-OBr" secondAttribute="centerY" id="vrH-km-glx"/>
+                                    <constraint firstItem="1CE-0G-4aC" firstAttribute="trailing" secondItem="7Vg-6f-OBr" secondAttribute="trailingMargin" id="zjV-TB-Nzc"/>
+                                </constraints>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="F7I-Hn-oUR" firstAttribute="top" secondItem="Llm-lL-Icb" secondAttribute="bottom" id="Dbb-TN-26g"/>
+                            <constraint firstItem="7Vg-6f-OBr" firstAttribute="leading" secondItem="9qo-7e-hd1" secondAttribute="leading" id="Qu5-yy-1EE"/>
+                            <constraint firstItem="7Vg-6f-OBr" firstAttribute="top" secondItem="F7I-Hn-oUR" secondAttribute="bottom" id="a8b-up-qV6"/>
+                            <constraint firstItem="F7I-Hn-oUR" firstAttribute="leading" secondItem="9qo-7e-hd1" secondAttribute="leading" id="kYr-Lz-btN"/>
+                            <constraint firstItem="F7I-Hn-oUR" firstAttribute="trailing" secondItem="9qo-7e-hd1" secondAttribute="trailing" id="kbK-WJ-Yez"/>
+                            <constraint firstItem="7Vg-6f-OBr" firstAttribute="trailing" secondItem="9qo-7e-hd1" secondAttribute="trailing" id="ks9-5c-50A"/>
+                        </constraints>
+                    </view>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="53" y="375"/>
+        </scene>
+    </scenes>
+</document>
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/Main.storyboard b/Tools/MobileMiniBrowser/MobileMiniBrowser/Base.lproj/Main.storyboard
new file mode 100644 (file)
index 0000000..0427a8d
--- /dev/null
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11191" systemVersion="16A291" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ohh-6U-lsQ">
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11156"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <scenes>
+        <!--Web View-->
+        <scene sceneID="hmw-yB-imE">
+            <objects>
+                <viewController storyboardIdentifier="idWebViewController" title="Web View" id="Ohh-6U-lsQ" customClass="WebViewController" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="O1S-Wg-hSL"/>
+                        <viewControllerLayoutGuide type="bottom" id="mUo-dB-Gut"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="1WJ-am-PnB">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SYm-x3-D12">
+                                <constraints>
+                                    <constraint firstAttribute="height" constant="44" id="0IC-RY-cRv"/>
+                                </constraints>
+                                <items>
+                                    <barButtonItem systemItem="rewind" id="EEz-Eu-Llp">
+                                        <connections>
+                                            <action selector="goBack:" destination="Ohh-6U-lsQ" id="yCS-m7-CSu"/>
+                                        </connections>
+                                    </barButtonItem>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="2hV-ik-Nst"/>
+                                    <barButtonItem systemItem="refresh" id="Qwd-Pc-zRG">
+                                        <connections>
+                                            <action selector="reload:" destination="Ohh-6U-lsQ" id="7fs-2o-7Vh"/>
+                                        </connections>
+                                    </barButtonItem>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="x6B-dk-wot"/>
+                                    <barButtonItem systemItem="fastForward" id="gRl-g5-HxZ">
+                                        <connections>
+                                            <action selector="goForward:" destination="Ohh-6U-lsQ" id="wXA-qv-wKE"/>
+                                        </connections>
+                                    </barButtonItem>
+                                    <barButtonItem style="plain" systemItem="flexibleSpace" id="Plg-UW-RO1"/>
+                                    <barButtonItem title="Tabs" id="riZ-ip-Qee">
+                                        <connections>
+                                            <action selector="showTabs:" destination="Ohh-6U-lsQ" id="ZZT-Jw-TR7"/>
+                                        </connections>
+                                    </barButtonItem>
+                                </items>
+                            </toolbar>
+                            <view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Wkd-K8-BC1" userLabel="URL Field Container">
+                                <subviews>
+                                    <toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SSg-5u-loI">
+                                        <items/>
+                                    </toolbar>
+                                    <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="n4f-v4-gO4">
+                                        <accessibility key="accessibilityConfiguration" identifier="idURLField" label="URL Field"/>
+                                        <nil key="textColor"/>
+                                        <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                                        <textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL" returnKeyType="go" enablesReturnKeyAutomatically="YES"/>
+                                        <connections>
+                                            <action selector="navigateTo:" destination="Ohh-6U-lsQ" eventType="primaryActionTriggered" id="rsS-Hh-pgq"/>
+                                            <action selector="urlFieldEditingBegan:" destination="Ohh-6U-lsQ" eventType="editingDidBegin" id="VDr-b6-Z9E"/>
+                                        </connections>
+                                    </textField>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qSw-Ym-IBE">
+                                        <accessibility key="accessibilityConfiguration" identifier="idGoToURL" label="Go To URL"/>
+                                        <constraints>
+                                            <constraint firstAttribute="width" constant="45.999999999999886" id="hr8-Tf-lDT"/>
+                                        </constraints>
+                                        <state key="normal" title="Go"/>
+                                        <connections>
+                                            <action selector="navigateTo:" destination="Ohh-6U-lsQ" eventType="touchUpInside" id="va2-3J-Gmh"/>
+                                        </connections>
+                                    </button>
+                                    <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="2bJ-bG-4SW"/>
+                                </subviews>
+                                <constraints>
+                                    <constraint firstItem="SSg-5u-loI" firstAttribute="trailing" secondItem="Wkd-K8-BC1" secondAttribute="trailing" id="6KS-dw-2cN"/>
+                                    <constraint firstItem="qSw-Ym-IBE" firstAttribute="top" secondItem="Wkd-K8-BC1" secondAttribute="top" constant="8" id="88d-RS-Chq"/>
+                                    <constraint firstItem="2bJ-bG-4SW" firstAttribute="bottom" secondItem="Wkd-K8-BC1" secondAttribute="bottom" id="DWe-kg-fd1"/>
+                                    <constraint firstItem="SSg-5u-loI" firstAttribute="bottom" secondItem="Wkd-K8-BC1" secondAttribute="bottom" id="H4E-pp-5hZ"/>
+                                    <constraint firstItem="qSw-Ym-IBE" firstAttribute="trailing" secondItem="Wkd-K8-BC1" secondAttribute="trailing" constant="-8.0000000000001137" id="I98-9l-yBo"/>
+                                    <constraint firstItem="n4f-v4-gO4" firstAttribute="trailing" secondItem="qSw-Ym-IBE" secondAttribute="leading" constant="-8" id="JVc-2x-zpB"/>
+                                    <constraint firstItem="2bJ-bG-4SW" firstAttribute="trailing" secondItem="Wkd-K8-BC1" secondAttribute="trailing" id="Ptf-aW-hFM"/>
+                                    <constraint firstItem="2bJ-bG-4SW" firstAttribute="leading" secondItem="Wkd-K8-BC1" secondAttribute="leading" id="Udl-4T-2r0"/>
+                                    <constraint firstItem="n4f-v4-gO4" firstAttribute="top" secondItem="Wkd-K8-BC1" secondAttribute="top" constant="7" id="ckp-l2-5Gm"/>
+                                    <constraint firstItem="n4f-v4-gO4" firstAttribute="leading" secondItem="Wkd-K8-BC1" secondAttribute="leading" constant="8" id="rdB-oq-lII"/>
+                                    <constraint firstItem="SSg-5u-loI" firstAttribute="leading" secondItem="Wkd-K8-BC1" secondAttribute="leading" id="t7A-Ip-cIN"/>
+                                    <constraint firstItem="SSg-5u-loI" firstAttribute="top" secondItem="Wkd-K8-BC1" secondAttribute="top" constant="-2" id="vxD-DZ-LSP"/>
+                                    <constraint firstAttribute="height" constant="44" id="zaj-6L-uzc"/>
+                                </constraints>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="719-Zt-fvZ" userLabel="Web View Container">
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <accessibility key="accessibilityConfiguration" label="Web View Container"/>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="Wkd-K8-BC1" firstAttribute="leading" secondItem="1WJ-am-PnB" secondAttribute="leading" id="2cZ-lB-Wel"/>
+                            <constraint firstItem="Wkd-K8-BC1" firstAttribute="trailing" secondItem="1WJ-am-PnB" secondAttribute="trailing" id="9PH-Z4-jms"/>
+                            <constraint firstItem="SYm-x3-D12" firstAttribute="leading" secondItem="719-Zt-fvZ" secondAttribute="leading" id="CVd-rC-DLK"/>
+                            <constraint firstItem="719-Zt-fvZ" firstAttribute="bottom" secondItem="mUo-dB-Gut" secondAttribute="top" id="TSf-qw-BSO"/>
+                            <constraint firstItem="719-Zt-fvZ" firstAttribute="trailing" secondItem="1WJ-am-PnB" secondAttribute="trailing" id="dli-wp-mIQ"/>
+                            <constraint firstItem="719-Zt-fvZ" firstAttribute="leading" secondItem="1WJ-am-PnB" secondAttribute="leading" id="drb-1d-e3b"/>
+                            <constraint firstItem="719-Zt-fvZ" firstAttribute="top" secondItem="Wkd-K8-BC1" secondAttribute="bottom" id="gTD-az-Bxc"/>
+                            <constraint firstItem="SYm-x3-D12" firstAttribute="trailing" secondItem="719-Zt-fvZ" secondAttribute="trailing" id="jnE-rM-ZkM"/>
+                            <constraint firstItem="Wkd-K8-BC1" firstAttribute="top" secondItem="SYm-x3-D12" secondAttribute="bottom" id="n1b-Z6-LbB"/>
+                            <constraint firstItem="SYm-x3-D12" firstAttribute="top" secondItem="O1S-Wg-hSL" secondAttribute="bottom" id="sSX-9p-jiJ"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="progressView" destination="2bJ-bG-4SW" id="epj-Uv-45U"/>
+                        <outlet property="tabButton" destination="riZ-ip-Qee" id="c25-vk-MxM"/>
+                        <outlet property="urlField" destination="n4f-v4-gO4" id="6y7-b7-P81"/>
+                        <outlet property="webViewContainer" destination="719-Zt-fvZ" id="UaF-fa-bAe"/>
+                        <segue destination="KyF-2k-9Cc" kind="popoverPresentation" identifier="TabPicker" popoverAnchorBarButtonItem="riZ-ip-Qee" id="XMx-lV-WXX">
+                            <popoverArrowDirection key="popoverArrowDirection" up="YES" down="YES" left="YES" right="YES"/>
+                        </segue>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="BYM-VV-HDr" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="748" y="-336.88155922038982"/>
+        </scene>
+        <!--Tab View Controller-->
+        <scene sceneID="aHE-jJ-oKr">
+            <objects>
+                <tableViewController storyboardIdentifier="idTabViewController" id="KyF-2k-9Cc" customClass="TabViewController" sceneMemberID="viewController">
+                    <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="Pid-8n-Ixq">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                        <prototypes>
+                            <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" restorationIdentifier="idTabViewCustomCell" selectionStyle="default" indentationWidth="10" id="Bxf-dM-uYf">
+                                <rect key="frame" x="0.0" y="28" width="375" height="44"/>
+                                <autoresizingMask key="autoresizingMask"/>
+                                <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Bxf-dM-uYf" id="lpb-yc-EJ5">
+                                    <frame key="frameInset" width="375" height="43.5"/>
+                                    <autoresizingMask key="autoresizingMask"/>
+                                </tableViewCellContentView>
+                            </tableViewCell>
+                        </prototypes>
+                        <connections>
+                            <outlet property="dataSource" destination="KyF-2k-9Cc" id="sCL-gS-Div"/>
+                            <outlet property="delegate" destination="KyF-2k-9Cc" id="nxb-Xb-9bW"/>
+                        </connections>
+                    </tableView>
+                </tableViewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="ZVi-NC-K5T" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="1480.8" y="-337.78110944527737"/>
+        </scene>
+    </scenes>
+</document>
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/Info.plist b/Tools/MobileMiniBrowser/MobileMiniBrowser/Info.plist
new file mode 100644 (file)
index 0000000..2414986
--- /dev/null
@@ -0,0 +1,55 @@
+<?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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>MiniBrowser</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>UILaunchStoryboardName</key>
+       <string>LaunchScreen</string>
+       <key>UIMainStoryboardFile</key>
+       <string>Main</string>
+       <key>UIRequiredDeviceCapabilities</key>
+       <array>
+               <string>armv7</string>
+       </array>
+       <key>UIStatusBarTintParameters</key>
+       <dict>
+               <key>UINavigationBar</key>
+               <dict>
+                       <key>Style</key>
+                       <string>UIBarStyleDefault</string>
+                       <key>Translucent</key>
+                       <false/>
+               </dict>
+       </dict>
+       <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>
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.h b/Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.h
new file mode 100644 (file)
index 0000000..d6a6f11
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <UIKit/UIKit.h>
+
+@class WKWebView;
+@class WebViewController;
+
+@interface TabViewController : UITableViewController
+
+@property (weak, nonatomic) WebViewController *parent;
+
+@end
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.m b/Tools/MobileMiniBrowser/MobileMiniBrowser/TabViewController.m
new file mode 100644 (file)
index 0000000..3c488bc
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "TabViewController.h"
+
+#import "WebViewController.h"
+#import <WebKit/WKWebView.h>
+
+void *ContentSizeContext = &ContentSizeContext;
+
+@implementation TabViewController
+
+- (void)dealloc
+{
+    [self.tableView removeObserver:self forKeyPath:@"contentSize" context:ContentSizeContext];
+}
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    [self.tableView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew context:ContentSizeContext];
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    if (context == ContentSizeContext)
+        self.preferredContentSize = CGSizeMake(self.preferredContentSize.width, self.tableView.contentSize.height);
+}
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    static NSString *MyIdentifier = @"MyReuseIdentifier";
+    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
+    if (!cell)
+        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:MyIdentifier];
+
+    if (indexPath.section == 1) {
+        cell.textLabel.text = @"New...";
+        return cell;
+    }
+
+    WKWebView *webView = [self.parent.webViews objectAtIndex:indexPath.row];
+    cell.textLabel.text = webView.title;
+    return cell;
+}
+
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    if (section == 1)
+        return 1;
+    return self.parent.webViews.count;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+    return 2;
+}
+
+- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return indexPath.section != 1;
+}
+
+- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    return NO;
+}
+
+- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    if (indexPath.section == 2)
+        return;
+
+    [self.parent removeWebViewAtIndex:indexPath.row];
+    [tableView reloadData];
+}
+
+- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
+{
+    if (indexPath.section == 1)
+        [self.parent addWebView];
+    else
+        [self.parent selectWebViewAtIndex:indexPath.row];
+    [self.parent dismissViewControllerAnimated:YES completion:nil];
+}
+
+@end
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.h b/Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.h
new file mode 100644 (file)
index 0000000..fdfc226
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <UIKit/UIKit.h>
+
+@class WKWebView;
+@class TabViewController;
+
+@interface WebViewController : UIViewController
+
+@property (strong, nonatomic) IBOutlet UIView *webViewContainer;
+@property (strong, nonatomic) IBOutlet UITextField *urlField;
+@property (strong, nonatomic) IBOutlet UIProgressView *progressView;
+@property (strong, nonatomic) IBOutlet UIBarButtonItem *tabButton;
+@property (strong, nonatomic) IBOutlet TabViewController *tabViewController;
+@property (strong, nonatomic) WKWebView *currentWebView;
+@property (strong, nonatomic) NSMutableArray<WKWebView *> *webViews;
+
+
+- (IBAction)reload:(id)sender;
+- (IBAction)goBack:(id)sender;
+- (IBAction)goForward:(id)sender;
+- (IBAction)urlFieldEditingBegan:(id)sender;
+- (IBAction)navigateTo:(id)sender;
+- (IBAction)showTabs:(id)sender;
+
+- (void)selectWebViewAtIndex:(NSUInteger)index;
+- (void)removeWebViewAtIndex:(NSUInteger)index;
+- (void)addWebView;
+
+@end
+
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.m b/Tools/MobileMiniBrowser/MobileMiniBrowser/WebViewController.m
new file mode 100644 (file)
index 0000000..fe47f66
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "config.h"
+#import "WebViewController.h"
+
+#import "TabViewController.h"
+#import <WebKit/WKNavigation.h>
+#import <WebKit/WKNavigationDelegate.h>
+#import <WebKit/WKWebView.h>
+#import <WebKit/WKWebViewConfiguration.h>
+
+@interface WebViewController () <WKNavigationDelegate> {
+    WKWebView *_currentWebView;
+}
+- (WKWebView *)createWebView;
+- (void)removeWebView:(WKWebView *)webView;
+- (void)setCurrentWebView:(WKWebView *)webView;
+@end
+
+void* EstimatedProgressContext = &EstimatedProgressContext;
+void* TitleContext = &TitleContext;
+void* URLContext = &URLContext;
+
+@implementation WebViewController
+
+- (void)viewDidLoad
+{
+    [super viewDidLoad];
+    self.webViews = [[NSMutableArray alloc] initWithCapacity:1];
+    self.tabViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"idTabViewController"];
+    self.tabViewController.parent = self;
+    self.tabViewController.modalPresentationStyle = UIModalPresentationPopover;
+
+    [self setCurrentWebView:[self createWebView]];
+}
+
+
+- (void)didReceiveMemoryWarning
+{
+    [super didReceiveMemoryWarning];
+}
+
+#pragma mark Actions
+
+- (IBAction)reload:(id)sender
+{
+    [self.currentWebView reload];
+}
+
+- (IBAction)goBack:(id)sender
+{
+    [self.currentWebView goBack];
+}
+
+- (IBAction)goForward:(id)sender
+{
+    [self.currentWebView goForward];
+}
+
+- (IBAction)urlFieldEditingBegan:(id)sender
+{
+    self.urlField.selectedTextRange = [self.urlField textRangeFromPosition:self.urlField.beginningOfDocument toPosition:self.urlField.endOfDocument];
+}
+
+- (IBAction)navigateTo:(id)sender
+{
+    [self.urlField resignFirstResponder];
+    NSString* requestedDestination = self.urlField.text;
+    if ([requestedDestination rangeOfString:@"^[\\p{Alphabetic}]+:" options:(NSRegularExpressionSearch | NSCaseInsensitiveSearch | NSAnchoredSearch)].location == NSNotFound)
+        requestedDestination = [@"http://" stringByAppendingString:requestedDestination];
+    [self.currentWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:requestedDestination]]];
+}
+
+- (IBAction)showTabs:(id)sender
+{
+    [self presentViewController:self.tabViewController animated:YES completion:^{ }];
+    self.tabViewController.popoverPresentationController.barButtonItem = self.tabButton;
+}
+
+#pragma mark Public methods
+
+@dynamic currentWebView;
+
+- (WKWebView *)currentWebView
+{
+    return _currentWebView;
+}
+
+- (void)setCurrentWebView:(WKWebView *)webView
+{
+    [_currentWebView removeObserver:self forKeyPath:@"estimatedProgress" context:EstimatedProgressContext];
+    [_currentWebView removeObserver:self forKeyPath:@"URL" context:URLContext];
+    [_currentWebView removeFromSuperview];
+
+    _currentWebView = webView;
+
+    [_currentWebView addObserver:self forKeyPath:@"estimatedProgress" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:EstimatedProgressContext];
+    [_currentWebView addObserver:self forKeyPath:@"URL" options:(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) context:URLContext];
+    [self.webViewContainer addSubview:_currentWebView];
+}
+
+- (void)selectWebViewAtIndex:(NSUInteger)index
+{
+    if (index >= self.webViews.count)
+        return;
+    self.currentWebView = self.webViews[index];
+}
+
+- (void)removeWebViewAtIndex:(NSUInteger)index
+{
+    if (index >= self.webViews.count)
+        return;
+    [self removeWebView:self.webViews[index]];
+}
+
+- (void)addWebView
+{
+    self.currentWebView = [self createWebView];
+}
+
+#pragma mark Internal methods
+
+- (WKWebView *)createWebView
+{
+    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
+    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.webViewContainer.bounds configuration:configuration];
+    webView.navigationDelegate = self;
+    webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+    [webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:TitleContext];
+    [self.webViews addObject:webView];
+
+    [self.tabViewController.tableView reloadData];
+
+    return webView;
+}
+
+- (void)removeWebView:(WKWebView *)webView
+{
+    NSUInteger index = [self.webViews indexOfObject:webView];
+    if (index != NSNotFound) {
+        [self.webViews[index] removeObserver:self forKeyPath:@"title" context:TitleContext];
+        [self.webViews removeObjectAtIndex:index];
+    } if (!self.webViews.count)
+        [self createWebView];
+    if (index >= self.webViews.count)
+        index = self.webViews.count - 1;
+    [self setCurrentWebView:self.webViews[index]];
+
+    [self.tabViewController.tableView reloadData];
+}
+
+#pragma mark Navigation Delegate
+
+- (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;
+{
+    [webView loadHTMLString:[error description] baseURL:nil];
+}
+
+#pragma mark KVO
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+    if (context == EstimatedProgressContext) {
+        float value = [[change valueForKey:NSKeyValueChangeNewKey] floatValue];
+        [self.progressView setProgress:value animated:YES];
+    } else if (context == URLContext) {
+        id newURLValue = [change valueForKey:NSKeyValueChangeNewKey];
+        if ([newURLValue isKindOfClass:[NSURL class]])
+            self.urlField.text = [newURLValue absoluteString];
+        else if ([newURLValue isKindOfClass:[NSNull class]])
+            self.urlField.text = @"";
+    } else if (context == TitleContext)
+        [self.tabViewController.tableView reloadData];
+    else
+        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
+}
+
+@end
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowser/main.m b/Tools/MobileMiniBrowser/MobileMiniBrowser/main.m
new file mode 100644 (file)
index 0000000..f8aa61d
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "AppDelegate.h"
+#import <UIKit/UIKit.h>
+
+int main(int argc, char * argv[])
+{
+    @autoreleasepool {
+        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+    }
+}
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowserUITests/Info.plist b/Tools/MobileMiniBrowser/MobileMiniBrowserUITests/Info.plist
new file mode 100644 (file)
index 0000000..6c6c23c
--- /dev/null
@@ -0,0 +1,22 @@
+<?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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>$(PRODUCT_NAME)</string>
+       <key>CFBundlePackageType</key>
+       <string>BNDL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+</dict>
+</plist>
diff --git a/Tools/MobileMiniBrowser/MobileMiniBrowserUITests/MobileMiniBrowserUITests.m b/Tools/MobileMiniBrowser/MobileMiniBrowserUITests/MobileMiniBrowserUITests.m
new file mode 100644 (file)
index 0000000..81d209d
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <XCTest/XCTest.h>
+#import <XCTest/XCUIRemote.h>
+
+@interface MobileMiniBrowserUITests : XCTestCase
+
+@end
+
+@implementation MobileMiniBrowserUITests
+
+- (void)setUp
+{
+    [super setUp];
+
+    self.continueAfterFailure = NO;
+
+    XCUIApplication *app = [[XCUIApplication alloc] init];
+    [app launch];
+}
+
+- (void)tearDown
+{
+    [super tearDown];
+}
+
+- (void)testBasicVideoPlayback
+{
+    XCUIApplication *app = [[XCUIApplication alloc] init];
+    NSPredicate *exists = [NSPredicate predicateWithFormat:@"exists == 1"];
+
+    XCUIElement *urlField = app.textFields[@"URL Field"];
+    [self expectationForPredicate:exists evaluatedWithObject:urlField handler:nil];
+    [self waitForExpectationsWithTimeout:5.0 handler:nil];
+    [urlField tap];
+
+    XCUIElement *clearButton = urlField.buttons[@"Clear text"];
+    if (clearButton.exists)
+        [clearButton tap];
+    [urlField typeText:@"http://test-safari.apple.com/"];
+    [app.buttons[@"Go To URL"] tap];
+
+    XCUIElement *captions = app.links[@"Captions"];
+    [self expectationForPredicate:exists evaluatedWithObject:captions handler:nil];
+    [self waitForExpectationsWithTimeout:5.0 handler:nil];
+    [captions tap];
+
+    XCUIElement *viewInPage = app.links[@"Video in page"];
+    [self expectationForPredicate:exists evaluatedWithObject:viewInPage handler:nil];
+    [self waitForExpectationsWithTimeout:5.0 handler:nil];
+    [viewInPage tap];
+
+    XCUIElement *startPlayback = app.buttons[@"Start Playback"];
+    [self expectationForPredicate:exists evaluatedWithObject:startPlayback handler:nil];
+    [self waitForExpectationsWithTimeout:5.0 handler:nil];
+    [startPlayback tap];
+
+    UIUserInterfaceIdiom idiom = UI_USER_INTERFACE_IDIOM();
+    if (idiom == UIUserInterfaceIdiomPhone) {
+        XCUIElement *pauseButton = app.buttons[@"PauseButton"];
+        [self expectationForPredicate:exists evaluatedWithObject:pauseButton handler:nil];
+        [self waitForExpectationsWithTimeout:5.0 handler:nil];
+        [pauseButton tap];
+
+        XCUIElement *doneButton = app.buttons[@"Done"];
+        [self expectationForPredicate:exists evaluatedWithObject:doneButton handler:nil];
+        [self waitForExpectationsWithTimeout:5.0 handler:nil];
+        [doneButton tap];
+    } else if (idiom == UIUserInterfaceIdiomPad) {
+        XCUIElement *pauseButton = app.buttons[@"Pause"];
+        [self expectationForPredicate:exists evaluatedWithObject:pauseButton handler:nil];
+        [self waitForExpectationsWithTimeout:5.0 handler:nil];
+        [pauseButton tap];
+    }
+}
+
+@end
index 5353ec3..ef8802b 100644 (file)
@@ -35,6 +35,9 @@
       location = "group:Tools/MiniBrowser/MiniBrowser.xcodeproj">
    </FileRef>
    <FileRef
+      location = "group:Tools/MobileMiniBrowser/MobileMiniBrowser.xcodeproj">
+   </FileRef>
+   <FileRef
       location = "group:Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj">
    </FileRef>
    <FileRef