1/** 2 * Cookie handler frontend script. 3 * Avoid caching of conditional content and hidden fields if they use url-params or cookies 4 */ 5 6window.addEventListener('load', (event) => { 7 8 // get elements 9 var conditionElements = document.querySelectorAll( ".wp-block-greyd-conditional-content[data-harden-conditions]" ); 10 var fieldElements = document.querySelectorAll( "form [data-harden-field]" ); 11 var liveFieldElements = document.querySelectorAll( "form [data-live-field]" ); 12 // console.log( conditionElements, fieldElements ); 13 if ( 14 ( !conditionElements || conditionElements.length == 0 ) && 15 ( !fieldElements || fieldElements.length == 0 ) && 16 ( !liveFieldElements || liveFieldElements.length == 0 ) 17 ) { 18 // console.info("exit"); 19 return; 20 } 21 22 /** 23 * Match condition. 24 * 25 * @param string is Current value. 26 * @param string should What the value should be. 27 * @param string condition Actual condition. 28 * @returns bool 29 */ 30 const matchCondition = function( is, should, condition = 'is' ) { 31 32 // sanitize 33 is = !is ? "" : (""+is+"").trim(); 34 should = !should ? "" : (""+should+"").trim(); 35 36 if ( condition === 'is' ) { 37 return should === is; 38 } 39 else if ( condition === 'is_not' ) { 40 return should !== is; 41 } 42 else if ( condition === 'has' ) { 43 return is.indexOf( should ) > -1; 44 } 45 else if ( condition === 'has_not' ) { 46 return is.indexOf( should ) == -1; 47 } 48 else if ( condition === 'empty' ) { 49 return is === ""; 50 } 51 else if ( condition === 'not_empty' ) { 52 return is !== ""; 53 } 54 return false; 55 56 }; 57 58 /** 59 * Check conditions. 60 * 61 * @param array conditions Array of conditions. 62 * @param object data All url params and cookie values. 63 */ 64 const checkConditions = function( conditions, data ) { 65 66 // check input 67 if ( !conditions || conditions.length == 0 ) { 68 return; 69 } 70 71 conditions.forEach( elementConditions => { 72 73 if ( !elementConditions || elementConditions.length == 0 ) { 74 return; 75 } 76 77 var results = []; 78 elementConditions.forEach( condition => { 79 80 var key = condition.detail; 81 var values = {}; 82 if ( condition.type == 'localStorage' ) { 83 values = localStorage; 84 } 85 else if ( condition.type == 'urlparam' || condition.type == 'cookie' ) { 86 values = condition.type == 'urlparam' ? data.url_values : data.cookie_values; 87 if ( key == 'custom' ) { 88 key = condition.custom; 89 values = condition.type == 'urlparam' ? data.all_url_values : data.all_cookie_values; 90 } 91 } 92 // console.log(key, values); 93 94 var is = values[key] ? values[key] : null; 95 var match = matchCondition( is, condition.value, condition.operator ); 96 results.push( match ); 97 98 } ); 99 100 var operator = elementConditions[0].mainoperator ?? "OR"; 101 var id = elementConditions[0].id; 102 // console.log(results, operator, id); 103 var final = operator === "OR" ? results.indexOf( true ) > -1 : results.indexOf( false ) === -1; 104 if ( final ) { 105 // console.log( "condition "+id+" should be visible" ); 106 var element = document.getElementById( id ); 107 if ( element ) element.style.display = 'block'; 108 } 109 else { 110 // console.log( "condition "+id+" should NOT be visible" ); 111 var element = document.getElementById( id ); 112 if ( element ) element.remove(); 113 } 114 115 } ); 116 117 }; 118 119 /** 120 * Check hidden form fields. 121 * 122 * @param array fields Array of fields. 123 * @param object data All url params and cookie values. 124 */ 125 const checkHiddenFields = function( fields, data ) { 126 127 // check input 128 if ( !fields || fields.length == 0 ) { 129 return; 130 } 131 132 fields.forEach( field => { 133 // console.log(field); 134 135 var value = ''; 136 if ( field.type == 'url' ) { 137 value = window.location.origin+window.location.pathname; 138 } 139 else if ( field.type == 'live_url' ) { 140 value = window.location.href; 141 } 142 else { 143 var key = field.name; 144 var values = field.type == 'cookie' ? data.all_cookie_values : data.all_url_values; 145 value = values[key] ? values[key] : field.default; 146 } 147 148 // console.log( "field "+field.id+" should be "+value ); 149 var element = document.getElementById( field.id ); 150 if ( element ) { 151 element.value = value; 152 // trigger change event 153 element.dispatchEvent( new Event( 'change' ) ); 154 } 155 156 } ); 157 158 }; 159 160 /** 161 * Get all url params and cookie values from rest. 162 * 163 * @returns array 164 */ 165 const getValues = async function() { 166 167 // get all url params to send them with the api request 168 var urlparams = new URLSearchParams( window.location.search );
169 urlparams = Object.fromEntries( urlparams.entries() ); 170 171 // get all url params and cookie values from rest and re-check conditions 172 return fetch( greyd.rest_api.root + 'greyd/v1/get_url_and_cookie_values', { 173 method: 'POST', 174 headers: { 175 'Content-Type': 'application/json', 176 }, 177 body: JSON.stringify( { 178 urlparams: urlparams, 179 } ), 180 } ).then( ( res ) => { 181 // console.log( res ); 182 // get json response 183 return res.json(); 184 } ).then( ( data ) => { 185 // console.log( 'url_and_cookie_values:', data ); 186 // handle success/error 187 if ( 188 data && 189 data.url_values && data.all_url_values && 190 data.cookie_values && data.all_cookie_values 191 ) { 192 return data; 193 } 194 return Promise.reject( 'response not valid' ); 195 } ).catch( ( err ) => { 196 // log error 197 console.error( "fetch error: ", err ); 198 } ); 199 200 }; 201 202 /** 203 * Get data from Elements. 204 * 205 * @param nodeList elements List of dom elements. 206 * @param string attribute Name of the data attribute to get data from. 207 * @returns array 208 */ 209 const getData = function( elements, attribute ) { 210 211 if ( !elements || elements.length == 0 || attribute == "" ) { 212 return false; 213 } 214 215 var result = []; 216 217 // console.log(elements); 218 if ( elements && elements.length > 0 ) { 219 elements.forEach( element => { 220 // console.log(element); 221 try { 222 var value = element.getAttribute(attribute); 223 var json = JSON.parse( value ); 224 result.push( json ); 225 } 226 catch {} 227 element.removeAttribute(attribute); 228 } ); 229 result = result.filter( item => item ); 230 } 231 if ( !result || result.length == 0 ) { 232 return false; 233 } 234 return result; 235 236 } 237 238 239 // get conditions and hidden fields data 240 var conditions = getData( conditionElements, "data-harden-conditions" ); 241 var hiddenFields = getData( fieldElements, "data-harden-field" ); 242 if ( conditions || hiddenFields ) { 243 244 // get url and cookie values, then check 245 // console.groupCollapsed("sending rest request ..."); 246 // if ( conditions ) console.log("hardening conditions"); 247 // if ( hiddenFields ) console.log("hardening hidden fields"); 248 // console.groupEnd(); 249 getValues().then( ( data ) => { 250 if ( data ) { 251 // console.info("rest data received"); 252 checkConditions( conditions, data ); 253 checkHiddenFields( hiddenFields, data ); 254 } 255 } ); 256 257 } 258 259 // get hidden fields (of type 'live_url') data 260 var liveFields = getData( liveFieldElements, "data-live-field" ); 261 if ( liveFields ) { 262 263 // check/fill field initially 264 checkHiddenFields( liveFields, {} ); 265 266 // listen for change of url 267 window.addEventListener("hashchange", function() { 268 // console.log(window.location.href); 269 checkHiddenFields( liveFields, {} ); 270 }); 271 272 } 273 274} );
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.