1 |
|
2 |
|
3 | import { Printing, showErrorMessage } from '@jupyterlab/apputils';
|
4 | import { IEditorMimeTypeService } from '@jupyterlab/codeeditor';
|
5 | import { ActivityMonitor } from '@jupyterlab/coreutils';
|
6 | import { MimeModel } from '@jupyterlab/rendermime';
|
7 | import { nullTranslator } from '@jupyterlab/translation';
|
8 | import { JSONExt, PromiseDelegate } from '@lumino/coreutils';
|
9 | import { MessageLoop } from '@lumino/messaging';
|
10 | import { StackedLayout, Widget } from '@lumino/widgets';
|
11 | import { ABCWidgetFactory, DocumentWidget } from './default';
|
12 |
|
13 |
|
14 |
|
15 | export class MimeContent extends Widget {
|
16 | |
17 |
|
18 |
|
19 | constructor(options) {
|
20 | super();
|
21 | |
22 |
|
23 |
|
24 | this._changeCallback = (options) => {
|
25 | if (!options.data || !options.data[this.mimeType]) {
|
26 | return;
|
27 | }
|
28 | const data = options.data[this.mimeType];
|
29 | if (typeof data === 'string') {
|
30 | if (data !== this._context.model.toString()) {
|
31 | this._context.model.fromString(data);
|
32 | }
|
33 | }
|
34 | else if (data !== null &&
|
35 | data !== undefined &&
|
36 | !JSONExt.deepEqual(data, this._context.model.toJSON())) {
|
37 | this._context.model.fromJSON(data);
|
38 | }
|
39 | };
|
40 | this._fragment = '';
|
41 | this._ready = new PromiseDelegate();
|
42 | this._isRendering = false;
|
43 | this._renderRequested = false;
|
44 | this.addClass('jp-MimeDocument');
|
45 | this.translator = options.translator || nullTranslator;
|
46 | this._trans = this.translator.load('jupyterlab');
|
47 | this.mimeType = options.mimeType;
|
48 | this._dataType = options.dataType || 'string';
|
49 | this._context = options.context;
|
50 | this.renderer = options.renderer;
|
51 | const layout = (this.layout = new StackedLayout());
|
52 | layout.addWidget(this.renderer);
|
53 | this._context.ready
|
54 | .then(() => {
|
55 | return this._render();
|
56 | })
|
57 | .then(() => {
|
58 |
|
59 |
|
60 | if (this.node === document.activeElement) {
|
61 |
|
62 |
|
63 | MessageLoop.sendMessage(this.renderer, Widget.Msg.ActivateRequest);
|
64 | }
|
65 |
|
66 | this._monitor = new ActivityMonitor({
|
67 | signal: this._context.model.contentChanged,
|
68 | timeout: options.renderTimeout
|
69 | });
|
70 | this._monitor.activityStopped.connect(this.update, this);
|
71 | this._ready.resolve(undefined);
|
72 | })
|
73 | .catch(reason => {
|
74 |
|
75 | requestAnimationFrame(() => {
|
76 | this.dispose();
|
77 | });
|
78 | void showErrorMessage(this._trans.__('Renderer Failure: %1', this._context.path), reason);
|
79 | });
|
80 | }
|
81 | |
82 |
|
83 |
|
84 | [Printing.symbol]() {
|
85 | return Printing.getPrintFunction(this.renderer);
|
86 | }
|
87 | |
88 |
|
89 |
|
90 | get ready() {
|
91 | return this._ready.promise;
|
92 | }
|
93 | |
94 |
|
95 |
|
96 | setFragment(fragment) {
|
97 | this._fragment = fragment;
|
98 | this.update();
|
99 | }
|
100 | |
101 |
|
102 |
|
103 | dispose() {
|
104 | if (this.isDisposed) {
|
105 | return;
|
106 | }
|
107 | if (this._monitor) {
|
108 | this._monitor.dispose();
|
109 | }
|
110 | this._monitor = null;
|
111 | super.dispose();
|
112 | }
|
113 | |
114 |
|
115 |
|
116 | onUpdateRequest(msg) {
|
117 | if (this._context.isReady) {
|
118 | void this._render();
|
119 | this._fragment = '';
|
120 | }
|
121 | }
|
122 | |
123 |
|
124 |
|
125 | async _render() {
|
126 | if (this.isDisposed) {
|
127 | return;
|
128 | }
|
129 |
|
130 |
|
131 | if (this._isRendering) {
|
132 | this._renderRequested = true;
|
133 | return;
|
134 | }
|
135 |
|
136 | this._renderRequested = false;
|
137 | const context = this._context;
|
138 | const model = context.model;
|
139 | const data = {};
|
140 | if (this._dataType === 'string') {
|
141 | data[this.mimeType] = model.toString();
|
142 | }
|
143 | else {
|
144 | data[this.mimeType] = model.toJSON();
|
145 | }
|
146 | const mimeModel = new MimeModel({
|
147 | data,
|
148 | callback: this._changeCallback,
|
149 | metadata: { fragment: this._fragment }
|
150 | });
|
151 | try {
|
152 |
|
153 | this._isRendering = true;
|
154 | await this.renderer.renderModel(mimeModel);
|
155 | this._isRendering = false;
|
156 |
|
157 | if (this._renderRequested) {
|
158 | return this._render();
|
159 | }
|
160 | }
|
161 | catch (reason) {
|
162 |
|
163 | requestAnimationFrame(() => {
|
164 | this.dispose();
|
165 | });
|
166 | void showErrorMessage(this._trans.__('Renderer Failure: %1', context.path), reason);
|
167 | }
|
168 | }
|
169 | }
|
170 |
|
171 |
|
172 |
|
173 | export class MimeDocument extends DocumentWidget {
|
174 | setFragment(fragment) {
|
175 | this.content.setFragment(fragment);
|
176 | }
|
177 | }
|
178 |
|
179 |
|
180 |
|
181 | export class MimeDocumentFactory extends ABCWidgetFactory {
|
182 | |
183 |
|
184 |
|
185 | constructor(options) {
|
186 | super(Private.createRegistryOptions(options));
|
187 | this._rendermime = options.rendermime;
|
188 | this._renderTimeout = options.renderTimeout || 1000;
|
189 | this._dataType = options.dataType || 'string';
|
190 | this._fileType = options.primaryFileType;
|
191 | this._factory = options.factory;
|
192 | }
|
193 | |
194 |
|
195 |
|
196 | createNewWidget(context) {
|
197 | var _a, _b;
|
198 | const ft = this._fileType;
|
199 | const mimeType = (ft === null || ft === void 0 ? void 0 : ft.mimeTypes.length)
|
200 | ? ft.mimeTypes[0]
|
201 | : IEditorMimeTypeService.defaultMimeType;
|
202 | const rendermime = this._rendermime.clone({
|
203 | resolver: context.urlResolver
|
204 | });
|
205 | let renderer;
|
206 | if (this._factory && this._factory.mimeTypes.includes(mimeType)) {
|
207 | renderer = this._factory.createRenderer({
|
208 | mimeType,
|
209 | resolver: rendermime.resolver,
|
210 | sanitizer: rendermime.sanitizer,
|
211 | linkHandler: rendermime.linkHandler,
|
212 | latexTypesetter: rendermime.latexTypesetter,
|
213 | markdownParser: rendermime.markdownParser
|
214 | });
|
215 | }
|
216 | else {
|
217 | renderer = rendermime.createRenderer(mimeType);
|
218 | }
|
219 | const content = new MimeContent({
|
220 | context,
|
221 | renderer,
|
222 | mimeType,
|
223 | renderTimeout: this._renderTimeout,
|
224 | dataType: this._dataType
|
225 | });
|
226 | content.title.icon = ft === null || ft === void 0 ? void 0 : ft.icon;
|
227 | content.title.iconClass = (_a = ft === null || ft === void 0 ? void 0 : ft.iconClass) !== null && _a !== void 0 ? _a : '';
|
228 | content.title.iconLabel = (_b = ft === null || ft === void 0 ? void 0 : ft.iconLabel) !== null && _b !== void 0 ? _b : '';
|
229 | const widget = new MimeDocument({ content, context });
|
230 | return widget;
|
231 | }
|
232 | }
|
233 |
|
234 |
|
235 |
|
236 | var Private;
|
237 | (function (Private) {
|
238 | |
239 |
|
240 |
|
241 | function createRegistryOptions(options) {
|
242 | return {
|
243 | ...options,
|
244 | readOnly: true
|
245 | };
|
246 | }
|
247 | Private.createRegistryOptions = createRegistryOptions;
|
248 | })(Private || (Private = {}));
|
249 |
|
\ | No newline at end of file |