Browse Source

Revert "Move CodeMirror HTML tree and related CSS to shadow DOM."

This reverts commit ab98eb95027b863f827b33bca89a6b0d70679157.
Jeremy Tuloup 4 years ago
parent
commit
a4cd0b5e46

+ 0 - 1
dev_mode/package.json

@@ -184,7 +184,6 @@
     "style-loader": "~1.2.1",
     "svg-url-loader": "~6.0.0",
     "terser-webpack-plugin": "^4.1.0",
-    "to-string-loader": "^1.1.6",
     "url-loader": "~4.1.0",
     "webpack": "~5.0.0-beta.29",
     "webpack-bundle-analyzer": "^3.6.0",

+ 2 - 2
packages/codeeditor/test/widget.spec.ts

@@ -133,7 +133,7 @@ describe('CodeEditorWrapper', () => {
         const editor = widget.editor as LogEditor;
         MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);
         editor.methods = [];
-        simulate(editor.editor.getInputField(), 'focus', { composed: true });
+        simulate(editor.editor.getInputField(), 'focus');
         expect(editor.methods).toEqual(['refresh']);
       });
     });
@@ -195,7 +195,7 @@ describe('CodeEditorWrapper', () => {
       editor.methods = [];
       MessageLoop.sendMessage(widget, Widget.ResizeMessage.UnknownSize);
       expect(editor.methods).toEqual([]);
-      simulate(editor.editor.getInputField(), 'focus', { composed: true });
+      simulate(editor.editor.getInputField(), 'focus');
       expect(editor.methods).toEqual(['refresh']);
     });
   });

+ 11 - 0
packages/codemirror-extension/src/index.ts

@@ -172,6 +172,17 @@ function activateEditorCommands(
     }
 
     theme = (settings.get('theme').composite as string | null) || theme;
+
+    // Lazy loading of theme stylesheets
+    if (theme !== 'jupyter' && theme !== 'default') {
+      const filename =
+        theme === 'solarized light' || theme === 'solarized dark'
+          ? 'solarized'
+          : theme;
+
+      await import(`codemirror/theme/${filename}.css`);
+    }
+
     scrollPastEnd =
       (settings.get('scrollPastEnd').composite as boolean | null) ??
       scrollPastEnd;

+ 4 - 74
packages/codemirror/src/editor.ts

@@ -55,11 +55,6 @@ import 'codemirror/keymap/emacs.js';
 import 'codemirror/keymap/sublime.js';
 // import 'codemirror/keymap/vim.js';  lazy loading of vim mode is available in ../codemirror-extension/index.ts
 
-// @ts-expect-error
-import shadowCss from '!!to-string-loader!css-loader!../style/shadow.css';
-// @ts-expect-error
-import jupyterThemeCSS from '!!to-string-loader!css-loader!../style/jupyter-theme.css';
-
 /**
  * The class name added to CodeMirrorWidget instances.
  */
@@ -80,11 +75,6 @@ const COLLABORATOR_CURSOR_CLASS = 'jp-CollaboratorCursor';
  */
 const COLLABORATOR_HOVER_CLASS = 'jp-CollaboratorCursor-hover';
 
-/**
- * The id of the style element containing CodeMirror theme CSS.
- */
-const CODEMIRROR_THEME_STYLE_ID = 'jp-CodeMirror-theme';
-
 /**
  * The key code for the up arrow key.
  */
@@ -112,19 +102,6 @@ export class CodeMirrorEditor implements CodeEditor.IEditor {
     this.translator = options.translator || nullTranslator;
     this._trans = this.translator.load('jupyterlab');
 
-    // Attach shadow root to host if host does not have already it.
-    const shadowRoot = host.shadowRoot || host.attachShadow({ mode: 'open' });
-
-    // Add a style element with the CodeMirror core CSS to the shadow root.
-    const shadowStyleEl = document.createElement('style');
-    shadowStyleEl.textContent = shadowCss;
-    shadowRoot.appendChild(shadowStyleEl);
-    // Add CodeMirror theme stylesheet.
-    const themeStyleEl = document.createElement('style');
-    themeStyleEl.id = CODEMIRROR_THEME_STYLE_ID;
-    themeStyleEl.textContent = jupyterThemeCSS;
-    shadowRoot.appendChild(themeStyleEl);
-
     host.classList.add(EDITOR_CLASS);
     host.classList.add('jp-Editor');
     host.addEventListener('focus', this, true);
@@ -146,10 +123,7 @@ export class CodeMirrorEditor implements CodeEditor.IEditor {
       ...CodeMirrorEditor.defaultConfig,
       ...config
     });
