From 60cb46c4b5027f7f6bfe776569a06f3f2c5a1b54 Mon Sep 17 00:00:00 2001
From: Andrew Head
Date: Wed, 27 Feb 2019 21:24:42 -0800
Subject: [PATCH] UI: Enabled the revision browser for Jupyter Lab once again
---
src/overlay/revision-browser.ts | 100 ++++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 src/overlay/revision-browser.ts
diff --git a/src/overlay/revision-browser.ts b/src/overlay/revision-browser.ts
new file mode 100644
index 0000000..76c03de
--- /dev/null
+++ b/src/overlay/revision-browser.ts
@@ -0,0 +1,100 @@
+import { nbformat } from "@jupyterlab/coreutils";
+import { RenderMimeRegistry, standardRendererFactories } from "@jupyterlab/rendermime";
+import { PanelLayout, Widget } from "@phosphor/widgets";
+import { GatherModel, GatherState } from "../model/model";
+import { log } from "../util/log";
+import { DisplayData } from "../widgets/displaydata";
+import { buildHistoryModel, HistoryViewer } from "../widgets/history";
+import { IOutputRenderer } from "../widgets/revision";
+
+/**
+ * Class for the revision browser widget.
+ */
+const REVISION_BROWSER_CLASS = "jp-Notebook-revisionbrowser";
+
+/**
+ * Class for output areas in the revision browser.
+ */
+const REVISION_OUTPUT_CLASS = "jp-Notebook-revisionbrowser-output";
+
+
+/**
+ * Renders output models for notebooks as new cells.
+ */
+class OutputRenderer implements IOutputRenderer {
+ /**
+ * Render HTML element for this output.
+ */
+ render(output: nbformat.IOutput): HTMLElement {
+ let widget = new DisplayData({
+ model: output,
+ rendermime: new RenderMimeRegistry({ initialFactories: standardRendererFactories })
+ });
+ widget.addClass(REVISION_OUTPUT_CLASS);
+ return widget.node;
+ }
+}
+
+/**
+ * Window that lets the user browse revisions of code.
+ */
+export class RevisionBrowser extends Widget {
+ /**
+ * Construct a new revision browser.
+ */
+ constructor(gatherModel: GatherModel) {
+ super();
+ this.id = "revision-browser";
+ this.title.label = "Revision browser";
+ this.title.icon = "jp-HistoryIcon";
+ this.title.closable = true;
+ this.addClass(REVISION_BROWSER_CLASS);
+
+ this._gatherModel = gatherModel;
+ this._outputRenderer = new OutputRenderer();
+ this.layout = new PanelLayout();
+
+ this.attachSliceWidgets(gatherModel);
+ }
+
+ attachSliceWidgets(model: GatherModel) {
+ let defSelections = model.selectedDefs;
+ let outputSelections = model.selectedOutputs;
+ let slices;
+ let cellPersistentId;
+ if (defSelections.length > 0) {
+ slices = model.getSelectedDefSlices(defSelections[0]);
+ cellPersistentId = defSelections[0].cell.persistentId;
+ } else if (outputSelections.length > 0) {
+ slices = model.getSelectedOutputSlices(outputSelections[0]);
+ cellPersistentId = outputSelections[0].cell.persistentId;
+ }
+ log("Bringing up the revision browser for selection", {
+ cellPersistendId: cellPersistentId, slices,
+ selectedDefs: model.selectedDefs,
+ selectedOutputs: model.selectedOutputs
+ });
+ if (slices && cellPersistentId) {
+ // Only show output if the selection was output.
+ let includeOutput = model.selectedOutputs.length >= 1;
+ let historyModel = buildHistoryModel(
+ model, cellPersistentId, slices, includeOutput);
+ let historyViewer = new HistoryViewer({
+ model: historyModel,
+ outputRenderer: this._outputRenderer
+ });
+ (this.layout as PanelLayout).addWidget(historyViewer);
+ }
+ }
+
+ /**
+ * Dismiss this widget.
+ */
+ dismiss() {
+ log("Dismissing revision browser");
+ this._gatherModel.requestStateChange(GatherState.SELECTING);
+ }
+
+ private _gatherModel: GatherModel;
+ private _outputRenderer: OutputRenderer;
+}
\ No newline at end of file