Skip to content

Commit b47d269

Browse files
committed
fix(mdviewer): extract CM event handlers and use off→on pattern
Extract focus and change handlers into named variables so they can be properly removed in deactivate(). Use off→on pattern for all CM event listeners (cursorActivity, focus, change) to prevent duplicate listeners on re-activation.
1 parent 91327d1 commit b47d269

1 file changed

Lines changed: 28 additions & 8 deletions

File tree

src/extensionsIntegrated/Phoenix-live-preview/MarkdownSync.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ define(function (require, exports, module) {
4444
let _docChangeHandler = null;
4545
let _themeChangeHandler = null;
4646
let _cursorHandler = null;
47+
let _focusHandler = null;
48+
let _changeHandler = null;
4749
let _onEditModeRequest = null;
4850
let _onIframeReadyCallback = null;
4951
let _cursorSyncEnabled = true;
@@ -205,20 +207,26 @@ define(function (require, exports, module) {
205207
const cm = _getCM();
206208
_activeCM = cm;
207209
if (cm) {
208-
cm.on("cursorActivity", _cursorHandler);
209210
// Clear sync highlight when CM gets focus (user is editing in CM)
210-
cm.on("focus", function () {
211+
_focusHandler = function () {
211212
if (_highlightLineHandle) {
212213
cm.removeLineClass(_highlightLineHandle, "background", "cm-cursor-sync-highlight");
213214
_highlightLineHandle = null;
214215
}
215-
});
216+
};
216217
// Listen for change origin (undo/redo detection)
217-
cm.on("change", function (_cm, changeObj) {
218+
_changeHandler = function (_cm, changeObj) {
218219
if (changeObj) {
219220
_lastChangeOrigin = changeObj.origin;
220221
}
221-
});
222+
};
223+
// off→on to prevent duplicate listeners on re-activation
224+
cm.off("cursorActivity", _cursorHandler);
225+
cm.on("cursorActivity", _cursorHandler);
226+
cm.off("focus", _focusHandler);
227+
cm.on("focus", _focusHandler);
228+
cm.off("change", _changeHandler);
229+
cm.on("change", _changeHandler);
222230
}
223231

224232
// If iframe is already ready (reusing same iframe), switch file using cache
@@ -241,11 +249,21 @@ define(function (require, exports, module) {
241249
clearTimeout(_scrollSyncTimer);
242250
clearTimeout(_selectionSyncTimer);
243251

244-
if (_cursorHandler) {
245-
const cm = _getCM();
246-
if (cm) {
252+
const cm = _getCM();
253+
if (cm) {
254+
if (_cursorHandler) {
247255
cm.off("cursorActivity", _cursorHandler);
248256
}
257+
if (_focusHandler) {
258+
cm.off("focus", _focusHandler);
259+
}
260+
if (_changeHandler) {
261+
cm.off("change", _changeHandler);
262+
}
263+
if (_highlightLineHandle) {
264+
cm.removeLineClass(_highlightLineHandle, "background", "cm-cursor-sync-highlight");
265+
_highlightLineHandle = null;
266+
}
249267
}
250268

251269
if (_doc && _docChangeHandler) {
@@ -269,6 +287,8 @@ define(function (require, exports, module) {
269287
_messageHandler = null;
270288
_themeChangeHandler = null;
271289
_cursorHandler = null;
290+
_focusHandler = null;
291+
_changeHandler = null;
272292
}
273293

274294
/**

0 commit comments

Comments
 (0)