2018-02-10 20:16:09 +01:00
|
|
|
|
//
|
|
|
|
|
// DetailWebView.swift
|
2018-08-29 07:18:24 +02:00
|
|
|
|
// NetNewsWire
|
2018-02-10 20:16:09 +01:00
|
|
|
|
//
|
|
|
|
|
// Created by Brent Simmons on 2/10/18.
|
|
|
|
|
// Copyright © 2018 Ranchero Software. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import AppKit
|
|
|
|
|
import WebKit
|
2019-04-13 23:34:00 +02:00
|
|
|
|
import RSCore
|
2018-02-10 20:16:09 +01:00
|
|
|
|
|
|
|
|
|
final class DetailWebView: WKWebView {
|
|
|
|
|
|
2019-03-01 23:56:40 +01:00
|
|
|
|
weak var keyboardDelegate: KeyboardDelegate?
|
|
|
|
|
|
2019-09-10 18:09:17 +02:00
|
|
|
|
override func accessibilityLabel() -> String? {
|
|
|
|
|
return NSLocalizedString("Article", comment: "Article")
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-01 23:56:40 +01:00
|
|
|
|
// MARK: - NSResponder
|
|
|
|
|
|
|
|
|
|
override func keyDown(with event: NSEvent) {
|
|
|
|
|
if keyboardDelegate?.keydown(event, in: self) ?? false {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
super.keyDown(with: event)
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 20:16:09 +01:00
|
|
|
|
// MARK: NSView
|
|
|
|
|
|
|
|
|
|
override func willOpenMenu(_ menu: NSMenu, with event: NSEvent) {
|
2019-02-13 07:56:44 +01:00
|
|
|
|
// There’s no API for affecting a WKWebView’s contextual menu.
|
|
|
|
|
// (WebView had API for this.)
|
|
|
|
|
//
|
|
|
|
|
// This a minor hack. It hides unwanted menu items.
|
|
|
|
|
// The menu item identifiers are not documented anywhere;
|
|
|
|
|
// they could change, and this code would need updating.
|
2018-02-10 20:16:09 +01:00
|
|
|
|
for menuItem in menu.items {
|
|
|
|
|
if shouldHideMenuItem(menuItem) {
|
|
|
|
|
menuItem.isHidden = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
super.willOpenMenu(menu, with: event)
|
|
|
|
|
}
|
2018-09-10 20:39:41 +02:00
|
|
|
|
|
2019-02-13 03:18:08 +01:00
|
|
|
|
override func viewWillStartLiveResize() {
|
|
|
|
|
super.viewWillStartLiveResize()
|
|
|
|
|
evaluateJavaScript("document.body.style.overflow = 'hidden';", completionHandler: nil)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func viewDidEndLiveResize() {
|
|
|
|
|
super.viewDidEndLiveResize()
|
|
|
|
|
evaluateJavaScript("document.body.style.overflow = 'visible';", completionHandler: nil)
|
2021-04-30 05:55:23 +02:00
|
|
|
|
bigSurOffsetFix()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func setFrameSize(_ newSize: NSSize) {
|
|
|
|
|
super.setFrameSize(newSize)
|
2021-04-30 06:52:15 +02:00
|
|
|
|
if (!inLiveResize) {
|
2021-04-30 05:55:23 +02:00
|
|
|
|
bigSurOffsetFix()
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-03-08 03:28:51 +01:00
|
|
|
|
|
2021-04-30 06:52:15 +02:00
|
|
|
|
private var inBigSurOffsetFix = false
|
|
|
|
|
|
2021-04-30 05:55:23 +02:00
|
|
|
|
private func bigSurOffsetFix() {
|
2021-03-08 07:12:32 +01:00
|
|
|
|
/*
|
|
|
|
|
On macOS 11, when a user exits full screen
|
|
|
|
|
or exits zoomed mode by disconnecting an external display
|
|
|
|
|
the webview's `origin.y` is offset by a sizeable amount.
|
2021-03-08 03:28:51 +01:00
|
|
|
|
|
2021-03-08 07:12:32 +01:00
|
|
|
|
This code adjusts the height of the window by -1pt/+1pt,
|
|
|
|
|
which puts the webview back in the correct place.
|
|
|
|
|
*/
|
2021-03-08 03:28:51 +01:00
|
|
|
|
if #available(macOS 11, *) {
|
|
|
|
|
guard var frame = window?.frame else {
|
|
|
|
|
return
|
|
|
|
|
}
|
2021-04-30 06:52:15 +02:00
|
|
|
|
|
|
|
|
|
guard !inBigSurOffsetFix else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inBigSurOffsetFix = true
|
|
|
|
|
|
|
|
|
|
defer {
|
|
|
|
|
inBigSurOffsetFix = false
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-08 03:28:51 +01:00
|
|
|
|
frame.size = NSSize(width: window!.frame.width, height: window!.frame.height - 1)
|
|
|
|
|
window!.setFrame(frame, display: false)
|
|
|
|
|
frame.size = NSSize(width: window!.frame.width, height: window!.frame.height + 1)
|
|
|
|
|
window!.setFrame(frame, display: false)
|
|
|
|
|
}
|
2019-02-13 03:18:08 +01:00
|
|
|
|
}
|
2018-02-10 20:16:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 07:56:44 +01:00
|
|
|
|
// MARK: - Private
|
|
|
|
|
|
2018-02-10 20:16:09 +01:00
|
|
|
|
private extension NSUserInterfaceItemIdentifier {
|
|
|
|
|
|
|
|
|
|
static let DetailMenuItemIdentifierReload = NSUserInterfaceItemIdentifier(rawValue: "WKMenuItemIdentifierReload")
|
|
|
|
|
static let DetailMenuItemIdentifierOpenLink = NSUserInterfaceItemIdentifier(rawValue: "WKMenuItemIdentifierOpenLink")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private extension DetailWebView {
|
|
|
|
|
|
|
|
|
|
static let menuItemIdentifiersToHide: [NSUserInterfaceItemIdentifier] = [.DetailMenuItemIdentifierReload, .DetailMenuItemIdentifierOpenLink]
|
|
|
|
|
static let menuItemIdentifierMatchStrings = ["newwindow", "download"]
|
|
|
|
|
|
|
|
|
|
func shouldHideMenuItem(_ menuItem: NSMenuItem) -> Bool {
|
|
|
|
|
|
|
|
|
|
guard let identifier = menuItem.identifier else {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if DetailWebView.menuItemIdentifiersToHide.contains(identifier) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let lowerIdentifier = identifier.rawValue.lowercased()
|
|
|
|
|
for matchString in DetailWebView.menuItemIdentifierMatchStrings {
|
|
|
|
|
if lowerIdentifier.contains(matchString) {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|