diff --git a/Kiwix-iOS/Controller/Main/JSInjection.swift b/Kiwix-iOS/Controller/Main/JSInjection.swift
new file mode 100644
index 00000000..8a07c680
--- /dev/null
+++ b/Kiwix-iOS/Controller/Main/JSInjection.swift
@@ -0,0 +1,55 @@
+//
+// JSInjection.swift
+// Kiwix
+//
+// Created by Chris Li on 9/9/16.
+// Copyright © 2016 Chris. All rights reserved.
+//
+
+import UIKit
+import JavaScriptCore
+
+class JSInjection {
+
+ class func injectTableWrappingJavaScriptIfNeeded(webView: UIWebView, traitCollection: UITraitCollection) {
+ if Preference.webViewInjectJavascriptToAdjustPageLayout {
+ if traitCollection.horizontalSizeClass == .Compact {
+ guard let path = NSBundle.mainBundle().pathForResource("adjustlayoutiPhone", ofType: "js") else {return}
+ guard let jString = try? String(contentsOfFile: path) else {return}
+ webView.stringByEvaluatingJavaScriptFromString(jString)
+ } else {
+ guard let path = NSBundle.mainBundle().pathForResource("adjustlayoutiPad", ofType: "js") else {return}
+ guard let jString = try? String(contentsOfFile: path) else {return}
+ webView.stringByEvaluatingJavaScriptFromString(jString)
+ }
+ }
+ }
+
+ class func adjustFontSizeIfNeeded(webView: UIWebView) {
+ let zoomScale = Preference.webViewZoomScale
+ guard zoomScale != 100.0 else {return}
+ let jString = String(format: "document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%.0f%%'", zoomScale)
+ webView.stringByEvaluatingJavaScriptFromString(jString)
+ }
+
+ class func getTableOfContents(webView: UIWebView) -> [HTMLHeading] {
+ guard let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext,
+ let path = NSBundle.mainBundle().pathForResource("getTableOfContents", ofType: "js"),
+ let jString = try? String(contentsOfFile: path),
+ let elements = context.evaluateScript(jString).toArray() as? [[String: String]] else {return [HTMLHeading]()}
+ var headings = [HTMLHeading]()
+ for element in elements {
+ guard let heading = HTMLHeading(rawValue: element) else {continue}
+ headings.append(heading)
+ }
+ return headings
+ }
+
+ class func getSnippet(webView: UIWebView) -> String? {
+ guard let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext,
+ let path = NSBundle.mainBundle().pathForResource("getSnippet", ofType: "js"),
+ let jString = try? String(contentsOfFile: path),
+ let snippet = context.evaluateScript(jString).toString() else {return nil}
+ return snippet
+ }
+}
diff --git a/Kiwix-iOS/Controller/Main/MainController.swift b/Kiwix-iOS/Controller/Main/MainController.swift
index 157a2ab0..102aad77 100644
--- a/Kiwix-iOS/Controller/Main/MainController.swift
+++ b/Kiwix-iOS/Controller/Main/MainController.swift
@@ -9,6 +9,7 @@
import UIKit
import Operations
+import SafariServices
class MainController: UIViewController {
@@ -23,7 +24,6 @@ class MainController: UIViewController {
// MARK: - Properties
- let webViewDelegate = WebViewDelegate()
var tableOfContentsController: TableOfContentsController?
let searchBar = SearchBar()
@@ -49,8 +49,7 @@ class MainController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- webView.delegate = webViewDelegate
- webViewDelegate.delegate = self
+ webView.delegate = self
@@ -120,6 +119,19 @@ class MainController: UIViewController {
load(mainPageURL)
}
+ func loadExternalResource(url: NSURL) {
+ let controller = SFSafariViewController(URL: url)
+ controller.delegate = self
+ presentViewController(controller, animated: true, completion: nil)
+ }
+
+ // MARK: - Tasks
+
+ func setTableOfContentIfNeeded() {
+ guard traitCollection.horizontalSizeClass == .Regular && isShowingTableOfContents else {return}
+ tableOfContentsController?.headings = JSInjection.getTableOfContents(webView)
+ }
+
// MARK: - Configure
func configureUIElements(horizontalSizeClass: UIUserInterfaceSizeClass) {
@@ -223,11 +235,7 @@ class MainController: UIViewController {
func showTableOfContentButtonTapped(sender: UIBarButtonItem) {
guard let _ = article else {return}
- if isShowingTableOfContents {
- animateOutTableOfContentsController()
- } else {
- animateInTableOfContentsController()
- }
+ isShowingTableOfContents ? animateOutTableOfContentsController() :animateInTableOfContentsController()
}
func showLibraryButtonTapped() {
diff --git a/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift b/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift
index a3f4f7f4..3dad28da 100644
--- a/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift
+++ b/Kiwix-iOS/Controller/Main/MainControllerDelegates.swift
@@ -11,7 +11,34 @@ import SafariServices
import JavaScriptCore
import DZNEmptyDataSet
-extension MainController: LPTBarButtonItemDelegate, TableOfContentsDelegate, ZimMultiReaderDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate, UIWebViewDelegate, SFSafariViewControllerDelegate, UIScrollViewDelegate, UIViewControllerTransitioningDelegate {
+extension MainController: UIWebViewDelegate, SFSafariViewControllerDelegate,
+ LPTBarButtonItemDelegate, TableOfContentsDelegate, ZimMultiReaderDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate, UIScrollViewDelegate, UIViewControllerTransitioningDelegate {
+
+ // MARK: - UIWebViewDelegate
+
+ func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
+ guard let url = request.URL else {return false}
+ guard url.isKiwixURL else {loadExternalResource(url); return false}
+ return true
+ }
+
+ func webViewDidStartLoad(webView: UIWebView) {
+
+ }
+
+ func webViewDidFinishLoad(webView: UIWebView) {
+
+ }
+
+ func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
+ print(error)
+ }
+
+ // MARK: - SFSafariViewControllerDelegate
+
+ func safariViewControllerDidFinish(controller: SFSafariViewController) {
+ controller.dismissViewControllerAnimated(true, completion: nil)
+ }
// MARK: - LPTBarButtonItemDelegate
@@ -27,7 +54,7 @@ extension MainController: LPTBarButtonItemDelegate, TableOfContentsDelegate, Zim
article.isBookmarked = !article.isBookmarked
if article.isBookmarked {article.bookmarkDate = NSDate()}
- if article.snippet == nil {article.snippet = getSnippet(webView)}
+ if article.snippet == nil {article.snippet = JSInjection.getSnippet(webView)}
let operation = UpdateWidgetDataSourceOperation()
GlobalQueue.shared.addOperation(operation)
@@ -91,96 +118,47 @@ extension MainController: LPTBarButtonItemDelegate, TableOfContentsDelegate, Zim
return .None
}
- // MARK: - UIWebViewDelegate
-
- func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
- guard let url = request.URL else {return true}
- if url.scheme == "kiwix" {
- return true
- } else {
- let svc = SFSafariViewController(URL: url)
- svc.delegate = self
- presentViewController(svc, animated: true, completion: nil)
- return false
- }
- }
-
- func webViewDidStartLoad(webView: UIWebView) {
- PacketAnalyzer.sharedInstance.startListening()
- }
-
- func webViewDidFinishLoad(webView: UIWebView) {
- guard let url = webView.request?.URL else {return}
- guard url.scheme!.caseInsensitiveCompare("Kiwix") == .OrderedSame else {return}
-
- let title = webView.stringByEvaluatingJavaScriptFromString("document.title")
- let managedObjectContext = UIApplication.appDelegate.managedObjectContext
- guard let bookID = url.host else {return}
- guard let book = Book.fetch(bookID, context: managedObjectContext) else {return}
- guard let article = Article.addOrUpdate(title, url: url, book: book, context: managedObjectContext) else {return}
-
- self.article = article
- if let image = PacketAnalyzer.sharedInstance.chooseImage() {
- article.thumbImageURL = image.url.absoluteString
- }
-
- configureSearchBarPlaceHolder()
- injectTableWrappingJavaScriptIfNeeded()
- adjustFontSizeIfNeeded()
- configureNavigationButtonTint()
- configureBookmarkButton()
-
- if traitCollection.horizontalSizeClass == .Regular && isShowingTableOfContents {
- tableOfContentsController?.headings = getTableOfContents(webView)
- }
-
- PacketAnalyzer.sharedInstance.stopListening()
- }
-
- // MARK: - Javascript
-
- func injectTableWrappingJavaScriptIfNeeded() {
- if Preference.webViewInjectJavascriptToAdjustPageLayout {
- if traitCollection.horizontalSizeClass == .Compact {
- guard let path = NSBundle.mainBundle().pathForResource("adjustlayoutiPhone", ofType: "js") else {return}
- guard let jString = try? String(contentsOfFile: path) else {return}
- webView.stringByEvaluatingJavaScriptFromString(jString)
- } else {
- guard let path = NSBundle.mainBundle().pathForResource("adjustlayoutiPad", ofType: "js") else {return}
- guard let jString = try? String(contentsOfFile: path) else {return}
- webView.stringByEvaluatingJavaScriptFromString(jString)
- }
- }
- }
-
- func adjustFontSizeIfNeeded() {
- let zoomScale = Preference.webViewZoomScale
- guard zoomScale != 100.0 else {return}
- let jString = String(format: "document.getElementsByTagName('body')[0].style.webkitTextSizeAdjust= '%.0f%%'", zoomScale)
- webView.stringByEvaluatingJavaScriptFromString(jString)
- }
-
- func getTableOfContents(webView: UIWebView) -> [HTMLHeading] {
- guard let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext,
- let path = NSBundle.mainBundle().pathForResource("getTableOfContents", ofType: "js"),
- let jString = try? String(contentsOfFile: path),
- let elements = context.evaluateScript(jString).toArray() as? [[String: String]] else {return [HTMLHeading]()}
- var headings = [HTMLHeading]()
- for element in elements {
- guard let heading = HTMLHeading(rawValue: element) else {continue}
- headings.append(heading)
- }
- return headings
- }
-
- func getSnippet(webView: UIWebView) -> String? {
- guard let context = webView.valueForKeyPath("documentView.webView.mainFrame.javaScriptContext") as? JSContext,
- let path = NSBundle.mainBundle().pathForResource("getSnippet", ofType: "js"),
- let jString = try? String(contentsOfFile: path),
- let snippet = context.evaluateScript(jString).toString() else {return nil}
- return snippet
- }
-
-
+//
+// func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
+// guard let url = request.URL else {return true}
+// if url.scheme == "kiwix" {
+// return true
+// } else {
+// let svc = SFSafariViewController(URL: url)
+// svc.delegate = self
+// presentViewController(svc, animated: true, completion: nil)
+// return false
+// }
+// }
+//
+// func webViewDidStartLoad(webView: UIWebView) {
+// PacketAnalyzer.sharedInstance.startListening()
+// }
+//
+// func webViewDidFinishLoad(webView: UIWebView) {
+// guard let url = webView.request?.URL else {return}
+// guard url.scheme!.caseInsensitiveCompare("Kiwix") == .OrderedSame else {return}
+//
+// let title = webView.stringByEvaluatingJavaScriptFromString("document.title")
+// let managedObjectContext = UIApplication.appDelegate.managedObjectContext
+// guard let bookID = url.host else {return}
+// guard let book = Book.fetch(bookID, context: managedObjectContext) else {return}
+// guard let article = Article.addOrUpdate(title, url: url, book: book, context: managedObjectContext) else {return}
+//
+// self.article = article
+// if let image = PacketAnalyzer.sharedInstance.chooseImage() {
+// article.thumbImageURL = image.url.absoluteString
+// }
+//
+// configureSearchBarPlaceHolder()
+// injectTableWrappingJavaScriptIfNeeded()
+// adjustFontSizeIfNeeded()
+// configureNavigationButtonTint()
+// configureBookmarkButton()
+//
+
+//
+// PacketAnalyzer.sharedInstance.stopListening()
+// }
}
diff --git a/Kiwix-iOS/Controller/Main/MainControllerShowHide.swift b/Kiwix-iOS/Controller/Main/MainControllerShowHide.swift
index 5b3959a3..74f2b97d 100644
--- a/Kiwix-iOS/Controller/Main/MainControllerShowHide.swift
+++ b/Kiwix-iOS/Controller/Main/MainControllerShowHide.swift
@@ -110,7 +110,7 @@ extension MainController {
dimView.hidden = false
dimView.alpha = 0.0
view.layoutIfNeeded()
- tableOfContentsController?.headings = getTableOfContents(webView)
+ tableOfContentsController?.headings = JSInjection.getTableOfContents(webView)
configureTOCViewConstraints()
UIView.animateWithDuration(0.3, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: .CurveEaseOut, animations: {
self.view.layoutIfNeeded()
diff --git a/Kiwix-iOS/Controller/Main/WebViewDelegate.swift b/Kiwix-iOS/Controller/Main/WebViewDelegate.swift
deleted file mode 100644
index 4268041b..00000000
--- a/Kiwix-iOS/Controller/Main/WebViewDelegate.swift
+++ /dev/null
@@ -1,46 +0,0 @@
-//
-// WebViewDelegate.swift
-// Kiwix
-//
-// Created by Chris Li on 9/9/16.
-// Copyright © 2016 Chris. All rights reserved.
-//
-
-import UIKit
-import SafariServices
-
-class WebViewDelegate: NSObject, UIWebViewDelegate, SFSafariViewControllerDelegate {
-
- weak var delegate: MainController?
-
- // MARK: - UIWebViewDelegate
-
- func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
- guard let url = request.URL else {return false}
- guard url.scheme?.caseInsensitiveCompare("kiwix") == .OrderedSame else {
- let svc = SFSafariViewController(URL: url)
- svc.delegate = self
- delegate?.presentViewController(svc, animated: true, completion: nil)
- return false
- }
- return true
- }
-
- func webViewDidStartLoad(webView: UIWebView) {
-
- }
-
- func webViewDidFinishLoad(webView: UIWebView) {
-
- }
-
- func webView(webView: UIWebView, didFailLoadWithError error: NSError) {
- print(error)
- }
-
- // MARK: - SFSafariViewControllerDelegate
-
- func safariViewControllerDidFinish(controller: SFSafariViewController) {
- controller.dismissViewControllerAnimated(true, completion: nil)
- }
-}
diff --git a/Kiwix-iOS/Info.plist b/Kiwix-iOS/Info.plist
index 444253f7..fde59af5 100644
--- a/Kiwix-iOS/Info.plist
+++ b/Kiwix-iOS/Info.plist
@@ -49,7 +49,7 @@
CFBundleVersion
- 1.8.20
+ 1.8.39
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
diff --git a/Kiwix.xcodeproj/project.pbxproj b/Kiwix.xcodeproj/project.pbxproj
index 67bbb03f..015713ff 100644
--- a/Kiwix.xcodeproj/project.pbxproj
+++ b/Kiwix.xcodeproj/project.pbxproj
@@ -76,7 +76,8 @@
9764CBD11D806AD800072D6A /* RefreshLibControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764CBD01D806AD800072D6A /* RefreshLibControl.swift */; };
9764CBD31D8083AA00072D6A /* ArticleOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764CBD21D8083AA00072D6A /* ArticleOperation.swift */; };
9764F5931D830EF200E0B1C4 /* liblzma.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9764F5921D830EF200E0B1C4 /* liblzma.tbd */; };
- 9764F5951D832D2000E0B1C4 /* WebViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764F5941D832D2000E0B1C4 /* WebViewDelegate.swift */; };
+ 9764F5971D8339D500E0B1C4 /* JSInjection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764F5961D8339D500E0B1C4 /* JSInjection.swift */; };
+ 9764F5991D833F2B00E0B1C4 /* KiwixURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */; };
9779C3141D4575AD0064CC8E /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97E609F01D103DED00EBCB9D /* NotificationCenter.framework */; };
9779C3171D4575AE0064CC8E /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9779C3161D4575AE0064CC8E /* TodayViewController.swift */; };
9779C31A1D4575AE0064CC8E /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9779C3181D4575AE0064CC8E /* MainInterface.storyboard */; };
@@ -295,7 +296,8 @@
9764CBD01D806AD800072D6A /* RefreshLibControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshLibControl.swift; sourceTree = ""; };
9764CBD21D8083AA00072D6A /* ArticleOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArticleOperation.swift; sourceTree = ""; };
9764F5921D830EF200E0B1C4 /* liblzma.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = liblzma.tbd; path = usr/lib/liblzma.tbd; sourceTree = SDKROOT; };
- 9764F5941D832D2000E0B1C4 /* WebViewDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebViewDelegate.swift; path = Main/WebViewDelegate.swift; sourceTree = ""; };
+ 9764F5961D8339D500E0B1C4 /* JSInjection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSInjection.swift; path = Main/JSInjection.swift; sourceTree = ""; };
+ 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KiwixURL.swift; sourceTree = ""; };
976A0C801D41619C0006A742 /* DZNEmptyDataSet.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DZNEmptyDataSet.framework; path = "../../../../Users/chrisli/Library/Developer/Xcode/DerivedData/Kiwix-ayxrfhaqnfxzendihdolvkklkmhk/Build/Products/Debug-iphoneos/DZNEmptyDataSet/DZNEmptyDataSet.framework"; sourceTree = ""; };
9779C3131D4575AD0064CC8E /* Bookmarks.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = Bookmarks.appex; sourceTree = BUILT_PRODUCTS_DIR; };
9779C3161D4575AE0064CC8E /* TodayViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TodayViewController.swift; sourceTree = ""; };
@@ -635,7 +637,7 @@
970E68B71D3809A3001E8514 /* MainController.swift */,
9722122A1D3FCCE200C0DCF2 /* MainControllerShowHide.swift */,
970E68B81D3809A3001E8514 /* MainControllerDelegates.swift */,
- 9764F5941D832D2000E0B1C4 /* WebViewDelegate.swift */,
+ 9764F5961D8339D500E0B1C4 /* JSInjection.swift */,
);
name = Main;
sourceTree = "";
@@ -917,6 +919,7 @@
isa = PBXGroup;
children = (
97A1FD1A1D6F71D800A80EE2 /* KiwixURLProtocol.swift */,
+ 9764F5981D833F2B00E0B1C4 /* KiwixURL.swift */,
97A1FD1B1D6F71D800A80EE2 /* PacketAnalyzer.swift */,
);
path = URLProtocol;
@@ -1531,6 +1534,7 @@
97D681271D6F70AC00E5FA99 /* UIOperations.swift in Sources */,
975B90FE1CEB909100D13906 /* iOSExtensions.swift in Sources */,
971A10521D022D9D007FC62C /* AppDelegate.swift in Sources */,
+ 9764F5991D833F2B00E0B1C4 /* KiwixURL.swift in Sources */,
97A127CC1D777CF100FB204D /* SearchResultTBVC.swift in Sources */,
97A8AD841D6C951A00584ED1 /* LocalBooksController.swift in Sources */,
97D452BE1D1723FF0033666F /* CollectionViewCells.swift in Sources */,
@@ -1551,9 +1555,9 @@
97A461B71D74819000AC3DED /* DownloadProgress.swift in Sources */,
971A10341D022AEC007FC62C /* BookmarkTBVC.swift in Sources */,
97A1FD1D1D6F71D800A80EE2 /* PacketAnalyzer.swift in Sources */,
+ 9764F5971D8339D500E0B1C4 /* JSInjection.swift in Sources */,
97A1FD441D6F728200A80EE2 /* Preference.swift in Sources */,
97D681311D6F70EC00E5FA99 /* 1.5.xcmappingmodel in Sources */,
- 9764F5951D832D2000E0B1C4 /* WebViewDelegate.swift in Sources */,
97D681441D6F713200E5FA99 /* CoreDataExtension.swift in Sources */,
97DF259C1D6F7613001648A3 /* BookOperation.swift in Sources */,
97A1FD181D6F71CE00A80EE2 /* SearchResult.swift in Sources */,
diff --git a/Kiwix/URLProtocol/KiwixURL.swift b/Kiwix/URLProtocol/KiwixURL.swift
new file mode 100644
index 00000000..1cbae817
--- /dev/null
+++ b/Kiwix/URLProtocol/KiwixURL.swift
@@ -0,0 +1,20 @@
+//
+// KiwixURL.swift
+// Kiwix
+//
+// Created by Chris Li on 9/9/16.
+// Copyright © 2016 Chris. All rights reserved.
+//
+
+import UIKit
+
+extension NSURL {
+ convenience init?(bookID: String, contentPath: String) {
+ let baseURLString = "kiwix://" + bookID
+ self.init(string: contentPath, relativeToURL: NSURL(string: baseURLString))
+ }
+
+ var isKiwixURL: Bool {
+ return scheme?.caseInsensitiveCompare("kiwix") == .OrderedSame
+ }
+}
diff --git a/Kiwix/URLProtocol/KiwixURLProtocol.swift b/Kiwix/URLProtocol/KiwixURLProtocol.swift
index 5f8db041..b172e166 100644
--- a/Kiwix/URLProtocol/KiwixURLProtocol.swift
+++ b/Kiwix/URLProtocol/KiwixURLProtocol.swift
@@ -50,6 +50,8 @@ class KiwixURLProtocol: NSURLProtocol {
}
extension NSURL {
+
+
class func kiwixURLWithZimFileid(id: String, contentURLString: String) -> NSURL? {
guard let escapedContentURLString = contentURLString.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet()) else {return nil}
let baseURLString = "kiwix://" + id