1
1
mirror of https://github.com/qvacua/vimr.git synced 2024-10-27 10:23:12 +03:00

GH-405 Retain scroll position after reloading markdown

This commit is contained in:
Tae Won Ha 2017-04-21 07:45:28 +02:00
parent f5fbc6def3
commit c22acf29d5
No known key found for this signature in database
GPG Key ID: E40743465B5B8B44
2 changed files with 29 additions and 12 deletions

View File

@ -75,6 +75,7 @@ class PreviewTool: NSView, UiComponent, WKNavigationDelegate {
refreshOnWrite.action = #selector(PreviewTool.refreshOnWriteAction)
self.addViews()
self.webview.navigationDelegate = self
self.webview.load(URLRequest(url: state.preview.server!))
source
@ -98,6 +99,11 @@ class PreviewTool: NSView, UiComponent, WKNavigationDelegate {
guard state.preview.updateDate > self.lastUpdateDate else { return }
guard let serverUrl = state.preview.server else { return }
if serverUrl != self.url {
self.url = serverUrl
self.scrollTop = 0
self.previewPosition = Marked(Position.beginning)
}
self.lastUpdateDate = state.preview.updateDate
self.webview.load(URLRequest(url: serverUrl))
@ -111,8 +117,9 @@ class PreviewTool: NSView, UiComponent, WKNavigationDelegate {
self.webviewMessageHandler.source
.throttle(0.75, latest: true, scheduler: self.scheduler)
.subscribe(onNext: { [unowned self] position in
.subscribe(onNext: { [unowned self] (position, scrollTop) in
self.previewPosition = Marked(position)
self.scrollTop = scrollTop
self.emitter.emit(UuidAction(uuid: self.uuid, action: Action.scroll(to: self.previewPosition)))
})
.addDisposableTo(self.disposeBag)
@ -131,6 +138,10 @@ class PreviewTool: NSView, UiComponent, WKNavigationDelegate {
NSLog("ERROR preview component's webview: \(error)")
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webview.evaluateJavaScript("document.body.scrollTop = \(self.scrollTop)")
}
fileprivate let emitter: ActionEmitter
fileprivate let uuid: String
@ -139,9 +150,11 @@ class PreviewTool: NSView, UiComponent, WKNavigationDelegate {
fileprivate let scheduler = ConcurrentDispatchQueueScheduler(qos: .userInitiated)
fileprivate var isOpen = false
fileprivate var url: URL?
fileprivate var lastUpdateDate = Date.distantPast
fileprivate var editorPosition = Marked(Position.beginning)
fileprivate var previewPosition = Marked(Position.beginning)
fileprivate var scrollTop = 0
fileprivate let userContentController = WKUserContentController()
fileprivate let webviewMessageHandler = WebviewMessageHandler()
@ -194,7 +207,7 @@ extension PreviewTool {
fileprivate class WebviewMessageHandler: NSObject, WKScriptMessageHandler {
var source: Observable<Position> {
var source: Observable<(Position, Int)> {
return self.subject.asObservable()
}
@ -207,12 +220,15 @@ fileprivate class WebviewMessageHandler: NSObject, WKScriptMessageHandler {
return
}
guard let lineBegin = msgBody["lineBegin"], let columnBegin = msgBody["columnBegin"] else {
guard let lineBegin = msgBody["lineBegin"],
let columnBegin = msgBody["columnBegin"],
let scrollTop = msgBody["scrollTop"]
else {
return
}
self.subject.onNext(Position(row: lineBegin, column: columnBegin))
self.subject.onNext((Position(row: lineBegin, column: columnBegin), scrollTop))
}
fileprivate let subject = PublishSubject<Position>()
fileprivate let subject = PublishSubject<(Position, Int)>()
}

View File

@ -26,7 +26,7 @@
function positionOfMarkdownElement(element) {
const regexResult = element.dataset.sourcepos.match(sourceposRegex);
if (regexResult.length != 5) {
if (regexResult.length !== 5) {
return null;
}
@ -62,13 +62,14 @@
}
const result = positionOfMarkdownElement(candidate);
if (result.lineBegin == lastMarkdownPosition.lineBegin
&& result.columnBegin == lastMarkdownPosition.columnBegin
&& result.lineEnd == lastMarkdownPosition.lineEnd
&& result.columnEnd == lastMarkdownPosition.columnEnd)
if (result.lineBegin === lastMarkdownPosition.lineBegin
&& result.columnBegin === lastMarkdownPosition.columnBegin
&& result.lineEnd === lastMarkdownPosition.lineEnd
&& result.columnEnd === lastMarkdownPosition.columnEnd)
{
return;
}
result.scrollTop = document.body.scrollTop;
lastMarkdownPosition = result;
// console.log(`webview scrolled to ${result.lineBegin}:${result.columnBegin}`);
@ -110,13 +111,13 @@
return Math.min(result, entry.rowDistance)
}, Number.MAX_SAFE_INTEGER);
const entriesWithMinRowDistance = entries.filter(entry => entry.rowDistance == minRowDistance);
const entriesWithMinRowDistance = entries.filter(entry => entry.rowDistance === minRowDistance);
const minColumnDistance = entriesWithMinRowDistance.reduce((result, entry) => {
return Math.min(result, entry.columnDistance)
}, Number.MAX_SAFE_INTEGER);
const candidateEntry = entriesWithMinRowDistance.find(entry => entry.columnDistance == minColumnDistance);
const candidateEntry = entriesWithMinRowDistance.find(entry => entry.columnDistance === minColumnDistance);
if (!candidateEntry) {
return;
}