#1270 (replacing UIWebView with WKWebView)

- All app-specific uses of UIWebView have been replaced with WKWebView.
- Some third-party uses remain.
- More testing required.
- Note that I’ve bumped the minimum iOS version to iOS 11, since that is needed for WKWebView support.
- Committing to a new branch until ready.
This commit is contained in:
David Sinclair 2020-02-23 15:21:32 -08:00 committed by Samuel Clay
parent 31451b1093
commit a6aeba2619
20 changed files with 400 additions and 564 deletions

View file

@ -7,10 +7,11 @@
//
#import <UIKit/UIKit.h>
@import WebKit;
@class NewsBlurAppDelegate;
@interface AuthorizeServicesViewController : UIViewController <UIWebViewDelegate> {
@interface AuthorizeServicesViewController : UIViewController <WKNavigationDelegate> {
NewsBlurAppDelegate *appDelegate;
NSString *url;
NSString *type;
@ -22,7 +23,7 @@
@property (nonatomic) NSString *type;
@property (nonatomic, readwrite) BOOL fromStory;
@property (weak, nonatomic) IBOutlet UIWebView *webView;
@property (weak, nonatomic) IBOutlet WKWebView *webView;
- (void)doCancelButton;
- (void)showError:(NSString *)error;

View file

@ -33,7 +33,6 @@
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.appDelegate = (NewsBlurAppDelegate *)[[UIApplication sharedApplication] delegate];
self.webView.delegate = self;
}
- (void)viewDidUnload {
@ -53,11 +52,14 @@
} else if ([type isEqualToString:@"twitter"]) {
self.navigationItem.title = @"Twitter";
}
NSString *urlAddress = [NSString stringWithFormat:@"%@%@", self.appDelegate.url, url];
NSURL *fullUrl = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:fullUrl];
[self.webView loadRequest:requestObj];
[self.appDelegate prepareWebView:self.webView completionHandler:^{
NSString *urlAddress = [NSString stringWithFormat:@"%@%@", self.appDelegate.url, url];
NSURL *fullUrl = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:fullUrl];
[self.webView loadRequest:requestObj];
}];
if (self.fromStory && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc]
initWithTitle: @"Cancel"
@ -79,51 +81,49 @@
[appDelegate.modalNavigationController dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSString *URLString = [[request URL] absoluteString];
NSLog(@"URL STRING IS %@", URLString);
// Look at the host & path to cope with http:// or https:// schemes
if ([request.URL.host isEqualToString:self.appDelegate.host] && [request.URL.path isEqualToString:@"/"]) {
NSString *error = [self.webView stringByEvaluatingJavaScriptFromString:@"NEWSBLUR.error"];
if (self.fromStory) {
[appDelegate refreshUserProfile:^{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[appDelegate.shareNavigationController viewWillAppear:YES];
[appDelegate.modalNavigationController dismissViewControllerAnimated:YES completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}];
} else {
[self.navigationController popViewControllerAnimated:YES];
if ([type isEqualToString:@"facebook"]) {
if (error.length) {
[self showError:error];
} else {
[appDelegate.firstTimeUserAddFriendsViewController selectFacebookButton];
}
} else if ([type isEqualToString:@"twitter"]) {
if (error.length) {
[self showError:error];
} else {
[appDelegate.firstTimeUserAddFriendsViewController selectTwitterButton];
[self.webView evaluateJavaScript:@"NEWSBLUR.error" completionHandler:^(id result, NSError *error) {
NSString *errorString = result;
if (self.fromStory) {
[appDelegate refreshUserProfile:^{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
[appDelegate.shareNavigationController viewWillAppear:YES];
[appDelegate.modalNavigationController dismissViewControllerAnimated:YES completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
}];
} else {
[self.navigationController popViewControllerAnimated:YES];
if ([type isEqualToString:@"facebook"]) {
if (errorString.length) {
[self showError:errorString];
} else {
[appDelegate.firstTimeUserAddFriendsViewController selectFacebookButton];
}
} else if ([type isEqualToString:@"twitter"]) {
if (errorString.length) {
[self showError:errorString];
} else {
[appDelegate.firstTimeUserAddFriendsViewController selectTwitterButton];
}
}
}
}
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
}];
return;
}
// // for failed google reader authorization
// if ([URLString hasPrefix:[NSString stringWithFormat:@"%@/import/callback", self.appDelegate.url]]) {
// [self.navigationController popViewControllerAnimated:YES];
// [appDelegate.firstTimeUserAddSitesViewController importFromGoogleReaderFailed];
// return NO;
// }
return YES;
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)showError:(NSString *)error {

View file

@ -1,169 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11E53</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.47</string>
<string key="IBDocument.HIToolboxVersion">569.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1181</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIView</string>
<string>IBUIWebView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIWebView" id="464701441">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">1</int>
<bytes key="NSRGB">MSAxIDEAA</bytes>
</object>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<int key="IBUIDataDetectorTypes">1</int>
<bool key="IBUIDetectsPhoneNumbers">YES</bool>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="464701441"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">webView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="464701441"/>
</object>
<int key="connectionID">5</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="464701441"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">4</int>
<reference key="object" ref="464701441"/>
<reference key="parent" ref="191373211"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">AuthorizeServicesViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="4.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">5</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">AuthorizeServicesViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">webView</string>
<string key="NS.object.0">UIWebView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">webView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">webView</string>
<string key="candidateClassName">UIWebView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/AuthorizeServicesViewController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1181</string>
</data>
</archive>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AuthorizeServicesViewController">
<connections>
<outlet property="view" destination="1" id="3"/>
<outlet property="webView" destination="8UG-TA-0d6" id="Opa-nd-RBg"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="1">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="8UG-TA-0d6">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<wkWebViewConfiguration key="configuration">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
<wkPreferences key="preferences"/>
</wkWebViewConfiguration>
</wkWebView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="8UG-TA-0d6" secondAttribute="trailing" id="0fo-lT-jLv"/>
<constraint firstItem="8UG-TA-0d6" firstAttribute="top" secondItem="1" secondAttribute="top" id="GZ6-CK-IVu"/>
<constraint firstItem="8UG-TA-0d6" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="HyD-aX-iiL"/>
<constraint firstAttribute="bottom" secondItem="8UG-TA-0d6" secondAttribute="bottom" id="I22-f0-3Fi"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-441" y="53"/>
</view>
</objects>
</document>

View file

@ -15,12 +15,11 @@
@class FeedbackModule;
@class FeedDetailViewController;
@interface DashboardViewController : UIViewController <UIPopoverControllerDelegate, UIWebViewDelegate> {
@interface DashboardViewController : UIViewController <UIPopoverControllerDelegate> {
NewsBlurAppDelegate *appDelegate;
InteractionsModule *interactionsModule;
ActivityModule *activitiesModule;
FeedDetailViewController *storiesModule;
UIWebView *feedbackWebView;
UIToolbar *toolbar;
NBDashboardNavigationBar *topToolbar;
UISegmentedControl *segmentedButton;
@ -30,7 +29,6 @@
@property (nonatomic) IBOutlet InteractionsModule *interactionsModule;
@property (nonatomic) IBOutlet ActivityModule *activitiesModule;
@property (nonatomic) IBOutlet FeedDetailViewController *storiesModule;
@property (nonatomic) IBOutlet UIWebView *feedbackWebView;
@property (nonatomic) IBOutlet NBDashboardNavigationBar *topToolbar;
@property (nonatomic) IBOutlet UIToolbar *toolbar;

View file

@ -16,15 +16,12 @@
#import "StoriesCollection.h"
#import "UISearchBar+Field.h"
#define FEEDBACK_URL @"http://www.newsblur.com/about"
@implementation DashboardViewController
@synthesize appDelegate;
@synthesize interactionsModule;
@synthesize activitiesModule;
@synthesize storiesModule;
@synthesize feedbackWebView;
@synthesize topToolbar;
@synthesize toolbar;
@synthesize segmentedButton;
@ -47,26 +44,13 @@
self.interactionsModule.hidden = NO;
}
self.activitiesModule.hidden = YES;
self.feedbackWebView.hidden = YES;
self.feedbackWebView.delegate = self;
self.segmentedButton.selectedSegmentIndex = 0;
// preload feedback
self.feedbackWebView.scalesPageToFit = YES;
[self.segmentedButton
setTitleTextAttributes:@{NSFontAttributeName:
[UIFont fontWithName:@"Helvetica-Bold" size:11.0f]}
forState:UIControlStateNormal];
NSString *urlAddress = FEEDBACK_URL;
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[self.feedbackWebView loadRequest:requestObj];
CGRect topToolbarFrame = self.topToolbar.frame;
topToolbarFrame.size.height += 20;
self.topToolbar.frame = topToolbarFrame;
@ -215,19 +199,4 @@
[self.activitiesModule fetchActivitiesDetail:1];
}
# pragma mark
# pragma mark Feedback
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSString *urlString = [NSString stringWithFormat:@"%@", url];
if ([urlString isEqualToString: FEEDBACK_URL]){
return YES;
} else {
return NO;
}
}
@end

View file

@ -10,7 +10,7 @@
#import "NewsBlurAppDelegate.h"
@interface FirstTimeUserAddFriendsViewController : BaseViewController <UIWebViewDelegate> {
@interface FirstTimeUserAddFriendsViewController : BaseViewController {
NewsBlurAppDelegate *appDelegate;
}

View file

@ -52,6 +52,7 @@
@class PINCache;
@class PremiumManager;
@class PremiumViewController;
@class WKWebView;
@interface NewsBlurAppDelegate : BaseViewController
<UIApplicationDelegate, UINavigationControllerDelegate, UIPopoverPresentationControllerDelegate,
@ -207,6 +208,7 @@ SFSafariViewControllerDelegate> {
@property (nonatomic, readonly) NSString *url;
@property (nonatomic, readonly) NSString *host;
@property (nonatomic, readonly) NSHTTPCookie *sessionIdCookie;
@property (readwrite) NSString * activeUsername;
@property (readwrite) NSString * activeUserProfileId;
@property (readwrite) NSString * activeUserProfileName;
@ -354,6 +356,8 @@ SFSafariViewControllerDelegate> {
success:(SEL)success
failure:(SEL)failure;
- (void)prepareWebView:(WKWebView *)webView completionHandler:(void (^)(void))completion;
- (void)loadFolder:(NSString *)folder feedID:(NSString *)feedIdStr;
- (void)reloadFeedsView:(BOOL)showLoader;
- (void)setTitle:(NSString *)title;

View file

@ -1430,6 +1430,29 @@
}];
}
- (NSHTTPCookie *)sessionIdCookie {
NSURL *url = [NSURL URLWithString:self.url];
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL: url];
for (NSHTTPCookie *cookie in cookies) {
if ([cookie.name isEqualToString:@"newsblur_sessionid"]) {
return cookie;
}
}
return nil;
}
- (void)prepareWebView:(WKWebView *)webView completionHandler:(void (^)(void))completion {
NSHTTPCookie *cookie = self.sessionIdCookie;
if (cookie != nil) {
[webView.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:completion];
} else {
completion();
}
}
#pragma mark -
- (void)loadFolder:(NSString *)folder feedID:(NSString *)feedIdStr {
@ -1887,7 +1910,7 @@
}
- (void)adjustStoryDetailWebView {
// change UIWebView
// change the web view
[storyPageControl.currentPage changeWebViewWidth];
[storyPageControl.nextPage changeWebViewWidth];
[storyPageControl.previousPage changeWebViewWidth];
@ -2125,7 +2148,9 @@
}
- (void)showSafariViewControllerWithURL:(NSURL *)url useReader:(BOOL)useReader {
self.safariViewController = [[SFSafariViewController alloc] initWithURL:url entersReaderIfAvailable:useReader];
SFSafariViewControllerConfiguration *config = [SFSafariViewControllerConfiguration new];
config.entersReaderIfAvailable = useReader;
self.safariViewController = [[SFSafariViewController alloc] initWithURL:url configuration:config];
self.safariViewController.delegate = self;
[self.storyPageControl setNavigationBarHidden:NO];
[navigationController presentViewController:self.safariViewController animated:YES completion:nil];

View file

@ -9,18 +9,19 @@
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "BaseViewController.h"
@import WebKit;
@class NewsBlurAppDelegate;
@interface StoryDetailViewController : BaseViewController
<UIScrollViewDelegate, UIGestureRecognizerDelegate,
UIActionSheetDelegate> {
UIActionSheetDelegate, WKNavigationDelegate> {
NewsBlurAppDelegate *appDelegate;
NSString *activeStoryId;
NSMutableDictionary *activeStory;
UIView *innerView;
UIWebView *webView;
WKWebView *webView;
NSInteger pageIndex;
BOOL pullingScrollview;
BOOL inTextView;
@ -37,7 +38,7 @@ UIActionSheetDelegate> {
@property (nonatomic) NSString *activeStoryId;
@property (nonatomic, readwrite) NSMutableDictionary *activeStory;
@property (nonatomic) IBOutlet UIView *innerView;
@property (nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic) IBOutlet WKWebView *webView;
@property (nonatomic) IBOutlet UIView *feedTitleGradient;
@property (nonatomic) IBOutlet UIView *noStoryMessage;
@property (nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;

View file

@ -24,7 +24,6 @@
#import "SBJson4.h"
#import "StringHelper.h"
#import "StoriesCollection.h"
#import "UIWebView+Offsets.h"
#import "UIView+ViewController.h"
#import "JNWThrottledBlock.h"
@ -77,7 +76,8 @@
[audioSession setCategory:AVAudioSessionCategoryPlayback
error:nil];
self.webView.scalesPageToFit = YES;
self.webView.navigationDelegate = self;
// self.webView.scalesPageToFit = YES;
self.webView.allowsLinkPreview = YES;
// self.webView.multipleTouchEnabled = NO;
@ -97,6 +97,7 @@
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
[self.appDelegate prepareWebView:self.webView completionHandler:nil];
[self clearWebView];
// UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc]
@ -148,19 +149,12 @@
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// NSLog(@"Gesture: %d - %d", (unsigned long)touch.tapCount, gestureRecognizer.state);
// NSLog(@"%@: taps: %@, state: %@", gestureRecognizer.class, @(touch.tapCount), @(gestureRecognizer.state));
inDoubleTap = (touch.tapCount == 2);
CGPoint pt = [self pointForGesture:gestureRecognizer];
if (pt.x == CGPointZero.x && pt.y == CGPointZero.y) return YES;
// NSLog(@"Tapped point: %@", NSStringFromCGPoint(pt));
NSString *tagName = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');",
(long)pt.x,(long)pt.y]];
if ([tagName isEqualToString:@"IMG"] && !inDoubleTap) {
return NO;
}
if (inDoubleTap) {
self.webView.scrollView.scrollEnabled = NO;
@ -182,31 +176,27 @@
if (gestureRecognizer.state == UIGestureRecognizerStateEnded && gestureRecognizer.numberOfTouches == 1 && appDelegate.storyPageControl.autoscrollAvailable && self.presentedViewController == nil) {
CGPoint pt = [self pointForGesture:gestureRecognizer];
if (pt.x == CGPointZero.x && pt.y == CGPointZero.y) return;
if (inDoubleTap) return;
// NSLog(@"Tapped point: %@", NSStringFromCGPoint(pt));
NSString *tagName = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');",
(long)pt.x,(long)pt.y]];
// Special case to handle the story title, Train, Save, and Share buttons.
if ([tagName isEqualToString:@"DIV"]) {
NSString *identifier = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'id');",
(long)pt.x,(long)pt.y]];
NSString *outerHTML = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'outerHTML');",
(long)pt.x,(long)pt.y]];
if (![identifier isEqualToString:@"NB-story"] && [outerHTML containsString:@"NB-"]) {
tagName = @"A";
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *tagName, NSError *error) {
// Special case to handle the story title, Train, Save, and Share buttons.
if ([tagName isEqualToString:@"DIV"]) {
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'id');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *identifier, NSError *error) {
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'outerHTML');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *outerHTML, NSError *error) {
if ([identifier isEqualToString:@"NB-story"] || ![outerHTML containsString:@"NB-"]) {
[appDelegate.storyPageControl showAutoscrollBriefly:YES];
}
}];
}];
return;
}
}
// Ignore links, videos, and iframes (e.g. embedded YouTube videos).
if (!inDoubleTap && ![@[@"A", @"VIDEO", @"IFRAME"] containsObject:tagName]) {
[appDelegate.storyPageControl showAutoscrollBriefly:YES];
}
// [self tapImage:gestureRecognizer];
// Ignore links, videos, and iframes (e.g. embedded YouTube videos).
if (![@[@"A", @"VIDEO", @"IFRAME"] containsObject:tagName]) {
[appDelegate.storyPageControl showAutoscrollBriefly:YES];
}
}];
}
}
@ -598,8 +588,8 @@
dispatch_async(dispatch_get_main_queue(), ^{
// NSLog(@"Drawing Story: %@", [self.activeStory objectForKey:@"story_title"]);
[self.webView setMediaPlaybackRequiresUserAction:NO];
self.webView.allowsInlineMediaPlayback = YES;
// [self.webView setMediaPlaybackRequiresUserAction:NO];
// self.webView.allowsInlineMediaPlayback = YES;
[self loadHTMLString:htmlTopAndBottom];
[self.appDelegate.storyPageControl setTextButton:self];
});
@ -1549,9 +1539,8 @@
}
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSURL *url = [request URL];
NSArray *urlComponents = [url pathComponents];
NSString *action = @"";
@ -1612,7 +1601,8 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
if (appDelegate.activeComment == nil) {
NSLog(@"PROBLEM! the active comment was not found in friend or public comments");
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
if ([action isEqualToString:@"reply"]) {
@ -1635,7 +1625,8 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
} else if ([action isEqualToString:@"unlike-comment"]) {
[self toggleLikeComment:NO];
}
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"togglechanges"]) {
if (self.activeStory[@"story_changes"] != nil) {
[self.activeStory removeObjectForKey:@"story_changes"];
@ -1643,16 +1634,19 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
} else {
[self fetchStoryChanges];
}
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"share"]) {
[self openShareDialog];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"train"] && [urlComponents count] > 5) {
[self openTrainingDialog:[[urlComponents objectAtIndex:2] intValue]
yCoordinate:[[urlComponents objectAtIndex:3] intValue]
width:[[urlComponents objectAtIndex:4] intValue]
height:[[urlComponents objectAtIndex:5] intValue]];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"save"]) {
BOOL isSaved = [appDelegate.storiesCollection toggleStorySaved:self.activeStory];
if (isSaved) {
@ -1661,24 +1655,29 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
width:[[urlComponents objectAtIndex:5] intValue]
height:[[urlComponents objectAtIndex:6] intValue]];
}
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"remove-user-tag"] || [action isEqualToString:@"add-user-tag"]) {
[self openUserTagsDialog:[[urlComponents objectAtIndex:3] intValue]
yCoordinate:[[urlComponents objectAtIndex:4] intValue]
width:[[urlComponents objectAtIndex:5] intValue]
height:[[urlComponents objectAtIndex:6] intValue]];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"classify-author"]) {
NSString *author = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleAuthorClassifier:author feedId:feedId];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"classify-tag"]) {
NSString *tag = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleTagClassifier:tag feedId:feedId];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"premium"]) {
[self.appDelegate showPremiumDialog];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"show-profile"] && [urlComponents count] > 6) {
appDelegate.activeUserProfileId = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
@ -1696,24 +1695,31 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
yCoordinate:[[urlComponents objectAtIndex:4] intValue]
width:[[urlComponents objectAtIndex:5] intValue]
height:[[urlComponents objectAtIndex:6] intValue]];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
} else if ([action isEqualToString:@"notify-loaded"]) {
[self webViewNotifyLoaded];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
} else if ([url.host hasSuffix:@"itunes.apple.com"]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {
// NSLog(@"Link clicked, views: %@ = %@", appDelegate.navigationController.topViewController, appDelegate.masterContainerViewController.childViewControllers);
if (appDelegate.isPresentingActivities) return NO;
if (appDelegate.isPresentingActivities) {
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
[appDelegate showOriginalStory:url];
return NO;
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
return YES;
decisionHandler(WKNavigationActionPolicyAllow);
}
- (void)showOriginalStory:(UIGestureRecognizer *)gesture {
@ -1769,7 +1775,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
[appDelegate showUserProfileModal:[NSValue valueWithCGRect:frame]];
}
- (void)webViewDidStartLoad:(UIWebView *)webView {
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
if (!self.hasStory) // other Web page loads aren't visible
return;
@ -1777,10 +1783,10 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
NSUserDefaults *userPreferences = [NSUserDefaults standardUserDefaults];
[self changeFontSize:[userPreferences stringForKey:@"story_font_size"]];
[self changeLineSpacing:[userPreferences stringForKey:@"story_line_spacing"]];
[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitTouchCallout='none';"];
[self.webView evaluateJavaScript:@"document.body.style.webkitTouchCallout='none';" completionHandler:nil];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
[self loadStory];
}
@ -1824,12 +1830,12 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
[appDelegate.tryFeedCategory isEqualToString:@"comment_reply"]) {
NSString *currentUserId = [NSString stringWithFormat:@"%@", [appDelegate.dictSocialProfile objectForKey:@"user_id"]];
NSString *jsFlashString = [[NSString alloc] initWithFormat:@"slideToComment('%@', true, true);", currentUserId];
[self.webView stringByEvaluatingJavaScriptFromString:jsFlashString];
[self.webView evaluateJavaScript:jsFlashString completionHandler:nil];
} else if ([appDelegate.tryFeedCategory isEqualToString:@"story_reshare"] ||
[appDelegate.tryFeedCategory isEqualToString:@"reply_reply"]) {
NSString *blurblogUserId = [NSString stringWithFormat:@"%@", [self.activeStory objectForKey:@"social_user_id"]];
NSString *jsFlashString = [[NSString alloc] initWithFormat:@"slideToComment('%@', true, true);", blurblogUserId];
[self.webView stringByEvaluatingJavaScriptFromString:jsFlashString];
[self.webView evaluateJavaScript:jsFlashString completionHandler:nil];
}
appDelegate.tryFeedCategory = nil;
}
@ -1846,7 +1852,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
"document.getElementById('NB-font-style').setAttribute('class', '%@')",
fontStyle];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
if (![fontStyle hasPrefix:@"NB-"]) {
jsString = [NSString stringWithFormat:@
@ -1856,28 +1862,28 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
jsString = @"document.getElementById('NB-font-style').setAttribute('style', '')";
}
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
}
- (void)changeFontSize:(NSString *)fontSize {
NSString *jsString = [[NSString alloc] initWithFormat:@"document.getElementById('NB-font-size').setAttribute('class', 'NB-%@')",
fontSize];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
}
- (void)changeLineSpacing:(NSString *)lineSpacing {
NSString *jsString = [[NSString alloc] initWithFormat:@"document.getElementById('NB-line-spacing').setAttribute('class', 'NB-line-spacing-%@')",
lineSpacing];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
}
- (void)updateStoryTheme {
NSString *jsString = [NSString stringWithFormat:@"document.getElementById('NB-theme-style').href='storyDetailView%@.css';",
[ThemeManager themeManager].themeCSSSuffix];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
self.webView.backgroundColor = UIColorFromLightDarkRGB(0x707070, 0x404040);
}
@ -2049,91 +2055,82 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
CGPoint pt = [self pointForGesture:gestureRecognizer];
if (pt.x == CGPointZero.x && pt.y == CGPointZero.y) return;
// NSLog(@"Tapped point: %@", NSStringFromCGPoint(pt));
NSString *tagName = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');",
(long)pt.x,(long)pt.y]];
if ([tagName isEqualToString:@"IMG"]) {
[self showImageMenu:pt];
[gestureRecognizer setEnabled:NO];
[gestureRecognizer setEnabled:YES];
}
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *tagName, NSError *error) {
if ([tagName isEqualToString:@"IMG"]) {
[self showImageMenu:pt];
[gestureRecognizer setEnabled:NO];
[gestureRecognizer setEnabled:YES];
}
}];
}
- (void)tapAndHold:(NSNotification*)notification {
CGPoint pt = [self pointForEvent:notification];
if (pt.x == CGPointZero.x && pt.y == CGPointZero.y) return;
NSString *tagName = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');",
(long)pt.x,(long)pt.y]];
if ([tagName isEqualToString:@"IMG"]) {
[self showImageMenu:pt];
}
if ([tagName isEqualToString:@"A"]) {
// [self showLinkContextMenu:pt];
}
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'tagName');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *tagName, NSError *error) {
if ([tagName isEqualToString:@"IMG"]) {
[self showImageMenu:pt];
}
if ([tagName isEqualToString:@"A"]) {
// [self showLinkContextMenu:pt];
}
}];
}
- (void)showImageMenu:(CGPoint)pt {
NSString *title = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'title');",
(long)pt.x,(long)pt.y]];
NSString *alt = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'alt');",
(long)pt.x,(long)pt.y]];
NSString *src = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'src');",
(long)pt.x,(long)pt.y]];
title = title.length ? title : alt;
activeLongPressUrl = [NSURL URLWithString:src];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title.length ? title : nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"View and zoom" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[appDelegate showOriginalStory:activeLongPressUrl];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Copy image" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self fetchImage:activeLongPressUrl copy:YES save:NO];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Save to camera roll" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self fetchImage:activeLongPressUrl copy:NO save:YES];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[alert setModalPresentationStyle:UIModalPresentationPopover];
UIPopoverPresentationController *popover = [alert popoverPresentationController];
popover.sourceRect = CGRectMake(pt.x, pt.y, 1, 1);
popover.sourceView = appDelegate.storyPageControl.view;
[self presentViewController:alert animated:YES completion:nil];
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'title');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *title, NSError *error) {
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'alt');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *alt, NSError *error) {
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'src');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *src, NSError * error) {
NSString *alertTitle = title.length ? title : alt;
activeLongPressUrl = [NSURL URLWithString:src];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:alertTitle.length ? alertTitle : nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
[alert addAction:[UIAlertAction actionWithTitle:@"View and zoom" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[appDelegate showOriginalStory:activeLongPressUrl];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Copy image" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self fetchImage:activeLongPressUrl copy:YES save:NO];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Save to camera roll" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self fetchImage:activeLongPressUrl copy:NO save:YES];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
}]];
[alert setModalPresentationStyle:UIModalPresentationPopover];
UIPopoverPresentationController *popover = [alert popoverPresentationController];
popover.sourceRect = CGRectMake(pt.x, pt.y, 1, 1);
popover.sourceView = appDelegate.storyPageControl.view;
[self presentViewController:alert animated:YES completion:nil];
}];
}];
}];
}
- (void)showLinkContextMenu:(CGPoint)pt {
NSString *href = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'href');",
(long)pt.x,(long)pt.y]];
NSString *title = [webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"linkAt(%li, %li, 'innerText');",
(long)pt.x,(long)pt.y]];
NSURL *url = [NSURL URLWithString:href];
if (!href || ![href length]) return;
NSValue *ptValue = [NSValue valueWithCGPoint:pt];
[appDelegate showSendTo:appDelegate.storyPageControl
sender:ptValue
withUrl:url
authorName:nil
text:nil
title:title
feedTitle:nil
images:nil];
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'href');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *href, NSError *error) {
[webView evaluateJavaScript:[NSString stringWithFormat:@"linkAt(%li, %li, 'innerText');", (long)pt.x,(long)pt.y] completionHandler:^(NSString *title, NSError *error) {
NSURL *url = [NSURL URLWithString:href];
if (!href || ![href length]) return;
NSValue *ptValue = [NSValue valueWithCGPoint:pt];
[appDelegate showSendTo:appDelegate.storyPageControl
sender:ptValue
withUrl:url
authorName:nil
text:nil
title:title
feedTitle:nil
images:nil];
}];
}];
}
- (CGPoint)pointForEvent:(NSNotification*)notification {
@ -2150,12 +2147,14 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
// convert point from view to HTML coordinate system
// CGPoint offset = [self.webView scrollOffset];
CGSize viewSize = [self.webView frame].size;
CGSize windowSize = [self.webView windowSize];
CGFloat f = windowSize.width / viewSize.width;
pt.x = pt.x * f;// + offset.x;
pt.y = pt.y * f;// + offset.y;
// The viewSize seems to always match the windowSize, so don't need this. If there is some case where it is needed, will need to cache it, as the old windowSize method would be async with WKWebView
// CGSize viewSize = [self.webView frame].size;
// CGSize windowSize = [self.webView windowSize];
//
// CGFloat f = windowSize.width / viewSize.width;
// pt.x = pt.x * f;// + offset.x;
// pt.y = pt.y * f;// + offset.y;
return pt;
}
@ -2168,12 +2167,13 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
// convert point from view to HTML coordinate system
// CGPoint offset = [self.webView scrollOffset];
CGSize viewSize = [self.webView frame].size;
CGSize windowSize = [self.webView windowSize];
CGFloat f = windowSize.width / viewSize.width;
pt.x = pt.x * f;// + offset.x;
pt.y = pt.y * f;// + offset.y;
// The viewSize seems to always match the windowSize, so don't need this. If there is some case where it is needed, will need to cache it, as the old windowSize method would be async with WKWebView
// CGSize viewSize = [self.webView frame].size;
// CGSize windowSize = [self.webView windowSize];
//
// CGFloat f = windowSize.width / viewSize.width;
// pt.x = pt.x * f;// + offset.x;
// pt.y = pt.y * f;// + offset.y;
return pt;
}
@ -2259,34 +2259,33 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
commentString,
shareBarString];
NSString *shareType = appDelegate.activeShareType;
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView stringByEvaluatingJavaScriptFromString:@"attachFastClick();"];
// HACK to make the scroll event happen after the replace innerHTML event above happens.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .15 * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
if (!replyId) {
NSString *currentUserId = [NSString stringWithFormat:@"%@",
[appDelegate.dictSocialProfile objectForKey:@"user_id"]];
NSString *jsFlashString = [[NSString alloc]
initWithFormat:@"slideToComment('%@', true);", currentUserId];
[self.webView stringByEvaluatingJavaScriptFromString:jsFlashString];
} else if ([replyId isEqualToString:@"like"]) {
} else {
NSString *jsFlashString = [[NSString alloc]
initWithFormat:@"slideToComment('%@', true);", replyId];
[self.webView stringByEvaluatingJavaScriptFromString:jsFlashString];
}
});
// // adding in a simulated delay
// sleep(1);
[self flashCheckmarkHud:shareType];
[self refreshSideoptions];
[self.webView evaluateJavaScript:jsString completionHandler:^(id result, NSError * _Nullable error) {
[self.webView evaluateJavaScript:@"attachFastClick();" completionHandler:^(id result, NSError * _Nullable error) {
// HACK to make the scroll event happen after the replace innerHTML event above happens.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, .15 * NSEC_PER_SEC),
dispatch_get_main_queue(), ^{
if (!replyId) {
NSString *currentUserId = [NSString stringWithFormat:@"%@",
[appDelegate.dictSocialProfile objectForKey:@"user_id"]];
NSString *jsFlashString = [[NSString alloc]
initWithFormat:@"slideToComment('%@', true);", currentUserId];
[self.webView evaluateJavaScript:jsFlashString completionHandler:^(id result, NSError * _Nullable error) {
[self flashCheckmarkHud:shareType];
[self refreshSideoptions];
}];
} else if ([replyId isEqualToString:@"like"]) {
} else {
NSString *jsFlashString = [[NSString alloc]
initWithFormat:@"slideToComment('%@', true);", replyId];
[self.webView evaluateJavaScript:jsFlashString completionHandler:^(id result, NSError * _Nullable error) {
[self flashCheckmarkHud:shareType];
[self refreshSideoptions];
}];
}
});
}];
}];
}
- (void)flashCheckmarkHud:(NSString *)messageType {
@ -2331,7 +2330,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
- (void)scrolltoComment {
NSString *currentUserId = [NSString stringWithFormat:@"%@", [appDelegate.dictSocialProfile objectForKey:@"user_id"]];
NSString *jsFlashString = [[NSString alloc] initWithFormat:@"slideToComment('%@', true);", currentUserId];
[self.webView stringByEvaluatingJavaScriptFromString:jsFlashString];
[self.webView evaluateJavaScript:jsFlashString completionHandler:nil];
}
- (void)tryScrollingDown:(BOOL)down {
@ -2428,7 +2427,7 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
alternateViewClass,
riverClass,
(long)contentWidth];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
// self.webView.hidden = NO;
}
@ -2439,9 +2438,9 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
NSString *jsString = [NSString stringWithFormat:@"document.getElementById('NB-header-container').innerHTML = '%@';",
headerString];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView stringByEvaluatingJavaScriptFromString:@"attachFastClick();"];
[self.webView evaluateJavaScript:jsString completionHandler:^(id result, NSError *error) {
[self.webView evaluateJavaScript:@"attachFastClick();" completionHandler:nil];
}];
}
- (void)refreshSideoptions {
@ -2450,9 +2449,9 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
NSString *jsString = [NSString stringWithFormat:@"document.getElementById('NB-sideoptions-container').innerHTML = '%@';",
sideoptionsString];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView stringByEvaluatingJavaScriptFromString:@"attachFastClick();"];
[self.webView evaluateJavaScript:jsString completionHandler:^(id result, NSError *error) {
[self.webView evaluateJavaScript:@"attachFastClick();" completionHandler:nil];
}];
}
#pragma mark -

