UNPKG

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