mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-21 03:43:16 +09:00
81 lines
6.2 KiB
Swift
81 lines
6.2 KiB
Swift
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
import Foundation
|
|
import GCDWebServers
|
|
|
|
struct ReaderModeHandlers {
|
|
static var readerModeCache: ReaderModeCache = DiskReaderModeCache.sharedInstance
|
|
|
|
static func register(_ webServer: WebServer, profile: Profile) {
|
|
// Register our fonts and css, which we want to expose to web content that we present in the WebView
|
|
webServer.registerMainBundleResourcesOfType("ttf", module: "reader-mode/fonts")
|
|
webServer.registerMainBundleResource("Reader.css", module: "reader-mode/styles")
|
|
|
|
// Register a handler that simply lets us know if a document is in the cache or not. This is called from the
|
|
// reader view interstitial page to find out when it can stop showing the 'Loading...' page and instead load
|
|
// the readerized content.
|
|
webServer.registerHandlerForMethod("GET", module: "reader-mode", resource: "page-exists") { (request: GCDWebServerRequest?) -> GCDWebServerResponse! in
|
|
guard let stringURL = request?.query["url"] as? String,
|
|
let url = URL(string: stringURL) else {
|
|
return GCDWebServerResponse(statusCode: 500)
|
|
}
|
|
|
|
let status = readerModeCache.contains(url) ? 200 : 404
|
|
return GCDWebServerResponse(statusCode: status)
|
|
}
|
|
|
|
// Register the handler that accepts /reader-mode/page?url=http://www.example.com requests.
|
|
webServer.registerHandlerForMethod("GET", module: "reader-mode", resource: "page") { (request: GCDWebServerRequest?) -> GCDWebServerResponse! in
|
|
if let url = request?.query["url"] as? String {
|
|
if let url = URL(string: url), url.isWebPage() {
|
|
do {
|
|
let readabilityResult = try readerModeCache.get(url)
|
|
// We have this page in our cache, so we can display it. Just grab the correct style from the
|
|
// profile and then generate HTML from the Readability results.
|
|
var readerModeStyle = DefaultReaderModeStyle
|
|
if let dict = profile.prefs.dictionaryForKey(ReaderModeProfileKeyStyle) {
|
|
if let style = ReaderModeStyle(dict: dict) {
|
|
readerModeStyle = style
|
|
}
|
|
}
|
|
if let html = ReaderModeUtils.generateReaderContent(readabilityResult, initialStyle: readerModeStyle),
|
|
let response = GCDWebServerDataResponse(html: html) {
|
|
// Apply a Content Security Policy that disallows everything except images from anywhere and fonts and css from our internal server
|
|
response.setValue("default-src 'none'; img-src *; style-src http://localhost:*; font-src http://localhost:*", forAdditionalHeader: "Content-Security-Policy")
|
|
return response
|
|
}
|
|
} catch _ {
|
|
// This page has not been converted to reader mode yet. This happens when you for example add an
|
|
// item via the app extension and the application has not yet had a change to readerize that
|
|
// page in the background.
|
|
//
|
|
// What we do is simply queue the page in the ReadabilityService and then show our loading
|
|
// screen, which will periodically call page-exists to see if the readerized content has
|
|
// become available.
|
|
ReadabilityService.sharedInstance.process(url, cache: readerModeCache)
|
|
if let readerViewLoadingPath = Bundle.main.path(forResource: "ReaderViewLoading", ofType: "html") {
|
|
do {
|
|
let readerViewLoading = try NSMutableString(contentsOfFile: readerViewLoadingPath, encoding: String.Encoding.utf8.rawValue)
|
|
readerViewLoading.replaceOccurrences(of: "%ORIGINAL-URL%", with: url.absoluteString,
|
|
options: NSString.CompareOptions.literal, range: NSRange(location: 0, length: readerViewLoading.length))
|
|
readerViewLoading.replaceOccurrences(of: "%LOADING-TEXT%", with: NSLocalizedString("Loading content…", comment: "Message displayed when the reader mode page is loading. This message will appear only when sharing to Firefox reader mode from another app."),
|
|
options: NSString.CompareOptions.literal, range: NSRange(location: 0, length: readerViewLoading.length))
|
|
readerViewLoading.replaceOccurrences(of: "%LOADING-FAILED-TEXT%", with: NSLocalizedString("The page could not be displayed in Reader View.", comment: "Message displayed when the reader mode page could not be loaded. This message will appear only when sharing to Firefox reader mode from another app."),
|
|
options: NSString.CompareOptions.literal, range: NSRange(location: 0, length: readerViewLoading.length))
|
|
readerViewLoading.replaceOccurrences(of: "%LOAD-ORIGINAL-TEXT%", with: NSLocalizedString("Load original page", comment: "Link for going to the non-reader page when the reader view could not be loaded. This message will appear only when sharing to Firefox reader mode from another app."),
|
|
options: NSString.CompareOptions.literal, range: NSRange(location: 0, length: readerViewLoading.length))
|
|
return GCDWebServerDataResponse(html: readerViewLoading as String)
|
|
} catch _ {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let errorString = NSLocalizedString("There was an error converting the page", comment: "Error displayed when reader mode cannot be enabled")
|
|
return GCDWebServerDataResponse(html: errorString) // TODO Needs a proper error page
|
|
}
|
|
}
|
|
}
|