View file

@ -23,6 +23,7 @@
#import "THCircularProgressView.h"
#import "FMDatabase.h"
#import "StoriesCollection.h"
@import WebKit;
@interface StoryPageControl ()
@ -1632,7 +1633,7 @@
}
- (void)autoscroll:(NSTimer *)timer {
UIWebView *webView = self.currentPage.webView;
WKWebView *webView = self.currentPage.webView;
CGFloat position = webView.scrollView.contentOffset.y + 0.5;
CGFloat maximum = webView.scrollView.contentSize.height - webView.frame.size.height;

View file

@ -9,9 +9,9 @@
#import <UIKit/UIKit.h>
#import "BaseViewController.h"
#import "NewsBlurAppDelegate.h"
@import WebKit;
@interface TrainerWebView : UIWebView {}
@interface TrainerWebView : WKWebView {}
- (void)focusTitle:(id)sender;
- (void)hideTitle:(id)sender;
@ -19,8 +19,7 @@
@end
@interface TrainerViewController : BaseViewController
<UIWebViewDelegate> {
@interface TrainerViewController : BaseViewController <WKNavigationDelegate> {
NewsBlurAppDelegate *appDelegate;
IBOutlet UIBarButtonItem * closeButton;

View file

@ -44,6 +44,7 @@
action:@selector(doCloseDialog:)];
self.navigationItem.rightBarButtonItem = done;
self.webView.navigationDelegate = self;
[self hideGradientBackground:webView];
[self.webView.scrollView setDelaysContentTouches:YES];
[self.webView.scrollView setDecelerationRate:UIScrollViewDecelerationRateNormal];
@ -140,9 +141,9 @@
NSString *jsString = [NSString stringWithFormat:@"document.getElementById('NB-trainer').innerHTML = '%@';",
headerString];
[self.webView stringByEvaluatingJavaScriptFromString:jsString];
[self.webView evaluateJavaScript:jsString completionHandler:nil];
[self.webView stringByEvaluatingJavaScriptFromString:@"attachFastClick({skipEvent: true});"];
[self.webView evaluateJavaScript:@"attachFastClick({skipEvent: true});" completionHandler:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
@ -545,16 +546,13 @@
- (void)changeTitle:(id)sender score:(int)score {
NSString *feedId = [NSString stringWithFormat:@"%@", [appDelegate.activeStory
objectForKey:@"story_feed_id"]];
NSString *selectedTitle = [self.webView
stringByEvaluatingJavaScriptFromString:@"window.getSelection().toString()"];
[self.appDelegate toggleTitleClassifier:selectedTitle feedId:feedId score:score];
[self.webView evaluateJavaScript:@"window.getSelection().toString()" completionHandler:^(id result, NSError *error) {
[self.appDelegate toggleTitleClassifier:result feedId:feedId score:score];
}];
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURLRequest *request = navigationAction.request;
NSURL *url = [request URL];
NSArray *urlComponents = [url pathComponents];
NSString *action = @"";
@ -570,23 +568,22 @@ shouldStartLoadWithRequest:(NSURLRequest *)request
if ([action isEqualToString:@"classify-author"]) {
NSString *author = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleAuthorClassifier:author feedId:feedId];
return NO;
} else if ([action isEqualToString:@"classify-tag"]) {
NSString *tag = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleTagClassifier:tag feedId:feedId];
return NO;
} else if ([action isEqualToString:@"classify-title"]) {
NSString *title = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleTitleClassifier:title feedId:feedId score:0];
return NO;
} else if ([action isEqualToString:@"classify-feed"]) {
NSString *feedId = [NSString stringWithFormat:@"%@", [urlComponents objectAtIndex:2]];
[self.appDelegate toggleFeedClassifier:feedId];
return NO;
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
return YES;
decisionHandler(WKNavigationActionPolicyAllow);
}
@end

View file

@ -484,7 +484,6 @@
FFA045B519CA49D700618DC4 /* SSWAnimator.m in Sources */ = {isa = PBXBuildFile; fileRef = FFA045B119CA49D700618DC4 /* SSWAnimator.m */; };
FFA045B619CA49D700618DC4 /* SSWDirectionalPanGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = FFA045B319CA49D700618DC4 /* SSWDirectionalPanGestureRecognizer.m */; };
FFA0483E19CA5B8400618DC4 /* EventWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = FFA0483D19CA5B8400618DC4 /* EventWindow.m */; };
FFA0484119CA5F5B00618DC4 /* UIWebView+Offsets.m in Sources */ = {isa = PBXBuildFile; fileRef = FFA0484019CA5F5B00618DC4 /* UIWebView+Offsets.m */; };
FFA0484419CA73B700618DC4 /* UIView+ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FFA0484319CA73B700618DC4 /* UIView+ViewController.m */; };
FFAD4971144A386100BA6919 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FFAD4970144A386100BA6919 /* libz.dylib */; };
FFAD89C218AC45A100D68567 /* StoriesCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = FFAD89C118AC45A100D68567 /* StoriesCollection.m */; };
@ -1312,8 +1311,6 @@
FFA045B319CA49D700618DC4 /* SSWDirectionalPanGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSWDirectionalPanGestureRecognizer.m; sourceTree = "<group>"; };
FFA0483C19CA5B8400618DC4 /* EventWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventWindow.h; sourceTree = "<group>"; };
FFA0483D19CA5B8400618DC4 /* EventWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EventWindow.m; sourceTree = "<group>"; };
FFA0483F19CA5F5B00618DC4 /* UIWebView+Offsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIWebView+Offsets.h"; path = "Other Sources/UIWebView+Offsets.h"; sourceTree = "<group>"; };
FFA0484019CA5F5B00618DC4 /* UIWebView+Offsets.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIWebView+Offsets.m"; path = "Other Sources/UIWebView+Offsets.m"; sourceTree = "<group>"; };
FFA0484219CA73B700618DC4 /* UIView+ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+ViewController.h"; path = "Other Sources/UIView+ViewController.h"; sourceTree = "<group>"; };
FFA0484319CA73B700618DC4 /* UIView+ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+ViewController.m"; path = "Other Sources/UIView+ViewController.m"; sourceTree = "<group>"; };
FFAD4970144A386100BA6919 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; };
@ -1718,8 +1715,6 @@
17C4954A1C129863004805A7 /* UISearchBar+Field.m */,
FF1F13D618AAC97900FDA816 /* UIImage+Resize.h */,
FF1F13D718AAC97900FDA816 /* UIImage+Resize.m */,
FFA0483F19CA5F5B00618DC4 /* UIWebView+Offsets.h */,
FFA0484019CA5F5B00618DC4 /* UIWebView+Offsets.m */,
FFFF683B19D628000081904A /* NBURLCache.h */,
FFFF683C19D628000081904A /* NBURLCache.m */,
FFD6604A1BACA45D006E4B8D /* THCircularProgressView.h */,
@ -3529,7 +3524,6 @@
FF83FF051FB52565008DAC0F /* PremiumViewController.m in Sources */,
FF03B00A19F987E00063002A /* NJKWebViewProgressView.m in Sources */,
FF11045F176950F900502C29 /* NBLoadingCell.m in Sources */,
FFA0484119CA5F5B00618DC4 /* UIWebView+Offsets.m in Sources */,
FF34FD701E9D93CB0062F8ED /* IASKTextViewCell.m in Sources */,
FFAD89C218AC45A100D68567 /* StoriesCollection.m in Sources */,
FF34FD6F1E9D93CB0062F8ED /* IASKTextView.m in Sources */,
@ -3833,7 +3827,6 @@
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = "NewsBlur-iPhone-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -3882,7 +3875,6 @@
GCC_VERSION = "";
HEADER_SEARCH_PATHS = "";
INFOPLIST_FILE = "NewsBlur-iPhone-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -3940,7 +3932,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/**";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 9.1.1;
ONLY_ACTIVE_ARCH = YES;
OTHER_LDFLAGS = "-ObjC";
@ -3988,7 +3980,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "$(BUILT_PRODUCTS_DIR)/**";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 9.1.1;
ONLY_ACTIVE_ARCH = NO;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";

