pull/1/head
Nicholas Bollweg 2020-05-18 22:54:29 -04:00
rodzic f0b6826012
commit 3674c341ff
2 zmienionych plików z 201 dodań i 61 usunięć

Wyświetl plik

@ -38,7 +38,7 @@ const DRAWIO_URL = URLExt.join(
"node_modules/jupyterlab-drawio/src/drawio/src/main/webapp/index.html"
);
const DEBUG = 1;
const DEBUG = 0;
/**
* Core URL params that are required to function properly
@ -112,6 +112,14 @@ export class DrawioWidget extends DocumentWidget<IFrame> {
await import("./_static");
}
exportAs(format: string) {
this._exportPromise = new PromiseDelegate();
this.postMessage({ action: "export", format });
return this._exportPromise.promise;
}
handleMessageEvent(evt: MessageEvent) {
const msg = JSON.parse(evt.data);
if (this._frame == null || evt.source !== this._frame.contentWindow) {
@ -139,6 +147,10 @@ export class DrawioWidget extends DocumentWidget<IFrame> {
this._lastEmitted = msg.xml;
this.context.model.fromString(msg.xml);
break;
case "export":
this._exportPromise.resolve(msg.data);
this._exportPromise = null;
break;
default:
DEBUG && console.warn("unhandled message", msg.event, msg);
break;
@ -164,13 +176,13 @@ export class DrawioWidget extends DocumentWidget<IFrame> {
this._frame.contentWindow.postMessage(JSON.stringify(msg), "*");
}
drawioTheme() {
private drawioTheme() {
return document.querySelector('body[data-jp-theme-light="true"]')
? "kennedy"
: "dark";
}
drawioUrl() {
private drawioUrl() {
const query = new URLSearchParams();
const params = {
...DEFAULT_EMBED_PARAMS,
@ -237,6 +249,7 @@ export class DrawioWidget extends DocumentWidget<IFrame> {
public revealed: Promise<void>;
readonly context: DocumentRegistry.Context;
private _ready = new PromiseDelegate<void>();
private _exportPromise: PromiseDelegate<string>;
private _frame: HTMLIFrameElement;
private _lastEmitted: string;
}

Wyświetl plik

@ -13,129 +13,256 @@
// limitations under the License.
import {
ILayoutRestorer, JupyterLab, JupyterFrontEndPlugin
} from '@jupyterlab/application';
ILayoutRestorer,
JupyterLab,
JupyterFrontEndPlugin,
} from "@jupyterlab/application";
import {
WidgetTracker, IWidgetTracker
} from '@jupyterlab/apputils';
WidgetTracker,
IWidgetTracker,
ICommandPalette,
} from "@jupyterlab/apputils";
import {
IFileBrowserFactory
} from '@jupyterlab/filebrowser';
import { IFileBrowserFactory } from "@jupyterlab/filebrowser";
import {
ILauncher
} from '@jupyterlab/launcher';
import { Contents } from "@jupyterlab/services";
import {
IMainMenu
} from '@jupyterlab/mainmenu';
import { ILauncher } from "@jupyterlab/launcher";
import {
Token
} from '@lumino/coreutils';
import { IMainMenu } from "@jupyterlab/mainmenu";
import {
DrawioWidget, DrawioFactory
} from './editor';
import { Token } from "@lumino/coreutils";
import { DrawioWidget, DrawioFactory } from "./editor";
import { PathExt } from "@jupyterlab/coreutils";
/**
* The name of the factory that creates editor widgets.
*/
const FACTORY = 'Drawio';
const FACTORY = "Drawio";
/**
* Supported formats include
* html (old embed format),
* html2 (new embed format),
* svg (default),
* xmlsvg (SVG with embeddded XML),
* png and xmlpng (PNG with embedded XML).
* The data parameter in the exportevent contains a valid data URI for the given export format.
*/
interface IExportFormat {
key: string;
ext: string;
label: string;
format: Contents.FileFormat;
mimetype: string;
transform?: (raw: string) => string;
}
const stripDataURI = (raw: string) => raw.split(",")[1];
const unbase64SVG = (raw: string) => atob(stripDataURI(raw));
const EXPORT_FORMATS: IExportFormat[] = [
{
key: "svg",
label: "SVG",
ext: ".svg",
format: "text",
mimetype: "image/svg+xml",
transform: unbase64SVG,
},
{
key: "xmlsvg",
label: "SVG (Editable)",
ext: ".svg",
format: "text",
mimetype: "image/svg+xml",
transform: unbase64SVG,
},
{
key: "html2",
label: "HTML",
ext: ".html",
format: "text",
mimetype: "text/html",
},
{
key: "png",
label: "PNG",
ext: ".png",
format: "base64",
mimetype: "image/png",
transform: stripDataURI,
},
{
key: "xmlpng",
label: "PNG (Editable)",
ext: ".png",
format: "base64",
mimetype: "image/png",
transform: stripDataURI,
},
];
interface IDrawioTracker extends IWidgetTracker<DrawioWidget> {}
export
const IDrawioTracker = new Token<IDrawioTracker>('drawio/tracki');
export const IDrawioTracker = new Token<IDrawioTracker>("drawio/tracki");
/**
* The editor tracker extension.
*/
const plugin: JupyterFrontEndPlugin<IDrawioTracker> = {
activate,
id: '@jupyterlab/drawio-extension:plugin',
requires: [IFileBrowserFactory, ILayoutRestorer, IMainMenu],
id: "@jupyterlab/drawio-extension:plugin",
requires: [IFileBrowserFactory, ILayoutRestorer, IMainMenu, ICommandPalette],
optional: [ILauncher],
provides: IDrawioTracker,
autoStart: true
autoStart: true,
};
export default plugin;
function activate(app: JupyterLab,
browserFactory: IFileBrowserFactory,
restorer: ILayoutRestorer,
menu: IMainMenu,
launcher: ILauncher | null
): IDrawioTracker {
const namespace = 'drawio';
const factory = new DrawioFactory({ name: FACTORY, fileTypes: ['dio'], defaultFor: ['dio'] });
function activate(
app: JupyterLab,
browserFactory: IFileBrowserFactory,
restorer: ILayoutRestorer,
menu: IMainMenu,
palette: ICommandPalette,
launcher: ILauncher | null
): IDrawioTracker {
const namespace = "drawio";
const factory = new DrawioFactory({
name: FACTORY,
fileTypes: ["dio"],
defaultFor: ["dio"],
});
const { commands } = app;
const tracker = new WidgetTracker<DrawioWidget>({ namespace });
/**
* Whether there is an active DrawIO editor.
*/
function isEnabled(): boolean {
return (
tracker.currentWidget !== null &&
tracker.currentWidget === app.shell.currentWidget
);
}
// Handle state restoration.
restorer.restore(tracker, {
command: 'docmanager:open',
args: widget => ({ path: widget.context.path, factory: FACTORY }),
name: widget => widget.context.path
command: "docmanager:open",
args: (widget) => ({ path: widget.context.path, factory: FACTORY }),
name: (widget) => widget.context.path,
});
factory.widgetCreated.connect((sender, widget) => {
widget.title.icon = 'jp-MaterialIcon jp-ImageIcon'; // TODO change
widget.title.icon = "jp-MaterialIcon jp-ImageIcon"; // TODO change
// Notify the instance tracker if restore data needs to update.
widget.context.pathChanged.connect(() => { tracker.save(widget); });
widget.context.pathChanged.connect(() => {
tracker.save(widget);
});
tracker.add(widget);
});
app.docRegistry.addWidgetFactory(factory);
// register the filetype
app.docRegistry.addFileType({
name: 'dio',
displayName: 'Diagram',
mimeTypes: ['application/dio'],
extensions: ['.dio'],
iconClass: 'jp-MaterialIcon jp-ImageIcon',
fileFormat: 'text'
name: "dio",
displayName: "Diagram",
mimeTypes: ["application/dio"],
extensions: [".dio"],
iconClass: "jp-MaterialIcon jp-ImageIcon",
fileFormat: "text",
});
// Function to create a new untitled diagram file, given
// the current working directory.
const createNewDIO = (cwd: string) => {
return commands.execute('docmanager:new-untitled', {
path: cwd, type: 'file', ext: '.dio'
}).then(model => {
return commands.execute('docmanager:open', {
path: model.path, factory: FACTORY
return commands
.execute("docmanager:new-untitled", {
path: cwd,
type: "file",
ext: ".dio",
})
.then((model: Contents.IModel) => {
return commands.execute("docmanager:open", {
path: model.path,
factory: FACTORY,
});
});
});
};
EXPORT_FORMATS.map((exportFormat) => {
const { ext, key, format, label, mimetype } = exportFormat;
const transform = exportFormat.transform || String;
const _exporter = async (cwd: string) => {
let model: Contents.IModel = await commands.execute(
"docmanager:new-untitled",
{
path: cwd,
type: "file",
ext,
}
);
let drawio = app.shell.currentWidget as DrawioWidget;
let stem = PathExt.basename(drawio.context.path);
model = await app.serviceManager.contents.rename(
model.path,
PathExt.join(cwd, `${stem}${ext}`)
);
const rawContent = await drawio.exportAs(key);
await app.serviceManager.contents.save(model.path, {
...model,
format,
mimetype,
content: transform(rawContent),
});
};
commands.addCommand(`drawio:export-${key}`, {
label: `Export diagram as ${label}`,
execute: () => {
let cwd = browserFactory.defaultBrowser.model.path;
return _exporter(cwd);
},
isEnabled,
});
palette.addItem({
command: `drawio:export-${key}`,
category: "Diagram Export",
});
});
// Add a command for creating a new diagram file.
commands.addCommand('drawio:create-new', {
label: 'Diagram',
iconClass: 'jp-MaterialIcon jp-ImageIcon',
caption: 'Create a new diagram file',
commands.addCommand("drawio:create-new", {
label: "Diagram",
iconClass: "jp-MaterialIcon jp-ImageIcon",
caption: "Create a new diagram file",
execute: () => {
let cwd = browserFactory.defaultBrowser.model.path;
return createNewDIO(cwd);
}
},
});
// Add a launcher item if the launcher is available.
if (launcher) {
launcher.add({
command: 'drawio:create-new',
command: "drawio:create-new",
rank: 1,
category: 'Other'
category: "Other",
});
}
if (menu) {
// Add new text file creation to the file menu.
menu.fileMenu.newMenu.addGroup([{ command: 'drawio:create-new' }], 40);
menu.fileMenu.newMenu.addGroup([{ command: "drawio:create-new" }], 40);
}
return tracker;