PageSourceSearch

https://aasifebiriyani.com/src/js/modules/testimonial_readmore.js?v=1790839790

js aasifebiriyani.com collected 2026-10-02 00:15:12 UTC 3,858 bytes, 95 lines download raw bytes

1'use strict';
2
3/**
4 * Testimonial "Read more" — companion to the .wla-testimonial-carousel widget
5 * (viewType 29). The body is CSS line-clamped to a fixed number of lines with a
6 * reserved min-height, so every slide is the same height and autoplay/scroll
7 * can't fluctuate the page. This module reveals the pre-rendered "Read more"
8 * button only on slides whose text actually overflows the clamp, toggles the
9 * `.is-expanded` state, pauses autoplay while a quote is open, and recollapses
10 * on slide change.
11 *
12 * Requires jQuery + slick (global, from base.php). Runs after slick_init.js.
13 */
14(function ($) {
15    if (typeof $ === 'undefined') return;
16
17    var SEL = '.wla-testimonial-carousel';
18
19    // Reveal/hide each body's button based on whether the clamped text overflows.
20    // Resets to collapsed first so re-runs (e.g. after a resize re-init, where the
21    // line count changes with width) re-measure cleanly.
22    function refresh($carousel) {
23        $carousel.find('.wla-testimonial__body').each(function () {
24            var body = this;
25            var $btn = $(body).siblings('.wla-testimonial__readmore');
26            body.classList.remove('is-expanded');
27            $btn.text('Read more').attr('aria-expanded', 'false');
28            var overflows = body.scrollHeight - body.clientHeight > 2;
29            $btn.toggleClass('is-on', overflows);
30        });
31        if ($carousel.hasClass('slick-initialized')) {
32            try { $carousel.slick('setPosition'); } catch (e) {}
33        }
34    }
35
36    function collapseAll($carousel) {
37        $carousel.find('.wla-testimonial__body.is-expanded').each(function () {
38            this.classList.remove('is-expanded');
39            $(this).siblings('.wla-testimonial__readmore')
40                .text('Read more').attr('aria-expanded', 'false');
41        });
42    }
43
44    function setup() {
45        $(SEL).each(function () {
46            var $c = $(this);
47            if ($c.data('tmReadmore')) { refresh($c); return; }
48            $c.data('tmReadmore', true);
49
50            refresh($c);
51
52            // Recollapse + resume autoplay whenever the slide changes.
53            $c.on('beforeChange', function () {
54                collapseAll($c);
55                if ($c.hasClass('slick-initialized')) {
56                    try { $c.slick('slickPlay'); } catch (e) {}
57                }
58            });
59        });
60    }
61
62    // Delegated toggle — survives slick's clone/re-init churn.
63    $(document).on('click', '.wla-testimonial__readmore', function () {
64        var $btn = $(this);
65        var body = $btn.siblings('.wla-testimonial__body')[0];
66        if (!body) return;
67        var $c = $btn.closest(SEL);
68        var expanded = body.classList.toggle('is-expanded');
69        $btn.text(expanded ? 'Read less' : 'Read more').attr('aria-expanded', String(expanded));
70        if ($c.hasClass('slick-initialized')) {
71            try { $c.slick(expanded ? 'slickPause' : 'slickPlay'); } catch (e) {}
72            try { $c.slick('setPosition'); } catch (e) {}
73        }
74    });
75
76    // Run after slick_init.js has booted the carousel. Both bind window.load;
77    // slick_init defers its .slick() call into a rAF, so wait two frames to be
78    // sure the carousel (and its clones) exist before we measure.
79    $(window).on('load', function () {
80        requestAnimationFrame(function () {
81            requestAnimationFrame(setup);
82        });
83    });
84
85    // After slick_init re-inits on resize (150ms debounce), re-measure since the
86    // wrapped line count — and thus what overflows — changes with viewport width.
87    var resizeTimer;
88    $(window).on('resize', function () {
89        clearTimeout(resizeTimer);
90        resizeTimer = setTimeout(function () {
91            $(SEL).each(function () { $(this).removeData('tmReadmore'); });
92            setup();
93        }, 300);
94    });
95})(window.jQuery);

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.