Skip to content
This repository has been archived by the owner on Nov 26, 2020. It is now read-only.

Feature/html content adjustments #150

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 65 additions & 39 deletions Source/FolioReaderCenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,31 @@ var nextPageNumber: Int!
var pageScrollDirection = ScrollDirection()
var isScrolling = false

/// Protocol which is used from `FolioReaderCenter`s.
@objc public protocol FolioReaderCenterDelegate: class {

/**
Notifies that a page appeared. This is triggered is a page is chosen and displayed.

- parameter page: The appeared page
*/
optional func pageDidAppear(page: FolioReaderPage)

/**
Passes and returns the HTML content as `String`. Implement this method if you want to modify the HTML content of a `FolioReaderPage`.

- parameter page: The `FolioReaderPage`
- parameter htmlContent: The current HTML content as `String`

- returns: The adjusted HTML content as `String`. This is the content which will be loaded into the given `FolioReaderPage`
*/
optional func htmlContentForPage(page: FolioReaderPage, htmlContent: String) -> String
}

public class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

/// This delegate receives the events from the current `FolioReaderPage`s delegate.
public weak var pageDelegate: FolioReaderPageDelegate?
public weak var delegate: FolioReaderCenterDelegate?

var collectionView: UICollectionView!
let collectionViewLayout = UICollectionViewFlowLayout()
Expand Down Expand Up @@ -344,38 +364,44 @@ public class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICo

// Configure the cell
let resource = book.spine.spineReferences[indexPath.row].resource
var html = try? String(contentsOfFile: resource.fullHref, encoding: NSUTF8StringEncoding)
let mediaOverlayStyleColors = "\"\(readerConfig.mediaOverlayColor.hexString(false))\", \"\(readerConfig.mediaOverlayColor.highlightColor().hexString(false))\""

// Inject CSS
let jsFilePath = NSBundle.frameworkBundle().pathForResource("Bridge", ofType: "js")
let cssFilePath = NSBundle.frameworkBundle().pathForResource("Style", ofType: "css")
let cssTag = "<link rel=\"stylesheet\" type=\"text/css\" href=\"\(cssFilePath!)\">"
let jsTag = "<script type=\"text/javascript\" src=\"\(jsFilePath!)\"></script>" +
"<script type=\"text/javascript\">setMediaOverlayStyleColors(\(mediaOverlayStyleColors))</script>"

let toInject = "\n\(cssTag)\n\(jsTag)\n</head>"
html = html?.stringByReplacingOccurrencesOfString("</head>", withString: toInject)

// Font class name
var classes = FolioReader.currentFont.cssIdentifier
classes += " "+FolioReader.currentMediaOverlayStyle.className()

// Night mode
if FolioReader.nightMode {
classes += " nightMode"
}

// Font Size
classes += " \(FolioReader.currentFontSize.cssIdentifier)"

html = html?.stringByReplacingOccurrencesOfString("<html ", withString: "<html class=\"\(classes)\"")

cell.loadHTMLString(html, baseURL: NSURL(fileURLWithPath: (resource.fullHref as NSString).stringByDeletingLastPathComponent))

if var html = try? String(contentsOfFile: resource.fullHref, encoding: NSUTF8StringEncoding) {
let mediaOverlayStyleColors = "\"\(readerConfig.mediaOverlayColor.hexString(false))\", \"\(readerConfig.mediaOverlayColor.highlightColor().hexString(false))\""

// Inject CSS
let jsFilePath = NSBundle.frameworkBundle().pathForResource("Bridge", ofType: "js")
let cssFilePath = NSBundle.frameworkBundle().pathForResource("Style", ofType: "css")
let cssTag = "<link rel=\"stylesheet\" type=\"text/css\" href=\"\(cssFilePath!)\">"
let jsTag = "<script type=\"text/javascript\" src=\"\(jsFilePath!)\"></script>" +
"<script type=\"text/javascript\">setMediaOverlayStyleColors(\(mediaOverlayStyleColors))</script>"

let toInject = "\n\(cssTag)\n\(jsTag)\n</head>"
html = html.stringByReplacingOccurrencesOfString("</head>", withString: toInject)

// Font class name
var classes = FolioReader.currentFont.cssIdentifier
classes += " "+FolioReader.currentMediaOverlayStyle.className()

// Night mode
if FolioReader.nightMode {
classes += " nightMode"
}

// Font Size
classes += " \(FolioReader.currentFontSize.cssIdentifier)"

html = html.stringByReplacingOccurrencesOfString("<html ", withString: "<html class=\"\(classes)\"")

// Let the delegate adjust the html string
if let modifiedHtmlContent = self.delegate?.htmlContentForPage?(cell, htmlContent: html) {
html = modifiedHtmlContent
}

cell.loadHTMLString(html, baseURL: NSURL(fileURLWithPath: (resource.fullHref as NSString).stringByDeletingLastPathComponent))
}