View file

@ -1,16 +0,0 @@
//
// UIWebView+Offsets.h
// NewsBlur
//
// Created by Samuel Clay on 9/17/14.
// Copyright (c) 2014 NewsBlur. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIWebView (Offsets)
- (CGSize)windowSize;
- (CGPoint)scrollOffset;
@end

View file

@ -1,29 +0,0 @@
//
// UIWebView+Offsets.m
// NewsBlur
//
// Created by Samuel Clay on 9/17/14.
// Copyright (c) 2014 NewsBlur. All rights reserved.
//
#import "UIWebView+Offsets.h"
@implementation UIWebView (Offsets)
- (CGSize)windowSize
{
CGSize size;
size.width = [[self stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] integerValue];
size.height = [[self stringByEvaluatingJavaScriptFromString:@"window.innerHeight"] integerValue];
return size;
}
- (CGPoint)scrollOffset
{
CGPoint pt;
pt.x = [[self stringByEvaluatingJavaScriptFromString:@"window.pageXOffset"] integerValue];
pt.y = [[self stringByEvaluatingJavaScriptFromString:@"window.pageYOffset"] integerValue];
return pt;
}
@end

View file

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F37" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="ipad9_7" orientation="portrait" layout="fullscreen" appearance="light"/>
<dependencies>
<deployment defaultVersion="1792" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DashboardViewController">
<connections>
<outlet property="activitiesModule" destination="38" id="39"/>
<outlet property="feedbackWebView" destination="49" id="50"/>
<outlet property="interactionsModule" destination="28" id="29"/>
<outlet property="segmentedButton" destination="24" id="44"/>
<outlet property="toolbar" destination="22" id="55"/>
@ -20,29 +21,24 @@
<rect key="frame" x="0.0" y="0.0" width="478" height="960"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" id="28" customClass="InteractionsModule">
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="28" customClass="InteractionsModule">
<rect key="frame" x="0.0" y="0.0" width="478" height="916"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<view contentMode="scaleToFill" id="38" customClass="ActivityModule">
<view contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="38" customClass="ActivityModule">
<rect key="frame" x="0.0" y="0.0" width="478" height="916"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<webView contentMode="scaleToFill" id="49">
<rect key="frame" x="0.0" y="0.0" width="478" height="916"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</webView>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="22">
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="22">
<rect key="frame" x="0.0" y="916" width="478" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<items>
<barButtonItem style="plain" systemItem="flexibleSpace" id="26"/>
<barButtonItem width="240" style="plain" id="25">
<segmentedControl key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" segmentControlStyle="bar" selectedSegmentIndex="0" id="24">
<rect key="frame" x="119" y="7" width="240" height="30"/>
<segmentedControl key="customView" opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" segmentControlStyle="bar" selectedSegmentIndex="0" id="24">
<rect key="frame" x="109.5" y="6" width="259" height="32"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments>
<segment title="INTERACTIONS">
@ -61,8 +57,10 @@
</items>
</toolbar>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="139" y="154"/>
</view>
</objects>
</document>
</document>

