1/** 2 * Reduce Motion for Divi's same-page anchor scroll. 3 * 4 * Divi's scripts.min.js binds a click handler to every a[href*="#"]:not([href="#"]) 5 * and scrolls with window.et_pb_smooth_scroll( target, toTop, duration, easing ), a 6 * jQuery `html, body` animate of 800ms. It never checks prefers-reduced-motion, so 7 * with Reduce Motion on every same-page link still glides. Measured on production 8 * 2026-09-24: 766 to 800ms on the PDP #reviews and #allergen-declaration links and 9 * the landing-page hero buttons (Apple HIG review 2026-09-24, finding A15). 10 * 11 * Under Reduce Motion this passes a duration of 0, so the page jumps. The landing 12 * spot does not change, because Divi's own offset math still runs. Without Reduce 13 * Motion the call passes straight through. The setting is read on every call, so 14 * turning it on or off in the OS takes effect without a reload. 15 * 16 * Every Divi caller looks the function up as a global at call time, so wrapping the 17 * global covers all of them: anchor clicks, the scroll to a #hash after page load, 18 * the side nav and module links. The accessor wraps whatever Divi assigns, so this 19 * works whether it runs before or after scripts.min.js. 20 * 21 * Must not be delayed by WP Rocket (fix-rocket-js-dependencies.php), or the first 22 * anchor tap on a cold load would still glide. 23 */ 24( function () { 25 'use strict'; 26 27 if ( typeof window.matchMedia !== 'function' ) { 28 return; 29 } 30 var reduce = window.matchMedia( '(prefers-reduced-motion: reduce)' ); 31 32 function wrap( fn ) { 33 if ( typeof fn !== 'function' || fn.gerbsReducedMotion ) { 34 return fn; 35 } 36 var wrapped = function () { 37 var args = Array.prototype.slice.call( arguments ); 38 if ( reduce.matches ) { 39 args[ 2 ] = 0; 40 } 41 return fn.apply( this, args ); 42 }; 43 wrapped.gerbsReducedMotion = true; 44 return wrapped; 45 } 46 47 var current = wrap( window.et_pb_smooth_scroll ); 48 try { 49 Object.defineProperty( window, 'et_pb_smooth_scroll', { 50 configurable: true, 51 enumerable: true, 52 get: function () { 53 return current; 54 }, 55 set: function ( fn ) { 56 current = wrap( fn ); 57 }, 58 } ); 59 } catch ( e ) { 60 // A global declared with a top-level `var` is not configurable and cannot take 61 // an accessor. It is still writable, so wrap what is there now. 62 if ( current ) { 63 window.et_pb_smooth_scroll = current; 64 } 65 } 66}() );
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.