PageSourceSearch

https://www2.lwl.org/static/django_privacy_mgmt/js/privacy_mgmt.c88038be1b12.js

js lwl.org collected 2026-09-24 09:01:20 UTC 8,027 bytes, 307 lines download raw bytes

1/**
2 * Privacy Management API
3 *
4 * This API is used to manage the privacy settings of a website.
5 */
6class PrivacyMgmt {
7  constructor() {
8    this.tracking_items = [];
9    this.listeners = {
10      change: [],
11    };
12  }
13
14  PREFERENCE_COOKIE_NAME = "django_privacy_mgmt_preferences";
15
16  CATEGORIES = {
17    ESSENTIAL: {
18      required: true,
19      default: true,
20    },
21    STATISTICS: {
22      required: false,
23      default: false,
24    },
25    MARKETING: {
26      required: false,
27      default: false,
28    },
29    SOCIAL_MEDIA: {
30      required: false,
31      default: false,
32    },
33    MISCELLANEOUS: {
34      required: false,
35      default: false,
36    },
37  };
38
39  initModal() {
40    const privacyModal = $("#privacysettings");
41
42    privacyModal.on("show.bs.modal", (e) => {
43      const checkboxes = document.querySelectorAll(
44        'input[data-js="privacy-check"]',
45      );
46      if (checkboxes) {
47        checkboxes.forEach((checkbox) => {
48          const name = checkbox.getAttribute("name");
49          const category = checkbox.getAttribute("data-category");
50          checkbox.checked =
51            this.getPreference(name) || category === "ESSENTIAL";
52        });
53      }
54    });
55
56    const saveButton = document.querySelector(
57      '[data-js="privacy-save-settings"]',
58    );
59    if (saveButton) {
60      saveButton.addEventListener("click", (e) => {
61        e.preventDefault();
62        const checkboxes = document.querySelectorAll(
63          'input[data-js="privacy-check"]',
64        );
65        const preferences = {};
66        checkboxes.forEach((checkbox) => {
67          const name = checkbox.getAttribute("name");
68          preferences[name] = checkbox.checked;
69        });
70        this.setPreferences(preferences);
71
72        privacyModal.modal("hide");
73      });
74    }
75
76    const infoToggles = document.querySelectorAll(
77      '[data-js="privacy-info-toggle"]',
78    );
79    if (infoToggles) {
80      infoToggles.forEach((infoToggle) => {
81        infoToggle.addEventListener("click", (e) => {
82          e.preventDefault();
83          const target = infoToggle.getAttribute("data-target");
84          const info = document.getElementById(target);
85          info.style.maxHeight =
86            info.style.maxHeight && info.style.maxHeight !== "0px"
87              ? "0px"
88              : info.scrollHeight + "px";
89          info.parentNode.classList.toggle("privacy-item--show");
90        });
91      });
92    }
93
94    const categoryToggles = document.querySelectorAll(
95      'input[data-js="privacy-check"]',
96    );
97    if (categoryToggles) {
98      categoryToggles.forEach((categoryToggle) => {
99        categoryToggle.addEventListener("change", (e) => {
100          // toggle all checkboxes in the category
101          const category = e.target.getAttribute("name");
102          if (this.CATEGORIES.hasOwnProperty(category)) {
103            const categoryCheckboxes = document.querySelectorAll(
104              `input[data-category="${category}"]`,
105            );
106            categoryCheckboxes.forEach((checkbox) => {
107              checkbox.checked = e.target.checked;
108            });
109          }
110        });
111      });
112    }
113
114    return privacyModal;
115  }
116
117  initTrackingItems() {
118    this.tracking_items = JSON.parse(
119      document.getElementById("tracking_items").textContent,
120    );
121  }
122
123  init() {
124    this.initTrackingItems();
125
126    const privacyModal = this.initModal();
127
128    const settingsButton = document.querySelector(
129      '[data-js="privacy-settings"]',
130    );
131    if (settingsButton) {
132      settingsButton.addEventListener("click", (e) => {
133        e.preventDefault();
134        this.showSettings();
135      });
136    }
137
138    const acceptAllButton = document.querySelector(
139      '[data-js="privacy-accept-all"]',
140    );
141    if (acceptAllButton) {
142      acceptAllButton.addEventListener("click", (e) => {
143        e.preventDefault();
144        this.setAcceptAll();
145        privacyModal.modal("hide");
146      });
147    }
148
149    const rejectAllButton = document.querySelector(
150      '[data-js="privacy-reject-all"]',
151    );
152    if (rejectAllButton) {
153      rejectAllButton.addEventListener("click", (e) => {
154        e.preventDefault();
155        this.setRejectAll();
156        privacyModal.modal("hide");
157      });
158    }
159  }
160
161  setPreference(name, value) {
162    const preferences = this._getPreferences();
163    preferences[name] = value;
164
165    const tracking_item = this.tracking_items.find(
166      (item) => item.slug === name,
167    );
168    if (tracking_item) {
169      preferences[tracking_item.id] = value;
170    }
171
172    if (this.CATEGORIES.hasOwnProperty(name)) {
173      // If it's a category, set all items in the category
174      for (const item of this.tracking_items) {
175        if (item.category === name) {
176          preferences[item.id] = value;
177        }
178      }
179    }
180
181    this.setPreferences(preferences);
182  }
183
184  setPreferences(preferences) {
185    const oldPreferences = this._getPreferences();
186
187    Cookies.set(this.PREFERENCE_COOKIE_NAME, JSON.stringify(preferences), {
188      expires: 180,
189    });
190    this.dispatchEvent("change", preferences);
191
192    // If preferences were removed, reload the page
193    for (const key in oldPreferences) {
194      if (oldPreferences[key] && !preferences[key]) {
195        location.reload();
196        break;
197      }
198    }
199  }
200
201  setAcceptAll() {
202    const preferences = {};
203    for (const category in this.CATEGORIES) {
204      preferences[category] = true;
205    }
206    for (const item of this.tracking_items) {
207      preferences[item.id] = true;
208    }
209    this.setPreferences(preferences);
210  }
211
212  setRejectAll() {
213    const preferences = {};
214    this.setPreferences(preferences);
215  }
216
217  showSettings() {
218    $("#privacysettings").modal("show");
219  }
220
221  _getPreferences() {
222    let preferences = Cookies.get(this.PREFERENCE_COOKIE_NAME);
223    try {
224      preferences = JSON.parse(preferences);
225    } catch (e) {
226      preferences = {};
227    }
228    return preferences;
229  }
230
231  getPreference(name) {
232    this.initTrackingItems(); // Just to be sure
233    const preferences = this._getPreferences();
234
235    if (preferences.hasOwnProperty(name)) {
236      return Boolean(preferences[name]);
237    } else {
238      // Is slug of a tracking item
239      const tracking_item = this.tracking_items.find(
240        (item) => item.slug === name,
241      );
242      if (tracking_item && preferences.hasOwnProperty(tracking_item.id)) {
243        return Boolean(preferences[tracking_item.id]);
244      }
245
246      // Is category
247      if (this.CATEGORIES.hasOwnProperty(name)) {
248        return this.CATEGORIES[name]["default"];
249      } else {
250        return false;
251      }
252    }
253  }
254
255  addListener(eventName, callback, name = null) {
256    // Ignore invalid names
257    if (this.listeners.hasOwnProperty(eventName)) {
258      this.listeners[eventName].push({
259        callback: callback,
260        name: name,
261      });
262    }
263  }
264
265  removeListener(eventName, callback, name = null) {
266    // Ignore invalid names
267    if (this.listeners.hasOwnProperty(eventName)) {
268      const listeners = this.listeners[eventName];
269      for (let index in listeners) {
270        if (
271          listeners[index].name === name &&
272          listeners[index].callback === callback
273        ) {
274          this.listeners[eventName].splice(index, 1);
275          break;
276        }
277      }
278    }
279  }
280
281  dispatchEvent(eventName, preferences) {
282    // Ignore invalid names
283    for (let listener of this.listeners[eventName]) {
284      if (listener.name) {
285        const name = listener.name;
286        if (preferences.hasOwnProperty(name)) {
287          listener.callback(preferences[name]);
288        }
289        // Is slug of a tracking item
290        const tracking_item = this.tracking_items.find(
291          (item) => item.slug === name,
292        );
293
294        if (tracking_item && preferences.hasOwnProperty(tracking_item.id)) {
295          listener.callback(preferences[tracking_item.id]);
296        }
297      } else {
298        listener.callback(preferences);
299      }
300    }
301  }
302}
303
304window.django_privacy_mgmt = new PrivacyMgmt();
305window.addEventListener("DOMContentLoaded", (event) => {
306  window.django_privacy_mgmt.init();
307});

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.