customize.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // eslint-disable-next-line no-unused-vars
  2. import { DevidedPagePath } from '@growi/core';
  3. import uglifycss from 'uglifycss';
  4. import loggerFactory from '~/utils/logger';
  5. import S2sMessage from '../models/vo/s2s-message';
  6. import ConfigManager from './config-manager';
  7. import { S2sMessageHandlable } from './s2s-messaging/handlable';
  8. const logger = loggerFactory('growi:service:CustomizeService');
  9. /**
  10. * the service class of CustomizeService
  11. */
  12. class CustomizeService implements S2sMessageHandlable {
  13. configManager: ConfigManager;
  14. s2sMessagingService: any;
  15. appService: any;
  16. xssService: any;
  17. lastLoadedAt?: Date;
  18. customCss?: string;
  19. customTitleTemplate!: string;
  20. constructor(crowi) {
  21. this.configManager = crowi.configManager;
  22. this.s2sMessagingService = crowi.s2sMessagingService;
  23. this.appService = crowi.appService;
  24. this.xssService = crowi.xssService;
  25. }
  26. /**
  27. * @inheritdoc
  28. */
  29. shouldHandleS2sMessage(s2sMessage) {
  30. const { eventName, updatedAt } = s2sMessage;
  31. if (eventName !== 'customizeServiceUpdated' || updatedAt == null) {
  32. return false;
  33. }
  34. return this.lastLoadedAt == null || this.lastLoadedAt < new Date(s2sMessage.updatedAt);
  35. }
  36. /**
  37. * @inheritdoc
  38. */
  39. async handleS2sMessage(s2sMessage) {
  40. const { configManager } = this;
  41. logger.info('Reset customized value by pubsub notification');
  42. await configManager.loadConfigs();
  43. this.initCustomCss();
  44. this.initCustomTitle();
  45. }
  46. async publishUpdatedMessage() {
  47. const { s2sMessagingService } = this;
  48. if (s2sMessagingService != null) {
  49. const s2sMessage = new S2sMessage('customizeServiceUpdated', { updatedAt: new Date() });
  50. try {
  51. await s2sMessagingService.publish(s2sMessage);
  52. }
  53. catch (e) {
  54. logger.error('Failed to publish update message with S2sMessagingService: ', e.message);
  55. }
  56. }
  57. }
  58. /**
  59. * initialize custom css strings
  60. */
  61. initCustomCss() {
  62. const rawCss = this.configManager.getConfig('crowi', 'customize:css') || '';
  63. // uglify and store
  64. this.customCss = uglifycss.processString(rawCss);
  65. this.lastLoadedAt = new Date();
  66. }
  67. getCustomCss() {
  68. return this.customCss;
  69. }
  70. getCustomScript() {
  71. return this.configManager.getConfig('crowi', 'customize:script');
  72. }
  73. getCustomNoscript() {
  74. return this.configManager.getConfig('crowi', 'customize:noscript');
  75. }
  76. initCustomTitle() {
  77. let configValue = this.configManager.getConfig('crowi', 'customize:title');
  78. if (configValue == null || configValue.trim().length === 0) {
  79. configValue = '{{pagename}} - {{sitename}}';
  80. }
  81. this.customTitleTemplate = configValue;
  82. this.lastLoadedAt = new Date();
  83. }
  84. generateCustomTitle(pageOrPath) {
  85. const path = pageOrPath.path || pageOrPath;
  86. const dPagePath = new DevidedPagePath(path, true, true);
  87. const customTitle = this.customTitleTemplate
  88. .replace('{{sitename}}', this.appService.getAppTitle())
  89. .replace('{{pagepath}}', path)
  90. .replace('{{page}}', dPagePath.latter) // for backward compatibility
  91. .replace('{{pagename}}', dPagePath.latter);
  92. return this.xssService.process(customTitle);
  93. }
  94. generateCustomTitleForFixedPageName(title) {
  95. // replace
  96. const customTitle = this.customTitleTemplate
  97. .replace('{{sitename}}', this.appService.getAppTitle())
  98. .replace('{{page}}', title)
  99. .replace('{{pagepath}}', title)
  100. .replace('{{pagename}}', title);
  101. return this.xssService.process(customTitle);
  102. }
  103. }
  104. module.exports = CustomizeService;