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