PageSourceSearch

https://ridekc.org/scripts/eTransit/main.js

js ridekc.org collected 2026-10-02 10:14:33 UTC 10,927 bytes, 326 lines download raw bytes

1var $toggleTrigger = $('[data-toggle_trigger]'),
2    $toggleContent = $('[data-toggle_content]'),
3    toggleTriggerCounter = 0,
4    $win = $(window),
5    $tpForm,
6    $tpFormOffset,
7    $tpFomrBottomPos,
8    $tpMap = $('.tp_map'),
9    $mapToggle = $('.map_expand'),
10    scrollPos = $win.scrollTop();
11
12if ($('.tp_sidebar').length) {
13    $tpForm = $('.tp_sidebar');
14    $tpFormOffset = $tpForm.length ? $tpForm.offset().top : null;
15    $tpFomrBottomPos = $tpForm.length ? $tpForm.offset().top + $tpForm.outerHeight(true) : null;
16}
17
18$win.on('resize', function () {
19    moveSaLink();
20});
21
22$win.on('scroll', function () {
23    scrollPos = $win.scrollTop();
24    if ($tpFormOffset <= scrollPos) {
25        $mapToggle.addClass('showB');
26    } else {
27        $mapToggle.removeClass('showB');
28        $tpMap.removeClass('show')
29    }
30});
31
32$mapToggle.on('click', function () {
33    $tpMap.toggleClass('show');
34});
35
36$toggleTrigger.each(function () {
37    var $this = $(this),
38        targetData = $this.data('toggle_trigger'),
39        triggerText = $.trim($this.text()).replace(/\s/g, '') + toggleTriggerCounter,
40        $target = $("[data-toggle_content='" + targetData + "']");
41
42    // Ensure non-button elements behave like buttons
43    if (!$this.is('button')) {
44        $this.attr({
45            'role': 'button',
46            'tabindex': '0'
47        });
48    }
49
50    $this.on('click', function (e) {
51        e.stopPropagation(); // Prevent bubbling to document
52
53        let isNested = $this.closest('[data-toggle_content].open').length > 0;
54
55        if (!$target.hasClass('open')) {
56            // Alert togglers do not close any other open accordions
57            if (!$target.hasClass('alert_toggled')) {
58                // Close other accordions only if the clicked one is not nested
59                if (!isNested) {
60                    $toggleTrigger.attr('aria-expanded', 'false').parent().removeClass('open');
61                    $toggleContent.removeClass('open')
62                        .attr('aria-hidden', 'true')
63                        .slideUp(250);
64                }
65            }
66
67            if ($target.hasClass('_grid')) {
68                $target.addClass('open')
69                    .attr('aria-hidden', 'false')
70                    .slideDown({
71                        start: function () {
72                            $(this).css({
73                                display: "flex"
74                            })
75                        }
76                    });
77
78            } else {
79                $target.addClass('open')
80                    .attr('aria-hidden', 'false')
81                    .slideDown(250);
82            }
83
84            // Open the clicked toggle
85            $this.attr('aria-expanded', 'true').parent().addClass('open');
86            $target.addClass('open');
87            //positionDropdown();
88            $target.attr('aria-hidden', 'false')
89                .slideDown(250);
90
91        } else {
92            // Close the current toggle
93            $this.attr('aria-expanded', 'false').parent().removeClass('open');
94            $target.removeClass('open')
95                .attr('aria-hidden', 'true')
96                .slideUp(250);
97
98        }
99    });
100
101    // Set roles for accessibility
102    $this.parent().attr('role', 'presentation');
103
104    // Add accessibility attributes to trigger
105    $this.attr({
106        'aria-expanded': 'false',
107        'id': triggerText,
108        'aria-controls': 'ctrl-' + triggerText,
109        'type': 'button'
110    });
111
112    // Add accessibility attributes to content
113    $target.attr({
114        'id': $this.attr('aria-controls'),
115        'role': 'region',
116        'aria-labelledby': $this.attr('id'),
117        'aria-hidden': 'true'
118    });
119
120    $(document).click(function (e) {
121        var $clickTarget = $(e.target);
122
123        // Ignore clicks inside the current trigger or its content panel.
124        if ($clickTarget.closest($this).length || $clickTarget.closest($target).length) {
125            return;
126        }
127
128        if ($target.is('.route_dd_list, .ru_toggle_item')) {
129            $this.attr('aria-expanded', 'false').parent().removeClass('open');
130            $target.removeClass('open')
131                .attr('aria-hidden', 'true')
132                .slideUp(250);
133        }
134    });
135
136    toggleTriggerCounter++;
137});
138
139// Open only the first trip accordion on load
140var $firstTripItem = $('.trip_item').first();
141if ($firstTripItem.length) {
142    var $firstTrigger = $firstTripItem.find('[data-toggle_trigger]').first(),
143        firstTargetData = $firstTrigger.data('toggle_trigger'),
144        $firstTarget = $firstTripItem
145            .find("[data-toggle_content='" + firstTargetData + "']")
146            .first();
147
148    if ($firstTrigger.length && $firstTarget.length) {
149        $firstTrigger
150            .attr('aria-expanded', 'true')
151            .parent()
152            .addClass('open');
153
154        $firstTarget
155            .removeAttr('hidden')
156            .addClass('open')
157            .attr('aria-hidden', 'false');
158
159        if ($firstTarget.hasClass('_grid')) {
160            $firstTarget.css('display', 'flex');
161        } else {
162            $firstTarget.show();
163        }
164    }
165}
166
167
168$('.exp_slider').slack({
169    variableWidth: false,
170    slidesToShow: 1,
171    dots: false
172});
173
174$('.s4_notif').slick({
175    dots: false,
176    arrows: true,
177    infinite: true
178});
179
180var $saLink = $('.sa_link'),
181    $saCount = $('.sa_count'),
182    $logo = $('#logo'),
183    headerHeight = $logo.outerHeight(true);
184
185function moveSaLink() {
186    if ($('#burgerNavStyle').css("display") === "block") {
187        headerHeight = $logo.outerHeight(true);
188        $saLink.show().css({
189            'padding': 0,
190            'position': 'absolute',
191            'top': 0,
192            'width': 'auto',
193            'right': 65 + 'px',
194            'height': headerHeight + 'px',
195            'display': 'flex',
196            'flex-direction': 'column',
197            'justify-content': 'center'
198        }).addClass('with_burg').insertBefore('#burgerNavStyle');
199    } else {
200        $saLink.removeAttr('style').removeClass('with_burg').appendTo('.sa_link_wrap');
201    }
202};
203moveSaLink();
204
205
206$(function () {
207    var $window = $(window);
208    var $header = $('#site-header');
209    var $originalWrap = $('.service_buttons_wrap');
210    var $stickyToggle = $('.sticky_service_toggle');
211    var $stickyButton = $stickyToggle.find('.service_buttons_toggle');
212    var $stickyListContainer = $stickyToggle.find('.service_buttons_list');
213
214    // Clone the original button list content into the sticky one
215    var $clonedList = $originalWrap.find('.service_buttons_list').clone(true, true);
216    $clonedList.removeAttr('hidden'); // Remove hidden attr since we'll use class-based visibility
217    $clonedList.removeAttr('id'); // Remove duplicate ID if necessary
218    $stickyListContainer.replaceWith($clonedList);
219
220    // Reassign the variable after replacement
221    $stickyListContainer = $stickyToggle.find('.service_buttons_list');
222
223    // Scroll check to determine when to show sticky toggle
224    function checkVisibility() {
225        var headerHeight = $header.outerHeight();
226        var wrapTop = $originalWrap.offset() ? $originalWrap.offset().top : 0;
227        var wrapBottom = wrapTop + $originalWrap.outerHeight();
228        var scrollTop = $window.scrollTop();
229
230        // If we've scrolled past the bottom of the original button block (with header offset)
231        if (scrollTop + headerHeight >= wrapBottom) {
232            $stickyToggle.attr('aria-hidden', 'false');
233        } else {
234            $stickyToggle.attr('aria-hidden', 'true');
235            $stickyButton.attr('aria-expanded', 'false');
236            $stickyListContainer.removeClass('show');
237        }
238    }
239
240    // Toggle the buttons panel when clicking the toggle button
241    $stickyButton.on('click', function () {
242        var isExpanded = $(this).attr('aria-expanded') === 'true';
243        var $list = $stickyToggle.find('.service_buttons_list');
244
245        $(this).attr('aria-expanded', String(!isExpanded));
246
247        if (!isExpanded) {
248            // Opening: add show class to trigger CSS transition
249            $list.addClass('show');
250        } else {
251            // Closing: remove show class
252            $list.removeClass('show');
253        }
254    });
255    
256    $(document).on('click', function (e) {
257        var $target = $(e.target);
258        var isInside = $target.closest('.sticky_service_toggle').length > 0;
259
260        if (!isInside) {
261            var isExpanded = $stickyButton.attr('aria-expanded') === 'true';
262
263            if (isExpanded) {
264                $stickyButton.attr('aria-expanded', 'false');
265                $stickyListContainer.removeClass('show');
266            }
267        }
268    });
269    // Run scroll check on page load and scroll/resize
270    $window.on('scroll resize', checkVisibility);
271    checkVisibility();
272});
273
274const $el = $('.firstRow_pod [data-slick]'); // adjust selector as needed
275
276document.querySelectorAll('.wrap-slash').forEach(el => {
277    el.innerHTML = el.textContent.replace(/\//g, '/<wbr>');
278});
279
280// --- Timetable sticky first-column top scrollbar sync ---
281(function () {
282    function initTtScrollSync(tripTable) {
283        var scroller = tripTable.querySelector('.table_scroller');
284        var scrollerTop = tripTable.querySelector('.table_scroller_top');
285        var scrollerTopInner = tripTable.querySelector('.table_scroller_top_inner');
286        var table = tripTable.querySelector('.tt_actual');
287        if (!scroller || !scrollerTop || !scrollerTopInner || !table) return;
288        if (scroller._ttSyncInit) return;
289        scroller._ttSyncInit = true;
290
291        function syncWidth() {
292            scrollerTopInner.style.width = table.scrollWidth + 'px';
293        }
294        syncWidth();
295
296        var syncing = false;
297        scroller.addEventListener('scroll', function () {
298            if (!syncing) { syncing = true; scrollerTop.scrollLeft = scroller.scrollLeft; syncing = false; }
299        });
300        scrollerTop.addEventListener('scroll', function () {
301            if (!syncing) { syncing = true; scroller.scrollLeft = scrollerTop.scrollLeft; syncing = false; }
302        });
303
304        new ResizeObserver(syncWidth).observe(table);
305    }
306
307    // Init any trip_table already visible on load (first-opened accordions)
308    document.querySelectorAll('.trip_table').forEach(function (tt) {
309        if (tt.offsetParent !== null) {
310            initTtScrollSync(tt);
311        }
312    });
313
314    // Watch for trip_tables that become visible when accordions are opened
315    var observer = new MutationObserver(function (mutations) {
316        mutations.forEach(function (m) {
317            var tt = m.target;
318            if (tt.classList && tt.classList.contains('trip_table') && tt.style.display !== 'none' && tt.style.display !== '') {
319                initTtScrollSync(tt);
320            }
321        });
322    });
323    document.querySelectorAll('.trip_table').forEach(function (tt) {
324        observer.observe(tt, { attributes: true, attributeFilter: ['style'] });
325    });
326}());

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.