customize.js 3.2 KB

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