PageSourceSearch

https://bitcoin.org/js/cookieconsent/cookieconsent.js?1790370652

js bitcoin.org collected 2026-10-01 06:47:18 UTC 9,687 bytes, 348 lines download raw bytes

1(function () {
2  // Stop from running again, if accidently included more than once.
3  if (window.hasCookieConsent) return;
4  window.hasCookieConsent = true;
5
6  /*
7   Constants
8   */
9
10  // Client variable which may be present containing options to override with
11  var OPTIONS_VARIABLE = 'cookieconsent_options';
12
13  // Change cookie consent options on the fly.
14  var OPTIONS_UPDATER = 'update_cookieconsent_options';
15
16  // Name of cookie to be set when dismissed
17  var DISMISSED_COOKIE = 'cookieconsent_dismissed';
18
19  // The path to style
20  var THEME_BUCKET_PATH = '/js/cookieconsent/';
21
22  // No point going further if they've already dismissed.
23  if (document.cookie.indexOf(DISMISSED_COOKIE) > -1) {
24    return;
25  }
26
27  // IE8...
28  if(typeof String.prototype.trim !== 'function') {
29    String.prototype.trim = function() {
30      return this.replace(/^\s+|\s+$/g, '');
31    };
32  }
33
34  /*
35   Helper methods
36   */
37  var Util = {
38    isArray: function (obj) {
39      var proto = Object.prototype.toString.call(obj);
40      return proto == '[object Array]';
41    },
42
43    isObject: function (obj) {
44      return Object.prototype.toString.call(obj) == '[object Object]';
45    },
46
47    each: function (arr, callback, /* optional: */context, force) {
48      if (Util.isObject(arr) && !force) {
49        for (var key in arr) {
50          if (arr.hasOwnProperty(key)) {
51            callback.call(context, arr[key], key, arr);
52          }
53        }
54      } else {
55        for (var i = 0, ii = arr.length; i < ii; i++) {
56          callback.call(context, arr[i], i, arr);
57        }
58      }
59    },
60
61    merge: function (obj1, obj2) {
62      if (!obj1) return;
63      Util.each(obj2, function (val, key) {
64        if (Util.isObject(val) && Util.isObject(obj1[key])) {
65          Util.merge(obj1[key], val);
66        } else {
67          obj1[key] = val;
68        }
69      })
70    },
71
72    bind: function (func, context) {
73      return function () {
74        return func.apply(context, arguments);
75      };
76    },
77
78    /*
79     find a property based on a . separated path.
80     i.e. queryObject({details: {name: 'Adam'}}, 'details.name') // -> 'Adam'
81     returns null if not found
82     */
83    queryObject: function (object, query) {
84      var queryPart;
85      var i = 0;
86      var head = object;
87      query = query.split('.');
88      while ( (queryPart = query[i++]) && head.hasOwnProperty(queryPart) && (head = head[queryPart]) )  {
89        if (i === query.length) return head;
90      }
91      return null;
92    },
93
94    setCookie: function (name, value, expiryDays, domain, path) {
95      expiryDays = expiryDays || 365;
96
97      var exdate = new Date();
98      exdate.setDate(exdate.getDate() + expiryDays);
99
100      var cookie = [
101        name + '=' + value,
102        'expires=' + exdate.toUTCString(),
103        'path=' + path || '/'
104      ];
105
106      if (domain) {
107        cookie.push(
108          'domain=' + domain
109        );
110      }
111
112      document.cookie = cookie.join(';');
113    },
114
115    addEventListener: function (el, event, eventListener) {
116      if (el.addEventListener) {
117        el.addEventListener(event, eventListener);
118      } else {
119        el.attachEvent('on' + event, eventListener);
120      }
121    }
122  };
123
124  var DomBuilder = (function () {
125    /*
126     The attribute we store events in.
127     */
128    var eventAttribute = 'data-cc-event';
129    var conditionAttribute = 'data-cc-if';
130
131    /*
132     Shim to make addEventListener work correctly with IE.
133     */
134    var addEventListener = function (el, event, eventListener) {
135      // Add multiple event listeners at once if array is passed.
136      if (Util.isArray(event)) {
137        return Util.each(event, function (ev) {
138          addEventListener(el, ev, eventListener);
139        });
140      }
141
142      if (el.addEventListener) {
143        el.addEventListener(event, eventListener);
144      } else {
145        el.attachEvent('on' + event, eventListener);
146      }
147    };
148
149    /*
150     Replace  with it's property on the scope
151     */
152    var insertReplacements = function (htmlStr, scope) {
153      return htmlStr.replace(/\{\{(.*?)\}\}/g, function (_match, sub) {
154        var tokens = sub.split('||');
155        var value;
156        while (token = tokens.shift()) {
157          token = token.trim();
158
159          // If string
160          if (token[0] === '"') return token.slice(1, token.length - 1);
161
162          // If query matches
163          value =  Util.queryObject(scope, token);
164
165          if (value) return value;
166        }
167
168        return '';
169      });
170    };
171
172    /*
173     Turn a string of html into DOM
174     */
175    var buildDom = function (htmlStr) {
176      var container = document.createElement('div');
177      container.innerHTML = htmlStr;
178      return container.children[0];
179    };
180
181    var applyToElementsWithAttribute = function (dom, attribute, func) {
182      var els = dom.parentNode.querySelectorAll('[' + attribute + ']');
183      Util.each(els, function (element) {
184        var attributeVal = element.getAttribute(attribute);
185        func(element, attributeVal);
186      }, window, true);
187    };
188
189    /*
190     Parse event attributes in dom and set listeners to their matching scope methods
191     */
192    var applyEvents = function (dom, scope) {
193      applyToElementsWithAttribute(dom, eventAttribute, function (element, attributeVal) {
194        var parts = attributeVal.split(':');
195        var listener = Util.queryObject(scope, parts[1]);
196        addEventListener(element, parts[0], Util.bind(listener, scope));
197      });
198    };
199
200    var applyConditionals = function (dom, scope) {
201      applyToElementsWithAttribute(dom, conditionAttribute, function (element, attributeVal) {
202        var value = Util.queryObject(scope, attributeVal);
203        if (!value) {
204          element.parentNode.removeChild(element);
205        }
206      });
207    };
208
209    return {
210      build: function (htmlStr, scope) {
211        if (Util.isArray(htmlStr)) htmlStr = htmlStr.join('');
212
213        htmlStr = insertReplacements(htmlStr, scope);
214        var dom = buildDom(htmlStr);
215        applyEvents(dom, scope);
216        applyConditionals(dom, scope);
217
218        return dom;
219      }
220    };
221  })();
222
223
224  /*
225   Plugin
226   */
227  var cookieconsent = {
228    options: {
229      message: 'This website uses cookies to ensure you get the best experience on our website. ',
230      dismiss: 'OK',
231      learnMore: 'More info',
232      link: null,
233      container: null, // selector
234      theme: 'light-floating',
235      domain: null, // default to current domain.
236      path: '/', 
237      expiryDays: 365,
238      markup: [
239        '<div class="cc_banner-wrapper ">',
240        '<div class="cc_banner cc_container cc_container--open">',
241        '<a href="#ok" data-cc-event="click:dismiss" target="_blank" class="cc_btn cc_btn_accept_all">OK</a>',
242        '<p class="cc_message">We use cookies to ensure you get the best experience on our website. <br><br>Please read our <a href="/en/privacy">privacy policy</a> to find out more.</p>',
243        '</div>',
244        '</div>'
245      ]
246    },
247
248    init: function () {
249      var options = window[OPTIONS_VARIABLE];
250      if (options) this.setOptions(options);
251
252      this.setContainer();
253
254      // Calls render when theme is loaded.
255      if (this.options.theme) {
256        this.loadTheme(this.render);
257      } else {
258        this.render();
259      }
260    },
261
262    setOptionsOnTheFly: function (options) {
263      this.setOptions(options);
264      this.render();
265    },
266
267    setOptions: function (options) {
268      Util.merge(this.options, options);
269    },
270
271    setContainer: function () {
272      if (this.options.container) {
273        this.container = document.querySelector(this.options.container);
274      } else {
275        this.container = document.body;
276      }
277
278      // Add class to container classes so we can specify css for IE8 only.
279      this.containerClasses = '';
280      if (navigator.appVersion.indexOf('MSIE 8') > -1) {
281        this.containerClasses += ' cc_ie8'
282      }
283    },
284
285    loadTheme: function (callback) {
286      var theme = this.options.theme;
287
288      // If theme is specified by name
289      if (theme.indexOf('.css') === -1) {
290        theme = THEME_BUCKET_PATH + theme + '.css';
291      }
292
293      var link = document.createElement('link');
294      link.rel = 'stylesheet';
295      link.type = 'text/css';
296      link.href = theme;
297
298      var loaded = false;
299      link.onload = Util.bind(function () {
300        if (!loaded && callback) {
301          callback.call(this);
302          loaded = true;
303        }
304      }, this);
305
306      document.getElementsByTagName("head")[0].appendChild(link);
307    },
308
309    render: function () {
310      // remove current element (if we've already rendered)
311      if (this.element && this.element.parentNode) {
312        this.element.parentNode.removeChild(this.element);
313        delete this.element;
314      }
315
316      this.element = DomBuilder.build(this.options.markup, this);
317      if (!this.container.firstChild) {
318        this.container.appendChild(this.element);
319      } else {
320        this.container.insertBefore(this.element, this.container.firstChild);
321      }
322    },
323
324    dismiss: function (evt) {
325      evt.preventDefault && evt.preventDefault();
326      evt.returnValue = false;
327      this.setDismissedCookie();
328      this.container.removeChild(this.element);
329    },
330
331    setDismissedCookie: function () {
332      Util.setCookie(DISMISSED_COOKIE, 'yes', this.options.expiryDays, this.options.domain, this.options.path);
333    }
334  };
335
336  var init;
337  var initialized = false;
338  (init = function () {
339    if (!initialized && document.readyState == 'complete') {
340      cookieconsent.init();
341      initialized = true;
342      window[OPTIONS_UPDATER] = Util.bind(cookieconsent.setOptionsOnTheFly, cookieconsent);
343    }
344  })();
345
346  Util.addEventListener(document, 'readystatechange', init);
347
348})();

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.