default.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import * as CodeMirror
  4. from 'codemirror';
  5. import {
  6. IContents, IKernel
  7. } from 'jupyter-js-services';
  8. import {
  9. IChangedArgs
  10. } from 'phosphor-properties';
  11. import {
  12. ISignal, Signal
  13. } from 'phosphor-signaling';
  14. import {
  15. Widget
  16. } from 'phosphor-widget';
  17. import {
  18. IDocumentModel, IWidgetFactory, IDocumentContext, IModelFactory
  19. } from './index';
  20. /**
  21. * The default implementation of a document model.
  22. */
  23. export
  24. class DocumentModel implements IDocumentModel {
  25. /**
  26. * Construct a new document model.
  27. */
  28. constructor(languagePreference?: string) {
  29. this._defaultLang = languagePreference || '';
  30. }
  31. /**
  32. * Get whether the model factory has been disposed.
  33. */
  34. get isDisposed(): boolean {
  35. return this._isDisposed;
  36. }
  37. /**
  38. * A signal emitted when the document content changes.
  39. */
  40. get contentChanged(): ISignal<IDocumentModel, void> {
  41. return Private.contentChangedSignal.bind(this);
  42. }
  43. /**
  44. * A signal emitted when the document state changes.
  45. */
  46. get stateChanged(): ISignal<IDocumentModel, IChangedArgs<any>> {
  47. return Private.stateChangedSignal.bind(this);
  48. }
  49. /**
  50. * The dirty state of the document.
  51. */
  52. get dirty(): boolean {
  53. return this._dirty;
  54. }
  55. set dirty(newValue: boolean) {
  56. if (newValue === this._dirty) {
  57. return;
  58. }
  59. let oldValue = this._dirty;
  60. this._dirty = newValue;
  61. this.stateChanged.emit({ name: 'dirty', oldValue, newValue });
  62. }
  63. /**
  64. * The read only state of the document.
  65. */
  66. get readOnly(): boolean {
  67. return this._readOnly;
  68. }
  69. set readOnly(newValue: boolean) {
  70. if (newValue === this._readOnly) {
  71. return;
  72. }
  73. let oldValue = this._readOnly;
  74. this._readOnly = newValue;
  75. this.stateChanged.emit({ name: 'readOnly', oldValue, newValue });
  76. }
  77. /**
  78. * The default kernel name of the document.
  79. *
  80. * #### Notes
  81. * This is a read-only property.
  82. */
  83. get defaultKernelName(): string {
  84. return '';
  85. }
  86. /**
  87. * The default kernel language of the document.
  88. *
  89. * #### Notes
  90. * This is a read-only property.
  91. */
  92. get defaultKernelLanguage(): string {
  93. return this._defaultLang;
  94. }
  95. /**
  96. * Dispose of the resources held by the document manager.
  97. */
  98. dispose(): void {
  99. this._isDisposed = true;
  100. }
  101. /**
  102. * Serialize the model to a string.
  103. */
  104. toString(): string {
  105. return this._text;
  106. }
  107. /**
  108. * Deserialize the model from a string.
  109. *
  110. * #### Notes
  111. * Should emit a [contentChanged] signal.
  112. */
  113. fromString(value: string): void {
  114. if (this._text === value) {
  115. return;
  116. }
  117. this._text = value;
  118. this.contentChanged.emit(void 0);
  119. this.dirty = true;
  120. }
  121. /**
  122. * Serialize the model to JSON.
  123. */
  124. toJSON(): any {
  125. return JSON.stringify(this._text);
  126. }
  127. /**
  128. * Deserialize the model from JSON.
  129. *
  130. * #### Notes
  131. * Should emit a [contentChanged] signal.
  132. */
  133. fromJSON(value: any): void {
  134. this.fromString(JSON.parse(value));
  135. }
  136. private _text = '';
  137. private _defaultLang = '';
  138. private _dirty = false;
  139. private _readOnly = false;
  140. private _isDisposed = false;
  141. }
  142. /**
  143. * An implementation of a model factory for text files.
  144. */
  145. export
  146. class TextModelFactory implements IModelFactory {
  147. /**
  148. * The name of the model type.
  149. *
  150. * #### Notes
  151. * This is a read-only property.
  152. */
  153. get name(): string {
  154. return 'text';
  155. }
  156. /**
  157. * The type of the file.
  158. *
  159. * #### Notes
  160. * This is a read-only property.
  161. */
  162. get fileType(): IContents.FileType {
  163. return 'file';
  164. }
  165. /**
  166. * The format of the file.
  167. *
  168. * This is a read-only property.
  169. */
  170. get fileFormat(): IContents.FileFormat {
  171. return 'text';
  172. }
  173. /**
  174. * Get whether the model factory has been disposed.
  175. */
  176. get isDisposed(): boolean {
  177. return this._isDisposed;
  178. }
  179. /**
  180. * Dispose of the resources held by the model factory.
  181. */
  182. dispose(): void {
  183. this._isDisposed = true;
  184. }
  185. /**
  186. * Create a new model.
  187. *
  188. * @param languagePreference - An optional kernel language preference.
  189. *
  190. * @returns A new document model.
  191. */
  192. createNew(languagePreference?: string): IDocumentModel {
  193. return new DocumentModel(languagePreference);
  194. }
  195. /**
  196. * Get the preferred kernel language given an extension.
  197. */
  198. preferredLanguage(ext: string): string {
  199. let mode = CodeMirror.findModeByExtension(ext.slice(1));
  200. if (mode) {
  201. return mode.mode;
  202. }
  203. }
  204. private _isDisposed = false;
  205. }
  206. /**
  207. * An implementation of a model factory for base64 files.
  208. */
  209. export
  210. class Base64ModelFactory extends TextModelFactory {
  211. /**
  212. * The name of the model type.
  213. *
  214. * #### Notes
  215. * This is a read-only property.
  216. */
  217. get name(): string {
  218. return 'base64';
  219. }
  220. /**
  221. * The type of the file.
  222. *
  223. * #### Notes
  224. * This is a read-only property.
  225. */
  226. get fileType(): IContents.FileType {
  227. return 'file';
  228. }
  229. /**
  230. * The format of the file.
  231. *
  232. * This is a read-only property.
  233. */
  234. get fileFormat(): IContents.FileFormat {
  235. return 'base64';
  236. }
  237. }
  238. /**
  239. * The default implemetation of a widget factory.
  240. */
  241. export
  242. abstract class ABCWidgetFactory<T extends Widget, U extends IDocumentModel> implements IWidgetFactory<T, U> {
  243. /**
  244. * A signal emitted when a widget is created.
  245. */
  246. get widgetCreated(): ISignal<IWidgetFactory<T, U>, T> {
  247. return Private.widgetCreatedSignal.bind(this);
  248. }
  249. /**
  250. * Get whether the model factory has been disposed.
  251. */
  252. get isDisposed(): boolean {
  253. return this._isDisposed;
  254. }
  255. /**
  256. * Dispose of the resources held by the document manager.
  257. */
  258. dispose(): void {
  259. this._isDisposed = true;
  260. }
  261. /**
  262. * Create a new widget given a document model and a context.
  263. *
  264. * #### Notes
  265. * It should emit the [widgetCreated] signal with the new widget.
  266. */
  267. abstract createNew(context: IDocumentContext<U>, kernel?: IKernel.IModel): T;
  268. private _isDisposed = false;
  269. }
  270. /**
  271. * A private namespace for data.
  272. */
  273. namespace Private {
  274. /**
  275. * A signal emitted when a document content changes.
  276. */
  277. export
  278. const contentChangedSignal = new Signal<IDocumentModel, void>();
  279. /**
  280. * A signal emitted when a widget is created.
  281. */
  282. export
  283. const widgetCreatedSignal = new Signal<IWidgetFactory<Widget, IDocumentModel>, Widget>();
  284. /**
  285. * A signal emitted when a document dirty state changes.
  286. */
  287. export
  288. const stateChangedSignal = new Signal<IDocumentModel, IChangedArgs<any>>();
  289. }