PageSourceSearch

https://help.vivaldi.com/wp-content/themes/vivaldi-help/js/helpful.js?ver=1767872052

js vivaldi.com collected 2026-09-24 08:04:14 UTC 10,757 bytes, 399 lines download raw bytes

1/**
2 * Utility Methods
3 */
4window.daexthefuUtility = {
5
6  /**
7   * The own properties of object b are copied in object a. Object a is then returned.
8   *
9   * @param a The target object
10   * @param b The source object
11   * @returns a The object with the properties extended
12   */
13  extend: function(a, b) {
14
15    'use strict';
16
17    for (let key in b) {
18      if (b.hasOwnProperty(key)) {
19        a[key] = b[key];
20      }
21    }
22    return a;
23
24  },
25
26  /**
27   * Given the name of the cookie the cookie value is returned if the cookie is found. If the cookie is not found false
28   * is returned.
29   *
30   * @param cname The name of the cookie
31   * @returns mixed The value of the cookie if the cookie is found or false if the cookie is not found
32   */
33  getCookie: function(cname) {
34
35    'use strict';
36
37    let name = cname + '=';
38    let decodedCookie = decodeURIComponent(document.cookie);
39    let ca = decodedCookie.split(';');
40    for (let i = 0; i < ca.length; i++) {
41      let c = ca[i];
42      while (c.charAt(0) == ' ') {
43        c = c.substring(1);
44      }
45      if (c.indexOf(name) == 0) {
46        return c.substring(name.length, c.length);
47      }
48    }
49    return false;
50  },
51
52  /**
53   * Set a cookie based on the provided parameters.
54   *
55   * @param name The name of the cookie.
56   * @param value The value of the cookie.
57   * @param The expiration in seconds.
58   */
59  setCookie: function(name, value, expiration) {
60
61    'use strict';
62
63    let now = new Date();
64    let time = now.getTime();
65    let expireTime = time + (expiration * 1000);
66    now.setTime(expireTime);
67    let formattedExpiration = now.toUTCString();
68    document.cookie = name + '=' + value + '; expires=' + formattedExpiration +
69        '; path=/';
70
71  },
72
73};
74
75/**
76 * This file is used to generate the cookie notice and handle the feedback form.
77 */
78window.daexthefuCookieNotice = (function(utility) {
79
80  'use strict';
81
82  //This object is used to save all the settings -----------------------------------------------------------------------
83  let settings = {};
84
85  //This object is used to save all the variable states of the cookie notice ---------------------------------------------
86  let states = {
87    value: null,
88  };
89
90  /**
91   * Bind the event listeners.
92   */
93  function bindEventListeners() {
94
95    'use strict';
96
97    //Handles the clicks on the positive and negative feedback buttons
98    document.querySelectorAll('.daexthefu-yes, .daexthefu-no').forEach((el) => {el.addEventListener('click', (e) => {
99
100      'use strict';
101
102      //Set the new value of the state
103      states.value = parseInt(e.target.closest('.daexthefu-yes, .daexthefu-no').dataset.value, 10);
104
105      //Update the buttons
106      updateButtonsSelectedClasses();
107
108      //Update the textarea label
109      if (states.value === 1) {
110        document.getElementById('daexthefu-comment-label').textContent = window.DAEXTHEFU_PHPDATA.textareaLabelPositiveFeedback;
111      } else {
112        document.getElementById('daexthefu-comment-label').textContent = window.DAEXTHEFU_PHPDATA.textareaLabelNegativeFeedback;
113      }
114
115      const comment = document.querySelector('.daexthefu-comment');
116      switch (window.DAEXTHEFU_PHPDATA.commentForm) {
117
118          //Always
119        case 0:
120
121          //show comments area
122          comment.style.display = 'block';
123          comment.style.opacity = 1;
124
125          break;
126
127          //After Positive Feedback
128        case 1:
129
130          if (states.value === 1) {
131
132            //show comments area
133            comment.style.display = 'block';
134            comment.style.opacity = 1;
135
136          } else {
137
138            //Save the feedback of the user with an AJAX request.
139            save_feedback();
140
141          }
142
143          break;
144
145          //After Negative Feedback
146        case 2:
147
148          if (states.value === 0) {
149
150            //show comments area
151            comment.style.display = 'block';
152            comment.style.opacity = 1;
153
154          } else {
155
156            //Save the feedback of the user with an AJAX request.
157            save_feedback();
158
159          }
160
161          break;
162
163          //Never
164        case 3:
165
166          //Save the feedback of the user with an AJAX request.
167          save_feedback();
168
169          break;
170
171      }
172
173    })});
174
175    //Handle the clicks on the comment submit button
176    document.querySelectorAll('.daexthefu-comment-submit').forEach((el) => {el.addEventListener('click', (e) => {
177
178      'use strict';
179
180      //Save the feedback of the user with an AJAX request.
181      save_feedback();
182
183    })});
184
185    //Handle the clicks on the comment cancel button
186    document.querySelectorAll('.daexthefu-comment-cancel').forEach((el) => {el.addEventListener('click', (e) => {
187
188      'use strict';
189
190      //hide the comments area
191      document.querySelector('.daexthefu-comment').style.opacity = 0;
192
193      //reset the state used to store the selected value
194      states.value = null;
195
196      //update the classes of the icons
197      updateButtonsSelectedClasses();
198
199    })});
200
201    //Implement the character counter
202    update_character_counter();
203    document.getElementById('daexthefu-comment-textarea').addEventListener('input', function() {
204      update_character_counter();
205    });
206
207  }
208
209  /**
210   * Update the character counter based on the character counted on the
211   * textarea.
212   */
213  function update_character_counter() {
214
215    'use strict';
216
217    const charCount = document.getElementById('daexthefu-comment-textarea').value.length;
218    document.getElementById('daexthefu-comment-character-counter-number').innerHTML = (charCount + '/' + window.DAEXTHEFU_PHPDATA.textareaCharacters);
219
220  }
221
222  /**
223   * Save the feedback of the user with an AJAX request.
224   */
225  function save_feedback() {
226
227    'use strict';
228
229    //Get the feedback data from the DOM
230    const postId = parseInt(document.getElementById('daexthefu-container').dataset.postId, 10);
231    const comment = document.getElementById('daexthefu-comment-textarea').value;
232
233    //Prepare the ajax request data
234    let data = {
235      'action': 'daexthefu_save_feedback',
236      'security': window.DAEXTHEFU_PHPDATA.nonce,
237      'value': states.value,
238      'post_id': postId,
239      'comment': comment,
240    };
241
242    //Send ajax request
243    const req = new Request(window.DAEXTHEFU_PHPDATA.ajaxUrl, {
244      method: 'POST',
245      body: new URLSearchParams(data),
246    });
247    fetch(req)
248      .then((response) => {
249        if (!response.ok) {
250          throw new Error(`HTTP error! Status: ${response.status}`);
251        }
252
253        //Hide the feedback section from the form
254        document.querySelector('.daexthefu-feedback').style.display = 'none';
255
256        //Hide the feedback comment area from the form
257        document.querySelector('.daexthefu-comment').style.display = 'none';
258
259        //Show a successful submission message
260        document.querySelector('.daexthefu-successful-submission-text').style.display = 'block';
261
262        //Save the cookie used to store for which posts the user has already submitted a feedback
263        saveCookie(postId);
264
265      })
266    ;
267  }
268
269  /**
270   * Save in a cookie named "daexthefu-data" the ID of the post for which has
271   * been already submitted a feedback. Note that this cookie includes a
272   * serialized array of post IDs.
273   *
274   * @param postId
275   */
276  function saveCookie(postId) {
277
278    'use strict';
279
280    /**
281     * If the cookie doesn't exist create it as a serialized array of post IDs.
282     * If the cookie exists add the current post ID to the serialized array of
283     * post IDs.
284     */
285    if (utility.getCookie('daexthefu-data') === false) {
286
287      //Create the new cookie
288
289      //Save the new submission status in the serialized "daexthefu-data" cookie
290      let dataCookie = [];
291      dataCookie.push(postId);
292
293      //Convert the array with the data to JSON and save these data in the 'daexthefu-data' cookie.
294      dataCookie = JSON.stringify(dataCookie);
295
296      //Set the cookie
297      if (parseInt(window.DAEXTHEFU_PHPDATA.uniqueSubmission, 10) === 1 ||
298          parseInt(window.DAEXTHEFU_PHPDATA.uniqueSubmission, 10) === 3) {
299        utility.setCookie('daexthefu-data', dataCookie,
300            window.DAEXTHEFU_PHPDATA.cookieExpiration);
301      }
302
303    } else {
304
305      //Update the existing cookie
306
307      //Get the current data as an array
308      const currentCookieValue = utility.getCookie('daexthefu-data');
309      let decodedCookieValue = JSON.parse(currentCookieValue);
310
311      //Add the current post ID to the array
312      decodedCookieValue.push(postId);
313
314      //Serialize the array
315      const completeCookie = JSON.stringify(decodedCookieValue);
316
317      //Set the cookie
318      if (parseInt(window.DAEXTHEFU_PHPDATA.uniqueSubmission, 10) === 1 ||
319          parseInt(window.DAEXTHEFU_PHPDATA.uniqueSubmission, 10) === 3) {
320        utility.setCookie('daexthefu-data', completeCookie,
321            window.DAEXTHEFU_PHPDATA.cookieExpiration);
322      }
323
324    }
325
326  }
327
328  /**
329   * Update classes used to identify which is the positive and negative button
330   * based on the status of states.value
331   *
332   * The plugin uses these classed to apply custom colors to the positive and
333   * negative feedback buttons.
334   */
335  function updateButtonsSelectedClasses() {
336
337    'use strict';
338
339    if (states.value === null) {
340
341      //No button is selected
342      document.querySelector('.daexthefu-yes').classList.remove('daexthefu-yes-selected');
343      document.querySelector('.daexthefu-no').classList.remove('daexthefu-no-selected');
344
345    } else if (parseInt(states.value, 10) === 1) {
346
347      //The positive feedback button is selected
348      document.querySelector('.daexthefu-yes').classList.add('daexthefu-yes-selected');
349      document.querySelector('.daexthefu-no').classList.remove('daexthefu-no-selected');
350
351    } else {
352
353      //The negative feedback button is selected
354      document.querySelector('.daexthefu-yes').classList.remove('daexthefu-yes-selected');
355      document.querySelector('.daexthefu-no').classList.add('daexthefu-no-selected');
356
357    }
358
359  }
360
361  /**
362   * Add the cookie notice to the DOM and add the event listeners.
363   */
364  function bootstrap() {
365
366    'use strict';
367
368    //Bind the event listeners
369    document.addEventListener('DOMContentLoaded', function() {
370
371      if(document.getElementById('daexthefu-container')){
372        bindEventListeners();
373      }
374
375    });
376
377  }
378
379  //Return an object exposed to the public -----------------------------------------------------------------------------
380  return {
381
382    initialize: function(configuration) {
383
384      'use strict';
385
386      //Merge the custom configuration provided by the user with the default configuration
387      settings = configuration;
388
389      //Start the process
390      bootstrap();
391
392    },
393
394  };
395
396}(daexthefuUtility));
397
398//Init
399window.daexthefuCookieNotice.initialize({});

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.