Browser improvements

This commit is contained in:
Ilya Laktyushin 2024-08-09 05:53:59 +02:00
parent f56903608c
commit bbe90fcadb
5 changed files with 255 additions and 228 deletions

View File

@ -9,7 +9,6 @@ import TelegramPresentationData
import TelegramUIPreferences
import PresentationDataUtils
import AccountContext
import WebKit
import AppBundle
import PromptUI
import SafariServices
@ -18,11 +17,11 @@ import UndoUI
import UrlEscaping
import PDFKit
final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate {
final class BrowserPdfContent: UIView, BrowserContent, UIScrollViewDelegate, PDFDocumentDelegate {
private let context: AccountContext
private var presentationData: PresentationData
private let webView: PDFView
private let pdfView: PDFView
private let scrollView: UIScrollView!
let uuid: UUID
@ -53,10 +52,10 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
self.uuid = UUID()
self.presentationData = presentationData
self.webView = PDFView()
self.pdfView = PDFView()
var scrollView: UIScrollView?
for view in self.webView.subviews {
for view in self.pdfView.subviews {
if let view = view as? UIScrollView {
scrollView = view
} else {
@ -69,12 +68,12 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
}
self.scrollView = scrollView
self.webView.displayDirection = .vertical
self.webView.autoScales = true
self.pdfView.displayDirection = .vertical
self.pdfView.autoScales = true
var title: String = "file"
if let path = self.context.account.postbox.mediaBox.completedResourcePath(file.resource), let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
self.webView.document = PDFDocument(data: data)
self.pdfView.document = PDFDocument(data: data)
title = file.fileName ?? "file"
}
@ -86,13 +85,13 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
if #available(iOS 15.0, *) {
self.backgroundColor = presentationData.theme.list.plainBackgroundColor
}
self.addSubview(self.webView)
self.addSubview(self.pdfView)
// Queue.mainQueue().after(1.0) {
// if let scrollView = self.scrollView {
// scrollView.delegate = self
// }
// }
Queue.mainQueue().after(1.0) {
if let scrollView = self.scrollView {
scrollView.delegate = self
}
}
}
required init?(coder: NSCoder) {
@ -109,134 +108,172 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
}
}
var currentFontState = BrowserPresentationState.FontState(size: 100, isSerif: false)
func updateFontState(_ state: BrowserPresentationState.FontState) {
self.updateFontState(state, force: false)
}
func updateFontState(_ state: BrowserPresentationState.FontState, force: Bool) {
self.currentFontState = state
}
// let fontFamily = state.isSerif ? "'Georgia, serif'" : "null"
// let textSizeAdjust = state.size != 100 ? "'\(state.size)%'" : "null"
// let js = "\(setupFontFunctions) setTelegramFontOverrides(\(fontFamily), \(textSizeAdjust))";
// self.webView.evaluateJavaScript(js) { _, _ in }
}
private var didSetupSearch = false
private func setupSearch(completion: @escaping () -> Void) {
// guard !self.didSetupSearch else {
// completion()
// return
// }
//
// let bundle = getAppBundle()
// guard let scriptPath = bundle.path(forResource: "UIWebViewSearch", ofType: "js") else {
// return
// }
// guard let scriptData = try? Data(contentsOf: URL(fileURLWithPath: scriptPath)) else {
// return
// }
// guard let script = String(data: scriptData, encoding: .utf8) else {
// return
// }
// self.didSetupSearch = true
// self.webView.evaluateJavaScript(script, completionHandler: { _, error in
// if error != nil {
// print()
// }
// completion()
// })
}
private var findSession: Any?
private var previousQuery: String?
func setSearch(_ query: String?, completion: ((Int) -> Void)?) {
// guard self.previousQuery != query else {
// return
// }
// self.previousQuery = query
// self.setupSearch { [weak self] in
// if let query = query {
// let js = "uiWebview_HighlightAllOccurencesOfString('\(query)')"
// self?.webView.evaluateJavaScript(js, completionHandler: { [weak self] _, _ in
// let js = "uiWebview_SearchResultCount"
// self?.webView.evaluateJavaScript(js, completionHandler: { [weak self] result, _ in
// if let result = result as? NSNumber {
// self?.searchResultsCount = result.intValue
// completion?(result.intValue)
// } else {
// completion?(0)
// }
// })
// })
// } else {
// let js = "uiWebview_RemoveAllHighlights()"
// self?.webView.evaluateJavaScript(js, completionHandler: nil)
//
// self?.currentSearchResult = 0
// self?.searchResultsCount = 0
// }
// }
}
private var currentSearchResult: Int = 0
private var searchResultsCount: Int = 0
private var searchResults: [PDFSelection] = []
private var searchCompletion: ((Int) -> Void)?
private var searchDimmingView: UIView?
private let matchColor = UIColor(rgb: 0xd4d4d, alpha: 0.2)
private let selectedColor = UIColor(rgb: 0xffe438)
func didMatchString(_ instance: PDFSelection) {
instance.color = self.matchColor
self.searchResults.append(instance)
}
func documentDidEndDocumentFind(_ notification: Notification) {
self.searchResultsCount = self.searchResults.count
if let searchCompletion = self.searchCompletion {
self.searchCompletion = nil
searchCompletion(self.searchResultsCount)
}
self.updateSearchHighlights(highlightedSelection: self.searchResults.first)
}
func updateSearchHighlights(highlightedSelection: PDFSelection?) {
self.pdfView.highlightedSelections = nil
if let highlightedSelection {
for selection in self.searchResults {
if selection === highlightedSelection {
selection.color = self.selectedColor
} else {
selection.color = self.matchColor
}
}
self.pdfView.highlightedSelections = self.searchResults
}
}
func setSearch(_ query: String?, completion: ((Int) -> Void)?) {
guard let document = self.pdfView.document, self.previousQuery != query else {
return
}
self.previousQuery = query
if #available(iOS 16.0, *), !"".isEmpty {
if let query {
var findSession: UIFindSession?
if let current = self.findSession as? UIFindSession {
findSession = current
} else {
self.pdfView.isFindInteractionEnabled = true
if let session = self.pdfView.findInteraction(self.pdfView.findInteraction, sessionFor: self.pdfView) {
findSession = session
self.findSession = session
self.pdfView.findInteraction(self.pdfView.findInteraction, didBegin: session)
}
}
if let findSession {
findSession.performSearch(query: query, options: BrowserSearchOptions())
self.pdfView.findInteraction.updateResultCount()
completion?(findSession.resultCount)
}
} else {
if let session = self.findSession as? UIFindSession {
self.pdfView.findInteraction(self.pdfView.findInteraction, didEnd: session)
self.findSession = nil
self.pdfView.isFindInteractionEnabled = false
}
}
} else {
if let query {
self.currentSearchResult = 0
self.searchCompletion = completion
document.cancelFindString()
document.delegate = self
document.beginFindString(query, withOptions: .caseInsensitive)
} else {
self.searchResults = []
self.currentSearchResult = 0
self.searchResultsCount = 0
self.updateSearchHighlights(highlightedSelection: nil)
document.cancelFindString()
document.delegate = nil
completion?(0)
}
}
}
func scrollToPreviousSearchResult(completion: ((Int, Int) -> Void)?) {
// let searchResultsCount = self.searchResultsCount
// var index = self.currentSearchResult - 1
// if index < 0 {
// index = searchResultsCount - 1
// }
// self.currentSearchResult = index
//
// let js = "uiWebview_ScrollTo('\(searchResultsCount - index - 1)')"
// self.webView.evaluateJavaScript(js, completionHandler: { _, _ in
// completion?(index, searchResultsCount)
// })
if #available(iOS 16.0, *), !"".isEmpty {
if let session = self.findSession as? UIFindSession {
session.highlightNextResult(in: .backward)
completion?(session.highlightedResultIndex, session.resultCount)
}
} else {
let searchResultsCount = self.searchResultsCount
var index = self.currentSearchResult - 1
if index < 0 {
index = searchResultsCount - 1
}
self.currentSearchResult = index
if index >= 0 && index < self.searchResults.count {
self.updateSearchHighlights(highlightedSelection: self.searchResults[index])
self.pdfView.go(to: self.searchResults[index])
completion?(index, searchResultsCount)
}
}
}
func scrollToNextSearchResult(completion: ((Int, Int) -> Void)?) {
// let searchResultsCount = self.searchResultsCount
// var index = self.currentSearchResult + 1
// if index >= searchResultsCount {
// index = 0
// }
// self.currentSearchResult = index
//
// let js = "uiWebview_ScrollTo('\(searchResultsCount - index - 1)')"
// self.webView.evaluateJavaScript(js, completionHandler: { _, _ in
// completion?(index, searchResultsCount)
// })
if #available(iOS 16.0, *), !"".isEmpty {
if let session = self.findSession as? UIFindSession {
session.highlightNextResult(in: .forward)
completion?(session.highlightedResultIndex, session.resultCount)
}
} else {
let searchResultsCount = self.searchResultsCount
var index = self.currentSearchResult + 1
if index >= searchResultsCount {
index = 0
}
self.currentSearchResult = index
if index >= 0 && index < self.searchResults.count {
self.updateSearchHighlights(highlightedSelection: self.searchResults[index])
self.pdfView.go(to: self.searchResults[index])
completion?(index, searchResultsCount)
}
}
}
func stop() {
// self.webView.stopLoading()
}
func reload() {
// self.webView.reload()
}
func navigateBack() {
// self.webView.goBack()
}
func navigateForward() {
// self.webView.goForward()
}
func navigateTo(historyItem: BrowserContentState.HistoryItem) {
// if let webItem = historyItem.webItem {
// self.webView.go(to: webItem)
// }
}
func navigateTo(address: String) {
// let finalUrl = explicitUrl(address)
// guard let url = URL(string: finalUrl) else {
// return
// }
// self.webView.load(URLRequest(url: url))
}
func scrollToTop() {
@ -250,14 +287,16 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
self.previousScrollingOffset = ScrollingOffsetState(value: self.scrollView.contentOffset.y, isDraggingOrDecelerating: self.scrollView.isDragging || self.scrollView.isDecelerating)
let webViewFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: CGSize(width: size.width - insets.left - insets.right, height: size.height - insets.top - insets.bottom))
transition.setFrame(view: self.webView, frame: webViewFrame)
let pdfViewFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: CGSize(width: size.width - insets.left - insets.right, height: size.height - insets.top - insets.bottom))
transition.setFrame(view: self.pdfView, frame: pdfViewFrame)
if let searchDimmingView = self.searchDimmingView {
transition.setFrame(view: searchDimmingView, frame: CGRect(origin: .zero, size: self.pdfView.bounds.size))
}
if isFirstTime {
self.webView.setNeedsLayout()
self.webView.layoutIfNeeded()
self.webView.minScaleFactor = self.webView.scaleFactorForSizeToFit
self.pdfView.setNeedsLayout()
self.pdfView.layoutIfNeeded()
self.pdfView.minScaleFactor = self.pdfView.scaleFactorForSizeToFit
}
}
@ -279,16 +318,29 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
self.updateScrollingOffset(isReset: false, transition: transition)
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
if let scrollViewDelegate = scrollView as? UIScrollViewDelegate {
return scrollViewDelegate.viewForZooming?(in: scrollView)
}
return nil
}
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
if let scrollViewDelegate = scrollView as? UIScrollViewDelegate {
scrollViewDelegate.scrollViewWillBeginZooming?(scrollView, with: view)
}
self.resetScrolling()
self.wasZooming = true
}
private var wasZooming = false
func scrollViewDidEndZooming(_ scrollView: UIScrollView, with view: UIView?, atScale scale: CGFloat) {
if let scrollViewDelegate = scrollView as? UIScrollViewDelegate {
scrollViewDelegate.scrollViewDidEndZooming?(scrollView, with: view, atScale: scale)
}
Queue.mainQueue().after(0.1, {
self.wasZooming = false
})
}
func scrollViewDidZoom(_ scrollView: UIScrollView) {
@ -298,7 +350,12 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.updateScrollingOffset(isReset: false, transition: .immediate)
if let scrollViewDelegate = scrollView as? UIScrollViewDelegate {
scrollViewDelegate.scrollViewDidScroll?(scrollView)
}
if !scrollView.isZooming && !self.wasZooming {
self.updateScrollingOffset(isReset: false, transition: .immediate)
}
}
public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
@ -353,90 +410,6 @@ final class BrowserPdfContent: UIView, BrowserContent, WKNavigationDelegate, WKU
self.updateScrollingOffset(isReset: true, transition: .spring(duration: 0.4))
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
// self.currentError = nil
self.updateFontState(self.currentFontState, force: true)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.updateState {
$0
.withUpdatedBackList(webView.backForwardList.backList.map { BrowserContentState.HistoryItem(webItem: $0) })
.withUpdatedForwardList(webView.backForwardList.forwardList.map { BrowserContentState.HistoryItem(webItem: $0) })
}
}
// func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
// if (error as NSError).code != -999 {
// self.currentError = error
// } else {
// self.currentError = nil
// }
// if let (size, insets) = self.validLayout {
// self.updateLayout(size: size, insets: insets, transition: .immediate)
// }
// }
//
// func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
// if (error as NSError).code != -999 {
// self.currentError = error
// } else {
// self.currentError = nil
// }
// if let (size, insets) = self.validLayout {
// self.updateLayout(size: size, insets: insets, transition: .immediate)
// }
// }
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil {
if let url = navigationAction.request.url?.absoluteString {
self.open(url: url, new: true)
}
}
return nil
}
func webViewDidClose(_ webView: WKWebView) {
self.close()
}
@available(iOSApplicationExtension 15.0, iOS 15.0, *)
func webView(_ webView: WKWebView, requestMediaCapturePermissionFor origin: WKSecurityOrigin, initiatedByFrame frame: WKFrameInfo, type: WKMediaCaptureType, decisionHandler: @escaping (WKPermissionDecision) -> Void) {
decisionHandler(.prompt)
}
// @available(iOS 13.0, *)
// func webView(_ webView: WKWebView, contextMenuConfigurationForElement elementInfo: WKContextMenuElementInfo, completionHandler: @escaping (UIContextMenuConfiguration?) -> Void) {
// guard let url = elementInfo.linkURL else {
// completionHandler(nil)
// return
// }
// let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
// let configuration = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { [weak self] _ in
// return UIMenu(title: "", children: [
// UIAction(title: presentationData.strings.Browser_ContextMenu_Open, image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Browser"), color: presentationData.theme.contextMenu.primaryColor), handler: { [weak self] _ in
// self?.open(url: url.absoluteString, new: false)
// }),
// UIAction(title: presentationData.strings.Browser_ContextMenu_OpenInNewTab, image: generateTintedImage(image: UIImage(bundleImageName: "Instant View/NewTab"), color: presentationData.theme.contextMenu.primaryColor), handler: { [weak self] _ in
// self?.open(url: url.absoluteString, new: true)
// }),
// UIAction(title: presentationData.strings.Browser_ContextMenu_AddToReadingList, image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReadingList"), color: presentationData.theme.contextMenu.primaryColor), handler: { _ in
// let _ = try? SSReadingList.default()?.addItem(with: url, title: nil, previewText: nil)
// }),
// UIAction(title: presentationData.strings.Browser_ContextMenu_CopyLink, image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: presentationData.theme.contextMenu.primaryColor), handler: { [weak self] _ in
// UIPasteboard.general.string = url.absoluteString
// self?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil)
// }),
// UIAction(title: presentationData.strings.Browser_ContextMenu_Share, image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: presentationData.theme.contextMenu.primaryColor), handler: { [weak self] _ in
// self?.share(url: url.absoluteString)
// })
// ])
// }
// completionHandler(configuration)
// }
private func open(url: String, new: Bool) {
let subject: BrowserScreen.Subject = .webPage(url: url)
if new, let navigationController = self.getNavigationController() {

View File

@ -641,6 +641,7 @@ public class BrowserScreen: ViewController, MinimizableController {
})
})
case .scrollToPreviousSearchResult:
self.view.window?.endEditing(true)
content.scrollToPreviousSearchResult(completion: { [weak self] index, count in
self?.updatePresentationState({ state in
var updatedState = state
@ -650,6 +651,7 @@ public class BrowserScreen: ViewController, MinimizableController {
})
})
case .scrollToNextSearchResult:
self.view.window?.endEditing(true)
content.scrollToNextSearchResult(completion: { [weak self] index, count in
self?.updatePresentationState({ state in
var updatedState = state
@ -1089,11 +1091,11 @@ public class BrowserScreen: ViewController, MinimizableController {
let canOpenIn = !(self.contentState?.url.hasPrefix("tonsite") ?? false)
var items: [ContextMenuItem] = []
items.append(.custom(fontItem, false))
if contentState.contentType == .document, contentState.title.lowercased().hasSuffix(".pdf") {
} else {
items.append(.custom(fontItem, false))
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.InstantPage_FontSanFrancisco, icon: forceIsSerif ? emptyIcon : checkIcon, action: { (controller, action) in
performAction.invoke(.updateFontIsSerif(false))
action(.default)
@ -1105,7 +1107,9 @@ public class BrowserScreen: ViewController, MinimizableController {
})))
}
items.append(.separator)
if !items.isEmpty {
items.append(.separator)
}
if case .webPage = contentState.contentType {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.WebBrowser_Reload, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Instant View/Settings/Reload"), color: theme.contextMenu.primaryColor) }, action: { (controller, action) in
@ -1113,7 +1117,7 @@ public class BrowserScreen: ViewController, MinimizableController {
action(.default)
})))
}
if [.webPage].contains(contentState.contentType) {
if [.webPage, .document].contains(contentState.contentType) {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.InstantPage_Search, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Instant View/Settings/Search"), color: theme.contextMenu.primaryColor) }, action: { (controller, action) in
performAction.invoke(.updateSearchActive(true))
action(.default)

View File

@ -2,6 +2,7 @@ import Foundation
import UIKit
import AsyncDisplayKit
import Display
import SwiftSignalKit
import ComponentFlow
import TelegramPresentationData
import AccountContext
@ -60,9 +61,8 @@ final class SearchBarContentComponent: Component {
}
}
private let activated: (Bool) -> Void = { _ in }
private let deactivated: (Bool) -> Void = { _ in }
private let updateQuery: (String?) -> Void = { _ in }
private let queryPromise = ValuePromise<String>()
private var queryDisposable: Disposable?
private let backgroundLayer: SimpleLayer
@ -145,6 +145,23 @@ final class SearchBarContentComponent: Component {
}
}
self.clearIconButton.addTarget(self, action: #selector(self.clearPressed), for: .touchUpInside)
let throttledSearchQuery = self.queryPromise.get()
|> mapToSignal { query -> Signal<String, NoError> in
if !query.isEmpty {
return (.complete() |> delay(0.6, queue: Queue.mainQueue()))
|> then(.single(query))
} else {
return .single(query)
}
}
self.queryDisposable = (throttledSearchQuery
|> deliverOnMainQueue).start(next: { [weak self] query in
if let self {
self.component?.performAction.invoke(.updateSearchQuery(query))
}
})
}
required public init?(coder: NSCoder) {
@ -174,23 +191,17 @@ final class SearchBarContentComponent: Component {
guard !(self.textField?.isFirstResponder ?? false) else {
return
}
self.activated(true)
self.textField?.becomeFirstResponder()
}
@objc private func cancelPressed() {
self.updateQuery(nil)
self.clearIconView.isHidden = true
self.clearIconButton.isHidden = true
let textField = self.textField
self.textField = nil
self.deactivated(textField?.isFirstResponder ?? false)
self.component?.performAction.invoke(.updateSearchActive(false))
if let textField {
@ -200,11 +211,11 @@ final class SearchBarContentComponent: Component {
}
@objc private func clearPressed() {
self.updateQuery(nil)
self.textField?.text = ""
self.clearIconView.isHidden = true
self.clearIconButton.isHidden = true
guard let textField = self.textField else {
return
}
textField.text = ""
self.textFieldChanged(textField)
}
func deactivate() {
@ -232,10 +243,8 @@ final class SearchBarContentComponent: Component {
self.clearIconView.isHidden = text.isEmpty
self.clearIconButton.isHidden = text.isEmpty
self.placeholderContent.view?.isHidden = !text.isEmpty
self.updateQuery(text)
self.component?.performAction.invoke(.updateSearchQuery(text))
self.queryPromise.set(text)
if let params = self.params {
self.update(theme: params.theme, strings: params.strings, size: params.size, transition: .immediate)

View File

@ -177,6 +177,8 @@ final class NavigationToolbarContentComponent: CombinedComponent {
let share = Child(Button.self)
let bookmark = Child(Button.self)
let openIn = Child(Button.self)
let search = Child(Button.self)
let quickLook = Child(Button.self)
return { context in
let availableSize = context.availableSize
@ -211,7 +213,45 @@ final class NavigationToolbarContentComponent: CombinedComponent {
if context.component.isDocument {
context.add(share
.position(CGPoint(x: sideInset + share.size.width / 2.0, y: availableSize.height / 2.0))
.position(CGPoint(x: availableSize.width / 2.0, y: availableSize.height / 2.0))
)
let search = search.update(
component: Button(
content: AnyComponent(
BundleIconComponent(
name: "Chat List/SearchIcon",
tintColor: context.component.accentColor
)
),
action: {
performAction.invoke(.updateSearchActive(true))
}
).minSize(buttonSize),
availableSize: buttonSize,
transition: .easeInOut(duration: 0.2)
)
context.add(search
.position(CGPoint(x: sideInset + search.size.width / 2.0, y: availableSize.height / 2.0))
)
let quickLook = quickLook.update(
component: Button(
content: AnyComponent(
BundleIconComponent(
name: "Stories/EmbeddedViewIcon",
tintColor: context.component.accentColor
)
),
action: {
performAction.invoke(.openIn)
}
).minSize(buttonSize),
availableSize: buttonSize,
transition: .easeInOut(duration: 0.2)
)
context.add(quickLook
.position(CGPoint(x: context.availableSize.width - sideInset - quickLook.size.width / 2.0, y: availableSize.height / 2.0))
)
} else {
let canGoBack = context.component.canGoBack

View File

@ -460,6 +460,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
self?.currentSearchResult = 0
self?.searchResultsCount = 0
completion?(0)
}
}
}