PageSourceSearch

https://cosmos-hotel.com.tw/wp-content/plugins/de-builder-evo-bloc…/assets/js/a11y_patches.js?ver=1.0.2

js cosmos-hotel.com.tw collected 2026-09-26 07:33:59 UTC 9,370 bytes, 246 lines download raw bytes

1(function ($) {
2
3    function itemsHn() {
4        //things that shouldn't be a title
5        $('h2:has(+ h1), h1 + h2, h3:has(+ h2), h2 + h3').attr('role', 'generic');
6
7        //things that have to be a title
8        $('.title:not(.content_wrap, .no_aria, h1)').each(function () {
9            var ancestor = $(this).parents('.de_block, #slideshow-1');
10
11            if (ancestor.attr('id') !== 'slideshow-1') {
12
13                var mainTitle = ancestor.find('h2');
14                var lvl = mainTitle.length > 0 ? '3' : '2';
15                var txt = $(this).text();
16                $(this).empty();
17                $(this).append('<span class="aria-title" role="heading" aria-level="' + lvl + '">' + txt + '</span>')
18
19            } else {
20                $(this).attr('role', 'generic')
21            }
22
23        });
24    }
25
26    function slickArrows() {
27        $('.slick-arrow').each(function () {
28            $(this).attr('role', 'button');
29            $(this).addClass('link_button');
30            if ($(this).hasClass('prev')) {
31                $(this).attr('aria-label', a11yPatchesStrings.prev);
32            } else {
33                $(this).attr('aria-label', a11yPatchesStrings.next);
34            }
35        });
36
37        $('.slick-initialized').each(function () {
38            var wrap = $(this);
39            var controls = wrap.parent().find('.slick-dots button, .slick-arrow');
40            var items = wrap.find(' .slick-slide:not(.slick-cloned)');
41            var total = items.length;
42            var liveRegion = wrap.find('span.slick-live-region');
43
44            if (liveRegion.length === 0) {
45                wrap.append('<span class="sr-only slick-live-region" aria-live="polite"></span>');
46            }
47
48            //sometimes controls are not in the parent (ex offers_carousel)
49            console.log(wrap.parent());
50            if (controls.length === 0 && !wrap.parent().hasClass('slideshow_container')) {
51                controls = wrap.parent().parent().find('.slick-dots button, .slick-arrow');
52            }
53
54            controls.on('click', function () {
55
56                var iterator = parseInt(wrap.find('.slick-current').attr('data-slick-index')) + 1;
57                var label = iterator + '/' + total;
58                label += wrap.find('.slick-current .title').eq(0).text() !== '' ? ' - ' + wrap.find('.slick-current .title').eq(0).text() : '';
59                label += wrap.find('.slick-current .price_wrap').eq(0).text() !== '' ? '. ' + wrap.find('.slick-current .price_wrap').eq(0).text() : '';
60
61                wrap.find('span.slick-live-region').empty();
62                wrap.find('span.slick-live-region').text(label);
63
64                setTimeout(function () {
65                    redundantLinks();
66                }, 1000);
67
68            });
69
70            items.each(function () {
71                var iterator = parseInt($(this).attr('data-slick-index')) + 1;
72                var labelGroup = iterator + '/' + total;
73                $(this).attr('role', 'group');
74                $(this).attr('aria-label', labelGroup);
75            });
76
77        })
78    }
79
80    function readMore() {
81        var links = $('.read_more, .info, .pop_up')
82        links.each(function () {
83            var link = $(this);
84            if (!link.is('a')) {
85                link = $(this).find('> a');
86            }
87            if (link.attr('href') === '#') {
88                link.attr('role', 'button');
89            }
90            var title = link.closest('.item_wrap').find('.title').eq(0).text();
91            var label = link.text() + ' ' + a11yPatchesStrings.about + ' ' + title;
92            link.attr('aria-label', label);
93        });
94    }
95
96    function redundantLinks() {
97        $('a.thumb, a.plus_corner:not(.description)').each(function () {
98            $(this).attr('tabindex', '-1');
99            $(this).attr('aria-hidden', 'true');
100        });
101        $('a:has(.aria-title):not([aria-expanded]), a.price_wrap').each(function () {
102            $(this).attr('tabindex', '-1');
103        });
104    }
105
106    function buttonFix() {
107        const body = $('body');
108        body.keydown(function (e) {
109            let isSupposedToBeAButton = $(e.target).is('.link_button[role="button"]');
110            if ((e.keyCode === 32 || e.keyCode === 13) && isSupposedToBeAButton) {
111                e.preventDefault();
112            }
113            if (e.keyCode === 32 && isSupposedToBeAButton) {
114                $(e.target).click();
115            }
116
117        });
118        body.keyup(function (e) {
119            let isSupposedToBeAButton = $(e.target).is('.link_button[role="button"]');
120            if ((e.keyCode === 32 || e.keyCode === 13) && isSupposedToBeAButton) {
121                e.preventDefault();
122            }
123            if (e.keyCode === 13 && isSupposedToBeAButton) {
124                $(e.target).click();
125            }
126        });
127    }
128
129
130    $(document).ready(function () {
131        itemsHn();
132        slickArrows();
133        readMore();
134        redundantLinks();
135        buttonFix();
136    });
137
138    $(window).on('load', function () {
139        itemsHn();
140        slickArrows();
141        readMore();
142        redundantLinks();
143        buttonFix();
144    });
145
146    //webSdk offers block
147    $('.offers_carousel > div, .offers_grid > div').on('builder_offers_ready', function () {
148        itemsHn();
149        readMore();
150        setTimeout(function () {
151            slickArrows();
152            redundantLinks();
153            buttonFix();
154        }, 1000);
155    });
156
157    $('div[data-websdk="Offers"][id^="room_"]').on('builder_offers_ready', function (e) {
158        redundantLinks();
159        var target = $(e.target);
160        var card = target.closest('.slick-slide');
161        if (card.attr('aria-hidden') === 'true') {
162            target.find('a').attr('tabindex', '-1');
163        }
164        setTimeout(function () {
165            if (card.attr('aria-hidden') === 'true' && card.hasClass('.slick-cloned')) {
166                card.find('div[data-websdk="Offers"][id^="room_"] a').attr('tabindex', '-1');
167            }
168
169        }, 1000);
170    });
171
172    //some fix for gform
173    $(document).on('gform_post_render', function (event, form_id, current_page) {
174        //add reference to error message via aria-describeby
175        var fields = $('#gform_' + form_id + ' .gfield');
176        var submit = $('#gform_submit_button_' + form_id);
177        var captcha = $('#gform_' + form_id + ' .ginput_recaptcha');
178        var iframe = captcha.find('iframe');
179
180        fields.each(function () {
181            field = $(this);
182            var input = field.find('input, select, textarea');
183            input.removeAttr('tabindex');
184            if (input.attr('aria-invalid') === 'true') {
185                var id = field.attr('id').replace('field_', '');
186                input.attr('aria-describedby', 'validation_message_' + id);
187            }
188        });
189        submit.removeAttr('aria-label');
190        submit.removeAttr('tabindex');
191        //bloody captcha
192        captcha.removeAttr('data-tabindex');
193        iframe.removeAttr('tabindex');
194        if (captcha.parent().hasClass('gfield_error')) {
195            var id = field.attr('id').replace('field_', '');
196            captcha.attr('aria-describedby', 'validation_message_' + id);
197            iframe.removeAttr('tabindex');
198
199        }
200
201        submit.on('click', function () {
202            $(this).attr('aria-label', a11yPatchesStrings.submit);
203        });
204
205        //focus on error/success message after validation
206        var error = $('*[id^=input_' + form_id + '][aria-invalid=true], ' +
207            '.gfield_error .clear-multi input[id^=input_' + form_id + '],' +
208            '.gfield_error .gfield_checkbox input[id^=choice_' + form_id + '],' +
209            '.gfield_error .ginput_recaptcha[id^=input_' + form_id + ']').eq(0);
210
211
212        if (error.length > 0) {
213            //damned captcha
214            if (error.hasClass('ginput_recaptcha')) {
215                error.attr('tabindex', '-1');
216            }
217            //bloody multi input field
218            if (error.parent().hasClass('clear-multi')) {
219                error.attr('aria-describedby', 'validation_message_' + error.attr('id').replace('input_', ''));
220            }
221            error.focus();
222        }
223
224        //goddam datepicker I hate it
225        $('.hidden_fancybox:visible').find('.hasDatepicker').on('focus', function () {
226            var dp = $('#ui-datepicker-div');
227            dp.css('position', 'fixed');
228            dp.css('top', $(this)[0].offsetTop + $(this)[0].offsetHeight + $('.hidden_fancybox:visible')[0].offsetTop + 'px');
229            dp.css('left', $(this)[0].offsetLeft + $('.hidden_fancybox:visible').offsetLeft + 'px');
230            if (($(this)[0].offsetTop + $(this)[0].offsetHeight + dp.height()) > window_height) {
231                dp.css('transform', 'translateY(calc(-100% - ' + $(this)[0].offsetHeight + 'px)');
232            }
233        });
234    });
235
236    $(document).on('gform_confirmation_loaded', function (event, formId) {
237        var success = $('.gform_confirmation_wrapper');
238        if (success.length > 0) {
239            success.attr('tabindex', '-1');
240            success.focus();
241        }
242
243    });
244
245
246}(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.