Преглед на файлове

Merge pull request #132 from marthacryan/configure-collapsible

Add ability to enable / disable collapsible notebook cells
Luciano Resende преди 5 години
родител
ревизия
9a48f9ace4

+ 3 - 1
packages/toc/package.json

@@ -20,6 +20,7 @@
   "author": "Project Jupyter",
   "files": [
     "lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
+    "schema/*.json",
     "style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
   ],
   "main": "lib/index.js",
@@ -74,6 +75,7 @@
     "access": "public"
   },
   "jupyterlab": {
-    "extension": "lib/extension.js"
+    "extension": "lib/extension.js",
+    "schemaDir": "schema"
   }
 }

+ 14 - 0
packages/toc/schema/plugin.json

@@ -0,0 +1,14 @@
+{
+  "title": "Table of Contents",
+  "description": "Table of contents settings.",
+  "properties": {
+    "collapsibleNotebooks": {
+      "title": "ToC Configuration",
+      "description": "Specifies whether to allow the ToC extension to collapse notebook cells.",
+      "type": "boolean",
+      "default": false
+    }
+  },
+  "additionalProperties": false,
+  "type": "object"
+}

+ 21 - 7
packages/toc/src/extension.ts

@@ -12,6 +12,7 @@ import { IEditorTracker } from '@jupyterlab/fileeditor';
 import { IMarkdownViewerTracker } from '@jupyterlab/markdownviewer';
 import { INotebookTracker } from '@jupyterlab/notebook';
 import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
