PageSourceSearch

https://www.zfsinc.com/wp-content/plugins/advanced-iframe/js/ai.min.js?ver=939406

js zfsinc.com collected 2026-10-07 21:59:06 UTC 88,297 bytes, 2,366 lines download raw bytes

1/**
2 *  Advanced iframe functions v2026.2
3 */
4/* jslint devel: true, unused: false */
5/* globals ai_show_id_only:false, aiChangeUrl: false, aiResizeIframeHeightId: false, aiShowIframeId: false, findAndReplaceDOMText: false, aiShowDebug: false */
6
7var aiEnableCookie = (typeof x === 'undefined') ? false : aiEnableCookie;
8var aiId = '';
9var aiExtraSpace = (typeof aiExtraSpace === 'undefined') ? 0 : aiExtraSpace;
10var aiAccTime = 0;
11var aiRealFullscreen = (typeof aiRealFullscreen === 'undefined') ? false : aiRealFullscreen;
12var aiInFullscreen = false;
13var aiOnloadEventsCounter = 0;
14var aiOverflowHtml = jQuery('html').css('overflow') ?? 'visible';
15var aiOverflowBody = jQuery('body').css('overflow') ?? 'visible';
16
17var aiCallbackExists = typeof aiReadyCallbacks !== 'undefined' && aiReadyCallbacks instanceof Array;
18var aiReadyCallbacks = aiCallbackExists ? aiReadyCallbacks : [];
19
20/**
21 * The debug messages are enabled if you enable the debug console.
22 */
23function aiDebugExtended(message) {
24  if (typeof aiShowDebug !== 'undefined' && aiShowDebug) {
25    if (console && console.log) {
26      console.log("Advanced iframe: " + message);
27    }
28  }
29}
30
31/**
32 *  This function resizes the iframe after loading to the height
33 *  of then content of the iframe.
34 *
35 *  The extra space is not stored in the cookie! The height would
36 *  be added every time otherwise and the iframe would grow,
37 */
38function aiResizeIframe(obj, resizeWidth, resizeMinHeight) {
39  aiDebugExtended("aiResizeIframe");
40  try {
41    if (obj.contentWindow.location.href === 'about:blank') {
42      return;
43    }
44    if (obj.contentWindow.document.body != null) {
45      var oldScrollPosition = jQuery(window).scrollTop();
46      obj.style.marginTop = '0';
47      obj.style.marginBottom = '0';
48      obj.height = Number(resizeMinHeight); // set to 1 because otherwise the iframe does never get smaller.
49      obj.style.height = Number(resizeMinHeight) + 'px';
50      var newHeight = aiGetIframeHeight(obj);
51      aiDebugExtended("aiResizeIframe - newHeight: " + newHeight);
52      obj.height = newHeight;
53      obj.style.height = newHeight + 'px';
54
55      // set the height of the zoom div
56      const zoomDivjQuery = jQuery('#ai-zoom-div-' + obj.id);
57      if (zoomDivjQuery.length !== 0) {
58        var zoom = window['zoom_' + obj.id];
59        zoomDivjQuery.css('height', newHeight * zoom);
60      }
61
62      if (aiEnableCookie && aiExtraSpace === 0) {
63        aiWriteCookie(newHeight);
64      }
65      var hash = aiGetIframeHash(obj.contentWindow.location.href);
66      if (hash !== '-1') {
67        var iframeId = '#' + obj.id;
68        try {
69          var hashPosition = jQuery(iframeId).contents().find('#' + hash);
70          if (hashPosition.length !== 0) {
71            var hashPositionTop = hashPosition.offset().top;
72            oldScrollPosition = Math.round(jQuery(iframeId).offset().top + hashPositionTop);
73          }
74        } catch (e) {
75          // in case of an invalid hash it is ignored.
76        }
77      }
78      setTimeout(function () {
79        jQuery("html,body").scrollTop(oldScrollPosition);
80      }, 50);
81
82      if (resizeWidth === 'true') {
83        var newWidth = aiGetIframeWidth(obj);
84        obj.width = newWidth;
85        obj.style.width = newWidth + 'px';
86      }
87      var fCallback = window['resizeCallback' + obj.id];
88      fCallback();
89      // fires the onload event again if iframes are wrapped
90      if (window.frameElement != null) {
91        parent.jQuery('iframe').trigger('onload');
92      }
93      aiHandleAnchorLinkScrolling(obj.id);
94    } else {
95      // body is not loaded yet - we wait 100 ms.
96      setTimeout(function () {
97        aiResizeIframe(obj, resizeWidth);
98      }, 100);
99    }
100  } catch (e) {
101    if (console && console.error) {
102      console.error(
103        'Advanced iframe configuration error: You have enabled the resize of the iframe for pages on the same domain. But you use an iframe page on a different domain. You need to use the external workaround like described in the settings. Also check the next log. There the browser message for this error is displayed.');
104      console.log(e);
105    }
106  }
107}
108
109function aiHandleAnchorLinkScrolling(iframeId) {
110  var iframejQuery = jQuery('#' + iframeId);
111  var posIframeTop = iframejQuery.offset().top;
112
113  iframejQuery.contents().find('body').on('click', "a[href^='#']", function () {
114    var anchorId = jQuery(this).attr('href');
115    var anchorElem = jQuery('#' + iframeId).contents().find(anchorId);
116
117    if (anchorElem.length !== 0) {
118      var anchorPositionTop = anchorElem.offset().top;
119      var totalPosition = Math.round(posIframeTop + anchorPositionTop + 2);
120      jQuery("html,body").scrollTop(totalPosition);
121    }
122  });
123}
124
125/**
126 * returns the position of a #hash in the iframe or -1 if none was found.
127 */
128
129function aiGetIframeHash(url) {
130  var hash = url.split('#')[1];
131  return (hash) ? hash : '-1';
132}
133
134/**
135 *  Get the iframe height
136 */
137function aiGetIframeHeight(obj) {
138  var bodyHeight = Math.max(obj.contentWindow.document.body.scrollHeight,
139    obj.contentWindow.document.body.offsetHeight,
140    obj.contentWindow.document.documentElement.scrollHeight,
141    obj.contentWindow.document.documentElement.offsetHeight);
142  return bodyHeight + aiExtraSpace;
143}
144
145/**
146 *  Get the iframe width
147 */
148function aiGetIframeWidth(obj) {
149  var oldWidth = obj.width;
150  obj.width = 1; // set to 1 because otherwise I don't get the minimum width
151  obj.style.width = '1px';
152  var bodyWidth = Math.max(obj.contentWindow.document.body.scrollWidth,
153    obj.contentWindow.document.body.offsetWidth,
154    obj.contentWindow.document.documentElement.scrollWidth,
155    obj.contentWindow.document.documentElement.offsetWidth);
156  if (bodyWidth !== 1) { // avoid that fully responsive sites do not get displayed at all.
157    obj.width = bodyWidth;
158    obj.style.width = bodyWidth + 'px';
159  } else {
160    obj.width = oldWidth;
161    obj.style.width = oldWidth + 'px';
162  }
163  return bodyWidth;
164}
165
166/**
167 *  Get the current width of the iframe inside the parent.
168 */
169function aiGetParentIframeWidth(obj) {
170  if (obj != null) {
171    const iframejQuery = jQuery('#' + obj.id);
172    if (iframejQuery.length !== 0) {
173      return iframejQuery.width();
174    }
175    return -1;
176  }
177}
178
179/**
180 *  Resizes an iframe to a given height.
181 *  this is used for xss enabled iframes.
182 *  Please read the documentation!
183 */
184function aiResizeIframeHeightById(id, nHeight) {
185  aiDebugExtended("aiResizeIframeHeightById - id: " + id + ", nHeight: " + nHeight);
186  try {
187    var fCallback = window['resizeCallback' + id];
188    fCallback();
189    var height = parseInt(nHeight, 10) + aiExtraSpace;
190    var iframe = document.getElementById(id);
191    if (iframe === null) {
192      if (console && console.error) {
193        console.error('Advanced iframe configuration error: The iframe to resize could not be found. The id of the iframe and the one defined for ai_external.js (' + id
194          + ') are most likely different! Check your settings.');
195        return;
196      }
197    }
198    var oldScrollposition = jQuery(document).scrollTop();
199    iframe.height = height;
200    iframe.style.height = height + 'px';
201    jQuery("html,body").scrollTop(oldScrollposition);
202    if (aiEnableCookie && aiExtraSpace === 0) {
203      aiWriteCookie(height);
204    }
205    // send the new height to the parent if it is a wrapped call
206    var parentResizeCall = window['aiExecuteWorkaround_' + id];
207    if (parentResizeCall != null) {
208      parentResizeCall();
209    }
210  } catch (e) {
211    if (console && console.error) {
212      console.error('Advanced iframe configuration error: The id of the parent and the external workaround are different! Check your settings.');
213      console.log(e);
214    }
215  }
216}
217
218/**
219 * Scrolls the parent window to the top.
220 * This is e.g. wanted when you have a link in the iframe and you want that the
221 * page starts at the top and not that only the iframe changes.
222 *
223 * Sometimes are 2 onload events after another. To prevent that this causes
224 * a jump to the top a delay of 1 sec is used for the increase of the counter.
225 */
226function aiScrollToTop(id, position) {
227  aiDebugExtended("aiScrollToTop - id: " + id + ", position: " + position);
228
229  if (aiOnloadEventsCounter > 0) {
230    var posTop = 0;
231    if (position === 'iframe') {
232      posTop = jQuery('#' + id).offset().top;
233    }
234    setTimeout(function () {
235      aiDebugExtended("aiScrollToTop - posTop: " + posTop);
236      window.scrollTo(0, posTop);
237    }, 100);
238  }
239  setTimeout(function () {
240    aiOnloadEventsCounter++;
241  }, 1000);
242}
243
244/**
245 * Writes the last height to the cookie.
246 */
247function aiWriteCookie(height) {
248  var cookieName = 'ai-last-height';
249  if (aiId !== '') {
250    cookieName = cookieName + '-' + aiId;
251  }
252  document.cookie = cookieName + '=' + height;
253}
254
255/**
256 * Reads the cookie and preset the height of the iframe
257 */
258function aiUseCookie() {
259  var cookieName = 'ai-last-height';
260  if (aiId !== '') {
261    cookieName = cookieName + '-' + aiId;
262  }
263  var allcookies = document.cookie;
264  // Get all the cookies pairs in an array
265  var cookiearray = allcookies.split(';');
266  // Now take key value pair out of this array
267  for (var i = 0; i < cookiearray.length; i++) {
268    var name = cookiearray[i].split('=')[0];
269    var value = cookiearray[i].split('=')[1];
270    // cookie does exist and has a numeric value
271    if (name === cookieName && value !== null && aiIsNumeric(value)) {
272      var iframe = document.getElementById(aiId);
273      iframe.height = parseInt(value, 10);
274      iframe.style.height = value + 'px';
275    }
276  }
277}
278
279/**
280 *  check if we have a numeric input
281 */
282function aiIsNumeric(input) {
283  return !isNaN(input);
284}
285
286/**
287 * Disable the additional_height input field
288 */
289function aiDisableHeight() {
290  jQuery('#additional_height').attr('readonly', 'readonly')
291  .val('0');
292}
293
294/**
295 * Enable the additional_height input field
296 */
297function aiEnableHeight() {
298  jQuery('#additional_height').removeAttr('readonly');
299}
300
301/**
302 * Removes all elements from an iframe except the given one
303 *
304 * @param iframeId id of the iframe
305 * @param showElement the id, class (jQuery syntax) of the element that should be displayed.
306 */
307function aiShowElementOnly(iframeId, showElement) {
308  aiDebugExtended("aiShowElementOnly");
309  try {
310    var iframe = jQuery(iframeId).contents().find('body');
311    var selectedBox = iframe.find(showElement).clone(true, true);
312    iframe.find('*').not(jQuery('script')).remove();
313    iframe.prepend(selectedBox);
314  } catch (e) {
315    if (console && console.error) {
316      console.error(
317        'Advanced iframe configuration error: You have enabled to show only one element of the iframe for pages on the same domain. But you use an iframe page on a different domain. You need to use the pro version of the external workaround like described in the settings. Also check the next log. There the browser message for this error is displayed.');
318      console.log(e);
319    }
320  }
321}
322
323function aiCheckIfValidTarget(evt, elements) {
324  var targ;
325  if (!evt) {
326    evt = window.event;
327  }
328  if (evt.target) {
329    targ = evt.target;
330  } else if (evt.srcElement) {
331    targ = evt.srcElement;
332  }
333  if (targ.nodeType === 3) {
334    targ = targ.parentNode;
335  }
336
337  var parts = elements.split(',');
338  // check each part if we have a match...
339  for (var i = 0; i < parts.length; ++i) {
340    var selectorArray = parts[i].split(':');
341    if (selectorArray[0].toLowerCase() === targ.nodeName.toLowerCase()) {
342      if (selectorArray.length > 1) {
343        if (targ.id.toLowerCase().indexOf(selectorArray[1].toLowerCase()) !== -1) {
344          return true;
345        }
346      } else {
347        return true;
348      }
349    }
350  }
351  return false;
352}
353
354function aiOpenSelectorWindow(url) {
355  aiDebugExtended("aiOpenSelectorWindow");
356  var localWidth = jQuery('#width').val();
357  var localHeight = jQuery('#ai-height-0').val();
358
359  if (localWidth.indexOf('%') >= 0 || Number(localWidth) < 900) {
360    localWidth = 900;
361  }
362  localWidth = Number(localWidth) + 40;
363  if (localWidth > (screen.width)) {
364    localWidth = screen.width;
365  }
366  if (localHeight.indexOf('%') >= 0) {
367    localHeight = screen.height;
368  } else {
369    localHeight = Number(localHeight) + 480;
370  }
371  if (localHeight > (screen.height - 50)) {
372    localHeight = screen.height - 50;
373  }
374  var options = 'width=' + localWidth + ',height=' + localHeight + ',left=0,top=0,resizable=1,scrollbars=1';
375  var popup_window = window.open(url, '', options);
376  popup_window.focus();
377}
378
379function aiDisableAiResizeOptions(value) {
380  jQuery('#onload_resize_delay').prop('readonly', value);
381  jQuery('input[id=store_height_in_cookie1]:radio, input[id=store_height_in_cookie2]:radio').attr('disabled', value);
382  jQuery('#additional_height').prop('readonly', value);
383  jQuery('input[id=onload_resize_width1]:radio, input[id=onload_resize_width2]:radio').attr('disabled', value);
384  jQuery('#resize_on_click').prop('readonly', value);
385  jQuery('#resize_on_click_elements').prop('readonly', value);
386  jQuery('#resize_on_ajax').prop('readonly', value);
387  jQuery('input[id=resize_on_ajax_jquery1]:radio, input[id=resize_on_ajax_jquery2]:radio').attr('disabled', value);
388
389  var selector = '#onload_resize_delay, #store_height_in_cookie1, #additional_height, #onload_resize_width1, ';
390  selector += '#resize_on_click, #resize_on_click_elements, #resize_on_ajax, #resize_on_ajax_jquery1';
391  aiDisableTextSection(value, selector);
392}
393
394function aiDisablePartOfIframeOptions(value) {
395  jQuery('#show_part_of_iframe_x').prop('readonly', value);
396  jQuery('#show_part_of_iframe_y').prop('readonly', value);
397  jQuery('#show_part_of_iframe_height').prop('readonly', value);
398  jQuery('#show_part_of_iframe_width').prop('readonly', value);
399  jQuery('input[id=show_part_of_iframe_allow_scrollbar_horizontal1]:radio, input[id=show_part_of_iframe_allow_scrollbar_horizontal2]:radio').attr('disabled', value);
400  jQuery('input[id=show_part_of_iframe_allow_scrollbar_vertical1]:radio, input[id=show_part_of_iframe_allow_scrollbar_vertical2]:radio').attr('disabled', value);
401  jQuery('#show_part_of_iframe_next_viewports').prop('readonly', value);
402  jQuery('input[id=show_part_of_iframe_next_viewports_loop1]:radio, input[id=show_part_of_iframe_next_viewports_loop2]:radio').attr('disabled', value);
403  jQuery('#show_part_of_iframe_new_window').prop('readonly', value);
404  jQuery('#show_part_of_iframe_new_url').prop('readonly', value);
405  jQuery('input[id=show_part_of_iframe_next_viewports_hide1]:radio, input[id=show_part_of_iframe_next_viewports_hide2]:radio').attr('disabled', value);
406  jQuery('#show_part_of_iframe_style').prop('readonly', value);
407  jQuery('input[id=show_part_of_iframe_zoom1]:radio, input[id=show_part_of_iframe_zoom2]:radio, input[id=show_part_of_iframe_zoom3]:radio').attr('disabled', value);
408  jQuery('.media-query-input').prop('readonly', value);
409
410  var selector = '#show_part_of_iframe_x, #show_part_of_iframe_y, #show_part_of_iframe_height, #show_part_of_iframe_width, ';
411  selector += '#show_part_of_iframe_allow_scrollbar_horizontal1, #show_part_of_iframe_next_viewports, #show_part_of_iframe_next_viewports_loop1, ';
412  selector += '#show_part_of_iframe_new_window, #show_part_of_iframe_new_url, #show_part_of_iframe_next_viewports_hide1, #show_part_of_iframe_style, ';
413  selector += '#show_part_of_iframe_zoom1, #show_part_of_iframe_allow_scrollbar_vertical1, #add-media-query-show_part_of_iframe_media_query';
414  aiDisableTextSection(value, selector);
415
416  if (value) {
417    jQuery('#add-media-query-show_part_of_iframe_media_query').hide();
418    jQuery('.ai-delete').hide();
419  } else {
420    jQuery('#add-media-query-show_part_of_iframe_media_query').show();
421    jQuery('.ai-delete').show();
422  }
423
424}
425
426function aiDisableLazyLoadOptions(value) {
427  jQuery('#enable_lazy_load_threshold').prop('readonly', value);
428  jQuery('#enable_lazy_load_fadetime').prop('readonly', value);
429  jQuery('input[id=enable_lazy_load_reserve_space1]:radio, input[id=enable_lazy_load_reserve_space2]:radio').attr('disabled', value);
430  jQuery('input[id=enable_lazy_load_manual1]:radio, input[id=enable_lazy_load_manual2]:radio, input[id=enable_lazy_load_manual3]:radio').attr('disabled', value);
431
432  var selector = '#enable_lazy_load_threshold, #enable_lazy_load_fadetime, #enable_lazy_load_reserve_space1, #enable_lazy_load_manual1';
433  aiDisableTextSection(value, selector);
434}
435
436function aiDisableIframeAsLayerOptions(value) {
437  jQuery('input[id=show_iframe_as_layer_full]:radio').attr('disabled', value);
438  jQuery('#show_iframe_as_layer_header_file').prop('readonly', value);
439  jQuery('#show_iframe_as_layer_header_height').prop('readonly', value);
440  jQuery('#show_iframe_as_layer_autoclick_delay').prop('readonly', value);
441  jQuery('#show_iframe_as_layer_autoclick_hide_time').prop('readonly', value);
442  jQuery('input[id=show_iframe_as_layer_header_position1]:radio, input[id=show_iframe_as_layer_header_position2]:radio').attr('disabled', value);
443  jQuery('input[id=show_iframe_as_layer_full1]:radio, input[id=show_iframe_as_layer_full2]:radio, input[id=show_iframe_as_layer_full3]:radio').attr('disabled', value);
444  jQuery('input[id=show_iframe_as_layer_keep_content1]:radio, input[id=show_iframe_as_layer_keep_content2]:radio').attr('disabled', value);
445
446  var selector = '#show_iframe_as_layer_full, #show_iframe_as_layer_header_file, #show_iframe_as_layer_header_height, ';
447  selector += '#show_iframe_as_layer_header_position1, #show_iframe_as_layer_full1, #show_iframe_as_layer_keep_content1, ';
448  selector += '#show_iframe_as_layer_autoclick_delay, #show_iframe_as_layer_autoclick_hide_time';
449
450  aiDisableTextSection(value, selector);
451
452}
453
454function aiDisableAddParamOptions(value) {
455  jQuery('input[id=add_iframe_url_as_param_direct1]:radio, input[id=add_iframe_url_as_param_direct2]:radio').attr('disabled', value);
456  jQuery('#add_iframe_url_as_param_prefix').prop('readonly', value);
457  var selector = '#add_iframe_url_as_param_prefix, #add_iframe_url_as_param_direct1';
458  aiDisableTextSection(value, selector);
459}
460
461function aiDisableTextSection(value, selector) {
462  if (value) {
463    jQuery(selector).closest('tr').addClass('disabled');
464  } else {
465    jQuery(selector).closest('tr').removeClass('disabled');
466  }
467}
468
469var aiInstance;
470
471/**
472 *  This function initializes all checks that are done by Javascript
473 *  on the admin page like enabling disabling fields...
474 */
475function aiInitAdminConfiguration(isPro, acc_type) {
476  // enable checkbox of onload_resize_delay and if resize is set to true external workaround is set to false
477  if (jQuery('input[type=radio][name=onload_resize]:checked').val() === 'false') {
478    aiDisableAiResizeOptions(true);
479  }
480  jQuery('input[type=radio][name=onload_resize]').click(function () {
481    if (jQuery(this).val() === 'true') {
482      jQuery('input:radio[name=enable_external_height_workaround]')[1].checked = true; // set to external!
483      aiDisableAiResizeOptions(false);
484    } else {
485      jQuery('#onload_resize_delay').val('');
486      aiDisableAiResizeOptions(true);
487
488    }
489  });
490
491  // if external workaround is set to to true resize on load is set to false and the
492  // onload_resize_delay is made readonly
493  jQuery('input[type=radio][name=enable_external_height_workaround]').click(function () {
494    if (jQuery(this).val() === 'true') {
495      jQuery('input:radio[name=onload_resize]')[1].checked = true;
496      jQuery('#onload_resize_delay').val('');
497      aiDisableAiResizeOptions(true);
498    }
499  });
500
501  // Show only a part of the iframe enable/disable
502  if (jQuery('input[type=radio][name=show_part_of_iframe]:checked').val() === 'false') {
503    aiDisablePartOfIframeOptions(true);
504  }
505  jQuery('input[type=radio][name=show_part_of_iframe]').click(function () {
506    if (jQuery(this).val() === 'false') {
507      aiDisablePartOfIframeOptions(true);
508    } else {
509      aiDisablePartOfIframeOptions(false);
510    }
511  });
512
513  // show_iframe_as_layer enable/disable
514  if (jQuery('input[type=radio][name=show_iframe_as_layer]:checked').val() === 'false') {
515    aiDisableIframeAsLayerOptions(true);
516  }
517  jQuery('input[type=radio][name=show_iframe_as_layer]').click(function () {
518    if (jQuery(this).val() === 'false') {
519      aiDisableIframeAsLayerOptions(true);
520    } else {
521      aiDisableIframeAsLayerOptions(false);
522    }
523  });
524
525  // if expert mode
526  if (jQuery('input[type=radio][name=expert_mode]:checked').val() === 'true') {
527    jQuery('.description').css('display', 'none');
528    jQuery('table.form-table th').css('cursor', 'pointer')
529    .css('padding-top', '8px')
530    .css('padding-bottom', '2px')
531    .click(function () {
532      jQuery('.description').css('display', 'none');
533      jQuery('.description', jQuery(this).parent()).css('display', 'block');
534    });
535    jQuery('table.form-table td').css('padding-top', '5px').css('padding-bottom', '5px');
536  }
537  jQuery('input[type=radio][name=expert_mode]').click(function () {
538    if (jQuery(this).val() === 'false') {
539      jQuery('.description').css('display', 'block');
540      jQuery('table.form-table th').css('cursor', 'auto')
541      .css('padding-top', '20px')
542      .css('padding-bottom', '20px')
543      .off('click');
544      jQuery('table.form-table td').css('padding-top', '15px').css('padding-bottom', '15px');
545    } else {
546      jQuery('.description').css('display', 'none');
547      jQuery('table.form-table th').css('cursor', 'pointer')
548      .css('padding-top', '8px')
549      .css('padding-bottom', '2px')
550      .click(function () {
551        jQuery('.description').css('display', 'none');
552        jQuery('.description', jQuery(this).parent()).css('display', 'block');
553      });
554      jQuery('table.form-table td').css('padding-top', '5px').css('padding-bottom', '5px');
555    }
556  });
557
558  const accordionjQuery = jQuery('#accordion');
559  accordionjQuery.find('h1').click(function () {
560    jQuery(this).next().slideToggle(aiAccTime);
561  }).next().hide();
562
563  accordionjQuery.find('a').click(function () {
564    var hash = jQuery(this).prop('hash');
565    var hash_only = '#h1-' + hash.substring(1);
566    jQuery(hash_only).next().show();
567    location.hash = hash_only;
568  });
569
570  // lazy load
571  if (jQuery('input[type=radio][name=enable_lazy_load_manual]:checked').val() === 'false') {
572    jQuery('#enable_lazy_load_manual_element').prop('readonly', true);
573  }
574
575  jQuery('input[type=radio][name=enable_lazy_load_manual]').click(function () {
576    if (jQuery(this).val() === 'false' || jQuery(this).val() === 'auto') {
577      jQuery('#enable_lazy_load_manual_element').prop('readonly', true);
578    } else {
579      jQuery('#enable_lazy_load_manual_element').prop('readonly', false);
580    }
581  });
582
583  // add_iframe_url_as_param
584  if (jQuery('input[type=radio][name=add_iframe_url_as_param]:checked').val() === 'false') {
585    aiDisableAddParamOptions(true);
586  }
587  jQuery('input[type=radio][name=add_iframe_url_as_param]').click(function () {
588    aiDisableAddParamOptions(jQuery(this).val() === 'false');
589  });
590
591  if (jQuery('input[type=radio][name=enable_lazy_load]:checked').val() === 'false') {
592    aiDisableLazyLoadOptions(true);
593    jQuery('#enable_lazy_load_manual_element').prop('readonly', true);
594  }
595
596  jQuery('input[type=radio][name=enable_lazy_load]').click(function () {
597    if (jQuery(this).val() === 'false') {
598      aiDisableLazyLoadOptions(true);
599      jQuery('#enable_lazy_load_manual_element').prop('readonly', true);
600    } else {
601      aiDisableLazyLoadOptions(false);
602      const valueLazyLoad = jQuery('input[type=radio][name=enable_lazy_load_manual]:checked').val();
603      if (valueLazyLoad === 'false' || valueLazyLoad === 'auto') {
604        jQuery('#enable_lazy_load_manual_element').prop('readonly', true);
605      } else {
606        jQuery('#enable_lazy_load_manual_element').prop('readonly', false);
607      }
608    }
609  });
610
611  jQuery('.confirmation').on('click', function () {
612    return confirm('Are you sure? Selecting OK will set all settings to the default.');
613  });
614
615  jQuery('.confirmation-file').on('click', function () {
616    return confirm('Do you really want to delete the file?');
617  });
618
619  jQuery('.confirmation-hash').on('click', function () {
620    return confirm('Do you really want to delete the hash/URL cache?');
621  });
622
623  jQuery('a.post').click(function (e) {
624    e.stopPropagation();
625    e.preventDefault();
626    var href = this.href;
627    var parts = href.split('?');
628    var url = parts[0];
629    var params = parts[1].split('&');
630    var pp, inputs = '';
631    url += '?' + params[0];
632    for (var i = 1, n = params.length; i < n; i++) {
633      pp = params[i].split('=');
634      inputs += '<input type="hidden" name="' + pp[0] + '" value="' + pp[1] + '" />';
635    }
636    // Add twg-options nonce
637    var nonceValue = jQuery('#twg-options').val();
638    inputs += '<input type="hidden" name="twg-options" value="' + nonceValue + '" />';
639
640    jQuery('body').append('<form action="' + url + '" method="post" id="poster">' + inputs + '</form>');
641    jQuery('#poster').submit();
642  });
643
644  jQuery('.ai-input-search').keyup(function () {
645    var searchTerm = jQuery('input.ai-input-search').val().toLowerCase();
646    aiSettingsSearch(searchTerm, acc_type);
647  })
648  .on('click', function () {
649    setTimeout(function () {
650      var searchTerm = jQuery('input.ai-input-search').val().toLowerCase();
651      aiSettingsSearch(searchTerm, acc_type);
652    }, 100);
653  });
654
655  jQuery(document).on('click', '.nav-tab-wrapper a', function () {
656    var current_tab = jQuery(this).attr('id');
657    jQuery('section').hide();
658    jQuery('section.' + current_tab).show();
659    jQuery('#current_tab').val(current_tab.substr(4, 1));
660    jQuery('.nav-tab').removeClass('nav-tab-active');
661    jQuery(this).addClass('nav-tab-active');
662    jQuery(this).blur();
663
664    return false;
665  });
666
667  // set the links between tabs and open the right one at the right section.
668  jQuery(document).on('click', 'a#external-workaround-link', function () {
669    jQuery('.external-workaround').click();
670    location.hash = 'tab_3';
671    // no flash
672    aiShowHeader('tab_3');
673    return false;
674  });
675  jQuery(document).on('click', 'a#resize-same-link', function () {
676    jQuery('.advanced-settings-tab').click();
677    jQuery('#id-advanced-resize').removeClass('closed');
678    location.hash = 'id-advanced-resize';
679    // no flash
680    aiShowHeader('id-advanced-resize');
681    return false;
682  });
683  jQuery(document).on('click', 'a.jquery-help-link', function () {
684    jQuery('.help-tab').click();
685    jQuery('#id-help-jquery').removeClass('closed');
686    jQuery('#jquery-help').show();
687    location.hash = 'id-help-jquery';
688    // no flash
689    aiShowHeader('id-help-jquery');
690    return false;
691  });
692  jQuery(document).on('click', 'a#browser-detection-link', function () {
693    jQuery('.help-tab').click();
694    jQuery('#id-help-browser').removeClass('closed');
695    jQuery('#browser-help').show();
696    location.hash = 'id-help-browser';
697    // no flash
698    aiShowHeader('id-help-browser');
699    return false;
700  });
701  jQuery(document).on('click', 'a.howto-id-link', function () {
702    jQuery('.help-tab').click();
703    jQuery('#id-help-id').removeClass('closed');
704    location.hash = 'id-help-id';
705    // no flash
706    aiShowHeader('id-help-id');
707    return false;
708  });
709  jQuery(document).on('click', '.modifycontent-link', function () {
710    jQuery('.advanced-settings-tab').click();
711    jQuery('#id-advanced-modify-iframe').removeClass('closed');
712    location.hash = 'id-advanced-modify-iframe';
713    aiShowHeader('id-advanced-modify-iframe', 'tr-' + jQuery(this).data('detail'));
714    return false;
715  });
716
717  jQuery(document).on('click', '.id-modify-css-iframe-link', function () {
718    jQuery('.advanced-settings-tab').click();
719    jQuery('#id-advanced-modify-iframe').removeClass('closed');
720    location.hash = 'id-modify-css-iframe';
721    aiShowHeader('id-advanced-modify-iframe', 'tr-' + jQuery(this).data('detail'));
722    return false;
723  });
724
725  jQuery(document).on('click', '.modify-target', function () {
726    jQuery('.advanced-settings-tab').click();
727    jQuery('#id-advanced-modify-iframe').removeClass('closed');
728    location.hash = 'id-modify-target';
729    aiShowHeader('id-advanced-modify-iframe', 'tr-' + jQuery(this).data('detail'));
730    return false;
731  });
732
733  jQuery(document).on('click', 'a.link-external-domain', function () {
734    jQuery('#id-external-different').removeClass('closed');
735    location.hash = '#id-external-different';
736    // no flash - 'id-external-different'
737    aiShowHeader('id-external-different');
738    return false;
739  });
740  jQuery(document).on('click', 'a.link-id-external-ai-config-post', function () {
741    jQuery('#id-external-ai-config-post').removeClass('closed');
742    location.hash = '#id-external-ai-config-post';
743    aiShowHeader('id-external-ai-config-post', 'tr-use_post_message');
744    return false;
745  });
746  jQuery(document).on('click', 'a.link-id-external-ai-overview', function () {
747    jQuery('#id-external-ai-overview').removeClass('closed');
748    location.hash = '#id-external-ai-overview';
749    aiShowHeader('id-external-ai-overview', 'id-external-ai-overview');
750    return false;
751  });
752  jQuery(document).on('click', 'a.post-message-help-link', function () {
753    jQuery('.help-tab').click();
754    jQuery('#id-help-communication').removeClass('closed');
755    location.hash = '#id-help-communication';
756    aiShowHeader('id-help-communication', 'id-help-communication');
757    return false;
758  });
759
760  jQuery(document).on('click', 'a.enable-admin', function () {
761    jQuery('.options-tab').click();
762    jQuery('#id-options-display').removeClass('closed');
763    location.hash = '#id-options-display';
764    aiShowHeader('id-options-display', 'tr-demo');
765    return false;
766  });
767
768  jQuery(document).on('click', 'a.enter-registration', function () {
769    jQuery('.options-tab').click();
770    jQuery('#id-options-registration').removeClass('closed');
771    location.hash = '#id-options-registration';
772    aiShowHeader('id-options-registration', 'tr-demo');
773    return false;
774  });
775  
776  jQuery(document).on('click', 'a.enter-pro', function () {
777    jQuery('.options-tab').click();
778    jQuery('#id-options-pro').removeClass('closed');
779    location.hash = '#id-options-pro';
780    aiShowHeader('id-options-pro', 'first');
781    return false;
782  });
783
784  jQuery(document).on('click', 'a#user-help-link', function () {
785    jQuery('#user-help').css('display', 'block');
786    return false;
787  });
788  jQuery(document).on('click', 'a#user-meta-link', function () {
789    jQuery('#meta-help').css('display', 'block');
790    return false;
791  });
792
793  jQuery(document).on('click', '#ai-selector-help-link', function () {
794    jQuery('#ai-selector-help').slideDown(1000);
795    return false;
796  });
797
798  jQuery(document).on('click', '.ai-selector-help-link-move', function () {
799    jQuery('#ai-selector-help').show('slow');
800    location.hash = '#ai-selector-help-link';
801    // no flash
802    aiShowHeader('ai-selector-help-link');
803    return false;
804  });
805
806  jQuery('#ai_form').submit(function () {
807    aiSetScrollposition();
808  });
809
810  // Close postboxes that should be closed.
811  jQuery('.if-js-closed').removeClass('if-js-closed').addClass('closed');
812  // Postboxes setup.
813  if (typeof postboxes !== 'undefined') {
814    postboxes.add_postbox_toggles('toplevel_page_advanced-iframe');
815  }
816
817  jQuery('.ai-spinner').css('display', 'none');
818  jQuery("#" + acc_type).next().show();
819
820  jQuery(document).on('click', '#test-pro-admin.is-permanent-closable button', function () {
821    closeInfoPermanent('test-pro-admin');
822  });
823
824  jQuery(document).on('click', '#show-registration-message.is-permanent-closable button', function () {
825    closeInfoPermanent('show-registration-message');
826  });
827
828  jQuery(document).on('click', '#show-version-message.is-permanent-closable button', function () {
829    closeInfoPermanent('show-version-message');
830  });
831
832  jQuery(document).on('click', '.mq-breakpoint-height a', function (evt) {
833    jQuery(this).parent().remove();
834    aiUpdateHeightHiddenField('height');
835    evt.preventDefault();
836    return false;
837  });
838
839  jQuery(document).on('click', 'a#add-media-query-height', function (evt) {
840    // count existing elements
841    var nextNr = jQuery(".mq-breakpoint-height").length + 1;
842    jQuery(this).parent().append('<div id="breakpoint-row-height-' + nextNr + '" class="mq-breakpoint-height">' +
843      '<input type="text" id="ai-height-' + nextNr
844      + '" style="width:150px;margin-top:5px;"  onblur="aiCheckHeightNumber(this, \'height\');" placeholder="Insert height"/> &nbsp;
844Breakpoint: '
845      +
846      '<input type="text" id="ai-breakpoint-height-' + nextNr
847      + '" style="width:130px;" onblur="aiCheckHeightNumber(this, \'height\');" placeholder="Insert breakpoint"/>' +
848      '<a id="delete-media-query-' + nextNr + '" href="#" class="delete ai-delete">Delete</a>');
849    evt.preventDefault();
850    return false;
851  });
852
853  jQuery(document).on('click', '.mq-breakpoint-show_part_of_iframe_media_query a', function (evt) {
854    jQuery(this).parent().remove();
855    aiUpdateHeightHiddenFieldMediaQuery('show_part_of_iframe_media_query');
856    evt.preventDefault();
857    return false;
858  });
859
860  jQuery(document).on('click', 'a#add-media-query-show_part_of_iframe_media_query', function (evt) {
861    // count existing elements
862    var nextNr = jQuery(".mq-breakpoint-show_part_of_iframe_media_query").length + 1;
863    jQuery(this).parent().append('<div id="breakpoint-row-show_part_of_iframe_media_query-' + nextNr
864      + '" class="mq-breakpoint-show_part_of_iframe_media_query">' +
865      'x: <input type="text" id="ai-x-show_part_of_iframe_media_query-' + nextNr + '" class="media-query-input" ' +
866      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="x"/>' +
867      ' &nbsp;y: <input type="text" id="ai-y-show_part_of_iframe_media_query-' + nextNr + '" class="media-query-input" '
868      +
869      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="y"/>' +
870      ' &nbsp;w: <input type="text" id="ai-w-show_part_of_iframe_media_query-' + nextNr + '" class="media-query-input" '
871      +
872      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="width"/>' +
873      ' &nbsp;h: <input type="text" id="ai-h-show_part_of_iframe_media_query-' + nextNr + '" class="media-query-input" '
874      +
875      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="height"/>' +
876      ' &nbsp;iframe width: <input type="text" id="ai-i-show_part_of_iframe_media_query-' + nextNr
877      + '" class="media-query-input" style="width:100px;" ' +
878      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="iframe width"/>'
879      +
880      ' &nbsp;Breakpoint: <input type="text" id="ai-breakpoint-show_part_of_iframe_media_query-' + nextNr
881      + '" class="media-query-input" style="width:130px;" ' +
882      ' onblur="aiCheckHeightNumberMediaQuery(this, \'show_part_of_iframe_media_query\');" placeholder="Insert breakpoint"/>'
883      +
884      '<a id="delete-media-query-show_part_of_iframe_media_query-' + nextNr
885      + '" href="#" class="delete ai-delete">Delete</a>');
886    evt.preventDefault();
887    return false;
888  });
889}
890
891function aiCheckHeightNumber(element, id) {
892  aiCheckInputNumber(element);
893  aiUpdateHeightHiddenField(id);
894}
895
896function aiCheckHeightNumberMediaQuery(element, id) {
897  aiCheckInputNumber(element);
898  aiUpdateHeightHiddenFieldMediaQuery(id);
899}
900
901function aiUpdateHeightHiddenField(id) {
902  var heightDefault = jQuery('#ai-' + id + '-0').val();
903  var breakpoints = [];
904  jQuery('.mq-breakpoint-' + id).each(function () {
905
906    var heightChild = jQuery(this).children().eq(0).val();
907    var breakpointChild = jQuery(this).children().eq(1).val();
908
909    if (heightChild !== '' && breakpointChild !== '') {
910      breakpoints.push({
911        heightChild: heightChild,
912        breakpointChild: breakpointChild
913      });
914    }
915  });
916
917  // we sort to have higher breakpoints first. Because of css cascading styles order is important
918  breakpoints.sort(function (a, b) {
919    return b.breakpointChild - a.breakpointChild;
920  });
921
922  let output = heightDefault;
923  breakpoints.forEach(function (element) {
924    output += ',' + element.heightChild + '|' + element.breakpointChild;
925  });
926  jQuery('#' + id).val(output);
927  const descriptionjQuery = jQuery('#description-' + id);
928  const newVal = descriptionjQuery.html().split('Shortcode attribute: ')[0];
929  descriptionjQuery.html(newVal + 'Shortcode attribute: ' + id + '="' + output + '"');
930}
931
932function aiUpdateHeightHiddenFieldMediaQuery(id) {
933  var breakpoints = [];
934  jQuery('.mq-breakpoint-' + id).each(function () {
935
936    var mediaX = jQuery(this).children().eq(0).val();
937    var mediaY = jQuery(this).children().eq(1).val();
938    var mediaW = jQuery(this).children().eq(2).val();
939    var mediaH = jQuery(this).children().eq(3).val();
940    var mediaIW = jQuery(this).children().eq(4).val();
941    var breakpointChild = jQuery(this).children().eq(5).val();
942
943    if ((mediaX !== '' || mediaY !== '' || mediaW !== '' || mediaH !== '' || mediaIW !== '') &&
944      breakpointChild !== '') {
945      breakpoints.push({
946        mediaX: mediaX,
947        mediaY: mediaY,
948        mediaW: mediaW,
949        mediaH: mediaH,
950        mediaIW: mediaIW,
951        breakpointChild: breakpointChild
952      });
953    }
954  });
955
956  // we sort to have higher breakpoints first. Because of css cascading styles order is important
957  breakpoints.sort(function (a, b) {
958    return b.breakpointChild - a.breakpointChild;
959  });
960
961  let output = '';
962  breakpoints.forEach(function (element) {
963    output += ',' + element.mediaX + '|' + element.mediaY + '|' +
964      element.mediaW + '|' + element.mediaH + '|' + element.mediaIW + '|' + element.breakpointChild
965  });
966  output = output.replace(/(^,)|(,$)/g, "");
967  jQuery('#' + id).val(output);
968  // update description
969  const descriptionjQuery = jQuery('#description-' + id);
970  const newVal = descriptionjQuery.html().split('Shortcode attribute: ')[0];
971  descriptionjQuery.html(newVal + 'Shortcode attribute: ' + id + '="' + output + '"');
972}
973
974function aiSettingsSearch(searchTerm, accType) {
975  var found = 0;
976
977  if (searchTerm !== '') {
978    jQuery('#ai p').not('.form-table p').hide();
979    jQuery('#ai ul').not('.form-table ul').hide();
980    jQuery('#ai ol').not('.form-table ol').hide();
981    if (accType !== 'false') {
982      jQuery('#ai h1').not('.show-always').hide();
983      jQuery('#ai #accordion').attr('id', 'acc');
984      jQuery('#ai #acc > div').show();
985      jQuery('#ai #spacer-div').show();
986    }
987    jQuery('#ai h2,#ai .icon_ai,#ai h3,#ai h4').not('.show-always').hide();
988    jQuery('#ai .form-table').addClass('ai-remove-margin');
989    jQuery('#ai hr, .signup_account_container, .config-file-block').hide();
990    jQuery('#ai .hide-always').hide();
991    jQuery('#ai .hide-search').hide();
992    jQuery('#ai .postbox-container').not('.show-always').hide();
993    jQuery('#ai .show-always p').show();
994    jQuery('#ai .show-always ul').show();
995    jQuery('#ai .show-always ol').show();
996    jQuery('#ai .show-always h2,#ai .show-always .icon_ai,#ai .show-always h3,#ai .show-always h4').show();
997  } else {
998    jQuery('#ai p').not('.form-table p').show();
999    jQuery('#ai section .ai-anchor').show();
1000    jQuery('#ai ul').not('.form-table ul').show();
1001    jQuery('#ai ol').not('.form-table ol').show();
1002    if (accType !== 'false') {
1003      jQuery('#ai h1').not('.show-always').show();
1004      jQuery('#ai #acc').attr('id', 'accordion');
1005      jQuery('#ai #accordion > div').hide();
1006      jQuery('#ai #spacer-div').hide();
1007    }
1008    jQuery('#ai h2,#ai .icon_ai,#ai h3,#ai h4').not('.show-always').show();
1009    jQuery('#ai .form-table').removeClass('ai-remove-margin');
1010    jQuery('#ai hr, .signup_account_container, .config-file-block').show();
1011    jQuery('#ai .sub-domain-container').show();
1012    jQuery('#ai .hide-search').show();
1013    jQuery('#ai .hide-always').hide();
1014    jQuery('#ai .postbox-container').show();
1015
1016    setTimeout(function () {
1017      jQuery('#ai .postbox-container .closed .inside').css('display', '');
1018    }, 5);
1019
1020  }
1021
1022  const markTabHeaderjQuery = jQuery('#ai .mark-tab-header');
1023  markTabHeaderjQuery.removeClass('mark-tab-header');
1024
1025  var firstHit = '';
1026
1027  // check the search.
1028  jQuery('#ai tr').each(function () {
1029    var $this = jQuery(this);
1030    var valueLabel = $this.find('th').text();
1031    var valueDescription = $this.find('p.description').text();
1032
1033    valueLabel = (valueLabel !== undefined) ? valueLabel.toLowerCase() : 'XXXXXXX';
1034    valueDescription = (valueDescription !== undefined) ? valueDescription.toLowerCase() : 'XXXXXXX';
1035
1036    if (valueLabel.indexOf(searchTerm) === -1 && valueDescription.indexOf(searchTerm) === -1) {
1037      if ($this.parents('.show-always').length === 0) {
1038        $this.addClass('hide-setting');
1039      }
1040    } else {
1041      $this.closest('table').prevAll('h2:first').show();
1042      $this.closest('.postbox-container').show();
1043      $this.closest('.postbox-container').find('h2, .inside').show();
1044      $this.closest('table').prevAll('#ai .icon_ai:first').show();
1045      $this.closest('table').nextAll('p.button-submit:first').show();
1046      $this.removeClass('hide-setting');
1047      $this.closest('.hide-search').show();
1048
1049      if (searchTerm.length > 2) {
1050        var headerId = $this.closest('section').attr('class');
1051        if (headerId !== undefined) {
1052          jQuery('#' + headerId).addClass('mark-tab-header');
1053          if (firstHit === '') {
1054            firstHit = headerId;
1055          }
1056        }
1057      }
1058      found++;
1059    }
1060  });
1061  if (found === 0) {
1062    jQuery('#ai-input-search-result').show();
1063    markTabHeaderjQuery.removeClass('mark-tab-header');
1064  } else {
1065    jQuery('#ai-input-search-result').hide();
1066    // https://github.com/padolsey/findAndReplaceDOMText
1067    aiInstance && aiInstance.revert();
1068    if (searchTerm !== '' && searchTerm.length > 2) {
1069      var regex = RegExp(searchTerm, 'gi');
1070      aiInstance = findAndReplaceDOMText(document.getElementById('tab_wrapper'), {
1071        find: regex,
1072        wrap: 'em'
1073      });
1074    }
1075    jQuery('#' + firstHit).click();
1076
1077  }
1078}
1079
1080/**
1081 *  Resizes the iframe with a certain ratio.
1082 *  Width is read and the height is than calculated.
1083 */
1084function aiResizeIframeRatio(obj, ratio) {
1085  aiDebugExtended("aiResizeIframeRatio");
1086  var width = jQuery('#' + obj.id).width();
1087  var valueRatio = parseFloat(ratio.replace(',', '.'));
1088  var newHeight = Math.ceil(width * valueRatio);
1089  obj.height = newHeight;
1090  obj.style.height = newHeight + 'px';
1091}
1092
1093/**
1094 * Generate a shortcode string from the current settings.
1095 */
1096function aiGenerateShortcode(isPro) {
1097  var output = '[advanced_iframe ';
1098
1099  // default section
1100  const securityKey = jQuery('#securitykey').val();
1101  if (securityKey !== '') {
1102    output += 'securitykey="' + securityKey + '" ';
1103  }
1104  output += 'use_shortcode_attributes_only="true" ';
1105
1106  var include_html_val = jQuery('#include_html').val();
1107  var include_url_val = jQuery('#include_url').val();
1108  var document_domain_add = jQuery('#document_domain_add').val();
1109
1110  if (include_html_val === undefined || (include_html_val === '' && include_url_val === '')) {
1111    var src = jQuery('#src').val();
1112    if (src === '') {
1113      alert('Required url is missing.');
1114    } else {
1115      output += 'src="' + src + '" ';
1116    }
1117
1118    output += aiGenerateTextShortcode('src_hide');
1119    output += aiGenerateTextShortcode('width');
1120    output += aiGenerateTextShortcode('height');
1121    output += aiGenerateRadioShortcode('scrolling', 'none');
1122    output += aiGenerateRadioShortcode('add_surrounding_p', 'false');
1123    output += aiGenerateRadioShortcode('enable_ios_mobile_scolling', 'false');
1124    output += aiGenerateTextShortcode('marginwidth');
1125    output += aiGenerateTextShortcode('marginheight');
1126    output += aiGenerateTextShortcode('frameborder');
1127    output += aiGenerateRadioShortcode('transparency', 'true');
1128    output += aiGenerateTextShortcode('class');
1129    output += aiGenerateTextShortcode('style');
1130    output += aiGenerateTextShortcodeWithDefault('id', 'advanced_iframe');
1131    output += aiGenerateTextShortcode('name');
1132    output += aiGenerateRadioShortcode('allowfullscreen', 'false');
1133    output += aiGenerateTextShortcode('safari_fix_url');
1134    output += aiGenerateTextShortcode('sandbox');
1135    output += aiGenerateTextShortcode('title');
1136    output += aiGenerateTextShortcode('allow');
1137    output += aiGenerateRadioShortcode('loading', 'lazy');
1138    output += aiGenerateTextShortcode('referrerpolicy');
1139    output += aiGenerateTextShortcode('custom');
1140
1141    // advanced settings
1142    output += aiGenerateTextShortcode('url_forward_parameter');
1143    output += aiGenerateTextShortcode('map_parameter_to_url');
1144    output += aiGenerateRadioShortcode('add_iframe_url_as_param', 'false');
1145    output += aiGenerateTextShortcode('add_iframe_url_as_param_prefix');
1146    output += aiGenerateRadioShortcode('add_iframe_url_as_param_direct', 'false');
1147    output += aiGenerateRadioShortcode('use_iframe_title_for_parent', 'false');
1148    output += aiGenerateRadioShortcode('onload_scroll_top', 'false');
1149    output += aiGenerateRadioShortcode('hide_page_until_loaded', 'false');
1150    output += aiGenerateRadioShortcode('show_iframe_loader', 'false');
1151    output += aiGenerateTextShortcode('hide_content_until_iframe_color');
1152    output += aiGenerateTextShortcode('iframe_zoom');
1153    output += aiGenerateRadioShortcode('use_zoom_absolute_fix', 'false');
1154    output += aiGenerateRadioShortcode('auto_zoom', 'false');
1155    output += aiGenerateTextShortcode('auto_zoom_by_ratio');
1156
1157    output += aiGenerateRadioShortcode('enable_responsive_iframe', 'false');
1158    output += aiGenerateTextShortcode('iframe_height_ratio');
1159
1160    output += aiGenerateRadioShortcode('enable_lazy_load', 'false');
1161    output += aiGenerateTextShortcodeWithDefault('enable_lazy_load_threshold', '3000');
1162    output += aiGenerateRadioShortcode('enable_lazy_load_reserve_space', 'true');
1163
1164    output += aiGenerateTextShortcode('enable_lazy_load_fadetime');
1165    output += aiGenerateRadioShortcode('enable_lazy_load_manual', 'false');
1166    output += aiGenerateRadioShortcode('enable_lazy_load_manual_element', 'false');
1167    output += aiGenerateTextShortcode('reload_interval');
1168
1169    // modify the parent page
1170    output += aiGenerateTextShortcode('hide_elements');
1171    output += aiGenerateTextShortcode('content_id');
1172    output += aiGenerateTextShortcode('content_styles');
1173    output += aiGenerateTextShortcode('parent_content_css');
1174    output += aiGenerateRadioShortcode('add_css_class_parent', 'false');
1175
1176    output += aiGenerateTextShortcode('change_parent_links_target');
1177    output += aiGenerateRadioShortcode('show_iframe_as_layer', 'false');
1178    output += aiGenerateRadioShortcode('show_iframe_as_layer_full', 'false');
1179
1180    output += aiGenerateTextShortcode('show_iframe_as_layer_autoclick_delay');
1181    output += aiGenerateTextShortcode('show_iframe_as_layer_autoclick_hide_time');
1182    output += aiGenerateTextShortcode('show_iframe_as_layer_header_file');
1183    output += aiGenerateTextShortcodeWithDefault('show_iframe_as_layer_header_height', '100');
1184    output += aiGenerateRadioShortcode('show_iframe_as_layer_header_position', 'top');
1185    output += aiGenerateRadioShortcode('show_iframe_as_layer_keep_content', 'true');
1186
1187    // show only a part of the iframe
1188    var showPartOfIframe = aiGenerateRadioShortcode('show_part_of_iframe', 'false');
1189    output += showPartOfIframe;
1190
1191    if (showPartOfIframe !== '') {
1192      output += aiGenerateTextShortcodeWithDefault('show_part_of_iframe_x', -1);
1193      output += aiGenerateTextShortcodeWithDefault('show_part_of_iframe_y', -1);
1194      output += aiGenerateTextShortcode('show_part_of_iframe_width');
1195      output += aiGenerateTextShortcode('show_part_of_iframe_height');
1196      output += aiGenerateTextShortcode('show_part_of_iframe_media_query');
1197      output += aiGenerateRadioShortcode('show_part_of_iframe_allow_scrollbar_horizontal', 'false');
1198      output += aiGenerateRadioShortcode('show_part_of_iframe_allow_scrollbar_vertical', 'false');
1199      output += aiGenerateTextShortcode('show_part_of_iframe_style');
1200      output += aiGenerateRadioShortcode('show_part_of_iframe_zoom', 'false');
1201
1202      output += aiGenerateTextShortcode('show_part_of_iframe_next_viewports');
1203      output += aiGenerateRadioShortcode('show_part_of_iframe_next_viewports_loop', 'false');
1204      output += aiGenerateTextShortcode('show_part_of_iframe_new_window');
1205      output += aiGenerateTextShortcode('show_part_of_iframe_new_url');
1206      output += aiGenerateRadioShortcode('show_part_of_iframe_next_viewports_hide', 'false');
1207    }
1208
1209    // hide cover parts on an iframe
1210    output += aiGenerateTextShortcode('hide_part_of_iframe');
1211    output += aiGenerateRadioShortcode('fullscreen_button', 'false');
1212    output += aiGenerateTextShortcode('fullscreen_button_hide_elements');
1213    output += aiGenerateRadioShortcode('fullscreen_button_full', 'false');
1214    output += aiGenerateRadioShortcode('fullscreen_button_style', 'black');
1215
1216    // same domain
1217    output += aiGenerateRadioShortcode('add_css_class_iframe', 'false');
1218    output += aiGenerateTextShortcode('iframe_hide_elements');
1219    output += aiGenerateTextShortcode('onload_show_element_only');
1220    output += aiGenerateTextShortcode('iframe_content_id');
1221    output += aiGenerateTextShortcode('iframe_content_styles');
1222    output += aiGenerateTextShortcode('iframe_content_css');
1223    output += aiGenerateTextShortcode('change_iframe_links');
1224    output += aiGenerateTextShortcode('change_iframe_links_target');
1225    output += aiGenerateTextShortcode('change_iframe_links_href');
1226
1227    // resize content height
1228    output += aiGenerateTextShortcode('onload');
1229    output += aiGenerateRadioShortcode('onload_resize', 'false');
1230    output += aiGenerateTextShortcode('onload_resize_delay');
1231    output += aiGenerateRadioShortcode('store_height_in_cookie', 'false');
1232    output += aiGenerateTextShortcode('additional_height');
1233    output += aiGenerateRadioShortcode('onload_resize_width', 'false');
1234    output += aiGenerateTextShortcode('resize_on_ajax');
1235    output += aiGenerateRadioShortcode('resize_on_ajax_jquery', 'true');
1236    output += aiGenerateTextShortcode('resize_on_click');
1237    output += aiGenerateTextShortcodeWithDefault('resize_on_click_elements', 'a');
1238
1239    output += aiGenerateTextShortcode('resize_on_element_resize');
1240    output += aiGenerateTextShortcodeWithDefault('resize_on_element_resize_delay', '250');
1241
1242    // tabs
1243    output += aiGenerateTextShortcode('tab_hidden');
1244    output += aiGenerateTextShortcode('tab_visible');
1245    // cross domain ....
1246    output += aiGenerateRadioShortcode('add_document_domain', 'false');
1247    //
1248    if (document_domain_add === 'true') {
1249      output += aiGenerateTextShortcode('document_domain');
1250    }
1251    output += aiGenerateRadioShortcode('enable_external_height_workaround', 'external');
1252    output += aiGenerateRadioShortcode('hide_page_until_loaded_external', 'false');
1253    output += aiGenerateTextShortcode('pass_id_by_url');
1254    output += aiGenerateRadioShortcode('multi_domain_enabled', 'true');
1255    if (isPro === 'true') {
1256      output += aiGenerateRadioShortcode('use_post_message', 'true');
1257    } else {
1258      output += aiGenerateRadioShortcode('use_post_message', 'false');
1259    }
1260    // additional files
1261    output += aiGenerateTextShortcode('additional_css');
1262    output += aiGenerateTextShortcode('additional_js');
1263    output += aiGenerateTextShortcode('additional_js_file_iframe');
1264    output += aiGenerateTextShortcode('additional_css_file_iframe');
1265  } else { // include content directly
1266    if (include_html_val === '') {
1267      output += aiGenerateTextShortcode('include_url');
1268      output += aiGenerateTextShortcode('include_content');
1269      output += aiGenerateTextShortcode('include_height');
1270      output += aiGenerateTextShortcode('include_fade');
1271      output += aiGenerateRadioShortcode('include_hide_page_until_loaded', 'false');
1272    } else {
1273      output += aiGenerateTextShortcode('include_html');
1274    }
1275  }
1276  // options
1277  output += aiGenerateRadioShortcode('debug_js', 'false');
1278  output = output.slice(0, -1);
1279  output += ']';
1280  jQuery('#gen-shortcode').html(output);
1281}
1282
1283/**
1284 * Generate a text shortcode with default
1285 */
1286function aiGenerateTextShortcodeWithDefault(field, defaultValue) {
1287  var output = '';
1288  var value = jQuery('#' + field);
1289  var val = value.val();
1290  if (value.length > 0 && val !== '' && val !== defaultValue) {
1291    output = field + '="' + val + '" ';
1292  }
1293  return output;
1294}
1295
1296/**
1297 * Generate a text shortcode if the value is not empty or != 0
1298 */
1299function aiGenerateTextShortcode(field) {
1300  var output = '';
1301  var value = jQuery('#' + field);
1302  var val = value.val();
1303  if (value.length > 0 && val !== '' && val !== '0') {
1304    output = field + '="' + val + '" ';
1305  }
1306  return output;
1307}
1308
1309/**
1310 * Generate a radio shortcode with default
1311 */
1312function aiGenerateRadioShortcode(field, defaultValue) {
1313  var output = '';
1314  var value = jQuery('input:radio[name=' + field + ']:checked');
1315  var val = value.val();
1316
1317  if (field === 'enable_ios_mobile_scolling') {
1318    field = 'enable_ios_mobile_scrolling';
1319  }
1320
1321  if (value.length > 0 && val !== defaultValue) {
1322    output += field + '="' + val + '" ';
1323  }
1324  return output;
1325}
1326
1327/**
1328 * Add a css class to the parents to enable that the iframe parents
1329 * can be identified very easy. Is an is ist set ai-class-<id> is used.
1330 * Otherwise a-class-<number> with an increasing number is used.
1331 */
1332function aiAddCssClassAllParents(element) {
1333  var parents = jQuery(element).parentsUntil('html');
1334  var ai_class = 'ai-class-';
1335  for (var i = 0; i < parents.length; i++) {
1336    var id = jQuery(parents[i]).attr('id');
1337    if (typeof id !== 'undefined') {
1338      if (id.indexOf('ai-') !== 0) {
1339        jQuery(parents[i]).addClass(ai_class + id);
1340      }
1341    } else {
1342      jQuery(parents[i]).addClass(ai_class + i);
1343    }
1344  }
1345}
1346
1347function aiAutoZoomExternalHeight(id, width, height, responsive) {
1348  aiDebugExtended("aiAutoZoomExternalHeight");
1349  var parentWidth = aiAutoZoomExternal(id, width, responsive);
1350  var zoomRatio = window['zoom_' + id];
1351  var oldScrollposition = jQuery(document).scrollTop();
1352  var newHeight = Math.ceil(height * zoomRatio);
1353  jQuery('#ai-zoom-div-' + id).css('height', newHeight);
1354  jQuery("html,body").scrollTop(oldScrollposition);
1355  return parentWidth;
1356}
1357
1358function aiAutoZoomExternal(id, width, responsive) {
1359  aiDebugExtended("aiAutoZoomExternal");
1360  var obj = document.getElementById(id);
1361  var objAround = document.getElementById('ai-zoom-div-' + id);
1362  var jObj = jQuery('#' + id);
1363
1364  if (responsive === 'true') {
1365    jObj.css('max-width', '100%');
1366  }
1367  var iframeWidth = width;
1368  var parentWidth = aiGetParentIframeWidth(obj);
1369  if (parentWidth === iframeWidth) {
1370    // we check again the surrounding div as some browser do return the zoomes value!
1371    parentWidth = aiGetParentIframeWidth(objAround);
1372  }
1373  var zoomRatio = parentWidth / iframeWidth;
1374  var zoomRatioRounded = Math.floor(zoomRatio * 100) / 100;
1375  if (zoomRatioRounded > 1) {
1376    zoomRatioRounded = 1;
1377  }
1378
1379  aiSetZoom(id, zoomRatioRounded);
1380  window['zoom_' + id] = zoomRatioRounded;
1381  jObj.width(iframeWidth).css('max-width', 'none');
1382  return parentWidth;
1383}
1384
1385function aiAutoZoom(id, responsive, ratio) {
1386  aiDebugExtended("aiAutoZoom");
1387  var parts = ratio.split('|');
1388  ratio = parts[0];
1389  var width = -1;
1390  if (parts.length !== 1) {
1391    width = parts[1];
1392  }
1393
1394  var obj = document.getElementById(id);
1395  var iframeWidth;
1396  if (width === -1) {
1397    obj.width = 1; // set to 1 because otherwise the iframe does never get smaller.
1398    obj.style.width = '1px';
1399    iframeWidth = aiGetIframeWidth(obj);
1400    obj.width = iframeWidth;
1401    obj.style.width = iframeWidth + 'px';
1402  } else {
1403    iframeWidth = width;
1404  }
1405
1406  var parentWidth = aiAutoZoomExternal(id, iframeWidth, responsive);
1407  if (ratio === '') {
1408    aiResizeIframe(obj, false);
1409  } else {
1410    var newheight = Math.ceil(iframeWidth * ratio);
1411    obj.height = newheight;
1412    obj.style.height = newheight + 'px';
1413    // set the height of the zoom div
1414    const zoomDivjQuery = jQuery('#ai-zoom-div-' + obj.id);
1415    if (zoomDivjQuery.length !== 0) {
1416      var zoom = window['zoom_' + obj.id];
1417      zoomDivjQuery.css('height', Math.ceil(newheight * zoom));
1418    }
1419  }
1420  return parentWidth;
1421}
1422
1423/**
1424 * Set the zoom div settings dynamically.
1425 */
1426function aiSetZoom(id, zoom) {
1427
1428  var obj = jQuery('#' + id);
1429
1430  obj.css({
1431    '-ms-transform': 'scale(' + zoom + ')',
1432    '-moz-transform': 'scale(' + zoom + ')',
1433    '-o-transform': 'scale(' + zoom + ')',
1434    '-webkit-transform': 'scale(' + zoom + ')',
1435    'transform': 'scale(' + zoom + ')'
1436  });
1437}
1438
1439function aiAutoZoomViewport(id, full) {
1440
1441  var viewportDiv = jQuery(id);
1442  var outerDiv = viewportDiv.parent();
1443  var counter = 0;
1444
1445  // We only go up and look for divs which are not from ai or p elements which are rendered by mistake.
1446  while (outerDiv.is('p') || (outerDiv.attr('id') !== undefined && outerDiv.attr('id').indexOf('ai-') === 0)) {
1447    outerDiv = outerDiv.parent();
1448    if (counter++ > 10) {
1449      alert('Unexpected div structure. Please disable the zoom.');
1450      break;
1451    }
1452  }
1453
1454  var viewportDivWidth = viewportDiv.width();
1455  var outer_div_width = outerDiv.width();
1456  var viewportDivHeight = viewportDiv.height();
1457  var zoom = outer_div_width / viewportDivWidth;
1458
1459  if (full === 'true' && zoom > 1) {
1460    zoom = 1;
1461  }
1462
1463  aiSetZoom(viewportDiv.attr('id'), zoom);
1464  // set the margin because otherwise it is normally "centered" in the old area
1465  var marginLeft = -Math.round((viewportDivWidth - viewportDivWidth * zoom) / 2);
1466  var marginTop = -Math.round((viewportDivHeight - viewportDivHeight * zoom) / 2);
1467  viewportDiv.css({
1468    'margin-left': marginLeft + 'px',
1469    'margin-right': marginLeft + 'px',
1470    'margin-top': marginTop + 'px',
1471    'margin-bottom': marginTop + 'px'
1472  });
1473
1474}
1475
1476function aiResetAiSettings() {
1477  jQuery('#action').val('reset');
1478}
1479
1480function aiCheckInputNumber(inputField) {
1481  inputField.value = inputField.value.split(' ').join('');
1482  var f = inputField.value;
1483  if (inputField.value === '') {
1484    return;
1485  }
1486  var match = f.match(
1487    /^(-)?([\d.])+(px|%|em|pt|vh|vw|rem|ch)?([-+])?([\d.]){0,7}(px|%|em|pt|vh|vw|rem|ch)?$/);
1488
1489  if (!match) {
1490    alert(
1491      'Please check the value you have entered. Only numbers with a dot or with an optional px, %, em or pt are allowed.');
1492    setTimeout(function () {
1493      inputField.focus();
1494    }, 10);
1495  }
1496}
1497
1498function aiCheckInputPurchaseCode(inputField) {
1499  inputField.value = inputField.value.split(' ').join('');
1500  var f = inputField.value;
1501  if (inputField.value === '') {
1502    return;
1503  }
1504
1505  if (!f.match(/^([a-f0-9]{8})-(([a-f0-9]{4})-){3}([a-f0-9]{12})$/i)) {
1506    alert('Please check the value you have entered. Your input seems not to be a valid purchase code.');
1507    inputField.value = '';
1508    setTimeout(function () {
1509      inputField.focus();
1510    }, 10);
1511  }
1512}
1513
1514function aiCheckInputNumberOnly(inputField) {
1515  inputField.value = inputField.value.split(' ').join('');
1516  var f = inputField.value;
1517  if (inputField.value === '') {
1518    inputField.value = '0';
1519    return;
1520  }
1521  var match = f.match(/^(-)?([\d.])+$/);
1522
1523  if (!match) {
1524    alert(
1525      'Please check the value you have entered. Only numbers without a dot or optional px, %, em or pt are allowed.');
1526    setTimeout(function () {
1527      inputField.focus();
1528    }, 10);
1529  }
1530}
1531
1532// https://codepen.io/anon/pen/baaLYB/
1533function aiShowHeader(id, element) {
1534  var y = jQuery(window).scrollTop();
1535  jQuery(window).scrollTop(y - 40);
1536  if (element !== undefined) {
1537    aiFlashElement(element);
1538  }
1539}
1540
1541function aiFlashElement(element) {
1542  setTimeout(function () {
1543    jQuery('#' + element).css('background-color', '#eee');
1544  }, 500);
1545  setTimeout(function () {
1546    jQuery('#' + element).css('background-color', '#fff');
1547  }, 900);
1548  setTimeout(function () {
1549    jQuery('#' + element).css('background-color', '#eee');
1550  }, 1300);
1551  setTimeout(function () {
1552    jQuery('#' + element).css('background-color', '#fff');
1553  }, 1700);
1554}
1555
1556function aiSetScrollposition() {
1557  var scrollposition = jQuery(document).scrollTop();
1558  jQuery('#scrollposition').val(scrollposition); // +32
1559}
1560
1561function aiResetShowPartOfAnIframe(id) {
1562  jQuery('#' + id).css('top', '0px').css('left', '0px').css('position', 'static');
1563  jQuery('#ai-div-' + id).css('width', 'auto').css('height', 'auto').css('overflow', 'auto').css('position', 'static');
1564}
1565
1566function aiShowLayerIframe(event, id, path, showLoadingIcon, keep, reload) {
1567  aiDebugExtended("aiShowLayerIframe");
1568  keep = (keep === undefined) ? false : keep;
1569  reload = (reload === undefined) ? true : reload;
1570
1571  var layerId = '#' + id;
1572  jQuery('#ai-zoom-div-' + id).show()
1573  .css('visibility', 'visible');
1574  jQuery(layerId).show();
1575  jQuery(layerId).css('visibility', 'visible');
1576
1577  if (jQuery('#ai-layer-div-' + id).length) {
1578    layerId = '#ai-layer-div-' + id;
1579    jQuery(layerId).show()
1580    .css('visibility', 'visible');
1581  }
1582
1583  jQuery('html').css('overflow-y', 'visible');
1584  jQuery('body').css('overflow', 'hidden')
1585  .append('<img alt="" id="ai_backlink" src="' + path + 'close.png" style="z-index:100005;position:fixed;top:0;right:0;cursor:pointer" />');
1586
1587  var icon = '<!-- -->';
1588  if (reload && showLoadingIcon === 'true') {
1589    icon = '<div id="ai-div-loader-global" style="position: fixed;z-index:100004;margin-left:-33px;left: 50%;top:50%;margin-top:-33px"><img src="' + path
1590      + 'loader.gif" width="66" height="66" title="Loading" alt="Loading"></div>';
1591  }
1592
1593  if (jQuery('#ai_backlayer').length === 0) { // we do not have a layer yet...
1594    jQuery(layerId).parent().append(
1595      '<div id="ai_backlayer" style="z-index:100001;position:fixed;top:0;left:0;width:100%;height:100%;background-color: rgba(50,50,50,0.5);overflow:hidden;cursor:pointer"><!-- --></div>' + icon);
1596  }
1597
1598  jQuery('#ai_backlink, #ai_backlayer').click(function () {
1599    aiHideLayerIframe(id, keep);
1600  });
1601  if (!reload) {
1602    event.preventDefault();
1603    event.stopPropagation();
1604  }
1605}
1606
1607function aiHideLayerIframe(id, keep) {
1608  aiDebugExtended("aiHideLayerIframe");
1609  const idjQuery = jQuery('#' + id);
1610  idjQuery.css('visibility', 'hidden');
1611  if (!keep) {
1612    idjQuery.attr('src', 'about:blank');
1613    aiLayerIframeHrefs[id] = 'about:blank';
1614  }
1615  jQuery('#ai-zoom-div-' + id).css('visibility', 'hidden');
1616  jQuery('#ai-layer-div-' + id).css('visibility', 'hidden');
1617  jQuery('#ai_backlink').remove();
1618  jQuery('#ai_backlayer').remove();
1619  jQuery('#ai-div-loader-global').remove();
1620  jQuery('body').css('overflow', 'auto');
1621  jQuery('html').css('overflow-y', 'scroll');
1622}
1623
1624/**
1625 * As the src of an iframe cannot be read from a remote domain we remember
1626 * the urls from the links here for each opened iframe.
1627 */
1628var aiLayerIframeHrefs = [];
1629
1630/**
1631 * Check if the location of the iframe is already the one of the link.
1632 * The iframe is only loaded if it is was not loaded already.
1633 *
1634 * true - if src and url of the iframe is different and need to be loaded
1635 * false - if it is already the same;
1636 */
1637function aiCheckReload(link, id) {
1638  var iframeSrc;
1639  if (typeof aiLayerIframeHrefs[id] === 'undefined') {
1640    iframeSrc = jQuery('#' + id).attr('src');
1641  } else {
1642    iframeSrc = aiLayerIframeHrefs[id];
1643  }
1644  var linkHref = jQuery(link).attr('href');
1645  // alert(linkHref + ": iframe:" + iframeSrc);
1646  aiLayerIframeHrefs[id] = linkHref;
1647  return (iframeSrc !== linkHref);
1648}
1649
1650function aiChangeTitle(id) {
1651  aiDebugExtended("aiChangeTitle");
1652  try {
1653    var title = document.getElementById(id).contentDocument.title;
1654    if (title !== null && title !== 'undefined' && title !== '') {
1655      document.title = title;
1656    }
1657  } catch (e) {
1658    if (console && console.error) {
1659      console.error(
1660        'Advanced iframe configuration error: You have enabled to add the title if the iframe to the parent on the same domain. But you use an iframe page on a different domain. You need to use the pro version of the external workaround like described in the settings. Also check the next log. There the browser message for this error is displayed.');
1661      console.log(e);
1662    }
1663  }
1664}
1665
1666/**
1667 * This changes the current url and adds or updates the
1668 * existing parameter with the given url
1669 */
1670function aiChangeUrlParam(loc, param, orig, prefix, isDirect) {
1671  aiDebugExtended("aiChangeUrlParam");
1672  var newUrl;
1673  var keepSlash = false;
1674
1675  // add protocol if // is used in the shortcode
1676  if (orig.lastIndexOf("//", 0) !== -1) {
1677    orig = location.protocol + orig;
1678  }
1679
1680  if (loc !== encodeURIComponent(orig)) {
1681    newUrl = aiSetGetParameter(param, loc);
1682    var removeProtocol = true;
1683    if (prefix.startsWith('hash')) {
1684      return aiGetUrlMapping(loc, param, prefix);
1685    } else if (prefix) {
1686      var repUrl = newUrl.replace(prefix, '');
1687      if (repUrl === newUrl) {
1688        removeProtocol = false;
1689      }
1690      newUrl = repUrl;
1691    }
1692
1693    // remove protocol
1694    if (removeProtocol) {
1695      newUrl = newUrl.replace('http%3A%2F%2F', '');
1696      if (window.location.href.toLowerCase().lastIndexOf("http:", 0) !== -1) {
1697        newUrl = newUrl.replace('https%3A%2F%2F', 's|');
1698      } else {
1699        newUrl = newUrl.replace('https%3A%2F%2F', '');
1700      }
1701    }
1702
1703    if (isDirect) {
1704      newUrl = aiRemoveQueryString(window.location.href);
1705      var locDecoded = decodeURIComponent(loc);
1706      var queryStart = locDecoded.indexOf('?');
1707      var hashStart = locDecoded.indexOf('#');
1708      if (queryStart !== -1) {
1709        var queryPart = locDecoded.slice(queryStart + 1);
1710        newUrl += '?' + queryPart;
1711        keepSlash = true;
1712      } else if (hashStart !== -1) {
1713        var hashPart = locDecoded.slice(hashStart + 1);
1714        newUrl += '?hash=' + hashPart;
1715        keepSlash = true;
1716      }
1717    }
1718    if (aiEndsWidth(newUrl, param + "=")) {
1719      newUrl = aiRemoveURLParameter(newUrl, param);
1720    }
1721  } else {
1722    var fullUrl = window.location.href;
1723    // remove param/* first
1724    fullUrl = fullUrl.split("/" + param + "/", 1)[0];
1725    newUrl = aiRemoveURLParameter(fullUrl, param);
1726  }
1727  var seperator = (newUrl.indexOf('?') >= 0) ? '&' : '?';
1728  newUrl = newUrl.replace("#", seperator + "hash=");
1729  aiSetBrowserUrl(newUrl, keepSlash);
1730}
1731
1732function aiGetUrlMappingUrl(param, prefix, id) {
1733  var fullUrl = window.location.href;
1734
1735  param = param.replace(":short", "");
1736  var newUrl = aiRemoveURLParameter(fullUrl, param);
1737  if (prefix.startsWith('hashrewrite')) {
1738    // remove param/* first
1739    var queryString = "";
1740    if (newUrl.indexOf('?') >= 0) {
1741      var newUrlArray = newUrl.split('?');
1742      newUrl = newUrlArray[0];
1743      queryString = '?' + newUrlArray[1];
1744    }
1745    var baseUrl = newUrl.split("/" + param + "/", 1)[0];
1746    // add the path before the query string
1747    if (!aiEndsWidth(baseUrl, "/")) {
1748      baseUrl += '/';
1749    }
1750    var path = param + "/";
1751    newUrl = baseUrl + path + id + queryString;
1752  } else {
1753    var seperator = (newUrl.indexOf('?') >= 0) ? '&' : '?';
1754    newUrl += seperator + param + "=" + id;
1755  }
1756  return newUrl;
1757}
1758
1759function aiSetBrowserUrl(newUrl, keepSlash) {
1760  if (aiSupportsHistoryApi()) {
1761    if (!keepSlash) {
1762      newUrl = newUrl.replace(/%2F/g, '/');
1763    }
1764    window.history.pushState({}, '', newUrl);
1765    // I asume the back button is clicked.
1766    window.onpopstate = function (event) {
1767      if (event && event.state) {
1768        window.history.back();
1769      }
1770    };
1771  }
1772}
1773
1774function aiRemoveQueryString(loc) {
1775  if (loc.indexOf('%3F') >= 0) {
1776    return loc.split('%3F')[0];
1777  } else if (loc.indexOf('?') >= 0) {
1778    return loc.split('?')[0];
1779  } else {
1780    return loc;
1781  }
1782}
1783
1784function aiGetUrlMapping(url, param, prefix) {
1785  var data = {
1786    action: 'aip_map_url_action',
1787    security: MyAjax.security,
1788    url: url
1789  };
1790
1791  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
1792  jQuery.post(MyAjax.ajaxurl, data, function (id) {
1793    var newUrl = aiGetUrlMappingUrl(param, prefix, id);
1794    aiSetBrowserUrl(newUrl, false);
1795  });
1796}
1797
1798function closeInfoPermanent(id) {
1799  var data = {
1800    action: 'aip_close_message_permanent',
1801    security: MyAjax.security,
1802    id: id
1803  };
1804  // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
1805  var message = 'The message before will only appear again when you reset the advanced iframe settings.';
1806  if (id === 'show-discount-message') {
1807    message = 'The message of advanced iframe shown before will only appear again when you reset the advanced iframe settings or a new discount is available.';
1808  } else if (id === 'show-registration-message') {
1809    message = 'The message will appear again after a page reload.';
1810  }
1811
1812  jQuery.post(MyAjax.ajaxurl, data, function () {
1813    jQuery('h1').after('<div class="message-notice notice notice-success"><p>' + message + '</p></div>');
1814  });
1815  setTimeout(function () {
1816    jQuery(".message-notice").fadeOut()
1817  }, 4000);
1818}
1819
1820function aiSupportsHistoryApi() {
1821  return !!(window.history && history.pushState);
1822}
1823
1824function aigetIframeLocation(id) {
1825  try {
1826    var location = document.getElementById(id).contentWindow.location;
1827    return encodeURIComponent(location);
1828  } catch (e) {
1829    if (console && console.error) {
1830      console.error(
1831        'Advanced iframe configuration error: You have enabled to add the url to the url on the same domain. But you use an iframe page on a different domain. You need to use the pro version of the external workaround like described 
1831in the settings. Also check the next log. There the browser message for this error is displayed.');
1832      console.log(e);
1833    }
1834  }
1835}
1836
1837/**
1838 * Replaces a url parameter with a given value.
1839 */
1840function aiSetGetParameter(paramName, paramValue) {
1841  var url = window.location.href;
1842  var splitAtAnchor = url.split('#');
1843  url = splitAtAnchor[0];
1844  var anchor = typeof splitAtAnchor[1] === 'undefined' ? '' : '#' + splitAtAnchor[1];
1845  if (url.indexOf(paramName + '=') >= 0) {
1846    var prefix = url.substring(0, url.indexOf(paramName + '='));
1847    var suffix = url.substring(url.indexOf(paramName + '='));
1848    suffix = suffix.substring(suffix.indexOf('=') + 1);
1849    suffix = (suffix.indexOf('&') >= 0) ? suffix.substring(suffix.indexOf('&')) : '';
1850    url = prefix + paramName + '=' + paramValue + suffix;
1851  } else {
1852    if (url.indexOf('?') < 0) {
1853      url += '?' + paramName + '=' + paramValue;
1854    } else {
1855      url += '&' + paramName + '=' + paramValue;
1856    }
1857  }
1858  return url + anchor;
1859}
1860
1861/**
1862 * Remove a given parameter from the url
1863 */
1864function aiRemoveURLParameter(url, parameter) {
1865  //prefer to use l.search if you have a location/link object
1866  var urlparts = url.split('?');
1867  if (urlparts.length >= 2) {
1868
1869    var prefix = encodeURIComponent(parameter) + '=';
1870    var pars = urlparts[1].split(/[&;]/g);
1871
1872    //reverse iteration as may be destructive
1873    for (var i = pars.length; i-- > 0;) {
1874      //idiom for string.startsWith
1875      if (pars[i].lastIndexOf(prefix, 0) !== -1) {
1876        pars.splice(i, 1);
1877      }
1878    }
1879    if (pars.length !== 0) {
1880      url = urlparts[0] + '?' + pars.join('&');
1881    } else {
1882      url = urlparts[0];
1883    }
1884    return url;
1885  } else {
1886    return url;
1887  }
1888}
1889
1890function aiEndsWidth(string, target) {
1891  return string.substr(-target.length) === target;
1892}
1893
1894/**
1895 * Adds css to the end of the body to make sure that styles are
1896 * not overwritten by inline css of any kind.
1897 */
1898function aiAddCss(id, css) {
1899  css = decodeURIComponent(css.replace(/\+/g, '%20'));
1900
1901  var body = jQuery(id).contents().find('body');
1902  var s = document.createElement('style');
1903  s.setAttribute('type', 'text/css');
1904  if (s.styleSheet) {   // IE
1905    s.styleSheet.cssText = css;
1906  } else {                // the world
1907    s.appendChild(document.createTextNode(css));
1908  }
1909  body.append(s);
1910}
1911
1912/**
1913 * add a css file to the end of the body to make sure that styles
1914 *  are not overwritten by inline css of any kind.
1915 */
1916function aiAddCssFile(id, filename) {
1917  var body = jQuery(id).contents().find('body');
1918  var link = document.createElement('link');
1919  link.rel = 'stylesheet';
1920  link.type = 'text/css';
1921  link.href = filename;
1922  body.append(link);
1923}
1924
1925/**
1926 * Add a Javascript file to the end of the body
1927 */
1928function aiAddJsFile(id, filename) {
1929  jQuery.ajaxSetup({cache: true});
1930
1931  var body = jQuery(id).contents().find('body');
1932  var script = document.createElement('script');
1933  script.type = 'text/javascript';
1934  script.src = filename;
1935  body.append(script);
1936}
1937
1938function aiPresetFullscreen() {
1939  jQuery('#style').val('position:fixed;z-index:9000;top:0px;left:0px;margin:0px');
1940  jQuery('#width').val('100%');
1941  jQuery('#ai-height-0').val('100%');
1942  jQuery('#content_id').val('html,body');
1943  jQuery('#content_styles').val('overflow:hidden');
1944  jQuery('#hide_content_until_iframe_color').val('#ffffff');
1945}
1946
1947/**
1948 * main ready function that calls all generated callbacks.
1949 * Add dynamically created functions that should be loaded
1950 * when the page is read to aiReadyCallbacks
1951 */
1952jQuery(document).ready(function () {
1953  aiDebugExtended("document.ready called");
1954
1955  // wordpress adds often p elements that have margins we remove here.
1956  jQuery('iframe').parent('p').css('margin', '0');
1957
1958  aiWindowWidth = jQuery(window).width();
1959  jQuery.each(aiReadyCallbacks, function (index, callback) {
1960    callback();
1961  });
1962
1963  jQuery('.ai-fullscreen-open').on('click', function () {
1964    jQuery(this).closest('.ai-wrapper-div').addClass("ai-fullscreen-wrapper");
1965    jQuery(this).closest('.ai-wrapper-div').find('iframe').addClass("ai-fullscreen");
1966    jQuery('.ai-fullscreen-open').hide();
1967    jQuery('.ai-fullscreen-hide').addClass("ai-fullscreen-display-none")
1968    .hide();
1969    jQuery('html,body').css('overflow', 'hidden');
1970
1971    var id = jQuery(this).data("id");
1972    // show/render the close button
1973    jQuery('.ai-fullscreen-close-' + id).show();
1974    jQuery(document).on('keydown', function (evt) {
1975      if (evt.key === "Escape") {
1976        jQuery('.ai-fullscreen-close').trigger("click");
1977      }
1978    });
1979    aiOpenFullscreen();
1980    aiInFullscreen = true;
1981  });
1982
1983  jQuery('.ai-fullscreen-close').on('click', function () {
1984    // remove css for fullscreen-open
1985    jQuery('div.ai-wrapper-div').removeClass("ai-fullscreen-wrapper")
1986    jQuery('iframe.ai-fullscreen').removeClass("ai-fullscreen");
1987    jQuery('html').css('overflow', aiOverflowHtml);
1988    jQuery('body').css('overflow', aiOverflowBody);
1989
1990    // hide/remove the close button
1991    jQuery('.ai-fullscreen-close').hide();
1992    // show the fullscreen icon again
1993    jQuery('.ai-fullscreen-open').show();
1994    jQuery('.ai-fullscreen-display-none').removeClass("ai-fullscreen-display-none");
1995    jQuery('.ai-fullscreen-hide').show();
1996
1997    jQuery(document).off("keydown");
1998    if (aiInFullscreen) {
1999      aiCloseFullscreen();
2000    }
2001
2002  });
2003
2004  setTimeout(function () {
2005    jQuery("#ai #ai-updated-text").css("visibility", "hidden")
2006  }, 4000);
2007
2008  jQuery('#ai #checkIframes').on('click', function () {
2009    jQuery('.ai-spinner').css('display', 'inline-table');
2010    jQuery(this).addClass('disabled');
2011    setTimeout(aiDisableCheckIframes, 200);
2012  });
2013
2014  var moved = false;
2015  jQuery('#aiDebugDivTotal').mousedown(function () {
2016    moved = false;
2017  }).mousemove(function () {
2018    moved = true;
2019  }).mouseup(function () {
2020    if (!moved) {
2021      var elem = jQuery('#aiDebugDiv');
2022      if (Math.floor(elem.height()) > '300') {
2023        elem.height('0px');
2024      } else {
2025        elem.height('400px');
2026      }
2027    }
2028  });
2029
2030  if (typeof ai_show_id_only !== 'undefined') {
2031    const showIdOnlyjQuery = jQuery('#' + ai_show_id_only);
2032    if (showIdOnlyjQuery.length === 0) {
2033      alert('The element with the id "' + ai_show_id_only + '" cannot be found. Please check your configuration.');
2034    } else {
2035      showIdOnlyjQuery.siblings().hide();
2036      var parents = showIdOnlyjQuery.parents();
2037      parents.siblings().hide();
2038      parents.css('padding', '0px').css('margin', '0px').css('overflow', 'hidden');
2039
2040      // we send the size of the element as post message if we are in an iframe
2041      if (parent === top) {
2042        var elementRaw = showIdOnlyjQuery[0];
2043        elementRaw.style.marginTop = elementRaw.style.marginBottom = '0';
2044        elementRaw.style.overflow = "hidden";
2045        var newHeightRaw = Math.max(elementRaw.scrollHeight, elementRaw.offsetHeight) + '';
2046        var newHeight = parseInt(newHeightRaw, 10);
2047        var data = {'aitype': 'height', 'height': newHeight, 'id': ai_show_id_only};
2048        var json_data = JSON.stringify(data);
2049        window.parent.postMessage(json_data, '*');
2050      }
2051    }
2052  }
2053});
2054
2055function aiDisableCheckIframes() {
2056  var input = jQuery("<input>").attr("type", "hidden").attr("name", "checkIframes").val("true");
2057  jQuery("#ai_form").append(input)
2058  .submit();
2059  jQuery('#checkIframes').prop('disabled', 'disabled');
2060}
2061
2062
2063function aiProcessMessage(event, id, debug, dataPostMessage, addIframeUrlAsParam, useIframeTitleForParent) {
2064  var jsObject;
2065  try {
2066    jsObject = JSON.parse(event.data);
2067  } catch (e) {
2068    // Result is not expected so we try if data is an object already
2069    // because a converter was not implemented properly.
2070    if (debug === 'debug' && console && console.log) {
2071      console.log(
2072        'Advanced iframe: The received message cannot be parsed and seems not to belong to advanced iframe pro. Please disable the postMessage debug mode if this o.k. and that this message is not shown anymore.');
2073      console.log("Advanced iframe: Unknown event: ", event);
2074    }
2075    jsObject = event.data;
2076  }
2077  try {
2078    // we only process objects from advanced iframe
2079    if (jsObject.hasOwnProperty('aitype')) {
2080      // we only process the ones for the same id here.
2081      if (id === jsObject.id) {
2082        var type = jsObject.aitype;
2083        if (type === 'debug') {
2084          aiProcessDebug(jsObject);
2085        } else if (type === 'scrollToTop') {
2086          aiProcessScrollToTop(jsObject);
2087        } else if (type === 'anchor') {
2088          aiProcessAnchor(jsObject);
2089        } else {
2090          // check if the data is of the expected
2091          if (type === 'height') {
2092            aiProcessHeight(jsObject, addIframeUrlAsParam, useIframeTitleForParent);
2093          } else if (type === 'show') {
2094            aiProcessShow(jsObject);
2095          }
2096		  
2097		  //only configured keys! 
2098          for (var key in jsObject.data) {
2099            if (jsObject.data.hasOwnProperty(key) && aiIsValidKey(key, dataPostMessage)) {
2100              jQuery(key).html(aiRemoveScriptTags(jsObject.data[key]));
2101            }
2102          }
2103        }
2104      }
2105    }
2106  } catch (e) {
2107    if (debug === 'debug' && console && console.log) {
2108      console.log('Advanced iframe: The received message do not belong to advanced iframe pro. Please disable the postMessage debug mode if this o.k. and that this message is not shown anymore.');
2109      console.log(e);
2110    }
2111  }
2112}
2113
2114/**
2115 * Checks if the key we get from the post message is in dataPostMessage saved
2116 */
2117function aiIsValidKey(key, dataPostMessage) {
2118  if (!dataPostMessage) return false;
2119
2120  var parts = dataPostMessage.split(',');
2121
2122  for (var i = 0; i < parts.length; i++) {
2123    var validKey = parts[i].split('|')[0].trim();
2124    if (validKey === key) {
2125      return true;
2126    }
2127  }
2128
2129  return false;
2130}
2131
2132function aiRemoveScriptTags(htmlString) {
2133  const temp = jQuery('<div>').html(htmlString);
2134  temp.find('script').remove();
2135  return temp.html();
2136}
2137
2138function aiProcessDebug(jsObject) {
2139  var debugData = jsObject.data;
2140  const debugDivjQuery = jQuery('#aiDebugDiv');
2141  if (debugDivjQuery.length !== 0) {
2142    debugData = debugData.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2143    debugData = debugData.replace('\"', '"').replace(/\\/g, "");
2144    debugDivjQuery.append('<p class="ai-debug-remote"> r: ' + debugData + '</p>');
2145  }
2146}
2147
2148function aiProcessScrollToTop(jsObject) {
2149  var id = jsObject.id;
2150  aiScrollToTop(id, aiOnloadScrollTop);
2151}
2152
2153function aiProcessAnchor(jsObject) {
2154  var id = jsObject.id;
2155  var position = parseInt(jsObject.position, 10);
2156  var iframeTop = jQuery("#" + id).offset().top;
2157  setTimeout(function () {
2158    jQuery("html,body").scrollTop(Math.round(iframeTop + position));
2159  }, 100);
2160}
2161
2162function aiProcessHeight(jsObject, addIframeUrlAsParam, useIframeTitleForParent) {
2163  var nHeight = jsObject.height;
2164  var nWidth = jsObject.width;
2165  var iAnchor = parseInt(jsObject.anchor, 10);
2166  var id = jsObject.id;
2167
2168  if (nHeight != null) {
2169    try {
2170	  if (addIframeUrlAsParam == "remote") {
2171		  var loc = jsObject.loc;
2172		  if (loc != null && !loc.includes("send_console_log")) {
2173			if (typeof aiChangeUrl === "function") {
2174			  aiChangeUrl(loc);
2175			}
2176		  }
2177	  }
2178	  if (useIframeTitleForParent == "remote") {
2179		  var title = jsObject.title;
2180		  if (title != null && title !== "undefined" && title !== "") {
2181			document.title = decodeURIComponent(title);
2182		  }
2183	  }
2184      if (id != null) {
2185        var iHeight = parseInt(nHeight, 10);
2186        var iWidth = parseInt(nWidth, 10);
2187        aiResizeIframeHeightId(iHeight, iWidth, id);
2188        if (!isNaN(iAnchor) && iAnchor > -1) {
2189          //
2190          var iframeTop = jQuery("#" + id).offset().top;
2191          setTimeout(function () {
2192            jQuery("html,body").scrollTop(Math.round(iframeTop + iAnchor));
2193            aiShowIframeId(id);
2194          }, 100);
2195        } else {
2196          aiShowIframeId(id);
2197        }
2198      } else {
2199        alert('Please update the ai_external.js to the current version.');
2200      }
2201    } catch (e) {
2202      if (console && console.log) {
2203        console.log(e);
2204      }
2205    }
2206  }
2207}
2208
2209function aiProcessShow(jsObject) {
2210  var id = jsObject.id;
2211
2212  try {
2213    aiShowIframeId(id);
2214  } catch (e) {
2215    if (console && console.log) {
2216      console.log(e);
2217    }
2218  }
2219}
2220
2221function aiDisableRightClick(id) {
2222  try {
2223    window.frames[id].document.oncontextmenu = function () {
2224      return false;
2225    };
2226  } catch (e) {
2227    // we ignore the error as it only works on the same domain.
2228  }
2229}
2230
2231function aiRemoveElementsFromHeight(id, height, removeElements) {
2232  const iframejQuery = jQuery('#' + id);
2233  var elementArray = removeElements.split(',');
2234  var totalHeight = 0;
2235  for (var i = 0; i < elementArray.length; i++) {
2236    try {
2237      var el = elementArray[i];
2238      if (el.includes("|")) {
2239        var rangeArray = el.split('|');
2240        var bottomElement = jQuery(rangeArray[0]);
2241        var beforeBottom = Math.round(bottomElement.offset().top + bottomElement.outerHeight(true));
2242        var nextTop = Math.round(jQuery(rangeArray[1]).offset().top);
2243        totalHeight += nextTop - beforeBottom;
2244      } else if (el === 'top') {
2245        totalHeight += Math.round(iframejQuery.offset().top);
2246      } else if (isNaN(el)) {
2247        totalHeight += jQuery(el).outerHeight(true);
2248      } else {
2249        totalHeight += parseInt(el);
2250      }
2251    } catch (e) {
2252      if (console && console.error) {
2253        console.error('Advanced iframe configuration error: The configuration of remove_elements_from_height "' + removeElements
2254          + '" is invalid. Please check if the elements you defined do exist and ids/classes are defined properly.');
2255        console.log(e);
2256      }
2257    }
2258  }
2259  var calc = 'calc(' + height + ' - ' + totalHeight + 'px)';
2260  iframejQuery.css('height', calc);
2261}
2262
2263function aiTriggerAutoOpen(id, selector, autoclickDelay, hideTime) {
2264  aiDebugExtended("aiTriggerAutoOpen");
2265
2266  if (autoclickDelay === 0) {
2267    aiOpenIframeOnClick(id, selector);
2268  } else {
2269    setTimeout(function () {
2270      aiOpenIframeOnClick(id, selector);
2271    }, autoclickDelay);
2272  }
2273
2274  var now = new Date();
2275  var time = now.getTime();
2276  var expireTime = time + (hideTime * 86400000);
2277  now.setTime(expireTime);
2278  var trimmedSelector = selector.replace(/[^A-Za-z0-9\-]/g, '');
2279  document.cookie = 'ai_disable_autoclick_iframe_' + trimmedSelector + '=Auto open is disabled until this cookie expires;expires=' + now.toUTCString() + ';path=/';
2280}
2281
2282function aiCheckAutoOpenHash(id, autoclickDelay, hideTime) {
2283  if (window.location.hash) {
2284    var hash = window.location.hash;
2285    var trimmedHash = hash.replace(/[^A-Za-z0-9\-]/g, '');
2286    trimmedHash = "#" + trimmedHash;
2287    if (jQuery(trimmedHash).length !== 0) { // id does exist
2288      if (jQuery(trimmedHash).first().attr('target') === id) { // target is 
2288iframe
2289        aiTriggerAutoOpen(id, trimmedHash, autoclickDelay, hideTime);
2290      }
2291    }
2292  }
2293}
2294
2295function aiOpenIframeOnClick(id, selector) {
2296  var myelement = jQuery(selector).first().attr("href");
2297  jQuery("#" + id).attr("src", myelement);
2298  jQuery(selector).first().click();
2299}
2300
2301// IE11 does not support includes
2302if (!String.prototype.includes) {
2303  String.prototype.includes = function (search, start) {
2304    if (typeof start !== 'number') {
2305      start = 0;
2306    }
2307    if (start + search.length > this.length) {
2308      return false;
2309    } else {
2310      return this.indexOf(search, start) !== -1;
2311    }
2312  };
2313}
2314
2315if (!String.prototype.startsWith) {
2316  String.prototype.startsWith = function (searchString, position) {
2317    position = position || 0;
2318    return this.indexOf(searchString, position) === position;
2319  };
2320}
2321
2322// aiRealFullscreen
2323/* Get the documentElement (<html>) to display the page in fullscreen */
2324var elem = document.documentElement;
2325
2326/* View in fullscreen */
2327function aiOpenFullscreen() {
2328  if (aiRealFullscreen) {
2329    if (elem.requestFullscreen) {
2330      elem.requestFullscreen();
2331    } else if (elem.webkitRequestFullscreen) { /* Safari */
2332      elem.webkitRequestFullscreen();
2333    } else if (elem.msRequestFullscreen) { /* IE11 */
2334      elem.msRequestFullscreen();
2335    }
2336  }
2337}
2338
2339/* Close fullscreen */
2340function aiCloseFullscreen() {
2341  if (aiRealFullscreen) {
2342    if (document.exitFullscreen) {
2343      document.exitFullscreen();
2344    } else if (document.webkitExitFullscreen) { /* Safari */
2345      document.webkitExitFullscreen();
2346    } else if (document.msExitFullscreen) { /* IE11 */
2347      document.msExitFullscreen();
2348    }
2349  }
2350}
2351
2352document.addEventListener('fullscreenchange', aiExitHandler);
2353document.addEventListener('webkitfullscreenchange', aiExitHandler);
2354document.addEventListener('mozfullscreenchange', aiExitHandler);
2355document.addEventListener('MSFullscreenChange', aiExitHandler);
2356
2357function aiExitHandler() {
2358  if (!document.fullscreenElement && !document.webkitIsFullScreen && !document.mozFullScreen && !document.msFullscreenElement) {
2359    aiInFullscreen = false;
2360    jQuery('.ai-fullscreen-close').trigger("click");
2361  }
2362}
2363
2364
2365
2366

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.