crowi.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /* eslint-disable react/jsx-filename-extension */
  2. require('jquery.cookie');
  3. require('./thirdparty-js/waves');
  4. const Crowi = {};
  5. if (!window) {
  6. window = {};
  7. }
  8. window.Crowi = Crowi;
  9. /**
  10. * set 'data-caret-line' attribute that will be processed when 'shown.bs.tab' event fired
  11. * @param {number} line
  12. */
  13. Crowi.setCaretLineData = function(line) {
  14. const { appContainer } = window;
  15. const navigationContainer = appContainer.getContainer('NavigationContainer');
  16. // navigationContainer.setEditorMode('edit');
  17. const pageEditorDom = document.querySelector('#page-editor');
  18. pageEditorDom.setAttribute('data-caret-line', line);
  19. };
  20. /**
  21. * invoked when;
  22. *
  23. * 1. 'shown.bs.tab' event fired
  24. */
  25. Crowi.setCaretLineAndFocusToEditor = function() {
  26. // get 'data-caret-line' attributes
  27. const pageEditorDom = document.querySelector('#page-editor');
  28. if (pageEditorDom == null) {
  29. return;
  30. }
  31. const { appContainer } = window;
  32. const editorContainer = appContainer.getContainer('EditorContainer');
  33. const line = pageEditorDom.getAttribute('data-caret-line') || 0;
  34. editorContainer.setCaretLine(+line);
  35. // reset data-caret-line attribute
  36. pageEditorDom.removeAttribute('data-caret-line');
  37. // focus
  38. editorContainer.focusToEditor();
  39. };
  40. // original: middleware.swigFilter
  41. Crowi.userPicture = function(user) {
  42. if (!user) {
  43. return '/images/icons/user.svg';
  44. }
  45. return user.image || '/images/icons/user.svg';
  46. };
  47. Crowi.modifyScrollTop = function() {
  48. const offset = 10;
  49. const hash = window.location.hash;
  50. if (hash === '') {
  51. return;
  52. }
  53. const pageHeader = document.querySelector('#page-header');
  54. if (!pageHeader) {
  55. return;
  56. }
  57. const pageHeaderRect = pageHeader.getBoundingClientRect();
  58. const sectionHeader = Crowi.findSectionHeader(hash);
  59. if (sectionHeader === null) {
  60. return;
  61. }
  62. let timeout = 0;
  63. if (window.scrollY === 0) {
  64. timeout = 200;
  65. }
  66. setTimeout(() => {
  67. const sectionHeaderRect = sectionHeader.getBoundingClientRect();
  68. if (sectionHeaderRect.top >= pageHeaderRect.bottom) {
  69. return;
  70. }
  71. window.scrollTo(0, (window.scrollY - pageHeaderRect.height - offset));
  72. }, timeout);
  73. };
  74. Crowi.initClassesByOS = function() {
  75. // add classes to cmd-key by OS
  76. const platform = navigator.platform.toLowerCase();
  77. const isMac = (platform.indexOf('mac') > -1);
  78. document.querySelectorAll('.system-version .cmd-key').forEach((element) => {
  79. if (isMac) {
  80. element.classList.add('mac');
  81. }
  82. else {
  83. element.classList.add('win');
  84. }
  85. });
  86. document.querySelectorAll('#shortcuts-modal .cmd-key').forEach((element) => {
  87. if (isMac) {
  88. element.classList.add('mac');
  89. }
  90. else {
  91. element.classList.add('win', 'key-longer');
  92. }
  93. });
  94. };
  95. Crowi.findHashFromUrl = function(url) {
  96. let match;
  97. /* eslint-disable no-cond-assign */
  98. if (match = url.match(/#(.+)$/)) {
  99. return `#${match[1]}`;
  100. }
  101. /* eslint-enable no-cond-assign */
  102. return '';
  103. };
  104. Crowi.findSectionHeader = function(hash) {
  105. if (hash.length === 0) {
  106. return;
  107. }
  108. // omit '#'
  109. const id = hash.replace('#', '');
  110. // don't use jQuery and document.querySelector
  111. // because hash may containe Base64 encoded strings
  112. const elem = document.getElementById(id);
  113. if (elem != null && elem.tagName.match(/h\d+/i)) { // match h1, h2, h3...
  114. return elem;
  115. }
  116. return null;
  117. };
  118. Crowi.unblinkSelectedSection = function(hash) {
  119. const elem = Crowi.findSectionHeader(hash);
  120. if (elem != null) {
  121. elem.classList.remove('blink');
  122. }
  123. };
  124. Crowi.blinkSelectedSection = function(hash) {
  125. const elem = Crowi.findSectionHeader(hash);
  126. if (elem != null) {
  127. elem.classList.add('blink');
  128. }
  129. };
  130. // window.addEventListener('load', () => {
  131. // const { appContainer } = window;
  132. // const pageContainer = appContainer.getContainer('PageContainer');
  133. // // Do nothing if the page does not exist
  134. // // ex.) admin page,login page
  135. // if (pageContainer == null) {
  136. // return null;
  137. // }
  138. // const { isAbleToOpenPageEditor } = pageContainer;
  139. // // hash on page
  140. // if (window.location.hash) {
  141. // const navigationContainer = appContainer.getContainer('NavigationContainer');
  142. // if (window.location.hash === '#edit' && isAbleToOpenPageEditor) {
  143. // navigationContainer.setEditorMode('edit');
  144. // // focus
  145. // Crowi.setCaretLineAndFocusToEditor();
  146. // }
  147. // else if (window.location.hash === '#hackmd') {
  148. // navigationContainer.setEditorMode('hackmd');
  149. // }
  150. // }
  151. // });
  152. window.addEventListener('load', () => {
  153. const crowi = window.crowi;
  154. if (crowi && crowi.users && crowi.users.length !== 0) {
  155. const totalUsers = crowi.users.length;
  156. const $listLiker = $('.page-list-liker');
  157. $listLiker.each((i, liker) => {
  158. const count = $(liker).data('count') || 0;
  159. if (count / totalUsers > 0.05) {
  160. $(liker).addClass('popular-page-high');
  161. // 5%
  162. }
  163. else if (count / totalUsers > 0.02) {
  164. $(liker).addClass('popular-page-mid');
  165. // 2%
  166. }
  167. else if (count / totalUsers > 0.005) {
  168. $(liker).addClass('popular-page-low');
  169. // 0.5%
  170. }
  171. });
  172. const $listSeer = $('.page-list-seer');
  173. $listSeer.each((i, seer) => {
  174. const count = $(seer).data('count') || 0;
  175. if (count / totalUsers > 0.10) {
  176. // 10%
  177. $(seer).addClass('popular-page-high');
  178. }
  179. else if (count / totalUsers > 0.05) {
  180. // 5%
  181. $(seer).addClass('popular-page-mid');
  182. }
  183. else if (count / totalUsers > 0.02) {
  184. // 2%
  185. $(seer).addClass('popular-page-low');
  186. }
  187. });
  188. }
  189. Crowi.blinkSelectedSection(window.location.hash);
  190. Crowi.modifyScrollTop();
  191. Crowi.initClassesByOS();
  192. });
  193. window.addEventListener('hashchange', (e) => {
  194. Crowi.unblinkSelectedSection(Crowi.findHashFromUrl(e.oldURL));
  195. Crowi.blinkSelectedSection(Crowi.findHashFromUrl(e.newURL));
  196. Crowi.modifyScrollTop();
  197. // const { appContainer } = window;
  198. // const navigationContainer = appContainer.getContainer('NavigationContainer');
  199. // hash on page
  200. if (window.location.hash) {
  201. if (window.location.hash === '#edit') {
  202. // navigationContainer.setEditorMode('edit');
  203. Crowi.setCaretLineAndFocusToEditor();
  204. }
  205. else if (window.location.hash === '#hackmd') {
  206. // navigationContainer.setEditorMode('hackmd');
  207. }
  208. }
  209. });
  210. // adjust min-height of page for print temporarily
  211. window.onbeforeprint = function() {
  212. $('#page-wrapper').css('min-height', '0px');
  213. };