Sfoglia il codice sorgente

Focus behavior fixes (#3624)

* Only change editor readonly status if needed in a cell update.

* Don’t blur the editor when setting to readonly.

* Don’t blur an editor - rather, focus something else.

* Preserve edit mode when changing browser tabs

Since we explicitly focus elements (rather than blurring) inside the app, we can distinguish between changing focus in the app and the window going into the background.

Solves #1737 again

* update test
Jason Grout 7 anni fa
parent
commit
6298c5a5cd

+ 1 - 6
packages/codemirror/src/editor.ts

@@ -1190,12 +1190,7 @@ namespace Private {
       break;
     case 'readOnly':
       let el = editor.getWrapperElement();
-      if (value) {
-        el.classList.add(READ_ONLY_CLASS);
-      } else {
-        el.classList.remove(READ_ONLY_CLASS);
-        editor.getInputField().blur();
-      }
+      el.classList.toggle(READ_ONLY_CLASS, value);
       editor.setOption(option, value);
       break;
     default:

+ 6 - 11
packages/notebook/src/widget.ts

@@ -813,11 +813,8 @@ class Notebook extends StaticNotebook {
       }
       activeCell.inputHidden = false;
     } else {
-      // Blur the active cell.
-      let activeCell = this.activeCell;
-      if (activeCell) {
-        activeCell.editor.blur();
-      }
+      // Focus on the notebook document, which blurs the active cell.
+      this.node.focus();
     }
     this._stateChanged.emit({ name: 'mode', oldValue, newValue });
     this._ensureFocus();
@@ -849,9 +846,6 @@ class Notebook extends StaticNotebook {
     if (cell !== this._activeCell) {
       // Post an update request.
       this.update();
-      if (this._activeCell) {
-        this._activeCell.editor.blur();
-      }
       this._activeCell = cell;
       this._activeCellChanged.emit(cell);
     }
@@ -1837,9 +1831,9 @@ class Notebook extends StaticNotebook {
   private _evtFocusOut(event: MouseEvent): void {
     let relatedTarget = event.relatedTarget as HTMLElement;
 
-    // Bail if focus is leaving the notebook.
-    if (!this.node.contains(relatedTarget)) {
-      this.mode = 'command';
+    // Bail if the window is losing focus, to preserve edit mode. This test
+    // assumes that we explicitly focus things rather than calling blur()
+    if (!relatedTarget) {
       return;
     }
 
@@ -1852,6 +1846,7 @@ class Notebook extends StaticNotebook {
         return;
       }
     }
+
     // Otherwise enter command mode.
     this.mode = 'command';
   }

+ 3 - 2
tests/test-notebook/src/widget.spec.ts

@@ -1289,8 +1289,9 @@ describe('notebook/widget', () => {
         it('should switch to command mode', () => {
           simulate(widget.node, 'focusin');
           widget.mode = 'edit';
-          let other = document.createElement('div');
-          simulate(widget.node, 'focusout', { relatedTarget: other });
+          let event = generate('focusout');
+          (event as any).relatedTarget = document.body;
+          widget.node.dispatchEvent(event);
           expect(widget.mode).to.be('command');
           MessageLoop.sendMessage(widget, Widget.Msg.ActivateRequest);
           expect(widget.mode).to.be('command');