-    const editor = (this._editor = Private.createEditor(
-      shadowRoot,
-      fullConfig
-    ));
+    const editor = (this._editor = Private.createEditor(host, fullConfig));
 
     const doc = editor.getDoc();
 
@@ -329,13 +303,7 @@ export class CodeMirrorEditor implements CodeEditor.IEditor {
     // Don't bother setting the option if it is already the same.
     if (this._config[option] !== value) {
       this._config[option] = value;
-      Private.setOption(
-        this.editor,
-        this.host.shadowRoot!,
-        option,
-        value,
-        this._config
-      );
+      Private.setOption(this.editor, option, value, this._config);
     }
   }
 
@@ -396,7 +364,7 @@ export class CodeMirrorEditor implements CodeEditor.IEditor {
    * Test whether the editor has keyboard focus.
    */
   hasFocus(): boolean {
-    return this.host === document.activeElement;
+    return this._editor.getWrapperElement().contains(document.activeElement);
   }
 
   /**
@@ -1351,7 +1319,7 @@ export namespace CodeMirrorEditor {
  */
 namespace Private {
   export function createEditor(
-    host: ShadowRoot,
+    host: HTMLElement,
     config: CodeMirrorEditor.IConfig
   ): CodeMirror.Editor {
     const {
@@ -1482,46 +1450,11 @@ namespace Private {
     );
   }
 
-  /**
-   * Set the stylesheet for the selected theme.
-   */
-  async function setTheme(
-    editor: CodeMirror.Editor,
-    shadowRoot: ShadowRoot,
-    theme: string
-  ): Promise<void> {
-    let stylesheet: string;
-
-    if (theme === 'jupyter') {
-      stylesheet = jupyterThemeCSS;
-    } else if (theme === 'default') {
-      stylesheet = '';
-    } else {
-      // Load the theme stylesheet.
-      const filename =
-        theme === 'solarized light' || theme === 'solarized dark'
-          ? 'solarized'
-          : theme;
-
-      const module = await import(
-        `!!to-string-loader!css-loader!codemirror/theme/${filename}.css`
-      );
-      stylesheet = module.default;
-    }
-
-    const themeStyleEl = shadowRoot.getElementById(
-      CODEMIRROR_THEME_STYLE_ID
-    ) as HTMLStyleElement;
-    themeStyleEl.textContent = stylesheet;
-    editor.setOption('theme', theme);
-  }
-
   /**
    * Set a config option for the editor.
    */
   export function setOption<K extends keyof CodeMirrorEditor.IConfig>(
     editor: CodeMirror.Editor,
-    shadowRoot: ShadowRoot,
     option: K,
     value: CodeMirrorEditor.IConfig[K],
     config: CodeMirrorEditor.IConfig
@@ -1598,9 +1531,6 @@ namespace Private {
         (editor.setOption as any)('foldGutter', value);
         editor.setOption('gutters', getActiveGutters(config));
         break;
-      case 'theme':
-        void setTheme(editor, shadowRoot, value as string);
-        break;
       default:
         (editor.setOption as any)(option, value);
         break;

+ 120 - 3
packages/codemirror/style/jupyter-theme.css → packages/codemirror/style/base.css

@@ -3,6 +3,117 @@
 | Distributed under the terms of the Modified BSD License.
 |----------------------------------------------------------------------------*/
 
+.CodeMirror {
+  line-height: var(--jp-code-line-height);
+  font-size: var(--jp-code-font-size);
+  font-family: var(--jp-code-font-family);
+  border: 0;
+  border-radius: 0;
+  height: auto;
+  /* Changed to auto to autogrow */
+}
+
+.CodeMirror pre {
+  padding: 0 var(--jp-code-padding);
+}
+
+.jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-dialog {
+  background-color: var(--jp-layout-color0);
+  color: var(--jp-content-font-color1);
+}
+
+/* This causes https://github.com/jupyter/jupyterlab/issues/522 */
+/* May not cause it not because we changed it! */
+.CodeMirror-lines {
+  padding: var(--jp-code-padding) 0;
+}
+
+.CodeMirror-linenumber {
+  padding: 0 8px;
+}
+
+.jp-CodeMirrorEditor {
+  cursor: text;
+}
+
+.jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor {
+  border-left: var(--jp-code-cursor-width0) solid var(--jp-editor-cursor-color);
+}
+
+/* When zoomed out 67% and 33% on a screen of 1440 width x 900 height */
+@media screen and (min-width: 2138px) and (max-width: 4319px) {
+  .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor {
+    border-left: var(--jp-code-cursor-width1) solid
+      var(--jp-editor-cursor-color);
+  }
+}
+
+/* When zoomed out less than 33% */
+@media screen and (min-width: 4320px) {
+  .jp-CodeMirrorEditor[data-type='inline'] .CodeMirror-cursor {
+    border-left: var(--jp-code-cursor-width2) solid
+      var(--jp-editor-cursor-color);
+  }
+}
+
+.CodeMirror.jp-mod-readOnly .CodeMirror-cursor {
+  display: none;
+}
+
+.CodeMirror-gutters {
+  border-right: 1px solid var(--jp-border-color2);
+  background-color: var(--jp-layout-color0);
+}
+
+.jp-CollaboratorCursor {
+  border-left: 5px solid transparent;
+  border-right: 5px solid transparent;
+  border-top: none;
+  border-bottom: 3px solid;
+  background-clip: content-box;
+  margin-left: -5px;
+  margin-right: -5px;
+}
+
+.CodeMirror-selectedtext.cm-searching {
+  background-color: var(--jp-search-selected-match-background-color) !important;
+  color: var(--jp-search-selected-match-color) !important;
+}
+
+.cm-searching {
+  background-color: var(
+    --jp-search-unselected-match-background-color
+  ) !important;
+  color: var(--jp-search-unselected-match-color) !important;
+}
+
+.CodeMirror-focused .CodeMirror-selected {
+  background-color: var(--jp-editor-selected-focused-background);
+}
+
+.CodeMirror-selected {
+  background-color: var(--jp-editor-selected-background);
+}
+
+.jp-CollaboratorCursor-hover {
+  position: absolute;
+  z-index: 1;
+  transform: translateX(-50%);
+  color: white;
+  border-radius: 3px;
+  padding-left: 4px;
+  padding-right: 4px;
+  padding-top: 1px;
+  padding-bottom: 1px;
+  text-align: center;
+  font-size: var(--jp-ui-font-size1);
+  white-space: nowrap;
+}
+
+.jp-CodeMirror-ruler {
+  border-left: 1px dashed var(--jp-border-color2);
+}
+
 /**
  * Here is our jupyter theme for CodeMirror syntax highlighting
  * This is used in our marked.js syntax highlighting and CodeMirror itself
@@ -10,14 +121,20 @@
  * This came from the classic notebook, which came form highlight.js/GitHub
  */
 
-:host {
+/**
+ * CodeMirror themes are handling the background/color in this way. This works
+ * fine for CodeMirror editors outside the notebook, but the notebook styles
+ * these things differently.
+ */
+.CodeMirror.cm-s-jupyter {
   background: var(--jp-layout-color0);
   color: var(--jp-content-font-color1);
 }
 
-.CodeMirror {
+/* In the notebook, we want this styling to be handled by its container */
+.jp-CodeConsole .CodeMirror.cm-s-jupyter,
+.jp-Notebook .CodeMirror.cm-s-jupyter {
   background: transparent;
-  color: inherit;
 }
 
 .cm-s-jupyter .CodeMirror-cursor {

+ 6 - 0
packages/codemirror/style/index.css

@@ -4,7 +4,13 @@
 |----------------------------------------------------------------------------*/
 
 /* This file was auto-generated by ensurePackage() in @jupyterlab/buildutils */
+@import url('~@jupyterlab/translation/style/index.css');
 @import url('~@lumino/widgets/style/index.css');
 @import url('~@jupyterlab/apputils/style/index.css');
 @import url('~@jupyterlab/codeeditor/style/index.css');
 @import url('~@jupyterlab/statusbar/style/index.css');
+@import url('~codemirror/lib/codemirror.css');
+@import url('~codemirror/addon/dialog/dialog.css');
+@import url('~codemirror/addon/fold/foldgutter.css');
+
+@import url('./base.css');

+ 0 - 119
packages/codemirror/style/shadow.css

@@ -1,119 +0,0 @@
-/*-----------------------------------------------------------------------------
-| Copyright (c) Jupyter Development Team.
-| Distributed under the terms of the Modified BSD License.
-|----------------------------------------------------------------------------*/
-
-@import url('~codemirror/lib/codemirror.css');
-@import url('~codemirror/addon/dialog/dialog.css');
-@import url('~codemirror/addon/fold/foldgutter.css');
-
-.CodeMirror {
-  line-height: var(--jp-code-line-height);
-  font-size: var(--jp-code-font-size);
-  font-family: var(--jp-code-font-family);
-  border: 0;
-  border-radius: 0;
-  height: auto;
-  /* Changed to auto to autogrow */
-}
-
-.CodeMirror pre {
-  padding: 0 var(--jp-code-padding);
-}
-
-:host([data-type='inline']) .CodeMirror-dialog {
-  background-color: var(--jp-layout-color0);
-  color: var(--jp-content-font-color1);
-}
-
-/* This causes https://github.com/jupyter/jupyterlab/issues/522 */
-/* May not cause it not because we changed it! */
-.CodeMirror-lines {
-  padding: var(--jp-code-padding) 0;
-}
-
-.CodeMirror-linenumber {
-  padding: 0 8px;
-}
-
-:host {
-  cursor: text;
-}
-
-:host([data-type='inline']) .CodeMirror-cursor {
-  border-left: var(--jp-code-cursor-width0) solid var(--jp-editor-cursor-color);
-}
-
-/* When zoomed out 67% and 33% on a screen of 1440 width x 900 height */
-@media screen and (min-width: 2138px) and (max-width: 4319px) {
-  :host([data-type='inline']) .CodeMirror-cursor {
-    border-left: var(--jp-code-cursor-width1) solid
-      var(--jp-editor-cursor-color);
-  }
-}
-
-/* When zoomed out less than 33% */
-@media screen and (min-width: 4320px) {
-  :host([data-type='inline']) .CodeMirror-cursor {
-    border-left: var(--jp-code-cursor-width2) solid
-      var(--jp-editor-cursor-color);
-  }
-}
-
-.CodeMirror.jp-mod-readOnly .CodeMirror-cursor {
-  display: none;
-}
-
-.CodeMirror-gutters {
-  border-right: 1px solid var(--jp-border-color2);
-  background-color: var(--jp-layout-color0);
-}
-
-.jp-CollaboratorCursor {
-  border-left: 5px solid transparent;
-  border-right: 5px solid transparent;
-  border-top: none;
-  border-bottom: 3px solid;
-  background-clip: content-box;
-  margin-left: -5px;
-  margin-right: -5px;
-}
-
-.CodeMirror-selectedtext.cm-searching {
-  background-color: var(--jp-search-selected-match-background-color) !important;
-  color: var(--jp-search-selected-match-color) !important;
-}
-
-.cm-searching {
-  background-color: var(
-    --jp-search-unselected-match-background-color
-  ) !important;
-  color: var(--jp-search-unselected-match-color) !important;
-}
-
-.CodeMirror-focused .CodeMirror-selected {
-  background-color: var(--jp-editor-selected-focused-background);
-}
-
-.CodeMirror-selected {
-  background-color: var(--jp-editor-selected-background);
-}
-
-.jp-CollaboratorCursor-hover {
-  position: absolute;
-  z-index: 1;
-  transform: translateX(-50%);
-  color: white;
-  border-radius: 3px;
-  padding-left: 4px;
-  padding-right: 4px;
-  padding-top: 1px;
-  padding-bottom: 1px;
-  text-align: center;
-  font-size: var(--jp-ui-font-size1);
-  white-space: nowrap;
-}
-
-.jp-CodeMirror-ruler {
-  border-left: 1px dashed var(--jp-border-color2);
-}

+ 3 - 3
packages/codemirror/test/editor.spec.ts

@@ -278,16 +278,16 @@ describe('CodeMirrorEditor', () => {
   describe('#handleEvent', () => {
     describe('focus', () => {
       it('should add the focus class to the host', () => {
-        simulate(editor.editor.getInputField(), 'focus', { composed: true });
+        simulate(editor.editor.getInputField(), 'focus');
         expect(host.classList.contains('jp-mod-focused')).toBe(true);
       });
     });
 
     describe('blur', () => {
       it('should remove the focus class from the host', () => {
-        simulate(editor.editor.getInputField(), 'focus', { composed: true });
+        simulate(editor.editor.getInputField(), 'focus');
         expect(host.classList.contains('jp-mod-focused')).toBe(true);
-        simulate(editor.editor.getInputField(), 'blur', { composed: true });
+        simulate(editor.editor.getInputField(), 'blur');
         expect(host.classList.contains('jp-mod-focused')).toBe(false);
       });
     });

+ 0 - 2
testutils/src/jest-config.ts

@@ -4,8 +4,6 @@ module.exports = function (baseDir: string) {
   return {
     preset: 'ts-jest/presets/js-with-babel',
     moduleNameMapper: {
-      '^!!to-string-loader!css-loader!.+\\.css':
-        '@jupyterlab/testutils/lib/jest-style-mock.js',
       '\\.(css|less|sass|scss)$': 'identity-obj-proxy',
       '\\.(gif|ttf|eot)$': '@jupyterlab/testutils/lib/jest-file-mock.js'
     },

+ 0 - 1
testutils/src/jest-style-mock.ts

@@ -1 +0,0 @@
-module.exports = '';