mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-10-06 03:34:57 +08:00
Simplify client hooks messaging
This commit is contained in:
parent
ab182ffecb
commit
2b6ce4a92a
4 changed files with 87 additions and 112 deletions
|
@ -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,
|
||||
});
|
||||
},
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue