Ad Inserter – WordPress Ads Management with AdSense Header Integration - Version 2.3.19

Version Description

  • Improved code for client-side insertion
  • Fix for rotation with shortcodes
  • Few minor bug fixes, cosmetic changes and code improvements
Download this release

Release Info

Developer spacetime
Plugin Icon 128x128 Ad Inserter – WordPress Ads Management with AdSense Header Integration
Version 2.3.19
Comparing to
See all releases

Code changes from version 2.3.18 to 2.3.19

ad-inserter.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  /*
4
  Plugin Name: Ad Inserter
5
- Version: 2.3.18
6
  Description: Ad management plugin with many advanced advertising features to insert ads at optimal positions
7
  Author: Igor Funa
8
  Author URI: http://igorfuna.com/
@@ -13,6 +13,11 @@ Plugin URI: https://adinserter.pro/documentation
13
 
14
  Change Log
15
 
 
 
 
 
 
16
  Ad Inserter 2.3.18 - 2018-08-21
17
  - Added support to schedule insertion for N days after publishing
18
  - Added support to schedule insertion only for posts published inside/outside time period (Pro only)
@@ -616,9 +621,9 @@ function ai_buffering_end () {
616
  $insert_after = $obj->get_automatic_insertion () == AI_AUTOMATIC_INSERTION_AFTER_HTML_ELEMENT;
617
  $selector = $obj->get_html_selector ();
618
 
619
- libxml_use_internal_errors(true);
620
  $content = phpQuery::newDocumentHTML ($body);
621
- libxml_use_internal_errors(false);
622
  foreach (pq ($selector) as $element){
623
  if ($insert_after)
624
  pq ($element)->after (AI_MARKER_START.$element->tagName.AI_MARKER_END); else
@@ -1016,7 +1021,7 @@ function ai_wp_hook () {
1016
  }
1017
  };
1018
 
1019
- function ai_init_hook() {
1020
  global $block_object, $ai_wp_data, $ai_db_options_extract;
1021
 
1022
  if (defined ('DOING_AJAX') && DOING_AJAX) {
@@ -1148,6 +1153,9 @@ function ai_admin_remove_scripts ($hook_suffix) {
1148
  function ai_wp_enqueue_scripts_hook () {
1149
  global $ai_wp_data;
1150
 
 
 
 
1151
  $footer_inline_scripts =
1152
  get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_SHOW ||
1153
  get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_INSERT ||
@@ -1158,6 +1166,7 @@ function ai_wp_enqueue_scripts_hook () {
1158
  $ai_wp_data [AI_ANIMATION] ||
1159
  $ai_wp_data [AI_CLOSE_BUTTONS] ||
1160
  $ai_wp_data [AI_LAZY_LOADING] ||
 
1161
  (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION && $ai_wp_data [AI_ADB_DETECTION]);
1162
 
1163
  if ($footer_inline_scripts ||
@@ -1481,9 +1490,11 @@ function add_footer_inline_scripts () {
1481
  $ai_wp_data [AI_ANIMATION] ||
1482
  $ai_wp_data [AI_CLOSE_BUTTONS] ||
1483
  $ai_wp_data [AI_LAZY_LOADING] ||
 
1484
  (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION && $ai_wp_data [AI_ADB_DETECTION]);
1485
 
1486
- if (($footer_inline_scripts || $ai_wp_data [AI_CLIENT_SIDE_INSERTION]) && !wp_script_is ('jquery', 'done')) {
 
1487
  // Should not insert as it is forced in the header if jquery needed in the footer
1488
  echo "<script type='text/javascript' src='", includes_url ('js/jquery/jquery.js'), "?ver=", $wp_version, "'></script>\n";
1489
  echo "<script type='text/javascript' src='", includes_url ('js/jquery/jquery-migrate.min.js'), "?ver=", $wp_version, "'></script>\n";
@@ -1494,7 +1505,7 @@ function add_footer_inline_scripts () {
1494
  echo "<script type='text/javascript' src='", plugins_url ('includes/js/theia-sticky-sidebar.min.js', __FILE__ ), "?ver=", AD_INSERTER_VERSION, "'></script>\n";
1495
  }
1496
 
1497
- if ($footer_inline_scripts) echo "<script type='text/javascript'>\n";
1498
 
1499
  $client_side_dynamic_blocks = get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_SHOW || get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_INSERT;
1500
 
@@ -1522,6 +1533,10 @@ function add_footer_inline_scripts () {
1522
  echo ai_get_js ('ai-close');
1523
  }
1524
 
 
 
 
 
1525
  if (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION) {
1526
  if ($ai_wp_data [AI_ADB_DETECTION]) {
1527
  if (!function_exists ('add_footer_inline_scripts_2')) echo ai_replace_js_data (ai_adb_code ());
@@ -5722,7 +5737,23 @@ function ai_process_shortcode (&$block, $atts) {
5722
  $ai_last_check = AI_CHECK_DEBUG_NO_INSERTION;
5723
  // if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_NO_INSERTION) == 0) {
5724
  if (!$obj->get_debug_disable_insertion ()) {
 
 
 
 
 
 
 
 
5725
  $code = $obj->get_code_for_serverside_insertion (true, false, $code_only);
 
 
 
 
 
 
 
 
5726
  // Must be after get_code_for_serverside_insertion ()
5727
  $ai_last_check = AI_CHECK_INSERTED;
5728
  return $code;
@@ -6448,6 +6479,8 @@ if (is_admin () === true) {
6448
  add_action ('wp_ajax_nopriv_ai_ajax', 'ai_ajax');
6449
  }
6450
 
 
 
6451
  if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0) {
6452
  $ai_total_plugin_time += microtime (true) - $start_time;
6453
  ai_log ("INITIALIZATION END\n");
2
 
3
  /*
4
  Plugin Name: Ad Inserter
5
+ Version: 2.3.19
6
  Description: Ad management plugin with many advanced advertising features to insert ads at optimal positions
7
  Author: Igor Funa
8
  Author URI: http://igorfuna.com/
13
 
14
  Change Log
15
 
16
+ Ad Inserter 2.3.19 - 2018-08-26
17
+ - Improved code for client-side insertion
18
+ - Fix for rotation with shortcodes
19
+ - Few minor bug fixes, cosmetic changes and code improvements
20
+
21
  Ad Inserter 2.3.18 - 2018-08-21
22
  - Added support to schedule insertion for N days after publishing
23
  - Added support to schedule insertion only for posts published inside/outside time period (Pro only)
621
  $insert_after = $obj->get_automatic_insertion () == AI_AUTOMATIC_INSERTION_AFTER_HTML_ELEMENT;
622
  $selector = $obj->get_html_selector ();
623
 
624
+ libxml_use_internal_errors (true);
625
  $content = phpQuery::newDocumentHTML ($body);
626
+ libxml_use_internal_errors (false);
627
  foreach (pq ($selector) as $element){
628
  if ($insert_after)
629
  pq ($element)->after (AI_MARKER_START.$element->tagName.AI_MARKER_END); else
1021
  }
1022
  };
1023
 
1024
+ function ai_init_hook () {
1025
  global $block_object, $ai_wp_data, $ai_db_options_extract;
1026
 
1027
  if (defined ('DOING_AJAX') && DOING_AJAX) {
1153
  function ai_wp_enqueue_scripts_hook () {
1154
  global $ai_wp_data;
1155
 
1156
+ // TEST
1157
+ // wp_deregister_script('jquery');
1158
+
1159
  $footer_inline_scripts =
1160
  get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_SHOW ||
1161
  get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_INSERT ||
1166
  $ai_wp_data [AI_ANIMATION] ||
1167
  $ai_wp_data [AI_CLOSE_BUTTONS] ||
1168
  $ai_wp_data [AI_LAZY_LOADING] ||
1169
+ $ai_wp_data [AI_CLIENT_SIDE_INSERTION] ||
1170
  (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION && $ai_wp_data [AI_ADB_DETECTION]);
1171
 
1172
  if ($footer_inline_scripts ||
1490
  $ai_wp_data [AI_ANIMATION] ||
1491
  $ai_wp_data [AI_CLOSE_BUTTONS] ||
1492
  $ai_wp_data [AI_LAZY_LOADING] ||
1493
+ $ai_wp_data [AI_CLIENT_SIDE_INSERTION] ||
1494
  (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION && $ai_wp_data [AI_ADB_DETECTION]);
1495
 
1496
+ // if (($footer_inline_scripts || $ai_wp_data [AI_CLIENT_SIDE_INSERTION]) && !wp_script_is ('jquery', 'done')) {
1497
+ if ($footer_inline_scripts && !wp_script_is ('jquery', 'done')) {
1498
  // Should not insert as it is forced in the header if jquery needed in the footer
1499
  echo "<script type='text/javascript' src='", includes_url ('js/jquery/jquery.js'), "?ver=", $wp_version, "'></script>\n";
1500
  echo "<script type='text/javascript' src='", includes_url ('js/jquery/jquery-migrate.min.js'), "?ver=", $wp_version, "'></script>\n";
1505
  echo "<script type='text/javascript' src='", plugins_url ('includes/js/theia-sticky-sidebar.min.js', __FILE__ ), "?ver=", AD_INSERTER_VERSION, "'></script>\n";
1506
  }
1507
 
1508
+ if ($footer_inline_scripts) echo "<script>\n";
1509
 
1510
  $client_side_dynamic_blocks = get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_SHOW || get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_CLIENT_SIDE_INSERT;
1511
 
1533
  echo ai_get_js ('ai-close');
1534
  }
1535
 
1536
+ if ($ai_wp_data [AI_CLIENT_SIDE_INSERTION]) {
1537
+ echo 'setTimeout (function() {Array.prototype.forEach.call (document.querySelectorAll (".ai-viewports"), function (element, index) {ai_insert_viewport (element);});}, 10);', PHP_EOL;
1538
+ }
1539
+
1540
  if (defined ('AI_ADBLOCKING_DETECTION') && AI_ADBLOCKING_DETECTION) {
1541
  if ($ai_wp_data [AI_ADB_DETECTION]) {
1542
  if (!function_exists ('add_footer_inline_scripts_2')) echo ai_replace_js_data (ai_adb_code ());
5737
  $ai_last_check = AI_CHECK_DEBUG_NO_INSERTION;
5738
  // if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_NO_INSERTION) == 0) {
5739
  if (!$obj->get_debug_disable_insertion ()) {
5740
+
5741
+ if (isset ($ai_wp_data [AI_SHORTCODES]['count'])) {
5742
+ $saved_count = $ai_wp_data [AI_SHORTCODES]['count'];
5743
+ }
5744
+ if (isset ($ai_wp_data [AI_SHORTCODES]['rotate'])) {
5745
+ $saved_rotate = $ai_wp_data [AI_SHORTCODES]['rotate'];
5746
+ }
5747
+
5748
  $code = $obj->get_code_for_serverside_insertion (true, false, $code_only);
5749
+
5750
+ if (isset ($saved_count)) {
5751
+ $ai_wp_data [AI_SHORTCODES]['count'] = $saved_count;
5752
+ }
5753
+ if (isset ($saved_rotate)) {
5754
+ $ai_wp_data [AI_SHORTCODES]['rotate'] = $saved_rotate;
5755
+ }
5756
+
5757
  // Must be after get_code_for_serverside_insertion ()
5758
  $ai_last_check = AI_CHECK_INSERTED;
5759
  return $code;
6479
  add_action ('wp_ajax_nopriv_ai_ajax', 'ai_ajax');
6480
  }
6481
 
6482
+
6483
+
6484
  if (($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_PROCESSING) != 0) {
6485
  $ai_total_plugin_time += microtime (true) - $start_time;
6486
  ai_log ("INITIALIZATION END\n");
class.php CHANGED
@@ -2295,7 +2295,7 @@ abstract class ai_CodeBlock extends ai_BaseCodeBlock {
2295
  public function get_code_for_serverside_insertion ($include_viewport_classes = true, $hidden_widgets = false, $code_only = false) {
2296
  global $ai_wp_data, $block_object;
2297
 
2298
- $html_element_insertion = false;
2299
  $viewports_insertion = $this->get_detection_client_side() && $this->get_client_side_action () == AI_CLIENT_SIDE_ACTION_INSERT;
2300
  $server_side_html_insertion = $this->get_html_element_insertion () == AI_HTML_INSERTION_SEREVR_SIDE;
2301
 
@@ -2311,46 +2311,51 @@ abstract class ai_CodeBlock extends ai_BaseCodeBlock {
2311
  $html_element_insertion = true;
2312
  break;
2313
  default:
 
2314
  if (!$viewports_insertion) return $this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only);
2315
  break;
2316
  }
2317
 
2318
  if ($ai_wp_data [AI_WP_AMP_PAGE] || $ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_FEED || $ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_AJAX) return '';
2319
 
2320
- $block_code = base64_encode ($this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only));
2321
-
2322
  if ($viewports_insertion && !$html_element_insertion) {
 
2323
  $selector = $this->get_viewport_names ();
2324
  $viewport_classes = trim ($this->get_viewport_classes ());
2325
 
2326
  $serverside_insertion_code = "<div class='ai-viewports $viewport_classes' data-code='[#AI_CODE#]' data-block='{$this->number}'></div>\n";
2327
- $serverside_insertion_code .= "<script>ai_insert_viewport (jQuery('script').last().prev());</script>\n";
2328
  }
2329
  elseif ($viewports_insertion && $html_element_insertion) {
2330
  $this->counters = '<span class="ai-selector-counter"></span>';
 
2331
  $selector = $this->get_html_selector (true);
2332
  $viewport_classes = trim ($this->get_viewport_classes ());
2333
 
2334
  $serverside_insertion_code = "<div class='ai-viewports $viewport_classes' data-insertion='$insertion' data-selector='$selector' data-code='[#AI_CODE#]' data-block='{$this->number}'></div>\n";
2335
  if ($this->get_html_element_insertion () == AI_HTML_INSERTION_CLIENT_SIDE)
2336
  // Try to insert it immediately. If the code is server-side inserted before the HTML element, it will be client-side inserted after DOM ready (remaining .ai-viewports)
2337
- $serverside_insertion_code .= "<script>ai_insert_viewport (jQuery('script').last().prev());</script>\n";
2338
  }
2339
  else { // only HTML element insertion
2340
  $this->counters = '<span class="ai-selector-counter"></span>';
 
2341
  $selector = $this->get_html_selector (true);
2342
 
2343
  $code_before = '';
2344
  $code_after = '';
2345
 
2346
  if ($this->get_html_element_insertion () == AI_HTML_INSERTION_CLIENT_SIDE_DOM_READY) {
2347
- $code_before = " jQuery(document).ready(function() {\n ";
2348
- $code_after = "\n });";
 
 
 
2349
  }
2350
 
2351
- $serverside_insertion_code = "<script>
2352
- {$code_before} ai_insert ('$insertion', '$selector', jQuery.base64Decode ('[#AI_CODE#]'));{$code_after}
2353
- </script>\n";
2354
  }
2355
 
2356
  if ($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_BLOCKS) {
@@ -2368,7 +2373,7 @@ abstract class ai_CodeBlock extends ai_BaseCodeBlock {
2368
 
2369
  $tag = $viewports_insertion ? 'div' : 'script';
2370
  $debug_script = new ai_block_labels ('ai-debug-script');
2371
- $serverside_insertion_code = $debug_script->bar (" $tag for " . $this->number . ' &nbsp; ' . $this->get_ad_name () . $version_name . ' ' . $fallback_block_name, '', $selector, $counters, $title) . $serverside_insertion_code;
2372
  }
2373
 
2374
  if ($this->w3tc_code != '' && get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_SERVER_SIDE_W3TC && !defined ('AI_NO_W3TC')) {
2295
  public function get_code_for_serverside_insertion ($include_viewport_classes = true, $hidden_widgets = false, $code_only = false) {
2296
  global $ai_wp_data, $block_object;
2297
 
2298
+ $html_element_insertion = false;
2299
  $viewports_insertion = $this->get_detection_client_side() && $this->get_client_side_action () == AI_CLIENT_SIDE_ACTION_INSERT;
2300
  $server_side_html_insertion = $this->get_html_element_insertion () == AI_HTML_INSERTION_SEREVR_SIDE;
2301
 
2311
  $html_element_insertion = true;
2312
  break;
2313
  default:
2314
+ $insertion = '';
2315
  if (!$viewports_insertion) return $this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only);
2316
  break;
2317
  }
2318
 
2319
  if ($ai_wp_data [AI_WP_AMP_PAGE] || $ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_FEED || $ai_wp_data [AI_WP_PAGE_TYPE] == AI_PT_AJAX) return '';
2320
 
 
 
2321
  if ($viewports_insertion && !$html_element_insertion) {
2322
+ $block_code = base64_encode ($this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only));
2323
  $selector = $this->get_viewport_names ();
2324
  $viewport_classes = trim ($this->get_viewport_classes ());
2325
 
2326
  $serverside_insertion_code = "<div class='ai-viewports $viewport_classes' data-code='[#AI_CODE#]' data-block='{$this->number}'></div>\n";
2327
+ $serverside_insertion_code .= "<script>var ai_script = document.getElementsByClassName ('ai-viewports'); ai_insert_viewport (ai_script [ai_script.length - 1]);</script>\n";
2328
  }
2329
  elseif ($viewports_insertion && $html_element_insertion) {
2330
  $this->counters = '<span class="ai-selector-counter"></span>';
2331
+ $block_code = base64_encode ($this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only));
2332
  $selector = $this->get_html_selector (true);
2333
  $viewport_classes = trim ($this->get_viewport_classes ());
2334
 
2335
  $serverside_insertion_code = "<div class='ai-viewports $viewport_classes' data-insertion='$insertion' data-selector='$selector' data-code='[#AI_CODE#]' data-block='{$this->number}'></div>\n";
2336
  if ($this->get_html_element_insertion () == AI_HTML_INSERTION_CLIENT_SIDE)
2337
  // Try to insert it immediately. If the code is server-side inserted before the HTML element, it will be client-side inserted after DOM ready (remaining .ai-viewports)
2338
+ $serverside_insertion_code .= "<script>var ai_script = document.getElementsByClassName ('ai-viewports'); ai_insert_viewport (ai_script [ai_script.length - 1]);</script>\n";
2339
  }
2340
  else { // only HTML element insertion
2341
  $this->counters = '<span class="ai-selector-counter"></span>';
2342
+ $block_code = base64_encode ($this->get_code_for_insertion ($include_viewport_classes, $hidden_widgets, $code_only));
2343
  $selector = $this->get_html_selector (true);
2344
 
2345
  $code_before = '';
2346
  $code_after = '';
2347
 
2348
  if ($this->get_html_element_insertion () == AI_HTML_INSERTION_CLIENT_SIDE_DOM_READY) {
2349
+
2350
+ $code_before = "var ai_insert_{$this->number} = function(){
2351
+ ";
2352
+ $code_after = "\n };
2353
+ if (document.readyState === 'complete' || (document.readyState !== 'loading' && !document.documentElement.doScroll)) ai_insert_{$this->number} (); else document.addEventListener ('DOMContentLoaded', ai_insert_{$this->number});";
2354
  }
2355
 
2356
+ $serverside_insertion_code = "<script>
2357
+ {$code_before}ai_insert ('$insertion', '$selector', b64d ('[#AI_CODE#]'));{$code_after}
2358
+ </script>\n";
2359
  }
2360
 
2361
  if ($ai_wp_data [AI_WP_DEBUGGING] & AI_DEBUG_BLOCKS) {
2373
 
2374
  $tag = $viewports_insertion ? 'div' : 'script';
2375
  $debug_script = new ai_block_labels ('ai-debug-script');
2376
+ $serverside_insertion_code = $debug_script->bar (" $tag for " . $this->number . ' &nbsp; ' . $this->get_ad_name () . $version_name . ' ' . $fallback_block_name, '', strtoupper (str_replace (array ('begin', 'end'), '', $insertion)) . ' ' . $selector, $counters, $title) . $serverside_insertion_code;
2377
  }
2378
 
2379
  if ($this->w3tc_code != '' && get_dynamic_blocks () == AI_DYNAMIC_BLOCKS_SERVER_SIDE_W3TC && !defined ('AI_NO_W3TC')) {
constants.php CHANGED
@@ -26,7 +26,7 @@ if (!defined( 'AD_INSERTER_NAME'))
26
  define ('AD_INSERTER_NAME', 'Ad Inserter');
27
 
28
  if (!defined( 'AD_INSERTER_VERSION'))
29
- define ('AD_INSERTER_VERSION', '2.3.18');
30
 
31
  if (!defined ('AD_INSERTER_PLUGIN_BASENAME'))
32
  define ('AD_INSERTER_PLUGIN_BASENAME', plugin_basename (__FILE__));
26
  define ('AD_INSERTER_NAME', 'Ad Inserter');
27
 
28
  if (!defined( 'AD_INSERTER_VERSION'))
29
+ define ('AD_INSERTER_VERSION', '2.3.19');
30
 
31
  if (!defined ('AD_INSERTER_PLUGIN_BASENAME'))
32
  define ('AD_INSERTER_PLUGIN_BASENAME', plugin_basename (__FILE__));
css/ad-inserter.css CHANGED
@@ -1,5 +1,5 @@
1
  #ai-data {
2
- font-family: "2.3.18"; /* Used for version number of the file */
3
  }
4
 
5
  #blocked-warning {
1
  #ai-data {
2
+ font-family: "2.3.19"; /* Used for version number of the file */
3
  }
4
 
5
  #blocked-warning {
css/images/index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-5.jpg" />
18
- </div>
19
- <p>
20
- Some Ad Inserter Pro features: IP address and country lists, Scheduling between dates with fallback
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
css/index.html CHANGED
@@ -1,25 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ads</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code Anywhere on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Ad Inserter is also a perfect <a href="https://adinserter.pro/adsense-ads" target="_blank" rel="nofollow">WordPress AdSense plugin</a> that can insert ads where other plugins fail.
14
- </p>
15
- <div>
16
- <img style="display: block;margin: 0 auto;" src="https://adinserter.pro/images/pages/ad-inserter/ad-inserter-adsense-code-generator.png" />
17
- </div>
18
- <p>
19
- AdSense code generator/editor
20
- </p>
21
- </div>
22
- <body>
23
-
24
- </html>
25
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
images/index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-2.jpg" />
18
- </div>
19
- <p>
20
- Code preview with visual CSS editor
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/ace/index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <a href="https://adinserter.pro/alignments-and-styles" target="_blank" rel="nofollow"><img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-3.jpg" width="800" alt="Alignments and styles"/></a>
18
- </div>
19
- <p>
20
- Code preview with visual CSS editor - highlighted code
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <a href="https://adinserter.pro/alignments-and-styles" target="_blank" rel="nofollow"><img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-3.jpg" width="800" alt="Alignments and styles"/></a>
18
- </div>
19
- <p>
20
- Code preview with visual CSS editor - highlighted code
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/js/ai-insert.js CHANGED
@@ -1,229 +1,127 @@
1
  function ai_insert (insertion, selector, insertion_code) {
2
- jQuery (selector).each (function (index, element) {
3
  var ai_debug = typeof ai_debugging !== 'undefined';
4
 
5
- if (typeof jQuery(this).attr ('id') != 'undefined') {
6
- selector_string = '#' + jQuery(this).attr ('id');
7
  } else
8
- if (typeof jQuery(this).attr ('class') != 'undefined') {
9
- selector_string = '.' + jQuery(this).attr ('class').replace (' ', '.');
10
  } else
11
  selector_string = '';
12
 
13
- var insertion_function = insertion;
14
- var ai_code = jQuery (insertion_code);
15
 
16
- jQuery ('.ai-selector-counter', ai_code).text (index + 1);
17
- jQuery ('.ai-debug-name.ai-main', ai_code).text (insertion.toUpperCase () + ' ' + jQuery(this).prop ('tagName').toLowerCase() + selector_string);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- jQuery(this)[insertion_function] (ai_code);
 
20
 
21
- if (ai_debug) console.log ('AI INSERT', insertion, selector);
22
  });
23
  }
24
 
25
  function ai_insert_viewport (element) {
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  var ai_debug = typeof ai_debugging !== 'undefined';
28
 
29
- if (ai_debug) console.log ('AI VIEWPORT INSERTION: class', element.attr ('class'));
30
 
31
- var visible = element.is(':visible');
32
- var block = element.data ('block');
33
 
34
  if (visible) {
35
- var insertion_code = element.data ('code');
36
- var insertion_type = element.data ('insertion');
37
- var selector = element.data ('selector');
 
 
 
38
 
39
- if (typeof insertion_code != 'undefined') {
40
- if (typeof insertion_type != 'undefined' && typeof selector != 'undefined') {
41
 
42
- var selector_exists = jQuery (selector).length
43
  if (ai_debug) console.log ('AI VIEWPORT VISIBLE: block', block, insertion_type, selector, selector_exists ? '' : 'NOT FOUND');
44
 
45
- ai_insert (insertion_type, selector, jQuery.base64Decode (insertion_code));
46
- if (selector_exists) element.removeClass ('ai-viewports');
 
 
47
  } else {
48
-
49
  if (ai_debug) console.log ('AI VIEWPORT VISIBLE: block', block);
50
 
51
- var ai_code = jQuery(jQuery.base64Decode (insertion_code));
52
- element.after (ai_code);
53
- element.removeClass ('ai-viewports');
 
 
54
  }
55
  }
56
  } else {
57
  if (ai_debug) console.log ('AI VIEWPORT NOT VISIBLE: block', block);
58
 
59
- var debug_bar = element.prev ();
60
- if (debug_bar.hasClass ('ai-debug-bar') && debug_bar.hasClass ('ai-debug-script')) {
61
- debug_bar.removeClass ('ai-debug-script')
62
- debug_bar.addClass ('ai-debug-viewport-invisible')
 
63
  }
 
 
64
  }
65
  }
66
 
67
- (function($){
68
- // Insert remaining elements that depend on viewports
69
- $(document).ready (function() {
70
- $('.ai-viewports').each (function (index, element) {
71
- ai_insert_viewport ($(this));
72
- });
73
- });
74
- })(jQuery);
75
-
76
-
77
- (function($){
78
- // Insert remaining elements that depend on viewports
79
- $(document).ready (function() {
80
- $('.ai-viewports').each (function (index, element) {
81
- ai_insert_viewport ($(this));
82
- });
83
- });
84
- })(jQuery);
85
-
86
- /**
87
- * jQuery BASE64 functions
88
- *
89
- * <code>
90
- * Encodes the given data with base64.
91
- * String $.base64Encode ( String str )
92
- * <br />
93
- * Decodes a base64 encoded data.
94
- * String $.base64Decode ( String str )
95
- * </code>
96
- *
97
- * Encodes and Decodes the given data in base64.
98
- * This encoding is designed to make binary data survive transport through transport layers that are not 8-bit clean, such as mail bodies.
99
- * Base64-encoded data takes about 33% more space than the original data.
100
- * This javascript code is used to encode / decode data using base64 (this encoding is designed to make binary data survive transport through transport layers that are not 8-bit clean). Script is fully compatible with UTF-8 encoding. You can use base64 encoded data as simple encryption mechanism.
101
- * If you plan using UTF-8 encoding in your project don't forget to set the page encoding to UTF-8 (Content-Type meta tag).
102
- * This function orginally get from the WebToolkit and rewrite for using as the jQuery plugin.
103
- *
104
- * Example
105
- * Code
106
- * <code>
107
- * $.base64Encode("I'm Persian.");
108
- * </code>
109
- * Result
110
- * <code>
111
- * "SSdtIFBlcnNpYW4u"
112
- * </code>
113
- * Code
114
- * <code>
115
- * $.base64Decode("SSdtIFBlcnNpYW4u");
116
- * </code>
117
- * Result
118
- * <code>
119
- * "I'm Persian."
120
- * </code>
121
- *
122
- * @alias Muhammad Hussein Fattahizadeh < muhammad [AT] semnanweb [DOT] com >
123
- * @link http://www.semnanweb.com/jquery-plugin/base64.html (no longer available?)
124
- * @link https://gist.github.com/gists/1602210
125
- * @see http://www.webtoolkit.info/
126
- * @license http://www.gnu.org/licenses/gpl.html [GNU General Public License]
127
- * @param {jQuery} {base64Encode:function(input))
128
- * @param {jQuery} {base64Decode:function(input))
129
- * @return string
130
- */
131
-
132
- (function($){
133
-
134
- var keyString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
135
-
136
- var uTF8Encode = function(string) {
137
- string = string.replace(/\x0d\x0a/g, "\x0a");
138
- var output = "";
139
- for (var n = 0; n < string.length; n++) {
140
- var c = string.charCodeAt(n);
141
- if (c < 128) {
142
- output += String.fromCharCode(c);
143
- } else if ((c > 127) && (c < 2048)) {
144
- output += String.fromCharCode((c >> 6) | 192);
145
- output += String.fromCharCode((c & 63) | 128);
146
- } else {
147
- output += String.fromCharCode((c >> 12) | 224);
148
- output += String.fromCharCode(((c >> 6) & 63) | 128);
149
- output += String.fromCharCode((c & 63) | 128);
150
- }
151
- }
152
- return output;
153
- };
154
-
155
- var uTF8Decode = function(input) {
156
- var string = "";
157
- var i = 0;
158
- var c = c1 = c2 = 0;
159
- while ( i < input.length ) {
160
- c = input.charCodeAt(i);
161
- if (c < 128) {
162
- string += String.fromCharCode(c);
163
- i++;
164
- } else if ((c > 191) && (c < 224)) {
165
- c2 = input.charCodeAt(i+1);
166
- string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
167
- i += 2;
168
- } else {
169
- c2 = input.charCodeAt(i+1);
170
- c3 = input.charCodeAt(i+2);
171
- string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
172
- i += 3;
173
- }
174
- }
175
- return string;
176
- }
177
 
178
- $.extend({
179
- base64Encode: function(input) {
180
- var output = "";
181
- var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
182
- var i = 0;
183
- input = uTF8Encode(input);
184
- while (i < input.length) {
185
- chr1 = input.charCodeAt(i++);
186
- chr2 = input.charCodeAt(i++);
187
- chr3 = input.charCodeAt(i++);
188
- enc1 = chr1 >> 2;
189
- enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
190
- enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
191
- enc4 = chr3 & 63;
192
- if (isNaN(chr2)) {
193
- enc3 = enc4 = 64;
194
- } else if (isNaN(chr3)) {
195
- enc4 = 64;
196
- }
197
- output = output + keyString.charAt(enc1) + keyString.charAt(enc2) + keyString.charAt(enc3) + keyString.charAt(enc4);
198
- }
199
- return output;
200
- },
201
- base64Decode: function(input) {
202
- var output = "";
203
- var chr1, chr2, chr3;
204
- var enc1, enc2, enc3, enc4;
205
- var i = 0;
206
- input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
207
- while (i < input.length) {
208
- enc1 = keyString.indexOf(input.charAt(i++));
209
- enc2 = keyString.indexOf(input.charAt(i++));
210
- enc3 = keyString.indexOf(input.charAt(i++));
211
- enc4 = keyString.indexOf(input.charAt(i++));
212
- chr1 = (enc1 << 2) | (enc2 >> 4);
213
- chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
214
- chr3 = ((enc3 & 3) << 6) | enc4;
215
- output = output + String.fromCharCode(chr1);
216
- if (enc3 != 64) {
217
- output = output + String.fromCharCode(chr2);
218
- }
219
- if (enc4 != 64) {
220
- output = output + String.fromCharCode(chr3);
221
- }
222
- }
223
- output = uTF8Decode(output);
224
- return output;
225
- }
226
- });
227
- })(jQuery);
228
 
229
 
1
  function ai_insert (insertion, selector, insertion_code) {
2
+ Array.prototype.forEach.call (document.querySelectorAll (selector), function (element, index) {
3
  var ai_debug = typeof ai_debugging !== 'undefined';
4
 
5
+ if (element.hasAttribute ('id')) {
6
+ selector_string = '#' + element.getAttribute ('id');
7
  } else
8
+ if (element.hasAttribute ('class')) {
9
+ selector_string = '.' + element.getAttribute ('class').replace (new RegExp (' ', 'g'), '.');
10
  } else
11
  selector_string = '';
12
 
13
+ var template = document.createElement ('div');
14
+ template.innerHTML = insertion_code;
15
 
16
+ var ai_selector_counter = template.getElementsByClassName ("ai-selector-counter")[0];
17
+ if (ai_selector_counter != null) {
18
+ ai_selector_counter.innerText = index + 1;
19
+ }
20
+
21
+ var ai_debug_name_ai_main = template.getElementsByClassName ("ai-debug-name ai-main")[0];
22
+ if (ai_debug_name_ai_main != null) {
23
+ ai_debug_name_ai_main.innerText = insertion.toUpperCase () + ' ' + selector + ' (' + element.tagName.toLowerCase() + selector_string + ')';
24
+ }
25
+
26
+ var range = document.createRange ();
27
+ var fragment = range.createContextualFragment (template.innerHTML);
28
+
29
+ if (insertion == 'before') {
30
+ element.parentNode.insertBefore (fragment, element);
31
+ } else
32
+ if (insertion == 'after') {
33
+ element.parentNode.insertBefore (fragment, element.nextSibling);
34
+ }
35
+
36
+ // before first child
37
+ // element.insertBefore (fragment, element.firstChild);
38
 
39
+ // after last child
40
+ // element.insertBefore (fragment, null);
41
 
42
+ if (ai_debug) console.log ('AI INSERT', insertion, selector, '(' + element.tagName.toLowerCase() + selector_string + ')');
43
  });
44
  }
45
 
46
  function ai_insert_viewport (element) {
47
 
48
+ function hasClass (element, cls) {
49
+ if (element.classList) return element.classList.contains (cls); else
50
+ return (' ' + element.className + ' ').indexOf (' ' + cls + ' ') > - 1;
51
+ }
52
+
53
+ function addClass (element, cls) {
54
+ if (element.classList) element.classList.add (cls); else
55
+ element.className += ' ' + cls;
56
+ }
57
+
58
+ function removeClass (element, cls) {
59
+ if (element.classList) element.classList.remove (cls); else
60
+ element.className = element.className.replace (new RegExp ('(^|\\b)' + cls.split (' ').join ('|') + '(\\b|$)', 'gi'), ' ');
61
+ }
62
+
63
  var ai_debug = typeof ai_debugging !== 'undefined';
64
 
65
+ if (ai_debug) console.log ('AI VIEWPORT INSERTION:', 'class=\'' + element.getAttribute ('class') + '\'');
66
 
67
+ var visible = element.offsetWidth > 0 || element.offsetHeight > 0;
68
+ var block = element.getAttribute ('data-block');
69
 
70
  if (visible) {
71
+ var insertion_code = element.getAttribute ('data-code');
72
+ var insertion_type = element.getAttribute ('data-insertion');
73
+ var selector = element.getAttribute ('data-selector');
74
+
75
+ if (insertion_code != null) {
76
+ if (insertion_type != null && selector != null) {
77
 
78
+ var selector_exists = document.querySelectorAll (selector).length;
 
79
 
 
80
  if (ai_debug) console.log ('AI VIEWPORT VISIBLE: block', block, insertion_type, selector, selector_exists ? '' : 'NOT FOUND');
81
 
82
+ if (selector_exists) {
83
+ ai_insert (insertion_type, selector, b64d (insertion_code));
84
+ removeClass (element, 'ai-viewports');
85
+ }
86
  } else {
 
87
  if (ai_debug) console.log ('AI VIEWPORT VISIBLE: block', block);
88
 
89
+ var range = document.createRange ();
90
+ var fragment = range.createContextualFragment (b64d (insertion_code));
91
+ element.parentNode.insertBefore (fragment, element.nextSibling);
92
+
93
+ removeClass (element, 'ai-viewports');
94
  }
95
  }
96
  } else {
97
  if (ai_debug) console.log ('AI VIEWPORT NOT VISIBLE: block', block);
98
 
99
+ var debug_bar = element.previousElementSibling;
100
+
101
+ if (hasClass (debug_bar, 'ai-debug-bar') && hasClass (debug_bar, 'ai-debug-script')) {
102
+ removeClass (debug_bar, 'ai-debug-script');
103
+ addClass (debug_bar, 'ai-debug-viewport-invisible');
104
  }
105
+
106
+ removeClass (element, 'ai-viewports');
107
  }
108
  }
109
 
110
+ function b64e (str) {
111
+ // first we use encodeURIComponent to get percent-encoded UTF-8,
112
+ // then we convert the percent encodings into raw bytes which
113
+ // can be fed into btoa.
114
+ return btoa(encodeURIComponent (str).replace (/%([0-9A-F]{2})/g,
115
+ function toSolidBytes (match, p1) {
116
+ return String.fromCharCode ('0x' + p1);
117
+ }));
118
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
+ function b64d (str) {
121
+ // Going backwards: from bytestream, to percent-encoding, to original string.
122
+ return decodeURIComponent (atob (str).split ('').map (function(c) {
123
+ return '%' + ('00' + c.charCodeAt (0).toString (16)).slice (-2);
124
+ }).join (''));
125
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
 
includes/js/ai-insert.min.js CHANGED
@@ -1,15 +1,8 @@
1
- /*
2
- http://www.gnu.org/licenses/gpl.html [GNU General Public License]
3
- @param {jQuery} {base64Encode:function(input))
4
- @param {jQuery} {base64Decode:function(input))
5
- @return string
6
- */
7
- function ai_insert(insertion,selector,insertion_code){jQuery(selector).each(function(index,element){var ai_debug=typeof ai_debugging!=="undefined";if(typeof jQuery(this).attr("id")!="undefined")selector_string="#"+jQuery(this).attr("id");else if(typeof jQuery(this).attr("class")!="undefined")selector_string="."+jQuery(this).attr("class").replace(" ",".");else selector_string="";var insertion_function=insertion;var ai_code=jQuery(insertion_code);jQuery(".ai-selector-counter",ai_code).text(index+1);
8
- jQuery(".ai-debug-name.ai-main",ai_code).text(insertion.toUpperCase()+" "+jQuery(this).prop("tagName").toLowerCase()+selector_string);jQuery(this)[insertion_function](ai_code);if(ai_debug)console.log("AI INSERT",insertion,selector)})}
9
- function ai_insert_viewport(element){var ai_debug=typeof ai_debugging!=="undefined";if(ai_debug)console.log("AI VIEWPORT INSERTION: class",element.attr("class"));var visible=element.is(":visible");var block=element.data("block");if(visible){var insertion_code=element.data("code");var insertion_type=element.data("insertion");var selector=element.data("selector");if(typeof insertion_code!="undefined")if(typeof insertion_type!="undefined"&&typeof selector!="undefined"){var selector_exists=jQuery(selector).length;
10
- if(ai_debug)console.log("AI VIEWPORT VISIBLE: block",block,insertion_type,selector,selector_exists?"":"NOT FOUND");ai_insert(insertion_type,selector,jQuery.base64Decode(insertion_code));if(selector_exists)element.removeClass("ai-viewports")}else{if(ai_debug)console.log("AI VIEWPORT VISIBLE: block",block);var ai_code=jQuery(jQuery.base64Decode(insertion_code));element.after(ai_code);element.removeClass("ai-viewports")}}else{if(ai_debug)console.log("AI VIEWPORT NOT VISIBLE: block",block);var debug_bar=
11
- element.prev();if(debug_bar.hasClass("ai-debug-bar")&&debug_bar.hasClass("ai-debug-script")){debug_bar.removeClass("ai-debug-script");debug_bar.addClass("ai-debug-viewport-invisible")}}}(function($){$(document).ready(function(){$(".ai-viewports").each(function(index,element){ai_insert_viewport($(this))})})})(jQuery);(function($){$(document).ready(function(){$(".ai-viewports").each(function(index,element){ai_insert_viewport($(this))})})})(jQuery);
12
- (function($){var keyString="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var uTF8Encode=function(string){string=string.replace(/\x0d\x0a/g,"\n");var output="";for(var n=0;n<string.length;n++){var c=string.charCodeAt(n);if(c<128)output+=String.fromCharCode(c);else if(c>127&&c<2048){output+=String.fromCharCode(c>>6|192);output+=String.fromCharCode(c&63|128)}else{output+=String.fromCharCode(c>>12|224);output+=String.fromCharCode(c>>6&63|128);output+=String.fromCharCode(c&63|128)}}return output};
13
- var uTF8Decode=function(input){var string="";var i=0;var c=c1=c2=0;while(i<input.length){c=input.charCodeAt(i);if(c<128){string+=String.fromCharCode(c);i++}else if(c>191&&c<224){c2=input.charCodeAt(i+1);string+=String.fromCharCode((c&31)<<6|c2&63);i+=2}else{c2=input.charCodeAt(i+1);c3=input.charCodeAt(i+2);string+=String.fromCharCode((c&15)<<12|(c2&63)<<6|c3&63);i+=3}}return string};$.extend({base64Encode:function(input){var output="";var chr1,chr2,chr3,enc1,enc2,enc3,enc4;var i=0;input=uTF8Encode(input);
14
- while(i<input.length){chr1=input.charCodeAt(i++);chr2=input.charCodeAt(i++);chr3=input.charCodeAt(i++);enc1=chr1>>2;enc2=(chr1&3)<<4|chr2>>4;enc3=(chr2&15)<<2|chr3>>6;enc4=chr3&63;if(isNaN(chr2))enc3=enc4=64;else if(isNaN(chr3))enc4=64;output=output+keyString.charAt(enc1)+keyString.charAt(enc2)+keyString.charAt(enc3)+keyString.charAt(enc4)}return output},base64Decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/=]/g,"");while(i<
15
- input.length){enc1=keyString.indexOf(input.charAt(i++));enc2=keyString.indexOf(input.charAt(i++));enc3=keyString.indexOf(input.charAt(i++));enc4=keyString.indexOf(input.charAt(i++));chr1=enc1<<2|enc2>>4;chr2=(enc2&15)<<4|enc3>>2;chr3=(enc3&3)<<6|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64)output=output+String.fromCharCode(chr2);if(enc4!=64)output=output+String.fromCharCode(chr3)}output=uTF8Decode(output);return output}})})(jQuery);
1
+ function ai_insert(insertion,selector,insertion_code){Array.prototype.forEach.call(document.querySelectorAll(selector),function(element,index){var ai_debug=typeof ai_debugging!=="undefined";if(element.hasAttribute("id"))selector_string="#"+element.getAttribute("id");else if(element.hasAttribute("class"))selector_string="."+element.getAttribute("class").replace(new RegExp(" ","g"),".");else selector_string="";var template=document.createElement("div");template.innerHTML=insertion_code;var ai_selector_counter=
2
+ template.getElementsByClassName("ai-selector-counter")[0];if(ai_selector_counter!=null)ai_selector_counter.innerText=index+1;var ai_debug_name_ai_main=template.getElementsByClassName("ai-debug-name ai-main")[0];if(ai_debug_name_ai_main!=null)ai_debug_name_ai_main.innerText=insertion.toUpperCase()+" "+selector+" ("+element.tagName.toLowerCase()+selector_string+")";var range=document.createRange();var fragment=range.createContextualFragment(template.innerHTML);if(insertion=="before")element.parentNode.insertBefore(fragment,
3
+ element);else if(insertion=="after")element.parentNode.insertBefore(fragment,element.nextSibling);if(ai_debug)console.log("AI INSERT",insertion,selector,"("+element.tagName.toLowerCase()+selector_string+")")})}
4
+ function ai_insert_viewport(element){function hasClass(element,cls){if(element.classList)return element.classList.contains(cls);else return(" "+element.className+" ").indexOf(" "+cls+" ")>-1}function addClass(element,cls){if(element.classList)element.classList.add(cls);else element.className+=" "+cls}function removeClass(element,cls){if(element.classList)element.classList.remove(cls);else element.className=element.className.replace(new RegExp("(^|\\b)"+cls.split(" ").join("|")+"(\\b|$)","gi")," ")}
5
+ var ai_debug=typeof ai_debugging!=="undefined";if(ai_debug)console.log("AI VIEWPORT INSERTION:","class='"+element.getAttribute("class")+"'");var visible=element.offsetWidth>0||element.offsetHeight>0;var block=element.getAttribute("data-block");if(visible){var insertion_code=element.getAttribute("data-code");var insertion_type=element.getAttribute("data-insertion");var selector=element.getAttribute("data-selector");if(insertion_code!=null)if(insertion_type!=null&&selector!=null){var selector_exists=
6
+ document.querySelectorAll(selector).length;if(ai_debug)console.log("AI VIEWPORT VISIBLE: block",block,insertion_type,selector,selector_exists?"":"NOT FOUND");if(selector_exists){ai_insert(insertion_type,selector,b64d(insertion_code));removeClass(element,"ai-viewports")}}else{if(ai_debug)console.log("AI VIEWPORT VISIBLE: block",block);var range=document.createRange();var fragment=range.createContextualFragment(b64d(insertion_code));element.parentNode.insertBefore(fragment,element.nextSibling);removeClass(element,
7
+ "ai-viewports")}}else{if(ai_debug)console.log("AI VIEWPORT NOT VISIBLE: block",block);var debug_bar=element.previousElementSibling;if(hasClass(debug_bar,"ai-debug-bar")&&hasClass(debug_bar,"ai-debug-script")){removeClass(debug_bar,"ai-debug-script");addClass(debug_bar,"ai-debug-viewport-invisible")}removeClass(element,"ai-viewports")}}function b64e(str){return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,function toSolidBytes(match,p1){return String.fromCharCode("0x"+p1)}))}
8
+ function b64d(str){return decodeURIComponent(atob(str).split("").map(function(c){return"%"+("00"+c.charCodeAt(0).toString(16)).slice(-2)}).join(""))};
 
 
 
 
 
 
 
includes/js/index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <a href="https://adinserter.pro/alignments-and-styles" target="_blank" rel="nofollow"><img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-3.jpg" width="800" alt="Alignments and styles"/></a>
18
- </div>
19
- <p>
20
- Code preview with visual CSS editor - highlighted code
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.html CHANGED
@@ -1,26 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks? Ad Inserter Pro supports
14
- 64 blocks, GEO targeting, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <a href="http://adinserter.pro/documentation" target="_blank" rel="nofollow"><img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-1.png" alt="Ad Inserter Documentation" /></a>
18
- </div>
19
- <p>
20
- Settings for one code block. Up to 16 blocks can be configured.
21
- </p>
22
- </div>
23
- <body>
24
-
25
- </html>
26
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/ad-inserter.js CHANGED
@@ -1,4 +1,4 @@
1
- var javascript_version = "2.3.18";
2
  var ignore_key = true;
3
  var start = 1;
4
  var end = 16;
1
+ var javascript_version = "2.3.19";
2
  var ignore_key = true;
3
  var start = 1;
4
  var end = 16;
js/ads.js CHANGED
@@ -1,4 +1 @@
1
- var e=document.createElement('div');
2
- e.id='dqwpediwqswqma';
3
- e.style.display='none';
4
- document.body.appendChild(e);
1
+ var e=document.createElement("div");e.id="dqwpediwqswqma";e.style.display="none";document.body.appendChild(e);
 
 
 
js/index.html CHANGED
@@ -1,27 +1 @@
1
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
- <head>
4
- <title>Ad Inserter - WordPress plugin for ad management</title>
5
- <meta name="description" content="WordPress ad management plugin for all advertising needs: AdSense, Amazon, banner rotation, sticky widgets, contextual ads, AMP, header/footer code" />
6
- </head>
7
- <body style="font-family: arial, helvetica;">
8
- <div style="width: 800px; padding: 2px 8px 6px 8px; margin: 8px 30px 8px 0; border: 1px solid rgb(221, 221, 221); border-radius: 5px; background: #fff;">
9
- <h1 style="text-align: center;">Ad Inserter</h1>
10
- <h2 style="text-align: center;">Insert Any Code on Any WordPress Page</h2>
11
- <p style="text-align: justify;">
12
- <a href="https://wordpress.org/plugins/ad-inserter/" target="_blank" rel="nofollow">Free Ad Inserter</a> - Insert any ad or HTML/Javascript/PHP code into Wordpress. Perfect for all kinds of ads. 16 code blocks, many display options and features.
13
- Need a powerful <a href="https://adinserter.pro/" target="_blank" rel="nofollow">WordPress ad management plugin</a> and more than 64 code blocks - Ad Inserter Pro supports
14
- 64 blocks, impression and click tracking (supports also Javascript ads like AdSense), A/B testing, sticky positions, 6 viewports, import/export of plugin settings and has additional multisite support.
15
- </p>
16
- <div>
17
- <img style="display: block;margin: 0 auto;" src="https://ps.w.org/ad-inserter/assets/screenshot-17.png" />
18
- </div>
19
- <p>
20
- Complete settings for one code block (Before Paragraph)
21
- </p>
22
- </div>
23
- </div>
24
- <body>
25
-
26
- </html>
27
-
1
+ <html><body bgcolor="#FFFFFF"></body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -6,7 +6,7 @@ Tags: ads, adsense, header footer code, ad management, sticky fixed widgets, adv
6
  Requires at least: 4.0
7
  Tested up to: 4.9
8
  Requires PHP: 5.6
9
- Stable tag: 2.3.17
10
  License: GPLv3
11
 
12
  Insert and manage ads: Amazon, Google AdSense ads, banner rotation, sticky widget ads, AMP, PHP, HTML, CSS, Javascript, tracking, footer, header code
@@ -679,6 +679,11 @@ AD CODE RIGHT
679
 
680
  == Changelog ==
681
 
 
 
 
 
 
682
  = 2.3.18 =
683
  - Added support to schedule insertion for N days after publishing
684
  - Added support to schedule insertion only for posts published inside/outside time period (Pro only)
@@ -795,6 +800,11 @@ For the changelog of earlier versions, please refer to the separate changelog.tx
795
 
796
  == Upgrade Notice ==
797
 
 
 
 
 
 
798
  = 2.3.18 =
799
  Added support to schedule insertion for N days after publishing;
800
  Added support to schedule insertion only for posts published inside/outside time period (Pro only);
6
  Requires at least: 4.0
7
  Tested up to: 4.9
8
  Requires PHP: 5.6
9
+ Stable tag: 2.3.18
10
  License: GPLv3
11
 
12
  Insert and manage ads: Amazon, Google AdSense ads, banner rotation, sticky widget ads, AMP, PHP, HTML, CSS, Javascript, tracking, footer, header code
679
 
680
  == Changelog ==
681
 
682
+ = 2.3.19 =
683
+ - Improved code for client-side insertion
684
+ - Fix for rotation with shortcodes
685
+ - Few minor bug fixes, cosmetic changes and code improvements
686
+
687
  = 2.3.18 =
688
  - Added support to schedule insertion for N days after publishing
689
  - Added support to schedule insertion only for posts published inside/outside time period (Pro only)
800
 
801
  == Upgrade Notice ==
802
 
803
+ = 2.3.19 =
804
+ Improved code for client-side insertion;
805
+ Fix for rotation with shortcodes;
806
+ Few minor bug fixes, cosmetic changes and code improvements;
807
+
808
  = 2.3.18 =
809
  Added support to schedule insertion for N days after publishing;
810
  Added support to schedule insertion only for posts published inside/outside time period (Pro only);
settings.php CHANGED
@@ -3419,7 +3419,7 @@ function sidebar_support_review () {
3419
  You've been using <strong>Ad Inserter</strong> for a while now, and I hope you're happy with it.
3420
  Positive <a href="https://wordpress.org/support/plugin/ad-inserter/reviews/" style="text-decoration: none; box-shadow: 0 0 0;" target="_blank">reviews</a> are a great way to show your appreciation for my work.
3421
  Besides being an incredible boost to my morale, they are also a great incentive to fix bugs and to add new features for better monetization of your website.
3422
- Thank you! Igor <img draggable="false" class="emoji" alt="happy" src="https://s.w.org/images/core/emoji/2.3/svg/1f642.svg" style="margin-left: 5px!important;">
3423
  </div>
3424
 
3425
  <?php
3419
  You've been using <strong>Ad Inserter</strong> for a while now, and I hope you're happy with it.
3420
  Positive <a href="https://wordpress.org/support/plugin/ad-inserter/reviews/" style="text-decoration: none; box-shadow: 0 0 0;" target="_blank">reviews</a> are a great way to show your appreciation for my work.
3421
  Besides being an incredible boost to my morale, they are also a great incentive to fix bugs and to add new features for better monetization of your website.
3422
+ Thank you, Igor <img draggable="false" class="emoji" alt="happy" src="https://s.w.org/images/core/emoji/2.3/svg/1f642.svg" style="margin-left: 5px!important;">
3423
  </div>
3424
 
3425
  <?php