renderer.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import { PromiseDelegate } from '@lumino/coreutils';
  4. import { Panel } from '@lumino/widgets';
  5. /**
  6. * A renderer for widgets.
  7. */
  8. export class WidgetRenderer extends Panel {
  9. constructor(options, manager) {
  10. super();
  11. this._manager = new PromiseDelegate();
  12. this._rerenderMimeModel = null;
  13. this.mimeType = options.mimeType;
  14. if (manager) {
  15. this.manager = manager;
  16. }
  17. }
  18. /**
  19. * The widget manager.
  20. */
  21. set manager(value) {
  22. value.restored.connect(this._rerender, this);
  23. this._manager.resolve(value);
  24. }
  25. async renderModel(model) {
  26. const source = model.data[this.mimeType];
  27. // Let's be optimistic, and hope the widget state will come later.
  28. this.node.textContent = 'Loading widget...';
  29. this.addClass('jupyter-widgets');
  30. const manager = await this._manager.promise;
  31. // If there is no model id, the view was removed, so hide the node.
  32. if (source.model_id === '') {
  33. this.hide();
  34. return Promise.resolve();
  35. }
  36. let wModel;
  37. try {
  38. wModel = await manager.get_model(source.model_id);
  39. }
  40. catch (err) {
  41. if (manager.restoredStatus) {
  42. // The manager has been restored, so this error won't be going away.
  43. this.node.textContent = 'Error displaying widget: model not found';
  44. this.addClass('jupyter-widgets');
  45. console.error(err);
  46. return;
  47. }
  48. // Store the model for a possible rerender
  49. this._rerenderMimeModel = model;
  50. return;
  51. }
  52. // Successful getting the model, so we don't need to try to rerender.
  53. this._rerenderMimeModel = null;
  54. let widget;
  55. try {
  56. widget = await manager.display_model(undefined, wModel, undefined);
  57. }
  58. catch (err) {
  59. this.node.textContent = 'Error displaying widget';
  60. this.addClass('jupyter-widgets');
  61. console.error(err);
  62. return;
  63. }
  64. // Clear any previous loading message.
  65. this.node.textContent = '';
  66. this.addWidget(widget);
  67. // When the widget is disposed, hide this container and make sure we
  68. // change the output model to reflect the view was closed.
  69. widget.disposed.connect(() => {
  70. this.hide();
  71. source.model_id = '';
  72. });
  73. }
  74. /**
  75. * Get whether the manager is disposed.
  76. *
  77. * #### Notes
  78. * This is a read-only property.
  79. */
  80. get isDisposed() {
  81. return this._manager === null;
  82. }
  83. /**
  84. * Dispose the resources held by the manager.
  85. */
  86. dispose() {
  87. if (this.isDisposed) {
  88. return;
  89. }
  90. super.dispose();
  91. this._manager = null;
  92. }
  93. _rerender() {
  94. if (this._rerenderMimeModel) {
  95. // Clear the error message
  96. this.node.textContent = '';
  97. this.removeClass('jupyter-widgets');
  98. // Attempt to rerender.
  99. this.renderModel(this._rerenderMimeModel);
  100. }
  101. }
  102. }