1/* global monsterinsights_user_journey */ 2 3'use strict'; 4 5/** 6 * MonsterInsights User Journey function. 7 * 8 * @since 1.0.0 9 */ 10var MonsterInsightsUserJourney = window.MonsterInsightsUserJourney || ( function( document, window ) { 11 12 /** 13 * Public functions and properties. 14 * 15 * @since 1.0.0 16 * 17 * @type {object} 18 */ 19 var app = { 20 21 /** 22 * Start the engine. 23 * 24 * @since 1.0.0 25 */ 26 init: function() { 27 28 if ( ! String.prototype.startsWith ) { 29 Object.defineProperty( 30 String.prototype, 31 'startsWith', 32 { 33 value: function( search, rawPos ) { 34 var pos = rawPos > 0 ? rawPos | 0 : 0; 35 return this.substring( pos, pos + search.length ) === search; 36 }, 37 } 38 ); 39 } 40 41 var timeStamp = Math.round( Date.now() / 1000 ), 42 cookie = app.getCookie( '_monsterinsights_uj' ), 43 data = {}, 44 url = window.location.href; 45 46 if ( ! cookie && document.referrer !== '' && ! document.referrer.startsWith( window.location.origin ) ) { 47 data[ timeStamp - 2 ] = document.referrer + '|#|{ReferrerPageTitle}'; 48 } 49 50 url += '|#|' + document.title; 51 52 if ( typeof monsterinsights_user_journey !== 'undefined' && monsterinsights_user_journey.page_id ) { 53 url += '|#|' + Number( monsterinsights_user_journey.page_id ); 54 } 55 56 if ( cookie ) { 57 data = JSON.parse( cookie ); 58 } 59 60 var encodedUrl = encodeURIComponent( url ); 61 var latestTimeStamp = app.getLatestTimeStamp( data ); 62
63 // Do not add info about the same page on reload. 64 if ( data[latestTimeStamp] !== encodedUrl ) { 65 data[timeStamp] = encodedUrl; 66 } 67 68 // Max Cookie length is 4096 bytes. We add less than 100 bytes of supplemental info to the journey data object. 69 var maxDataLength = 4096 - 100; 70 71 var dataString = JSON.stringify( data ); 72 73 // If cookie info exceeds the max length, cookie will not be updated anymore. 74 // So, we have to delete the oldest info from the journey object. 75 while ( dataString.length > maxDataLength ) { 76 delete data[ app.getEarliestTimeStamp( data ) ]; 77 dataString = JSON.stringify( data ); 78 } 79 80 app.createCookie( '_monsterinsights_uj', JSON.stringify( data ), 365 ); 81 }, 82 83 /** 84 * Create cookie. 85 * We can't use this method from monsterinsights because this script must load on each page. 86 * 87 * @since 1.0.0 88 * 89 * @param {string} name Cookie name. 90 * @param {string} value Cookie value. 91 * @param {string} days Whether it should expire and when. 92 */ 93 createCookie: function( name, value, days ) { 94 95 var expires = ''; 96 var secure = ''; 97 98 if ( monsterinsights_user_journey.is_ssl ) { 99 secure = ';secure'; 100 } 101 102 // If we have a days value, set it in the expiry of the cookie. 103 if ( days ) { 104 105 // If -1 is our value, set a session based cookie instead of a persistent cookie. 106 if ( '-1' === days ) { 107 expires = ''; 108 } else { 109 var date = new Date(); 110 date.setTime( date.getTime() + ( days * 24 * 60 * 60 * 1000 ) ); 111 expires = ';expires=' + date.toGMTString(); 112 } 113 } else { 114 expires = ';expires=Thu, 01 Jan 1970 00:00:01 GMT'; 115 } 116 117 // Write the cookie. 118 document.cookie = name + '=' + value + expires + ';path=/;samesite=strict' + secure; 119 }, 120 121 /** 122 * Retrieve cookie. 123 * We can't use this method from monsterinsights because this script must load on each page. 124 * 125 * @since 1.0.0 126 * 127 * @param {string} name Cookie name. 128 * 129 * @returns {string|null} Cookie value or null when it doesn't exist. 130 */ 131 getCookie: function( name ) { 132 133 var nameEQ = name + '=', 134 ca = document.cookie.split( ';' ); 135 136 for ( var i = 0; i < ca.length; i++ ) { 137 var c = ca[i]; 138 while ( ' ' === c.charAt( 0 ) ) { 139 c = c.substring( 1, c.length ); 140 } 141 if ( 0 === c.indexOf( nameEQ ) ) { 142 return c.substring( nameEQ.length, c.length ); 143 } 144 } 145 146 return null; 147 }, 148 149 /** 150 * Get the earliest timestamp from data object. 151 * 152 * @param {object} data Data object containing journey info. 153 * @returns {string} The earliest timestamp. 154 */ 155 getEarliestTimeStamp: function( data ) { 156 let timeStamps = Object.keys( data ).map( timeStamp => parseInt( timeStamp, 10 ) ); 157 158 return Math.min( ...timeStamps ).toString(); 159 }, 160 161 /** 162 * Get the latest timestamp from data object. 163 * 164 * @param {object} data Data object containing journey info. 165 * @returns {string} The latest timestamp. 166 */ 167 getLatestTimeStamp: function( data ) { 168 let timeStamps = Object.keys( data ).map( timeStamp => parseInt( timeStamp, 10 ) ); 169 170 return Math.max( ...timeStamps ).toString(); 171 }, 172 173 }; 174 175 // Provide access to public functions/properties. 176 return app; 177 178}( document, window ) ); 179 180// Initialize. 181MonsterInsightsUserJourney.init();
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.