+import { ISettingRegistry } from '@jupyterlab/settingregistry';
 import { TableOfContents } from './toc';
 import {
   createLatexGenerator,
@@ -40,7 +41,7 @@ import '../style/index.css';
  * @param rendermime - rendered MIME registry
  * @returns table of contents registry
  */
-function activateTOC(
+async function activateTOC(
   app: JupyterFrontEnd,
   docmanager: IDocumentManager,
   editorTracker: IEditorTracker,
@@ -48,8 +49,9 @@ function activateTOC(
   restorer: ILayoutRestorer,
   markdownViewerTracker: IMarkdownViewerTracker,
   notebookTracker: INotebookTracker,
-  rendermime: IRenderMimeRegistry
-): ITableOfContentsRegistry {
+  rendermime: IRenderMimeRegistry,
+  settingRegistry: ISettingRegistry
+): Promise<ITableOfContentsRegistry> {
   // Create the ToC widget:
   const toc = new TableOfContents({ docmanager, rendermime });
 
@@ -63,13 +65,24 @@ function activateTOC(
   labShell.add(toc, 'left', { rank: 700 });
 
   // Add the ToC widget to the application restorer:
-  restorer.add(toc, 'juputerlab-toc');
+  restorer.add(toc, '@jupyterlab/toc:plugin');
+
+  // Attempt to load plugin settings:
+  let settings: ISettingRegistry.ISettings | undefined;
+  try {
+    settings = await settingRegistry.load('@jupyterlab/toc:plugin');
+  } catch (error) {
+    console.error(
+      `Failed to load settings for the Table of Contents extension.\n\n${error}`
+    );
+  }
 
   // Create a notebook generator:
   const notebookGenerator = createNotebookGenerator(
     notebookTracker,
     toc,
-    rendermime.sanitizer
+    rendermime.sanitizer,
+    settings
   );
   registry.add(notebookGenerator);
 
@@ -131,7 +144,7 @@ function activateTOC(
  * @private
  */
 const extension: JupyterFrontEndPlugin<ITableOfContentsRegistry> = {
-  id: 'jupyterlab-toc',
+  id: '@jupyterlab/toc:plugin',
   autoStart: true,
   provides: ITableOfContentsRegistry,
   requires: [
@@ -141,7 +154,8 @@ const extension: JupyterFrontEndPlugin<ITableOfContentsRegistry> = {
     ILayoutRestorer,
     IMarkdownViewerTracker,
     INotebookTracker,
-    IRenderMimeRegistry
+    IRenderMimeRegistry,
+    ISettingRegistry
   ],
   activate: activateTOC
 };

+ 8 - 1
packages/toc/src/generators/notebook/index.ts

@@ -4,6 +4,7 @@
 import { ISanitizer } from '@jupyterlab/apputils';
 import { CodeCell, CodeCellModel, MarkdownCell, Cell } from '@jupyterlab/cells';
 import { INotebookTracker, NotebookPanel } from '@jupyterlab/notebook';
+import { ISettingRegistry } from '@jupyterlab/settingregistry';
 import { TableOfContentsRegistry as Registry } from '../../registry';
 import { TableOfContents } from '../../toc';
 import { isMarkdown } from '../../utils/is_markdown';
@@ -31,10 +32,16 @@ import { toolbar } from './toolbar_generator';
 function createNotebookGenerator(
   tracker: INotebookTracker,
   widget: TableOfContents,
-  sanitizer: ISanitizer
+  sanitizer: ISanitizer,
+  settings?: ISettingRegistry.ISettings
 ): Registry.IGenerator<NotebookPanel> {
+  let collapsibleNotebooks = true;
+  if (settings) {
+    collapsibleNotebooks = settings.composite.collapsibleNotebooks as boolean;
+  }
   const options = new OptionsManager(widget, tracker, {
     numbering: false,
+    collapsibleNotebooks: collapsibleNotebooks,
     sanitizer: sanitizer
   });
   return {

+ 14 - 0
packages/toc/src/generators/notebook/options_manager.ts

@@ -21,6 +21,11 @@ interface Options {
    */
   sanitizer: ISanitizer;
 
+  /**
+   * Boolean indicating whether notebook cells are collapsible.
+   */
+  collapsibleNotebooks: boolean;
+
   /**
    * Tag tool component.
    */
@@ -50,6 +55,7 @@ class OptionsManager extends Registry.IOptionsManager {
     this._numbering = options.numbering;
     this._widget = widget;
     this._notebook = notebook;
+    this._collapsible = options.collapsibleNotebooks;
     this.sanitizer = options.sanitizer;
     this.storeTags = [];
   }
@@ -92,6 +98,13 @@ class OptionsManager extends Registry.IOptionsManager {
     return this._numbering;
   }
 
+  /**
+   * Gets the ToC setting specifying whether to allow collapsing notebook cells.
+   */
+  get collapsibleNotebooks() {
+    return this._collapsible;
+  }
+
   /**
    * Toggles whether to show code previews in the table of contents.
    */
@@ -195,6 +208,7 @@ class OptionsManager extends Registry.IOptionsManager {
   private _showMarkdown = false;
   private _showTags = false;
   private _notebook: INotebookTracker;
+  private _collapsible = false;
   private _widget: TableOfContents;
   private _tagTool: TagsToolComponent | null = null;
   public storeTags: string[];

+ 29 - 18
packages/toc/src/generators/notebook/render.tsx

@@ -49,19 +49,24 @@ function render(
           'toc-hr-collapsed'
         ) as boolean;
 
-        // Render the twist button:
-        let button = twistButton(item.cellRef, collapsed || false, onClick);
-
         // Update the collapsed state of the corresponding notebook cell:
         setCollapsedState(tracker, item.cellRef, collapsed);
 
-        // Render the heading item:
-        jsx = (
-          <div className="toc-entry-holder">
-            {button}
-            {jsx}
-          </div>
-        );
+        // Only render the twist button if configured to enable collapsing behavior:
+        if (options.collapsibleNotebooks) {
+          let button = twistButton(item.cellRef, collapsed || false, onClick);
+
+          // Render the heading item:
+          jsx = (
+            <div className="toc-entry-holder">
+              {button}
+              {jsx}
+            </div>
+          );
+        } else {
+          // Render the heading item without the dropdown button:
+          jsx = <div className="toc-entry-holder">{jsx}</div>;
+        }
       }
       return jsx;
     }
@@ -76,14 +81,20 @@ function render(
         let collapsed = item.cellRef!.model.metadata.get(
           'toc-hr-collapsed'
         ) as boolean;
-        let button = twistButton(item.cellRef, collapsed || false, onClick);
-        setCollapsedState(tracker, item.cellRef, collapsed);
-        jsx = (
-          <div className="toc-entry-holder">
-            {button}
-            {jsx}
-          </div>
-        );
+
+        if (options.collapsibleNotebooks) {
+          let button = twistButton(item.cellRef, collapsed || false, onClick);
+          setCollapsedState(tracker, item.cellRef, collapsed);
+          jsx = (
+            <div className="toc-entry-holder">
+              {button}
+              {jsx}
+            </div>
+          );
+        } else {
+          // Render the heading item without the dropdown button:
+          jsx = <div className="toc-entry-holder">{jsx}</div>;
+        }
       }
       return jsx;
     }

+ 1 - 1
packages/toc/src/registry.ts

@@ -18,7 +18,7 @@ export interface ITableOfContentsRegistry extends TableOfContentsRegistry {}
  * Table of contents registry token.
  */
 export const ITableOfContentsRegistry = new Token<TableOfContentsRegistry>(
-  'jupyterlab-toc:ITableOfContentsRegistry'
+  '@jupyterlab/toc:ITableOfContentsRegistry'
 );
 /* tslint:enable */