UNPKG

32.4 kBJavaScriptView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3import { PathExt } from '@jupyterlab/coreutils';
4import { nullTranslator } from '@jupyterlab/translation';
5import { fileIcon, folderIcon, imageIcon, jsonIcon, juliaIcon, markdownIcon, notebookIcon, pdfIcon, pythonIcon, rKernelIcon, spreadsheetIcon, yamlIcon } from '@jupyterlab/ui-components';
6import { ArrayExt, find } from '@lumino/algorithm';
7import { DisposableDelegate } from '@lumino/disposable';
8import { Signal } from '@lumino/signaling';
9import { TextModelFactory } from './default';
10/**
11 * The document registry.
12 */
13export class DocumentRegistry {
14 /**
15 * Construct a new document registry.
16 */
17 constructor(options = {}) {
18 this._modelFactories = Object.create(null);
19 this._widgetFactories = Object.create(null);
20 this._defaultWidgetFactory = '';
21 this._defaultWidgetFactoryOverrides = Object.create(null);
22 this._defaultWidgetFactories = Object.create(null);
23 this._defaultRenderedWidgetFactories = Object.create(null);
24 this._widgetFactoriesForFileType = Object.create(null);
25 this._fileTypes = [];
26 this._extenders = Object.create(null);
27 this._changed = new Signal(this);
28 this._isDisposed = false;
29 const factory = options.textModelFactory;
30 this.translator = options.translator || nullTranslator;
31 if (factory && factory.name !== 'text') {
32 throw new Error('Text model factory must have the name `text`');
33 }
34 this._modelFactories['text'] = factory || new TextModelFactory(true);
35 const fts = options.initialFileTypes ||
36 DocumentRegistry.getDefaultFileTypes(this.translator);
37 fts.forEach(ft => {
38 const value = {
39 ...DocumentRegistry.getFileTypeDefaults(this.translator),
40 ...ft
41 };
42 this._fileTypes.push(value);
43 });
44 }
45 /**
46 * A signal emitted when the registry has changed.
47 */
48 get changed() {
49 return this._changed;
50 }
51 /**
52 * Get whether the document registry has been disposed.
53 */
54 get isDisposed() {
55 return this._isDisposed;
56 }
57 /**
58 * Dispose of the resources held by the document registry.
59 */
60 dispose() {
61 if (this.isDisposed) {
62 return;
63 }
64 this._isDisposed = true;
65 for (const modelName in this._modelFactories) {
66 this._modelFactories[modelName].dispose();
67 }
68 for (const widgetName in this._widgetFactories) {
69 this._widgetFactories[widgetName].dispose();
70 }
71 for (const widgetName in this._extenders) {
72 this._extenders[widgetName].length = 0;
73 }
74 this._fileTypes.length = 0;
75 Signal.clearData(this);
76 }
77 /**
78 * Add a widget factory to the registry.
79 *
80 * @param factory - The factory instance to register.
81 *
82 * @returns A disposable which will unregister the factory.
83 *
84 * #### Notes
85 * If a factory with the given `'name'` is already registered,
86 * a warning will be logged, and this will be a no-op.
87 * If `'*'` is given as a default extension, the factory will be registered
88 * as the global default.
89 * If an extension or global default is already registered, this factory
90 * will override the existing default.
91 * The factory cannot be named an empty string or the string `'default'`.
92 */
93 addWidgetFactory(factory) {
94 const name = factory.name.toLowerCase();
95 if (!name || name === 'default') {
96 throw Error('Invalid factory name');
97 }
98 if (this._widgetFactories[name]) {
99 console.warn(`Duplicate registered factory ${name}`);
100 return new DisposableDelegate(Private.noOp);
101 }
102 this._widgetFactories[name] = factory;
103 for (const ft of factory.defaultFor || []) {
104 if (factory.fileTypes.indexOf(ft) === -1) {
105 continue;
106 }
107 if (ft === '*') {
108 this._defaultWidgetFactory = name;
109 }
110 else {
111 this._defaultWidgetFactories[ft] = name;
112 }
113 }
114 for (const ft of factory.defaultRendered || []) {
115 if (factory.fileTypes.indexOf(ft) === -1) {
116 continue;
117 }
118 this._defaultRenderedWidgetFactories[ft] = name;
119 }
120 // For convenience, store a mapping of file type name -> name
121 for (const ft of factory.fileTypes) {
122 if (!this._widgetFactoriesForFileType[ft]) {
123 this._widgetFactoriesForFileType[ft] = [];
124 }
125 this._widgetFactoriesForFileType[ft].push(name);
126 }
127 this._changed.emit({
128 type: 'widgetFactory',
129 name,
130 change: 'added'
131 });
132 return new DisposableDelegate(() => {
133 delete this._widgetFactories[name];
134 if (this._defaultWidgetFactory === name) {
135 this._defaultWidgetFactory = '';
136 }
137 for (const ext of Object.keys(this._defaultWidgetFactories)) {
138 if (this._defaultWidgetFactories[ext] === name) {
139 delete this._defaultWidgetFactories[ext];
140 }
141 }
142 for (const ext of Object.keys(this._defaultRenderedWidgetFactories)) {
143 if (this._defaultRenderedWidgetFactories[ext] === name) {
144 delete this._defaultRenderedWidgetFactories[ext];
145 }
146 }
147 for (const ext of Object.keys(this._widgetFactoriesForFileType)) {
148 ArrayExt.removeFirstOf(this._widgetFactoriesForFileType[ext], name);
149 if (this._widgetFactoriesForFileType[ext].length === 0) {
150 delete this._widgetFactoriesForFileType[ext];
151 }
152 }
153 for (const ext of Object.keys(this._defaultWidgetFactoryOverrides)) {
154 if (this._defaultWidgetFactoryOverrides[ext] === name) {
155 delete this._defaultWidgetFactoryOverrides[ext];
156 }
157 }
158 this._changed.emit({
159 type: 'widgetFactory',
160 name,
161 change: 'removed'
162 });
163 });
164 }
165 /**
166 * Add a model factory to the registry.
167 *
168 * @param factory - The factory instance.
169 *
170 * @returns A disposable which will unregister the factory.
171 *
172 * #### Notes
173 * If a factory with the given `name` is already registered, or
174 * the given factory is already registered, a warning will be logged
175 * and this will be a no-op.
176 */
177 addModelFactory(factory) {
178 const name = factory.name.toLowerCase();
179 if (this._modelFactories[name]) {
180 console.warn(`Duplicate registered factory ${name}`);
181 return new DisposableDelegate(Private.noOp);
182 }
183 this._modelFactories[name] = factory;
184 this._changed.emit({
185 type: 'modelFactory',
186 name,
187 change: 'added'
188 });
189 return new DisposableDelegate(() => {
190 delete this._modelFactories[name];
191 this._changed.emit({
192 type: 'modelFactory',
193 name,
194 change: 'removed'
195 });
196 });
197 }
198 /**
199 * Add a widget extension to the registry.
200 *
201 * @param widgetName - The name of the widget factory.
202 *
203 * @param extension - A widget extension.
204 *
205 * @returns A disposable which will unregister the extension.
206 *
207 * #### Notes
208 * If the extension is already registered for the given
209 * widget name, a warning will be logged and this will be a no-op.
210 */
211 addWidgetExtension(widgetName, extension) {
212 widgetName = widgetName.toLowerCase();
213 if (!(widgetName in this._extenders)) {
214 this._extenders[widgetName] = [];
215 }
216 const extenders = this._extenders[widgetName];
217 const index = ArrayExt.firstIndexOf(extenders, extension);
218 if (index !== -1) {
219 console.warn(`Duplicate registered extension for ${widgetName}`);
220 return new DisposableDelegate(Private.noOp);
221 }
222 this._extenders[widgetName].push(extension);
223 this._changed.emit({
224 type: 'widgetExtension',
225 name: widgetName,
226 change: 'added'
227 });
228 return new DisposableDelegate(() => {
229 ArrayExt.removeFirstOf(this._extenders[widgetName], extension);
230 this._changed.emit({
231 type: 'widgetExtension',
232 name: widgetName,
233 change: 'removed'
234 });
235 });
236 }
237 /**
238 * Add a file type to the document registry.
239 *
240 * @param fileType - The file type object to register.
241 * @param factories - Optional factories to use for the file type.
242 *
243 * @returns A disposable which will unregister the command.
244 *
245 * #### Notes
246 * These are used to populate the "Create New" dialog.
247 *
248 * If no default factory exists for the file type, the first factory will
249 * be defined as default factory.
250 */
251 addFileType(fileType, factories) {
252 const value = {
253 ...DocumentRegistry.getFileTypeDefaults(this.translator),
254 ...fileType,
255 // fall back to fileIcon if needed
256 ...(!(fileType.icon || fileType.iconClass) && { icon: fileIcon })
257 };
258 this._fileTypes.push(value);
259 // Add the filetype to the factory - filetype mapping
260 // We do not change the factory itself
261 if (factories) {
262 const fileTypeName = value.name.toLowerCase();
263 factories
264 .map(factory => factory.toLowerCase())
265 .forEach(factory => {
266 if (!this._widgetFactoriesForFileType[fileTypeName]) {
267 this._widgetFactoriesForFileType[fileTypeName] = [];
268 }
269 if (!this._widgetFactoriesForFileType[fileTypeName].includes(factory)) {
270 this._widgetFactoriesForFileType[fileTypeName].push(factory);
271 }
272 });
273 if (!this._defaultWidgetFactories[fileTypeName]) {
274 this._defaultWidgetFactories[fileTypeName] =
275 this._widgetFactoriesForFileType[fileTypeName][0];
276 }
277 }
278 this._changed.emit({
279 type: 'fileType',
280 name: value.name,
281 change: 'added'
282 });
283 return new DisposableDelegate(() => {
284 ArrayExt.removeFirstOf(this._fileTypes, value);
285 if (factories) {
286 const fileTypeName = value.name.toLowerCase();
287 for (const name of factories.map(factory => factory.toLowerCase())) {
288 ArrayExt.removeFirstOf(this._widgetFactoriesForFileType[fileTypeName], name);
289 }
290 if (this._defaultWidgetFactories[fileTypeName] ===
291 factories[0].toLowerCase()) {
292 delete this._defaultWidgetFactories[fileTypeName];
293 }
294 }
295 this._changed.emit({
296 type: 'fileType',
297 name: fileType.name,
298 change: 'removed'
299 });
300 });
301 }
302 /**
303 * Get a list of the preferred widget factories.
304 *
305 * @param path - The file path to filter the results.
306 *
307 * @returns A new array of widget factories.
308 *
309 * #### Notes
310 * Only the widget factories whose associated model factory have
311 * been registered will be returned.
312 * The first item is considered the default. The returned array
313 * has widget factories in the following order:
314 * - path-specific default factory
315 * - path-specific default rendered factory
316 * - global default factory
317 * - all other path-specific factories
318 * - all other global factories
319 */
320 preferredWidgetFactories(path) {
321 const factories = new Set();
322 // Get the ordered matching file types.
323 const fts = this.getFileTypesForPath(PathExt.basename(path));
324 // Start with any user overrides for the defaults.
325 fts.forEach(ft => {
326 if (ft.name in this._defaultWidgetFactoryOverrides) {
327 factories.add(this._defaultWidgetFactoryOverrides[ft.name]);
328 }
329 });
330 // Next add the file type default factories.
331 fts.forEach(ft => {
332 if (ft.name in this._defaultWidgetFactories) {
333 factories.add(this._defaultWidgetFactories[ft.name]);
334 }
335 });
336 // Add the file type default rendered factories.
337 fts.forEach(ft => {
338 if (ft.name in this._defaultRenderedWidgetFactories) {
339 factories.add(this._defaultRenderedWidgetFactories[ft.name]);
340 }
341 });
342 // Add the global default factory.
343 if (this._defaultWidgetFactory) {
344 factories.add(this._defaultWidgetFactory);
345 }
346 // Add the file type factories in registration order.
347 for (const ft of fts) {
348 if (ft.name in this._widgetFactoriesForFileType) {
349 for (const n of this._widgetFactoriesForFileType[ft.name]) {
350 factories.add(n);
351 }
352 }
353 }
354 // Add the rest of the global factories, in registration order.
355 if ('*' in this._widgetFactoriesForFileType) {
356 for (const n of this._widgetFactoriesForFileType['*']) {
357 factories.add(n);
358 }
359 }
360 // Construct the return list, checking to make sure the corresponding
361 // model factories are registered.
362 const factoryList = [];
363 for (const name of factories) {
364 const factory = this._widgetFactories[name];
365 if (!factory) {
366 continue;
367 }
368 const modelName = factory.modelName || 'text';
369 if (modelName in this._modelFactories) {
370 factoryList.push(factory);
371 }
372 }
373 return factoryList;
374 }
375 /**
376 * Get the default rendered widget factory for a path.
377 *
378 * @param path - The path to for which to find a widget factory.
379 *
380 * @returns The default rendered widget factory for the path.
381 *
382 * ### Notes
383 * If the widget factory has registered a separate set of `defaultRendered`
384 * file types and there is a match in that set, this returns that.
385 * Otherwise, this returns the same widget factory as
386 * [[defaultWidgetFactory]].
387 *
388 * The user setting `defaultViewers` took precedence on this one too.
389 */
390 defaultRenderedWidgetFactory(path) {
391 // Get the matching file types.
392 const ftNames = this.getFileTypesForPath(PathExt.basename(path)).map(ft => ft.name);
393 // Start with any user overrides for the defaults.
394 for (const name in ftNames) {
395 if (name in this._defaultWidgetFactoryOverrides) {
396 return this._widgetFactories[this._defaultWidgetFactoryOverrides[name]];
397 }
398 }
399 // Find if a there is a default rendered factory for this type.
400 for (const name in ftNames) {
401 if (name in this._defaultRenderedWidgetFactories) {
402 return this._widgetFactories[this._defaultRenderedWidgetFactories[name]];
403 }
404 }
405 // Fallback to the default widget factory
406 return this.defaultWidgetFactory(path);
407 }
408 /**
409 * Get the default widget factory for a path.
410 *
411 * @param path - An optional file path to filter the results.
412 *
413 * @returns The default widget factory for an path.
414 *
415 * #### Notes
416 * This is equivalent to the first value in [[preferredWidgetFactories]].
417 */
418 defaultWidgetFactory(path) {
419 if (!path) {
420 return this._widgetFactories[this._defaultWidgetFactory];
421 }
422 return this.preferredWidgetFactories(path)[0];
423 }
424 /**
425 * Set overrides for the default widget factory for a file type.
426 *
427 * Normally, a widget factory informs the document registry which file types
428 * it should be the default for using the `defaultFor` option in the
429 * IWidgetFactoryOptions. This function can be used to override that after
430 * the fact.
431 *
432 * @param fileType The name of the file type.
433 *
434 * @param factory The name of the factory.
435 *
436 * #### Notes
437 * If `factory` is undefined, then any override will be unset, and the
438 * default factory will revert to the original value.
439 *
440 * If `factory` or `fileType` are not known to the docregistry, or
441 * if `factory` cannot open files of type `fileType`, this will throw
442 * an error.
443 */
444 setDefaultWidgetFactory(fileType, factory) {
445 fileType = fileType.toLowerCase();
446 if (!this.getFileType(fileType)) {
447 throw Error(`Cannot find file type ${fileType}`);
448 }
449 if (!factory) {
450 if (this._defaultWidgetFactoryOverrides[fileType]) {
451 delete this._defaultWidgetFactoryOverrides[fileType];
452 }
453 return;
454 }
455 if (!this.getWidgetFactory(factory)) {
456 throw Error(`Cannot find widget factory ${factory}`);
457 }
458 factory = factory.toLowerCase();
459 const factories = this._widgetFactoriesForFileType[fileType];
460 if (factory !== this._defaultWidgetFactory &&
461 !(factories && factories.includes(factory))) {
462 throw Error(`Factory ${factory} cannot view file type ${fileType}`);
463 }
464 this._defaultWidgetFactoryOverrides[fileType] = factory;
465 }
466 /**
467 * Create an iterator over the widget factories that have been registered.
468 *
469 * @returns A new iterator of widget factories.
470 */
471 *widgetFactories() {
472 for (const name in this._widgetFactories) {
473 yield this._widgetFactories[name];
474 }
475 }
476 /**
477 * Create an iterator over the model factories that have been registered.
478 *
479 * @returns A new iterator of model factories.
480 */
481 *modelFactories() {
482 for (const name in this._modelFactories) {
483 yield this._modelFactories[name];
484 }
485 }
486 /**
487 * Create an iterator over the registered extensions for a given widget.
488 *
489 * @param widgetName - The name of the widget factory.
490 *
491 * @returns A new iterator over the widget extensions.
492 */
493 *widgetExtensions(widgetName) {
494 widgetName = widgetName.toLowerCase();
495 if (widgetName in this._extenders) {
496 for (const extension of this._extenders[widgetName]) {
497 yield extension;
498 }
499 }
500 }
501 /**
502 * Create an iterator over the file types that have been registered.
503 *
504 * @returns A new iterator of file types.
505 */
506 *fileTypes() {
507 for (const type of this._fileTypes) {
508 yield type;
509 }
510 }
511 /**
512 * Get a widget factory by name.
513 *
514 * @param widgetName - The name of the widget factory.
515 *
516 * @returns A widget factory instance.
517 */
518 getWidgetFactory(widgetName) {
519 return this._widgetFactories[widgetName.toLowerCase()];
520 }
521 /**
522 * Get a model factory by name.
523 *
524 * @param name - The name of the model factory.
525 *
526 * @returns A model factory instance.
527 */
528 getModelFactory(name) {
529 return this._modelFactories[name.toLowerCase()];
530 }
531 /**
532 * Get a file type by name.
533 */
534 getFileType(name) {
535 name = name.toLowerCase();
536 return find(this._fileTypes, fileType => {
537 return fileType.name.toLowerCase() === name;
538 });
539 }
540 /**
541 * Get a kernel preference.
542 *
543 * @param path - The file path.
544 *
545 * @param widgetName - The name of the widget factory.
546 *
547 * @param kernel - An optional existing kernel model.
548 *
549 * @returns A kernel preference.
550 */
551 getKernelPreference(path, widgetName, kernel) {
552 widgetName = widgetName.toLowerCase();
553 const widgetFactory = this._widgetFactories[widgetName];
554 if (!widgetFactory) {
555 return void 0;
556 }
557 const modelFactory = this.getModelFactory(widgetFactory.modelName || 'text');
558 if (!modelFactory) {
559 return void 0;
560 }
561 const language = modelFactory.preferredLanguage(PathExt.basename(path));
562 const name = kernel && kernel.name;
563 const id = kernel && kernel.id;
564 return {
565 id,
566 name,
567 language,
568 shouldStart: widgetFactory.preferKernel,
569 canStart: widgetFactory.canStartKernel,
570 shutdownOnDispose: widgetFactory.shutdownOnClose,
571 autoStartDefault: widgetFactory.autoStartDefault
572 };
573 }
574 /**
575 * Get the best file type given a contents model.
576 *
577 * @param model - The contents model of interest.
578 *
579 * @returns The best matching file type.
580 */
581 getFileTypeForModel(model) {
582 let ft = null;
583 if (model.name || model.path) {
584 const name = model.name || PathExt.basename(model.path);
585 const fts = this.getFileTypesForPath(name);
586 if (fts.length > 0) {
587 ft = fts[0];
588 }
589 }
590 switch (model.type) {
591 case 'directory':
592 if (ft !== null && ft.contentType === 'directory') {
593 return ft;
594 }
595 return (find(this._fileTypes, ft => ft.contentType === 'directory') ||
596 DocumentRegistry.getDefaultDirectoryFileType(this.translator));
597 case 'notebook':
598 if (ft !== null && ft.contentType === 'notebook') {
599 return ft;
600 }
601 return (find(this._fileTypes, ft => ft.contentType === 'notebook') ||
602 DocumentRegistry.getDefaultNotebookFileType(this.translator));
603 default:
604 // Find the best matching extension.
605 if (ft !== null) {
606 return ft;
607 }
608 return (this.getFileType('text') ||
609 DocumentRegistry.getDefaultTextFileType(this.translator));
610 }
611 }
612 /**
613 * Get the file types that match a file name.
614 *
615 * @param path - The path of the file.
616 *
617 * @returns An ordered list of matching file types.
618 */
619 getFileTypesForPath(path) {
620 const fts = [];
621 const name = PathExt.basename(path);
622 // Look for a pattern match first.
623 let ft = find(this._fileTypes, ft => {
624 return !!(ft.pattern && name.match(ft.pattern) !== null);
625 });
626 if (ft) {
627 fts.push(ft);
628 }
629 // Then look by extension name, starting with the longest
630 let ext = Private.extname(name);
631 while (ext.length > 1) {
632 const ftSubset = this._fileTypes.filter(ft =>
633 // In Private.extname, the extension is transformed to lower case
634 ft.extensions.map(extension => extension.toLowerCase()).includes(ext));
635 fts.push(...ftSubset);
636 ext = '.' + ext.split('.').slice(2).join('.');
637 }
638 return fts;
639 }
640}
641/**
642 * The namespace for the `DocumentRegistry` class statics.
643 */
644(function (DocumentRegistry) {
645 /**
646 * The defaults used for a file type.
647 *
648 * @param translator - The application language translator.
649 *
650 * @returns The default file type.
651 */
652 function getFileTypeDefaults(translator) {
653 translator = translator || nullTranslator;
654 const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
655 return {
656 name: 'default',
657 displayName: trans.__('default'),
658 extensions: [],
659 mimeTypes: [],
660 contentType: 'file',
661 fileFormat: 'text'
662 };
663 }
664 DocumentRegistry.getFileTypeDefaults = getFileTypeDefaults;
665 /**
666 * The default text file type used by the document registry.
667 *
668 * @param translator - The application language translator.
669 *
670 * @returns The default text file type.
671 */
672 function getDefaultTextFileType(translator) {
673 translator = translator || nullTranslator;
674 const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
675 const fileTypeDefaults = getFileTypeDefaults(translator);
676 return {
677 ...fileTypeDefaults,
678 name: 'text',
679 displayName: trans.__('Text'),
680 mimeTypes: ['text/plain'],
681 extensions: ['.txt'],
682 icon: fileIcon
683 };
684 }
685 DocumentRegistry.getDefaultTextFileType = getDefaultTextFileType;
686 /**
687 * The default notebook file type used by the document registry.
688 *
689 * @param translator - The application language translator.
690 *
691 * @returns The default notebook file type.
692 */
693 function getDefaultNotebookFileType(translator) {
694 translator = translator || nullTranslator;
695 const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
696 return {
697 ...getFileTypeDefaults(translator),
698 name: 'notebook',
699 displayName: trans.__('Notebook'),
700 mimeTypes: ['application/x-ipynb+json'],
701 extensions: ['.ipynb'],
702 contentType: 'notebook',
703 fileFormat: 'json',
704 icon: notebookIcon
705 };
706 }
707 DocumentRegistry.getDefaultNotebookFileType = getDefaultNotebookFileType;
708 /**
709 * The default directory file type used by the document registry.
710 *
711 * @param translator - The application language translator.
712 *
713 * @returns The default directory file type.
714 */
715 function getDefaultDirectoryFileType(translator) {
716 translator = translator || nullTranslator;
717 const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
718 return {
719 ...getFileTypeDefaults(translator),
720 name: 'directory',
721 displayName: trans.__('Directory'),
722 extensions: [],
723 mimeTypes: ['text/directory'],
724 contentType: 'directory',
725 icon: folderIcon
726 };
727 }
728 DocumentRegistry.getDefaultDirectoryFileType = getDefaultDirectoryFileType;
729 /**
730 * The default file types used by the document registry.
731 *
732 * @param translator - The application language translator.
733 *
734 * @returns The default directory file types.
735 */
736 function getDefaultFileTypes(translator) {
737 translator = translator || nullTranslator;
738 const trans = translator === null || translator === void 0 ? void 0 : translator.load('jupyterlab');
739 return [
740 getDefaultTextFileType(translator),
741 getDefaultNotebookFileType(translator),
742 getDefaultDirectoryFileType(translator),
743 {
744 name: 'markdown',
745 displayName: trans.__('Markdown File'),
746 extensions: ['.md'],
747 mimeTypes: ['text/markdown'],
748 icon: markdownIcon
749 },
750 {
751 name: 'PDF',
752 displayName: trans.__('PDF File'),
753 extensions: ['.pdf'],
754 mimeTypes: ['application/pdf'],
755 icon: pdfIcon
756 },
757 {
758 name: 'python',
759 displayName: trans.__('Python File'),
760 extensions: ['.py'],
761 mimeTypes: ['text/x-python'],
762 icon: pythonIcon
763 },
764 {
765 name: 'json',
766 displayName: trans.__('JSON File'),
767 extensions: ['.json'],
768 mimeTypes: ['application/json'],
769 icon: jsonIcon
770 },
771 {
772 name: 'jsonl',
773 displayName: trans.__('JSONLines File'),
774 extensions: ['.jsonl', '.ndjson'],
775 mimeTypes: [
776 'text/jsonl',
777 'application/jsonl',
778 'application/json-lines'
779 ],
780 icon: jsonIcon
781 },
782 {
783 name: 'julia',
784 displayName: trans.__('Julia File'),
785 extensions: ['.jl'],
786 mimeTypes: ['text/x-julia'],
787 icon: juliaIcon
788 },
789 {
790 name: 'csv',
791 displayName: trans.__('CSV File'),
792 extensions: ['.csv'],
793 mimeTypes: ['text/csv'],
794 icon: spreadsheetIcon
795 },
796 {
797 name: 'tsv',
798 displayName: trans.__('TSV File'),
799 extensions: ['.tsv'],
800 mimeTypes: ['text/csv'],
801 icon: spreadsheetIcon
802 },
803 {
804 name: 'r',
805 displayName: trans.__('R File'),
806 mimeTypes: ['text/x-rsrc'],
807 extensions: ['.R'],
808 icon: rKernelIcon
809 },
810 {
811 name: 'yaml',
812 displayName: trans.__('YAML File'),
813 mimeTypes: ['text/x-yaml', 'text/yaml'],
814 extensions: ['.yaml', '.yml'],
815 icon: yamlIcon
816 },
817 {
818 name: 'svg',
819 displayName: trans.__('Image'),
820 mimeTypes: ['image/svg+xml'],
821 extensions: ['.svg'],
822 icon: imageIcon,
823 fileFormat: 'base64'
824 },
825 {
826 name: 'tiff',
827 displayName: trans.__('Image'),
828 mimeTypes: ['image/tiff'],
829 extensions: ['.tif', '.tiff'],
830 icon: imageIcon,
831 fileFormat: 'base64'
832 },
833 {
834 name: 'jpeg',
835 displayName: trans.__('Image'),
836 mimeTypes: ['image/jpeg'],
837 extensions: ['.jpg', '.jpeg'],
838 icon: imageIcon,
839 fileFormat: 'base64'
840 },
841 {
842 name: 'gif',
843 displayName: trans.__('Image'),
844 mimeTypes: ['image/gif'],
845 extensions: ['.gif'],
846 icon: imageIcon,
847 fileFormat: 'base64'
848 },
849 {
850 name: 'png',
851 displayName: trans.__('Image'),
852 mimeTypes: ['image/png'],
853 extensions: ['.png'],
854 icon: imageIcon,
855 fileFormat: 'base64'
856 },
857 {
858 name: 'bmp',
859 displayName: trans.__('Image'),
860 mimeTypes: ['image/bmp'],
861 extensions: ['.bmp'],
862 icon: imageIcon,
863 fileFormat: 'base64'
864 },
865 {
866 name: 'webp',
867 displayName: trans.__('Image'),
868 mimeTypes: ['image/webp'],
869 extensions: ['.webp'],
870 icon: imageIcon,
871 fileFormat: 'base64'
872 }
873 ];
874 }
875 DocumentRegistry.getDefaultFileTypes = getDefaultFileTypes;
876})(DocumentRegistry || (DocumentRegistry = {}));
877/**
878 * A private namespace for DocumentRegistry data.
879 */
880var Private;
881(function (Private) {
882 /**
883 * Get the extension name of a path.
884 *
885 * @param path - string.
886 *
887 * #### Notes
888 * Dotted filenames (e.g. `".table.json"` are allowed).
889 */
890 function extname(path) {
891 const parts = PathExt.basename(path).split('.');
892 parts.shift();
893 const ext = '.' + parts.join('.');
894 return ext.toLowerCase();
895 }
896 Private.extname = extname;
897 /**
898 * A no-op function.
899 */
900 function noOp() {
901 /* no-op */
902 }
903 Private.noOp = noOp;
904})(Private || (Private = {}));
905//# sourceMappingURL=registry.js.map
\No newline at end of file