mirror of
https://github.com/livebook-dev/livebook.git
synced 2024-09-20 10:05:57 +08:00
Adjustments (#1087)
* Fix horizontal scrollbar on smaller screens * Apply navigation shortcuts without an additional roundtrip * Shorten the data element selector * Fix URL in changelog * Return reference from handle_intellisense
This commit is contained in:
parent
00c913adcc
commit
902c993098
|
@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||
|
||||
## [v0.5.2](https://github.com/livebook-dev/livebook/tree/v0.5.1) (2022-01-27)
|
||||
## [v0.5.2](https://github.com/livebook-dev/livebook/tree/v0.5.2) (2022-01-27)
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
@ -19,93 +19,91 @@ solely client-side operations.
|
|||
|
||||
/* === Session === */
|
||||
|
||||
[data-element="session"]:not([data-js-insert-mode])
|
||||
[data-element="insert-mode-indicator"] {
|
||||
[data-el-session]:not([data-js-insert-mode]) [data-el-insert-mode-indicator] {
|
||||
@apply invisible;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-insert-mode])
|
||||
[data-element="cell"][data-type="markdown"]
|
||||
[data-element="editor-box"],
|
||||
[data-element="session"][data-js-insert-mode]
|
||||
[data-element="cell"][data-type="markdown"]:not([data-js-focused])
|
||||
[data-element="editor-box"] {
|
||||
[data-el-session]:not([data-js-insert-mode])
|
||||
[data-el-cell][data-type="markdown"]
|
||||
[data-el-editor-box],
|
||||
[data-el-session][data-js-insert-mode]
|
||||
[data-el-cell][data-type="markdown"]:not([data-js-focused])
|
||||
[data-el-editor-box] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-insert-mode]
|
||||
[data-element="cell"][data-js-focused]
|
||||
[data-element="enable-insert-mode-button"] {
|
||||
[data-el-session][data-js-insert-mode]
|
||||
[data-el-cell][data-js-focused]
|
||||
[data-el-enable-insert-mode-button] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-insert-mode])
|
||||
[data-element="cell"][data-type="markdown"][data-js-focused]
|
||||
[data-element="insert-image-button"] {
|
||||
[data-el-session]:not([data-js-insert-mode])
|
||||
[data-el-cell][data-type="markdown"][data-js-focused]
|
||||
[data-el-insert-image-button] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="notebook-headline"]:hover [data-element="heading"],
|
||||
[data-element="section-headline"]:hover [data-element="heading"] {
|
||||
[data-el-notebook-headline]:hover [data-el-heading],
|
||||
[data-el-section-headline]:hover [data-el-heading] {
|
||||
@apply border-blue-200;
|
||||
}
|
||||
|
||||
[data-element="notebook-headline"][data-js-focused] [data-element="heading"],
|
||||
[data-element="section-headline"][data-js-focused] [data-element="heading"] {
|
||||
[data-el-notebook-headline][data-js-focused] [data-el-heading],
|
||||
[data-el-section-headline][data-js-focused] [data-el-heading] {
|
||||
@apply border-blue-300;
|
||||
}
|
||||
|
||||
[data-element="section-headline"]:not(:hover):not([data-js-focused])
|
||||
[data-element="heading"]
|
||||
+ [data-element="section-actions"]:not(:focus-within) {
|
||||
[data-el-section-headline]:not(:hover):not([data-js-focused])
|
||||
[data-el-heading]
|
||||
+ [data-el-section-actions]:not(:focus-within) {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-js-focused] {
|
||||
[data-el-cell][data-js-focused] {
|
||||
@apply border-blue-300 border-opacity-100;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-focused])
|
||||
[data-element="actions"]:not(:focus-within) {
|
||||
[data-el-cell]:not([data-js-focused]) [data-el-actions]:not(:focus-within) {
|
||||
/* Note: using opacity, so the buttons are focusable (via tab navigation)
|
||||
and when focused we show the actions back. */
|
||||
@apply opacity-0;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-focused])
|
||||
[data-element="actions"]:not([data-primary]):not(:focus-within) {
|
||||
[data-el-cell]:not([data-js-focused])
|
||||
[data-el-actions]:not([data-primary]):not(:focus-within) {
|
||||
@apply pointer-events-none;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-focused])[data-js-hover]
|
||||
[data-element="actions"][data-primary] {
|
||||
[data-el-cell]:not([data-js-focused])[data-js-hover]
|
||||
[data-el-actions][data-primary] {
|
||||
@apply opacity-100 pointer-events-auto;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-js-changed] [data-element="cell-status"] {
|
||||
[data-el-cell][data-js-changed] [data-el-cell-status] {
|
||||
@apply italic;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-changed])
|
||||
[data-element="cell-status"]
|
||||
[data-element="change-indicator"] {
|
||||
[data-el-cell]:not([data-js-changed])
|
||||
[data-el-cell-status]
|
||||
[data-el-change-indicator] {
|
||||
@apply invisible;
|
||||
}
|
||||
|
||||
[data-element="sections-list-item"][data-js-is-viewed] {
|
||||
[data-el-sections-list-item][data-js-is-viewed] {
|
||||
@apply text-gray-900;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-focused])[data-js-hover]
|
||||
[data-element="cell-focus-indicator"] {
|
||||
[data-el-cell]:not([data-js-focused])[data-js-hover]
|
||||
[data-el-cell-focus-indicator] {
|
||||
@apply bg-blue-200;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-js-focused] [data-element="cell-focus-indicator"] {
|
||||
[data-el-cell][data-js-focused] [data-el-cell-focus-indicator] {
|
||||
@apply bg-blue-300;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-js-amplified] [data-element="outputs-container"] {
|
||||
[data-el-cell][data-js-amplified] [data-el-outputs-container] {
|
||||
@apply bg-white m-0 py-16;
|
||||
|
||||
width: 90vw;
|
||||
|
@ -113,155 +111,151 @@ solely client-side operations.
|
|||
left: calc(-45vw + 50%);
|
||||
}
|
||||
|
||||
[data-element="cell"][data-js-amplified]
|
||||
[data-element="amplify-outputs-button"]
|
||||
[data-element="zoom-in-icon"] {
|
||||
[data-el-cell][data-js-amplified]
|
||||
[data-el-amplify-outputs-button]
|
||||
[data-el-zoom-in-icon] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"]:not([data-js-amplified])
|
||||
[data-element="amplify-outputs-button"]
|
||||
[data-element="zoom-out-icon"] {
|
||||
[data-el-cell]:not([data-js-amplified])
|
||||
[data-el-amplify-outputs-button]
|
||||
[data-el-zoom-out-icon] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="smart"]:not([data-js-source-visible])
|
||||
[data-element="editor-box"] {
|
||||
[data-el-cell][data-type="smart"]:not([data-js-source-visible])
|
||||
[data-el-editor-box] {
|
||||
/* Note: we intentionally don't hide the editor, because this leads
|
||||
to issues with hover intellisense once the editor is shown. */
|
||||
@apply h-0 overflow-hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="smart"][data-js-source-visible]
|
||||
[data-element="ui-box"] {
|
||||
[data-el-cell][data-type="smart"][data-js-source-visible] [data-el-ui-box] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-insert-mode])
|
||||
[data-element="cell"][data-type="setup"]:not([data-eval-validity="fresh"]:not([data-js-empty])):not([data-js-changed])
|
||||
[data-element="editor-box"],
|
||||
[data-element="session"]
|
||||
[data-element="cell"][data-type="setup"]:not([data-eval-validity="fresh"]:not([data-js-empty])):not([data-js-changed]):not([data-js-focused])
|
||||
[data-element="editor-box"] {
|
||||
[data-el-session]:not([data-js-insert-mode])
|
||||
[data-el-cell][data-type="setup"]:not([data-eval-validity="fresh"]:not([data-js-empty])):not([data-js-changed])
|
||||
[data-el-editor-box],
|
||||
[data-el-session]
|
||||
[data-el-cell][data-type="setup"]:not([data-eval-validity="fresh"]:not([data-js-empty])):not([data-js-changed]):not([data-js-focused])
|
||||
[data-el-editor-box] {
|
||||
@apply h-0 overflow-hidden;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-insert-mode]
|
||||
[data-element="cell"][data-type="setup"][data-js-focused]
|
||||
[data-element="enable-insert-mode-button"],
|
||||
[data-element="session"]
|
||||
[data-element="cell"][data-type="setup"][data-eval-validity="fresh"]:not([data-js-empty])
|
||||
[data-element="enable-insert-mode-button"],
|
||||
[data-element="session"]
|
||||
[data-element="cell"][data-type="setup"][data-js-changed]
|
||||
[data-element="enable-insert-mode-button"] {
|
||||
[data-el-session][data-js-insert-mode]
|
||||
[data-el-cell][data-type="setup"][data-js-focused]
|
||||
[data-el-enable-insert-mode-button],
|
||||
[data-el-session]
|
||||
[data-el-cell][data-type="setup"][data-eval-validity="fresh"]:not([data-js-empty])
|
||||
[data-el-enable-insert-mode-button],
|
||||
[data-el-session]
|
||||
[data-el-cell][data-type="setup"][data-js-changed]
|
||||
[data-el-enable-insert-mode-button] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-insert-mode]
|
||||
[data-element="cell"][data-type="setup"][data-js-focused]
|
||||
[data-element="info-box"],
|
||||
[data-element="session"]
|
||||
[data-element="cell"][data-type="setup"][data-eval-validity="fresh"]:not([data-js-empty])
|
||||
[data-element="info-box"],
|
||||
[data-element="session"]
|
||||
[data-element="cell"][data-type="setup"][data-js-changed]
|
||||
[data-element="info-box"] {
|
||||
[data-el-session][data-js-insert-mode]
|
||||
[data-el-cell][data-type="setup"][data-js-focused]
|
||||
[data-el-info-box],
|
||||
[data-el-session]
|
||||
[data-el-cell][data-type="setup"][data-eval-validity="fresh"]:not([data-js-empty])
|
||||
[data-el-info-box],
|
||||
[data-el-session]
|
||||
[data-el-cell][data-type="setup"][data-js-changed]
|
||||
[data-el-info-box] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="smart"]:not([data-js-source-visible])
|
||||
[data-element="show-ui-icon"] {
|
||||
[data-el-cell][data-type="smart"]:not([data-js-source-visible])
|
||||
[data-el-show-ui-icon] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="smart"][data-js-source-visible]
|
||||
[data-element="show-code-icon"] {
|
||||
[data-el-cell][data-type="smart"][data-js-source-visible]
|
||||
[data-el-show-code-icon] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="smart"][data-js-source-visible]
|
||||
[data-element="cell-status-container"] {
|
||||
[data-el-cell][data-type="smart"][data-js-source-visible]
|
||||
[data-el-cell-status-container] {
|
||||
@apply absolute bottom-2 right-2;
|
||||
}
|
||||
|
||||
[data-element="output"]:not([data-wrapper]) {
|
||||
[data-el-output]:not([data-wrapper]) {
|
||||
@apply py-4;
|
||||
}
|
||||
|
||||
[data-element="output"][data-border] {
|
||||
[data-el-output][data-border] {
|
||||
@apply px-4 border border-t-0 border-gray-200 divide-y divide-gray-200;
|
||||
}
|
||||
|
||||
[data-element="output"][data-border]:first-child {
|
||||
[data-el-output][data-border]:first-child {
|
||||
@apply rounded-t-lg border-t;
|
||||
}
|
||||
|
||||
[data-element="output"]:not([data-border])
|
||||
+ [data-element="output"][data-border] {
|
||||
[data-el-output]:not([data-border]) + [data-el-output][data-border] {
|
||||
@apply border-t;
|
||||
}
|
||||
|
||||
[data-element="output"][data-border]:last-child {
|
||||
[data-el-output][data-border]:last-child {
|
||||
@apply rounded-b-lg border-b;
|
||||
}
|
||||
|
||||
[data-element="output"]:not(:first-child) {
|
||||
[data-el-output]:not(:first-child) {
|
||||
@apply mt-2;
|
||||
}
|
||||
|
||||
[data-element="output"][data-border] + [data-element="output"][data-border] {
|
||||
[data-el-output][data-border] + [data-el-output][data-border] {
|
||||
@apply mt-0;
|
||||
}
|
||||
|
||||
[data-element="outputs-container"] > [data-element="output"]:first-child {
|
||||
[data-el-outputs-container] > [data-el-output]:first-child {
|
||||
@apply mt-2;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-side-panel-content])
|
||||
[data-element="side-panel"] {
|
||||
[data-el-session]:not([data-js-side-panel-content]) [data-el-side-panel] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-side-panel-content="sections-list"])
|
||||
[data-element="sections-list"] {
|
||||
[data-el-session]:not([data-js-side-panel-content="sections-list"])
|
||||
[data-el-sections-list] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-side-panel-content="clients-list"])
|
||||
[data-element="clients-list"] {
|
||||
[data-el-session]:not([data-js-side-panel-content="clients-list"])
|
||||
[data-el-clients-list] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"]:not([data-js-side-panel-content="runtime-info"])
|
||||
[data-element="runtime-info"] {
|
||||
[data-el-session]:not([data-js-side-panel-content="runtime-info"])
|
||||
[data-el-runtime-info] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-side-panel-content="sections-list"]
|
||||
[data-element="sections-list-toggle"] {
|
||||
[data-el-session][data-js-side-panel-content="sections-list"]
|
||||
[data-el-sections-list-toggle] {
|
||||
@apply text-gray-50 bg-gray-700;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-side-panel-content="clients-list"]
|
||||
[data-element="clients-list-toggle"] {
|
||||
[data-el-session][data-js-side-panel-content="clients-list"]
|
||||
[data-el-clients-list-toggle] {
|
||||
@apply text-gray-50 bg-gray-700;
|
||||
}
|
||||
|
||||
[data-element="session"][data-js-side-panel-content="runtime-info"]
|
||||
[data-element="runtime-info-toggle"] {
|
||||
[data-el-session][data-js-side-panel-content="runtime-info"]
|
||||
[data-el-runtime-info-toggle] {
|
||||
@apply text-gray-50 bg-gray-700;
|
||||
}
|
||||
|
||||
[data-element="clients-list-item"]:not([data-js-followed])
|
||||
[data-meta="unfollow"] {
|
||||
[data-el-clients-list-item]:not([data-js-followed]) [data-meta="unfollow"] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[data-element="clients-list-item"][data-js-followed] [data-meta="follow"] {
|
||||
[data-el-clients-list-item][data-js-followed] [data-meta="follow"] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
[phx-hook="VirtualizedLines"]:not(:hover) [data-element="clipcopy"] {
|
||||
[phx-hook="VirtualizedLines"]:not(:hover) [data-el-clipcopy] {
|
||||
@apply hidden;
|
||||
}
|
||||
|
|
|
@ -145,13 +145,13 @@
|
|||
|
||||
/* Overrides for user-entered markdown */
|
||||
|
||||
[data-element="cell"][data-type="markdown"] .markdown h1,
|
||||
[data-element="cell"][data-type="markdown"] .markdown h2 {
|
||||
[data-el-cell][data-type="markdown"] .markdown h1,
|
||||
[data-el-cell][data-type="markdown"] .markdown h2 {
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
[data-element="cell"][data-type="markdown"] .markdown h1:after,
|
||||
[data-element="cell"][data-type="markdown"] .markdown h2:after {
|
||||
[data-el-cell][data-type="markdown"] .markdown h1:after,
|
||||
[data-el-cell][data-type="markdown"] .markdown h2:after {
|
||||
@apply text-red-400 text-base font-medium;
|
||||
content: "warning: heading levels 1 and 2 are reserved for notebook and section names, please use heading 3 and above.";
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ const Cell = {
|
|||
|
||||
if (this.props.type === "code") {
|
||||
const amplifyButton = this.el.querySelector(
|
||||
`[data-element="amplify-outputs-button"]`
|
||||
`[data-el-amplify-outputs-button]`
|
||||
);
|
||||
amplifyButton.addEventListener("click", (event) => {
|
||||
this.el.toggleAttribute("data-js-amplified");
|
||||
|
@ -44,7 +44,7 @@ const Cell = {
|
|||
|
||||
if (this.props.type === "smart") {
|
||||
const toggleSourceButton = this.el.querySelector(
|
||||
`[data-element="toggle-source-button"]`
|
||||
`[data-el-toggle-source-button]`
|
||||
);
|
||||
toggleSourceButton.addEventListener("click", (event) => {
|
||||
this.el.toggleAttribute("data-js-source-visible");
|
||||
|
@ -185,7 +185,7 @@ const Cell = {
|
|||
// Setup markdown rendering
|
||||
if (this.props.type === "markdown") {
|
||||
const markdownContainer = this.el.querySelector(
|
||||
`[data-element="markdown-container"]`
|
||||
`[data-el-markdown-container]`
|
||||
);
|
||||
const markdown = new Markdown(markdownContainer, source, {
|
||||
baseUrl: this.props.sessionPath,
|
||||
|
@ -254,10 +254,9 @@ const Cell = {
|
|||
},
|
||||
|
||||
updateChangeIndicator() {
|
||||
const cellStatus = this.el.querySelector(`[data-element="cell-status"]`);
|
||||
const cellStatus = this.el.querySelector(`[data-el-cell-status]`);
|
||||
const indicator =
|
||||
cellStatus &&
|
||||
cellStatus.querySelector(`[data-element="change-indicator"]`);
|
||||
cellStatus && cellStatus.querySelector(`[data-el-change-indicator]`);
|
||||
|
||||
if (indicator && this.props.evaluationDigest) {
|
||||
const source = this.liveEditors.primary.getSource();
|
||||
|
|
|
@ -9,7 +9,7 @@ const CellEditor = {
|
|||
`cell_editor_init:${this.props.cellId}:${this.props.tag}`,
|
||||
({ source_view, language, intellisense, read_only }) => {
|
||||
const editorContainer = this.el.querySelector(
|
||||
`[data-element="editor-container"]`
|
||||
`[data-el-editor-container]`
|
||||
);
|
||||
|
||||
// Remove the content placeholder
|
||||
|
|
|
@ -52,7 +52,7 @@ const Headline = {
|
|||
},
|
||||
|
||||
initializeHeadingEl() {
|
||||
const headingEl = this.el.querySelector(`[data-element="heading"]`);
|
||||
const headingEl = this.el.querySelector(`[data-el-heading]`);
|
||||
|
||||
if (headingEl === this.headingEl) {
|
||||
return;
|
||||
|
|
|
@ -165,9 +165,9 @@ const JSView = {
|
|||
this.iframe = document.createElement("iframe");
|
||||
this.iframe.className = "w-full h-0 absolute z-[1]";
|
||||
|
||||
const notebookEl = document.querySelector(`[data-element="notebook"]`);
|
||||
const notebookEl = document.querySelector(`[data-el-notebook]`);
|
||||
const notebookContentEl = notebookEl.querySelector(
|
||||
`[data-element="notebook-content"]`
|
||||
`[data-el-notebook-content]`
|
||||
);
|
||||
|
||||
// Most placeholder position changes are accompanied by changes to the
|
||||
|
@ -219,7 +219,7 @@ const JSView = {
|
|||
|
||||
repositionIframe() {
|
||||
const { iframe, iframePlaceholder } = this;
|
||||
const notebookEl = document.querySelector(`[data-element="notebook"]`);
|
||||
const notebookEl = document.querySelector(`[data-el-notebook]`);
|
||||
|
||||
if (iframePlaceholder.offsetParent === null) {
|
||||
// When the placeholder is hidden, we hide the iframe as well
|
||||
|
@ -239,9 +239,7 @@ const JSView = {
|
|||
},
|
||||
|
||||
loadIframe() {
|
||||
const iframesEl = document.querySelector(
|
||||
`[data-element="js-view-iframes"]`
|
||||
);
|
||||
const iframesEl = document.querySelector(`[data-el-js-view-iframes]`);
|
||||
initializeIframeSource(this.iframe, this.props.iframePort).then(() => {
|
||||
iframesEl.appendChild(this.iframe);
|
||||
});
|
||||
|
|
|
@ -405,7 +405,7 @@ const Session = {
|
|||
*/
|
||||
handleDocumentMouseDown(event) {
|
||||
// If the click is outside the notebook element, keep the focus as is
|
||||
if (!event.target.closest(`[data-element="notebook"]`)) {
|
||||
if (!event.target.closest(`[data-el-notebook]`)) {
|
||||
if (this.insertMode) {
|
||||
this.setInsertMode(false);
|
||||
}
|
||||
|
@ -413,7 +413,7 @@ const Session = {
|
|||
}
|
||||
|
||||
// When clicking an insert button, keep focus and insert mode as is
|
||||
if (event.target.closest(`[data-element="insert-buttons"] button`)) {
|
||||
if (event.target.closest(`[data-el-insert-buttons] button`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,7 +427,7 @@ const Session = {
|
|||
}
|
||||
|
||||
// If a cell action is clicked, keep the insert mode as is
|
||||
if (event.target.closest(`[data-element="actions"]`)) {
|
||||
if (event.target.closest(`[data-el-actions]`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -440,7 +440,7 @@ const Session = {
|
|||
editableElementClicked(event, focusableEl) {
|
||||
if (focusableEl) {
|
||||
const editableElement = event.target.closest(
|
||||
`[data-element="editor-container"], [data-element="heading"]`
|
||||
`[data-el-editor-container], [data-el-heading]`
|
||||
);
|
||||
return editableElement && focusableEl.contains(editableElement);
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ const Session = {
|
|||
* Enters insert mode when markdown edit action is clicked.
|
||||
*/
|
||||
handleDocumentClick(event) {
|
||||
if (event.target.closest(`[data-element="enable-insert-mode-button"]`)) {
|
||||
if (event.target.closest(`[data-el-enable-insert-mode-button]`)) {
|
||||
this.setInsertMode(true);
|
||||
}
|
||||
},
|
||||
|
@ -477,7 +477,7 @@ const Session = {
|
|||
* Enters insert mode when a markdown cell is double-clicked.
|
||||
*/
|
||||
handleDocumentDoubleClick(event) {
|
||||
const cell = event.target.closest(`[data-element="cell"]`);
|
||||
const cell = event.target.closest(`[data-el-cell]`);
|
||||
const type = cell && cell.getAttribute("data-type");
|
||||
|
||||
if (
|
||||
|
@ -494,9 +494,7 @@ const Session = {
|
|||
* Handles section link clicks in the section list.
|
||||
*/
|
||||
handleSectionsListClick(event) {
|
||||
const sectionButton = event.target.closest(
|
||||
`[data-element="sections-list-item"]`
|
||||
);
|
||||
const sectionButton = event.target.closest(`[data-el-sections-list-item]`);
|
||||
if (sectionButton) {
|
||||
const sectionId = sectionButton.getAttribute("data-section-id");
|
||||
const section = this.getSectionById(sectionId);
|
||||
|
@ -508,20 +506,18 @@ const Session = {
|
|||
* Handles client link clicks in the clients list.
|
||||
*/
|
||||
handleClientsListClick(event) {
|
||||
const clientListItem = event.target.closest(
|
||||
`[data-element="clients-list-item"]`
|
||||
);
|
||||
const clientListItem = event.target.closest(`[data-el-clients-list-item]`);
|
||||
|
||||
if (clientListItem) {
|
||||
const clientPid = clientListItem.getAttribute("data-client-pid");
|
||||
|
||||
const clientLink = event.target.closest(`[data-element="client-link"]`);
|
||||
const clientLink = event.target.closest(`[data-el-client-link]`);
|
||||
if (clientLink) {
|
||||
this.handleClientLinkClick(clientPid);
|
||||
}
|
||||
|
||||
const clientFollowToggle = event.target.closest(
|
||||
`[data-element="client-follow-toggle"]`
|
||||
`[data-el-client-follow-toggle]`
|
||||
);
|
||||
if (clientFollowToggle) {
|
||||
this.handleClientFollowToggleClick(clientPid, clientListItem);
|
||||
|
@ -535,7 +531,7 @@ const Session = {
|
|||
|
||||
handleClientFollowToggleClick(clientPid, clientListItem) {
|
||||
const followedClientListItem = this.el.querySelector(
|
||||
`[data-element="clients-list-item"][data-js-followed]`
|
||||
`[data-el-clients-list-item][data-js-followed]`
|
||||
);
|
||||
|
||||
if (followedClientListItem) {
|
||||
|
@ -563,7 +559,7 @@ const Session = {
|
|||
* Handles button clicks within cell indicators section.
|
||||
*/
|
||||
handleCellIndicatorsClick(event) {
|
||||
const button = event.target.closest(`[data-element="focus-cell-button"]`);
|
||||
const button = event.target.closest(`[data-el-focus-cell-button]`);
|
||||
if (button) {
|
||||
const cellId = button.getAttribute("data-target");
|
||||
this.setFocusedEl(cellId);
|
||||
|
@ -603,7 +599,7 @@ const Session = {
|
|||
*/
|
||||
updateSectionListHighlight() {
|
||||
const currentListItem = this.el.querySelector(
|
||||
`[data-element="sections-list-item"][data-js-is-viewed]`
|
||||
`[data-el-sections-list-item][data-js-is-viewed]`
|
||||
);
|
||||
|
||||
if (currentListItem) {
|
||||
|
@ -622,7 +618,7 @@ const Session = {
|
|||
if (viewedSection) {
|
||||
const sectionId = viewedSection.getAttribute("data-section-id");
|
||||
const listItem = this.el.querySelector(
|
||||
`[data-element="sections-list-item"][data-section-id="${sectionId}"]`
|
||||
`[data-el-sections-list-item][data-section-id="${sectionId}"]`
|
||||
);
|
||||
listItem.setAttribute("data-js-is-viewed", "");
|
||||
}
|
||||
|
@ -651,7 +647,8 @@ const Session = {
|
|||
},
|
||||
|
||||
showBin() {
|
||||
this.pushEvent("show_bin", {});
|
||||
const actionEl = this.el.querySelector(`[data-btn-show-bin]`);
|
||||
actionEl && actionEl.click();
|
||||
},
|
||||
|
||||
showDependencySearch() {
|
||||
|
@ -715,7 +712,8 @@ const Session = {
|
|||
},
|
||||
|
||||
showShortcuts() {
|
||||
this.pushEvent("show_shortcuts", {});
|
||||
const actionEl = this.el.querySelector(`[data-btn-show-shortcuts]`);
|
||||
actionEl && actionEl.click();
|
||||
},
|
||||
|
||||
isInsertModeAvailable() {
|
||||
|
@ -803,8 +801,8 @@ const Session = {
|
|||
if (focusElement) {
|
||||
// Focus the primary content in the focusable element, this is important for screen readers
|
||||
const contentEl =
|
||||
el.querySelector(`[data-element="cell-body"]`) ||
|
||||
el.querySelector(`[data-element="heading"]`) ||
|
||||
el.querySelector(`[data-el-cell-body]`) ||
|
||||
el.querySelector(`[data-el-heading]`) ||
|
||||
el;
|
||||
contentEl.focus({ preventScroll: true });
|
||||
}
|
||||
|
@ -866,9 +864,7 @@ const Session = {
|
|||
|
||||
handleSectionInserted(sectionId) {
|
||||
const section = this.getSectionById(sectionId);
|
||||
const headlineEl = section.querySelector(
|
||||
`[data-element="section-headline"]`
|
||||
);
|
||||
const headlineEl = section.querySelector(`[data-el-section-headline]`);
|
||||
const { focusableId } = headlineEl.dataset;
|
||||
this.setFocusedEl(focusableId);
|
||||
this.setInsertMode(true);
|
||||
|
@ -1081,7 +1077,7 @@ const Session = {
|
|||
|
||||
getSectionIdByFocusableId(focusableId) {
|
||||
const el = this.getFocusableEl(focusableId);
|
||||
const section = el.closest(`[data-element="section"]`);
|
||||
const section = el.closest(`[data-el-section]`);
|
||||
return section && section.getAttribute("data-section-id");
|
||||
},
|
||||
|
||||
|
@ -1091,17 +1087,17 @@ const Session = {
|
|||
},
|
||||
|
||||
getSections() {
|
||||
return Array.from(this.el.querySelectorAll(`[data-element="section"]`));
|
||||
return Array.from(this.el.querySelectorAll(`[data-el-section]`));
|
||||
},
|
||||
|
||||
getSectionById(sectionId) {
|
||||
return this.el.querySelector(
|
||||
`[data-element="section"][data-section-id="${sectionId}"]`
|
||||
`[data-el-section][data-section-id="${sectionId}"]`
|
||||
);
|
||||
},
|
||||
|
||||
getElement(name) {
|
||||
return this.el.querySelector(`[data-element="${name}"]`);
|
||||
return this.el.querySelector(`[data-el-${name}]`);
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -370,8 +370,8 @@ defprotocol Livebook.Runtime do
|
|||
The given `base_locator` idenfities an evaluation that may be
|
||||
used as the context when resolving the request (if relevant).
|
||||
"""
|
||||
@spec handle_intellisense(t(), pid(), reference(), intellisense_request(), locator()) :: :ok
|
||||
def handle_intellisense(runtime, send_to, ref, request, base_locator)
|
||||
@spec handle_intellisense(t(), pid(), intellisense_request(), locator()) :: reference()
|
||||
def handle_intellisense(runtime, send_to, request, base_locator)
|
||||
|
||||
@doc """
|
||||
Returns true if the given runtime is self-contained.
|
||||
|
|
|
@ -94,8 +94,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.Attached do
|
|||
RuntimeServer.drop_container(runtime.server_pid, container_ref)
|
||||
end
|
||||
|
||||
def handle_intellisense(runtime, send_to, ref, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, ref, request, base_locator)
|
||||
def handle_intellisense(runtime, send_to, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, request, base_locator)
|
||||
end
|
||||
|
||||
def standalone?(_runtime), do: false
|
||||
|
|
|
@ -141,8 +141,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.ElixirStandalone do
|
|||
RuntimeServer.drop_container(runtime.server_pid, container_ref)
|
||||
end
|
||||
|
||||
def handle_intellisense(runtime, send_to, ref, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, ref, request, base_locator)
|
||||
def handle_intellisense(runtime, send_to, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, request, base_locator)
|
||||
end
|
||||
|
||||
def standalone?(_runtime), do: true
|
||||
|
|
|
@ -88,8 +88,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.Embedded do
|
|||
RuntimeServer.drop_container(runtime.server_pid, container_ref)
|
||||
end
|
||||
|
||||
def handle_intellisense(runtime, send_to, ref, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, ref, request, base_locator)
|
||||
def handle_intellisense(runtime, send_to, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, request, base_locator)
|
||||
end
|
||||
|
||||
def standalone?(_runtime), do: false
|
||||
|
|
|
@ -108,12 +108,13 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServer do
|
|||
@spec handle_intellisense(
|
||||
pid(),
|
||||
pid(),
|
||||
reference(),
|
||||
Runtime.intellisense_request(),
|
||||
Runtime.locator()
|
||||
) :: :ok
|
||||
def handle_intellisense(pid, send_to, ref, request, base_locator) do
|
||||
) :: reference()
|
||||
def handle_intellisense(pid, send_to, request, base_locator) do
|
||||
ref = make_ref()
|
||||
GenServer.cast(pid, {:handle_intellisense, send_to, ref, request, base_locator})
|
||||
ref
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -181,8 +181,8 @@ defimpl Livebook.Runtime, for: Livebook.Runtime.MixStandalone do
|
|||
RuntimeServer.drop_container(runtime.server_pid, container_ref)
|
||||
end
|
||||
|
||||
def handle_intellisense(runtime, send_to, ref, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, ref, request, base_locator)
|
||||
def handle_intellisense(runtime, send_to, request, base_locator) do
|
||||
RuntimeServer.handle_intellisense(runtime.server_pid, send_to, request, base_locator)
|
||||
end
|
||||
|
||||
def standalone?(_runtime), do: true
|
||||
|
|
|
@ -85,7 +85,7 @@ defmodule LivebookWeb.HomeLive do
|
|||
</.live_component>
|
||||
</div>
|
||||
|
||||
<div class="py-12" data-element="explore-section" role="region" aria-label="explore section">
|
||||
<div class="py-12" data-el-explore-section role="region" aria-label="explore section">
|
||||
<div class="mb-4 flex justify-between items-center">
|
||||
<h2 class="uppercase font-semibold text-gray-500">
|
||||
Explore
|
||||
|
|
|
@ -109,7 +109,7 @@ defmodule LivebookWeb.HomeLive.SessionListComponent do
|
|||
<input type="checkbox" name="session_ids[]" value={session.id}
|
||||
aria-label={session.notebook_name}
|
||||
class="checkbox-base hidden mr-3"
|
||||
data-element="bulk-edit-member"
|
||||
data-el-bulk-edit-member
|
||||
phx-click={JS.dispatch("lb:session_list:on_selection_change")}>
|
||||
</div>
|
||||
<div class="grow flex flex-col items-start">
|
||||
|
@ -218,7 +218,7 @@ defmodule LivebookWeb.HomeLive.SessionListComponent do
|
|||
<span>Edit</span>
|
||||
</button>
|
||||
<button class="hidden w-28 button-base button-outlined-gray px-4 py-1 flex justify-between items-center"
|
||||
data-element="bulk-edit-member"
|
||||
data-el-bulk-edit-member
|
||||
type="button">
|
||||
<span>Actions</span>
|
||||
<.remix_icon icon="arrow-down-s-line" class="text-lg leading-none align-middle ml-1" />
|
||||
|
@ -264,14 +264,14 @@ defmodule LivebookWeb.HomeLive.SessionListComponent do
|
|||
end
|
||||
|
||||
def toggle_edit(:on) do
|
||||
JS.remove_class("hidden", to: "[data-element='bulk-edit-member']")
|
||||
JS.remove_class("hidden", to: "[data-el-bulk-edit-member]")
|
||||
|> JS.add_class("hidden", to: "#toggle-edit")
|
||||
|> JS.dispatch("lb:session_list:on_selection_change")
|
||||
|> sr_message("bulk actions available")
|
||||
end
|
||||
|
||||
def toggle_edit(:off) do
|
||||
JS.add_class("hidden", to: "[data-element='bulk-edit-member']")
|
||||
JS.add_class("hidden", to: "[data-el-bulk-edit-member]")
|
||||
|> JS.remove_class("hidden", to: "#toggle-edit")
|
||||
|> JS.dispatch("lb:uncheck", to: "[name='session_ids[]']")
|
||||
|> JS.dispatch("lb:session_list:on_selection_change")
|
||||
|
|
|
@ -12,7 +12,7 @@ defmodule LivebookWeb.Output do
|
|||
~H"""
|
||||
<%= for {idx, output} <- Enum.reverse(@outputs) do %>
|
||||
<div class="max-w-full" id={"output-wrapper-#{@dom_id_map[idx] || idx}"}
|
||||
data-element="output"
|
||||
data-el-output
|
||||
data-border={border?(output)}
|
||||
data-wrapper={wrapper?(output)}>
|
||||
<%= render_output(output, %{
|
||||
|
|
|
@ -45,7 +45,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
defp input(%{attrs: %{type: :select}} = assigns) do
|
||||
~H"""
|
||||
<select
|
||||
data-element="input"
|
||||
data-el-input
|
||||
class="input input-select"
|
||||
name="value">
|
||||
<%= for {{key, label}, idx} <- Enum.with_index(@attrs.options) do %>
|
||||
|
@ -61,7 +61,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
~H"""
|
||||
<div class="mt-1">
|
||||
<.switch_checkbox
|
||||
data-element="input"
|
||||
data-el-input
|
||||
name="value"
|
||||
checked={@value} />
|
||||
</div>
|
||||
|
@ -73,7 +73,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
<div class="flex items-center space-x-2">
|
||||
<div><%= @attrs.min %></div>
|
||||
<input type="range"
|
||||
data-element="input"
|
||||
data-el-input
|
||||
class="input-range"
|
||||
name="value"
|
||||
value={@value}
|
||||
|
@ -93,7 +93,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
defp input(%{attrs: %{type: :textarea}} = assigns) do
|
||||
~H"""
|
||||
<textarea
|
||||
data-element="input"
|
||||
data-el-input
|
||||
class="input min-h-[200px] tiny-scrollbar"
|
||||
name="value"
|
||||
phx-debounce="300"
|
||||
|
@ -107,7 +107,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
~H"""
|
||||
<.with_password_toggle id={"#{@id}-password-toggle"}>
|
||||
<input type="password"
|
||||
data-element="input"
|
||||
data-el-input
|
||||
class="input w-auto bg-gray-50"
|
||||
name="value"
|
||||
value={@value}
|
||||
|
@ -123,7 +123,7 @@ defmodule LivebookWeb.Output.InputComponent do
|
|||
defp input(%{attrs: %{type: type}} = assigns) when type in [:number, :color, :url, :text] do
|
||||
~H"""
|
||||
<input type={html_input_type(@attrs.type)}
|
||||
data-element="input"
|
||||
data-el-input
|
||||
class={"input w-auto #{if(@error, do: "input--error")}"}
|
||||
name="value"
|
||||
value={to_string(@value)}
|
||||
|
|
|
@ -65,7 +65,7 @@ defmodule LivebookWeb.Output.StdoutComponent do
|
|||
phx-update="ignore"></div>
|
||||
<div class="absolute right-2 top-0 z-10">
|
||||
<button class="icon-button bg-gray-100"
|
||||
data-element="clipcopy"
|
||||
data-el-clipcopy
|
||||
phx-click={JS.dispatch("lb:clipcopy", to: "#virtualized-text-#{@id}-template")}>
|
||||
<.remix_icon icon="clipboard-line" class="text-lg" />
|
||||
</button>
|
||||
|
|
|
@ -17,7 +17,7 @@ defmodule LivebookWeb.Output.TextComponent do
|
|||
phx-update="ignore"></div>
|
||||
<div class="absolute right-2 top-0 z-10">
|
||||
<button class="icon-button bg-gray-100"
|
||||
data-element="clipcopy"
|
||||
data-el-clipcopy
|
||||
phx-click={JS.dispatch("lb:clipcopy", to: "#virtualized-text-#{@id}-template")}>
|
||||
<.remix_icon icon="clipboard-line" class="text-lg" />
|
||||
</button>
|
||||
|
|
|
@ -90,7 +90,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
~H"""
|
||||
<div class="flex grow h-full"
|
||||
id={"session-#{@session.id}"}
|
||||
data-element="session"
|
||||
data-el-session
|
||||
phx-hook="Session"
|
||||
data-global-status={elem(@data_view.global_status, 0)}
|
||||
data-autofocus-cell-id={@autofocus_cell_id}>
|
||||
|
@ -99,45 +99,47 @@ defmodule LivebookWeb.SessionLive do
|
|||
<SidebarHelpers.button_item
|
||||
icon="booklet-fill"
|
||||
label="Sections (ss)"
|
||||
data_element="sections-list-toggle" />
|
||||
button_attrs={[data_el_sections_list_toggle: true]} />
|
||||
<SidebarHelpers.button_item
|
||||
icon="group-fill"
|
||||
label="Connected users (su)"
|
||||
data_element="clients-list-toggle" />
|
||||
button_attrs={[data_el_clients_list_toggle: true]} />
|
||||
<SidebarHelpers.button_item
|
||||
icon="cpu-line"
|
||||
label="Runtime settings (sr)"
|
||||
data_element="runtime-info-toggle" />
|
||||
button_attrs={[data_el_runtime_info_toggle: true]} />
|
||||
<SidebarHelpers.link_item
|
||||
icon="delete-bin-6-fill"
|
||||
label="Bin (sb)"
|
||||
path={Routes.session_path(@socket, :bin, @session.id)}
|
||||
active={@live_action == :bin} />
|
||||
active={@live_action == :bin}
|
||||
link_attrs={[data_btn_show_bin: true]} />
|
||||
<SidebarHelpers.break_item />
|
||||
<SidebarHelpers.link_item
|
||||
icon="keyboard-box-fill"
|
||||
label="Keyboard shortcuts (?)"
|
||||
path={Routes.session_path(@socket, :shortcuts, @session.id)}
|
||||
active={@live_action == :shortcuts} />
|
||||
active={@live_action == :shortcuts}
|
||||
link_attrs={[data_btn_show_shortcuts: true]} />
|
||||
<SidebarHelpers.user_item current_user={@current_user} />
|
||||
</SidebarHelpers.sidebar>
|
||||
<div class="flex flex-col h-full w-full max-w-xs absolute z-30 top-0 left-[64px] overflow-y-auto shadow-xl md:static md:shadow-none bg-gray-50 border-r border-gray-100 px-6 py-10"
|
||||
data-element="side-panel">
|
||||
<div data-element="sections-list">
|
||||
data-el-side-panel>
|
||||
<div data-el-sections-list>
|
||||
<.sections_list data_view={@data_view} />
|
||||
</div>
|
||||
<div data-element="clients-list">
|
||||
<div data-el-clients-list>
|
||||
<.clients_list data_view={@data_view} self={@self} />
|
||||
</div>
|
||||
<div data-element="runtime-info">
|
||||
<div data-el-runtime-info>
|
||||
<.runtime_info data_view={@data_view} session={@session} socket={@socket} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="grow overflow-y-auto relative" data-element="notebook">
|
||||
<div data-element="js-view-iframes" phx-update="ignore" id="js-view-iframes"></div>
|
||||
<div class="w-full max-w-screen-lg px-16 mx-auto py-7" data-element="notebook-content">
|
||||
<div class="grow overflow-y-auto relative" data-el-notebook>
|
||||
<div data-el-js-view-iframes phx-update="ignore" id="js-view-iframes"></div>
|
||||
<div class="w-full max-w-screen-lg px-16 mx-auto py-7" data-el-notebook-content>
|
||||
<div class="flex items-center pb-4 mb-2 space-x-4 border-b border-gray-200"
|
||||
data-element="notebook-headline"
|
||||
data-el-notebook-headline
|
||||
data-focusable-id="notebook"
|
||||
id="notebook"
|
||||
phx-hook="Headline"
|
||||
|
@ -146,7 +148,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
<h1 class="grow p-1 -ml-1 text-3xl font-semibold text-gray-800 border border-transparent rounded-lg whitespace-pre-wrap"
|
||||
tabindex="0"
|
||||
id="notebook-heading"
|
||||
data-element="heading"
|
||||
data-el-heading
|
||||
spellcheck="false"><%= @data_view.notebook_name %></h1>
|
||||
<.menu id="session-menu">
|
||||
<:toggle>
|
||||
|
@ -337,7 +339,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
<%= for section_item <- @data_view.sections_items do %>
|
||||
<div class="flex items-center">
|
||||
<button class="grow flex items-center text-gray-500 hover:text-gray-900 text-left"
|
||||
data-element="sections-list-item"
|
||||
data-el-sections-list-item
|
||||
data-section-id={section_item.id}>
|
||||
<span class="flex items-center space-x-1">
|
||||
<span><%= section_item.name %></span>
|
||||
|
@ -379,24 +381,24 @@ defmodule LivebookWeb.SessionLive do
|
|||
<%= for {client_pid, user} <- @data_view.clients do %>
|
||||
<div class="flex items-center justify-between space-x-2"
|
||||
id={"clients-list-item-#{inspect(client_pid)}"}
|
||||
data-element="clients-list-item"
|
||||
data-el-clients-list-item
|
||||
data-client-pid={inspect(client_pid)}>
|
||||
<button class="flex items-center space-x-2 text-gray-500 hover:text-gray-900 disabled:pointer-events-none"
|
||||
disabled={client_pid == @self}
|
||||
data-element="client-link">
|
||||
data-el-client-link>
|
||||
<.user_avatar user={user} class="shrink-0 h-7 w-7" text_class="text-xs" />
|
||||
<span><%= user.name || "Anonymous" %></span>
|
||||
</button>
|
||||
<%= if client_pid != @self do %>
|
||||
<span class="tooltip left" data-tooltip="Follow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-el-client-follow-toggle
|
||||
data-meta="follow">
|
||||
<button class="icon-button" aria-label="follow this user">
|
||||
<.remix_icon icon="pushpin-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" data-tooltip="Unfollow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-el-client-follow-toggle
|
||||
data-meta="unfollow">
|
||||
<button class="icon-button" aria-label="unfollow this user">
|
||||
<.remix_icon icon="pushpin-fill" class="text-lg" />
|
||||
|
@ -501,7 +503,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
|
||||
defp session_status(%{status: :evaluating} = assigns) do
|
||||
~H"""
|
||||
<button data-element="focus-cell-button" data-target={@cell_id}>
|
||||
<button data-el-focus-cell-button data-target={@cell_id}>
|
||||
<.status_indicator circle_class="bg-blue-500" animated_circle_class="bg-blue-400">
|
||||
</.status_indicator>
|
||||
</button>
|
||||
|
@ -510,7 +512,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
|
||||
defp session_status(%{status: :stale} = assigns) do
|
||||
~H"""
|
||||
<button data-element="focus-cell-button" data-target={@cell_id}>
|
||||
<button data-el-focus-cell-button data-target={@cell_id}>
|
||||
<.status_indicator circle_class="bg-yellow-bright-200">
|
||||
</.status_indicator>
|
||||
</button>
|
||||
|
@ -782,16 +784,6 @@ defmodule LivebookWeb.SessionLive do
|
|||
end
|
||||
end
|
||||
|
||||
def handle_event("show_shortcuts", %{}, socket) do
|
||||
{:noreply,
|
||||
push_patch(socket, to: Routes.session_path(socket, :shortcuts, socket.assigns.session.id))}
|
||||
end
|
||||
|
||||
def handle_event("show_bin", %{}, socket) do
|
||||
{:noreply,
|
||||
push_patch(socket, to: Routes.session_path(socket, :bin, socket.assigns.session.id))}
|
||||
end
|
||||
|
||||
def handle_event("reconnect_runtime", %{}, socket) do
|
||||
{_, socket} = maybe_reconnect_runtime(socket)
|
||||
{:noreply, socket}
|
||||
|
@ -838,9 +830,8 @@ defmodule LivebookWeb.SessionLive do
|
|||
|
||||
with {:ok, cell, section} <- Notebook.fetch_cell_and_section(data.notebook, cell_id) do
|
||||
if Runtime.connected?(data.runtime) do
|
||||
ref = make_ref()
|
||||
base_locator = Session.find_base_locator(data, cell, section, existing: true)
|
||||
Runtime.handle_intellisense(data.runtime, self(), ref, request, base_locator)
|
||||
ref = Runtime.handle_intellisense(data.runtime, self(), request, base_locator)
|
||||
|
||||
{:reply, %{"ref" => inspect(ref)}, socket}
|
||||
else
|
||||
|
|
|
@ -5,7 +5,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col relative"
|
||||
data-element="cell"
|
||||
data-el-cell
|
||||
id={"cell-#{@cell_view.id}"}
|
||||
phx-hook="Cell"
|
||||
data-cell-id={@cell_view.id}
|
||||
|
@ -33,7 +33,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
</:secondary>
|
||||
</.cell_actions>
|
||||
<.cell_body>
|
||||
<div class="pb-4" data-element="editor-box">
|
||||
<div class="pb-4" data-el-editor-box>
|
||||
<.live_component module={LivebookWeb.SessionLive.CellEditorComponent}
|
||||
id={"#{@cell_view.id}-primary"}
|
||||
cell_id={@cell_view.id}
|
||||
|
@ -42,7 +42,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
language="markdown" />
|
||||
</div>
|
||||
<div class="markdown"
|
||||
data-element="markdown-container"
|
||||
data-el-markdown-container
|
||||
id={"markdown-container-#{@cell_view.id}"}
|
||||
phx-update="ignore">
|
||||
<.content_skeleton empty={empty?(@cell_view.source_view)} />
|
||||
|
@ -111,13 +111,13 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
</:secondary>
|
||||
</.cell_actions>
|
||||
<.cell_body>
|
||||
<div data-element="info-box">
|
||||
<div data-el-info-box>
|
||||
<div class="p-3 flex items-center justify-between border border-gray-200 text-sm text-gray-400 font-medium rounded-lg">
|
||||
<span>Notebook dependencies and setup</span>
|
||||
<.cell_status id={"#{@cell_view.id}-1"} cell_view={@cell_view} />
|
||||
</div>
|
||||
</div>
|
||||
<div data-element="editor-box">
|
||||
<div data-el-editor-box>
|
||||
<div class="relative">
|
||||
<.live_component module={LivebookWeb.SessionLive.CellEditorComponent}
|
||||
id={"#{@cell_view.id}-primary"}
|
||||
|
@ -162,7 +162,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
</:secondary>
|
||||
</.cell_actions>
|
||||
<.cell_body>
|
||||
<div data-element="ui-box">
|
||||
<div data-el-ui-box>
|
||||
<%= case @cell_view.status do %>
|
||||
<% :started -> %>
|
||||
<div class={"flex #{if(@cell_view.editor && @cell_view.editor.placement == :top, do: "flex-col-reverse", else: "flex-col")}"}>
|
||||
|
@ -195,7 +195,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
<.cell_status id={"#{@cell_view.id}-1"} cell_view={@cell_view} />
|
||||
</div>
|
||||
</div>
|
||||
<div data-element="editor-box">
|
||||
<div data-el-editor-box>
|
||||
<div class="relative">
|
||||
<.live_component module={LivebookWeb.SessionLive.CellEditorComponent}
|
||||
id={"#{@cell_view.id}-primary"}
|
||||
|
@ -227,13 +227,13 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
~H"""
|
||||
<div class="mb-1 flex items-center justify-between">
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2" data-element="actions" data-primary>
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2" data-el-actions data-primary>
|
||||
<%= render_slot(@primary) %>
|
||||
</div>
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2"
|
||||
role="toolbar"
|
||||
aria-label="cell actions"
|
||||
data-element="actions">
|
||||
data-el-actions>
|
||||
<%= render_slot(@secondary) %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -244,8 +244,8 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
~H"""
|
||||
<!-- By setting tabindex we can programmatically focus this element,
|
||||
also we actually want to make this element tab-focusable -->
|
||||
<div class="flex relative" data-element="cell-body" tabindex="0">
|
||||
<div class="w-1 h-full rounded-lg absolute top-0 -left-3" data-element="cell-focus-indicator">
|
||||
<div class="flex relative" data-el-cell-body tabindex="0">
|
||||
<div class="w-1 h-full rounded-lg absolute top-0 -left-3" data-el-cell-focus-indicator>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<%= render_slot(@inner_block) %>
|
||||
|
@ -324,7 +324,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp enable_insert_mode_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" data-tooltip="Edit content" data-element="enable-insert-mode-button">
|
||||
<span class="tooltip top" data-tooltip="Edit content" data-el-enable-insert-mode-button>
|
||||
<button class="icon-button" aria-label="edit content">
|
||||
<.remix_icon icon="pencil-line" class="text-xl" />
|
||||
</button>
|
||||
|
@ -334,7 +334,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp insert_image_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" data-tooltip="Insert image" data-element="insert-image-button">
|
||||
<span class="tooltip top" data-tooltip="Insert image" data-el-insert-image-button>
|
||||
<%= live_patch to: Routes.session_path(@socket, :cell_upload, @session_id, @cell_id),
|
||||
class: "icon-button",
|
||||
aria_label: "insert image",
|
||||
|
@ -347,10 +347,10 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp toggle_source_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" data-tooltip="Toggle source" data-element="toggle-source-button">
|
||||
<span class="tooltip top" data-tooltip="Toggle source" data-el-toggle-source-button>
|
||||
<button class="icon-button" aria-label="toggle source">
|
||||
<.remix_icon icon="code-line" class="text-xl" data-element="show-code-icon" />
|
||||
<.remix_icon icon="pencil-line" class="text-xl" data-element="show-ui-icon" />
|
||||
<.remix_icon icon="code-line" class="text-xl" data-el-show-code-icon />
|
||||
<.remix_icon icon="pencil-line" class="text-xl" data-el-show-ui-icon />
|
||||
</button>
|
||||
</span>
|
||||
"""
|
||||
|
@ -414,11 +414,11 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
def amplify_output_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" data-tooltip="Amplify output" data-element="amplify-outputs-button">
|
||||
<span class="tooltip top" data-tooltip="Amplify output" data-el-amplify-outputs-button>
|
||||
<button class="icon-button"
|
||||
aria-label="amplify outputs">
|
||||
<.remix_icon icon="zoom-in-line" class="text-xl" data-element="zoom-in-icon" />
|
||||
<.remix_icon icon="zoom-out-line" class="text-xl" data-element="zoom-out-icon" />
|
||||
<.remix_icon icon="zoom-in-line" class="text-xl" data-el-zoom-in-icon />
|
||||
<.remix_icon icon="zoom-out-line" class="text-xl" data-el-zoom-out-icon />
|
||||
</button>
|
||||
</span>
|
||||
"""
|
||||
|
@ -488,7 +488,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp setup_cell_info(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top"
|
||||
<span class="tooltip left"
|
||||
data-tooltip={
|
||||
~s'''
|
||||
The setup cell includes code that initializes the notebook
|
||||
|
@ -506,7 +506,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
defp evaluation_outputs(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col"
|
||||
data-element="outputs-container"
|
||||
data-el-outputs-container
|
||||
id={"outputs-#{@cell_view.id}-#{@cell_view.eval.outputs_batch_number}"}
|
||||
phx-update="append">
|
||||
<LivebookWeb.Output.outputs
|
||||
|
@ -584,10 +584,10 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
~H"""
|
||||
<div class={"#{if(@tooltip, do: "tooltip")} bottom distant-medium"} data-tooltip={@tooltip}>
|
||||
<div class="flex items-center space-x-1">
|
||||
<div class="flex text-xs text-gray-400" data-element="cell-status">
|
||||
<div class="flex text-xs text-gray-400" data-el-cell-status>
|
||||
<%= render_slot(@inner_block) %>
|
||||
<%= if @change_indicator do %>
|
||||
<span data-element="change-indicator">*</span>
|
||||
<span data-el-change-indicator>*</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<span class="flex relative h-3 w-3">
|
||||
|
|
|
@ -42,7 +42,7 @@ defmodule LivebookWeb.SessionLive.CellEditorComponent do
|
|||
phx-hook="CellEditor"
|
||||
data-cell-id={@cell_id}
|
||||
data-tag={@tag}>
|
||||
<div class="py-3 rounded-lg bg-editor" data-element="editor-container">
|
||||
<div class="py-3 rounded-lg bg-editor" data-el-editor-container>
|
||||
<div class="px-8">
|
||||
<.content_skeleton bg_class="bg-gray-500" empty={empty?(@source_view)} />
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col items-center space-y-2" data-element="notebook-indicators">
|
||||
<div class="flex flex-col items-center space-y-2" data-el-notebook-indicators>
|
||||
<%= if @file do %>
|
||||
<%= if @dirty do %>
|
||||
<%= if @autosave_interval_s do %>
|
||||
|
@ -58,7 +58,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<% end %>
|
||||
|
||||
<%# Note: this indicator is shown/hidden using CSS based on the current mode %>
|
||||
<span class="tooltip left" data-tooltip="Insert mode" data-element="insert-mode-indicator">
|
||||
<span class="tooltip left" data-tooltip="Insert mode" data-el-insert-mode-indicator>
|
||||
<span class="text-sm font-medium text-gray-400 cursor-default">
|
||||
ins
|
||||
</span>
|
||||
|
@ -72,7 +72,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<span class="tooltip left" data-tooltip="Go to evaluating cell">
|
||||
<button class="border-blue-400 icon-button icon-outlined-button hover:bg-blue-50 focus:bg-blue-50"
|
||||
aria-label="go to evaluating cell"
|
||||
data-element="focus-cell-button"
|
||||
data-el-focus-cell-button
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-blue-500 animate-spin" />
|
||||
</button>
|
||||
|
@ -85,7 +85,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<span class="tooltip left" data-tooltip="Go to last evaluated cell">
|
||||
<button class="border-green-bright-300 icon-button icon-outlined-button hover:bg-green-bright-50 focus:bg-green-bright-50"
|
||||
aria-label="go to last evaluated cell"
|
||||
data-element="focus-cell-button"
|
||||
data-el-focus-cell-button
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-green-bright-400" />
|
||||
</button>
|
||||
|
@ -98,7 +98,7 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<span class="tooltip left" data-tooltip="Go to first stale cell">
|
||||
<button class="border-yellow-bright-200 icon-button icon-outlined-button hover:bg-yellow-bright-50 focus:bg-yellow-bright-50"
|
||||
aria-label="go to first stale cell"
|
||||
data-element="focus-cell-button"
|
||||
data-el-focus-cell-button
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-yellow-bright-300" />
|
||||
</button>
|
||||
|
|
|
@ -6,7 +6,7 @@ defmodule LivebookWeb.SessionLive.InsertButtonsComponent do
|
|||
<div class="relative top-0.5 m-0 flex justify-center"
|
||||
role="toolbar"
|
||||
aria-label="insert new"
|
||||
data-element="insert-buttons">
|
||||
data-el-insert-buttons>
|
||||
<div class={"w-full absolute z-10 focus-within:z-[11] #{if(@persistent, do: "opacity-100", else: "opacity-0")} hover:opacity-100 focus-within:opacity-100 flex space-x-2 justify-center items-center"}>
|
||||
<button class="button-base button-small"
|
||||
phx-click="insert_cell_below"
|
||||
|
|
|
@ -3,9 +3,9 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<section data-element="section" data-section-id={@section_view.id}>
|
||||
<section data-el-section data-section-id={@section_view.id}>
|
||||
<div class="flex space-x-4 items-center"
|
||||
data-element="section-headline"
|
||||
data-el-section-headline
|
||||
id={@section_view.id}
|
||||
data-focusable-id={@section_view.id}
|
||||
phx-hook="Headline"
|
||||
|
@ -14,9 +14,9 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
<h2 class="grow text-gray-800 font-semibold text-2xl px-1 -ml-1 rounded-lg border border-transparent whitespace-pre-wrap cursor-text"
|
||||
tabindex="0"
|
||||
id={@section_view.html_id}
|
||||
data-element="heading"
|
||||
data-el-heading
|
||||
spellcheck="false"><%= @section_view.name %></h2>
|
||||
<div class="flex space-x-2 items-center" data-element="section-actions"
|
||||
<div class="flex space-x-2 items-center" data-el-section-actions
|
||||
role="toolbar"
|
||||
aria-label="section actions">
|
||||
<span class="tooltip top" data-tooltip="Link">
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
<span class="tooltip right distant" data-tooltip={@label}>
|
||||
<button class="text-2xl text-gray-400 hover:text-gray-50 focus:text-gray-50 rounded-xl h-10 w-10 flex items-center justify-center"
|
||||
aria-label={@label}
|
||||
data-element={@data_element}>
|
||||
{@button_attrs}>
|
||||
<.remix_icon icon={@icon} />
|
||||
</button>
|
||||
</span>
|
||||
|
@ -44,11 +44,13 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
end
|
||||
|
||||
def link_item(assigns) do
|
||||
assigns = assign_new(assigns, :link_attrs, fn -> [] end)
|
||||
|
||||
~H"""
|
||||
<span class="tooltip right distant" data-tooltip={@label}>
|
||||
<%= live_patch to: @path,
|
||||
<%= live_patch [to: @path,
|
||||
class: "text-gray-400 hover:text-gray-50 focus:text-gray-50 rounded-xl h-10 w-10 flex items-center justify-center #{if(@active, do: "text-gray-50 bg-gray-700")}",
|
||||
aria_label: @label do %>
|
||||
aria_label: @label] ++ @link_attrs do %>
|
||||
<.remix_icon icon={@icon} class="text-2xl" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
|
@ -135,9 +135,9 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServerTest do
|
|||
describe "handle_intellisense/5 given completion request" do
|
||||
test "provides basic completion when no evaluation reference is given", %{pid: pid} do
|
||||
request = {:completion, "System.ver"}
|
||||
RuntimeServer.handle_intellisense(pid, self(), :ref, request, {:c1, nil})
|
||||
ref = RuntimeServer.handle_intellisense(pid, self(), request, {:c1, nil})
|
||||
|
||||
assert_receive {:runtime_intellisense_response, :ref, ^request,
|
||||
assert_receive {:runtime_intellisense_response, ^ref, ^request,
|
||||
%{items: [%{label: "version/0"}]}}
|
||||
end
|
||||
|
||||
|
@ -151,15 +151,15 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServerTest do
|
|||
assert_receive {:runtime_evaluation_response, :e1, _, %{evaluation_time_ms: _time_ms}}
|
||||
|
||||
request = {:completion, "num"}
|
||||
RuntimeServer.handle_intellisense(pid, self(), :ref, request, {:c1, :e1})
|
||||
ref = RuntimeServer.handle_intellisense(pid, self(), request, {:c1, :e1})
|
||||
|
||||
assert_receive {:runtime_intellisense_response, :ref, ^request,
|
||||
assert_receive {:runtime_intellisense_response, ^ref, ^request,
|
||||
%{items: [%{label: "number"}]}}
|
||||
|
||||
request = {:completion, "ANSI.brigh"}
|
||||
RuntimeServer.handle_intellisense(pid, self(), :ref, request, {:c1, :e1})
|
||||
ref = RuntimeServer.handle_intellisense(pid, self(), request, {:c1, :e1})
|
||||
|
||||
assert_receive {:runtime_intellisense_response, :ref, ^request,
|
||||
assert_receive {:runtime_intellisense_response, ^ref, ^request,
|
||||
%{items: [%{label: "bright/0"}]}}
|
||||
end
|
||||
end
|
||||
|
@ -167,9 +167,9 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServerTest do
|
|||
describe "handle_intellisense/5 given details request" do
|
||||
test "responds with identifier details", %{pid: pid} do
|
||||
request = {:details, "System.version", 10}
|
||||
RuntimeServer.handle_intellisense(pid, self(), :ref, request, {:c1, nil})
|
||||
ref = RuntimeServer.handle_intellisense(pid, self(), request, {:c1, nil})
|
||||
|
||||
assert_receive {:runtime_intellisense_response, :ref, ^request,
|
||||
assert_receive {:runtime_intellisense_response, ^ref, ^request,
|
||||
%{range: %{from: 1, to: 15}, contents: [_]}}
|
||||
end
|
||||
end
|
||||
|
@ -177,9 +177,9 @@ defmodule Livebook.Runtime.ErlDist.RuntimeServerTest do
|
|||
describe "handle_intellisense/5 given format request" do
|
||||
test "responds with a formatted code", %{pid: pid} do
|
||||
request = {:format, "System.version"}
|
||||
RuntimeServer.handle_intellisense(pid, self(), :ref, request, {:c1, nil})
|
||||
ref = RuntimeServer.handle_intellisense(pid, self(), request, {:c1, nil})
|
||||
|
||||
assert_receive {:runtime_intellisense_response, :ref, ^request, %{code: "System.version()"}}
|
||||
assert_receive {:runtime_intellisense_response, ^ref, ^request, %{code: "System.version()"}}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -233,7 +233,7 @@ defmodule LivebookWeb.HomeLiveTest do
|
|||
|
||||
assert {:error, {:live_redirect, %{to: to}}} =
|
||||
view
|
||||
|> element(~s{[data-element="explore-section"] a}, "Welcome to Livebook")
|
||||
|> element(~s{[data-el-explore-section] a}, "Welcome to Livebook")
|
||||
|> render_click()
|
||||
|> follow_redirect(conn)
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("queue_cell_evaluation", %{"cell_id" => cell_id})
|
||||
|
||||
assert %{cell_infos: %{^cell_id => %{eval: %{status: :evaluating}}}} =
|
||||
|
@ -137,7 +137,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("queue_cell_evaluation", %{"cell_id" => "setup"})
|
||||
|
||||
assert_receive {:operation, {:set_runtime, _pid, %{} = _runtime}}
|
||||
|
@ -150,11 +150,11 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("queue_cell_evaluation", %{"cell_id" => cell_id})
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("cancel_cell_evaluation", %{"cell_id" => cell_id})
|
||||
|
||||
assert %{cell_infos: %{^cell_id => %{eval: %{status: :ready}}}} =
|
||||
|
@ -168,7 +168,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("insert_cell_below", %{"cell_id" => cell_id, "type" => "markdown"})
|
||||
|
||||
assert %{notebook: %{sections: [%{cells: [_first_cell, %Cell.Markdown{}]}]}} =
|
||||
|
@ -182,7 +182,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("insert_cell_below", %{"section_id" => section_id, "type" => "markdown"})
|
||||
|
||||
assert %{notebook: %{sections: [%{cells: [%Cell.Markdown{}, _first_cell]}]}} =
|
||||
|
@ -196,7 +196,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("delete_cell", %{"cell_id" => cell_id})
|
||||
|
||||
assert %{notebook: %{sections: [%{cells: []}]}} = Session.get_data(session.pid)
|
||||
|
@ -245,7 +245,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s/[data-element="outputs-container"] form/)
|
||||
|> element(~s/[data-el-outputs-container] form/)
|
||||
|> render_change(%{"value" => "10"})
|
||||
|
||||
assert %{input_values: %{"input1" => 10}} = Session.get_data(session.pid)
|
||||
|
@ -274,7 +274,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s/[data-element="outputs-container"] form/)
|
||||
|> element(~s/[data-el-outputs-container] form/)
|
||||
|> render_change(%{"value" => "line\r\nline"})
|
||||
|
||||
assert %{input_values: %{"input1" => "line\nline"}} = Session.get_data(session.pid)
|
||||
|
@ -312,7 +312,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s/[data-element="outputs-container"] form/)
|
||||
|> element(~s/[data-el-outputs-container] form/)
|
||||
|> render_change(%{"value" => "sherlock"})
|
||||
|
||||
# The new value is on the page
|
||||
|
@ -321,7 +321,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
assert %{input_values: %{"input1" => "initial"}} = Session.get_data(session.pid)
|
||||
|
||||
view
|
||||
|> element(~s/[data-element="outputs-container"] button/, "Send")
|
||||
|> element(~s/[data-el-outputs-container] button/, "Send")
|
||||
|> render_click()
|
||||
|
||||
assert_receive {:event, :form_ref, %{data: %{name: "sherlock"}, type: :submit}}
|
||||
|
@ -512,7 +512,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("intellisense_request", %{
|
||||
"cell_id" => cell_id,
|
||||
"type" => "completion",
|
||||
|
@ -534,7 +534,7 @@ defmodule LivebookWeb.SessionLiveTest do
|
|||
{:ok, view, _} = live(conn, "/sessions/#{session.id}")
|
||||
|
||||
view
|
||||
|> element(~s{[data-element="session"]})
|
||||
|> element(~s{[data-el-session]})
|
||||
|> render_hook("intellisense_request", %{
|
||||
"cell_id" => cell_id,
|
||||
"type" => "completion",
|
||||
|
|
|
@ -24,7 +24,7 @@ defmodule Livebook.Runtime.NoopRuntime do
|
|||
def evaluate_code(_, _, _, _, _ \\ []), do: :ok
|
||||
def forget_evaluation(_, _), do: :ok
|
||||
def drop_container(_, _), do: :ok
|
||||
def handle_intellisense(_, _, _, _, _), do: :ok
|
||||
def handle_intellisense(_, _, _, _), do: make_ref()
|
||||
|
||||
def standalone?(_), do: false
|
||||
def read_file(_, _), do: raise("not implemented")
|
||||
|
|
Loading…
Reference in a new issue