gristlabs_grist-core/app/client/components/CodeEditorPanel.ts
Paul Fitzpatrick 1a091f1dd5 (core) another bundle of dependabot suggestions
Summary:
Version changes suggested by dependabot for security issues that
may or may not affect us (it is easier to apply the changes than
to figure out if the issues are relevant).

 * understore 1.12.1
 * ini 1.3.7, 1.3.8
 * electron 19.0.9
 * js-yaml 3.13.1, 3.14.1
 * highlight.js 10.7.3
 * file-type 16.5.4

Test Plan: existing tests pass

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3629
2022-09-12 14:20:09 -04:00

65 lines
2.4 KiB
TypeScript

import {GristDoc} from 'app/client/components/GristDoc';
import {reportError} from 'app/client/models/errors';
import {DisposableWithEvents} from 'app/common/DisposableWithEvents';
import {dom, Observable} from 'grainjs';
// Rather than require the whole of highlight.js, require just the core with the one language we
// need, to keep our bundle smaller and the build faster.
const hljs = require('highlight.js/lib/core');
hljs.registerLanguage('python', require('highlight.js/lib/languages/python'));
export class CodeEditorPanel extends DisposableWithEvents {
private _schema = Observable.create(this, '');
private _denied = Observable.create(this, false);
constructor(private _gristDoc: GristDoc) {
super();
this.listenTo(_gristDoc, 'schemaUpdateAction', this._onSchemaAction.bind(this));
this._onSchemaAction().catch(reportError); // Fetch the schema to initialize
}
public buildDom() {
// The tabIndex enables the element to gain focus, and the .clipboard class prevents the
// Clipboard module from re-grabbing it. This is a quick fix for the issue where clipboard
// interferes with text selection. TODO it should be possible for the Clipboard to never
// interfere with text selection even for un-focusable elements.
return dom('div.g-code-panel.clipboard',
{tabIndex: "-1"},
dom.maybe(this._denied, () => dom('div.g-code-panel-denied',
dom('h2', dom.text('Access denied')),
dom('div', dom.text('Code View is available only when you have full document access.')),
)),
dom.maybe(this._schema, (schema) => {
// The reason to scope and rebuild instead of using `kd.text(schema)` is because
// hljs.highlightBlock(elem) replaces `elem` with a whole new dom tree.
const elem = dom('code.g-code-viewer',
dom.text(schema),
dom.hide(true)
);
setTimeout(() => {
hljs.highlightBlock(elem);
dom.showElem(elem, true);
});
return elem;
})
);
}
private async _onSchemaAction() {
try {
const schema = await this._gristDoc.docComm.fetchTableSchema();
if (!this.isDisposed()) {
this._schema.set(schema);
this._denied.set(false);
}
} catch (err) {
if (!String(err).match(/Cannot view code/)) {
throw err;
}
if (!this.isDisposed()) {
this._schema.set('');
this._denied.set(true);
}
}
}
}