1/** 2 * Rainmaker - Underscore.js Protection 3 * 4 * Protects WordPress Underscore.js from being overwritten by third-party 5 * scripts like SumoMe/BDOW (which bundles Lodash 4.x). 6 * 7 * Problem: SumoMe overwrites the global _ with Lodash 4.x, which removed 8 * the third "thisArg" parameter from _.each(), _.every(), _.some(), etc. 9 * This breaks Ninja Forms Conditional Logic which relies on that parameter. 10 */ 11( function( window, document ) { 12 'use strict'; 13 14 /* 15 * WP core also assigns its own Lodash 4.x to window._, but hands it back on 16 * the very next line through the inline `window.lodash = _.noConflict();` 17 * that follows the file. Blocking that assignment aborts the handshake and 18 * leaves window._ undefined, so no Ninja Form renders at all (sc-26068). 19 * Core's Lodash has to be let through; every other one is diverted. 20 */ 21 var CORE_LODASH_SRC = /\/wp-includes\/js\/dist\/vendor\/lodash(\.min)?\.js/; 22 23 function isLodashFour( value ) { 24 return !! value && 'string' === typeof value.VERSION && 0 === value.VERSION.indexOf( '4.' ); 25 } 26 27 var underscore = window._; 28 29 // Underscore was already overwritten before this ran and we never saw its 30 // reference, so leave the page alone rather than pin the wrong library. 31 if ( ! underscore || isLodashFour( underscore ) ) { 32 return; 33 } 34 35 var current = underscore; 36 37 window._lodash = window._lodash || null; 38 39 function isCoreLodash() { 40 var script = document.currentScript; 41 42 return !! script && !! script.src && CORE_LODASH_SRC.test( script.src ); 43 } 44 45 function handBackUnderscore() { 46 if ( isLodashFour( current ) ) { 47 current = underscore; 48 } 49 } 50 51 /* 52 * Optimizers can delay the inline handshake past the Lodash file, or drop 53 * it entirely. Waiting for DOMContentLoaded covers the delayed case â 54 * deferred scripts all run before it â and the never-runs case falls back 55 * to the timeout. 56 */ 57 function scheduleHandBack() { 58 if ( 'loading' === document.readyState ) { 59 document.addEventListener( 'DOMContentLoaded', handBackUnderscore ); 60 } else { 61 window.setTimeout( handBackUnderscore, 0 ); 62 } 63 } 64 65 try { 66 Object.defineProperty( window, '_', { 67 get: function() { 68 return current; 69 }, 70 set: function( value ) { 71 if ( isLodashFour( value ) ) { 72 /* 73 * Stash every Lodash 4, core included: besides keeping it 74 * reachable, this arms the window.lodash trap below â if a 75 * delayed handshake stores Underscore there after the 76 * hand-back, the substitution needs this reference. 77 */ 78 window._lodash = value; 79 80 if ( isCoreLodash() ) { 81 current = value; 82 83 // Hand Underscore back if the handshake never comes. 84 scheduleHandBack(); 85 } 86 87 return; 88 } 89 90 // Never let _ be cleared: an undefined _ breaks Ninja Forms just 91 // as badly as a Lodash one. 92 if ( value ) { 93 current = value; 94 } 95 }, 96 configurable: true 97 } ); 98 } catch ( e ) { 99 // window._ is already locked by another script, leave the page alone. 100 } 101 102 /* 103 * When a script aggregator repackages the page, the diverted Lodash never 104 * reaches the handshake and `window.lodash = _.noConflict();` stores 105 * Underscore instead â crashing Yoast and any other window.lodash consumer 106 * that runs before we could repair it. Trap window.lodash too: if something 107 * assigns a non-Lodash there while we hold a diverted Lodash 4, substitute 108 * the real one, synchronously. Deliberately clearing window.lodash (or a 109 * future non-4.x Lodash) gets substituted too while the stash is armed â 110 * accepted: that permissiveness is what makes the aggregate rescue work. 111 */ 112 var lodashGlobal = window.lodash; 113 114 try { 115 Object.defineProperty( window, 'lodash', { 116 get: function() { 117 return lodashGlobal; 118 }, 119 set: function( value ) { 120 if ( ! isLodashFour( value ) && isLodashFour( window._lodash ) ) { 121 value = window._lodash; 122 } 123 124 lodashGlobal = value; 125 }, 126 configurable: true 127 } ); 128 } catch ( e ) { 129 // Same as above: locked by another script, leave it alone. 130 } 131}( window, document ) );
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.