Spaces:
Sleeping
Sleeping
File size: 5,588 Bytes
7aec436 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
import Cocoa
import WebKit
class ViewController: NSViewController, WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler {
@IBOutlet var webView: WKWebView!
var windowTitle: String = "Window Title"
override func loadView() {
super.loadView()
let configUrl = Bundle.main.url(forResource: "application_config", withExtension: "json")!
let configContents = try! Data(contentsOf: configUrl);
let configParsed = try! JSONSerialization.jsonObject(with: configContents, options: [])
var width = 480
var height = 360
var background = NSColor.black.cgColor
if let dict = configParsed as? [String: Any] {
if let title = dict["title"] as? String {
self.windowTitle = title
}
if let number = dict["width"] as? Int {
width = number
}
if let number = dict["height"] as? Int {
height = number
}
if let color = dict["background"] as? [Int] {
background = NSColor(
red: CGFloat(color[0]) / 255.0,
green: CGFloat(color[1]) / 255.0,
blue: CGFloat(color[2]) / 255.0,
alpha: CGFloat(color[3])
).cgColor
}
}
view.wantsLayer = true
view.layer?.backgroundColor = background
view.frame = CGRect(x: 0, y: 0, width: width, height: height)
webView.navigationDelegate = self
webView.uiDelegate = self
webView.configuration.userContentController.add(self, name: "download")
webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
#if DEBUG
webView.configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
#endif
webView.isHidden = true
}
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "index", withExtension: "html")!
webView.loadFileURL(url, allowingReadAccessTo: url.deletingLastPathComponent())
}
override func viewDidAppear() {
super.viewDidAppear()
view.window?.title = windowTitle
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// The packager will use window.ExternalDownloadHelper instead of native JS file downloads.
// We use this because older versions of macOS's WKWebView do not handle file downloads
// properly or at all.
webView.evaluateJavaScript("""
window.ExternalDownloadHelper = {
download: (filename, blob) => {
const reader = new FileReader();
reader.onload = () => {
const array = Array.from(new Uint8Array(reader.result));
webkit.messageHandlers.download.postMessage({
name: filename,
data: array
});
};
reader.onerror = () => {
console.error(reader.error);
};
reader.readAsArrayBuffer(blob);
}
};
""")
webView.isHidden = false
}
func webView(_ webView: WKWebView, runOpenPanelWith parameters: WKOpenPanelParameters, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping ([URL]?) -> Void) {
// Used by list import.
let panel = NSOpenPanel()
panel.canChooseFiles = true
panel.canChooseDirectories = false
panel.allowsMultipleSelection = parameters.allowsMultipleSelection
panel.allowedFileTypes = ["txt", "csv", "tsv"]
panel.allowsOtherFileTypes = true
panel.begin { (result) -> Void in
if result == NSApplication.ModalResponse.OK, let url = panel.url {
completionHandler([url])
} else {
completionHandler(nil)
}
}
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// Used by window.ExternalDownloadHelper which is used by list export.
if message.name == "download",
let body = message.body as? NSDictionary,
let name = body["name"] as? NSString,
let rawData = body["data"] as? [UInt8] {
let panel = NSSavePanel()
panel.allowsOtherFileTypes = true
panel.nameFieldStringValue = name as String
panel.allowedFileTypes = ["txt"]
panel.begin { (result) -> Void in
if result == NSApplication.ModalResponse.OK, let url = panel.url {
let data = Data(rawData)
try! data.write(to: url)
}
}
}
}
@available(macOS 12.0, *)
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
// macOS will already show a permission prompt.
// This code prevents WKWebView from showing an additional permission prompt each time.
decisionHandler(WKPermissionDecision.grant)
}
func webViewDidClose(_ webView: WKWebView) {
// Implements window.close()
self.view.window?.close();
}
}
|