diff --git a/assets/js/hooks/cell.js b/assets/js/hooks/cell.js index 9d551a7ddf9..7725b4a816d 100644 --- a/assets/js/hooks/cell.js +++ b/assets/js/hooks/cell.js @@ -85,13 +85,23 @@ const Cell = { this.subscriptions = [ globalPubsub.subscribe( - "navigation", - this.handleNavigationEvent.bind(this), + "navigation:focus_changed", + ({ focusableId, scroll }) => + this.handleElementFocused(focusableId, scroll), + ), + globalPubsub.subscribe("navigation:insert_mode_changed", ({ enabled }) => + this.handleInsertModeChanged(enabled), + ), + globalPubsub.subscribe("cells:cell_moved", ({ cellId }) => + this.handleCellMoved(cellId), ), - globalPubsub.subscribe("cells", this.handleCellsEvent.bind(this)), globalPubsub.subscribe( - `cells:${this.props.cellId}`, - this.handleCellEvent.bind(this), + `cells:${this.props.cellId}:dispatch_queue_evaluation`, + ({ dispatch }) => this.handleDispatchQueueEvaluation(dispatch), + ), + globalPubsub.subscribe( + `cells:${this.props.cellId}:jump_to_line`, + ({ line, offset = 0 }) => this.handleJumpToLine(line, offset), ), ]; @@ -138,30 +148,6 @@ const Cell = { ]); }, - handleNavigationEvent(event) { - if (event.type === "element_focused") { - this.handleElementFocused(event.focusableId, event.scroll); - } else if (event.type === "insert_mode_changed") { - this.handleInsertModeChanged(event.enabled); - } - }, - - handleCellsEvent(event) { - if (event.type === "cell_moved") { - this.handleCellMoved(event.cellId); - } - }, - - handleCellEvent(event) { - if (event.type === "dispatch_queue_evaluation") { - this.handleDispatchQueueEvaluation(event.dispatch); - } else if (event.type === "jump_to_line") { - if (this.isFocused) { - this.currentEditor().moveCursorToLine(event.line, event.offset || 0); - } - } - }, - handleElementFocused(focusableId, scroll) { if (this.props.cellId === focusableId) { this.isFocused = true; @@ -355,8 +341,7 @@ const Cell = { handleDispatchQueueEvaluation(dispatch) { if (this.props.type === "smart" && this.props.smartCellJsViewRef) { // Ensure the smart cell UI is reflected on the server, before the evaluation - globalPubsub.broadcast(`js_views:${this.props.smartCellJsViewRef}`, { - type: "sync", + globalPubsub.broadcast(`js_views:${this.props.smartCellJsViewRef}:sync`, { callback: dispatch, }); } else { @@ -364,6 +349,12 @@ const Cell = { } }, + handleJumpToLine(line, offset) { + if (this.isFocused) { + this.currentEditor().moveCursorToLine(line, offset); + } + }, + scrollEditorCursorIntoViewIfNeeded() { const element = this.currentEditor().getElementAtCursor(); @@ -381,9 +372,9 @@ const Cell = { const cursor = this.currentEditor().getCurrentCursorPosition(); if (cursor === null) return; - globalPubsub.broadcast("history", { - ...cursor, - type: "navigation", + globalPubsub.broadcast("navigation:cursor_moved", { + line: cursor.line, + offset: cursor.offset, cellId: this.props.cellId, }); }, diff --git a/assets/js/hooks/headline.js b/assets/js/hooks/headline.js index ed96e09aeb7..6616ef6c18e 100644 --- a/assets/js/hooks/headline.js +++ b/assets/js/hooks/headline.js @@ -26,10 +26,16 @@ const Headline = { this.initializeHeadingEl(); - this.navigationSubscription = globalPubsub.subscribe( - "navigation", - this.handleNavigationEvent.bind(this), - ); + this.subscriptions = [ + globalPubsub.subscribe( + "navigation:focus_changed", + ({ focusableId, scroll }) => + this.handleElementFocused(focusableId, scroll), + ), + globalPubsub.subscribe("navigation:insert_mode_changed", ({ enabled }) => + this.handleInsertModeChanged(enabled), + ), + ]; }, updated() { @@ -38,7 +44,7 @@ const Headline = { }, destroyed() { - this.navigationSubscription.destroy(); + this.subscriptions.forEach((subscription) => subscription.destroy()); }, getProps() { @@ -80,14 +86,6 @@ const Headline = { }); }, - handleNavigationEvent(event) { - if (event.type === "element_focused") { - this.handleElementFocused(event.focusableId, event.scroll); - } else if (event.type === "insert_mode_changed") { - this.handleInsertModeChanged(event.enabled); - } - }, - handleElementFocused(focusableId, scroll) { if (this.props.id === focusableId) { this.isFocused = true; diff --git a/assets/js/hooks/js_view.js b/assets/js/hooks/js_view.js index 767314d6a9f..36fbd7ad009 100644 --- a/assets/js/hooks/js_view.js +++ b/assets/js/hooks/js_view.js @@ -132,12 +132,15 @@ const JSView = { this.subscriptions = [ globalPubsub.subscribe( - `js_views:${this.props.ref}`, - this.handleJSViewEvent.bind(this), + `js_views:${this.props.ref}:sync`, + ({ callback }) => this.handleSync(callback), ), globalPubsub.subscribe( - "navigation", - this.handleNavigationEvent.bind(this), + `js_views:${this.props.ref}:secret_selected`, + ({ secretName }) => this.handleSecretSelected(secretName), + ), + globalPubsub.subscribe("navigation:focus_changed", ({ focusableId }) => + this.handleElementFocused(focusableId), ), ]; @@ -248,11 +251,10 @@ const JSView = { // dispatched to trigger reposition. This way we don't need to // use deep MutationObserver, which would be expensive, especially // with code editor - const jsViewSubscription = globalPubsub.subscribe("js_views", (event) => { - if (event.type === "reposition") { - this.repositionIframe(); - } - }); + const jsViewSubscription = globalPubsub.subscribe( + "js_views:reposition", + (event) => this.repositionIframe(), + ); // Emulate mouse enter and leave on the placeholder. Note that we // intentionally use bubbling to notify all parents that may have @@ -467,36 +469,33 @@ const JSView = { callback(); }, - handleJSViewEvent(event) { - if (event.type === "sync") { - // First, we invoke optional synchronization callback in the iframe, - // that may send any deferred UI changes to the server. Then, we - // do a ping to synchronize with the server - this.syncCallbackQueue.push(event.callback); - this.postMessage({ type: "sync" }); - } else if (event.type == "secretSelected") { - this.postMessage({ - type: "secretSelected", - secretName: event.secretName, - }); - } + handleSync(callback) { + // First, we invoke optional synchronization callback in the iframe, + // that may send any deferred UI changes to the server. Then, we + // do a ping to synchronize with the server + this.syncCallbackQueue.push(callback); + this.postMessage({ type: "sync" }); }, - handleNavigationEvent(event) { - if (event.type === "element_focused") { - // If a parent focusable element is focused, mirror the attribute - // to the iframe element. This way if we need to apply style rules - // (such as opacity) to focused elements, we can target the iframe - // elements placed elsewhere in the DOM + handleSecretSelected(secretName) { + this.postMessage({ type: "secretSelected", secretName }); + }, - const focusableEl = this.el.closest(`[data-focusable-id]`); - const focusableId = focusableEl ? focusableEl.dataset.focusableId : null; + handleElementFocused(focusableId) { + // If a parent focusable element is focused, mirror the attribute + // to the iframe element. This way if we need to apply style rules + // (such as opacity) to focused elements, we can target the iframe + // elements placed elsewhere in the DOM - this.iframe.toggleAttribute( - "data-js-focused", - focusableId === event.focusableId, - ); - } + const parentFocusableEl = this.el.closest(`[data-focusable-id]`); + const parentFocusableId = parentFocusableEl + ? parentFocusableEl.dataset.focusableId + : null; + + this.iframe.toggleAttribute( + "data-js-focused", + parentFocusableId === focusableId, + ); }, }; diff --git a/assets/js/hooks/session.js b/assets/js/hooks/session.js index 6d03663294a..335b081b2de 100644 --- a/assets/js/hooks/session.js +++ b/assets/js/hooks/session.js @@ -163,7 +163,11 @@ const Session = { globalPubsub.subscribe("jump_to_editor", ({ line, file }) => this.jumpToLine(file, line), ), - globalPubsub.subscribe("history", this.handleHistoryEvent.bind(this)), + globalPubsub.subscribe( + "navigation:cursor_moved", + ({ cellId, line, offset }) => + this.cursorHistory.push(cellId, line, offset), + ), ]; this.initializeDragAndDrop(); @@ -951,10 +955,10 @@ const Session = { // If an evaluable cell is focused, we forward the evaluation // request to that cell, so it can synchronize itself before // sending the request to the server - globalPubsub.broadcast(`cells:${this.focusedId}`, { - type: "dispatch_queue_evaluation", - dispatch, - }); + globalPubsub.broadcast( + `cells:${this.focusedId}:dispatch_queue_evaluation`, + { dispatch }, + ); } else { dispatch(); } @@ -1085,8 +1089,7 @@ const Session = { } } - globalPubsub.broadcast("navigation", { - type: "element_focused", + globalPubsub.broadcast("navigation:focus_changed", { focusableId: focusableId, scroll, }); @@ -1105,8 +1108,7 @@ const Session = { this.el.removeAttribute("data-js-insert-mode"); } - globalPubsub.broadcast("navigation", { - type: "insert_mode_changed", + globalPubsub.broadcast("navigation:insert_mode_changed", { enabled: insertModeEnabled, }); }, @@ -1265,7 +1267,7 @@ const Session = { this.repositionJSViews(); if (this.focusedId === cellId) { - globalPubsub.broadcast("cells", { type: "cell_moved", cellId }); + globalPubsub.broadcast("cells:cell_moved", { cellId }); } }, @@ -1323,8 +1325,7 @@ const Session = { }, handleSecretSelected(select_secret_ref, secretName) { - globalPubsub.broadcast(`js_views:${select_secret_ref}`, { - type: "secretSelected", + globalPubsub.broadcast(`js_views:${select_secret_ref}:secret_selected`, { secretName, }); }, @@ -1344,14 +1345,8 @@ const Session = { } }, - handleHistoryEvent(event) { - if (event.type === "navigation") { - this.cursorHistory.push(event.cellId, event.line, event.offset); - } - }, - repositionJSViews() { - globalPubsub.broadcast("js_views", { type: "reposition" }); + globalPubsub.broadcast("js_views:reposition", {}); }, /** @@ -1476,7 +1471,7 @@ const Session = { this.setFocusedEl(cellId, { scroll: false }); this.setInsertMode(true); - globalPubsub.broadcast(`cells:${cellId}`, { type: "jump_to_line", line }); + globalPubsub.broadcast(`cells:${cellId}:jump_to_line`, { line }); }, cursorHistoryGoBack() { @@ -1485,11 +1480,7 @@ const Session = { this.setFocusedEl(cellId, { scroll: false }); this.setInsertMode(true); - globalPubsub.broadcast(`cells:${cellId}`, { - type: "jump_to_line", - line, - offset, - }); + globalPubsub.broadcast(`cells:${cellId}:jump_to_line`, { line, offset }); } }, @@ -1499,11 +1490,7 @@ const Session = { this.setFocusedEl(cellId, { scroll: false }); this.setInsertMode(true); - globalPubsub.broadcast(`cells:${cellId}`, { - type: "jump_to_line", - line, - offset, - }); + globalPubsub.broadcast(`cells:${cellId}:jump_to_line`, { line, offset }); } }, };