Summary
When switching between notes in preview mode, clicking links (asset links, external URLs) and toggling checkboxes stops working. The same issue affects scroll position tracking.
Steps to Reproduce
- Open Note A in preview mode (Cmd+/)
- Click a link in Note A — it works
- Switch to Note B (also in preview mode)
- Click a link in Note B — may or may not work
- Switch back to Note A
- Click any link in Note A — nothing happens
Root Cause
The MPreviewView (WKWebView subclass) is reused across note switches — loadMarkdownWebView() only creates a new instance on first use. On subsequent note switches, it calls webView.load(note:force:) which loads new HTML but does NOT update the native WKScriptMessageHandler instances.
Three handlers hold a strong reference to the original note from init() time:
HandlerOpen — handles link clicks
HandlerCheckbox — handles checkbox toggles
PreviewScrollHandler — tracks scroll position
These are added to the WKUserContentController during MPreviewView.init() and never updated. When you switch to Note B, HandlerOpen still resolves asset paths against Note A's directory.
Additionally, the JavaScript <a> click handler used event.target.getAttribute("href") which returns null when the click hits a child element inside the <a> tag (should use event.currentTarget). And MPreviewView.decidePolicyFor uses a weak var note reference that can become nil.
Proposed Fix
-
Store handlers as properties on MPreviewView and update their note references in load(note:force:):
public func load(note: Note, force: Bool = false) {
guard self.note != note || force else { return }
self.note = note
handlerOpen.note = note
handlerCheckbox.note = note
handlerScroll.note = note
// ... load HTML ...
}
-
Fix JavaScript click handler to use event.currentTarget instead of event.target, and add event.preventDefault() to prevent double-handling via decidePolicyFor.
-
Add fallback in decidePolicyFor to use ViewController.shared()?.notesTableView.getSelectedNote() when the weak self.note is nil.
Files Changed
MPreviewView.swift — Store handler references; update in load(); fix decidePolicyFor fallback
index.html — Fix event.target → event.currentTarget; add event.preventDefault()
🤖 Generated with Claude Code
Summary
When switching between notes in preview mode, clicking links (asset links, external URLs) and toggling checkboxes stops working. The same issue affects scroll position tracking.
Steps to Reproduce
Root Cause
The
MPreviewView(WKWebView subclass) is reused across note switches —loadMarkdownWebView()only creates a new instance on first use. On subsequent note switches, it callswebView.load(note:force:)which loads new HTML but does NOT update the nativeWKScriptMessageHandlerinstances.Three handlers hold a strong reference to the original note from
init()time:HandlerOpen— handles link clicksHandlerCheckbox— handles checkbox togglesPreviewScrollHandler— tracks scroll positionThese are added to the
WKUserContentControllerduringMPreviewView.init()and never updated. When you switch to Note B,HandlerOpenstill resolves asset paths against Note A's directory.Additionally, the JavaScript
<a>click handler usedevent.target.getAttribute("href")which returnsnullwhen the click hits a child element inside the<a>tag (should useevent.currentTarget). AndMPreviewView.decidePolicyForuses aweak var notereference that can become nil.Proposed Fix
Store handlers as properties on
MPreviewViewand update theirnotereferences inload(note:force:):Fix JavaScript click handler to use
event.currentTargetinstead ofevent.target, and addevent.preventDefault()to prevent double-handling viadecidePolicyFor.Add fallback in
decidePolicyForto useViewController.shared()?.notesTableView.getSelectedNote()when the weakself.noteis nil.Files Changed
MPreviewView.swift— Store handler references; update inload(); fixdecidePolicyForfallbackindex.html— Fixevent.target→event.currentTarget; addevent.preventDefault()🤖 Generated with Claude Code