AppContainer.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import { Container } from 'unstated';
  2. import GrowiRenderer, { generatePreviewRenderer } from '~/services/renderer/growi-renderer';
  3. import { i18nFactory } from '../util/i18n';
  4. /**
  5. * Service container related to options for Application
  6. * @extends {Container} unstated Container
  7. */
  8. export default class AppContainer extends Container {
  9. constructor() {
  10. super();
  11. this.config = JSON.parse(document.getElementById('growi-context-hydrate').textContent || '{}');
  12. // init i18n
  13. const currentUserElem = document.getElementById('growi-current-user');
  14. let userLocaleId;
  15. if (currentUserElem != null) {
  16. const currentUser = JSON.parse(currentUserElem.textContent);
  17. userLocaleId = currentUser?.lang;
  18. }
  19. this.i18n = i18nFactory(userLocaleId);
  20. this.containerInstances = {};
  21. this.componentInstances = {};
  22. }
  23. /**
  24. * Workaround for the mangling in production build to break constructor.name
  25. */
  26. static getClassName() {
  27. return 'AppContainer';
  28. }
  29. initApp() {
  30. this.injectToWindow();
  31. }
  32. initContents() {
  33. const body = document.querySelector('body');
  34. this.isDocSaved = true;
  35. const isPluginEnabled = body.dataset.pluginEnabled === 'true';
  36. if (isPluginEnabled) {
  37. this.initPlugins();
  38. }
  39. this.injectToWindow();
  40. }
  41. initPlugins() {
  42. const growiPlugin = window.growiPlugin;
  43. growiPlugin.installAll(this);
  44. }
  45. injectToWindow() {
  46. window.appContainer = this;
  47. const growiRenderer = new GrowiRenderer(this.getConfig());
  48. growiRenderer.init();
  49. window.growiRenderer = growiRenderer;
  50. // backward compatibility
  51. window.crowi = this;
  52. window.crowiRenderer = window.growiRenderer;
  53. window.crowiPlugin = window.growiPlugin;
  54. }
  55. getConfig() {
  56. return this.config;
  57. }
  58. /**
  59. * Register unstated container instance
  60. * @param {object} instance unstated container instance
  61. */
  62. registerContainer(instance) {
  63. if (instance == null) {
  64. throw new Error('The specified instance must not be null');
  65. }
  66. const className = instance.constructor.getClassName();
  67. if (this.containerInstances[className] != null) {
  68. throw new Error('The specified instance couldn\'t register because the same type object has already been registered');
  69. }
  70. this.containerInstances[className] = instance;
  71. }
  72. /**
  73. * Get registered unstated container instance
  74. * !! THIS METHOD SHOULD ONLY BE USED FROM unstated CONTAINERS !!
  75. * !! From component instances, inject containers with `import { Subscribe } from 'unstated'` !!
  76. *
  77. * @param {string} className
  78. */
  79. getContainer(className) {
  80. return this.containerInstances[className];
  81. }
  82. /**
  83. * Register React component instance
  84. * @param {string} id
  85. * @param {object} instance React component instance
  86. */
  87. registerComponentInstance(id, instance) {
  88. if (instance == null) {
  89. throw new Error('The specified instance must not be null');
  90. }
  91. this.componentInstances[id] = instance;
  92. }
  93. /**
  94. * Get registered React component instance
  95. * @param {string} id
  96. */
  97. getComponentInstance(id) {
  98. return this.componentInstances[id];
  99. }
  100. }