PageSourceSearch

https://prashant.me/assets/js/main.js

js prashant.me collected 2026-09-25 21:49:57 UTC 9,455 bytes, 245 lines download raw bytes

1/**
2 * Copyright (c) Prashant Shrestha
3 * Developer: Prashant Shrestha (www.prashant.me)
4 */
5
6$(window).on('load', function () {
7    // What a pain, might move to vanilla JS.
8    $.ajaxSetup({ cache: false })
9
10    /* Images Lazy Load.
11    –––––––––––––––––––––––––––––––––––––––––––––––––– */
12    const observer = lozad('.lazy', {
13        loaded: (el) => {
14            el.src = el.dataset.src
15            el.onload = () => {
16                el.classList.add('fade')
17            }
18        },
19    })
20    observer.observe()
21
22    /* Theming - Light & Dark
23	–––––––––––––––––––––––––––––––––––––––––––––––––– */
24    let currentTheme = localStorage.getItem('theme')
25    // Set current theme if the theme data exists in LS.
26    if (currentTheme) {
27        document.documentElement.setAttribute('theme', currentTheme)
28        // Change lightbulb icon.
29        $('.site-theme-toggle .fa-lightbulb')
30            .removeClass('fas')
31            .removeClass('far')
32            .addClass(currentTheme === 'light' ? 'far' : 'fas')
33        // Change lightbulb's trigger title accordingly.
34        $('.site-theme-toggle .fa-lightbulb').prop(
35            'title',
36            currentTheme == 'light' ? 'Enable dark mode.' : 'Enable light mode.'
37        )
38    } else {
39        // If no values are set, just set dark as default.
40        currentTheme = 'light'
41        localStorage.setItem('theme', currentTheme)
42        document.documentElement.setAttribute('theme', currentTheme)
43        // Change lightbulb icon.
44        $('.site-theme-toggle .fa-lightbulb')
45            .removeClass('fas')
46            .removeClass('far')
47            .addClass(currentTheme === 'light' ? 'far' : 'fas')
48        // Change lightbulb's trigger title accordingly.
49        $('.site-theme-toggle .fa-lightbulb').prop(
50            'title',
51            currentTheme == 'light' ? 'Enable dark mode.' : 'Enable light mode.'
52        )
53    }
54
55    /* Smooth Scroll to anchor.
56	https://css-tricks.com/snippets/jquery/smooth-scrolling/
57	–––––––––––––––––––––––––––––––––––––––––––––––––– */
58    // Select all links with hashes
59    $('a[href^="#"]')
60        // Remove links that don't actually link to anything
61        .not('[href="#"]')
62        .not('[href="#0"]')
63        .click(function (event) {
64            // On-page links
65            if (
66                location.pathname.replace(/^\//, '') ==
67                    this.pathname.replace(/^\//, '') &&
68                location.hostname == this.hostname
69            ) {
70                // Figure out element to scroll to
71                var target = $(this.hash)
72                target = target.length
73                    ? target
74                    : $('[name=' + this.hash.slice(1) + ']')
75                // Does a scroll target exist?
76                if (target.length) {
77                    // Only prevent default if animation is actually gonna happen
78                    event.preventDefault()
79                    $('html, body').animate(
80                        {
81                            scrollTop: target.offset().top,
82                        },
83                        500,
84                        function () {
85                            // Callback after animation
86                            // Must change focus!
87                            var $target = $(target)
88                            $target.focus()
89                            if ($target.is(':focus')) {
90                                // Checking if the target was focused
91                                return false
92                            } else {
93                                $target.attr('tabindex', '-1') // Adding tabindex for elements not focusable
94                                $target.focus() // Set focus again
95                            }
96                        }
97                    )
98                }
99            }
100        })
101
102    /* Scroll to top button visibility toggling!
103	–––––––––––––––––––––––––––––––––––––––––––––––––– */
104    $(window).scroll(() => {
105        if ($(this).scrollTop()) {
106            $('.to-top').fadeIn()
107        } else {
108            $('.to-top').fadeOut()
109        }
110    })
111
112    /* Toggle theme
113	–––––––––––––––––––––––––––––––––––––––––––––––––– */
114    $('.site-theme-toggle').on('click', function (e) {
115        e.preventDefault()
116        // Try and get current theme (if exists in LS).
117        var currentTheme = localStorage.getItem('theme')
118        // Set theme value accordingly.
119        if (
120            currentTheme &&
121            (currentTheme == 'dark' || currentTheme == 'light')
122        ) {
123            document.documentElement.setAttribute(
124                'theme',
125                currentTheme == 'dark' ? 'light' : 'dark'
126            )
127            localStorage.setItem(
128                'theme',
129                currentTheme == 'dark' ? 'light' : 'dark'
130            )
131        } else {
132            // Other value for our theme = !dark, !light. Set to default light.
133            document.documentElement.setAttribute('theme', 'light')
134            localStorage.setItem('theme', 'light')
135        }
136
137        // Get updated theme value.
138        currentTheme = localStorage.getItem('theme')
139        // Change Icon of our lightbulb.
140        $('.site-theme-toggle .fa-lightbulb')
141            .removeClass('fas')
142            .removeClass('far')
143            .addClass(currentTheme === 'light' ? 'far' : 'fas')
144        // Change title value for our theme trigger.
145        $('.site-theme-toggle .fa-lightbulb').prop(
146            'title',
147            currentTheme == 'light' ? 'Enable dark mode.' : 'Enable light mode.'
148        )
149    })
150
151    /**
152     * Enabling highlight label.
153     */
154    var highlights = document.querySelectorAll(
155        'div[class^="language-"], figure[class="highlight"'
156    )
157    if (highlights.length > 0) {
158        Array.prototype.forEach.call(highlights, (block) => {
159            var splitted = block.getAttribute('class').split(' ')
160            var filtered = splitted.filter(
161                (_sp) => _sp.indexOf('language-') > -1
162            )
163            let language = filtered[0].split('-')[1] || 'Unknown'
164
165            var languageLabel = document.createElement('div')
166            languageLabel.className = 'language-label language-' + language
167            languageLabel.innerHTML = language
168            block.appendChild(languageLabel)
169        })
170    }
171
172    /**
173     * Custom search page functions
174     */
175    if (/search/.test(window.location.href)) {
176        $('button.clear').on('click', (e) => {
177            $('.search-input-text').val('')
178            $('.search-input-text').focus()
179            e.preventDefault()
180            return false
181        })
182
183        $('button.search').on('click', (e) => {
184            let searchKey = $('input.search-input-text').val()
185
186            // Search key should have the criteria of length >= 3.
187            if (searchKey.length >= 3) {
188                $.getJSON('search.json', function (data) {
189                    let searchResultsWithKey = data.filter((items) => {
190                        return (
191                            items.title
192                                .toLowerCase()
193                                .indexOf(searchKey.toLowerCase()) > -1
194                        )
195                    })
196
197                    // Found the results.
198                    if (searchResultsWithKey.length > 0) {
199                        $('.search-output')
200                            .empty()
201                            .append(
202                                `<h5>Found ${searchResultsWithKey.length} results.`
203                            )
204                        searchResultsWithKey.map((results) => {
205                            $('.search-output').append(
206                                '<a href="' +
207                                    results.url +
208                                    '">' +
209                                    results.title +
210                                    '</a>'
211                            )
212                        })
213                    } else {
214                        $('.search-output')
215                            .empty()
216                            .append('<h4>No blog posts found!</h4>')
217                    }
218                })
219            }
220            e.preventDefault()
221            return false
222        })
223
224        $('input.search-input-text').keypress(function (e) {
225            if (e.which == 13) {
226                // Enter key
227                $('button.search').click()
228            }
229        })
230        $('input.search-input-text').keyup(function (e) {
231            if (e.which == 27) {
232                // Escape key
233                $('button.clear').click()
234            }
235        })
236    }
237
238    /* Image Lightbox Initialization
239	–––––––––––––––––––––––––––––––––––––––––––––––––– */
240    $("a[data-rel^='lightcase']").lightcase({
241        maxWidth: '100%',
242    })
243
244    console.log('Loaded!')
245})

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.