1"use strict"; 2 3window.metoffice.getSiteControl_widgetSelect = function(config) { 4 const ONE_YEAR_MILLIS = 3.154e+10; 5 const getCookie = function(name) { 6 const value = `; ${document.cookie}`; 7 const parts = value.split(`; ${name}=`); 8 return (parts.length === 2) ? parts.pop().split(';').shift() : null; 9 }; 10 let gscStateJson = getCookie("mo-gsc-state"); 11 let gscState = {}; 12 if (gscStateJson != null) { 13 gscState = JSON.parse(decodeURIComponent(gscStateJson)); 14 } 15 16 // Populate state with new items that may not yet exist... 17 let configItemIDs = new Set(); 18 let newConfigItemIDs = new Set(); 19 config.forEach((itm) => { 20 if (gscState[itm.id] == undefined) { 21 gscState[itm.id] = { 22 rnd: Math.floor(Math.random() * 10000) / 100 23 } 24 newConfigItemIDs.add(itm.id); 25 } 26 configItemIDs.add(itm.id); 27 }); 28 29 // For new items, If previous cookies exist, include them 30 newConfigItemIDs.forEach(function(key) { 31 if (document.cookie.includes(`mo-getsitecontrol-${key}=true;`)) { 32 gscState[key].rnd = 0; 33 gscState[key].migrated=true; 34 35 } else if (document.cookie.includes(`mo-getsitecontrol-${key}=false;`)) { 36 gscState[key].rnd = 100; 37 gscState[key].migrated=true; 38 } 39 }); 40 41 // Remove those that no longer exist. 42 Object.keys(gscState).forEach(function(key) { 43 if (!configItemIDs.has(key)) { 44 delete gscState[key]; 45 } 46 }); 47 48 document.cookie = 'mo-gsc-widget=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; 49 50 // Build list of get site control widgets that are applicable to be shown on this page.. 51 let percentageOfUsersCheck = (itm) => itm.percentageOfUsers > gscState[itm.id].rnd; 52 53 let pathIncludesCheck = (itm) => itm.pathIncludes == null ? false : 54 Array.isArray(itm.pathIncludes) ? 55 itm.pathIncludes.find((pathIncludes) => window.location.pathname.match('^' + pathIncludes.replace('*', '.*') + '$')) != undefined : 56 window.location.pathname.match('^' + itm.pathIncludes.replace('*', '.*') + '$'); 57 58 let pathExcludesCheck = (itm) => itm.pathExcludes == null ? true : 59 Array.isArray(itm.pathExcludes) ? 60 itm.pathExcludes.find((pathExcludes) => window.location.pathname.match('^' + pathExcludes.replace('*', '.*') + '$')) == undefined : 61 !window.location.pathname.match('^' + itm.pathExcludes.replace('*', '.*') + '$'); 62 63 let hostCheck = (itm) => itm.host == null ? true : 64 Array.isArray(itm.host) ? 65 itm.host.find((host) => window.location.hostname.match('^' + host.replace('*', '.*') + '$')) != undefined : 66 window.location.hostname.match('^' + itm.host.replace('*', '.*') + '$'); 67 68 let conditionCheck = (itm) => 69 !((typeof itm.condition == 'boolean' && itm.condition === false) || 70 (typeof itm.condition == 'function' && itm.condition() === false)); 71 72 let getSiteControlItems = []; 73 config.forEach((itm) => { 74 let applicable = 75 pathIncludesCheck(itm) && 76 pathExcludesCheck(itm) && 77 hostCheck(itm) && 78 conditionCheck(itm); 79 80 if (!applicable) { 81 return; 82 } 83 84 // if NOT included in the percentage of users, return 85 // but remove firstShown incase percentages were lowered temporarily, 86 // and when raised again in future, want to re-show the popup, without it have becomming timed out. 87 if (!percentageOfUsersCheck(itm)) { 88 delete gscState[itm.id].firstShown; 89 return; 90 }; 91 92 93 // If widget has already been showing for more than 2 weeks (or item.timeOut), dont add. 94 if (gscState[itm.id].firstShown != undefined) { 95 let firstShownTime = new Date(gscState[itm.id].firstShown); 96 let diffDays = Math.floor((new Date() - firstShownTime) / (1000 * 60 * 60 * 24)); 97 let timeOutDays = (itm.timeOut == null) ? 14 : itm.timeOut; 98 let redisplayAfterDays = (itm.redisplayAfter == null) ? 28 : itm.redisplayAfter; 99 100 if (diffDays >= timeOutDays && diffDays < redisplayAfterDays) { 101 return; 102 } else {
103 itm.firstShown = gscState[itm.id].firstShown; 104 } 105 } 106 107 if (itm.priority == null) itm.priority = 3; // default priority of 3 108 if (gscState[itm.id].migrated) itm.migrated = true; 109 getSiteControlItems.push(itm); 110 }); 111 112 // Sort by priority. Items which have a firstShownTime will be higher priority. 113 getSiteControlItems.sort((a, b) => { 114 if (a.firstShown != null && b.firstShown != null) return new Date(a.firstShown) - new Date(b.firstShown); 115 else if (a.firstShown != null) return -1; 116 else if (b.firstShown != null) return 1; 117 else if (a.migrated && b.migrated) return 0; 118 else if (a.migrated) return -1; 119 else if (b.migrated) return 1; 120 121 122 else return a.priority - b.priority; 123 } 124 ); 125 126 // Set cookie mo-gsc-widget to indicate what widget to show. 127 // getSiteControl should use this to condition showing a survey. 128 if (getSiteControlItems.length > 0) { 129 const widget = getSiteControlItems[0]; 130 document.cookie = `mo-gsc-widget=${widget.id}; path=/;`; 131 const now = new Date().toISOString(); 132 if (typeof gscState[widget.id].firstShown == 'undefined') { 133 // First time showing the widget 134 gscState[widget.id].firstShown = now; 135 } else {
136 // Widget was shown before 137 const redisplayAfterDays = (widget.redisplayAfter == null) ? 28 : widget.redisplayAfter; 138 const lastShownTime = new Date(gscState[widget.id].firstShown); 139 const diffDays = Math.floor((new Date() - lastShownTime) / (1000 * 60 * 60 * 24)); 140 if (diffDays >= redisplayAfterDays) { 141 // Enough time has passed since the last show 142 gscState[widget.id].firstShown = now; 143 } 144 } 145 } 146 147 // set the cookie. 148 let expiresDate = new Date(); 149 expiresDate.setTime(expiresDate.getTime() + ONE_YEAR_MILLIS); 150 gscStateJson = encodeURIComponent(JSON.stringify(gscState)); 151 document.cookie = `mo-gsc-state=${gscStateJson}; expires=${expiresDate.toUTCString()}; path=/;` 152}
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.