PageSourceSearch

https://www.shelter.org.uk/shelter-cookies.js

js shelter.org.uk collected 2026-10-02 02:20:01 UTC 17,424 bytes, 558 lines download raw bytes

1/* global CookieControl */
2/* eslint-disable */
3
4/**
5 * Civic CookieControl reads its `CookieControl` cookie and runs an UNGUARDED
6 * JSON.parse on the value during load(). A corrupt cookie (truncated, wrong
7 * format, junk prepended) therefore throws, and because it happens inside the
8 * library's own promise chain a try/catch around CookieControl.load() cannot
9 * catch it. The only reliable fix is to detect a bad cookie and delete it
10 * BEFORE calling load(), so the value never reaches the parser.
11 */
12
13// Read a single cookie's raw (still url-encoded) value from a cookie string.
14// The (?:^|;\s*) boundary stops us matching a cookie whose NAME merely ends in
15// the target name (e.g. XCookieControl). The caller passes document.cookie,
16// which a privacy extension can hand back as undefined even when
17// navigator.cookieEnabled reports true, so an absent string is not an error.
18function getCookieValue(cookieString, name) {
19  if (!cookieString) return undefined;
20  var match = cookieString.match(new RegExp('(?:^|;\\s*)' + name + '=([^;]*)'));
21  return match ? match[1] : undefined;
22}
23
24// Validate the cookie the way load() needs it. An absent cookie is fine (load()
25// handles "no stored consent"). Otherwise the value must decode, parse as JSON,
26// AND be a non-empty plain object, which is the shape Cookie Control expects.
27// Valid JSON that is a primitive (e.g. a bare number), an array, or an empty
28// object still crashes load() when it reads properties off it, so those are
29// treated as bad.
30function isValidCookie(raw) {
31  if (raw === undefined) return true;
32  var value;
33  try {
34    value = JSON.parse(decodeURIComponent(raw));
35  } catch (e) {
36    return false;
37  }
38  return (
39    typeof value === 'object' &&
40    value !== null &&
41    !Array.isArray(value) &&
42    Object.keys(value).length > 0
43  );
44}
45
46// Every domain scope a CookieControl cookie could live on for the given host.
47// With subDomains:true the cookie is written to the registrable domain
48// (.shelter.org.uk), but on localhost / Netlify previews it is host-only. A
49// delete only works if its domain matches how the cookie was set, so we cover
50// every suffix of the current host.
51function cookieClearDomains(host) {
52  var domains = ['', host, '.' + host]; // '' = host-only (localhost / preview case)
53  var parts = host.split('.');
54  for (var i = 1; i < parts.length - 1; i++) {
55    domains.push('.' + parts.slice(i).join('.')); // .shelter.org.uk, etc.
56  }
57  return domains;
58}
59
60// Expire the CookieControl cookie across every plausible domain scope.
61function clearCookieControlCookie() {
62  var base = 'CookieControl=; Max-Age=0; path=/';
63  cookieClearDomains(window.location.hostname).forEach(function (d) {
64    document.cookie = base + (d ? '; domain=' + d : '');
65  });
66}
67
68(function () {
69  if (!window.dataLayer) window.dataLayer = [];
70
71  var onRevokeCategory = function () {
72    CookieControl.cookieCategoryRevokedNeedRefresh = true;
73  };
74
75  function gtag() {
76    dataLayer.push(arguments);
77  }
78
79  gtag('consent', 'default', {
80    ad_storage: 'denied',
81    analytics_storage: 'denied',
82    ad_user_data: 'denied',
83    ad_personalization: 'denied',
84    functionality_storage: 'granted',
85    security_storage: 'granted',
86  });
87
88  var cookiePolicyUrl =
89    window.location.host.indexOf('scot') !== -1
90      ? 'https://scotland.shelter.org.uk/about_us/about_this_website/cookies'
91      : 'https://england.shelter.org.uk/contact_us/cookies';
92
93  var ccConfig = {
94    apiKey: '10a22203c863d759dabbeb158635f6193b03a3ea',
95    branding: {
96      fontFamily:
97        'Barlow, -apple-system, BlinkMacSystemFont, Roboto, sans-serif',
98      fontSizeTitle: '1.5em',
99      fontSizeHeaders: '1.3em',
100      fontSize: '0.9em',
101      fontColor: '#333',
102      notifyFontColor: '#FFF',
103      backgroundColor: '#FFF',
104      notifyBackgroundColor: '#262626',
105      acceptText: '#FFF',
106      acceptBackground: '#EB001F',
107      rejectText: '#333',
108      rejectBackground: '#FFF',
109      closeBackground: '#262626',
110      toggleText: '#FFF',
111      toggleColor: '#FFF',
112      toggleBackground: '#262626',
113      removeAbout: true,
114      removeIcon: true,
115    },
116    notifyDismissButton: false,
117    closeStyle: 'button',
118    consentCookieExpiry: 365,
119    initialState: 'notify',
120    layout: 'slideout',
121    position: 'left',
122    logConsent: true,
123    product: 'PRO_MULTISITE',
124    setInnerHTML: true,
125    statement: {
126      updated: '14/10/2021',
127    },
128    subDomains: true,
129    text: {
130      title: 'Help us improve your experience with Shelter',
131      intro:
132        'Cookies are needed for us to understand how our visitors use our website. By accepting our recommended cookies, you’re helping improve this website for everyone, and your own experience.<br/><br/> You can change your cookie settings and find more information on our <a href=' +
133        cookiePolicyUrl +
134        ' style="color:#336DF5!important;">cookie policy page</a>.',
135
136      acceptSettings: 'I accept cookies',
137      rejectSettings: 'I reject cookies',
138      closeLabel: 'Save and close',
139      necessaryTitle: 'Necessary',
140      necessaryDescription:
141        'Our website needs these to run. You can only turn them off using your browser settings.',
142      notifyTitle: 'Help us improve your experience with Shelter',
143      notifyDescription:
144        'By accepting our recommended cookies, you will help us improve your own experience by remembering your settings',
145      accept: 'I accept cookies',
146      reject: 'I reject cookies',
147      settings: 'Cookie settings',
148    },
149    theme: 'dark',
150    necessaryCookies: [
151      'DntSession',
152      'has_js',
153      'SnapABugChatSession',
154      'SnapABugNoProactiveChat',
155      'SnapABugChatPoll',
156      'SnapABugChatView',
157      'SnapABugBanned',
158      'SnapABugChatWindow',
159      'SnapABugMinimizeStashCookie',
160      'SnapABugAgentAvatar',
161      'SnapABugApproval',
162      'SnapABugChatMessage',
163      'SnapABugHistory',
164      'SnapABugRef',
165      'SnapABugUserAlias',
166      'SnapABugUserEmail',
167      'SnapABugVisit',
168      '_GRECAPTCHA',
169      '_secure_session_id',
170      '_shopify_country',
171      '_shopify_m',
172      '_shopify_tm',
173      '_shopify_tw',
174      '_storefront_u',
175      '_tracking_consent',
176      'c',
177      'cart',
178      'cart_currency',
179      'cart_sig',
180      'cart_ts',
181      'cart_ver',
182      'checkout',
183      'checkout_token',
184      'dynamic_checkout_shown_on_cart',
185      'hide_shopify_pay_for_checkout',
186      'keep_alive',
187      'master_device_id',
188      'previous_step',
189      'remember_me',
190      'secure_customer_sig',
191      'shopify_pay',
192      'shopify_pay_redirect',
193      'storefront_digest',
194      'tracked_start_checkout',
195      'javascript',
196      'starvale_session',
197      'webform-*',
198      '_landing_page',
199      '_orig_referrer',
200      'exp_*',
201      '__stripe_sid',
202      '__stripe_mid',
203      'dnt_amount',
204      'dnt_coords',
205      'checkout_one_experiment',
206      'checkout_session_lookup',
207      'checkout_session_token_*',
208      '_checkout_queue_checkout_token',
209      '_checkout_queue_token',
210      'preview_theme',
211      'SSESSed*',
212      'split_test_*',
213    ],
214    optionalCookies: [
215      {
216        name: 'functional',
217        label: 'Functional',
218        description: 'This helps each part of our website work properly.',
219        cookies: [
220          'adiLP',
221          '__adiCookieCheck',
222          'adiErr',
223          'adiS',
224          'adiV',
225          'adiVi',
226          'JSESSIONID',
227          'localization',
228        ],
229        onAccept: function () {
230          window.dataLayer.push({
231            civic_cookies_functional: 'consent_given',
232            event: 'functional_consent_given',
233          });
234        },
235        onRevoke: function () {
236          window.dataLayer.push({
237            civic_cookies_functional: 'consent_revoked',
238          });
239          onRevokeCategory();
240        },
241      },
242      {
243        name: 'analytics',
244        label: 'Analytics',
245        description:
246          'This improves our website by collecting anonymous information on how people use it.',
247        cookies: [
248          'ethnio_displayed',
249          '_ga*',
250          'gcl_au',
251          '_gid',
252          'DV',
253          '_BEAMER_FIRST_VISIT_*',
254          '_BEAMER_LAST_UPDATE_*',
255          '_BEAMER_USER_ID_*',
256          '_hjAbsoluteSessionInProgress',
257          '_hjFirstSeen',
258          '_hjid',
259          '_hjIncludedInPageviewSample',
260          '_hjIncludedInSessionSample',
261          '_hjKB',
262          '_hjMinimizedPolls',
263          'ajs_anonymous_id',
264          'ajs_user_id',
265          'shelterEmployee',
266          'VISITOR_INFO1_LIVE',
267          'webform_tracking',
268          'YSC',
269          '_s',
270          '_shopify_d',
271          '_shopify_s',
272          '_shopify_sa_p',
273          '_shopify_sa_t',
274          '_shopify_y',
275          '_y',
276          '_shopify_evids',
277          'nf_ab',
278          '_clck',
279          '_clsk',
280          'check',
281          '_hjSessionRejected',
282          '_hjSession_*',
283          '_hjSessionUser_*',
284          '_gat_*',
285          '_shopify_ga',
286          '__Secure-ENID',
287          'AEC',
288          'survey_user_id',
289        ],
290        onAccept: function () {
291          gtag('consent', 'update', { analytics_storage: 'granted' });
292          window.dataLayer.push({
293            civic_cookies_analytics: 'consent_given',
294            event: 'analytics_consent_given',
295          });
296
297          if (window.generateSurveyId) window.generateSurveyId();
298
299          // If the current site is Impact Stack
300          var subDomain = window.location.host.split('.')[0];
301          if (subDomain === 'act' || subDomain === 'campaigns') {
302            document.dispatchEvent(new Event('analytics_consent_given'));
303          }
304        },
305        onRevoke: function () {
306          gtag('consent', 'update', { analytics_storage: 'denied' });
307          window.dataLayer.push({
308            civic_cookies_analytics: 'consent_revoked',
309          });
310          onRevokeCategory();
311        },
312      },
313      {
314        name: 'marketing',
315        label: 'Marketing',
316        description:
317          'By accepting our marketing cookies, you give Google products such as Google Analytics and Google Ads permission to gather data, to help us improve your online experience. They also send information to our social media channels for marketing purposes',
318        cookies: [
319          'anj',
320          'uuid2',
321          'IDE',
322          '_fbp',
323          'c_user',
324          'datr',
325          'fr',
326          'sb',
327          'spin',
328          'xs',
329          '__Secure-1PAPISID',
330          '__Secure-1PSID',
331          '1P_JAR',
332          'AID',
333          'APISID',
334          'CONSENT',
335          'HSID',
336          'OGPC',
337          'OTZ',
338          'SAPISID',
339          'SEARCH_SAMESITE',
340          'SID',
341          'SIDCC',
342          'outbrain_cid_fetch',
343          'obuid',
344          'auid',
345          '_pin_unauth',
346          '_pinterest_ct_ua',
347          '_pinterest_sess',
348          '_pinterest_ct',
349          '_epik',
350          '_derived_epik',
351          '_scid',
352          'sc_at',
353          'X-AB',
354          'tt_csrf_token',
355          'tt_webid',
356          'tt_webid_v2',
357          'ct0',
358          'guest_id',
359          'personalization_id',
360          '__Secure-3PAPISID',
361          '__Secure-3PSID',
362          '__Secure-3PSIDCC',
363          'LOGIN_INFO',
364          'PREF',
365          'SSID',
366          '_gcl_au',
367          'cookie-consent',
368          'ttwid',
369          'NID',
370          'MUID',
371          '_uetsid',
372          '_uetvid',
373          'ndclid',
374          '_uetsid_exp',
375          '_uetvid_exp',
376          '_tt_enable_cookie',
377          '_ttp',
378          '_rdt_uuid',
379          '_sctr',
380          '_tt_sessionId',
381        ],
382        onAccept: function () {
383          gtag('consent', 'update', {
384            ad_storage: 'granted',
385            ad_personalization: 'granted',
386            ad_user_data: 'granted',
387          });
388          window.dataLayer.push({
389            civic_cookies_marketing: 'consent_given',
390            event: 'marketing_consent_given',
391          });
392        },
393        onRevoke: function () {
394          gtag('consent', 'update', {
395            ad_storage: 'denied',
396            ad_user_data: 'denied',
397            ad_personalization: 'denied',
398          });
399          window.dataLayer.push({
400            civic_cookies_marketing: 'consent_revoked',
401          });
402          onRevokeCategory();
403        },
404      },
405    ],
406  };
407
408  if (navigator.cookieEnabled) {
409    var headTag = document.getElementsByTagName('head')[0];
410
411    var ccScript = document.createElement('script');
412    ccScript.src =
413      'https://cc.cdn.civiccomputing.com/9/cookieControl-9.x.min.js';
414
415    ccScript.addEventListener('load', function () {
416      // If the stored cookie is invalid, remove it so load() starts from a
417      // clean slate and the banner re-shows. Healthy cookies are left untouched.
418      if (!isValidCookie(getCookieValue(document.cookie, 'CookieControl'))) {
419        clearCookieControlCookie();
420      }
421
422      // The load event fires even when the CDN answers with a non-script body,
423      // so the library may not exist. Deliberately below the cookie handling,
424      // which still has to run. No banner means consent stays denied.
425      if (typeof CookieControl === 'undefined') return;
426
427      CookieControl.load(ccConfig);
428    });
429
430    headTag.appendChild(ccScript);
431
432    // The styles below are hardcoded overrides that ensure the consent banner
433    // displays correctly across the third-party platforms that load this file
434    // (e.g. iRaiser, Shelter Shop), where the host page's own CSS would
435    // otherwise interfere with Cookie Control's default styling.
436    var ccStyle = document.createElement('style');
437
438    const acceptBtn = '#ccc .ccc-notify-button.ccc-accept-button';
439    const rejectBtnBar = '#ccc #ccc-notify-reject';
440    const rejectBtnPanel = '#ccc #ccc-reject-settings';
441    const saveAndCloseBtn = '#ccc #ccc-content #ccc-dismiss-button';
442
443    ccStyle.textContent = `
444      #ccc-overlay {
445        background: rgba(0,0,0,.5)!important;
446      }
447
448      #ccc .checkbox-toggle:focus-within {
449        outline: 0;box-shadow: 0 0 0 2px #fff,0 0 0 4px #262626 !important;
450      }
451
452      .checkbox-toggle--slider .checkbox-toggle-off{
453        opacity:1!important;
454      }
455
456      #ccc h1#ccc-title {
457        color: #333
458      }
459
460      h2#ccc-title {
461        margin-top: 0 !important;
462      }
463
464      #shelter-online-shop #ccc p { font-size:16px!important; }
465      #shelter-online-shop #ccc h2 { font-size: 24px !important; }
466      #shelter-online-shop #ccc h3 { font-size: 21px !important; }
467      #shelter-online-shop #ccc .ccc-notify-button { font-size: 16px !important; }
468
469      .ccc-notify-button {
470        border-style: none !important;
471        border-radius: 0 !important;
472        font-weight:700! important;
473        text-transform:initial! important;
474      }
475      
476      .ccc-notify-button:focus {
477        outline: 0;
478        box-shadow: 0 0 0 2px #fff,0 0 0 4px #262626 !important;
479      }
480
481      ${acceptBtn}:hover, ${acceptBtn}:hover span  {
482        background-color: #c8001a !important; 
483      }
484
485      ${acceptBtn}:focus, ${acceptBtn}:focus span  {
486        background-color: #c8001a !important; 
487      }
488
489      ${acceptBtn}:focus {
490        box-shadow: rgb(255, 255, 255) 0px 0px 0px 2px, rgb(38, 38, 38) 0px 0px 0px 4px !important
491      }
492      
493      ${rejectBtnBar}, ${rejectBtnBar} span { 
494        color: #FFF !important; 
495        background-color: transparent !important;
496      }
497
498      ${rejectBtnBar} {
499        box-shadow: rgb(255, 255, 255) 0px 0px 0px 2px inset;
500      }
501
502      ${rejectBtnBar}:hover, ${rejectBtnBar}:hover span, ${rejectBtnBar}:focus, ${rejectBtnBar}:focus span  { 
503        color: #ff4760 !important;
504      }
505
506      ${rejectBtnBar}:hover { 
507        box-shadow: rgb(255, 71, 96) 0px 0px 0px 2px inset !important;
508      }
509      
510      ${rejectBtnBar}:focus {
511        box-shadow: rgb(255, 71, 96) 0px 0px 0px 2px inset, rgb(255, 255, 255) 0px 0px 0px 2px, rgb(38, 38, 38) 0px 0px 0px 4px !important;
512      }
513
514      ${rejectBtnPanel} { 
515        box-shadow: rgb(51, 51, 51) 0px 0px 0px 2px inset !important;
516      }
517
518      ${rejectBtnPanel}:hover, ${rejectBtnPanel}:hover span, ${rejectBtnPanel}:focus, ${rejectBtnPanel}:focus span  { 
519        color: #EB001F !important;
520      }
521
522      ${rejectBtnPanel}:hover { 
523        box-shadow: rgb(235, 0, 31) 0px 0px 0px 2px inset !important;
524      }
525
526      ${rejectBtnPanel}:focus { 
527        box-shadow: rgb(235, 0, 31) 0px 0px 0px 2px inset, rgb(255, 255, 255) 0px 0px 0px 2px, rgb(38, 38, 38) 0px 0px 0px 4px !important;
528      }
529      
530      ${saveAndCloseBtn}:hover, ${saveAndCloseBtn}:focus {
531        color: #fff !important;
532        background-color: #EB001F !important; 
533      }
534
535      ${saveAndCloseBtn}:focus {
536        box-shadow: rgb(255, 255, 255) 0px 0px 0px 2px, rgb(38, 38, 38) 0px 0px 0px 4px !important;
537      }
538
539      ${saveAndCloseBtn}:hover span, ${saveAndCloseBtn}:focus span  {
540        background-color: #EB001F !important;
541      }
542
543      `;
544
545    headTag.appendChild(ccStyle);
546  }
547})();
548
549/* Exposed for unit tests (Jest/CommonJS); ignored in the browser where
550   `module` is undefined. */
551if (typeof module !== 'undefined' && module.exports) {
552  module.exports = {
553    getCookieValue: getCookieValue,
554    isValidCookie: isValidCookie,
555    cookieClearDomains: cookieClearDomains,
556    clearCookieControlCookie: clearCookieControlCookie,
557  };
558}

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.