PageSourceSearch

https://www.psychiatrist.com/wp-content/plugins/simple-cloudflare-…/js/integrations/woocommerce.js?ver=1.9

js psychiatrist.com collected 2026-09-24 08:44:12 UTC 9,407 bytes, 226 lines download raw bytes

1/* Woo Checkout */
2( function () {
3
4    // perf.php excludes this file from "delay JavaScript" optimizers so the widget can appear
5    // without a user interaction. Those optimizers may therefore run it BEFORE jQuery, which is
6    // usually still delayed - and touching jQuery at eval time would throw, aborting this script
7    // and cascading into Woo's own delayed checkout scripts (breaking country/state switching and
8    // the order review refresh). So nothing here touches jQuery until it is known to exist, and
9    // everything that does not need jQuery runs independently of it.
10
11    var WIDGET_ID = 'cf-turnstile-woo-checkout';
12
13    function cfturnstileWooWidget() {
14        return document.getElementById( WIDGET_ID );
15    }
16
17    function cfturnstileWooOnReady( fn ) {
18        if ( document.readyState === 'loading' ) {
19            document.addEventListener( 'DOMContentLoaded', fn );
20        } else {
21            fn();
22        }
23    }
24
25    // Matches a delegated click without needing jQuery.
26    function cfturnstileWooClicked( e, selector ) {
27        return !!( e.target && e.target.closest && e.target.closest( selector ) );
28    }
29
30    // Explicit rendering ignores data-*-callback, which would leave the submit button disabled.
31    function cfturnstileWooOpts( target ) {
32        return ( typeof window.cfturnstileOpts === 'function' ) ? window.cfturnstileOpts( target ) : {};
33    }
34
35    /* Give the classic checkout widget a fresh token. Touches only the DOM and the global
36       `turnstile`, so it is safe to call at any point. */
37    function turnstileWooCheckoutReset() {
38        if ( typeof turnstile === 'undefined' ) {
39            return;
40        }
41
42        var el = cfturnstileWooWidget();
43        if ( !el ) {
44            return;
45        }
46
47        // Woo replaced the container and left it empty: render a new widget into it.
48        if ( !el.firstElementChild ) {
49            try { turnstile.render( el, cfturnstileWooOpts( el ) ); } catch ( e ) {}
50            return;
51        }
52
53        // Otherwise reset in place, which clears the used or expired token.
54        try {
55            turnstile.reset( el );
56            return;
57        } catch ( e ) {}
58
59        // reset() only fails when Turnstile no longer recognises the element, so rebuild it.
60        try { turnstile.remove( el ); } catch ( e ) {}
61        try { turnstile.render( el, cfturnstileWooOpts( el ) ); } catch ( e ) {}
62    }
63
64    /* "Show login" toggle: rebuild that widget once the panel is open. Bound natively on document
65       so it survives fragment refreshes and works whether or not jQuery has loaded. */
66    document.addEventListener( 'click', function ( e ) {
67        if ( !cfturnstileWooClicked( e, '.showlogin, .show-login, .e-show-login, .woocommerce-form-login-toggle a' ) ) {
68            return;
69        }
70        setTimeout( function () {
71            if ( typeof turnstile === 'undefined' ) {
72                return;
73            }
74            try { turnstile.remove( '.sct-woocommerce-login' ); } catch ( err ) {}
75            try { turnstile.render( '.sct-woocommerce-login', cfturnstileWooOpts( '.sct-woocommerce-login' ) ); } catch ( err ) {}
76        }, 250 );
77    } );
78
79    /* Classic checkout: keep the widget valid across Woo's fragment refreshes. Woo fires these as
80       jQuery custom events, so this is the one part that genuinely needs jQuery. */
81    function cfturnstileWooRun() {
82
83        var $ = window.jQuery;
84
85        $( document ).ready( function () {
86
87            var attempted = false;
88
89            function hasCheckoutError() {
90                return !!document.querySelector( '.woocommerce-error' );
91            }
92
93            // Only reset after a real submission attempt, not on every checkout refresh.
94            $( document.body ).on( 'submit', 'form.checkout', function () {
95                attempted = true;
96            } );
97
98            // Page loaded with an error already showing: the next submit needs a fresh token.
99            if ( hasCheckoutError() ) {
100                setTimeout( turnstileWooCheckoutReset, 50 );
101            }
102
103            $( document.body ).on( 'update_checkout updated_checkout applied_coupon_in_checkout removed_coupon_in_checkout', function () {
104                var el = cfturnstileWooWidget();
105
106                // Container was replaced or emptied: re-render once the DOM has settled.
107                if ( !el || !el.firstElementChild ) {
108                    setTimeout( turnstileWooCheckoutReset, 300 );
109                    return;
110                }
111
112                // Woo refreshes fragments after a failed submit; clear the used token.
113                if ( attempted && hasCheckoutError() ) {
114                    setTimeout( turnstileWooCheckoutReset, 300 );
115                    attempted = false;
116                }
117            } );
118
119            // Fired when the AJAX checkout submission comes back with an error.
120            $( document.body ).on( 'checkout_error', function () {
121                setTimeout( turnstileWooCheckoutReset, 500 );
122                attempted = false;
123            } );
124        } );
125    }
126
127    /* Woo Checkout Block. React based and needs nothing from jQuery, so it must not wait on a
128       jQuery that a delay-JS optimizer may only load on the first interaction. PHP does not emit
129       a render script for this widget on a block checkout, so this is what renders it. */
130    function cfturnstileWooBlockRun() {
131
132        // Guard against the classic (shortcode) checkout, which uses the same widget id - without
133        // this the block code would tear down and re-render the classic widget while wiring it to
134        // the block-only wc/store/checkout. wp.data is always defined (declared as a dependency).
135        if ( !document.querySelector( '.wp-block-woocommerce-checkout, .wc-block-checkout' ) || typeof wp === 'undefined' || !wp.data ) {
136            return;
137        }
138
139        function setExtensionData( token ) {
140            var dispatch = wp.data.dispatch( 'wc/store/checkout' );
141            if ( !dispatch ) {
142                return;
143            }
144            if ( typeof dispatch.setExtensionData === 'function' ) {
145                dispatch.setExtensionData( 'simple-cloudflare-turnstile', { token: token } );
146            } else if ( typeof dispatch.__internalSetExtensionData === 'function' ) {
147                dispatch.__internalSetExtensionData( 'simple-cloudflare-turnstile', { token: token } );
148            }
149        }
150
151        function renderBlockWidget() {
152            // The API is loaded with render=explicit and may still be in flight. Bail quietly -
153            // the subscription below runs on every cart change and calls back once it lands.
154            if ( typeof turnstile === 'undefined' ) {
155                return;
156            }
157
158            var el = cfturnstileWooWidget();
159            if ( !el ) {
160                return;
161            }
162
163            // Already up: reset in place, which clears the token but keeps the widget.
164            if ( el.getAttribute( 'data-sct-init' ) === 'true' && el.firstElementChild ) {
165                try {
166                    turnstile.reset( el );
167                    setExtensionData( '' );
168                    return;
169                } catch ( e ) {}
170            }
171
172            try { turnstile.remove( el ); } catch ( e ) {}
173
174            try {
175                turnstile.render( el, {
176                    sitekey: el.dataset.sitekey,
177                    appearance: el.dataset.appearance || 'always',
178                    callback: setExtensionData,
179                    'expired-callback': function () { setExtensionData( '' ); }
180                } );
181                el.setAttribute( 'data-sct-init', 'true' );
182            } catch ( e ) {}
183        }
184
185        // Refresh the token shortly after Place order is clicked.
186        var clickTimer = null;
187        document.addEventListener( 'click', function ( e ) {
188            if ( !cfturnstileWooClicked( e, '.wc-block-components-checkout-place-order-button' ) ) {
189                return;
190            }
191            clearTimeout( clickTimer );
192            clickTimer = setTimeout( renderBlockWidget, 2000 );
193        } );
194
195        // Render whenever the cart store changes and the widget is missing or uninitialised. This
196        // runs on every change, so test for a child element rather than serializing innerHTML.
197        wp.data.subscribe( function () {
198            var el = cfturnstileWooWidget();
199            if ( el && ( !el.firstElementChild || el.getAttribute( 'data-sct-init' ) !== 'true' ) ) {
200                renderBlockWidget();
201            }
202        }, 'wc/store/cart' );
203
204        renderBlockWidget();
205    }
206
207    // The block checkout needs no jQuery, so boot it as soon as the DOM is ready.
208    cfturnstileWooOnReady( cfturnstileWooBlockRun );
209
210    // The classic checkout handlers are jQuery based. When a delay-JS optimizer runs this file
211    // ahead of jQuery, poll for it (jQuery loads on the first interaction) instead of throwing.
212    if ( typeof window.jQuery !== 'undefined' ) {
213        cfturnstileWooRun();
214    } else {
215        var tries = 0;
216        var wait = setInterval( function () {
217            if ( typeof window.jQuery !== 'undefined' ) {
218                clearInterval( wait );
219                cfturnstileWooRun();
220            } else if ( ++tries > 1200 ) { // ~60s safety cap
221                clearInterval( wait );
222            }
223        }, 50 );
224    }
225
226} )();

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.