123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- /*-----------------------------------------------------------------------------
- | Copyright (c) Jupyter Development Team.
- | Distributed under the terms of the Modified BSD License.
- |----------------------------------------------------------------------------*/
- import {
- DataConnector, ISchemaValidator
- } from '@jupyterlab/coreutils';
- import {
- InspectionHandler, InspectorPanel
- } from '@jupyterlab/inspector';
- import {
- RenderMimeRegistry, standardRendererFactories
- } from '@jupyterlab/rendermime';
- import {
- ReadonlyJSONObject
- } from '@phosphor/coreutils';
- import {
- RawEditor
- } from './raweditor';
- /**
- * Create a raw editor inspector.
- */
- export
- function createInspector(editor: RawEditor, rendermime?: RenderMimeRegistry): InspectorPanel {
- const connector = new InspectorConnector(editor);
- const inspector = new InspectorPanel();
- const handler = new InspectionHandler({
- connector,
- rendermime: rendermime || new RenderMimeRegistry({
- initialFactories: standardRendererFactories
- })
- });
- inspector.add({
- className: 'jp-SettingsDebug',
- name: 'Debug',
- rank: 0,
- type: 'hints'
- });
- inspector.source = handler;
- handler.editor = editor.source;
- return inspector;
- }
- /**
- * The data connector used to populate a code inspector.
- *
- * #### Notes
- * This data connector debounces fetch requests to throttle them at no more than
- * one request per 100ms. This means that using the connector to populate
- * multiple client objects can lead to missed fetch responses.
- */
- class InspectorConnector extends DataConnector<InspectionHandler.IReply, void, InspectionHandler.IRequest> {
- constructor(editor: RawEditor) {
- super();
- this._editor = editor;
- }
- /**
- * Fetch inspection requests.
- */
- fetch(request: InspectionHandler.IRequest): Promise<InspectionHandler.IReply> {
- return new Promise<InspectionHandler.IReply>(resolve => {
- // Debounce requests at a rate of 100ms.
- const current = this._current = window.setTimeout(() => {
- if (current !== this._current) {
- return resolve(null);
- }
- const errors = this._validate(request.text);
- if (!errors) {
- return resolve(null);
- }
- resolve({ data: Private.render(errors), metadata: { } });
- }, 100);
- });
- }
- private _validate(raw: string): ISchemaValidator.IError[] | null {
- const editor = this._editor;
- const data = { composite: { }, user: { } };
- const id = editor.settings.plugin;
- const schema = editor.settings.schema;
- const validator = editor.registry.validator;
- return validator.validateData({ data, id, raw, schema }, false);
- }
- private _current = 0;
- private _editor: RawEditor;
- }
- /**
- * A namespace for private module data.
- */
- namespace Private {
- /**
- * Render validation errors as an HTML string.
- */
- export
- function render(errors: ISchemaValidator.IError[]): ReadonlyJSONObject {
- return { 'text/markdown': errors.map(renderError).join('') };
- }
- /**
- * Render an individual validation error as a markdown string.
- */
- function renderError(error: ISchemaValidator.IError): string {
- switch (error.keyword) {
- case 'additionalProperties':
- return `**\`[additional property error]\`**
- \`${error.params.additionalProperty}\` is not a valid property`;
- case 'syntax':
- return `**\`[syntax error]\`** *${error.message}*`;
- case 'type':
- return `**\`[type error]\`**
- \`${error.dataPath}\` ${error.message}`;
- default:
- return `**\`[error]\`** *${error.message}*`;
- }
- }
- }
|