X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/cca3533d35c23848edff7edcbfe0327fd9d283a7..refs/pull/524/head:/resources/assets/js/global.js diff --git a/resources/assets/js/global.js b/resources/assets/js/global.js index 2cd45e5bc..352616c5a 100644 --- a/resources/assets/js/global.js +++ b/resources/assets/js/global.js @@ -1,62 +1,130 @@ -// Configure ZeroClipboard -window.ZeroClipboard = require('zeroclipboard'); -window.ZeroClipboard.config({ - swfPath: '/ZeroClipboard.swf' +"use strict"; +require("babel-polyfill"); +require('./dom-polyfills'); + +// 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; +}; + +// Global Event System +class EventManager { + constructor() { + this.listeners = {}; + this.stack = []; + } + + emit(eventName, eventData) { + this.stack.push({name: eventName, data: eventData}); + if (typeof this.listeners[eventName] === 'undefined') return this; + let eventsToStart = this.listeners[eventName]; + for (let i = 0; i < eventsToStart.length; i++) { + let event = eventsToStart[i]; + event(eventData); + } + return this; + } + + listen(eventName, callback) { + if (typeof this.listeners[eventName] === 'undefined') this.listeners[eventName] = []; + this.listeners[eventName].push(callback); + return this; + } +} + +window.$events = new EventManager(); + +const Vue = require("vue"); +const axios = require("axios"); + +let axiosInstance = axios.create({ + headers: { + 'X-CSRF-TOKEN': document.querySelector('meta[name=token]').getAttribute('content'), + 'baseURL': window.baseUrl('') + } }); +axiosInstance.interceptors.request.use(resp => { + return resp; +}, err => { + if (typeof err.response === "undefined" || typeof err.response.data === "undefined") return Promise.reject(err); + if (typeof err.response.data.error !== "undefined") window.$events.emit('error', err.response.data.error); + if (typeof err.response.data.message !== "undefined") window.$events.emit('error', err.response.data.message); +}); +window.$http = axiosInstance; + +Vue.prototype.$http = axiosInstance; +Vue.prototype.$events = window.$events; + +// Translation setup +// Creates a global function with name 'trans' to be used in the same way as Laravel's translation system +const Translations = require("./translations"); +let translator = new Translations(window.translations); +window.trans = translator.get.bind(translator); +window.trans_choice = translator.getPlural.bind(translator); -// 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'); -var ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize']); -var services = require('./services')(ngApp); -var directives = require('./directives')(ngApp); -var controllers = require('./controllers')(ngApp); +require("./vues/vues"); +require("./components"); + //Global jQuery Config & Extensions +/** + * Scroll the view to a specific element. + * @param {HTMLElement} element + */ +window.scrollToElement = function(element) { + if (!element) return; + let offset = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; + let top = element.getBoundingClientRect().top + offset; + $('html, body').animate({ + scrollTop: top - 60 // Adjust to change final scroll position top margin + }, 300); +}; + +/** + * Scroll and highlight an element. + * @param {HTMLElement} element + */ +window.scrollAndHighlight = function(element) { + if (!element) return; + window.scrollToElement(element); + let color = document.getElementById('custom-styles').getAttribute('data-color-light'); + let initColor = window.getComputedStyle(element).getPropertyValue('background-color'); + element.style.backgroundColor = color; + setTimeout(() => { + element.classList.add('selectFade'); + element.style.backgroundColor = initColor; + }, 10); + setTimeout(() => { + element.classList.remove('selectFade'); + element.style.backgroundColor = ''; + }, 3000); +}; + // Smooth scrolling jQuery.fn.smoothScrollTo = function () { if (this.length === 0) return; - $('body').animate({ - scrollTop: this.offset().top - 60 // Adjust to change final scroll position top margin - }, 800); // Adjust to change animations speed (ms) + window.scrollToElement(this[0]); 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; }; }); -// Global jQuery Elements -$(function () { - - // Notification hiding - $('.notification').click(function () { - $(this).fadeOut(100); - }); - - // Chapter page list toggles - $('.chapter-toggle').click(function (e) { - e.preventDefault(); - $(this).toggleClass('open'); - $(this).closest('.chapter').find('.inset-list').slideToggle(180); - }); - -}); - - -function elemExists(selector) { - return document.querySelector(selector) !== null; +// Detect IE for css +if(navigator.userAgent.indexOf('MSIE')!==-1 + || navigator.appVersion.indexOf('Trident/') > 0 + || navigator.userAgent.indexOf('Safari') !== -1){ + document.body.classList.add('flexbox-support'); } -// 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");