View file

@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="9531" systemVersion="15C50" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13174"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -12,7 +11,7 @@
<connections>
<outlet property="activityIndicator" destination="LBH-6T-jFu" id="zQr-GD-QKs"/>
<outlet property="view" destination="1" id="75"/>
<outlet property="webView" destination="39" id="54"/>
<outlet property="webView" destination="UBf-r9-Jaj" id="9Sr-LL-rd6"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
@ -21,27 +20,29 @@
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="LBH-6T-jFu">
<rect key="frame" x="142" y="212" width="37" height="37"/>
<rect key="frame" x="141.5" y="211.5" width="37" height="37"/>
</activityIndicatorView>
<webView multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="39">
<wkWebView multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="UBf-r9-Jaj">
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
<color key="backgroundColor" red="0.43529411759999997" green="0.4431372549" blue="0.47450980390000003" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<outlet property="delegate" destination="-1" id="52"/>
</connections>
</webView>
<color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<wkWebViewConfiguration key="configuration" allowsInlineMediaPlayback="YES">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" audio="YES" video="YES"/>
<wkPreferences key="preferences"/>
</wkWebViewConfiguration>
</wkWebView>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="LBH-6T-jFu" firstAttribute="centerX" secondItem="1" secondAttribute="centerX" id="AIu-Em-rhG"/>
<constraint firstItem="39" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="DpF-n8-Epm"/>
<constraint firstAttribute="trailing" secondItem="UBf-r9-Jaj" secondAttribute="trailing" id="GZU-zu-Bzs"/>
<constraint firstItem="LBH-6T-jFu" firstAttribute="centerY" secondItem="1" secondAttribute="centerY" id="T4x-f0-Y9g"/>
<constraint firstAttribute="trailing" secondItem="39" secondAttribute="trailing" id="UNS-0C-ycK"/>
<constraint firstItem="39" firstAttribute="top" secondItem="1" secondAttribute="top" id="eYc-te-DnY"/>
<constraint firstAttribute="bottom" secondItem="39" secondAttribute="bottomMargin" constant="8" id="nHf-0B-3lN"/>
<constraint firstAttribute="bottom" secondItem="UBf-r9-Jaj" secondAttribute="bottom" id="dzb-XJ-owh"/>
<constraint firstItem="UBf-r9-Jaj" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="rnC-nC-QKW"/>
<constraint firstItem="UBf-r9-Jaj" firstAttribute="top" secondItem="1" secondAttribute="top" id="v6G-Nq-MzW"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-548" y="153"/>
</view>
</objects>
</document>

