--- /dev/null
+//
+// FolioReaderConfig.swift
+// FolioReaderKit
+//
+// Created by Heberti Almeida on 08/04/15.
+// Copyright (c) 2015 Folio Reader. All rights reserved.
+//
+
+import UIKit
+
+import RealmSwift
+
+// MARK: - FolioReaderScrollDirection
+
+/// Defines the Reader scrolling direction
+///
+/// - vertical: Section and content scroll on vertical.
+/// - horizontal: Section and content scroll on horizontal.
+/// - horizontalWithVerticalContent: Sections scroll horizontal and content scroll on vertical.
+/// - defaultVertical: The default scroll direction, if not overridden; works as .vertical.
+public enum FolioReaderScrollDirection: Int {
+ case vertical
+ case horizontal
+ case horizontalWithVerticalContent
+ case defaultVertical
+
+ /// The current scroll direction
+ ///
+ /// - Returns: Returns `UICollectionViewScrollDirection`
+ func collectionViewScrollDirection() -> UICollectionViewScrollDirection {
+ switch self {
+ case .vertical, .defaultVertical:
+ return .vertical
+ case .horizontal, .horizontalWithVerticalContent:
+ return .horizontal
+ }
+ }
+}
+
+// MARK: - ClassBasedOnClickListener
+
+/**
+ A `ClassBasedOnClickListener` takes a closure which is performed if a given html `class` is clicked. The closure will reveice the content of the specified parameter.
+
+ Eg. A ClassBasedOnClickListener with the className `quote` and parameterName `id` with the given epub html content `<section class="quote" id="12345">` would call the given closure on a click on this section with the String `12345` as parameter.
+ */
+public struct ClassBasedOnClickListener {
+
+ /// The name of the URL scheme which should be used. Note: Make sure that the given `String` is a valid as scheme name.
+ public var schemeName: String
+
+ /// The query selector for the elements which the listener should be added to. See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector for further information about query selectors.
+ public var querySelector: String
+
+ /// The name of the attribute whose content should be passed to the `onClickAction` action.
+ public var attributeName: String
+
+ /// Whether the listener should be added to all found elements or only to the first one. See https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll for further information. The default value is `true`.
+ public var selectAll: Bool
+
+ /// The closure which will be called if the specified class was clicked. `attributeContent` contains the string content of the specified attribute and `touchPointRelativeToWebView` reprsents the touch point relative to the web view.
+ public var onClickAction: ((_ attributeContent: String?, _ touchPointRelativeToWebView: CGPoint) -> Void)
+
+ /**
+ Initializes a `ClassBasedOnClickListener` instance. Append it to the `classBasedOnClickListeners` property from the `FolioReaderConfig` to receive on click events. The default `selectAll` value is `true`.
+
+ - parameter schemeName: The name of the URL scheme which should be used. Note: Make sure that the given `String` is a valid as scheme name.
+ - parameter querySelector: The query selector for the elements which the listener should be added to. See https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector for further information about query selectors.
+ - parameter attributeName: The name of the attribute whose content should be passed to the `onClickAction` action.
+ - parameter selectAll: Whether the listener should be added to all found elements or only to the first one. See https://developer.mozilla.org/en-US/docs/Web/API/Element/querySelectorAll for further information. The default value is `true`.
+ - parameter onClickAction: The closure which will be called if the specified class was clicked. `attributeContent` contains the string content of the specified attribute and `touchPointRelativeToWebView` reprsents the touch point relative to the web view.
+ */
+ public init(schemeName: String, querySelector: String, attributeName: String, selectAll: Bool = true, onClickAction: @escaping ((_ attributeContent: String?, _ touchPointRelativeToWebView: CGPoint) -> Void)) {
+ self.schemeName = schemeName.lowercased()
+ self.querySelector = querySelector
+ self.attributeName = attributeName
+ self.selectAll = selectAll
+ self.onClickAction = onClickAction
+ }
+}
+
+// MARK: - FolioReaderConfig
+
+/**
+ Defines the Reader custom configuration
+ */
+open class FolioReaderConfig: NSObject {
+
+ // MARK: ClassBasedOnClickListener
+
+ /**
+ Array of `ClassBasedOnClickListener` objects. A `ClassBasedOnClickListener` takes a closure which is performed if a given html `class` is clicked. The closure will reveice the content of the specified parameter.
+
+ Eg. A ClassBasedOnClickListener with the className `quote` and parameterName `id` with the given epub html content `<section class="quote" id="12345">` would call the given closure on a click on this section with the String `12345` as parameter.
+ */
+ open var classBasedOnClickListeners = [ClassBasedOnClickListener]()
+
+ // MARK: Colors
+
+ /// Base header custom TintColor
+ open var tintColor = UIColor(rgba: "#6ACC50")
+
+ /// Menu background color
+ open var menuBackgroundColor = UIColor.white
+
+ /// Menu separator Color
+ open var menuSeparatorColor = UIColor(rgba: "#D7D7D7")
+
+ /// Menu text color
+ open var menuTextColor = UIColor(rgba: "#767676")
+
+ /// Night mode background color
+ open var nightModeBackground = UIColor(rgba: "#131313")
+
+ /// Night mode menu background color
+ open var nightModeMenuBackground = UIColor(rgba: "#1E1E1E")
+
+ /// Night mode separator color
+ open var nightModeSeparatorColor = UIColor(white: 0.5, alpha: 0.2)
+
+ /// Media overlay or TTS selection color
+ open lazy var mediaOverlayColor: UIColor! = self.tintColor
+
+ // MARK: Custom actions
+
+ /// hide the navigation bar and the bottom status view
+ open var hideBars = false
+
+ /// If `canChangeScrollDirection` is `true` it will be overrided by user's option.
+ open var scrollDirection: FolioReaderScrollDirection = .defaultVertical
+
+ /// Enable or disable hability to user change scroll direction on menu.
+ open var canChangeScrollDirection = true
+
+ /// Should hide navigation bar on user tap
+ open var shouldHideNavigationOnTap = true
+
+ /// Allow sharing option, if `false` will hide all sharing icons and options
+ open var allowSharing = true
+
+ /// Enable TTS (Text To Speech)
+ open var enableTTS = true
+
+ /// Display book title in navbar
+ open var displayTitle = false
+
+ /// Hide the page indicator
+ open var hidePageIndicator = false
+
+ /// Go to saved position when open a book
+ open var loadSavedPositionForCurrentBook = true
+
+ // MARK: Quote image share
+
+ /// Custom Quote logo
+ open var quoteCustomLogoImage = UIImage(readerImageNamed: "icon-logo")
+
+ /// Add custom backgrounds and font colors to Quote Images
+ open var quoteCustomBackgrounds = [QuoteImage]()
+
+ /// Enable or disable default Quote Image backgrounds
+ open var quotePreserveDefaultBackgrounds = true
+
+ // MARK: Realm
+
+ /// Realm configuration for storing highlights
+ open var realmConfiguration = Realm.Configuration()
+
+ // MARK: Localized strings
+
+ /// Localizes Highlight title
+ open var localizedHighlightsTitle = NSLocalizedString("Highlights", comment: "")
+
+ /// Localizes Content title
+ open var localizedContentsTitle = NSLocalizedString("Contents", comment: "")
+
+ /// Use the readers `UIMenuController` which enables the highlighting etc. The default is `true`. If set to false it's possible to modify the shared `UIMenuController` for yourself. Note: This doesn't disable the text selection in the web view.
+ open var useReaderMenuController = true
+
+ /// Used to distinguish between multiple or different reader instances. The content of the user defaults (font settings etc.) depends on this identifier. The default is `nil`.
+ open var identifier: String?
+
+ /// Localizes Highlight date format. This is a `dateFormat` from `NSDateFormatter`, so be careful 🤔
+ open var localizedHighlightsDateFormat = "MMM dd, YYYY | HH:mm"
+ open var localizedHighlightMenu = NSLocalizedString("Highlight", comment: "")
+ open var localizedDefineMenu = NSLocalizedString("Define", comment: "")
+ open var localizedPlayMenu = NSLocalizedString("Play", comment: "")
+ open var localizedPauseMenu = NSLocalizedString("Pause", comment: "")
+ open var localizedFontMenuNight = NSLocalizedString("Night", comment: "")
+ open var localizedPlayerMenuStyle = NSLocalizedString("Style", comment: "")
+ open var localizedFontMenuDay = NSLocalizedString("Day", comment: "")
+ open var localizedLayoutHorizontal = NSLocalizedString("Horizontal", comment: "")
+ open var localizedLayoutVertical = NSLocalizedString("Vertical", comment: "")
+ open var localizedReaderOnePageLeft = NSLocalizedString("1 page left", comment: "")
+ open var localizedReaderManyPagesLeft = NSLocalizedString("pages left", comment: "")
+ open var localizedReaderManyMinutes = NSLocalizedString("minutes", comment: "")
+ open var localizedReaderOneMinute = NSLocalizedString("1 minute", comment: "")
+ open var localizedReaderLessThanOneMinute = NSLocalizedString("Less than a minute", comment: "")
+ open var localizedShareWebLink: URL? = nil
+ open var localizedShareChapterSubject = NSLocalizedString("Check out this chapter from", comment: "")
+ open var localizedShareHighlightSubject = NSLocalizedString("Notes from", comment: "")
+ open var localizedShareAllExcerptsFrom = NSLocalizedString("All excerpts from", comment: "")
+ open var localizedShareBy = NSLocalizedString("by", comment: "")
+ open var localizedCancel = NSLocalizedString("Cancel", comment: "")
+ open var localizedShare = NSLocalizedString("Share", comment: "")
+ open var localizedChooseExisting = NSLocalizedString("Choose existing", comment: "")
+ open var localizedTakePhoto = NSLocalizedString("Take Photo", comment: "")
+ open var localizedShareImageQuote = NSLocalizedString("Share image quote", comment: "")
+ open var localizedShareTextQuote = NSLocalizedString("Share text quote", comment: "")
+
+ public convenience init(withIdentifier identifier: String) {
+ self.init()
+
+ self.identifier = identifier
+ }
+
+ /**
+ Simplify attibution of values based on direction, basically is to avoid too much usage of `switch`,
+ `if` and `else` statements to check. So basically this is like a shorthand version of the `switch` verification.
+
+ For example:
+ ```
+ let pageOffsetPoint = readerConfig.isDirection(CGPoint(x: 0, y: pageOffset), CGPoint(x: pageOffset, y: 0), CGPoint(x: 0, y: pageOffset))
+ ```
+
+ As usually the `vertical` direction and `horizontalContentVertical` has similar statements you can basically hide the last
+ value and it will assume the value from `vertical` as fallback.
+ ```
+ let pageOffsetPoint = readerConfig.isDirection(CGPoint(x: 0, y: pageOffset), CGPoint(x: pageOffset, y: 0))
+ ```
+
+ - parameter vertical: Value for `vertical` direction
+ - parameter horizontal: Value for `horizontal` direction
+ - parameter horizontalContentVertical: Value for `horizontalWithVerticalContent` direction, if nil will fallback to `vertical` value
+
+ - returns: The right value based on direction.
+ */
+ func isDirection<T> (_ vertical: T, _ horizontal: T, _ horizontalContentVertical: T) -> T {
+ switch self.scrollDirection {
+ case .vertical, .defaultVertical: return vertical
+ case .horizontal: return horizontal
+ case .horizontalWithVerticalContent: return horizontalContentVertical
+ }
+ }
+}