return cell
}

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
return CGSizeMake(collectionView.frame.width, collectionView.frame.height)
}
Expand Down Expand Up @@ -503,10 +529,8 @@ public class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICo
currentPageNumber = page.pageNumber
} else {
let currentIndexPath = getCurrentIndexPath()
if currentIndexPath != NSIndexPath(forRow: 0, inSection: 0) {
currentPage = collectionView.cellForItemAtIndexPath(currentIndexPath) as? FolioReaderPage
}

currentPage = collectionView.cellForItemAtIndexPath(currentIndexPath) as? FolioReaderPage

previousPageNumber = currentIndexPath.row
currentPageNumber = currentIndexPath.row+1
}
Expand All @@ -532,7 +556,11 @@ public class FolioReaderCenter: UIViewController, UICollectionViewDelegate, UICo
}
pagesForCurrentPage(page)
}


if let currentPage = currentPage {
self.delegate?.pageDidAppear?(currentPage)
}

completion?()
}

Expand Down Expand Up @@ -1091,15 +1119,13 @@ extension FolioReaderCenter: FolioReaderPageDelegate {
let offsetPoint = self.currentWebViewScrollPositions[page.pageNumber - 1] {
page.webView.scrollView.setContentOffset(offsetPoint, animated: false)
}

self.pageDelegate?.pageDidLoad(page)
}
}

// MARK: FolioReaderChapterListDelegate

extension FolioReaderCenter: FolioReaderChapterListDelegate {

func chapterList(chapterList: FolioReaderChapterList, didSelectRowAtIndexPath indexPath: NSIndexPath, withTocReference reference: FRTocReference) {
let item = findPageByResource(reference)

Expand Down
62 changes: 34 additions & 28 deletions Source/FolioReaderPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import UIMenuItem_CXAImageSupport
import JSQWebViewController

/// Protocol which is used from `FolioReaderPage`s.
public protocol FolioReaderPageDelegate: class {
protocol FolioReaderPageDelegate: class {
/**
Notify that page did loaded

Expand Down Expand Up @@ -98,35 +98,41 @@ public class FolioReaderPage: UICollectionViewCell, UIWebViewDelegate, UIGesture
)
}

func loadHTMLString(string: String!, baseURL: NSURL!) {

var html = (string as NSString)

// Restore highlights
let highlights = Highlight.allByBookId((kBookId as NSString).stringByDeletingPathExtension, andPage: pageNumber)

if highlights.count > 0 {
for item in highlights {
let style = HighlightStyle.classForStyle(item.type)
let tag = "<highlight id=\"\(item.highlightId)\" onclick=\"callHighlightURL(this);\" class=\"\(style)\">\(item.content)</highlight>"
var locator = item.contentPre + item.content + item.contentPost
locator = Highlight.removeSentenceSpam(locator) /// Fix for Highlights
let range: NSRange = html.rangeOfString(locator, options: .LiteralSearch)

if range.location != NSNotFound {
let newRange = NSRange(location: range.location + item.contentPre.characters.count, length: item.content.characters.count)
html = html.stringByReplacingCharactersInRange(newRange, withString: tag)
}
else {
print("highlight range not found")
}
}
}

func loadHTMLString(htmlContent: String!, baseURL: NSURL!) {
// Insert the stored highlights to the HTML
var tempHtmlContent = htmlContentWithInsertHighlights(htmlContent)
// Load the html into the webview
webView.alpha = 0
webView.loadHTMLString(html as String, baseURL: baseURL)
webView.loadHTMLString(tempHtmlContent, baseURL: baseURL)
}


// MARK: - Highlights

private func htmlContentWithInsertHighlights(htmlContent: String) -> String {
var tempHtmlContent = htmlContent as NSString
// Restore highlights
let highlights = Highlight.allByBookId((kBookId as NSString).stringByDeletingPathExtension, andPage: pageNumber)

if highlights.count > 0 {
for item in highlights {
let style = HighlightStyle.classForStyle(item.type)
let tag = "<highlight id=\"\(item.highlightId)\" onclick=\"callHighlightURL(this);\" class=\"\(style)\">\(item.content)</highlight>"
var locator = item.contentPre + item.content + item.contentPost
locator = Highlight.removeSentenceSpam(locator) /// Fix for Highlights
let range: NSRange = tempHtmlContent.rangeOfString(locator, options: .LiteralSearch)

if range.location != NSNotFound {
let newRange = NSRange(location: range.location + item.contentPre.characters.count, length: item.content.characters.count)
tempHtmlContent = tempHtmlContent.stringByReplacingCharactersInRange(newRange, withString: tag)
}
else {
print("highlight range not found")
}
}
}
return tempHtmlContent as String
}

// MARK: - UIWebView Delegate

public func webViewDidFinishLoad(webView: UIWebView) {
Expand Down