X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/cca3533d35c23848edff7edcbfe0327fd9d283a7..refs/pull/232/head:/resources/assets/js/global.js diff --git a/resources/assets/js/global.js b/resources/assets/js/global.js index 2cd45e5bc..9ca335ee7 100644 --- a/resources/assets/js/global.js +++ b/resources/assets/js/global.js @@ -1,33 +1,65 @@ -// Configure ZeroClipboard -window.ZeroClipboard = require('zeroclipboard'); -window.ZeroClipboard.config({ - swfPath: '/ZeroClipboard.swf' -}); +"use strict"; // AngularJS - Create application and load components var angular = require('angular'); var ngResource = require('angular-resource'); var ngAnimate = require('angular-animate'); var ngSanitize = require('angular-sanitize'); +require('angular-ui-sortable'); + +// Url retrieval function +window.baseUrl = function(path) { + let basePath = document.querySelector('meta[name="base-url"]').getAttribute('content'); + if (basePath[basePath.length-1] === '/') basePath = basePath.slice(0, basePath.length-1); + if (path[0] === '/') path = path.slice(1); + return basePath + '/' + path; +}; + +var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']); + +// Global Event System +class EventManager { + constructor() { + this.listeners = {}; + } + + emit(eventName, eventData) { + if (typeof this.listeners[eventName] === 'undefined') return this; + var eventsToStart = this.listeners[eventName]; + for (let i = 0; i < eventsToStart.length; i++) { + var event = eventsToStart[i]; + event(eventData); + } + return this; + } -var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize']); -var services = require('./services')(ngApp); -var directives = require('./directives')(ngApp); -var controllers = require('./controllers')(ngApp); + listen(eventName, callback) { + if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = []; + this.listeners[eventName].push(callback); + return this; + } +}; +window.Events = new EventManager(); + + +var services = require('./services')(ngApp, window.Events); +var directives = require('./directives')(ngApp, window.Events); +var controllers = require('./controllers')(ngApp, window.Events); //Global jQuery Config & Extensions // Smooth scrolling jQuery.fn.smoothScrollTo = function () { if (this.length === 0) return; - $('body').animate({ + let scrollElem = document.documentElement.scrollTop === 0 ? document.body : document.documentElement; + $(scrollElem).animate({ scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin }, 800); // Adjust to change animations speed (ms) return this; }; // Making contains text expression not worry about casing -$.expr[":"].contains = $.expr.createPseudo(function (arg) { +jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) { return function (elem) { return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; @@ -36,8 +68,29 @@ $.expr[":"].contains = $.expr.createPseudo(function (arg) { // Global jQuery Elements $(function () { + var notifications = $('.notification'); + var successNotification = notifications.filter('.pos'); + var errorNotification = notifications.filter('.neg'); + var warningNotification = notifications.filter('.warning'); + // Notification Events + window.Events.listen('success', function (text) { + successNotification.hide(); + successNotification.find('span').text(text); + setTimeout(() => { + successNotification.show(); + }, 1); + }); + window.Events.listen('warning', function (text) { + warningNotification.find('span').text(text); + warningNotification.show(); + }); + window.Events.listen('error', function (text) { + errorNotification.find('span').text(text); + errorNotification.show(); + }); + // Notification hiding - $('.notification').click(function () { + notifications.click(function () { $(this).fadeOut(100); }); @@ -48,15 +101,58 @@ $(function () { $(this).closest('.chapter').find('.inset-list').slideToggle(180); }); -}); + // Back to top button + $('#back-to-top').click(function() { + $('#header').smoothScrollTo(); + }); + var scrollTopShowing = false; + var scrollTop = document.getElementById('back-to-top'); + var scrollTopBreakpoint = 1200; + window.addEventListener('scroll', function() { + let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0; + if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) { + scrollTop.style.display = 'block'; + scrollTopShowing = true; + setTimeout(() => { + scrollTop.style.opacity = 0.4; + }, 1); + } else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) { + scrollTop.style.opacity = 0; + scrollTopShowing = false; + setTimeout(() => { + scrollTop.style.display = 'none'; + }, 500); + } + }); + + // Common jQuery actions + $('[data-action="expand-entity-list-details"]').click(function() { + $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240); + }); + // Popup close + $('.popup-close').click(function() { + $(this).closest('.overlay').fadeOut(240); + }); + $('.overlay').click(function(event) { + if (!$(event.target).hasClass('overlay')) return; + $(this).fadeOut(240); + }); + + // Prevent markdown display link click redirect + $('.markdown-display').on('click', 'a', function(event) { + event.preventDefault(); + window.open($(this).attr('href')); + }); + + // Detect IE for css + if(navigator.userAgent.indexOf('MSIE')!==-1 + || navigator.appVersion.indexOf('Trident/') > 0 + || navigator.userAgent.indexOf('Safari') !== -1){ + $('body').addClass('flexbox-support'); + } -function elemExists(selector) { - return document.querySelector(selector) !== null; -} +}); -// TinyMCE editor -if (elemExists('#html-editor')) { - var tinyMceOptions = require('./pages/page-form'); - tinymce.init(tinyMceOptions); -} \ No newline at end of file +// Page specific items +require('./pages/page-show');