FLEXWebViewController.m 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. //
  2. // FLEXWebViewController.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 6/10/14.
  6. // Copyright (c) 2020 FLEX Team. All rights reserved.
  7. //
  8. #import "FLEXWebViewController.h"
  9. #import "FLEXUtility.h"
  10. #import <WebKit/WebKit.h>
  11. #import <TargetConditionals.h>
  12. #if !TARGET_OS_TV
  13. @interface FLEXWebViewController () <WKNavigationDelegate>
  14. #else
  15. @interface FLEXWebViewController ()
  16. #endif
  17. #if !TARGET_OS_TV
  18. @property (nonatomic) WKWebView *webView;
  19. #else
  20. @property (nonatomic) KBWebView *webView;
  21. #endif
  22. @property (nonatomic) NSString *originalText;
  23. @end
  24. @implementation FLEXWebViewController
  25. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
  26. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  27. if (self) {
  28. #if !TARGET_OS_TV
  29. WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
  30. if (@available(iOS 10.0, *)) {
  31. configuration.dataDetectorTypes = UIDataDetectorTypeLink;
  32. }
  33. self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
  34. self.webView.navigationDelegate = self;
  35. #else
  36. self.webView = [[objc_getClass("UIWebView") alloc] initWithFrame:CGRectZero];
  37. self.webView.delegate = self;
  38. #endif
  39. }
  40. return self;
  41. }
  42. - (id)initWithText:(NSString *)text {
  43. self = [self initWithNibName:nil bundle:nil];
  44. if (self) {
  45. self.originalText = text;
  46. NSString *htmlString = [NSString stringWithFormat:@"<head><meta name='viewport' content='initial-scale=1.0'></head><body><pre>%@</pre></body>", [FLEXUtility stringByEscapingHTMLEntitiesInString:text]];
  47. [self.webView loadHTMLString:htmlString baseURL:nil];
  48. }
  49. return self;
  50. }
  51. - (id)initWithURL:(NSURL *)url {
  52. self = [self initWithNibName:nil bundle:nil];
  53. if (self) {
  54. NSURLRequest *request = [NSURLRequest requestWithURL:url];
  55. [self.webView loadRequest:request];
  56. }
  57. return self;
  58. }
  59. - (void)dealloc {
  60. // WKWebView's delegate is assigned so we need to clear it manually.
  61. #if !TARGET_OS_TV
  62. if (_webView.navigationDelegate == self) {
  63. _webView.navigationDelegate = nil;
  64. }
  65. #else
  66. if (_webView.delegate = self){
  67. _webView.delegate = nil;
  68. }
  69. #endif
  70. }
  71. - (void)viewDidLoad {
  72. [super viewDidLoad];
  73. [self.view addSubview:self.webView];
  74. self.webView.frame = self.view.bounds;
  75. self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  76. if (self.originalText.length > 0) {
  77. self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Copy" style:UIBarButtonItemStylePlain target:self action:@selector(copyButtonTapped:)];
  78. }
  79. }
  80. - (void)copyButtonTapped:(id)sender {
  81. #if !TARGET_OS_TV
  82. [UIPasteboard.generalPasteboard setString:self.originalText];
  83. #endif
  84. }
  85. #if TARGET_OS_TV
  86. #pragma mark - KBWebView Delegate
  87. -(void) webViewDidStartLoad:(KBWebView *)webView {
  88. LOG_SELF;
  89. }
  90. - (BOOL)webView:(KBWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(NSInteger)navigationType {
  91. FXLog(@"navtype: %lu", navigationType);
  92. FXLog(@"urL: %@", request.URL);
  93. FXLog(@"scheme: %@", request.URL.scheme);
  94. FXLog(@"navigationType: %lu", navigationType);
  95. if (navigationType == 5){//
  96. return YES;
  97. } else {
  98. FLEXWebViewController *webVC = [[[self class] alloc] initWithURL:[request URL]];
  99. webVC.title = [[request URL] absoluteString];
  100. [self.navigationController pushViewController:webVC animated:YES];
  101. return NO;//? maybe?
  102. }
  103. return YES;
  104. }
  105. -(void) webViewDidFinishLoad:(KBWebView *)webView {
  106. LOG_SELF;
  107. }
  108. #else
  109. #pragma mark - WKWebView Delegate
  110. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
  111. WKNavigationActionPolicy policy = WKNavigationActionPolicyCancel;
  112. if (navigationAction.navigationType == WKNavigationTypeOther) {
  113. // Allow the initial load
  114. policy = WKNavigationActionPolicyAllow;
  115. } else {
  116. // For clicked links, push another web view controller onto the navigation stack so that hitting the back button works as expected.
  117. // Don't allow the current web view to handle the navigation.
  118. NSURLRequest *request = navigationAction.request;
  119. FLEXWebViewController *webVC = [[[self class] alloc] initWithURL:[request URL]];
  120. webVC.title = [[request URL] absoluteString];
  121. [self.navigationController pushViewController:webVC animated:YES];
  122. }
  123. decisionHandler(policy);
  124. }
  125. #endif
  126. #pragma mark - Class Helpers
  127. + (BOOL)supportsPathExtension:(NSString *)extension {
  128. BOOL supported = NO;
  129. NSSet<NSString *> *supportedExtensions = [self webViewSupportedPathExtensions];
  130. if ([supportedExtensions containsObject:[extension lowercaseString]]) {
  131. supported = YES;
  132. }
  133. return supported;
  134. }
  135. + (NSSet<NSString *> *)webViewSupportedPathExtensions {
  136. static NSSet<NSString *> *pathExtensions = nil;
  137. static dispatch_once_t onceToken;
  138. dispatch_once(&onceToken, ^{
  139. // Note that this is not exhaustive, but all these extensions should work well in the web view.
  140. // See https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW7
  141. pathExtensions = [NSSet<NSString *> setWithArray:@[@"jpg", @"jpeg", @"png", @"gif", @"pdf", @"svg", @"tiff", @"3gp", @"3gpp", @"3g2",
  142. @"3gp2", @"aiff", @"aif", @"aifc", @"cdda", @"amr", @"mp3", @"swa", @"mp4", @"mpeg",
  143. @"mpg", @"mp3", @"wav", @"bwf", @"m4a", @"m4b", @"m4p", @"mov", @"qt", @"mqv", @"m4v"]];
  144. });
  145. return pathExtensions;
  146. }
  147. @end