Attempt to fix stale tabs losing info
This commit is contained in:
@@ -19,7 +19,6 @@ class Tab: NSObject, SBRProcessBundleBridgeDelegate
|
|||||||
|
|
||||||
public var tabInfo: TabInfo {
|
public var tabInfo: TabInfo {
|
||||||
get {
|
get {
|
||||||
updateMetadata()
|
|
||||||
return _tabInfo
|
return _tabInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,18 +38,14 @@ class Tab: NSObject, SBRProcessBundleBridgeDelegate
|
|||||||
}
|
}
|
||||||
public var policyManager: ResourcePolicyManager
|
public var policyManager: ResourcePolicyManager
|
||||||
|
|
||||||
private var _tabInfo: TabInfo = TabInfo()
|
// Persisted snapshot of visible tab metadata; do not recompute on read.
|
||||||
|
var _tabInfo: TabInfo = TabInfo()
|
||||||
|
|
||||||
private var loadedWebView: WKWebView? = nil
|
private var loadedWebView: WKWebView? = nil
|
||||||
public var title: String? { get { tabInfo.title } }
|
public var title: String? { get { tabInfo.title } }
|
||||||
public var url: URL? {
|
public var url: URL? {
|
||||||
get {
|
if let urlString = tabInfo.urlString { return URL(string: urlString) }
|
||||||
if let urlString = tabInfo.urlString {
|
return nil
|
||||||
return URL(string: urlString)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var javaScriptEnabled: Bool = false {
|
public var javaScriptEnabled: Bool = false {
|
||||||
@@ -110,6 +105,10 @@ class Tab: NSObject, SBRProcessBundleBridgeDelegate
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
bridge.delegate = self
|
bridge.delegate = self
|
||||||
|
|
||||||
|
// Initialize snapshot metadata
|
||||||
|
_tabInfo.identifier = self.identifier
|
||||||
|
if let url { _tabInfo.urlString = url.absoluteString }
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@@ -117,6 +116,8 @@ class Tab: NSObject, SBRProcessBundleBridgeDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
func beginLoadingURL(_ url: URL) {
|
func beginLoadingURL(_ url: URL) {
|
||||||
|
// Update snapshot immediately so UI keeps URL even if process jettisons.
|
||||||
|
_tabInfo.urlString = url.absoluteString
|
||||||
let request = URLRequest(url: url)
|
let request = URLRequest(url: url)
|
||||||
webView.load(request)
|
webView.load(request)
|
||||||
}
|
}
|
||||||
@@ -150,15 +151,4 @@ class Tab: NSObject, SBRProcessBundleBridgeDelegate
|
|||||||
.assign(to: \.favicon, on: self)
|
.assign(to: \.favicon, on: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateMetadata() {
|
|
||||||
guard contentProcessTerminated == false else { return }
|
|
||||||
|
|
||||||
_tabInfo = TabInfo(
|
|
||||||
title: loadedWebView?.title,
|
|
||||||
urlString: loadedWebView?.url?.absoluteString ?? self.homeURL?.absoluteString,
|
|
||||||
faviconData: self.favicon?.pngData(),
|
|
||||||
identifier: self.identifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,16 +49,28 @@ class TabController
|
|||||||
tabs.append(tab)
|
tabs.append(tab)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Title observation
|
// Title observation: update snapshot and notify delegate.
|
||||||
tab.titleObservation = tab.webView.observe(\.title, changeHandler: { [weak tab, weak self] (webView, change) in
|
tab.titleObservation = tab.webView.observe(\.title, changeHandler: { [weak tab, weak self] (webView, change) in
|
||||||
if let tab = tab, let self = self, let delegate = self.controllerDelegate {
|
guard let tab = tab else { return }
|
||||||
|
if let newTitle = webView.title, !newTitle.isEmpty {
|
||||||
|
tab._tabInfo.title = newTitle
|
||||||
|
}
|
||||||
|
if let self = self, let delegate = self.controllerDelegate {
|
||||||
delegate.tabController(self, didUpdateTitle: webView.title ?? "", forTab: tab)
|
delegate.tabController(self, didUpdateTitle: webView.title ?? "", forTab: tab)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// URL observation: persist the latest URL in the snapshot.
|
||||||
|
tab.urlObservation = tab.webView.observe(\.url, changeHandler: { [weak tab] (webView, change) in
|
||||||
|
guard let tab = tab else { return }
|
||||||
|
tab._tabInfo.urlString = webView.url?.absoluteString ?? tab._tabInfo.urlString
|
||||||
|
})
|
||||||
|
|
||||||
// Favicon Observation
|
// Favicon Observation
|
||||||
tab.faviconObservation = tab.$favicon.receive(on: RunLoop.main).sink { [weak tab, weak self] val in
|
tab.faviconObservation = tab.$favicon.receive(on: RunLoop.main).sink { [weak tab, weak self] val in
|
||||||
if let tab = tab, let self = self, let delegate = self.controllerDelegate {
|
guard let tab = tab else { return }
|
||||||
|
tab._tabInfo.faviconData = val?.pngData()
|
||||||
|
if let self = self, let delegate = self.controllerDelegate {
|
||||||
delegate.tabController(self, didUpdateFavicon: val, forTab: tab)
|
delegate.tabController(self, didUpdateFavicon: val, forTab: tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -790,7 +790,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "App/Supporting Files/SBrowser.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "App/Supporting Files/SBrowser.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 5;
|
CURRENT_PROJECT_VERSION = 6;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = 3SJALV9BQ7;
|
DEVELOPMENT_TEAM = 3SJALV9BQ7;
|
||||||
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
|
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
|
||||||
@@ -801,7 +801,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 4.0;
|
MARKETING_VERSION = 4.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.attractor;
|
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.attractor;
|
||||||
PRODUCT_NAME = Attractor;
|
PRODUCT_NAME = Attractor;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@@ -825,7 +825,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "App/Supporting Files/SBrowser.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "App/Supporting Files/SBrowser.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 5;
|
CURRENT_PROJECT_VERSION = 6;
|
||||||
DEAD_CODE_STRIPPING = YES;
|
DEAD_CODE_STRIPPING = YES;
|
||||||
DEVELOPMENT_TEAM = 3SJALV9BQ7;
|
DEVELOPMENT_TEAM = 3SJALV9BQ7;
|
||||||
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
|
INFOPLIST_FILE = "App/Supporting Files/Info.plist";
|
||||||
@@ -836,7 +836,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 4.0;
|
MARKETING_VERSION = 4.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.attractor;
|
PRODUCT_BUNDLE_IDENTIFIER = net.buzzert.attractor;
|
||||||
PRODUCT_NAME = Attractor;
|
PRODUCT_NAME = Attractor;
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
Reference in New Issue
Block a user