331 lines
8.5 KiB
JavaScript
331 lines
8.5 KiB
JavaScript
import $ from 'jquery';
|
|
import Headroom from 'headroom.js';
|
|
import tippy from 'tippy.js';
|
|
import 'tippy.js/dist/tippy.css';
|
|
import shave from 'shave';
|
|
import GhostContentAPI from '@tryghost/content-api';
|
|
import Fuse from 'fuse.js/dist/fuse.basic.esm.min.js';
|
|
import Swiper, { FreeMode, A11y } from 'swiper';
|
|
import 'swiper/css';
|
|
import { isRTL, formatDate, isMobile } from './helpers';
|
|
|
|
$(() => {
|
|
if (isRTL()) {
|
|
$('html')
|
|
.attr('dir', 'rtl')
|
|
.addClass('rtl');
|
|
}
|
|
|
|
const $body = $('body');
|
|
const $header = $('.js-header');
|
|
const $announcementBar = $('#announcement-bar-root');
|
|
const $openMenu = $('.js-open-menu');
|
|
const $closeMenu = $('.js-close-menu');
|
|
const $menu = $('.js-menu');
|
|
const $toggleSubmenu = $('.js-toggle-submenu');
|
|
const $submenuOption = $('.js-submenu-option')[0];
|
|
const $submenu = $('.js-submenu');
|
|
const $recentSlider = $('.js-recent-slider');
|
|
const $openSecondaryMenu = $('.js-open-secondary-menu');
|
|
const $openSearch = $('.js-open-search');
|
|
const $closeSearch = $('.js-close-search');
|
|
const $search = $('.js-search');
|
|
const $inputSearch = $('.js-input-search');
|
|
const $searchResults = $('.js-search-results');
|
|
const $searchNoResults = $('.js-no-results');
|
|
const $toggleDarkMode = $('.js-toggle-darkmode');
|
|
const $mainNav = $('.js-main-nav');
|
|
const $mainNavLeft = $('.js-main-nav-left');
|
|
const $newsletterElements = $('.js-newsletter');
|
|
const $nativeComments = $('.js-native-comments > div > iframe')[0];
|
|
const currentSavedTheme = localStorage.getItem('theme');
|
|
|
|
let fuse = null;
|
|
let submenuIsOpen = false;
|
|
let secondaryMenuTippy = null;
|
|
|
|
const showSubmenu = () => {
|
|
$header.addClass('submenu-is-active');
|
|
$toggleSubmenu.addClass('active');
|
|
$submenu.removeClass('closed').addClass('opened');
|
|
};
|
|
|
|
const hideSubmenu = () => {
|
|
$header.removeClass('submenu-is-active');
|
|
$toggleSubmenu.removeClass('active');
|
|
$submenu.removeClass('opened').addClass('closed');
|
|
};
|
|
|
|
const toggleScrollVertical = () => {
|
|
$body.toggleClass('no-scroll-y');
|
|
};
|
|
|
|
const tryToRemoveNewsletter = () => {
|
|
if (typeof disableNewsletter !== 'undefined' && disableNewsletter) {
|
|
$newsletterElements.remove();
|
|
}
|
|
};
|
|
|
|
const trySearchFeature = () => {
|
|
if (typeof ghostSearchApiKey !== 'undefined' && typeof nativeSearchEnabled === 'undefined') {
|
|
getAllPosts(ghostHost, ghostSearchApiKey);
|
|
} else {
|
|
$openSearch.css('visibility', 'hidden');
|
|
$closeSearch.remove();
|
|
$search.remove();
|
|
}
|
|
};
|
|
|
|
const getAllPosts = (host, key) => {
|
|
const api = new GhostContentAPI({
|
|
url: host,
|
|
key,
|
|
version: 'v5.0'
|
|
});
|
|
const allPosts = [];
|
|
const fuseOptions = {
|
|
shouldSort: true,
|
|
ignoreLocation: true,
|
|
findAllMatches: true,
|
|
includeScore: true,
|
|
minMatchCharLength: 2,
|
|
keys: ['title', 'custom_excerpt', 'tags.name']
|
|
};
|
|
|
|
api.posts
|
|
.browse({
|
|
limit: 'all',
|
|
include: 'tags',
|
|
fields: 'id, title, url, published_at, custom_excerpt'
|
|
})
|
|
.then(posts => {
|
|
for (let i = 0, len = posts.length; i < len; i++) {
|
|
allPosts.push(posts[i]);
|
|
}
|
|
|
|
fuse = new Fuse(allPosts, fuseOptions);
|
|
})
|
|
.catch(err => {
|
|
console.log(err);
|
|
});
|
|
};
|
|
|
|
const toggleDesktopTopbarOverflow = disableOverflow => {
|
|
if (!isMobile()) {
|
|
if (disableOverflow) {
|
|
$mainNav.addClass('toggle-overflow');
|
|
$mainNavLeft.addClass('toggle-overflow');
|
|
} else {
|
|
$mainNav.removeClass('toggle-overflow');
|
|
$mainNavLeft.removeClass('toggle-overflow');
|
|
}
|
|
}
|
|
};
|
|
|
|
$openMenu.on('click', () => {
|
|
$header.addClass('mobile-menu-opened');
|
|
$menu.addClass('opened');
|
|
toggleScrollVertical();
|
|
});
|
|
|
|
$closeMenu.on('click', () => {
|
|
$header.removeClass('mobile-menu-opened');
|
|
$menu.removeClass('opened');
|
|
toggleScrollVertical();
|
|
});
|
|
|
|
$toggleSubmenu.on('click', () => {
|
|
submenuIsOpen = !submenuIsOpen;
|
|
|
|
if (submenuIsOpen) {
|
|
showSubmenu();
|
|
} else {
|
|
hideSubmenu();
|
|
}
|
|
});
|
|
|
|
$openSearch.on('click', () => {
|
|
$search.addClass('opened');
|
|
setTimeout(() => {
|
|
$inputSearch.trigger('focus');
|
|
}, 400);
|
|
toggleScrollVertical();
|
|
});
|
|
|
|
$closeSearch.on('click', () => {
|
|
$inputSearch.trigger('blur');
|
|
$search.removeClass('opened');
|
|
toggleScrollVertical();
|
|
});
|
|
|
|
$inputSearch.on('keyup', () => {
|
|
if ($inputSearch.val().length > 0 && fuse) {
|
|
const results = fuse.search($inputSearch.val());
|
|
const bestResults = results.filter(result => {
|
|
if (result.score <= 0.5) {
|
|
return result;
|
|
}
|
|
});
|
|
|
|
let htmlString = '';
|
|
|
|
if (bestResults.length > 0) {
|
|
for (let i = 0, len = bestResults.length; i < len; i++) {
|
|
htmlString += `
|
|
<article class="m-result">\
|
|
<a href="${bestResults[i].item.url}" class="m-result__link">\
|
|
<h3 class="m-result__title">${bestResults[i].item.title}</h3>\
|
|
<span class="m-result__date">${formatDate(
|
|
bestResults[i].item.published_at
|
|
)}</span>\
|
|
</a>\
|
|
</article>`;
|
|
}
|
|
|
|
$searchNoResults.hide();
|
|
$searchResults.html(htmlString);
|
|
$searchResults.show();
|
|
} else {
|
|
$searchResults.html('');
|
|
$searchResults.hide();
|
|
$searchNoResults.show();
|
|
}
|
|
} else {
|
|
$searchResults.html('');
|
|
$searchResults.hide();
|
|
$searchNoResults.hide();
|
|
}
|
|
});
|
|
|
|
$toggleDarkMode.on('change', () => {
|
|
if ($toggleDarkMode.is(':checked')) {
|
|
$('html').attr('data-theme', 'dark');
|
|
localStorage.setItem('theme', 'dark');
|
|
} else {
|
|
$('html').attr('data-theme', 'light');
|
|
localStorage.setItem('theme', 'light');
|
|
}
|
|
|
|
if ($nativeComments) {
|
|
$nativeComments.contentDocument.location.reload(true);
|
|
}
|
|
});
|
|
|
|
$toggleDarkMode.on('mouseenter', () => {
|
|
toggleDesktopTopbarOverflow(true);
|
|
});
|
|
|
|
$toggleDarkMode.on('mouseleave', () => {
|
|
toggleDesktopTopbarOverflow(false);
|
|
});
|
|
|
|
$(window).on('click', e => {
|
|
if (submenuIsOpen) {
|
|
if ($submenuOption && !$submenuOption.contains(e.target)) {
|
|
submenuIsOpen = false;
|
|
hideSubmenu();
|
|
}
|
|
}
|
|
});
|
|
|
|
$(document).on('keyup', e => {
|
|
if (e.key === 'Escape' && $search.hasClass('opened')) {
|
|
$closeSearch.trigger('click');
|
|
}
|
|
});
|
|
|
|
if (currentSavedTheme) {
|
|
if (currentSavedTheme === 'dark') {
|
|
$toggleDarkMode.each(function() {
|
|
$(this).attr('checked', true);
|
|
});
|
|
}
|
|
}
|
|
|
|
if ($header.length > 0) {
|
|
const headroom = new Headroom($header[0], {
|
|
tolerance: {
|
|
down: 10,
|
|
up: 20
|
|
},
|
|
offset: 15,
|
|
onUnpin: () => {
|
|
if (!isMobile() && secondaryMenuTippy) {
|
|
const desktopSecondaryMenuTippy = secondaryMenuTippy[0];
|
|
|
|
if (
|
|
desktopSecondaryMenuTippy &&
|
|
desktopSecondaryMenuTippy.state.isVisible
|
|
) {
|
|
desktopSecondaryMenuTippy.hide();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
headroom.init();
|
|
}
|
|
|
|
if ($announcementBar.length > 0) {
|
|
$announcementBar.detach().prependTo($header);
|
|
$header.addClass('with-announcement-bar');
|
|
|
|
setTimeout(() => {
|
|
$body.css('padding-top', $announcementBar.height());
|
|
$header.removeAttr('data-animate');
|
|
}, 500);
|
|
|
|
const barObserver = new MutationObserver((e) => {
|
|
if (e[0].removedNodes.length) {
|
|
$body.css('padding-top', 0);
|
|
}
|
|
})
|
|
|
|
barObserver.observe($announcementBar[0], { childList: true });
|
|
} else {
|
|
setTimeout(() => {
|
|
$header.removeAttr('data-animate');
|
|
}, 500);
|
|
}
|
|
|
|
if ($recentSlider.length > 0) {
|
|
const recentSwiper = new Swiper('.js-recent-slider', {
|
|
modules: [FreeMode, A11y],
|
|
freeMode: true,
|
|
slidesPerView: 'auto',
|
|
a11y: true,
|
|
on: {
|
|
init: function() {
|
|
shave('.js-recent-article-title', 50);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if ($openSecondaryMenu.length > 0) {
|
|
const template = document.getElementById('secondary-navigation-template');
|
|
|
|
secondaryMenuTippy = tippy('.js-open-secondary-menu', {
|
|
appendTo: document.body,
|
|
content: template.innerHTML,
|
|
allowHTML: true,
|
|
arrow: true,
|
|
trigger: 'click',
|
|
interactive: true,
|
|
onShow() {
|
|
toggleDesktopTopbarOverflow(true);
|
|
},
|
|
onHidden() {
|
|
toggleDesktopTopbarOverflow(false);
|
|
}
|
|
});
|
|
}
|
|
|
|
tippy('.js-tooltip');
|
|
|
|
shave('.js-article-card-title', 100);
|
|
shave('.js-article-card-title-no-image', 250);
|
|
|
|
tryToRemoveNewsletter();
|
|
trySearchFeature();
|
|
});
|