webpack-bootstrap-ui-kit/src/js/_main.js

419 lines
10 KiB
JavaScript
Raw Normal View History

2020-02-04 19:15:22 +01:00
'use strict';
2019-06-08 17:20:51 +02:00
import $ from 'jquery';
import Events from './_events';
2019-10-20 01:40:40 +02:00
import Consts from './_consts';
2019-06-08 17:20:51 +02:00
import Spinner from './_components/_ui.spinner';
2019-09-07 03:49:08 +02:00
// AJAX functionality
import AjaxUI from './_components/_ui.ajax';
2019-07-10 20:59:57 +02:00
2019-06-08 17:20:51 +02:00
import FormBasics from './_components/_ui.form.basics';
2019-06-08 17:20:51 +02:00
import SmoothScroll from 'smooth-scroll';
const smoothScroll = SmoothScroll();
2020-02-17 19:06:39 +01:00
const MainUI = ($ => {
2019-06-08 17:20:51 +02:00
// Constants
const W = window;
const D = document;
const $Body = $('body');
const NAME = 'MainUI';
// get browser locale
//const Locale = $('html').attr('lang').substring(0, 2);
const $AlertNotify = $('#AlertNotify');
const $SiteWideMessage = $('#SiteWideMessage');
// get browser window visibility preferences
// Opera 12.10, Firefox >=18, Chrome >=31, IE11
const HiddenName = 'hidden';
const VisibilityChangeEvent = 'visibilitychange';
// update visibility state
D.addEventListener(VisibilityChangeEvent, () => {
if (D.visibilityState === HiddenName) {
console.log('Tab: hidden');
$Body.addClass('is-hidden');
$Body.trigger(Events.TABHIDDEN);
2019-06-08 17:20:51 +02:00
} else {
console.log('Tab: focused');
$Body.removeClass('is-hidden');
$Body.trigger(Events.TABFOCUSED);
2019-06-08 17:20:51 +02:00
}
});
// update online/offline state
2019-10-20 01:40:40 +02:00
const updateOnlineStatus = () => {
2019-06-08 17:20:51 +02:00
if (!navigator.onLine) {
console.log('Tab: offline');
$Body.addClass('is-offline');
$Body.trigger(Events.OFFLINE);
2019-06-08 17:20:51 +02:00
} else {
console.log('Tab: online');
$Body.removeClass('is-offline');
$Body.trigger(Events.ONLINE);
2019-06-08 17:20:51 +02:00
}
};
if (typeof navigator.onLine !== 'undefined') {
2020-02-04 19:15:22 +01:00
W.addEventListener(
'offline',
() => {
updateOnlineStatus();
},
false,
);
2019-06-08 17:20:51 +02:00
2020-02-04 19:15:22 +01:00
W.addEventListener(
'online',
() => {
updateOnlineStatus();
},
false,
);
2019-06-08 17:20:51 +02:00
W.addEventListener('load', () => {
updateOnlineStatus();
});
}
// scrollTo
2019-10-20 01:40:40 +02:00
const ScrollTo = (trigger, selector) => {
2020-02-04 19:15:22 +01:00
smoothScroll.animateScroll(D.querySelector(selector), trigger, {
speed: 500,
offset: -20,
//easing: 'easeInOutCubic',
// Callback API
//before: (anchor, toggle) => {}, // Callback to run before scroll
//`after: (anchor, toggle) => {} // Callback to run after scroll
});
2019-06-08 17:20:51 +02:00
};
// session ping
2019-12-17 23:33:17 +01:00
const pingInterval = setInterval(() => {
2019-06-08 17:20:51 +02:00
if ($Body.hasClass('is-offline')) {
return;
}
$.ajax({
sync: false,
async: true,
cache: false,
url: '/Security/ping',
global: false,
type: 'POST',
complete(data, datastatus) {
if (datastatus !== 'success') {
2019-12-17 23:33:17 +01:00
clearInterval(pingInterval);
2019-12-20 01:12:13 +01:00
$Body.addClass('is-offline');
2019-12-17 23:33:17 +01:00
//W.location.reload(false);
2019-12-20 01:12:13 +01:00
} else {
$Body.removeClass('is-offline');
2019-06-08 17:20:51 +02:00
}
},
});
}, 300000); // 5 min in ms
W.URLDetails = {
2020-02-04 19:15:22 +01:00
base: $('base').attr('href'),
relative: '/',
hash: '',
2019-06-08 17:20:51 +02:00
};
2020-02-17 19:06:39 +01:00
W.IsTouchScreen = 'ontouchstart' in window || navigator.msMaxTouchPoints;
2019-06-08 17:20:51 +02:00
class MainUI {
// Static methods
static init() {
this.dispose();
console.log(`Initializing: ${NAME}`);
// update location details
this.updateLocation();
// mark available offline areas
if ('caches' in W) {
$('a.offline').addClass('offline-available');
}
2019-10-20 01:40:40 +02:00
this.loadImages();
// detect bootstrap screen size
this.detectBootstrapScreenSize();
2019-06-08 17:20:51 +02:00
// mark external links
$('a.external,a[rel="external"]').attr('target', '_blank');
// show encoded emails
2019-10-20 01:40:40 +02:00
/*$(D).find('.obm').each(() => {
if ($(this).attr('data-val') !== undefined) {
const email = $(this).attr('data-val').split('')
.reverse()
.join('')
.slice(0, -8)
.replace(/[a-zA-Z]/g, (c) => String.fromCharCode((c <= 'Z' ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26))
.replace('#AT#', '@');
const attr = $(this).attr('data-val-append');
if (attr !== undefined && attr !== false) {
$(this).append(email);
}
if ($(this).find('.sr-only').length > 0) {
$(this).find('.sr-only').append(email);
}
if ($(this).attr('href') !== undefined) {
$(this).attr('href', `mailto:${email}`);
}
}
});*/
2019-06-08 17:20:51 +02:00
//
// scroll links
2020-02-17 19:06:39 +01:00
$('.js-scrollTo').on('click', e => {
2019-06-08 17:20:51 +02:00
e.preventDefault();
const el = e.currentTarget;
const $el = $(e.currentTarget);
2019-10-20 01:40:40 +02:00
ScrollTo(el, $el.attr('data-target'));
2019-06-08 17:20:51 +02:00
});
// load external fonts
if ($('[data-extfont]').length) {
2020-02-04 19:15:22 +01:00
$.getScript(
'//ajax.googleapis.com/ajax/libs/webfont/1/webfont.js',
() => {
const fonts = [];
$('[data-extfont]').each((i, el) => {
fonts[i] = $(el).attr('data-extfont');
});
W.WebFont.load({
google: {
families: fonts,
},
});
},
);
2019-06-08 17:20:51 +02:00
}
// data-set links
2020-02-17 19:06:39 +01:00
$('[data-set-target]').on('click', e => {
2019-06-08 17:20:51 +02:00
const $el = $(e.currentTarget);
const $target = $($el.data('set-target'));
if (!$target.length) {
return;
}
$target.each((i, targetEl) => {
const $targetEl = $(targetEl);
const tag = $targetEl.prop('tagName').toLowerCase();
if (tag === 'input' || tag === 'select') {
$targetEl.val($el.data('set-val'));
} else if (!$targetEl.hasClass('field')) {
$targetEl.text($el.data('set-val'));
}
});
$el.trigger(Events.SET_TARGET_UPDATE);
$target.closest('form').trigger(Events.SET_TARGET_UPDATE);
});
2020-02-06 16:14:17 +01:00
// emulate links
2020-02-17 19:06:39 +01:00
$('.a[data-href]').on('click', e => {
2020-02-06 16:14:17 +01:00
const $el = $(e.currentTarget);
const href = $el.data('href');
if (!href.length) {
console.warn('Missing data-href');
console.warn($el);
}
W.location.assign(href);
});
2019-06-08 17:20:51 +02:00
// hide spinner
Spinner.hide(() => {
$Body.addClass('loaded');
});
// fire page printing
if (W.URLDetails['hash'].indexOf('printpage') > -1) {
W.print();
}
2019-08-27 17:25:41 +02:00
2019-10-20 01:40:40 +02:00
$Body.data(NAME, this);
}
static detectBootstrapScreenSize() {
const $el = $('<div class="env-test"></div>');
2020-02-07 21:13:38 +01:00
let envs = [...Consts.ENVS];
2019-10-20 01:40:40 +02:00
$Body.append($el);
2020-02-07 21:13:38 +01:00
2019-10-20 01:40:40 +02:00
let curEnv = envs.shift();
2020-02-07 21:13:38 +01:00
envs = envs.reverse();
2019-10-20 01:40:40 +02:00
2020-02-07 21:13:38 +01:00
for (let i = 0; i < envs.length; ++i) {
const env = envs[i];
2019-10-20 01:40:40 +02:00
$el.addClass(`d-${env}-none`);
if ($el.is(':hidden')) {
curEnv = env;
break;
}
2019-08-27 17:25:41 +02:00
}
2019-10-20 01:40:40 +02:00
$el.remove();
$Body.removeClass(envs);
$Body.addClass(curEnv);
return curEnv;
2019-06-08 17:20:51 +02:00
}
static updateLocation(url) {
let location = url || W.location.href;
location = location.replace(W.URLDetails['base'], '/');
const hash = location.indexOf('#');
W.URLDetails.relative = location.split('#')[0];
2020-02-04 19:15:22 +01:00
W.URLDetails.hash =
hash >= 0 ? location.substr(location.indexOf('#')) : '';
2019-06-08 17:20:51 +02:00
}
// show site-wide alert
static alert(msg, cls) {
$SiteWideMessage.fadeOut('fast');
2020-02-04 19:15:22 +01:00
$SiteWideMessage.html(
`<div class="page-alert"><div class="alert alert-${cls}"><i class="close" data-dismiss="alert">&times;</i>${msg}</div></div>`,
);
2019-06-08 17:20:51 +02:00
$SiteWideMessage.find('.page-alert').alert();
$SiteWideMessage.find('.close[data-dismiss="alert"]').click(() => {
$SiteWideMessage.fadeOut('slow', () => {
$SiteWideMessage.find('.page-alert').alert('close');
});
});
$SiteWideMessage.fadeIn('slow');
if ($AlertNotify.length) {
$AlertNotify[0].play();
}
$(W).trigger(`${Events.ALLERTAPPEARED}`);
2019-06-08 17:20:51 +02:00
}
// hide site-wide alert
static alertHide() {
if ($SiteWideMessage.length !== 0) {
$SiteWideMessage.fadeOut('slow', () => {
$SiteWideMessage.find('.alert').alert('close');
});
}
2020-02-04 19:15:22 +01:00
if ($AlertNotify.length && typeof $AlertNotify[0].stop !== 'undefined') {
2019-06-08 17:20:51 +02:00
$AlertNotify[0].stop();
}
$(W).trigger(`${Events.ALLERTREMOVED}`);
2019-06-08 17:20:51 +02:00
}
// load all images
static loadImages() {
const $imgs = $Body.find('img');
const $imgUrls = [];
const $imgLazyUrls = [];
// collect image details
$imgs.each((i, el) => {
const $el = $(el);
const src = $el.attr('src');
const lazySrc = $el.data('lazy-src');
if (src && src.length) {
$imgUrls.push(src);
}
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc);
$el.addClass('loading');
AjaxUI.preload([lazySrc]).then(() => {
$el.attr('src', lazySrc);
$el.addClass('loaded');
$el.removeClass('loading');
$el.trigger(`${Events.LAZYIMAGEREADY}`);
2019-06-08 17:20:51 +02:00
});
}
});
2020-02-04 19:15:22 +01:00
// load lazy backgrounds
$Body.find('[data-lazy-bg]').each((i, el) => {
const $el = $(el);
const lazySrc = $el.data('lazy-bg');
if (lazySrc && lazySrc.length) {
$imgLazyUrls.push(lazySrc);
$el.addClass('loading');
AjaxUI.preload([lazySrc]).then(() => {
2020-02-06 16:14:17 +01:00
$el.css({ 'background-image': `url(${lazySrc})` });
2020-02-04 19:15:22 +01:00
$el.addClass('loaded');
$el.removeClass('loading');
$el.trigger(`${Events.LAZYIMAGEREADY}`);
2020-02-04 19:15:22 +01:00
});
}
});
2019-06-08 17:20:51 +02:00
// load defined images
AjaxUI.preload($imgUrls).then(() => {
$(W).trigger('images-loaded');
// load lazy images
AjaxUI.preload($imgLazyUrls).then(() => {
console.log('All images are loaded!');
2020-02-11 21:07:12 +01:00
setTimeout(() => {
$(W).trigger(`${Events.LAZYIMAGESREADY}`);
}, 100);
2019-06-08 17:20:51 +02:00
});
});
}
static dispose() {
console.log(`Destroying: ${NAME}`);
}
}
$(W).on(`${Events.AJAX} ${Events.LOADED}`, () => {
MainUI.init();
});
2019-10-20 01:40:40 +02:00
$(W).on('resize', () => {
MainUI.detectBootstrapScreenSize();
});
$(W).on('beforeunload unload', () => {
2019-07-18 08:07:11 +02:00
Spinner.show(() => {
$Body.removeClass('loaded');
});
});
2019-06-08 17:20:51 +02:00
W.MainUI = MainUI;
return MainUI;
})($);
export default MainUI;