]> BookStack Code Mirror - bookstack/blob - resources/assets/js/global.js
Fixed back-to-top button on firefox. Fixes #153.
[bookstack] / resources / assets / js / global.js
1 "use strict";
2
3 // AngularJS - Create application and load components
4 var angular = require('angular');
5 var ngResource = require('angular-resource');
6 var ngAnimate = require('angular-animate');
7 var ngSanitize = require('angular-sanitize');
8 require('angular-ui-sortable');
9
10 var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
11
12 // Global Event System
13 class Events {
14     constructor() {
15         this.listeners = {};
16     }
17
18     emit(eventName, eventData) {
19         if (typeof this.listeners[eventName] === 'undefined') return this;
20         var eventsToStart = this.listeners[eventName];
21         for (let i = 0; i < eventsToStart.length; i++) {
22             var event = eventsToStart[i];
23             event(eventData);
24         }
25         return this;
26     }
27
28     listen(eventName, callback) {
29         if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = [];
30         this.listeners[eventName].push(callback);
31         return this;
32     }
33 };
34 window.Events = new Events();
35
36 var services = require('./services')(ngApp, Events);
37 var directives = require('./directives')(ngApp, Events);
38 var controllers = require('./controllers')(ngApp, Events);
39
40 //Global jQuery Config & Extensions
41
42 // Smooth scrolling
43 jQuery.fn.smoothScrollTo = function () {
44     if (this.length === 0) return;
45     let scrollElem = document.documentElement.scrollTop === 0 ?  document.body : document.documentElement;
46     $(scrollElem).animate({
47         scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin
48     }, 800); // Adjust to change animations speed (ms)
49     return this;
50 };
51
52 // Making contains text expression not worry about casing
53 jQuery.expr[":"].contains = $.expr.createPseudo(function (arg) {
54     return function (elem) {
55         return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
56     };
57 });
58
59 // Global jQuery Elements
60 $(function () {
61
62     var notifications = $('.notification');
63     var successNotification = notifications.filter('.pos');
64     var errorNotification = notifications.filter('.neg');
65     var warningNotification = notifications.filter('.warning');
66     // Notification Events
67     window.Events.listen('success', function (text) {
68         successNotification.hide();
69         successNotification.find('span').text(text);
70         setTimeout(() => {
71             successNotification.show();
72         }, 1);
73     });
74     window.Events.listen('warning', function (text) {
75         warningNotification.find('span').text(text);
76         warningNotification.show();
77     });
78     window.Events.listen('error', function (text) {
79         errorNotification.find('span').text(text);
80         errorNotification.show();
81     });
82
83     // Notification hiding
84     notifications.click(function () {
85         $(this).fadeOut(100);
86     });
87
88     // Chapter page list toggles
89     $('.chapter-toggle').click(function (e) {
90         e.preventDefault();
91         $(this).toggleClass('open');
92         $(this).closest('.chapter').find('.inset-list').slideToggle(180);
93     });
94
95     // Back to top button
96     $('#back-to-top').click(function() {
97          $('#header').smoothScrollTo();
98     });
99     var scrollTopShowing = false;
100     var scrollTop = document.getElementById('back-to-top');
101     var scrollTopBreakpoint = 1200;
102     window.addEventListener('scroll', function() {
103         let scrollTopPos = document.documentElement.scrollTop || document.body.scrollTop || 0;
104         if (!scrollTopShowing && scrollTopPos > scrollTopBreakpoint) {
105             scrollTop.style.display = 'block';
106             scrollTopShowing = true;
107             setTimeout(() => {
108                 scrollTop.style.opacity = 0.4;
109             }, 1);
110         } else if (scrollTopShowing && scrollTopPos < scrollTopBreakpoint) {
111             scrollTop.style.opacity = 0;
112             scrollTopShowing = false;
113             setTimeout(() => {
114                 scrollTop.style.display = 'none';
115             }, 500);
116         }
117     });
118
119     // Common jQuery actions
120     $('[data-action="expand-entity-list-details"]').click(function() {
121         $('.entity-list.compact').find('p').not('.empty-text').slideToggle(240);
122     });
123
124
125 });
126
127 // Page specific items
128 require('./pages/page-show');