| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669 |
- /* eslint-disable react/jsx-filename-extension */
- import { pathUtils } from 'growi-commons';
- require('jquery.cookie');
- require('./thirdparty-js/waves');
- const Crowi = {};
- if (!window) {
- window = {};
- }
- window.Crowi = Crowi;
- /**
- * set 'data-caret-line' attribute that will be processed when 'shown.bs.tab' event fired
- * @param {number} line
- */
- Crowi.setCaretLineData = function(line) {
- const pageEditorDom = document.querySelector('#page-editor');
- pageEditorDom.setAttribute('data-caret-line', line);
- };
- /**
- * invoked when;
- *
- * 1. 'shown.bs.tab' event fired
- */
- Crowi.setCaretLineAndFocusToEditor = function() {
- // get 'data-caret-line' attributes
- const pageEditorDom = document.querySelector('#page-editor');
- if (pageEditorDom == null) {
- return;
- }
- const { appContainer } = window;
- const editorContainer = appContainer.getContainer('EditorContainer');
- const line = pageEditorDom.getAttribute('data-caret-line') || 0;
- editorContainer.setCaretLine(+line);
- // reset data-caret-line attribute
- pageEditorDom.removeAttribute('data-caret-line');
- // focus
- editorContainer.focusToEditor();
- };
- // original: middleware.swigFilter
- Crowi.userPicture = function(user) {
- if (!user) {
- return '/images/icons/user.svg';
- }
- return user.image || '/images/icons/user.svg';
- };
- Crowi.modifyScrollTop = function() {
- const offset = 10;
- const hash = window.location.hash;
- if (hash === '') {
- return;
- }
- const pageHeader = document.querySelector('#page-header');
- if (!pageHeader) {
- return;
- }
- const pageHeaderRect = pageHeader.getBoundingClientRect();
- const sectionHeader = Crowi.findSectionHeader(hash);
- if (sectionHeader === null) {
- return;
- }
- let timeout = 0;
- if (window.scrollY === 0) {
- timeout = 200;
- }
- setTimeout(() => {
- const sectionHeaderRect = sectionHeader.getBoundingClientRect();
- if (sectionHeaderRect.top >= pageHeaderRect.bottom) {
- return;
- }
- window.scrollTo(0, (window.scrollY - pageHeaderRect.height - offset));
- }, timeout);
- };
- Crowi.handleKeyEHandler = (event) => {
- // ignore when dom that has 'modal in' classes exists
- if (document.getElementsByClassName('modal in').length > 0) {
- return;
- }
- // show editor
- $('a[data-toggle="tab"][href="#edit"]').tab('show');
- event.preventDefault();
- };
- Crowi.handleKeyCHandler = (event) => {
- // ignore when dom that has 'modal in' classes exists
- if (document.getElementsByClassName('modal in').length > 0) {
- return;
- }
- // show modal to create a page
- $('#create-page').modal();
- event.preventDefault();
- };
- Crowi.handleKeyCtrlSlashHandler = (event) => {
- // show modal to create a page
- $('#shortcuts-modal').modal('toggle');
- event.preventDefault();
- };
- Crowi.initClassesByOS = function() {
- // add classes to cmd-key by OS
- const platform = navigator.platform.toLowerCase();
- const isMac = (platform.indexOf('mac') > -1);
- document.querySelectorAll('.system-version .cmd-key').forEach((element) => {
- if (isMac) {
- element.classList.add('mac');
- }
- else {
- element.classList.add('win');
- }
- });
- document.querySelectorAll('#shortcuts-modal .cmd-key').forEach((element) => {
- if (isMac) {
- element.classList.add('mac');
- }
- else {
- element.classList.add('win', 'key-longer');
- }
- });
- };
- Crowi.findHashFromUrl = function(url) {
- let match;
- /* eslint-disable no-cond-assign */
- if (match = url.match(/#(.+)$/)) {
- return `#${match[1]}`;
- }
- /* eslint-enable no-cond-assign */
- return '';
- };
- Crowi.findSectionHeader = function(hash) {
- if (hash.length === 0) {
- return;
- }
- // omit '#'
- const id = hash.replace('#', '');
- // don't use jQuery and document.querySelector
- // because hash may containe Base64 encoded strings
- const elem = document.getElementById(id);
- if (elem != null && elem.tagName.match(/h\d+/i)) { // match h1, h2, h3...
- return elem;
- }
- return null;
- };
- Crowi.unhighlightSelectedSection = function(hash) {
- const elem = Crowi.findSectionHeader(hash);
- if (elem != null) {
- elem.classList.remove('highlighted');
- }
- };
- Crowi.highlightSelectedSection = function(hash) {
- const elem = Crowi.findSectionHeader(hash);
- if (elem != null) {
- elem.classList.add('highlighted');
- }
- };
- $(() => {
- const appContainer = window.appContainer;
- const websocketContainer = appContainer.getContainer('WebsocketContainer');
- const config = appContainer.getConfig();
- const pageId = $('#content-main').data('page-id');
- // const revisionId = $('#content-main').data('page-revision-id');
- // const revisionCreatedAt = $('#content-main').data('page-revision-created');
- // const currentUser = $('#content-main').data('current-user');
- const isSeen = $('#content-main').data('page-is-seen');
- const pagePath = $('#content-main').data('path');
- const isSavedStatesOfTabChanges = config.isSavedStatesOfTabChanges;
- $('[data-toggle="popover"]').popover();
- $('[data-toggle="tooltip"]').tooltip();
- $('[data-tooltip-stay]').tooltip('show');
- $('#toggle-crowi-sidebar').click((e) => {
- const $body = $('body');
- if ($body.hasClass('aside-hidden')) {
- $body.removeClass('aside-hidden');
- $.cookie('aside-hidden', 0, { expires: 30, path: '/' });
- }
- else {
- $body.addClass('aside-hidden');
- $.cookie('aside-hidden', 1, { expires: 30, path: '/' });
- }
- return false;
- });
- if ($.cookie('aside-hidden') === 1) {
- $('body').addClass('aside-hidden');
- }
- $('.copy-link').on('click', function() {
- $(this).select();
- });
- // TODO GW-2355 remove this after refactoring
- $('#create-page').on('shown.bs.modal', (e) => {
- // quick hack: replace from server side rendering "date" to client side "date"
- const today = new Date();
- const month = (`0${today.getMonth() + 1}`).slice(-2);
- const day = (`0${today.getDate()}`).slice(-2);
- const dateString = `${today.getFullYear()}/${month}/${day}`;
- $('#create-page-today .page-today-suffix').text(`/${dateString}/`);
- $('#create-page-today .page-today-input2').data('prefix', `/${dateString}/`);
- // focus
- $('#create-page-today .page-today-input2').eq(0).focus();
- });
- $('#create-page-today').submit(function(e) {
- let prefix1 = $('input.page-today-input1', this).data('prefix');
- let prefix2 = $('input.page-today-input2', this).data('prefix');
- const input1 = $('input.page-today-input1', this).val();
- const input2 = $('input.page-today-input2', this).val();
- if (input1 === '') {
- prefix1 = 'メモ';
- }
- if (input2 === '') {
- prefix2 = prefix2.slice(0, -1);
- }
- window.location.href = `${prefix1 + input1 + prefix2 + input2}#edit`;
- return false;
- });
- $('#create-page-under-tree').submit(function(e) {
- let name = $('input', this).val();
- if (!name.match(/^\//)) {
- name = `/${name}`;
- }
- if (name.match(/.+\/$/)) {
- name = name.substr(0, name.length - 1);
- }
- // TODO: remove by GW-2278
- window.location.href = `${pathUtils.encodePagePath(name)}#edit`;
- return false;
- });
- // rename
- $('#renamePage').on('shown.bs.modal', (e) => {
- $('#renamePage #newPageName').focus();
- $('#renamePage .msg').hide();
- });
- $('#renamePageForm').submit(function(e) {
- // create name-value map
- const nameValueMap = {};
- $(this).serializeArray().forEach((obj) => {
- nameValueMap[obj.name] = obj.value; // nameValueMap.new_path is renamed page path
- });
- nameValueMap.socketClientId = websocketContainer.getSocketClientId();
- $.ajax({
- type: 'POST',
- url: '/_api/pages.rename',
- data: nameValueMap,
- dataType: 'json',
- })
- .done((res) => {
- // error
- if (!res.ok) {
- const linkPath = pathUtils.normalizePath(nameValueMap.new_path);
- $('#renamePage .msg').hide();
- $(`#renamePage .msg-${res.code}`).show();
- $('#renamePage #linkToNewPage').html(`
- <a href="${linkPath}">${linkPath} <i class="icon-login"></i></a>
- `);
- }
- else {
- const page = res.page;
- window.location.href = `${page.path}?renamed=${pagePath}`;
- }
- });
- return false;
- });
- // empty trash
- $('#emptyTrash').on('shown.bs.modal', (e) => {
- $('#emptyTrash .msg').hide();
- });
- $('#empty-trash-form').submit((e) => {
- // create name-value map
- const nameValueMap = {};
- $('#empty-trash-form').serializeArray().forEach((obj) => {
- nameValueMap[obj.name] = obj.value;
- });
- $.ajax({
- type: 'DELETE',
- url: '/_api/v3/pages/empty-trash',
- data: nameValueMap,
- dataType: 'json',
- }).done((res) => {
- window.location.href = '/trash';
- }).fail((jqXHR, textStatus, errorThrown) => {
- $('#emptyTrash .msg').hide();
- $('#emptyTrash .msg-unknown').show();
- });
- return false;
- });
- // delete
- $('#deletePage').on('shown.bs.modal', (e) => {
- $('#deletePage .msg').hide();
- });
- $('#delete-page-form').submit((e) => {
- // create name-value map
- const nameValueMap = {};
- $('#delete-page-form').serializeArray().forEach((obj) => {
- nameValueMap[obj.name] = obj.value;
- });
- nameValueMap.socketClientId = websocketContainer.getSocketClientId();
- $.ajax({
- type: 'POST',
- url: '/_api/pages.remove',
- data: nameValueMap,
- dataType: 'json',
- }).done((res) => {
- // error
- if (!res.ok) {
- $('#deletePage .msg').hide();
- $(`#deletePage .msg-${res.code}`).show();
- }
- else {
- const page = res.page;
- window.location.href = page.path;
- }
- });
- return false;
- });
- // Put Back
- $('#putBackPage').on('shown.bs.modal', (e) => {
- $('#putBackPage .msg').hide();
- });
- $('#revert-delete-page-form').submit((e) => {
- $.ajax({
- type: 'POST',
- url: '/_api/pages.revertRemove',
- data: $('#revert-delete-page-form').serialize(),
- dataType: 'json',
- }).done((res) => {
- // error
- if (!res.ok) {
- $('#putBackPage .msg').hide();
- $(`#putBackPage .msg-${res.code}`).show();
- }
- else {
- const page = res.page;
- window.location.href = page.path;
- }
- });
- return false;
- });
- $('#unlink-page-form').submit((e) => {
- $.ajax({
- type: 'POST',
- url: '/_api/pages.unlink',
- data: $('#unlink-page-form').serialize(),
- dataType: 'json',
- })
- .done((res) => {
- if (!res.ok) {
- $('#delete-errors').html(`<i class="fa fa-times-circle"></i> ${res.error}`);
- $('#delete-errors').addClass('alert-danger');
- }
- else {
- window.location.href = `${res.path}?unlinked=true`;
- }
- });
- return false;
- });
- $('#create-portal-button').on('click', (e) => {
- $('a[data-toggle="tab"][href="#edit"]').tab('show');
- $('body').addClass('on-edit');
- $('body').addClass('builtin-editor');
- const path = $('.content-main').data('path');
- if (path !== '/' && $('.content-main').data('page-id') === '') {
- const upperPage = path.substr(0, path.length - 1);
- $.get('/_api/pages.get', { path: upperPage }, (res) => {
- if (res.ok && res.page) {
- $('#portal-warning-modal').modal('show');
- }
- });
- }
- });
- $('#portal-form-close').on('click', (e) => {
- $('#edit').removeClass('active');
- $('body').removeClass('on-edit');
- $('body').removeClass('builtin-editor');
- window.location.hash = '#';
- });
- if (pageId) {
- // for Crowi Template LangProcessor
- $('.template-create-button', $('#revision-body')).on('click', function() {
- const path = $(this).data('path');
- const templateId = $(this).data('template');
- const template = $(`#${templateId}`).html();
- const editorContainer = appContainer.getContainer('EditorContainer');
- editorContainer.saveDraft(path, template);
- window.location.href = `${path}#edit`;
- });
- if (!isSeen) {
- $.post('/_api/pages.seen', { page_id: pageId }, (res) => {
- // ignore unless response has error
- if (res.ok && res.seenUser) {
- $('#content-main').data('page-is-seen', 1);
- }
- });
- }
- // presentation
- let presentaionInitialized = false;
- const $b = $('body');
- $(document).on('click', '.toggle-presentation', function(e) {
- const $a = $(this);
- e.preventDefault();
- $b.toggleClass('overlay-on');
- if (!presentaionInitialized) {
- presentaionInitialized = true;
- $('<iframe />').attr({
- src: $a.attr('href'),
- }).appendTo($('#presentation-container'));
- }
- }).on('click', '.fullscreen-layer', () => {
- $b.toggleClass('overlay-on');
- });
- } // end if pageId
- // tab changing handling
- $('a[href="#revision-body"]').on('show.bs.tab', () => {
- appContainer.setState({ editorMode: null });
- });
- $('a[href="#edit"]').on('show.bs.tab', () => {
- appContainer.setState({ editorMode: 'builtin' });
- $('body').addClass('on-edit');
- $('body').addClass('builtin-editor');
- });
- $('a[href="#edit"]').on('hide.bs.tab', () => {
- $('body').removeClass('on-edit');
- $('body').removeClass('builtin-editor');
- });
- $('a[href="#hackmd"]').on('show.bs.tab', () => {
- appContainer.setState({ editorMode: 'hackmd' });
- $('body').addClass('on-edit');
- $('body').addClass('hackmd');
- });
- $('a[href="#hackmd"]').on('hide.bs.tab', () => {
- $('body').removeClass('on-edit');
- $('body').removeClass('hackmd');
- });
- // hash handling
- if (isSavedStatesOfTabChanges) {
- $('a[data-toggle="tab"][href="#revision-history"]').on('show.bs.tab', () => {
- window.location.hash = '#revision-history';
- window.history.replaceState('', 'History', '#revision-history');
- });
- $('a[data-toggle="tab"][href="#edit"]').on('show.bs.tab', () => {
- window.location.hash = '#edit';
- window.history.replaceState('', 'Edit', '#edit');
- });
- $('a[data-toggle="tab"][href="#hackmd"]').on('show.bs.tab', () => {
- window.location.hash = '#hackmd';
- window.history.replaceState('', 'HackMD', '#hackmd');
- });
- $('a[data-toggle="tab"][href="#revision-body"]').on('show.bs.tab', () => {
- // couln't solve https://github.com/weseek/crowi-plus/issues/119 completely -- 2017.07.03 Yuki Takei
- window.location.hash = '#';
- window.history.replaceState('', '', window.location.href);
- });
- }
- else {
- $('a[data-toggle="tab"][href="#revision-history"]').on('show.bs.tab', () => {
- window.history.replaceState('', 'History', '#revision-history');
- });
- $('a[data-toggle="tab"][href="#edit"]').on('show.bs.tab', () => {
- window.history.replaceState('', 'Edit', '#edit');
- });
- $('a[data-toggle="tab"][href="#hackmd"]').on('show.bs.tab', () => {
- window.history.replaceState('', 'HackMD', '#hackmd');
- });
- $('a[data-toggle="tab"][href="#revision-body"]').on('show.bs.tab', () => {
- window.history.replaceState('', '', window.location.href.replace(window.location.hash, ''));
- });
- // replace all href="#edit" link behaviors
- $(document).on('click', 'a[href="#edit"]', () => {
- window.location.replace('#edit');
- });
- }
- // focus to editor when 'shown.bs.tab' event fired
- $('a[href="#edit"]').on('shown.bs.tab', (e) => {
- Crowi.setCaretLineAndFocusToEditor();
- });
- });
- window.addEventListener('load', (e) => {
- const { appContainer } = window;
- // do nothing if user is guest
- if (appContainer.currentUser == null) {
- return;
- }
- // hash on page
- if (window.location.hash) {
- if ((window.location.hash === '#edit' || window.location.hash === '#edit-form') && $('.tab-pane#edit').length > 0) {
- appContainer.setState({ editorMode: 'builtin' });
- $('a[data-toggle="tab"][href="#edit"]').tab('show');
- $('body').addClass('on-edit');
- $('body').addClass('builtin-editor');
- // focus
- Crowi.setCaretLineAndFocusToEditor();
- }
- else if (window.location.hash === '#hackmd' && $('.tab-pane#hackmd').length > 0) {
- appContainer.setState({ editorMode: 'hackmd' });
- $('a[data-toggle="tab"][href="#hackmd"]').tab('show');
- $('body').addClass('on-edit');
- $('body').addClass('hackmd');
- }
- else if (window.location.hash === '#revision-history' && $('.tab-pane#revision-history').length > 0) {
- $('a[data-toggle="tab"][href="#revision-history"]').tab('show');
- }
- }
- });
- window.addEventListener('load', (e) => {
- const crowi = window.crowi;
- if (crowi && crowi.users && crowi.users.length !== 0) {
- const totalUsers = crowi.users.length;
- const $listLiker = $('.page-list-liker');
- $listLiker.each((i, liker) => {
- const count = $(liker).data('count') || 0;
- if (count / totalUsers > 0.05) {
- $(liker).addClass('popular-page-high');
- // 5%
- }
- else if (count / totalUsers > 0.02) {
- $(liker).addClass('popular-page-mid');
- // 2%
- }
- else if (count / totalUsers > 0.005) {
- $(liker).addClass('popular-page-low');
- // 0.5%
- }
- });
- const $listSeer = $('.page-list-seer');
- $listSeer.each((i, seer) => {
- const count = $(seer).data('count') || 0;
- if (count / totalUsers > 0.10) {
- // 10%
- $(seer).addClass('popular-page-high');
- }
- else if (count / totalUsers > 0.05) {
- // 5%
- $(seer).addClass('popular-page-mid');
- }
- else if (count / totalUsers > 0.02) {
- // 2%
- $(seer).addClass('popular-page-low');
- }
- });
- }
- Crowi.highlightSelectedSection(window.location.hash);
- Crowi.modifyScrollTop();
- Crowi.initClassesByOS();
- });
- window.addEventListener('hashchange', (e) => {
- Crowi.unhighlightSelectedSection(Crowi.findHashFromUrl(e.oldURL));
- Crowi.highlightSelectedSection(Crowi.findHashFromUrl(e.newURL));
- Crowi.modifyScrollTop();
- // hash on page
- if (window.location.hash) {
- if (window.location.hash === '#edit') {
- $('a[data-toggle="tab"][href="#edit"]').tab('show');
- }
- else if (window.location.hash === '#hackmd') {
- $('a[data-toggle="tab"][href="#hackmd"]').tab('show');
- }
- else if (window.location.hash === '#revision-history') {
- $('a[data-toggle="tab"][href="#revision-history"]').tab('show');
- }
- }
- else {
- $('a[data-toggle="tab"][href="#revision-body"]').tab('show');
- }
- });
- window.addEventListener('keydown', (event) => {
- const target = event.target;
- // ignore when target dom is input
- const inputPattern = /^input|textinput|textarea$/i;
- if (inputPattern.test(target.tagName) || target.isContentEditable) {
- return;
- }
- switch (event.key) {
- case 'e':
- if (!event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
- Crowi.handleKeyEHandler(event);
- }
- break;
- case 'c':
- if (!event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
- Crowi.handleKeyCHandler(event);
- }
- break;
- case '/':
- if (event.ctrlKey || event.metaKey) {
- Crowi.handleKeyCtrlSlashHandler(event);
- }
- break;
- default:
- }
- });
- // adjust min-height of page for print temporarily
- window.onbeforeprint = function() {
- $('#page-wrapper').css('min-height', '0px');
- };
|