Bundling JS with ESBuild (#702)
* add npm dependencies used in this theme * implement helper to configure JS and ESBuild * migrate jquery popper.js bootstrap fontawesome to js bundle * refactor main.js into smaller pieces, and moved navbar.js to assets * remove list.js. It adjusts post card height to be the same, but is actually not needed. * refactored notes.js, search.js, single.js into application.js * move ityped to js asset, implement experiences horizontal vertical line in css * align recent post height via css * migrated home.js and refactored into various sections * migrated darkMode feature to js bundle * moved mermaid feature to js bundle * migrate syntax highlight to js bundle * migrate katex ( js portion ) to js bundle * migrate pdf-js to js bundle by delegating to cdn * set explicit comparisions for feature envvars so js can properly optimize * removed goat-counter * more fixes for broken achievements and small bugs * more bug fixes * allow configuration of hightlight.js, fix video-player shortcode * remove jquery all together * add null handling and fix merge conflicts Co-authored-by: Aaron Qian <aaron@yeet.io>
This commit is contained in:
parent
fe14b0fbf5
commit
02db3d3044
491 changed files with 4919 additions and 151344 deletions
220
assets/scripts/sections/achievements.js
Normal file
220
assets/scripts/sections/achievements.js
Normal file
|
@ -0,0 +1,220 @@
|
|||
import { getDeviceState } from '../core'
|
||||
|
||||
function fourColumRow (gallery, entries, i) {
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-lg-6', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
|
||||
const entry2 = document.createElement('div')
|
||||
entry2.classList.add('col-lg-3', 'm-0', 'p-0')
|
||||
entry2.appendChild(entries[i].cloneNode(true))
|
||||
entry2.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry2)
|
||||
i++
|
||||
|
||||
const entry3 = document.createElement('div')
|
||||
entry3.classList.add('col-lg-3', 'm-0', 'p-0')
|
||||
entry3.appendChild(entries[i].cloneNode(true))
|
||||
entry3.children[0].classList.add('img-type-2')
|
||||
i++
|
||||
entry3.appendChild(entries[i].cloneNode(true))
|
||||
entry3.children[1].classList.add('img-type-2')
|
||||
gallery.appendChild(entry3)
|
||||
i++
|
||||
}
|
||||
|
||||
function fourColumnReversedRow (gallery, entries, i) {
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-lg-3', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-2')
|
||||
i++
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[1].classList.add('img-type-2')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
|
||||
const entry2 = document.createElement('div')
|
||||
entry2.classList.add('col-lg-3', 'm-0', 'p-0')
|
||||
entry2.appendChild(entries[i].cloneNode(true))
|
||||
entry2.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry2)
|
||||
i++
|
||||
|
||||
const entry3 = document.createElement('div')
|
||||
entry3.classList.add('col-lg-6', 'm-0', 'p-0')
|
||||
entry3.appendChild(entries[i].cloneNode(true))
|
||||
entry3.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry3)
|
||||
i++
|
||||
}
|
||||
|
||||
function threeColumnRow (gallery, entries, i) {
|
||||
console.log(i)
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-lg-6', 'col-md-6', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
|
||||
const entry2 = document.createElement('div')
|
||||
entry2.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
|
||||
entry2.appendChild(entries[i].cloneNode(true))
|
||||
entry2.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry2)
|
||||
i++
|
||||
|
||||
const entry3 = document.createElement('div')
|
||||
entry3.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
|
||||
entry3.appendChild(entries[i].cloneNode(true))
|
||||
entry3.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry3)
|
||||
i++
|
||||
}
|
||||
|
||||
function threeColumnReversedRow (gallery, entries, i) {
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
|
||||
const entry2 = document.createElement('div')
|
||||
entry2.classList.add('col-lg-3', 'col-md-3', 'm-0', 'p-0')
|
||||
entry2.appendChild(entries[i].cloneNode(true))
|
||||
entry2.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry2)
|
||||
i++
|
||||
|
||||
const entry3 = document.createElement('div')
|
||||
entry3.classList.add('col-lg-6', 'col-md-3', 'm-0', 'p-0')
|
||||
entry3.appendChild(entries[i].cloneNode(true))
|
||||
entry3.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry3)
|
||||
i++
|
||||
}
|
||||
|
||||
function twoColumnRow (gallery, entries, i) {
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-6', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
|
||||
const entry2 = document.createElement('div')
|
||||
entry2.classList.add('col-6', 'm-0', 'p-0')
|
||||
entry2.appendChild(entries[i].cloneNode(true))
|
||||
entry2.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry2)
|
||||
i++
|
||||
}
|
||||
|
||||
function singleColumnRow (gallery, entries, i) {
|
||||
const entry1 = document.createElement('div')
|
||||
entry1.classList.add('col-12', 'm-0', 'p-0')
|
||||
entry1.appendChild(entries[i].cloneNode(true))
|
||||
entry1.children[0].classList.add('img-type-1')
|
||||
gallery.appendChild(entry1)
|
||||
i++
|
||||
}
|
||||
|
||||
function showAchievements () {
|
||||
const { isLaptop, isTablet } = getDeviceState()
|
||||
// show achievements from achievements-holder div
|
||||
const gallery = document.getElementById('gallery')
|
||||
if (gallery == null) {
|
||||
return
|
||||
}
|
||||
gallery.innerHTML = ''
|
||||
const entries = document.getElementById('achievements-holder').children
|
||||
let len = entries.length
|
||||
let i = 0
|
||||
let rowNumber = 1
|
||||
while (i < len) {
|
||||
if (isLaptop) {
|
||||
if (i + 4 <= len) {
|
||||
if (rowNumber % 2) {
|
||||
fourColumRow(gallery, entries, i)
|
||||
} else {
|
||||
fourColumnReversedRow(gallery, entries, i)
|
||||
}
|
||||
i += 4
|
||||
} else if (i + 3 <= len) {
|
||||
if (rowNumber % 2) {
|
||||
threeColumnRow(gallery, entries, i)
|
||||
} else {
|
||||
threeColumnReversedRow(gallery, entries, i)
|
||||
}
|
||||
i += 3
|
||||
} else if (i + 2 <= len) {
|
||||
twoColumnRow(gallery, entries, i)
|
||||
i += 2
|
||||
} else {
|
||||
singleColumnRow(gallery, entries, i)
|
||||
i++
|
||||
}
|
||||
} else if (isTablet) {
|
||||
if (i + 2 <= len) {
|
||||
twoColumnRow(gallery, entries, i)
|
||||
i += 2
|
||||
} else {
|
||||
singleColumnRow(gallery, entries, i)
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
singleColumnRow(gallery, entries, i)
|
||||
i++
|
||||
}
|
||||
rowNumber++
|
||||
}
|
||||
|
||||
// show full image on click
|
||||
const elements = document.getElementsByClassName('achievement-entry')
|
||||
len = elements.length
|
||||
for (let i = 0; i < len; i++) {
|
||||
elements[i].onclick = function () {
|
||||
const achievements = document.getElementsByClassName('achievement-entry')
|
||||
const len2 = achievements.length
|
||||
for (let j = 0; j < len2; j++) {
|
||||
achievements[j].classList.toggle('hidden')
|
||||
}
|
||||
this.classList.toggle('achievement-details')
|
||||
this.classList.toggle('hidden')
|
||||
this.parentElement.classList.toggle('col-lg-12')
|
||||
this.parentElement.classList.toggle('col-md-12')
|
||||
this.parentElement.classList.toggle('col-sm-12')
|
||||
if (this.children.SmallImage.hasAttribute('active')) {
|
||||
const mainLogo = this.children.LargeImage.getAttribute('Style')
|
||||
this.children.LargeImage.setAttribute('active', true)
|
||||
this.children.SmallImage.removeAttribute('active')
|
||||
|
||||
this.setAttribute('Style', mainLogo)
|
||||
} else {
|
||||
const mainLogo = this.children.SmallImage.getAttribute('Style')
|
||||
this.children.SmallImage.setAttribute('active', true)
|
||||
this.children.LargeImage.removeAttribute('active')
|
||||
this.setAttribute('Style', mainLogo)
|
||||
}
|
||||
|
||||
if (this.children.caption !== undefined) {
|
||||
this.children.caption.classList.toggle('hidden')
|
||||
}
|
||||
if (this.children['enlarge-icon'] !== undefined) {
|
||||
this.getElementsByClassName('fa-xmark')[0].classList.toggle('hidden')
|
||||
this.getElementsByClassName('fa-magnifying-glass-plus')[0].classList.toggle('hidden')
|
||||
}
|
||||
if (this.children['achievement-title'] !== undefined) {
|
||||
this.children['achievement-title'].classList.toggle('hidden')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
['DOMContentLoaded', 'resize'].forEach((event) =>
|
||||
document.addEventListener(event, showAchievements))
|
33
assets/scripts/sections/education.js
Normal file
33
assets/scripts/sections/education.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Show more rows in the taken courses table
|
||||
function toggleCourseVisibility (elem) {
|
||||
// find the courses
|
||||
const courses = elem.parentNode.getElementsByClassName('course')
|
||||
if (courses == null) {
|
||||
return
|
||||
}
|
||||
|
||||
// toggle hidden-course class from the third elements
|
||||
for (const course of courses) {
|
||||
if (course.classList.contains('hidden-course') || course.classList.contains('toggled-hidden-course')) {
|
||||
course.classList.toggle('hidden-course')
|
||||
course.classList.add('toggled-hidden-course')
|
||||
}
|
||||
}
|
||||
|
||||
// toggle the buttons visibility
|
||||
const buttonsToToggle = elem.parentNode.getElementsByClassName('show-more-btn')
|
||||
for (const buttonToToggle of buttonsToToggle) {
|
||||
buttonToToggle.classList.toggle('hidden')
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const els = [
|
||||
document.getElementById('show-more-btn'),
|
||||
document.getElementById('show-less-btn')
|
||||
]
|
||||
|
||||
els.filter((el) => el != null).forEach((el) =>
|
||||
el.addEventListener('click', ({ target }) =>
|
||||
toggleCourseVisibility(target)))
|
||||
})
|
7
assets/scripts/sections/index.js
Normal file
7
assets/scripts/sections/index.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import './navbar'
|
||||
import './sidebar'
|
||||
|
||||
import './education'
|
||||
import './achievements'
|
||||
import './projects'
|
||||
import './publications'
|
60
assets/scripts/sections/navbar.js
Normal file
60
assets/scripts/sections/navbar.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
const updateNavBar = () => {
|
||||
const topNavbar = document.getElementById('top-navbar')
|
||||
const navbarToggler = document.getElementById('navbar-toggler')
|
||||
const themeIcon = document.getElementById('navbar-theme-icon-svg')
|
||||
|
||||
if (window.scrollY > 40) {
|
||||
topNavbar?.classList.remove('initial-navbar')
|
||||
topNavbar?.classList.add('final-navbar', 'shadow')
|
||||
|
||||
navbarToggler?.classList.remove('navbar-dark')
|
||||
navbarToggler?.classList.add('navbar-light')
|
||||
|
||||
// color theme selector a.k.a. dark mode
|
||||
themeIcon?.classList.remove('navbar-icon-svg-dark')
|
||||
|
||||
// get the main logo from hidden img tag
|
||||
const mainLogo = document.getElementById('main-logo')
|
||||
if (mainLogo) {
|
||||
const logoURL = mainLogo.getAttribute('src')
|
||||
document.getElementById('logo')?.setAttribute('src', logoURL)
|
||||
}
|
||||
} else {
|
||||
topNavbar?.classList.remove('final-navbar', 'shadow')
|
||||
topNavbar?.classList.add('initial-navbar')
|
||||
|
||||
navbarToggler?.classList.remove('navbar-light')
|
||||
navbarToggler?.classList.add('navbar-dark')
|
||||
|
||||
// color theme selector a.k.a. dark mode
|
||||
themeIcon?.classList.add('navbar-icon-svg-dark')
|
||||
|
||||
// get the inverted logo from hidden img tag
|
||||
const invertedLogo = document.getElementById('inverted-logo')
|
||||
if (invertedLogo) {
|
||||
const logoURL = invertedLogo.getAttribute('src')
|
||||
document.getElementById('logo')?.setAttribute('src', logoURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// change navbar style on scroll
|
||||
// ==================================================
|
||||
// When the user scrolls down 80px from the top of the document,
|
||||
// resize the navbar's padding and the logo's font size
|
||||
document.addEventListener('scroll', updateNavBar)
|
||||
|
||||
// Creates a click handler to collapse the navigation when
|
||||
// anchors in the mobile nav pop up are clicked
|
||||
const navMain =document.getElementsByClassName('navbar-collapse')
|
||||
Array.from(navMain).forEach(function(el) {
|
||||
el.addEventListener('click', function (e) {
|
||||
if (e.target.tagName === 'A') {
|
||||
el.classList.add('collapse')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
updateNavBar()
|
||||
})
|
19
assets/scripts/sections/projects.js
Normal file
19
assets/scripts/sections/projects.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import Filterizr from 'filterizr'
|
||||
import { insertScript } from '../core'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// ================== Project cards =====================
|
||||
|
||||
// setup project filter buttons
|
||||
const projectCardHolder = document.getElementById('project-card-holder')
|
||||
if (projectCardHolder != null && projectCardHolder.children.length !== 0) {
|
||||
// eslint-disable-next-line no-new
|
||||
new Filterizr('.filtr-projects', {
|
||||
layout: 'sameWidth',
|
||||
controlsSelector: '.project-filtr-control'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// dynamically insert github buttons script.
|
||||
insertScript('github-buttons', 'https://buttons.github.io/buttons.js')
|
13
assets/scripts/sections/publications.js
Normal file
13
assets/scripts/sections/publications.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import Filterizr from 'filterizr'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const publicationCardHolder = document.getElementById('publication-card-holder')
|
||||
if (publicationCardHolder != null && publicationCardHolder.children.length !== 0) {
|
||||
// eslint-disable-next-line no-new
|
||||
new Filterizr('.filtr-publications', {
|
||||
layout: 'sameWidth',
|
||||
gridItemsSelector: '.pub-filtr-item',
|
||||
controlsSelector: '.pub-filtr-control'
|
||||
})
|
||||
}
|
||||
})
|
38
assets/scripts/sections/sidebar.js
Normal file
38
assets/scripts/sections/sidebar.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { getDeviceState } from '../core/device'
|
||||
|
||||
// Toggle sidebar on click. Here, class "hide" open the sidebar
|
||||
function toggleSidebar () {
|
||||
const sidebar = document.getElementById('sidebar-section')
|
||||
if (sidebar == null) {
|
||||
return
|
||||
}
|
||||
if (sidebar.classList.contains('hide')) {
|
||||
sidebar.classList.remove('hide')
|
||||
} else {
|
||||
// if toc-section is open, then close it first
|
||||
const toc = document.getElementById('toc-section')
|
||||
if (toc != null && toc.classList.contains('hide')) {
|
||||
toc.classList.remove('hide')
|
||||
}
|
||||
// add "hide" class
|
||||
sidebar.classList.add('hide')
|
||||
// if it is mobile device. then scroll to top.
|
||||
const { isMobile } = getDeviceState()
|
||||
if (isMobile && sidebar.classList.contains('hide')) {
|
||||
document.body.scrollTop = 0
|
||||
document.documentElement.scrollTop = 0
|
||||
if (document.getElementById('hero-area') != null) {
|
||||
document.getElementById('hero-area').classList.toggle('hide')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (document.getElementById('content-section') != null) {
|
||||
document.getElementById('content-section').classList.toggle('hide')
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
// bind click event to #sidebar-toggler in navbar-2.html
|
||||
const toggle = document.getElementById('sidebar-toggler')
|
||||
if (toggle) toggle.addEventListener('click', toggleSidebar)
|
||||
})
|
Loading…
Add table
Add a link
Reference in a new issue