PageSourceSearch

https://wolli.ai/wp-content/plugins/bdthemes-element-pack-lite/assets/js/common/helper.js?ver=5.10.25

js wolli.ai collected 2026-10-05 15:59:46 UTC 8,844 bytes, 300 lines download raw bytes

1var debounce = function (func, wait, immediate) {
2  // 'private' variable for instance
3  // The returned function will be able to reference this due to closure.
4  // Each call to the returned function will share this common timer.
5  var timeout;
6
7  // Calling debounce returns a new anonymous function
8  return function () {
9    // reference the context and args for the setTimeout function
10    var context = this,
11      args = arguments;
12
13    // Should the function be called now? If immediate is true
14    //   and not already in a timeout then the answer is: Yes
15    var callNow = immediate && !timeout;
16
17    // This is the basic debounce behaviour where you can call this
18    //   function several times, but it will only execute once
19    //   [before or after imposing a delay].
20    //   Each time the returned function is called, the timer starts over.
21    clearTimeout(timeout);
22
23    // Set the new timeout
24    timeout = setTimeout(function () {
25      // Inside the timeout function, clear the timeout variable
26      // which will let the next execution run when in 'immediate' mode
27      timeout = null;
28
29      // Check if the function already ran with the immediate flag
30      if (!immediate) {
31        // Call the original function with apply
32        // apply lets you define the 'this' object as well as the arguments
33        //    (both captured before setTimeout)
34        func.apply(context, args);
35      }
36    }, wait);
37
38    // Immediate mode and no wait timer? Execute the function..
39    if (callNow) func.apply(context, args);
40  };
41};
42
43function epObserveTarget(target, callback) {
44  var options =
45    arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
46  // Set the rootMargin to trigger when the target is 10% past the viewport
47  options.rootMargin = options.rootMargin || "10% 0px 0px 0px";
48  var observer = new IntersectionObserver(function (entries, observer) {
49    entries.forEach(function (entry) {
50      if (entry.isIntersecting) {
51        callback(entry);
52
53        if (!options.loop) observer.unobserve(entry.target); // Unobserve after the first intersection
54      }
55    });
56  }, options);
57  observer.observe(target);
58}
59
60/**
61 * Safe HTML
62 */
63function EP_SAFE_HTML(input) {
64  /**
65   * Expanded list of allowed tags and attributes for a more flexible sanitization
66   */
67  const allowedTags = {
68    'img': ['src', 'alt', 'title', 'width', 'height', 'style'],
69    'a': ['href', 'title', 'target', 'rel'],
70    'p': ['class', 'style', 'id'],
71    'b': ['class', 'style'],
72    'i': ['class', 'style'],
73    'u': ['class', 'style'],
74    'strong': ['class', 'style'],
75    'em': ['class', 'style'],
76    'br': [],
77    'hr': ['class', 'style'],
78    'ul': ['class', 'style'],
79    'ol': ['class', 'style'],
80    'li': ['class', 'style'],
81    'div': ['class', 'style', 'id'],
82    'span': ['class', 'style', 'id'],
83    'blockquote': ['cite', 'class', 'style'],
84    'code': ['class', 'style'],
85    'pre': ['class', 'style'],
86    'h1': ['class', 'style', 'id'],
87    'h2': ['class', 'style', 'id'],
88    'h3': ['class', 'style', 'id'],
89    'h4': ['class', 'style', 'id'],
90    'h5': ['class', 'style', 'id'],
91    'h6': ['class', 'style', 'id'],
92    'table': ['class', 'style', 'id'],
93    'thead': ['class', 'style'],
94    'tbody': ['class', 'style'],
95    'tfoot': ['class', 'style'],
96    'tr': ['class', 'style'],
97    'th': ['class', 'style', 'scope'],
98    'td': ['class', 'style', 'colspan', 'rowspan'],
99  };
100
101  /**
102   * Main sanitization process
103   */
104  const tagPattern = /<\/?([a-zA-Z0-9]+)([^>]*)>/g;
105  input = input.replace(tagPattern, (match, tagName, attributes) => {
106    tagName = tagName.toLowerCase();
107
108    /**
109     * Remove the tag if it's not allowed
110     */
111    if (!allowedTags.hasOwnProperty(tagName)) {
112      return '';
113    }
114
115    /**
116     * Filter attributes for allowed tags only
117     */
118    const allowedAttributes = allowedTags[tagName];
119    const filteredAttributes = attributes.replace(/([a-zA-Z0-9-]+)\s*=\s*("[^"]*"|'[^']*'|[^\s>]*)/g, (match, attrName, attrValue) => {
120      attrName = attrName.toLowerCase();
121
122      /**
123       * Only keep attributes in the allowed list and ignore any "on" events or disallowed protocols
124       */
125      if (!allowedAttributes.includes(attrName) || attrName.startsWith("on") || /^javascript:/i.test(attrValue)) {
126        return '';
127      }
128
129      return `${attrName}=${attrValue}`;
130    });
131
132    return `<${tagName}${filteredAttributes}>`;
133  });
134
135  return input;
136}
137/**
138 * /Safe HTML
139 */
140
141/**
142 * Start Crypto Currency
143 */
144
145function returnCurrencySymbol(currency = null) {
146  if (currency === null) return "";
147  let currency_symbols = {
148    USD: "$", // US Dollar
149    EUR: "€", // Euro
150    CRC: "₡", // Costa Rican Colón
151    GBP: "£", // British Pound Sterling
152    ILS: "₪", // Israeli New Sheqel
153    INR: "₹", // Indian Rupee
154    JPY: "Â¥", // Japanese Yen
155    KRW: "₩", // South Korean Won
156    NGN: "₦", // Nigerian Naira
157    PHP: "₱", // Philippine Peso
158    PLN: "zł", // Polish Zloty
159    PYG: "₲", // Paraguayan Guarani
160    THB: "฿", // Thai Baht
161    UAH: "₴", // Ukrainian Hryvnia
162    VND: "₫", // Vietnamese Dong
163  };
164  if (currency_symbols[currency] !== undefined) {
165    return currency_symbols[currency];
166  } else {
167    return ""; // this is means there is not any
168  }
169}
170
171/**
172 * End Crypto Currency
173 */
174
175(function ($) {
176  /**
177   * Open Offcanvas on Mini Cart Update
178   */
179
180  jQuery(document).ajaxComplete(function (event, request, settings) {
181    if (
182      request.responseJSON &&
183      typeof request.responseJSON.cart_hash !== "undefined" &&
184      request.responseJSON.cart_hash
185    ) {
186      if (jQuery(".bdt-offcanvas").hasClass("__update_cart")) {
187        let id = jQuery(".bdt-offcanvas.__update_cart").attr("id");
188        bdtUIkit.util.ready(function () {
189          bdtUIkit.offcanvas("#" + id).show();
190        });
191      }
192    }
193  });
194
195  /**
196   * /Open Offcanvas on Mini Cart Update
197   */
198
199  jQuery(document).ready(function () {
200    /**
201     * Start used on Social Share
202     */
203
204    jQuery(".bdt-ss-link").on("click", function () {
205      var $temp = jQuery("<input>");
206      jQuery("body").append($temp);
207      $temp.val(jQuery(this).data("url")).select();
208      document.execCommand("copy");
209      $temp.remove();
210
211      // Update the text to indicate that it has been copied
212      jQuery(this)
213        .find(".bdt-social-share-title")
214        .html(jQuery(this).data("copied"));
215
216      // Reset the text after a delay (e.g., 5 seconds)
217      setTimeout(() => {
218        jQuery(this)
219          .find(".bdt-social-share-title")
220          .html(jQuery(this).data("orginal"));
221      }, 5000);
222    });
223
224    /**
225     * end Social Share
226     */
227
228    /**
229     * Open In a New Tab Feature
230     */
231    const element = {
232      "elementor-widget-bdt-post-grid-tab": {
233        selectors: [
234          ".bdt-post-grid-desc-inner a",
235          ".bdt-post-grid-tab-readmore",
236        ],
237      },
238      "elementor-widget-bdt-post-grid": {
239        selectors: [".bdt-post-grid-title a", ".bdt-post-grid-readmore"],
240      },
241      "elementor-widget-bdt-post-card": {
242        selectors: [".bdt-post-card-title a", ".bdt-post-card-button"],
243      },
244      "elementor-widget-bdt-post-block": {
245        selectors: [".bdt-post-block-title a", ".bdt-post-block-read-more"],
246      },
247      "elementor-widget-bdt-post-block-modern": {
248        selectors: [
249          ".bdt-post-block-modern-title a",
250          ".bdt-post-block-modern-read-more",
251        ],
252      },
253      "elementor-widget-bdt-post-gallery": {
254        selectors: [".bdt-post-gallery-title-link", ".bdt-gallery-item-link"],
255      },
256      "elementor-widget-bdt-post-list": {
257        selectors: [".bdt-title a", ".bdt-image a"],
258      },
259      "elementor-widget-bdt-post-slider": {
260        selectors: [".bdt-post-slider-title-wrap a", ".bdt-post-slider-button"],
261      },
262    };
263
264    Object.keys(element).forEach(function (key) {
265      if (jQuery("." + key).length > 0) {
266        if (
267          jQuery("." + key).data("settings") !== undefined &&
268          jQuery("." + key).data("settings").bdt_link_new_tab === "yes"
269        ) {
270          element[key].selectors.forEach(function (selector) {
271            jQuery(selector).attr("target", "_blank");
272          });
273        }
274      }
275    });
276    /**
277     * /Open In a New Tab Feature
278     */
279
280    /** Toggle Pass */
281
282    jQuery(".bdt-pass-input-wrapper")
283      .find("i")
284      .on("click", function () {
285        if (jQuery(this).hasClass("fa-eye")) {
286          jQuery(this).toggleClass("fa-eye-slash");
287        }
288        let input = jQuery(this)
289          .closest(".bdt-pass-input-wrapper")
290          .find("input");
291        if (input.attr("type") == "password") {
292          jQuery(input).attr("type", "text");
293        } else {
294          jQuery(input).attr("type", "password");
295        }
296      });
297
298    /** /Toggle Pass */
299  });
300})(jQuery);

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.