View file

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="4510" systemVersion="12F37" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="TrainerViewController">
<connections>
<outlet property="view" destination="1" id="14"/>
<outlet property="webView" destination="3" id="13"/>
<outlet property="webView" destination="GKy-Nf-Wvj" id="zud-uf-diH"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
@ -15,19 +18,26 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<webView opaque="NO" contentMode="scaleToFill" id="3" customClass="TrainerWebView">
<wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GKy-Nf-Wvj" customClass="TrainerWebView">
<rect key="frame" x="0.0" y="0.0" width="320" height="504"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<dataDetectorType key="dataDetectorTypes"/>
<connections>
<outlet property="delegate" destination="-1" id="12"/>
</connections>
</webView>
<color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<wkWebViewConfiguration key="configuration">
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
<wkPreferences key="preferences"/>
</wkWebViewConfiguration>
</wkWebView>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="scrollViewTexturedBackgroundColor"/>
<constraints>
<constraint firstItem="GKy-Nf-Wvj" firstAttribute="top" secondItem="1" secondAttribute="top" id="1a7-1T-kvM"/>
<constraint firstItem="GKy-Nf-Wvj" firstAttribute="leading" secondItem="1" secondAttribute="leading" id="TyU-gH-Y2q"/>
<constraint firstAttribute="trailing" secondItem="GKy-Nf-Wvj" secondAttribute="trailing" id="awn-3M-7sd"/>
<constraint firstAttribute="bottom" secondItem="GKy-Nf-Wvj" secondAttribute="bottom" id="r5q-ka-FVF"/>
</constraints>
<nil key="simulatedStatusBarMetrics"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="-548" y="153"/>
</view>
</objects>
</document>
</document>

View file

@ -52,6 +52,21 @@
font-family: "Helvetica";
}
@font-face {
font-family: "ChronicleSSm-Book";
src: url("ChronicleSSm-Book.otf");
}
@font-face {
font-family: "GothamNarrow-Book";
src: url("GothamNarrow-Book.otf");
}
@font-face {
font-family: "WhitneySSm-Book";
src: url("WhitneySSm-Book-Bas.otf");
}
/* Line spacing */
.NB-story {
line-height: 1.5em;
@ -210,7 +225,6 @@ body {
-webkit-text-size-adjust: 100%; /* Prevent font scaling in landscape while allowing user zoom */
font-size: 14px;
line-height: 120%;
overflow: hidden;
font-family: Helvetica;
}
@ -537,7 +551,7 @@ div + p {
max-width: 100%;
display: none;
-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/copy in UIWebView */
-webkit-user-select: none; /* Disable selection/copy in the web view */
}
/* Get iOS 11 Smart Invert to leave images and videos alone. */