Version Description
- whitelist field groups created by Advanced Custom Fields on the ad edit page
- prevent including AdSense Auto ads code when the Borlabs Cookie is already adding it
- prevented adding unneeded escape characters to ads.txt file
- added compatibility with Funding Choices when consent is not needed
Download this release
Release Info
Developer | advancedads |
Plugin | Advanced Ads |
Version | 1.20.3 |
Comparing to | |
See all releases |
Code changes from version 1.20.2 to 1.20.3
- admin/assets/css/admin.css +0 -1
- advanced-ads.php +2 -2
- classes/compatibility.php +112 -7
- classes/plugin.php +1 -1
- languages/advanced-ads.pot +42 -38
- modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php +5 -3
- modules/gadsense/admin/views/borlabs-cookie-auto-ads-warning.php +11 -0
- modules/gadsense/includes/class-network-adsense.php +20 -26
- modules/privacy/admin/views/setting-general.php +5 -0
- public/assets/js/advanced.js +874 -1
- public/assets/js/advanced.min.js +1 -0
- public/assets/js/advanced.orig.js +0 -815
- readme.txt +8 -1
admin/assets/css/admin.css
CHANGED
@@ -191,7 +191,6 @@ select + .advads-conditions-single { padding-left: 10px }
|
|
191 |
.advads-option > span + div select { vertical-align: top; }
|
192 |
.advads-option > div > .description { max-width: 80%; }
|
193 |
.advads-option + .advads-option { margin-top: 20px; }
|
194 |
-
.advads-option input, .advads-option select { background: transparent; }
|
195 |
|
196 |
.advads-placements-table .advads-option > span { padding: 0; }
|
197 |
.advads-placements-table .advads-option > span + div { padding: 0; }
|
191 |
.advads-option > span + div select { vertical-align: top; }
|
192 |
.advads-option > div > .description { max-width: 80%; }
|
193 |
.advads-option + .advads-option { margin-top: 20px; }
|
|
|
194 |
|
195 |
.advads-placements-table .advads-option > span { padding: 0; }
|
196 |
.advads-placements-table .advads-option > span + div { padding: 0; }
|
advanced-ads.php
CHANGED
@@ -12,7 +12,7 @@
|
|
12 |
* Plugin Name: Advanced Ads
|
13 |
* Plugin URI: https://wpadvancedads.com
|
14 |
* Description: Manage and optimize your ads in WordPress
|
15 |
-
* Version: 1.20.
|
16 |
* Author: Thomas Maier, Advanced Ads GmbH
|
17 |
* Author URI: https://wpadvancedads.com
|
18 |
* Text Domain: advanced-ads
|
@@ -39,7 +39,7 @@ define( 'ADVADS_BASE_DIR', dirname( ADVADS_BASE ) ); // directory of the plugin
|
|
39 |
// general and global slug, e.g. to store options in WP.
|
40 |
define( 'ADVADS_SLUG', 'advanced-ads' );
|
41 |
define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
|
42 |
-
define( 'ADVADS_VERSION', '1.20.
|
43 |
|
44 |
// Autoloading, modules and functions.
|
45 |
|
12 |
* Plugin Name: Advanced Ads
|
13 |
* Plugin URI: https://wpadvancedads.com
|
14 |
* Description: Manage and optimize your ads in WordPress
|
15 |
+
* Version: 1.20.3
|
16 |
* Author: Thomas Maier, Advanced Ads GmbH
|
17 |
* Author URI: https://wpadvancedads.com
|
18 |
* Text Domain: advanced-ads
|
39 |
// general and global slug, e.g. to store options in WP.
|
40 |
define( 'ADVADS_SLUG', 'advanced-ads' );
|
41 |
define( 'ADVADS_URL', 'https://wpadvancedads.com/' );
|
42 |
+
define( 'ADVADS_VERSION', '1.20.3' );
|
43 |
|
44 |
// Autoloading, modules and functions.
|
45 |
|
classes/compatibility.php
CHANGED
@@ -30,16 +30,25 @@ class Advanced_Ads_Compatibility {
|
|
30 |
// Add shortcode for MailPoet.
|
31 |
add_filter( 'mailpoet_newsletter_shortcode', array( $this, 'mailpoet_ad_shortcode' ), 10, 5 );
|
32 |
|
|
|
|
|
|
|
|
|
|
|
33 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_dequeue_scripts_and_styles' ), 100 );
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
/**
|
37 |
* Modify xPath expression for Elementor plugin.
|
38 |
* The plugin does not wrap newly created text in 'p' tags.
|
39 |
*
|
40 |
-
* @param
|
41 |
-
*
|
42 |
-
* @return xPath expression
|
43 |
*/
|
44 |
public function content_injection_elementor( $tag ) {
|
45 |
if ( 'p' === $tag ) {
|
@@ -56,7 +65,6 @@ class Advanced_Ads_Compatibility {
|
|
56 |
* the code that depends on this function into the footer.
|
57 |
*
|
58 |
* @param array $pattern Patterns to match in inline JS content.
|
59 |
-
*
|
60 |
* @return array
|
61 |
*/
|
62 |
public function exclude_inline_js( $pattern ) {
|
@@ -70,7 +78,6 @@ class Advanced_Ads_Compatibility {
|
|
70 |
* show only all languages in language switcher on Advanced Ads pages if ads and groups are translated
|
71 |
*
|
72 |
* @param array $active_languages languages that can be used in language switcher.
|
73 |
-
*
|
74 |
* @return array
|
75 |
*/
|
76 |
public function wpml_language_switcher( $active_languages ) {
|
@@ -106,8 +113,8 @@ class Advanced_Ads_Compatibility {
|
|
106 |
*
|
107 |
* @param array $url Array of URL parts.
|
108 |
* @param string $type URL type.
|
109 |
-
* @param
|
110 |
-
* @return array
|
111 |
*/
|
112 |
public function wordpress_seo_noindex_ad_attachments( $url, $type, $post ) {
|
113 |
if ( 'post' !== $type ) {
|
@@ -212,4 +219,102 @@ class Advanced_Ads_Compatibility {
|
|
212 |
wp_dequeue_style( 'jnews-admin' );
|
213 |
}
|
214 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
215 |
}
|
30 |
// Add shortcode for MailPoet.
|
31 |
add_filter( 'mailpoet_newsletter_shortcode', array( $this, 'mailpoet_ad_shortcode' ), 10, 5 );
|
32 |
|
33 |
+
// Enable Advanced Custom Fields on ad edit pages.
|
34 |
+
if ( class_exists( 'ACF', false ) ) {
|
35 |
+
add_filter( 'advanced-ads-ad-edit-allowed-metaboxes', array( $this, 'advanced_custom_fields_box' ) );
|
36 |
+
}
|
37 |
+
|
38 |
add_action( 'admin_enqueue_scripts', array( $this, 'admin_dequeue_scripts_and_styles' ), 100 );
|
39 |
+
|
40 |
+
if ( defined( 'BORLABS_COOKIE_VERSION' ) ) {
|
41 |
+
// Check if Verification code & Auto ads ads can be displayed.
|
42 |
+
add_filter( 'advanced-ads-can-display-ads-in-header', array( $this, 'borlabs_cookie_can_add_auto_ads_code' ), 10 );
|
43 |
+
}
|
44 |
}
|
45 |
|
46 |
/**
|
47 |
* Modify xPath expression for Elementor plugin.
|
48 |
* The plugin does not wrap newly created text in 'p' tags.
|
49 |
*
|
50 |
+
* @param string $tag xpath tag.
|
51 |
+
* @return string xPath expression
|
|
|
52 |
*/
|
53 |
public function content_injection_elementor( $tag ) {
|
54 |
if ( 'p' === $tag ) {
|
65 |
* the code that depends on this function into the footer.
|
66 |
*
|
67 |
* @param array $pattern Patterns to match in inline JS content.
|
|
|
68 |
* @return array
|
69 |
*/
|
70 |
public function exclude_inline_js( $pattern ) {
|
78 |
* show only all languages in language switcher on Advanced Ads pages if ads and groups are translated
|
79 |
*
|
80 |
* @param array $active_languages languages that can be used in language switcher.
|
|
|
81 |
* @return array
|
82 |
*/
|
83 |
public function wpml_language_switcher( $active_languages ) {
|
113 |
*
|
114 |
* @param array $url Array of URL parts.
|
115 |
* @param string $type URL type.
|
116 |
+
* @param object $post WP_Post object of attachment.
|
117 |
+
* @return array|bool Unmodified array of URL parts or false to remove URL.
|
118 |
*/
|
119 |
public function wordpress_seo_noindex_ad_attachments( $url, $type, $post ) {
|
120 |
if ( 'post' !== $type ) {
|
219 |
wp_dequeue_style( 'jnews-admin' );
|
220 |
}
|
221 |
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Check if Adsense Auto ads code can be added to the header.
|
225 |
+
*
|
226 |
+
* @param bool $can_display if the ad can already be displayed.
|
227 |
+
* @return bool
|
228 |
+
*/
|
229 |
+
public function borlabs_cookie_can_add_auto_ads_code( $can_display ) {
|
230 |
+
if ( ! $can_display ) {
|
231 |
+
return false;
|
232 |
+
}
|
233 |
+
|
234 |
+
return ! self::borlabs_cookie_adsense_auto_ads_code_exists();
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Check if Adsense Auto ads code is added by the Borlabs Cookie plugin.
|
239 |
+
*
|
240 |
+
* This allows to prevent the "Only one 'enable_page_level_ads' allowed per page" error
|
241 |
+
* that makes impossible to close the "Privacy Preference" window created by the "Borlabs Cookie" plugin.
|
242 |
+
*
|
243 |
+
* @return bool
|
244 |
+
*/
|
245 |
+
public static function borlabs_cookie_adsense_auto_ads_code_exists() {
|
246 |
+
// Cache the result in order to perform the check only once.
|
247 |
+
static $result = null;
|
248 |
+
|
249 |
+
if ( null !== $result ) {
|
250 |
+
return $result;
|
251 |
+
}
|
252 |
+
|
253 |
+
// Set the `autoload` param to `true` so that the class loads both in frontend and backend.
|
254 |
+
if ( class_exists( '\BorlabsCookie\Cookie\Frontend\Cookies', true ) ) {
|
255 |
+
try {
|
256 |
+
$refl_cookies = new ReflectionClass( '\BorlabsCookie\Cookie\Frontend\Cookies' );
|
257 |
+
|
258 |
+
if ( $refl_cookies->hasMethod( 'getInstance' ) && $refl_cookies->hasMethod( 'getAllCookieGroups' ) ) {
|
259 |
+
$instance = $refl_cookies->getMethod( 'getInstance' );
|
260 |
+
$cookie_groups = $refl_cookies->getMethod( 'getAllCookieGroups' );
|
261 |
+
|
262 |
+
if ( $instance->isPublic() && $instance->isStatic() && $cookie_groups->isPublic() ) {
|
263 |
+
$all_cookies = BorlabsCookie\Cookie\Frontend\Cookies::getInstance()->getAllCookieGroups();
|
264 |
+
}
|
265 |
+
}
|
266 |
+
} catch ( Exception $e ) {
|
267 |
+
$result = false;
|
268 |
+
return $result;
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
if ( empty( $all_cookies ) ) {
|
273 |
+
$result = false;
|
274 |
+
return $result;
|
275 |
+
}
|
276 |
+
|
277 |
+
foreach ( $all_cookies as $cookie_group_data ) {
|
278 |
+
if ( ! empty( $cookie_group_data->group_id ) && 'marketing' === $cookie_group_data->group_id
|
279 |
+
&& ! empty( $cookie_group_data->cookies ) ) {
|
280 |
+
foreach ( $cookie_group_data->cookies as $cookie_data ) {
|
281 |
+
if ( ! empty( $cookie_data->cookie_id ) && 'google-adsense' === $cookie_data->cookie_id
|
282 |
+
&& ! empty( $cookie_data->opt_in_js ) ) {
|
283 |
+
$opt_in_js = $cookie_data->opt_in_js;
|
284 |
+
}
|
285 |
+
}
|
286 |
+
}
|
287 |
+
}
|
288 |
+
|
289 |
+
if ( empty( $opt_in_js ) ) {
|
290 |
+
$result = false;
|
291 |
+
return $result;
|
292 |
+
}
|
293 |
+
|
294 |
+
$result = preg_match( '/<script[^>]+data-ad-client/', $opt_in_js ) || false !== strpos( $opt_in_js, 'enable_page_level_ads:' );
|
295 |
+
return $result;
|
296 |
+
}
|
297 |
+
|
298 |
+
/**
|
299 |
+
* Whitelist meta boxes created by the Advanced Custom Fields plugin on the ad edit pages
|
300 |
+
* when they are dedicated for the "Ad" post type.
|
301 |
+
*
|
302 |
+
* @param array $meta_boxes already whitelisted meta boxes.
|
303 |
+
* @return array
|
304 |
+
*/
|
305 |
+
public function advanced_custom_fields_box( $meta_boxes ) {
|
306 |
+
|
307 |
+
// load ACF field groups dedicated to the Advanced Ads post type
|
308 |
+
$groups = acf_get_field_groups( array( 'post_type' => Advanced_Ads::POST_TYPE_SLUG ) );
|
309 |
+
|
310 |
+
if ( is_array( $groups ) && $groups ) {
|
311 |
+
foreach ( $groups as $_group ) {
|
312 |
+
if ( isset( $_group['key'] ) ) {
|
313 |
+
$meta_boxes[] = 'acf-' . $_group['key'];
|
314 |
+
}
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
return $meta_boxes;
|
319 |
+
}
|
320 |
}
|
classes/plugin.php
CHANGED
@@ -165,7 +165,7 @@ class Advanced_Ads_Plugin {
|
|
165 |
if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
|
166 |
wp_enqueue_script(
|
167 |
$this->get_plugin_slug() . '-advanced-js',
|
168 |
-
sprintf( '%spublic/assets/js/advanced%s.js', ADVADS_BASE_URL, defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '
|
169 |
array( 'jquery' ),
|
170 |
ADVADS_VERSION,
|
171 |
false
|
165 |
if ( $activated_js || ! empty( $_COOKIE['advads_frontend_picker'] ) ) {
|
166 |
wp_enqueue_script(
|
167 |
$this->get_plugin_slug() . '-advanced-js',
|
168 |
+
sprintf( '%spublic/assets/js/advanced%s.js', ADVADS_BASE_URL, defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min' ),
|
169 |
array( 'jquery' ),
|
170 |
ADVADS_VERSION,
|
171 |
false
|
languages/advanced-ads.pot
CHANGED
@@ -2,14 +2,14 @@
|
|
2 |
# This file is distributed under the same license as the Advanced Ads plugin.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: Advanced Ads 1.20.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
|
7 |
"Last-Translator: Thomas Maier <post@webzunft.de>\n"
|
8 |
"Language-Team: webgilde <support@wpadvancedads.com>\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
12 |
-
"POT-Creation-Date: 2020-10-
|
13 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
14 |
"X-Generator: WP-CLI 2.4.0\n"
|
15 |
"X-Domain: advanced-ads\n"
|
@@ -1372,7 +1372,7 @@ msgstr ""
|
|
1372 |
#: admin/views/placements-ad-label.php:9
|
1373 |
#: admin/views/placements-ad-label.php:11
|
1374 |
#: admin/views/placements.php:150
|
1375 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
1376 |
msgid "default"
|
1377 |
msgstr ""
|
1378 |
|
@@ -1628,7 +1628,7 @@ msgid "Visitor conditions limit the number of users who can see your ad. There i
|
|
1628 |
msgstr ""
|
1629 |
|
1630 |
#: admin/views/conditions/visitor-conditions-form-top.php:9
|
1631 |
-
#: modules/privacy/admin/views/setting-general.php:
|
1632 |
msgid "It seems that a caching plugin is activated."
|
1633 |
msgstr ""
|
1634 |
|
@@ -3086,7 +3086,7 @@ msgid "I want to change the position of the ads"
|
|
3086 |
msgstr ""
|
3087 |
|
3088 |
#: classes/frontend_checks.php:854
|
3089 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3090 |
msgid "Display Auto ads only on specific pages"
|
3091 |
msgstr ""
|
3092 |
|
@@ -3213,7 +3213,7 @@ msgid "Ad blocker fix"
|
|
3213 |
msgstr ""
|
3214 |
|
3215 |
#: modules/ad-blocker/admin/admin.php:150
|
3216 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3217 |
msgid "Unable to connect to the filesystem. Please confirm your credentials."
|
3218 |
msgstr ""
|
3219 |
|
@@ -3300,49 +3300,49 @@ msgstr ""
|
|
3300 |
msgid "Want to know how many of your visitors are using an ad blocker? Enter your Google Analytics property ID above to count them."
|
3301 |
msgstr ""
|
3302 |
|
3303 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3304 |
msgid "The ads.txt file cannot be placed because the URL contains a subdirectory. You need to make the file available at %s"
|
3305 |
msgstr ""
|
3306 |
|
3307 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3308 |
msgid "The file is available on %s."
|
3309 |
msgstr ""
|
3310 |
|
3311 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3312 |
msgid "The file was not created."
|
3313 |
msgstr ""
|
3314 |
|
3315 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3316 |
msgid "Import & Replace"
|
3317 |
msgstr ""
|
3318 |
|
3319 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3320 |
msgid "Move the content of the existing ads.txt file into Advanced Ads and remove it."
|
3321 |
msgstr ""
|
3322 |
|
3323 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3324 |
#: modules/ads-txt/admin/views/setting-additional-content.php:29
|
3325 |
msgid "An error occured: %s."
|
3326 |
msgstr ""
|
3327 |
|
3328 |
#. translators: %s the line that may need to be added manually
|
3329 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3330 |
msgid "If your site is located on a subdomain, you need to add the following line to the ads.txt file of the root domain: %s"
|
3331 |
msgstr ""
|
3332 |
|
3333 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3334 |
msgid "The ads.txt is now managed with Advanced Ads."
|
3335 |
msgstr ""
|
3336 |
|
3337 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3338 |
msgid "Not the main blog"
|
3339 |
msgstr ""
|
3340 |
|
3341 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3342 |
msgid "Could not delete the existing ads.txt file"
|
3343 |
msgstr ""
|
3344 |
|
3345 |
-
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:
|
3346 |
msgid "Could not find the existing ads.txt file"
|
3347 |
msgstr ""
|
3348 |
|
@@ -3544,6 +3544,11 @@ msgstr ""
|
|
3544 |
msgid "How to enable Auto ads in 30 seconds (video tutorial)"
|
3545 |
msgstr ""
|
3546 |
|
|
|
|
|
|
|
|
|
|
|
3547 |
#: modules/gadsense/admin/views/connect-adsense.php:35
|
3548 |
msgid "Please enter the confirmation code."
|
3549 |
msgstr ""
|
@@ -3748,31 +3753,31 @@ msgid "An error occurred while requesting account details."
|
|
3748 |
msgstr ""
|
3749 |
|
3750 |
#: modules/gadsense/includes/class-mapi.php:1320
|
3751 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3752 |
msgctxt "AdSense ad type"
|
3753 |
msgid "Matched Content"
|
3754 |
msgstr ""
|
3755 |
|
3756 |
#: modules/gadsense/includes/class-mapi.php:1323
|
3757 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3758 |
msgctxt "AdSense ad type"
|
3759 |
msgid "In-article"
|
3760 |
msgstr ""
|
3761 |
|
3762 |
#: modules/gadsense/includes/class-mapi.php:1325
|
3763 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3764 |
msgctxt "AdSense ad type"
|
3765 |
msgid "In-feed"
|
3766 |
msgstr ""
|
3767 |
|
3768 |
#: modules/gadsense/includes/class-mapi.php:1330
|
3769 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3770 |
msgctxt "AdSense ad type"
|
3771 |
msgid "Display"
|
3772 |
msgstr ""
|
3773 |
|
3774 |
#: modules/gadsense/includes/class-mapi.php:1332
|
3775 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3776 |
msgctxt "AdSense ad type"
|
3777 |
msgid "Link"
|
3778 |
msgstr ""
|
@@ -3843,42 +3848,41 @@ msgstr ""
|
|
3843 |
msgid "Enable this option to stop loading stats from AdSense into your WordPress backend."
|
3844 |
msgstr ""
|
3845 |
|
3846 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3847 |
-
msgid "
|
3848 |
msgstr ""
|
3849 |
|
3850 |
-
|
3851 |
-
|
3852 |
-
msgid "Please read <a href=\"%s\" target=\"_blank\">this article</a> if <strong>ads appear in random places</strong>."
|
3853 |
msgstr ""
|
3854 |
|
3855 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3856 |
msgid "Enable AMP Auto ads"
|
3857 |
msgstr ""
|
3858 |
|
3859 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3860 |
msgid "Disable warnings about potential violations of the AdSense terms."
|
3861 |
msgstr ""
|
3862 |
|
3863 |
#. Translators: %s is a URL.
|
3864 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3865 |
msgid "Our <a href=\"%s\" target=\"_blank\">Ad Health</a> feature monitors if AdSense is implemented correctly on your site. It also considers ads not managed with Advanced Ads. Enable this option to remove these checks"
|
3866 |
msgstr ""
|
3867 |
|
3868 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3869 |
msgid "Enable this option in case your theme adds an unfortunate background color to AdSense ads."
|
3870 |
msgstr ""
|
3871 |
|
3872 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3873 |
msgid "enable"
|
3874 |
msgstr ""
|
3875 |
|
3876 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3877 |
msgid "disable"
|
3878 |
msgstr ""
|
3879 |
|
3880 |
#. Translators: %s is a URL.
|
3881 |
-
#: modules/gadsense/includes/class-network-adsense.php:
|
3882 |
msgid "Whether your responsive ad unit may expand to <a href='%s' target='blank'>use the full width</a> of your visitor's mobile device screen"
|
3883 |
msgstr ""
|
3884 |
|
@@ -4089,20 +4093,20 @@ msgstr ""
|
|
4089 |
msgid "Show non-personalized AdSense ads until consent is given."
|
4090 |
msgstr ""
|
4091 |
|
4092 |
-
#: modules/privacy/admin/views/setting-general.php:
|
4093 |
msgid "Your users’ consent might get cached and show ads to users who didn’t give their consent yet. "
|
4094 |
msgstr ""
|
4095 |
|
4096 |
-
#: modules/privacy/admin/views/setting-general.php:
|
4097 |
msgid "Cache-busting in Advanced Ads Pro solves that."
|
4098 |
msgstr ""
|
4099 |
|
4100 |
-
#: modules/privacy/admin/views/setting-general.php:
|
4101 |
msgid "Ads are loaded after the user gives their consent and reloads the page."
|
4102 |
msgstr ""
|
4103 |
|
4104 |
#. Translators: 1: opening link tag with link to Advanced Ads Pro 2: closing link tag
|
4105 |
-
#: modules/privacy/admin/views/setting-general.php:
|
4106 |
msgid "Install %1$sAdvanced Ads Pro%2$s to reload the ads instantly without an additional page request."
|
4107 |
msgstr ""
|
4108 |
|
2 |
# This file is distributed under the same license as the Advanced Ads plugin.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: Advanced Ads 1.20.3\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/advanced-ads/\n"
|
7 |
"Last-Translator: Thomas Maier <post@webzunft.de>\n"
|
8 |
"Language-Team: webgilde <support@wpadvancedads.com>\n"
|
9 |
"MIME-Version: 1.0\n"
|
10 |
"Content-Type: text/plain; charset=UTF-8\n"
|
11 |
"Content-Transfer-Encoding: 8bit\n"
|
12 |
+
"POT-Creation-Date: 2020-10-23T08:57:18+00:00\n"
|
13 |
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
14 |
"X-Generator: WP-CLI 2.4.0\n"
|
15 |
"X-Domain: advanced-ads\n"
|
1372 |
#: admin/views/placements-ad-label.php:9
|
1373 |
#: admin/views/placements-ad-label.php:11
|
1374 |
#: admin/views/placements.php:150
|
1375 |
+
#: modules/gadsense/includes/class-network-adsense.php:318
|
1376 |
msgid "default"
|
1377 |
msgstr ""
|
1378 |
|
1628 |
msgstr ""
|
1629 |
|
1630 |
#: admin/views/conditions/visitor-conditions-form-top.php:9
|
1631 |
+
#: modules/privacy/admin/views/setting-general.php:64
|
1632 |
msgid "It seems that a caching plugin is activated."
|
1633 |
msgstr ""
|
1634 |
|
3086 |
msgstr ""
|
3087 |
|
3088 |
#: classes/frontend_checks.php:854
|
3089 |
+
#: modules/gadsense/includes/class-network-adsense.php:228
|
3090 |
msgid "Display Auto ads only on specific pages"
|
3091 |
msgstr ""
|
3092 |
|
3213 |
msgstr ""
|
3214 |
|
3215 |
#: modules/ad-blocker/admin/admin.php:150
|
3216 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:367
|
3217 |
msgid "Unable to connect to the filesystem. Please confirm your credentials."
|
3218 |
msgstr ""
|
3219 |
|
3300 |
msgid "Want to know how many of your visitors are using an ad blocker? Enter your Google Analytics property ID above to count them."
|
3301 |
msgstr ""
|
3302 |
|
3303 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:181
|
3304 |
msgid "The ads.txt file cannot be placed because the URL contains a subdirectory. You need to make the file available at %s"
|
3305 |
msgstr ""
|
3306 |
|
3307 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:192
|
3308 |
msgid "The file is available on %s."
|
3309 |
msgstr ""
|
3310 |
|
3311 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:196
|
3312 |
msgid "The file was not created."
|
3313 |
msgstr ""
|
3314 |
|
3315 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:203
|
3316 |
msgid "Import & Replace"
|
3317 |
msgstr ""
|
3318 |
|
3319 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:205
|
3320 |
msgid "Move the content of the existing ads.txt file into Advanced Ads and remove it."
|
3321 |
msgstr ""
|
3322 |
|
3323 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:212
|
3324 |
#: modules/ads-txt/admin/views/setting-additional-content.php:29
|
3325 |
msgid "An error occured: %s."
|
3326 |
msgstr ""
|
3327 |
|
3328 |
#. translators: %s the line that may need to be added manually
|
3329 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:225
|
3330 |
msgid "If your site is located on a subdomain, you need to add the following line to the ads.txt file of the root domain: %s"
|
3331 |
msgstr ""
|
3332 |
|
3333 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:340
|
3334 |
msgid "The ads.txt is now managed with Advanced Ads."
|
3335 |
msgstr ""
|
3336 |
|
3337 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:385
|
3338 |
msgid "Not the main blog"
|
3339 |
msgstr ""
|
3340 |
|
3341 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:414
|
3342 |
msgid "Could not delete the existing ads.txt file"
|
3343 |
msgstr ""
|
3344 |
|
3345 |
+
#: modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php:417
|
3346 |
msgid "Could not find the existing ads.txt file"
|
3347 |
msgstr ""
|
3348 |
|
3544 |
msgid "How to enable Auto ads in 30 seconds (video tutorial)"
|
3545 |
msgstr ""
|
3546 |
|
3547 |
+
#. translators: 1: the plugin name that is managing the Auto ads code.
|
3548 |
+
#: modules/gadsense/admin/views/borlabs-cookie-auto-ads-warning.php:4
|
3549 |
+
msgid "Advanced Ads detected that <strong>%s</strong> is managing the Auto ads code and will therefore not add it."
|
3550 |
+
msgstr ""
|
3551 |
+
|
3552 |
#: modules/gadsense/admin/views/connect-adsense.php:35
|
3553 |
msgid "Please enter the confirmation code."
|
3554 |
msgstr ""
|
3753 |
msgstr ""
|
3754 |
|
3755 |
#: modules/gadsense/includes/class-mapi.php:1320
|
3756 |
+
#: modules/gadsense/includes/class-network-adsense.php:509
|
3757 |
msgctxt "AdSense ad type"
|
3758 |
msgid "Matched Content"
|
3759 |
msgstr ""
|
3760 |
|
3761 |
#: modules/gadsense/includes/class-mapi.php:1323
|
3762 |
+
#: modules/gadsense/includes/class-network-adsense.php:510
|
3763 |
msgctxt "AdSense ad type"
|
3764 |
msgid "In-article"
|
3765 |
msgstr ""
|
3766 |
|
3767 |
#: modules/gadsense/includes/class-mapi.php:1325
|
3768 |
+
#: modules/gadsense/includes/class-network-adsense.php:511
|
3769 |
msgctxt "AdSense ad type"
|
3770 |
msgid "In-feed"
|
3771 |
msgstr ""
|
3772 |
|
3773 |
#: modules/gadsense/includes/class-mapi.php:1330
|
3774 |
+
#: modules/gadsense/includes/class-network-adsense.php:512
|
3775 |
msgctxt "AdSense ad type"
|
3776 |
msgid "Display"
|
3777 |
msgstr ""
|
3778 |
|
3779 |
#: modules/gadsense/includes/class-mapi.php:1332
|
3780 |
+
#: modules/gadsense/includes/class-network-adsense.php:513
|
3781 |
msgctxt "AdSense ad type"
|
3782 |
msgid "Link"
|
3783 |
msgstr ""
|
3848 |
msgid "Enable this option to stop loading stats from AdSense into your WordPress backend."
|
3849 |
msgstr ""
|
3850 |
|
3851 |
+
#: modules/gadsense/includes/class-network-adsense.php:229
|
3852 |
+
msgid "Why are ads appearing in random positions?"
|
3853 |
msgstr ""
|
3854 |
|
3855 |
+
#: modules/gadsense/includes/class-network-adsense.php:238
|
3856 |
+
msgid "Adjust Auto ads options"
|
|
|
3857 |
msgstr ""
|
3858 |
|
3859 |
+
#: modules/gadsense/includes/class-network-adsense.php:255
|
3860 |
msgid "Enable AMP Auto ads"
|
3861 |
msgstr ""
|
3862 |
|
3863 |
+
#: modules/gadsense/includes/class-network-adsense.php:276
|
3864 |
msgid "Disable warnings about potential violations of the AdSense terms."
|
3865 |
msgstr ""
|
3866 |
|
3867 |
#. Translators: %s is a URL.
|
3868 |
+
#: modules/gadsense/includes/class-network-adsense.php:282
|
3869 |
msgid "Our <a href=\"%s\" target=\"_blank\">Ad Health</a> feature monitors if AdSense is implemented correctly on your site. It also considers ads not managed with Advanced Ads. Enable this option to remove these checks"
|
3870 |
msgstr ""
|
3871 |
|
3872 |
+
#: modules/gadsense/includes/class-network-adsense.php:306
|
3873 |
msgid "Enable this option in case your theme adds an unfortunate background color to AdSense ads."
|
3874 |
msgstr ""
|
3875 |
|
3876 |
+
#: modules/gadsense/includes/class-network-adsense.php:319
|
3877 |
msgid "enable"
|
3878 |
msgstr ""
|
3879 |
|
3880 |
+
#: modules/gadsense/includes/class-network-adsense.php:320
|
3881 |
msgid "disable"
|
3882 |
msgstr ""
|
3883 |
|
3884 |
#. Translators: %s is a URL.
|
3885 |
+
#: modules/gadsense/includes/class-network-adsense.php:327
|
3886 |
msgid "Whether your responsive ad unit may expand to <a href='%s' target='blank'>use the full width</a> of your visitor's mobile device screen"
|
3887 |
msgstr ""
|
3888 |
|
4093 |
msgid "Show non-personalized AdSense ads until consent is given."
|
4094 |
msgstr ""
|
4095 |
|
4096 |
+
#: modules/privacy/admin/views/setting-general.php:67
|
4097 |
msgid "Your users’ consent might get cached and show ads to users who didn’t give their consent yet. "
|
4098 |
msgstr ""
|
4099 |
|
4100 |
+
#: modules/privacy/admin/views/setting-general.php:70
|
4101 |
msgid "Cache-busting in Advanced Ads Pro solves that."
|
4102 |
msgstr ""
|
4103 |
|
4104 |
+
#: modules/privacy/admin/views/setting-general.php:79
|
4105 |
msgid "Ads are loaded after the user gives their consent and reloads the page."
|
4106 |
msgstr ""
|
4107 |
|
4108 |
#. Translators: 1: opening link tag with link to Advanced Ads Pro 2: closing link tag
|
4109 |
+
#: modules/privacy/admin/views/setting-general.php:83
|
4110 |
msgid "Install %1$sAdvanced Ads Pro%2$s to reload the ads instantly without an additional page request."
|
4111 |
msgstr ""
|
4112 |
|
modules/ads-txt/admin/class-advanced-ads-ads-txt-admin.php
CHANGED
@@ -33,9 +33,11 @@ class Advanced_Ads_Ads_Txt_Admin {
|
|
33 |
* @return array $options Options.
|
34 |
*/
|
35 |
public function toggle( $options ) {
|
36 |
-
|
37 |
-
$
|
38 |
-
$
|
|
|
|
|
39 |
|
40 |
$this->strategy->toggle( $create, $all_network, $additional_content );
|
41 |
$content = $this->get_adsense_blog_data();
|
33 |
* @return array $options Options.
|
34 |
*/
|
35 |
public function toggle( $options ) {
|
36 |
+
// phpcs:disable WordPress.Security.NonceVerification.Missing
|
37 |
+
$create = ! empty( $_POST['advads-ads-txt-create'] );
|
38 |
+
$all_network = ! empty( $_POST['advads-ads-txt-all-network'] );
|
39 |
+
$additional_content = ! empty( $_POST['advads-ads-txt-additional-content'] ) ? trim( wp_unslash( $_POST['advads-ads-txt-additional-content'] ) ) : '';
|
40 |
+
// phpcs:enable
|
41 |
|
42 |
$this->strategy->toggle( $create, $all_network, $additional_content );
|
43 |
$content = $this->get_adsense_blog_data();
|
modules/gadsense/admin/views/borlabs-cookie-auto-ads-warning.php
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php printf(
|
2 |
+
wp_kses(
|
3 |
+
/* translators: 1: the plugin name that is managing the Auto ads code. */
|
4 |
+
__( 'Advanced Ads detected that <strong>%s</strong> is managing the Auto ads code and will therefore not add it.', 'advanced-ads' ),
|
5 |
+
array(
|
6 |
+
'strong' => array(),
|
7 |
+
)
|
8 |
+
),
|
9 |
+
'Borlabs Cookies'
|
10 |
+
);
|
11 |
+
|
modules/gadsense/includes/class-network-adsense.php
CHANGED
@@ -222,38 +222,32 @@ class Advanced_Ads_Network_Adsense extends Advanced_Ads_Ad_Network {
|
|
222 |
<label><input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[page-level-enabled]" value="1" <?php checked( $page_level ); ?> />
|
223 |
<?php
|
224 |
esc_attr_e( 'Insert the AdSense header code used for verification and the Auto Ads feature.', 'advanced-ads' );
|
225 |
-
|
226 |
-
|
227 |
-
|
|
|
|
|
228 |
<?php
|
|
|
|
|
|
|
|
|
229 |
/**
|
230 |
* Translators: this is the text for a link to a sub-page in an AdSense account
|
231 |
*/
|
232 |
esc_attr_e( 'Adjust Auto ads options', 'advanced-ads' );
|
233 |
-
|
234 |
-
</a>
|
235 |
-
|
236 |
endif;
|
237 |
-
|
238 |
-
</
|
239 |
-
<?php
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
'a' => array(
|
246 |
-
'href' => array(),
|
247 |
-
'target' => array(),
|
248 |
-
),
|
249 |
-
'strong' => array(),
|
250 |
-
)
|
251 |
-
),
|
252 |
-
esc_url( ADVADS_URL ) . 'adsense-in-random-positions-auto-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads'
|
253 |
-
);
|
254 |
-
?>
|
255 |
-
</p>
|
256 |
-
<p class="description"><a href="<?php echo esc_url( ADVADS_URL ) . 'adsense-auto-ads-wordpress/#Display_Auto_Ads_only_on_specific_pages'; ?>" target="_blank"><?php esc_attr_e( 'Display Auto ads only on specific pages', 'advanced-ads' ); ?></a></p>
|
257 |
<?php
|
258 |
// Show information about AMP Auto ads when an AMP plugin is installed and Responsive Ads is missing.
|
259 |
if ( ! defined( 'AAR_VERSION' ) && Advanced_Ads_Checks::active_amp_plugin() ) :
|
222 |
<label><input type="checkbox" name="<?php echo esc_attr( GADSENSE_OPT_NAME ); ?>[page-level-enabled]" value="1" <?php checked( $page_level ); ?> />
|
223 |
<?php
|
224 |
esc_attr_e( 'Insert the AdSense header code used for verification and the Auto Ads feature.', 'advanced-ads' );
|
225 |
+
?>
|
226 |
+
</label>
|
227 |
+
<ul>
|
228 |
+
<li><a href="<?php echo esc_url( ADVADS_URL ) . 'adsense-auto-ads-wordpress/#Display_Auto_Ads_only_on_specific_pages'; ?>" target="_blank"><?php esc_attr_e( 'Display Auto ads only on specific pages', 'advanced-ads' ); ?></a></li>
|
229 |
+
<li><a href="<?php echo esc_url( ADVADS_URL ) . 'adsense-in-random-positions-auto-ads/#utm_source=advanced-ads&utm_medium=link&utm_campaign=backend-autoads-ads'; ?>" target="_blank"><?php esc_attr_e( 'Why are ads appearing in random positions?', 'advanced-ads' ); ?></a></li>
|
230 |
<?php
|
231 |
+
if ( ! empty( $options['adsense-id'] ) ) :
|
232 |
+
?>
|
233 |
+
<li><a href="https://www.google.com/adsense/new/u/0/<?php echo esc_attr( $options['adsense-id'] ); ?>/myads/auto-ads" target="_blank">
|
234 |
+
<?php
|
235 |
/**
|
236 |
* Translators: this is the text for a link to a sub-page in an AdSense account
|
237 |
*/
|
238 |
esc_attr_e( 'Adjust Auto ads options', 'advanced-ads' );
|
239 |
+
?>
|
240 |
+
</a></li>
|
241 |
+
<?php
|
242 |
endif;
|
243 |
+
?>
|
244 |
+
</ul>
|
245 |
+
<?php if ( Advanced_Ads_Compatibility::borlabs_cookie_adsense_auto_ads_code_exists() ) : ?>
|
246 |
+
<p class="advads-error-message">
|
247 |
+
<?php require GADSENSE_BASE_PATH . 'admin/views/borlabs-cookie-auto-ads-warning.php'; ?>
|
248 |
+
</p>
|
249 |
+
<?php endif; ?>
|
250 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
251 |
<?php
|
252 |
// Show information about AMP Auto ads when an AMP plugin is installed and Responsive Ads is missing.
|
253 |
if ( ! defined( 'AAR_VERSION' ) && Advanced_Ads_Checks::active_amp_plugin() ) :
|
modules/privacy/admin/views/setting-general.php
CHANGED
@@ -52,6 +52,11 @@
|
|
52 |
<input type="checkbox" name="<?php echo esc_attr( Advanced_Ads_Privacy::OPTION_KEY ); ?>[show-non-personalized-adsense]" <?php checked( $show_non_personalized_adsense ); ?> />
|
53 |
<?php esc_html_e( 'Show non-personalized AdSense ads until consent is given.', 'advanced-ads' ); ?>
|
54 |
</label>
|
|
|
|
|
|
|
|
|
|
|
55 |
</div>
|
56 |
|
57 |
<?php if ( apply_filters( 'advanced-ads-privacy-custom-show-warning', ! empty( $checked ) && Advanced_Ads_Checks::cache() ) ) : ?>
|
52 |
<input type="checkbox" name="<?php echo esc_attr( Advanced_Ads_Privacy::OPTION_KEY ); ?>[show-non-personalized-adsense]" <?php checked( $show_non_personalized_adsense ); ?> />
|
53 |
<?php esc_html_e( 'Show non-personalized AdSense ads until consent is given.', 'advanced-ads' ); ?>
|
54 |
</label>
|
55 |
+
<?php if ( Advanced_Ads_Compatibility::borlabs_cookie_adsense_auto_ads_code_exists() ) : ?>
|
56 |
+
<p class="description">
|
57 |
+
<?php require GADSENSE_BASE_PATH . 'admin/views/borlabs-cookie-auto-ads-warning.php'; ?>
|
58 |
+
</p>
|
59 |
+
<?php endif; ?>
|
60 |
</div>
|
61 |
|
62 |
<?php if ( apply_filters( 'advanced-ads-privacy-custom-show-warning', ! empty( $checked ) && Advanced_Ads_Checks::cache() ) ) : ?>
|
public/assets/js/advanced.js
CHANGED
@@ -1 +1,874 @@
|
|
1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* advanced ads functions to be used directly within ad codes
|
3 |
+
*/
|
4 |
+
|
5 |
+
advads = {
|
6 |
+
/**
|
7 |
+
* check if localstorage is supported/enabled by client
|
8 |
+
*/
|
9 |
+
supports_localstorage: function () {
|
10 |
+
"use strict";
|
11 |
+
try {
|
12 |
+
if ( ! window || window.localStorage === undefined ) {
|
13 |
+
return false;
|
14 |
+
}
|
15 |
+
// storage might be full or disabled
|
16 |
+
window.localStorage.setItem( "x", "x" );
|
17 |
+
window.localStorage.removeItem( "x" );
|
18 |
+
return true;
|
19 |
+
} catch ( e ) {
|
20 |
+
return false;
|
21 |
+
}
|
22 |
+
},
|
23 |
+
/**
|
24 |
+
* check if the ad is displayed more than {max} times per session
|
25 |
+
* every check increases the counter
|
26 |
+
*
|
27 |
+
* @param {string} name (no id needed, just any id-formated string)
|
28 |
+
* @param {type} max number of maximum times the ad can be displayed within the period
|
29 |
+
* @returns {bool} true if limit is reached
|
30 |
+
*/
|
31 |
+
max_per_session: function ( name, max ) {
|
32 |
+
var num = 1;
|
33 |
+
if ( max === undefined || parseInt( max ) === 0 ) {
|
34 |
+
max = 1;
|
35 |
+
}
|
36 |
+
|
37 |
+
// check if cookie exists and get the value
|
38 |
+
if ( this.cookie_exists( name ) ) {
|
39 |
+
if ( this.get_cookie( name ) >= max ) {
|
40 |
+
return true;
|
41 |
+
}
|
42 |
+
num = num + parseInt( this.get_cookie( name ) );
|
43 |
+
}
|
44 |
+
this.set_cookie( name, num );
|
45 |
+
return false;
|
46 |
+
},
|
47 |
+
/**
|
48 |
+
* increase a cookie with an integer value by 1
|
49 |
+
*
|
50 |
+
* @param {str} name of the cookie
|
51 |
+
* @param {int} exdays days until cookie expires
|
52 |
+
*/
|
53 |
+
count_up: function ( name, exdays ) {
|
54 |
+
var num = 1;
|
55 |
+
|
56 |
+
// check if cookie exists and get the value
|
57 |
+
if ( this.cookie_exists( name ) ) {
|
58 |
+
num = num + parseInt( this.get_cookie( name ) );
|
59 |
+
}
|
60 |
+
this.set_cookie( name, num );
|
61 |
+
},
|
62 |
+
/**
|
63 |
+
* return true, if cookie exists
|
64 |
+
* return false, if not
|
65 |
+
* if not exists, create it
|
66 |
+
* use case: to check if something already happened in this page impression
|
67 |
+
*
|
68 |
+
* @param {type} name
|
69 |
+
* @returns {unresolved}
|
70 |
+
*/
|
71 |
+
set_cookie_exists: function ( name ) {
|
72 |
+
if ( get_cookie( name ) ) {
|
73 |
+
return true;
|
74 |
+
}
|
75 |
+
set_cookie( name, '', 0 );
|
76 |
+
return false;
|
77 |
+
},
|
78 |
+
/**
|
79 |
+
* get a cookie value
|
80 |
+
*
|
81 |
+
* @param {str} name of the cookie
|
82 |
+
*/
|
83 |
+
get_cookie: function ( name ) {
|
84 |
+
var i, x, y, ADVcookies = document.cookie.split( ";" );
|
85 |
+
for ( i = 0; i < ADVcookies.length; i ++ ) {
|
86 |
+
x = ADVcookies[i].substr( 0, ADVcookies[i].indexOf( "=" ) );
|
87 |
+
y = ADVcookies[i].substr( ADVcookies[i].indexOf( "=" ) + 1 );
|
88 |
+
x = x.replace( /^\s+|\s+$/g, "" );
|
89 |
+
if ( x === name ) {
|
90 |
+
return unescape( y );
|
91 |
+
}
|
92 |
+
}
|
93 |
+
},
|
94 |
+
/**
|
95 |
+
* set a cookie value
|
96 |
+
*
|
97 |
+
* @param {str} name of the cookie
|
98 |
+
* @param {str} value of the cookie
|
99 |
+
* @param {int} exdays days until cookie expires
|
100 |
+
* set 0 to expire cookie immidiatelly
|
101 |
+
* set null to expire cookie in the current session
|
102 |
+
*/
|
103 |
+
set_cookie: function ( name, value, exdays, path, domain, secure ) {
|
104 |
+
// days in seconds
|
105 |
+
var expiry = (
|
106 |
+
exdays == null
|
107 |
+
) ? null : exdays * 24 * 60 * 60;
|
108 |
+
this.set_cookie_sec( name, value, expiry, path, domain, secure );
|
109 |
+
},
|
110 |
+
/**
|
111 |
+
* set a cookie with expiry given in seconds
|
112 |
+
*
|
113 |
+
* @param {str} name of the cookie
|
114 |
+
* @param {str} value of the cookie
|
115 |
+
* @param {int} expiry seconds until cookie expires
|
116 |
+
* set 0 to expire cookie immidiatelly
|
117 |
+
* set null to expire cookie in the current session
|
118 |
+
*/
|
119 |
+
set_cookie_sec: function ( name, value, expiry, path, domain, secure ) {
|
120 |
+
var exdate = new Date();
|
121 |
+
exdate.setSeconds( exdate.getSeconds() + parseInt( expiry ) );
|
122 |
+
document.cookie = name + "=" + escape( value ) +
|
123 |
+
(
|
124 |
+
(
|
125 |
+
expiry == null
|
126 |
+
) ? "" : "; expires=" + exdate.toUTCString()
|
127 |
+
) +
|
128 |
+
(
|
129 |
+
(
|
130 |
+
path == null
|
131 |
+
) ? "; path=/" : "; path=" + path
|
132 |
+
) +
|
133 |
+
(
|
134 |
+
(
|
135 |
+
domain == null
|
136 |
+
) ? "" : "; domain=" + domain
|
137 |
+
) +
|
138 |
+
(
|
139 |
+
(
|
140 |
+
secure == null
|
141 |
+
) ? "" : "; secure"
|
142 |
+
);
|
143 |
+
},
|
144 |
+
/**
|
145 |
+
* check if a cookie is set and contains a value
|
146 |
+
*
|
147 |
+
* @param {str} name of the cookie
|
148 |
+
* @returns {bool} true, if cookie is set
|
149 |
+
*/
|
150 |
+
cookie_exists: function ( name ) {
|
151 |
+
var c_value = this.get_cookie( name );
|
152 |
+
if ( c_value !== null && c_value !== "" && c_value !== undefined ) {
|
153 |
+
return true;
|
154 |
+
}
|
155 |
+
return false;
|
156 |
+
},
|
157 |
+
/**
|
158 |
+
* move one element into another
|
159 |
+
*
|
160 |
+
* @param {str} element selector of the element that should be moved
|
161 |
+
* @param {str} target selector of the element where to move
|
162 |
+
* @param {arr} options
|
163 |
+
*/
|
164 |
+
move: function ( element, target, options ) {
|
165 |
+
|
166 |
+
var el = jQuery( element );
|
167 |
+
var target_string = target;
|
168 |
+
|
169 |
+
if ( typeof options === 'undefined' ) {
|
170 |
+
options = {};
|
171 |
+
}
|
172 |
+
if ( typeof options.css === 'undefined' ) {
|
173 |
+
options.css = {};
|
174 |
+
}
|
175 |
+
if ( typeof options.method === 'undefined' ) {
|
176 |
+
options.method = 'prependTo';
|
177 |
+
}
|
178 |
+
|
179 |
+
// search for abstract target element
|
180 |
+
if ( target === '' && typeof options.target !== 'undefined' ) {
|
181 |
+
switch ( options.target ) {
|
182 |
+
case 'wrapper' : // wrapper
|
183 |
+
var offset = 'left';
|
184 |
+
if ( typeof options.offset !== 'undefined' ) {
|
185 |
+
offset = options.offset;
|
186 |
+
}
|
187 |
+
target = this.find_wrapper( element, offset );
|
188 |
+
break;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
// use only visible elements
|
193 |
+
if ( typeof options.moveintohidden === 'undefined' ) {
|
194 |
+
target = jQuery( target ).filter( ':visible' );
|
195 |
+
} else {
|
196 |
+
target = jQuery( target );
|
197 |
+
}
|
198 |
+
|
199 |
+
// print warning in console if the element appears multiple times
|
200 |
+
if ( target.length > 1 ) {
|
201 |
+
console.log( "Advanced Ads: element '" + target_string + "' found " + target.length + " times." );
|
202 |
+
}
|
203 |
+
|
204 |
+
// switch insert method
|
205 |
+
switch ( options.method ) {
|
206 |
+
case 'insertBefore' :
|
207 |
+
el.insertBefore( target );
|
208 |
+
break;
|
209 |
+
case 'insertAfter' :
|
210 |
+
el.insertAfter( target );
|
211 |
+
break;
|
212 |
+
case 'appendTo' :
|
213 |
+
el.appendTo( target );
|
214 |
+
break;
|
215 |
+
case 'prependTo' :
|
216 |
+
el.prependTo( target );
|
217 |
+
break;
|
218 |
+
default :
|
219 |
+
el.prependTo( target );
|
220 |
+
}
|
221 |
+
},
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Set 'relative' position for a parent element.
|
225 |
+
*
|
226 |
+
* @param {str} element selector
|
227 |
+
*/
|
228 |
+
set_parent_relative: function ( element, options ) {
|
229 |
+
var options = typeof options !== 'undefined' ? options : {};
|
230 |
+
var el = jQuery( element );
|
231 |
+
// give "position" style to parent element, if missing
|
232 |
+
var parent = el.parent();
|
233 |
+
|
234 |
+
if ( options.use_grandparent ) {
|
235 |
+
parent = parent.parent();
|
236 |
+
}
|
237 |
+
|
238 |
+
if ( parent.css( 'position' ) === 'static' || parent.css( 'position' ) === '' ) {
|
239 |
+
parent.css( 'position', 'relative' );
|
240 |
+
}
|
241 |
+
},
|
242 |
+
|
243 |
+
/**
|
244 |
+
* make an absolute position element fixed at the current position
|
245 |
+
* hint: use only after DOM is fully loaded in order to fix a wrong position
|
246 |
+
*
|
247 |
+
* @param {str} element selector
|
248 |
+
* @param {obj} options
|
249 |
+
*/
|
250 |
+
fix_element: function ( element, options ) {
|
251 |
+
var options = typeof options !== 'undefined' ? options : {};
|
252 |
+
|
253 |
+
var el = jQuery( element );
|
254 |
+
|
255 |
+
if ( options.use_grandparent ) {
|
256 |
+
this.set_parent_relative( el.parent() );
|
257 |
+
} else {
|
258 |
+
this.set_parent_relative( el );
|
259 |
+
}
|
260 |
+
|
261 |
+
// fix element at current position
|
262 |
+
// get position for hidden elements by showing them for a very short time
|
263 |
+
if ( options.is_invisible ) {
|
264 |
+
el.show();
|
265 |
+
}
|
266 |
+
var topoffset = parseInt( el.offset().top );
|
267 |
+
var leftoffset = parseInt( el.offset().left );
|
268 |
+
if ( options.is_invisible ) {
|
269 |
+
el.hide();
|
270 |
+
}
|
271 |
+
if ( 'left' === options.offset ) {
|
272 |
+
// Allow to scale the nested image down when it has `max-width: 100%` and touches the left edge of the viewport.
|
273 |
+
var rightoffset = jQuery( window ).width() - leftoffset - el.outerWidth();
|
274 |
+
el.css( 'position', 'fixed' ).css( 'top', topoffset + 'px' ).css( 'right', rightoffset + 'px' ).css( 'left', '' );
|
275 |
+
} else {
|
276 |
+
// reset "right" to prevent conflicts
|
277 |
+
el.css( 'position', 'fixed' ).css( 'top', topoffset + 'px' ).css( 'left', leftoffset + 'px' ).css( 'right', '' );
|
278 |
+
}
|
279 |
+
|
280 |
+
},
|
281 |
+
|
282 |
+
/**
|
283 |
+
* find the main wrapper
|
284 |
+
* either id or first of its class
|
285 |
+
*
|
286 |
+
* @param {str} element selector
|
287 |
+
* @param {str} offset which position of the offset to check (left or right)
|
288 |
+
* @return {str} selector
|
289 |
+
*/
|
290 |
+
find_wrapper: function ( element, offset ) {
|
291 |
+
// first margin: auto element after body
|
292 |
+
var returnValue;
|
293 |
+
jQuery( 'body' ).children().each( function ( key, value ) {
|
294 |
+
// exclude current element
|
295 |
+
// TODO exclude <script>
|
296 |
+
if ( value.id !== element.substring( 1 ) ) {
|
297 |
+
// check offset value
|
298 |
+
var checkedelement = jQuery( value );
|
299 |
+
// check if there is space left or right of the element
|
300 |
+
if ( (
|
301 |
+
offset === 'right' && (
|
302 |
+
checkedelement.offset().left + jQuery( checkedelement ).width() < jQuery( window ).width()
|
303 |
+
)
|
304 |
+
) ||
|
305 |
+
(
|
306 |
+
offset === 'left' && checkedelement.offset().left > 0
|
307 |
+
) ) {
|
308 |
+
// fix element
|
309 |
+
if ( checkedelement.css( 'position' ) === 'static' || checkedelement.css( 'position' ) === '' ) {
|
310 |
+
checkedelement.css( 'position', 'relative' );
|
311 |
+
}
|
312 |
+
// set return value
|
313 |
+
returnValue = value;
|
314 |
+
return false;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
} );
|
318 |
+
return returnValue;
|
319 |
+
},
|
320 |
+
/**
|
321 |
+
* center fixed element on the screen
|
322 |
+
*
|
323 |
+
* @param {str} element selector
|
324 |
+
*/
|
325 |
+
center_fixed_element: function ( element ) {
|
326 |
+
var el = jQuery( element );
|
327 |
+
// half window width minus half element width
|
328 |
+
var left = (
|
329 |
+
jQuery( window ).width() / 2
|
330 |
+
) - (
|
331 |
+
parseInt( el.css( 'width' ) ) / 2
|
332 |
+
);
|
333 |
+
el.css( 'left', left + 'px' );
|
334 |
+
},
|
335 |
+
/**
|
336 |
+
* center element vertically on the screen
|
337 |
+
*
|
338 |
+
* @param {str} element selector
|
339 |
+
*/
|
340 |
+
center_vertically: function ( element ) {
|
341 |
+
var el = jQuery( element );
|
342 |
+
// half window height minus half element height
|
343 |
+
var left = (
|
344 |
+
jQuery( window ).height() / 2
|
345 |
+
) - (
|
346 |
+
parseInt( el.css( 'height' ) ) / 2
|
347 |
+
);
|
348 |
+
|
349 |
+
// Center correctly when the ad is attached to the element that begins lower.
|
350 |
+
if ( el.css( 'position' ) !== 'fixed' ) {
|
351 |
+
left -= topoffset = parseInt( el.offset().top );
|
352 |
+
}
|
353 |
+
el.css( 'top', left + 'px' );
|
354 |
+
},
|
355 |
+
/**
|
356 |
+
* close an ad and add a cookie
|
357 |
+
*
|
358 |
+
* @param {str} element selector
|
359 |
+
*/
|
360 |
+
close: function ( element ) {
|
361 |
+
var wrapper = jQuery( element );
|
362 |
+
// remove the ad
|
363 |
+
wrapper.remove();
|
364 |
+
},
|
365 |
+
/**
|
366 |
+
* Wait until images are ready.
|
367 |
+
*
|
368 |
+
* @param {obj} $el jQuery object.
|
369 |
+
* @param {function} ready_callback Ready callback.
|
370 |
+
* derrived from https://github.com/alexanderdickson/waitForImages/blob/master/dist/jquery.waitforimages.js
|
371 |
+
*/
|
372 |
+
wait_for_images: function ( $el, ready_callback ) {
|
373 |
+
var loaded_count = 0;
|
374 |
+
var srcs = [];
|
375 |
+
|
376 |
+
$el.find( 'img[src][src!=""]' ).each( function () {
|
377 |
+
srcs.push( this.src );
|
378 |
+
} );
|
379 |
+
|
380 |
+
if ( srcs.length === 0 ) {
|
381 |
+
ready_callback.call( $el );
|
382 |
+
}
|
383 |
+
|
384 |
+
jQuery.each( srcs, function ( i, src ) {
|
385 |
+
var image = new Image();
|
386 |
+
image.src = src;
|
387 |
+
var events = 'load error';
|
388 |
+
|
389 |
+
jQuery( image ).one( events, function me( event ) {
|
390 |
+
// Remove remaining handler (either 'load' or 'error').
|
391 |
+
jQuery( this ).off( events, me );
|
392 |
+
loaded_count ++;
|
393 |
+
|
394 |
+
if ( loaded_count == srcs.length ) {
|
395 |
+
ready_callback.call( $el[0] );
|
396 |
+
return false;
|
397 |
+
}
|
398 |
+
} );
|
399 |
+
} );
|
400 |
+
},
|
401 |
+
|
402 |
+
privacy: {
|
403 |
+
state: 'unknown',
|
404 |
+
state_executed: false,
|
405 |
+
/**
|
406 |
+
* Get consent state.
|
407 |
+
* IIFE so the events fire only once per event.
|
408 |
+
*
|
409 |
+
* @return string
|
410 |
+
* 'not_needed' - consent is not needed.
|
411 |
+
* 'accepted' - consent was given.
|
412 |
+
* 'unknown' - consent was not given yet.
|
413 |
+
*/
|
414 |
+
get_state: (
|
415 |
+
function () {
|
416 |
+
return function () {
|
417 |
+
// if we already have a state, return that.
|
418 |
+
if ( window.advads_options.privacy.state !== 'unknown' ) {
|
419 |
+
// make sure this only gets executed once.
|
420 |
+
if ( ! advads.privacy.state_executed ) {
|
421 |
+
advads.privacy.state_executed = true;
|
422 |
+
advads.privacy.dispatch_event( window.advads_options.privacy.state, false );
|
423 |
+
}
|
424 |
+
return advads.privacy.state;
|
425 |
+
}
|
426 |
+
|
427 |
+
// If using the cookie method, fire an initial event, regardless if cookie set or not.
|
428 |
+
if ( window.advads_options.privacy['consent-method'] === 'custom' ) {
|
429 |
+
var cookie_regex = new RegExp( window.advads_options.privacy['custom-cookie-name'] + '=.*?' + window.advads_options.privacy['custom-cookie-value'] + '[^;]*' );
|
430 |
+
// Force the event, if we haven't yet fired one.
|
431 |
+
if ( ! advads.privacy.state_executed ) {
|
432 |
+
advads.privacy.state_executed = true;
|
433 |
+
advads.privacy.dispatch_event( document.cookie.match( cookie_regex ) !== null ? 'accepted' : 'unknown', true );
|
434 |
+
}
|
435 |
+
}
|
436 |
+
|
437 |
+
// make sure this only gets executed once.
|
438 |
+
advads.privacy.state_executed = true;
|
439 |
+
|
440 |
+
// Run this in an interval (every 0.1s) just in case we are still waiting for consent
|
441 |
+
var cnt = 0,
|
442 |
+
consentSetInterval = setInterval( function () {
|
443 |
+
// Bail if we have not gotten a consent response after 60 seconds.
|
444 |
+
if ( ++ cnt === 600 ) {
|
445 |
+
clearInterval( consentSetInterval );
|
446 |
+
}
|
447 |
+
switch ( window.advads_options.privacy['consent-method'] ) {
|
448 |
+
case 'custom' :
|
449 |
+
// check if custom cookie is set and matches value.
|
450 |
+
if ( document.cookie.match( cookie_regex ) !== null ) {
|
451 |
+
clearInterval( consentSetInterval );
|
452 |
+
if ( advads.privacy.state !== 'accepted' ) {
|
453 |
+
advads.privacy.dispatch_event( 'accepted', true );
|
454 |
+
}
|
455 |
+
}
|
456 |
+
break;
|
457 |
+
|
458 |
+
case 'iab_tcf_20' :
|
459 |
+
// Check if window.__tcfapi has been set.
|
460 |
+
if ( typeof window.__tcfapi === 'undefined' ) {
|
461 |
+
return;
|
462 |
+
}
|
463 |
+
clearInterval( consentSetInterval );
|
464 |
+
|
465 |
+
window.__tcfapi( 'addEventListener', 2, function ( TCData, listenerSuccess ) {
|
466 |
+
if ( ! listenerSuccess ) {
|
467 |
+
return;
|
468 |
+
}
|
469 |
+
if (
|
470 |
+
TCData.eventStatus === 'tcloaded'
|
471 |
+
|| TCData.eventStatus === 'useractioncomplete'
|
472 |
+
// if this is google funding choices, eventStatus is not set. Check if either gdpr doesn't apply or if there is a purpose object.
|
473 |
+
|| ( TCData.eventStatus === null && typeof window.googlefc !== 'undefined' && (
|
474 |
+
typeof TCData.purpose !== 'undefined' || ! TCData.gdprApplies
|
475 |
+
) )
|
476 |
+
) {
|
477 |
+
var userAction = TCData.eventStatus === 'useractioncomplete';
|
478 |
+
if ( ! TCData.gdprApplies ) {
|
479 |
+
if ( advads.privacy.state !== 'not_needed' ) {
|
480 |
+
advads.privacy.dispatch_event( 'not_needed', userAction );
|
481 |
+
}
|
482 |
+
return;
|
483 |
+
}
|
484 |
+
|
485 |
+
if ( TCData.purpose.consents[1] ) {
|
486 |
+
if ( advads.privacy.state !== 'accepted' ) {
|
487 |
+
advads.privacy.dispatch_event( 'accepted', userAction );
|
488 |
+
}
|
489 |
+
return;
|
490 |
+
}
|
491 |
+
|
492 |
+
// fire another event, in case the user revokes the previous consent.
|
493 |
+
if ( advads.privacy.state !== 'rejected' ) {
|
494 |
+
advads.privacy.dispatch_event( 'rejected', userAction );
|
495 |
+
}
|
496 |
+
}
|
497 |
+
}
|
498 |
+
);
|
499 |
+
break;
|
500 |
+
}
|
501 |
+
}, 100 );
|
502 |
+
|
503 |
+
return advads.privacy.state;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
)(),
|
507 |
+
/**
|
508 |
+
* Check if the privacy_method is custom cookie, and non personalized ads are allowed.
|
509 |
+
*
|
510 |
+
* @returns {boolean}
|
511 |
+
*/
|
512 |
+
is_adsense_npa_enabled: function () {
|
513 |
+
if ( ! window.advads_options || ! window.advads_options.privacy ) {
|
514 |
+
return true;
|
515 |
+
}
|
516 |
+
return !! (
|
517 |
+
window.advads_options.privacy['show-non-personalized-adsense'] && window.advads_options.privacy['consent-method'] === 'custom'
|
518 |
+
);
|
519 |
+
},
|
520 |
+
/**
|
521 |
+
* Dispatch a custom event whenever the state changes.
|
522 |
+
*
|
523 |
+
* @param {String} state The current privacy state.
|
524 |
+
* @param {boolean} userAction This is result of action by user.
|
525 |
+
*/
|
526 |
+
dispatch_event: function ( state, userAction ) {
|
527 |
+
var previousState = advads.privacy.state,
|
528 |
+
fire_event = function () {
|
529 |
+
document.dispatchEvent( new CustomEvent( 'advanced_ads_privacy', {
|
530 |
+
detail: {
|
531 |
+
state: state,
|
532 |
+
previousState: previousState,
|
533 |
+
userAction: userAction
|
534 |
+
}
|
535 |
+
} ) );
|
536 |
+
};
|
537 |
+
|
538 |
+
advads.privacy.state = state;
|
539 |
+
|
540 |
+
console.log( {
|
541 |
+
state: state,
|
542 |
+
previousState: previousState,
|
543 |
+
userAction: userAction
|
544 |
+
} );
|
545 |
+
|
546 |
+
// DOM is ready.
|
547 |
+
if ( document.readyState !== 'loading' ) {
|
548 |
+
return fire_event();
|
549 |
+
}
|
550 |
+
|
551 |
+
// If DOM is still loading, wait for it to be interactive/complete.
|
552 |
+
document.addEventListener( 'readystatechange', fire_event, {once: true} );
|
553 |
+
},
|
554 |
+
/**
|
555 |
+
* Check if ad is decoded.
|
556 |
+
*
|
557 |
+
* @param {integer} id
|
558 |
+
*
|
559 |
+
* @returns {boolean}
|
560 |
+
*/
|
561 |
+
is_ad_decoded: function ( id ) {
|
562 |
+
return document.querySelector( 'script[data-tcf="waiting-for-consent"][data-id="' + id + '"]' ) === null;
|
563 |
+
},
|
564 |
+
/**
|
565 |
+
* Decode ad content.
|
566 |
+
*
|
567 |
+
* @param {Element} el
|
568 |
+
* @param {boolean} inject
|
569 |
+
*/
|
570 |
+
decode_ad: function ( el, inject ) {
|
571 |
+
// this can also be a number if used in a foreach.
|
572 |
+
inject = typeof inject === 'boolean' ? inject : true;
|
573 |
+
var string = decodeURIComponent( Array.prototype.map.call( atob( el.textContent ), function ( c ) {
|
574 |
+
return '%' + (
|
575 |
+
'00' + c.charCodeAt( 0 ).toString( 16 )
|
576 |
+
).slice( - 2 )
|
577 |
+
} ).join( '' ) );
|
578 |
+
|
579 |
+
if ( ! inject ) {
|
580 |
+
return string;
|
581 |
+
}
|
582 |
+
|
583 |
+
el.replaceWith( document.createRange().createContextualFragment( string ) );
|
584 |
+
}
|
585 |
+
}
|
586 |
+
};
|
587 |
+
|
588 |
+
(
|
589 |
+
window.advanced_ads_ready || jQuery( document ).ready
|
590 |
+
).call( null, function () {
|
591 |
+
advads.privacy.get_state();
|
592 |
+
} );
|
593 |
+
|
594 |
+
document.addEventListener( 'advanced_ads_privacy', function ( event ) {
|
595 |
+
if (
|
596 |
+
(
|
597 |
+
event.detail.state !== 'accepted' && event.detail.state !== 'not_needed'
|
598 |
+
)
|
599 |
+
|| event.detail.userAction
|
600 |
+
|| document.readyState === 'loading'
|
601 |
+
) {
|
602 |
+
return;
|
603 |
+
}
|
604 |
+
|
605 |
+
// Find all scripts waiting for consent and decode them.
|
606 |
+
document.querySelectorAll( 'script[type="text/plain"][data-tcf="waiting-for-consent"]' ).forEach( advads.privacy.decode_ad );
|
607 |
+
} );
|
608 |
+
|
609 |
+
// highlight elements in frontend, if local storage variable is set
|
610 |
+
jQuery( document ).ready( function () {
|
611 |
+
|
612 |
+
function is_enabled() {
|
613 |
+
if ( ! advads.supports_localstorage() || ! localStorage.getItem( 'advads_frontend_picker' ) ) {
|
614 |
+
return false;
|
615 |
+
}
|
616 |
+
|
617 |
+
// Check if the frontend picker was started on the current blog.
|
618 |
+
if ( window.advads_options.blog_id
|
619 |
+
&& localStorage.getItem( 'advads_frontend_blog_id' )
|
620 |
+
&& window.advads_options.blog_id !== localStorage.getItem( 'advads_frontend_blog_id' ) ) {
|
621 |
+
return false;
|
622 |
+
}
|
623 |
+
|
624 |
+
// Deactivate the frontend picker if it was started more than 45 minutes ago.
|
625 |
+
if ( localStorage.getItem( 'advads_frontend_starttime' )
|
626 |
+
&& parseInt( localStorage.getItem( 'advads_frontend_starttime' ), 10 ) < (
|
627 |
+
new Date().getTime()
|
628 |
+
) - 45 * 60 * 1000 ) {
|
629 |
+
localStorage.removeItem( 'advads_frontend_action' );
|
630 |
+
localStorage.removeItem( 'advads_frontend_element' );
|
631 |
+
localStorage.removeItem( 'advads_frontend_picker' );
|
632 |
+
localStorage.removeItem( 'advads_prev_url' );
|
633 |
+
localStorage.removeItem( 'advads_frontend_pathtype' );
|
634 |
+
localStorage.removeItem( 'advads_frontend_boundary' );
|
635 |
+
localStorage.removeItem( 'advads_frontend_blog_id' );
|
636 |
+
localStorage.removeItem( 'advads_frontend_starttime' );
|
637 |
+
advads.set_cookie( 'advads_frontend_picker', '', - 1 );
|
638 |
+
return false;
|
639 |
+
}
|
640 |
+
|
641 |
+
return true;
|
642 |
+
}
|
643 |
+
|
644 |
+
// only trigger if local storage is available
|
645 |
+
if ( is_enabled() ) {
|
646 |
+
var advads_picker_cur, advads_picker_overlay = jQuery( "<div id='advads-picker-overlay'>" ),
|
647 |
+
advads_picker_no = [document.body, document.documentElement, document];
|
648 |
+
advads_picker_overlay.css( {
|
649 |
+
position: 'absolute', border: 'solid 2px #428bca',
|
650 |
+
backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
|
651 |
+
zIndex: 1000000, pointerEvents: 'none'
|
652 |
+
} ).prependTo( 'body' );
|
653 |
+
|
654 |
+
if ( 'true' === localStorage.getItem( 'advads_frontend_boundary' ) ) {
|
655 |
+
jQuery( 'body' ).css( 'cursor', 'not-allowed' );
|
656 |
+
}
|
657 |
+
|
658 |
+
/**
|
659 |
+
* Check if we can traverse up the dom tree.
|
660 |
+
*
|
661 |
+
* We cannot use event delegation because:
|
662 |
+
* - the content can be loaded via AJAX dynamically
|
663 |
+
* - we cannot wrap the content in a `div` that represents post boundary
|
664 |
+
* because that may prevent css rules from working
|
665 |
+
*
|
666 |
+
* @param HTMLElement The current element.
|
667 |
+
* return bool
|
668 |
+
*/
|
669 |
+
window.advads.is_boundary_reached = function ( advads_picker_cur ) {
|
670 |
+
if ( 'true' !== localStorage.getItem( 'advads_frontend_boundary' ) ) {
|
671 |
+
return false;
|
672 |
+
}
|
673 |
+
$advads_picker_cur = jQuery( advads_picker_cur );
|
674 |
+
// A boundary helper is the `ins` element inside of the post content
|
675 |
+
// that is used to determine the post boundary (where the content starts and ends).
|
676 |
+
var $boundary_helpers = jQuery( '.advads-frontend-picker-boundary-helper' );
|
677 |
+
|
678 |
+
$boundaries = $boundary_helpers.parent();
|
679 |
+
$boundaries.css( 'cursor', 'pointer' );
|
680 |
+
return $advads_picker_cur.is( $boundaries ) || ! $advads_picker_cur.closest( $boundaries ).length;
|
681 |
+
}
|
682 |
+
|
683 |
+
if ( 'xpath' === localStorage.getItem( 'advads_frontend_pathtype' ) ) {
|
684 |
+
var fn = 'getXPath';
|
685 |
+
} else {
|
686 |
+
var fn = 'getPath';
|
687 |
+
}
|
688 |
+
|
689 |
+
jQuery( document ).mousemove( function ( e ) {
|
690 |
+
if ( e.target === advads_picker_cur ) {
|
691 |
+
return;
|
692 |
+
}
|
693 |
+
|
694 |
+
if ( ~ advads_picker_no.indexOf( e.target ) ) {
|
695 |
+
advads_picker_cur = null;
|
696 |
+
advads_picker_overlay.hide();
|
697 |
+
return;
|
698 |
+
}
|
699 |
+
|
700 |
+
var target = jQuery( e.target ),
|
701 |
+
offset = target.offset(),
|
702 |
+
width = target.outerWidth(),
|
703 |
+
height = target.outerHeight();
|
704 |
+
|
705 |
+
advads_picker_cur = e.target;
|
706 |
+
|
707 |
+
var path = jQuery( advads_picker_cur )[fn]();
|
708 |
+
if ( ! path ) {
|
709 |
+
// A click outside of the boundary.
|
710 |
+
// @see `is_boundary_reached`.
|
711 |
+
return;
|
712 |
+
}
|
713 |
+
//log path
|
714 |
+
console.log( path );
|
715 |
+
|
716 |
+
advads_picker_overlay.css( {
|
717 |
+
top: offset.top,
|
718 |
+
left: offset.left,
|
719 |
+
width: width,
|
720 |
+
height: height
|
721 |
+
} ).show();
|
722 |
+
|
723 |
+
} );
|
724 |
+
// save on click
|
725 |
+
jQuery( document ).click( function ( e ) {
|
726 |
+
var path = jQuery( advads_picker_cur )[fn]();
|
727 |
+
|
728 |
+
if ( advads.is_boundary_reached( advads_picker_cur ) ) {
|
729 |
+
return;
|
730 |
+
}
|
731 |
+
|
732 |
+
localStorage.setItem( 'advads_frontend_element', path );
|
733 |
+
window.location = localStorage.getItem( 'advads_prev_url' );
|
734 |
+
} );
|
735 |
+
}
|
736 |
+
;
|
737 |
+
} );
|
738 |
+
/*
|
739 |
+
derrived from jQuery-GetPath v0.01, by Dave Cardwell. (2007-04-27)
|
740 |
+
http://davecardwell.co.uk/javascript/jquery/plugins/jquery-getpath/
|
741 |
+
Usage:
|
742 |
+
var path = $('#foo').getPath();
|
743 |
+
*/
|
744 |
+
|
745 |
+
jQuery.fn.extend( {
|
746 |
+
getPath: function ( path, depth ) {
|
747 |
+
// The first time this function is called, path won't be defined.
|
748 |
+
if ( typeof path === 'undefined' ) {
|
749 |
+
path = '';
|
750 |
+
}
|
751 |
+
if ( typeof depth === 'undefined' ) {
|
752 |
+
depth = 0;
|
753 |
+
}
|
754 |
+
|
755 |
+
// If this element is <html> we've reached the end of the path.
|
756 |
+
// also end after 2 elements
|
757 |
+
if ( this.is( 'html' ) ) {
|
758 |
+
return 'html > ' + path;
|
759 |
+
} else if ( 3 === depth ) {
|
760 |
+
return path;
|
761 |
+
}
|
762 |
+
|
763 |
+
// Add the element name.
|
764 |
+
var cur = this.get( 0 ).nodeName.toLowerCase();
|
765 |
+
|
766 |
+
// Determine the IDs and path.
|
767 |
+
var el_id = this.attr( 'id' ),
|
768 |
+
el_class = this.attr( 'class' );
|
769 |
+
|
770 |
+
depth = depth + 1;
|
771 |
+
|
772 |
+
// Add the #id if there is one. Ignore ID with number.
|
773 |
+
if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
|
774 |
+
cur += '#' + el_id;
|
775 |
+
} else if ( typeof el_class !== 'undefined' ) {
|
776 |
+
// Add classes if there is no id.
|
777 |
+
el_class = el_class.split( /[\s\n]+/ );
|
778 |
+
// Skip classes with numbers.
|
779 |
+
el_class = jQuery.grep( el_class, function ( element, index ) {
|
780 |
+
return ! /\d/.test( element )
|
781 |
+
} );
|
782 |
+
// Add 2 classes.
|
783 |
+
if ( el_class.length ) {
|
784 |
+
cur += '.' + el_class.slice( 0, 2 ).join( '.' );
|
785 |
+
}
|
786 |
+
}
|
787 |
+
|
788 |
+
// add index if this element is not unique among its siblings
|
789 |
+
if ( this.siblings( cur ).length ) {
|
790 |
+
cur += ":eq(" + this.siblings( cur ).addBack().not( '#advads-picker-overlay' ).index( this ) + ")";
|
791 |
+
}
|
792 |
+
|
793 |
+
// Recurse up the DOM.
|
794 |
+
if ( path === '' ) {
|
795 |
+
return this.parent().getPath( cur, depth );
|
796 |
+
} else {
|
797 |
+
return this.parent().getPath( cur + ' > ' + path, depth );
|
798 |
+
}
|
799 |
+
},
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Get XPath.
|
803 |
+
*/
|
804 |
+
getXPath: function ( path, depth ) {
|
805 |
+
// The first time this function is called, path won't be defined.
|
806 |
+
if ( typeof path === 'undefined' ) {
|
807 |
+
path = '';
|
808 |
+
}
|
809 |
+
if ( typeof depth === 'undefined' ) {
|
810 |
+
depth = 0;
|
811 |
+
}
|
812 |
+
|
813 |
+
// If this element is <html> we've reached the end of the path.
|
814 |
+
// also end after 2 elements
|
815 |
+
if ( this.is( 'body' ) || 3 === depth ) {
|
816 |
+
return path;
|
817 |
+
}
|
818 |
+
|
819 |
+
if ( advads.is_boundary_reached( this ) ) {
|
820 |
+
return path;
|
821 |
+
}
|
822 |
+
|
823 |
+
// Add the element name.
|
824 |
+
var tag = this.get( 0 ).nodeName.toLowerCase();
|
825 |
+
var cur = tag;
|
826 |
+
|
827 |
+
// Determine the IDs and path.
|
828 |
+
var el_id = this.attr( 'id' ),
|
829 |
+
el_class = this.attr( 'class' );
|
830 |
+
var classes = [];
|
831 |
+
|
832 |
+
// Add the #id if there is one. Ignore ID with number.
|
833 |
+
if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
|
834 |
+
return cur + '[@id and id="' + el_id + '"]/' + path;
|
835 |
+
} else if ( typeof el_class !== 'undefined' ) {
|
836 |
+
// Add classes if there is no id.
|
837 |
+
el_class = el_class.split( /[\s\n]+/ );
|
838 |
+
// Skip classes with numbers.
|
839 |
+
el_class = jQuery.grep( el_class, function ( element, index ) {
|
840 |
+
return ! /\d/.test( element )
|
841 |
+
} );
|
842 |
+
// Add 2 classes.
|
843 |
+
if ( el_class.length ) {
|
844 |
+
depth = depth + 1;
|
845 |
+
var classes = el_class.slice( 0, 2 );
|
846 |
+
|
847 |
+
var xpath_classes = [];
|
848 |
+
for ( var i = 0; i < classes.length; i ++ ) {
|
849 |
+
xpath_classes.push( '(@class and contains(concat(" ", normalize-space(@class), " "), " ' + classes[i] + ' "))' );
|
850 |
+
}
|
851 |
+
cur += '[' + xpath_classes.join( ' and ' ) + ']';
|
852 |
+
}
|
853 |
+
}
|
854 |
+
|
855 |
+
// Add index if this element is not unique among its siblings.
|
856 |
+
if ( classes.length ) {
|
857 |
+
var $siblings = this.siblings( tag + '.' + classes.join( '.' ) );
|
858 |
+
} else {
|
859 |
+
var $siblings = this.siblings( tag );
|
860 |
+
}
|
861 |
+
|
862 |
+
if ( $siblings.length ) {
|
863 |
+
var index = $siblings.addBack().not( '#advads-picker-overlay' ).index( this );
|
864 |
+
cur += '[' + index + ']';
|
865 |
+
}
|
866 |
+
|
867 |
+
// Recurse up the DOM.
|
868 |
+
if ( path === '' ) {
|
869 |
+
return this.parent().getXPath( cur, depth );
|
870 |
+
} else {
|
871 |
+
return this.parent().getXPath( cur + '/' + path, depth );
|
872 |
+
}
|
873 |
+
}
|
874 |
+
} );
|
public/assets/js/advanced.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
advads={supports_localstorage:function(){"use strict";try{return!(!window||void 0===window.localStorage)&&(window.localStorage.setItem("x","x"),window.localStorage.removeItem("x"),!0)}catch(e){return!1}},max_per_session:function(e,t){var a=1;if(void 0!==t&&0!==parseInt(t)||(t=1),this.cookie_exists(e)){if(this.get_cookie(e)>=t)return!0;a+=parseInt(this.get_cookie(e))}return this.set_cookie(e,a),!1},count_up:function(e,t){var a=1;this.cookie_exists(e)&&(a+=parseInt(this.get_cookie(e))),this.set_cookie(e,a)},set_cookie_exists:function(e){return!!get_cookie(e)||(set_cookie(e,"",0),!1)},get_cookie:function(e){var t,a,o,n=document.cookie.split(";");for(t=0;t<n.length;t++)if(a=n[t].substr(0,n[t].indexOf("=")),o=n[t].substr(n[t].indexOf("=")+1),(a=a.replace(/^\s+|\s+$/g,""))===e)return unescape(o)},set_cookie:function(e,t,a,o,n,i){var r=null==a?null:24*a*60*60;this.set_cookie_sec(e,t,r,o,n,i)},set_cookie_sec:function(e,t,a,o,n,i){var r=new Date;r.setSeconds(r.getSeconds()+parseInt(a)),document.cookie=e+"="+escape(t)+(null==a?"":"; expires="+r.toUTCString())+(null==o?"; path=/":"; path="+o)+(null==n?"":"; domain="+n)+(null==i?"":"; secure")},cookie_exists:function(e){var t=this.get_cookie(e);return null!==t&&""!==t&&void 0!==t},move:function(e,t,a){var o=jQuery(e);if(void 0===a&&(a={}),void 0===a.css&&(a.css={}),void 0===a.method&&(a.method="prependTo"),""===t&&void 0!==a.target)switch(a.target){case"wrapper":var n="left";void 0!==a.offset&&(n=a.offset),t=this.find_wrapper(e,n)}switch((t=void 0===a.moveintohidden?jQuery(t).filter(":visible"):jQuery(t)).length>1&&t.length,a.method){case"insertBefore":o.insertBefore(t);break;case"insertAfter":o.insertAfter(t);break;case"appendTo":o.appendTo(t);break;case"prependTo":o.prependTo(t);break;default:o.prependTo(t)}},set_parent_relative:function(e,t){t=void 0!==t?t:{};var a=jQuery(e).parent();t.use_grandparent&&(a=a.parent()),"static"!==a.css("position")&&""!==a.css("position")||a.css("position","relative")},fix_element:function(e,t){t=void 0!==t?t:{};var a=jQuery(e);t.use_grandparent?this.set_parent_relative(a.parent()):this.set_parent_relative(a),t.is_invisible&&a.show();var o=parseInt(a.offset().top),n=parseInt(a.offset().left);if(t.is_invisible&&a.hide(),"left"===t.offset){var i=jQuery(window).width()-n-a.outerWidth();a.css("position","fixed").css("top",o+"px").css("right",i+"px").css("left","")}else a.css("position","fixed").css("top",o+"px").css("left",n+"px").css("right","")},find_wrapper:function(e,t){var a;return jQuery("body").children().each((function(o,n){if(n.id!==e.substring(1)){var i=jQuery(n);if("right"===t&&i.offset().left+jQuery(i).width()<jQuery(window).width()||"left"===t&&i.offset().left>0)return"static"!==i.css("position")&&""!==i.css("position")||i.css("position","relative"),a=n,!1}})),a},center_fixed_element:function(e){var t=jQuery(e),a=jQuery(window).width()/2-parseInt(t.css("width"))/2;t.css("left",a+"px")},center_vertically:function(e){var t=jQuery(e),a=jQuery(window).height()/2-parseInt(t.css("height"))/2;"fixed"!==t.css("position")&&(a-=topoffset=parseInt(t.offset().top)),t.css("top",a+"px")},close:function(e){jQuery(e).remove()},wait_for_images:function(e,t){var a=0,o=[];e.find('img[src][src!=""]').each((function(){o.push(this.src)})),0===o.length&&t.call(e),jQuery.each(o,(function(n,i){var r=new Image;r.src=i;var s="load error";jQuery(r).one(s,(function n(i){if(jQuery(this).off(s,n),++a==o.length)return t.call(e[0]),!1}))}))},privacy:{state:"unknown",state_executed:!1,get_state:function(){if("unknown"!==window.advads_options.privacy.state)return advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(window.advads_options.privacy.state,!1)),advads.privacy.state;if("custom"===window.advads_options.privacy["consent-method"]){var e=new RegExp(window.advads_options.privacy["custom-cookie-name"]+"=.*?"+window.advads_options.privacy["custom-cookie-value"]+"[^;]*");advads.privacy.state_executed||(advads.privacy.state_executed=!0,advads.privacy.dispatch_event(null!==document.cookie.match(e)?"accepted":"unknown",!0))}advads.privacy.state_executed=!0;var t=0,a=setInterval((function(){switch(600==++t&&clearInterval(a),window.advads_options.privacy["consent-method"]){case"custom":null!==document.cookie.match(e)&&(clearInterval(a),"accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",!0));break;case"iab_tcf_20":if(void 0===window.__tcfapi)return;clearInterval(a),window.__tcfapi("addEventListener",2,(function(e,t){if(t&&("tcloaded"===e.eventStatus||"useractioncomplete"===e.eventStatus||null===e.eventStatus&&void 0!==window.googlefc&&(void 0!==e.purpose||!e.gdprApplies))){var a="useractioncomplete"===e.eventStatus;if(!e.gdprApplies)return void("not_needed"!==advads.privacy.state&&advads.privacy.dispatch_event("not_needed",a));if(e.purpose.consents[1])return void("accepted"!==advads.privacy.state&&advads.privacy.dispatch_event("accepted",a));"rejected"!==advads.privacy.state&&advads.privacy.dispatch_event("rejected",a)}}))}}),100);return advads.privacy.state},is_adsense_npa_enabled:function(){return!window.advads_options||!window.advads_options.privacy||!(!window.advads_options.privacy["show-non-personalized-adsense"]||"custom"!==window.advads_options.privacy["consent-method"])},dispatch_event:function(e,t){var a=advads.privacy.state,o=function(){document.dispatchEvent(new CustomEvent("advanced_ads_privacy",{detail:{state:e,previousState:a,userAction:t}}))};if(advads.privacy.state=e,"loading"!==document.readyState)return o();document.addEventListener("readystatechange",o,{once:!0})},is_ad_decoded:function(e){return null===document.querySelector('script[data-tcf="waiting-for-consent"][data-id="'+e+'"]')},decode_ad:function(e,t){t="boolean"!=typeof t||t;var a=decodeURIComponent(Array.prototype.map.call(atob(e.textContent),(function(e){return"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)})).join(""));if(!t)return a;e.replaceWith(document.createRange().createContextualFragment(a))}}},(window.advanced_ads_ready||jQuery(document).ready).call(null,(function(){advads.privacy.get_state()})),document.addEventListener("advanced_ads_privacy",(function(e){"accepted"!==e.detail.state&&"not_needed"!==e.detail.state||e.detail.userAction||"loading"===document.readyState||document.querySelectorAll('script[type="text/plain"][data-tcf="waiting-for-consent"]').forEach(advads.privacy.decode_ad)})),jQuery(document).ready((function(){if(!(!advads.supports_localstorage()||!localStorage.getItem("advads_frontend_picker")||window.advads_options.blog_id&&localStorage.getItem("advads_frontend_blog_id")&&window.advads_options.blog_id!==localStorage.getItem("advads_frontend_blog_id")||localStorage.getItem("advads_frontend_starttime")&&parseInt(localStorage.getItem("advads_frontend_starttime"),10)<(new Date).getTime()-27e5&&(localStorage.removeItem("advads_frontend_action"),localStorage.removeItem("advads_frontend_element"),localStorage.removeItem("advads_frontend_picker"),localStorage.removeItem("advads_prev_url"),localStorage.removeItem("advads_frontend_pathtype"),localStorage.removeItem("advads_frontend_boundary"),localStorage.removeItem("advads_frontend_blog_id"),localStorage.removeItem("advads_frontend_starttime"),advads.set_cookie("advads_frontend_picker","",-1),1))){var e,t=jQuery("<div id='advads-picker-overlay'>"),a=[document.body,document.documentElement,document];if(t.css({position:"absolute",border:"solid 2px #428bca",backgroundColor:"rgba(66,139,202,0.5)",boxSizing:"border-box",zIndex:1e6,pointerEvents:"none"}).prependTo("body"),"true"===localStorage.getItem("advads_frontend_boundary")&&jQuery("body").css("cursor","not-allowed"),window.advads.is_boundary_reached=function(e){if("true"!==localStorage.getItem("advads_frontend_boundary"))return!1;$advads_picker_cur=jQuery(e);var t=jQuery(".advads-frontend-picker-boundary-helper");return $boundaries=t.parent(),$boundaries.css("cursor","pointer"),$advads_picker_cur.is($boundaries)||!$advads_picker_cur.closest($boundaries).length},"xpath"===localStorage.getItem("advads_frontend_pathtype"))var o="getXPath";else o="getPath";jQuery(document).mousemove((function(n){if(n.target!==e){if(~a.indexOf(n.target))return e=null,void t.hide();var i=jQuery(n.target),r=i.offset(),s=i.outerWidth(),d=i.outerHeight();e=n.target;var c=jQuery(e)[o]();c&&t.css({top:r.top,left:r.left,width:s,height:d}).show()}})),jQuery(document).click((function(t){var a=jQuery(e)[o]();advads.is_boundary_reached(e)||(localStorage.setItem("advads_frontend_element",a),window.location=localStorage.getItem("advads_prev_url"))}))}})),jQuery.fn.extend({getPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("html"))return"html > "+e;if(3===t)return e;var a=this.get(0).nodeName.toLowerCase(),o=this.attr("id"),n=this.attr("class");return t+=1,void 0===o||/\d/.test(o)?void 0!==n&&(n=n.split(/[\s\n]+/),(n=jQuery.grep(n,(function(e,t){return!/\d/.test(e)}))).length&&(a+="."+n.slice(0,2).join("."))):a+="#"+o,this.siblings(a).length&&(a+=":eq("+this.siblings(a).addBack().not("#advads-picker-overlay").index(this)+")"),""===e?this.parent().getPath(a,t):this.parent().getPath(a+" > "+e,t)},getXPath:function(e,t){if(void 0===e&&(e=""),void 0===t&&(t=0),this.is("body")||3===t)return e;if(advads.is_boundary_reached(this))return e;var a=this.get(0).nodeName.toLowerCase(),o=a,n=this.attr("id"),i=this.attr("class"),r=[];if(void 0!==n&&!/\d/.test(n))return o+'[@id and id="'+n+'"]/'+e;if(void 0!==i&&(i=i.split(/[\s\n]+/),(i=jQuery.grep(i,(function(e,t){return!/\d/.test(e)}))).length)){t+=1;r=i.slice(0,2);for(var s=[],d=0;d<r.length;d++)s.push('(@class and contains(concat(" ", normalize-space(@class), " "), " '+r[d]+' "))');o+="["+s.join(" and ")+"]"}if(r.length)var c=this.siblings(a+"."+r.join("."));else c=this.siblings(a);c.length&&(o+="["+c.addBack().not("#advads-picker-overlay").index(this)+"]");return""===e?this.parent().getXPath(o,t):this.parent().getXPath(o+"/"+e,t)}});
|
public/assets/js/advanced.orig.js
DELETED
@@ -1,815 +0,0 @@
|
|
1 |
-
/*
|
2 |
-
* advanced ads functions to be used directly within ad codes
|
3 |
-
*/
|
4 |
-
|
5 |
-
advads = {
|
6 |
-
/**
|
7 |
-
* check if localstorage is supported/enabled by client
|
8 |
-
*/
|
9 |
-
supports_localstorage: function() {
|
10 |
-
"use strict";
|
11 |
-
try {
|
12 |
-
if (!window || window.localStorage === undefined) {
|
13 |
-
return false;
|
14 |
-
}
|
15 |
-
// storage might be full or disabled
|
16 |
-
window.localStorage.setItem("x", "x");
|
17 |
-
window.localStorage.removeItem("x");
|
18 |
-
return true;
|
19 |
-
} catch(e) {
|
20 |
-
return false;
|
21 |
-
}
|
22 |
-
},
|
23 |
-
/**
|
24 |
-
* check if the ad is displayed more than {max} times per session
|
25 |
-
* every check increases the counter
|
26 |
-
*
|
27 |
-
* @param {string} name (no id needed, just any id-formated string)
|
28 |
-
* @param {type} max number of maximum times the ad can be displayed within the period
|
29 |
-
* @returns {bool} true if limit is reached
|
30 |
-
*/
|
31 |
-
max_per_session: function(name, max){
|
32 |
-
var num = 1;
|
33 |
-
if(max === undefined || parseInt( max ) === 0) { max = 1; }
|
34 |
-
|
35 |
-
// check if cookie exists and get the value
|
36 |
-
if(this.cookie_exists( name )){
|
37 |
-
if(this.get_cookie( name ) >= max) { return true; }
|
38 |
-
num = num + parseInt( this.get_cookie( name ) );
|
39 |
-
}
|
40 |
-
this.set_cookie( name, num );
|
41 |
-
return false;
|
42 |
-
},
|
43 |
-
/**
|
44 |
-
* increase a cookie with an integer value by 1
|
45 |
-
*
|
46 |
-
* @param {str} name of the cookie
|
47 |
-
* @param {int} exdays days until cookie expires
|
48 |
-
*/
|
49 |
-
count_up: function( name, exdays ){
|
50 |
-
var num = 1;
|
51 |
-
|
52 |
-
// check if cookie exists and get the value
|
53 |
-
if(this.cookie_exists( name )){
|
54 |
-
num = num + parseInt( this.get_cookie( name ) );
|
55 |
-
}
|
56 |
-
this.set_cookie( name, num );
|
57 |
-
},
|
58 |
-
/**
|
59 |
-
* return true, if cookie exists
|
60 |
-
* return false, if not
|
61 |
-
* if not exists, create it
|
62 |
-
* use case: to check if something already happened in this page impression
|
63 |
-
*
|
64 |
-
* @param {type} name
|
65 |
-
* @returns {unresolved}
|
66 |
-
*/
|
67 |
-
set_cookie_exists: function( name ){
|
68 |
-
if( get_cookie(name) ){
|
69 |
-
return true;
|
70 |
-
}
|
71 |
-
set_cookie( name, '', 0 );
|
72 |
-
return false;
|
73 |
-
},
|
74 |
-
/**
|
75 |
-
* get a cookie value
|
76 |
-
*
|
77 |
-
* @param {str} name of the cookie
|
78 |
-
*/
|
79 |
-
get_cookie: function (name) {
|
80 |
-
var i, x, y, ADVcookies = document.cookie.split( ";" );
|
81 |
-
for (i = 0; i < ADVcookies.length; i++)
|
82 |
-
{
|
83 |
-
x = ADVcookies[i].substr( 0, ADVcookies[i].indexOf( "=" ) );
|
84 |
-
y = ADVcookies[i].substr( ADVcookies[i].indexOf( "=" ) + 1 );
|
85 |
-
x = x.replace( /^\s+|\s+$/g, "" );
|
86 |
-
if (x === name)
|
87 |
-
{
|
88 |
-
return unescape( y );
|
89 |
-
}
|
90 |
-
}
|
91 |
-
},
|
92 |
-
/**
|
93 |
-
* set a cookie value
|
94 |
-
*
|
95 |
-
* @param {str} name of the cookie
|
96 |
-
* @param {str} value of the cookie
|
97 |
-
* @param {int} exdays days until cookie expires
|
98 |
-
* set 0 to expire cookie immidiatelly
|
99 |
-
* set null to expire cookie in the current session
|
100 |
-
*/
|
101 |
-
set_cookie: function (name, value, exdays, path, domain, secure) {
|
102 |
-
// days in seconds
|
103 |
-
var expiry = ( exdays == null ) ? null : exdays * 24 * 60 * 60;
|
104 |
-
this.set_cookie_sec( name, value, expiry, path, domain, secure );
|
105 |
-
},
|
106 |
-
/**
|
107 |
-
* set a cookie with expiry given in seconds
|
108 |
-
*
|
109 |
-
* @param {str} name of the cookie
|
110 |
-
* @param {str} value of the cookie
|
111 |
-
* @param {int} expiry seconds until cookie expires
|
112 |
-
* set 0 to expire cookie immidiatelly
|
113 |
-
* set null to expire cookie in the current session
|
114 |
-
*/
|
115 |
-
set_cookie_sec: function (name, value, expiry, path, domain, secure) {
|
116 |
-
var exdate = new Date();
|
117 |
-
exdate.setSeconds( exdate.getSeconds() + parseInt( expiry ) );
|
118 |
-
document.cookie = name + "=" + escape( value ) +
|
119 |
-
((expiry == null) ? "" : "; expires=" + exdate.toUTCString()) +
|
120 |
-
((path == null) ? "; path=/" : "; path=" + path) +
|
121 |
-
((domain == null) ? "" : "; domain=" + domain) +
|
122 |
-
((secure == null) ? "" : "; secure");
|
123 |
-
},
|
124 |
-
/**
|
125 |
-
* check if a cookie is set and contains a value
|
126 |
-
*
|
127 |
-
* @param {str} name of the cookie
|
128 |
-
* @returns {bool} true, if cookie is set
|
129 |
-
*/
|
130 |
-
cookie_exists: function (name)
|
131 |
-
{
|
132 |
-
var c_value = this.get_cookie( name );
|
133 |
-
if (c_value !== null && c_value !== "" && c_value !== undefined)
|
134 |
-
{
|
135 |
-
return true;
|
136 |
-
}
|
137 |
-
return false;
|
138 |
-
},
|
139 |
-
/**
|
140 |
-
* move one element into another
|
141 |
-
*
|
142 |
-
* @param {str} element selector of the element that should be moved
|
143 |
-
* @param {str} target selector of the element where to move
|
144 |
-
* @param {arr} options
|
145 |
-
*/
|
146 |
-
move: function( element, target, options )
|
147 |
-
{
|
148 |
-
|
149 |
-
var el = jQuery(element);
|
150 |
-
var target_string = target;
|
151 |
-
|
152 |
-
if( typeof options === 'undefined' ){
|
153 |
-
options = {};
|
154 |
-
}
|
155 |
-
if( typeof options.css === 'undefined' ){
|
156 |
-
options.css = {};
|
157 |
-
}
|
158 |
-
if( typeof options.method === 'undefined' ){
|
159 |
-
options.method = 'prependTo';
|
160 |
-
}
|
161 |
-
|
162 |
-
// search for abstract target element
|
163 |
-
if( target === '' && typeof options.target !== 'undefined' ){
|
164 |
-
switch( options.target ){
|
165 |
-
case 'wrapper' : // wrapper
|
166 |
-
var offset = 'left';
|
167 |
-
if( typeof options.offset !== 'undefined' ){
|
168 |
-
offset = options.offset;
|
169 |
-
}
|
170 |
-
target = this.find_wrapper( element, offset );
|
171 |
-
break;
|
172 |
-
}
|
173 |
-
}
|
174 |
-
|
175 |
-
// use only visible elements
|
176 |
-
if( typeof options.moveintohidden === 'undefined' ){
|
177 |
-
target = jQuery( target ).filter(':visible');
|
178 |
-
} else {
|
179 |
-
target = jQuery( target );
|
180 |
-
}
|
181 |
-
|
182 |
-
// print warning in console if the element appears multiple times
|
183 |
-
if( target.length > 1 ){
|
184 |
-
console.log( "Advanced Ads: element '" + target_string + "' found " + target.length + " times." );
|
185 |
-
}
|
186 |
-
|
187 |
-
// switch insert method
|
188 |
-
switch( options.method ){
|
189 |
-
case 'insertBefore' :
|
190 |
-
el.insertBefore(target);
|
191 |
-
break;
|
192 |
-
case 'insertAfter' :
|
193 |
-
el.insertAfter(target);
|
194 |
-
break;
|
195 |
-
case 'appendTo' :
|
196 |
-
el.appendTo(target);
|
197 |
-
break;
|
198 |
-
case 'prependTo' :
|
199 |
-
el.prependTo(target);
|
200 |
-
break;
|
201 |
-
default :
|
202 |
-
el.prependTo(target);
|
203 |
-
}
|
204 |
-
},
|
205 |
-
|
206 |
-
/**
|
207 |
-
* Set 'relative' position for a parent element.
|
208 |
-
*
|
209 |
-
* @param {str} element selector
|
210 |
-
*/
|
211 |
-
set_parent_relative: function( element, options ) {
|
212 |
-
var options = typeof options !== 'undefined' ? options: {};
|
213 |
-
var el = jQuery(element);
|
214 |
-
// give "position" style to parent element, if missing
|
215 |
-
var parent = el.parent();
|
216 |
-
|
217 |
-
if ( options.use_grandparent ) {
|
218 |
-
parent = parent.parent();
|
219 |
-
}
|
220 |
-
|
221 |
-
if(parent.css('position') === 'static' || parent.css('position') === ''){
|
222 |
-
parent.css('position', 'relative');
|
223 |
-
}
|
224 |
-
},
|
225 |
-
|
226 |
-
/**
|
227 |
-
* make an absolute position element fixed at the current position
|
228 |
-
* hint: use only after DOM is fully loaded in order to fix a wrong position
|
229 |
-
*
|
230 |
-
* @param {str} element selector
|
231 |
-
* @param {obj} options
|
232 |
-
*/
|
233 |
-
fix_element: function( element, options ){
|
234 |
-
var options = typeof options !== 'undefined' ? options: {};
|
235 |
-
|
236 |
-
var el = jQuery(element);
|
237 |
-
|
238 |
-
if ( options.use_grandparent ) {
|
239 |
-
this.set_parent_relative( el.parent() );
|
240 |
-
} else {
|
241 |
-
this.set_parent_relative( el );
|
242 |
-
}
|
243 |
-
|
244 |
-
// fix element at current position
|
245 |
-
// get position for hidden elements by showing them for a very short time
|
246 |
-
if ( options.is_invisible ) {
|
247 |
-
el.show();
|
248 |
-
}
|
249 |
-
var topoffset = parseInt(el.offset().top);
|
250 |
-
var leftoffset = parseInt(el.offset().left);
|
251 |
-
if ( options.is_invisible ) {
|
252 |
-
el.hide();
|
253 |
-
}
|
254 |
-
if ( 'left' === options.offset ) {
|
255 |
-
// Allow to scale the nested image down when it has `max-width: 100%` and touches the left edge of the viewport.
|
256 |
-
var rightoffset = jQuery( window ).width() - leftoffset - el.outerWidth();
|
257 |
-
el.css( 'position', 'fixed' ).css( 'top', topoffset + 'px' ).css( 'right', rightoffset + 'px' ).css( 'left', '' );
|
258 |
-
} else {
|
259 |
-
// reset "right" to prevent conflicts
|
260 |
-
el.css('position', 'fixed').css('top', topoffset + 'px').css('left', leftoffset + 'px').css('right', '');
|
261 |
-
}
|
262 |
-
|
263 |
-
},
|
264 |
-
|
265 |
-
/**
|
266 |
-
* find the main wrapper
|
267 |
-
* either id or first of its class
|
268 |
-
*
|
269 |
-
* @param {str} element selector
|
270 |
-
* @param {str} offset which position of the offset to check (left or right)
|
271 |
-
* @return {str} selector
|
272 |
-
*/
|
273 |
-
find_wrapper: function( element, offset ){
|
274 |
-
// first margin: auto element after body
|
275 |
-
var returnValue;
|
276 |
-
jQuery('body').children().each(function(key, value){
|
277 |
-
// exclude current element
|
278 |
-
// TODO exclude <script>
|
279 |
-
if( value.id !== element.substring(1) ){
|
280 |
-
// check offset value
|
281 |
-
var checkedelement = jQuery( value );
|
282 |
-
// check if there is space left or right of the element
|
283 |
-
if( ( offset === 'right' && ( checkedelement.offset().left + jQuery(checkedelement).width() < jQuery(window).width() ) ) ||
|
284 |
-
( offset === 'left' && checkedelement.offset().left > 0 ) ){
|
285 |
-
// fix element
|
286 |
-
if( checkedelement.css('position') === 'static' || checkedelement.css('position') === ''){
|
287 |
-
checkedelement.css('position', 'relative');
|
288 |
-
}
|
289 |
-
// set return value
|
290 |
-
returnValue = value;
|
291 |
-
return false;
|
292 |
-
}
|
293 |
-
}
|
294 |
-
});
|
295 |
-
return returnValue;
|
296 |
-
},
|
297 |
-
/**
|
298 |
-
* center fixed element on the screen
|
299 |
-
*
|
300 |
-
* @param {str} element selector
|
301 |
-
*/
|
302 |
-
center_fixed_element: function( element ){
|
303 |
-
var el = jQuery(element);
|
304 |
-
// half window width minus half element width
|
305 |
-
var left = ( jQuery(window).width() / 2 ) - ( parseInt( el.css('width')) / 2 );
|
306 |
-
el.css('left', left + 'px');
|
307 |
-
},
|
308 |
-
/**
|
309 |
-
* center element vertically on the screen
|
310 |
-
*
|
311 |
-
* @param {str} element selector
|
312 |
-
*/
|
313 |
-
center_vertically: function( element ){
|
314 |
-
var el = jQuery(element);
|
315 |
-
// half window height minus half element height
|
316 |
-
var left = ( jQuery(window).height() / 2 ) - ( parseInt( el.css('height')) / 2 );
|
317 |
-
|
318 |
-
// Center correctly when the ad is attached to the element that begins lower.
|
319 |
-
if ( el.css( 'position' ) !== 'fixed' ) {
|
320 |
-
left -= topoffset = parseInt( el.offset().top );
|
321 |
-
}
|
322 |
-
el.css('top', left + 'px');
|
323 |
-
},
|
324 |
-
/**
|
325 |
-
* close an ad and add a cookie
|
326 |
-
*
|
327 |
-
* @param {str} element selector
|
328 |
-
*/
|
329 |
-
close: function( element ){
|
330 |
-
var wrapper = jQuery(element);
|
331 |
-
// remove the ad
|
332 |
-
wrapper.remove();
|
333 |
-
},
|
334 |
-
/**
|
335 |
-
* Wait until images are ready.
|
336 |
-
*
|
337 |
-
* @param {obj} $el jQuery object.
|
338 |
-
* @param {function} ready_callback Ready callback.
|
339 |
-
* derrived from https://github.com/alexanderdickson/waitForImages/blob/master/dist/jquery.waitforimages.js
|
340 |
-
*/
|
341 |
-
wait_for_images: function( $el, ready_callback ) {
|
342 |
-
var loaded_count = 0;
|
343 |
-
var srcs = [];
|
344 |
-
|
345 |
-
$el.find( 'img[src][src!=""]' ).each( function () {
|
346 |
-
srcs.push( this.src );
|
347 |
-
});
|
348 |
-
|
349 |
-
if ( srcs.length === 0 ) {
|
350 |
-
ready_callback.call( $el );
|
351 |
-
}
|
352 |
-
|
353 |
-
jQuery.each( srcs, function( i, src ) {
|
354 |
-
var image = new Image();
|
355 |
-
image.src = src;
|
356 |
-
var events = 'load error';
|
357 |
-
|
358 |
-
jQuery( image ).one( events, function me( event ) {
|
359 |
-
// Remove remaining handler (either 'load' or 'error').
|
360 |
-
jQuery( this ).off( events, me );
|
361 |
-
loaded_count++;
|
362 |
-
|
363 |
-
if ( loaded_count == srcs.length ) {
|
364 |
-
ready_callback.call( $el[0] );
|
365 |
-
return false;
|
366 |
-
}
|
367 |
-
} );
|
368 |
-
} );
|
369 |
-
},
|
370 |
-
|
371 |
-
privacy: {
|
372 |
-
state: 'unknown',
|
373 |
-
state_executed: false,
|
374 |
-
/**
|
375 |
-
* Get consent state.
|
376 |
-
* IIFE so the events fire only once per event.
|
377 |
-
*
|
378 |
-
* @return string
|
379 |
-
* 'not_needed' - consent is not needed.
|
380 |
-
* 'accepted' - consent was given.
|
381 |
-
* 'unknown' - consent was not given yet.
|
382 |
-
*/
|
383 |
-
get_state: (function () {
|
384 |
-
return function () {
|
385 |
-
// if we already have a state, return that.
|
386 |
-
if (window.advads_options.privacy.state !== 'unknown') {
|
387 |
-
// make sure this only gets executed once.
|
388 |
-
if (!advads.privacy.state_executed) {
|
389 |
-
advads.privacy.state_executed = true;
|
390 |
-
advads.privacy.dispatch_event(window.advads_options.privacy.state, false);
|
391 |
-
}
|
392 |
-
return advads.privacy.state;
|
393 |
-
}
|
394 |
-
|
395 |
-
// If using the cookie method, fire an initial event, regardless if cookie set or not.
|
396 |
-
if (window.advads_options.privacy['consent-method'] === 'custom') {
|
397 |
-
var cookie_regex = new RegExp(window.advads_options.privacy['custom-cookie-name'] + '=.*?' + window.advads_options.privacy['custom-cookie-value'] + '[^;]*');
|
398 |
-
// Force the event, if we haven't yet fired one.
|
399 |
-
if (!advads.privacy.state_executed) {
|
400 |
-
advads.privacy.state_executed = true;
|
401 |
-
advads.privacy.dispatch_event(document.cookie.match(cookie_regex) !== null ? 'accepted' : 'unknown', true);
|
402 |
-
}
|
403 |
-
}
|
404 |
-
|
405 |
-
// make sure this only gets executed once.
|
406 |
-
advads.privacy.state_executed = true;
|
407 |
-
|
408 |
-
// Run this in an interval (every 0.1s) just in case we are still waiting for consent
|
409 |
-
var cnt = 0,
|
410 |
-
consentSetInterval = setInterval(function () {
|
411 |
-
// Bail if we have not gotten a consent response after 60 seconds.
|
412 |
-
if (++cnt === 600) {
|
413 |
-
clearInterval(consentSetInterval);
|
414 |
-
}
|
415 |
-
switch (window.advads_options.privacy['consent-method']) {
|
416 |
-
case 'custom' :
|
417 |
-
// check if custom cookie is set and matches value.
|
418 |
-
if (document.cookie.match(cookie_regex) !== null) {
|
419 |
-
clearInterval(consentSetInterval);
|
420 |
-
if (advads.privacy.state !== 'accepted') {
|
421 |
-
advads.privacy.dispatch_event('accepted', true);
|
422 |
-
}
|
423 |
-
}
|
424 |
-
break;
|
425 |
-
|
426 |
-
case 'iab_tcf_20' :
|
427 |
-
// Check if window.__tcfapi has been set.
|
428 |
-
if (typeof window.__tcfapi === 'undefined') {
|
429 |
-
return;
|
430 |
-
}
|
431 |
-
clearInterval(consentSetInterval);
|
432 |
-
|
433 |
-
window.__tcfapi('addEventListener', 2, function (TCData, listenerSuccess) {
|
434 |
-
if (!listenerSuccess) {
|
435 |
-
return;
|
436 |
-
}
|
437 |
-
if (TCData.eventStatus === 'tcloaded' || TCData.eventStatus === 'useractioncomplete') {
|
438 |
-
var userAction = TCData.eventStatus === 'useractioncomplete';
|
439 |
-
if (!TCData.gdprApplies) {
|
440 |
-
if (advads.privacy.state !== 'not_needed') {
|
441 |
-
advads.privacy.dispatch_event('not_needed', userAction);
|
442 |
-
}
|
443 |
-
return;
|
444 |
-
}
|
445 |
-
|
446 |
-
if (TCData.purpose.consents[1]) {
|
447 |
-
if (advads.privacy.state !== 'accepted') {
|
448 |
-
advads.privacy.dispatch_event('accepted', userAction);
|
449 |
-
}
|
450 |
-
return;
|
451 |
-
}
|
452 |
-
|
453 |
-
// fire another event, in case the user revokes the previous consent.
|
454 |
-
if (advads.privacy.state !== 'rejected') {
|
455 |
-
advads.privacy.dispatch_event('rejected', userAction);
|
456 |
-
}
|
457 |
-
}
|
458 |
-
}
|
459 |
-
);
|
460 |
-
break;
|
461 |
-
}
|
462 |
-
}, 100);
|
463 |
-
|
464 |
-
return advads.privacy.state;
|
465 |
-
}
|
466 |
-
})(),
|
467 |
-
/**
|
468 |
-
* Check if the privacy_method is custom cookie, and non personalized ads are allowed.
|
469 |
-
*
|
470 |
-
* @returns {boolean}
|
471 |
-
*/
|
472 |
-
is_adsense_npa_enabled: function () {
|
473 |
-
if (!window.advads_options || !window.advads_options.privacy) {
|
474 |
-
return true;
|
475 |
-
}
|
476 |
-
return !!(window.advads_options.privacy['show-non-personalized-adsense'] && window.advads_options.privacy['consent-method'] === 'custom');
|
477 |
-
},
|
478 |
-
/**
|
479 |
-
* Dispatch a custom event whenever the state changes.
|
480 |
-
*
|
481 |
-
* @param {String} state The current privacy state.
|
482 |
-
* @param {boolean} userAction This is result of action by user.
|
483 |
-
*/
|
484 |
-
dispatch_event: function (state, userAction) {
|
485 |
-
var previousState = advads.privacy.state,
|
486 |
-
fire_event = function () {
|
487 |
-
document.dispatchEvent(new CustomEvent('advanced_ads_privacy', {
|
488 |
-
detail: {
|
489 |
-
state: state,
|
490 |
-
previousState: previousState,
|
491 |
-
userAction: userAction
|
492 |
-
}
|
493 |
-
}));
|
494 |
-
};
|
495 |
-
|
496 |
-
advads.privacy.state = state;
|
497 |
-
|
498 |
-
console.log({
|
499 |
-
state: state,
|
500 |
-
previousState: previousState,
|
501 |
-
userAction: userAction
|
502 |
-
});
|
503 |
-
|
504 |
-
// DOM is ready.
|
505 |
-
if (document.readyState !== 'loading') {
|
506 |
-
return fire_event();
|
507 |
-
}
|
508 |
-
|
509 |
-
// If DOM is still loading, wait for it to be interactive/complete.
|
510 |
-
document.addEventListener('readystatechange', fire_event, {once: true});
|
511 |
-
},
|
512 |
-
/**
|
513 |
-
* Check if ad is decoded.
|
514 |
-
*
|
515 |
-
* @param {integer} id
|
516 |
-
*
|
517 |
-
* @returns {boolean}
|
518 |
-
*/
|
519 |
-
is_ad_decoded: function(id) {
|
520 |
-
return document.querySelector('script[data-tcf="waiting-for-consent"][data-id="' + id + '"]') === null;
|
521 |
-
},
|
522 |
-
/**
|
523 |
-
* Decode ad content.
|
524 |
-
*
|
525 |
-
* @param {Element} el
|
526 |
-
* @param {boolean} inject
|
527 |
-
*/
|
528 |
-
decode_ad: function (el, inject) {
|
529 |
-
// this can also be a number if used in a foreach.
|
530 |
-
inject = typeof inject === 'boolean' ? inject : true;
|
531 |
-
var string = decodeURIComponent(Array.prototype.map.call(atob(el.textContent), function (c) {
|
532 |
-
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
|
533 |
-
}).join(''));
|
534 |
-
|
535 |
-
if (!inject) {
|
536 |
-
return string;
|
537 |
-
}
|
538 |
-
|
539 |
-
el.replaceWith(document.createRange().createContextualFragment(string));
|
540 |
-
}
|
541 |
-
}
|
542 |
-
};
|
543 |
-
|
544 |
-
(window.advanced_ads_ready || jQuery(document).ready).call(null, function () {
|
545 |
-
advads.privacy.get_state();
|
546 |
-
});
|
547 |
-
|
548 |
-
document.addEventListener('advanced_ads_privacy', function (event) {
|
549 |
-
if (
|
550 |
-
(event.detail.state !== 'accepted' && event.detail.state !== 'not_needed')
|
551 |
-
|| event.detail.userAction
|
552 |
-
|| document.readyState === 'loading'
|
553 |
-
) {
|
554 |
-
return;
|
555 |
-
}
|
556 |
-
|
557 |
-
// Find all scripts waiting for consent and decode them.
|
558 |
-
document.querySelectorAll('script[type="text/plain"][data-tcf="waiting-for-consent"]').forEach(advads.privacy.decode_ad);
|
559 |
-
});
|
560 |
-
|
561 |
-
// highlight elements in frontend, if local storage variable is set
|
562 |
-
jQuery(document).ready(function(){
|
563 |
-
|
564 |
-
function is_enabled() {
|
565 |
-
if ( ! advads.supports_localstorage() || ! localStorage.getItem('advads_frontend_picker') ) {
|
566 |
-
return false;
|
567 |
-
}
|
568 |
-
|
569 |
-
// Check if the frontend picker was started on the current blog.
|
570 |
-
if ( window.advads_options.blog_id
|
571 |
-
&& localStorage.getItem( 'advads_frontend_blog_id' )
|
572 |
-
&& window.advads_options.blog_id !== localStorage.getItem( 'advads_frontend_blog_id' ) ) {
|
573 |
-
return false;
|
574 |
-
}
|
575 |
-
|
576 |
-
|
577 |
-
// Deactivate the frontend picker if it was started more than 45 minutes ago.
|
578 |
-
if ( localStorage.getItem( 'advads_frontend_starttime' )
|
579 |
-
&& parseInt( localStorage.getItem( 'advads_frontend_starttime' ), 10 ) < ( new Date().getTime() ) - 45 * 60 * 1000 ) {
|
580 |
-
localStorage.removeItem( 'advads_frontend_action' );
|
581 |
-
localStorage.removeItem( 'advads_frontend_element' );
|
582 |
-
localStorage.removeItem( 'advads_frontend_picker' );
|
583 |
-
localStorage.removeItem( 'advads_prev_url' );
|
584 |
-
localStorage.removeItem( 'advads_frontend_pathtype' );
|
585 |
-
localStorage.removeItem( 'advads_frontend_boundary' );
|
586 |
-
localStorage.removeItem( 'advads_frontend_blog_id' );
|
587 |
-
localStorage.removeItem( 'advads_frontend_starttime' );
|
588 |
-
advads.set_cookie( 'advads_frontend_picker', '', -1 );
|
589 |
-
return false;
|
590 |
-
}
|
591 |
-
|
592 |
-
return true;
|
593 |
-
}
|
594 |
-
|
595 |
-
// only trigger if local storage is available
|
596 |
-
if ( is_enabled() ) {
|
597 |
-
var advads_picker_cur, advads_picker_overlay = jQuery("<div id='advads-picker-overlay'>"),
|
598 |
-
advads_picker_no = [document.body, document.documentElement, document];
|
599 |
-
advads_picker_overlay.css({position: 'absolute', border: 'solid 2px #428bca',
|
600 |
-
backgroundColor: 'rgba(66,139,202,0.5)', boxSizing: 'border-box',
|
601 |
-
zIndex: 1000000, pointerEvents: 'none'}).prependTo('body');
|
602 |
-
|
603 |
-
if ( 'true' === localStorage.getItem( 'advads_frontend_boundary' ) ) {
|
604 |
-
jQuery( 'body' ).css( 'cursor', 'not-allowed' );
|
605 |
-
}
|
606 |
-
|
607 |
-
/**
|
608 |
-
* Check if we can traverse up the dom tree.
|
609 |
-
*
|
610 |
-
* We cannot use event delegation because:
|
611 |
-
* - the content can be loaded via AJAX dynamically
|
612 |
-
* - we cannot wrap the content in a `div` that represents post boundary
|
613 |
-
* because that may prevent css rules from working
|
614 |
-
*
|
615 |
-
* @param HTMLElement The current element.
|
616 |
-
* return bool
|
617 |
-
*/
|
618 |
-
window.advads.is_boundary_reached = function( advads_picker_cur ) {
|
619 |
-
if ( 'true' !== localStorage.getItem( 'advads_frontend_boundary' ) ) {
|
620 |
-
return false;
|
621 |
-
}
|
622 |
-
$advads_picker_cur = jQuery( advads_picker_cur );
|
623 |
-
// A boundary helper is the `ins` element inside of the post content
|
624 |
-
// that is used to determine the post boundary (where the content starts and ends).
|
625 |
-
var $boundary_helpers = jQuery( '.advads-frontend-picker-boundary-helper' );
|
626 |
-
|
627 |
-
$boundaries = $boundary_helpers.parent();
|
628 |
-
$boundaries.css( 'cursor', 'pointer' );
|
629 |
-
return $advads_picker_cur.is( $boundaries ) || ! $advads_picker_cur.closest( $boundaries ).length;
|
630 |
-
}
|
631 |
-
|
632 |
-
if ( 'xpath' === localStorage.getItem( 'advads_frontend_pathtype' ) ) {
|
633 |
-
var fn = 'getXPath';
|
634 |
-
} else {
|
635 |
-
var fn = 'getPath';
|
636 |
-
}
|
637 |
-
|
638 |
-
|
639 |
-
jQuery(document).mousemove(function(e) {
|
640 |
-
if (e.target === advads_picker_cur) {
|
641 |
-
return;
|
642 |
-
}
|
643 |
-
|
644 |
-
if (~advads_picker_no.indexOf(e.target)) {
|
645 |
-
advads_picker_cur = null;
|
646 |
-
advads_picker_overlay.hide();
|
647 |
-
return;
|
648 |
-
}
|
649 |
-
|
650 |
-
var target = jQuery(e.target),
|
651 |
-
offset = target.offset(),
|
652 |
-
width = target.outerWidth(),
|
653 |
-
height = target.outerHeight();
|
654 |
-
|
655 |
-
advads_picker_cur = e.target;
|
656 |
-
|
657 |
-
var path = jQuery( advads_picker_cur )[fn]();
|
658 |
-
if ( ! path ) {
|
659 |
-
// A click outside of the boundary.
|
660 |
-
// @see `is_boundary_reached`.
|
661 |
-
return;
|
662 |
-
}
|
663 |
-
//log path
|
664 |
-
console.log( path);
|
665 |
-
|
666 |
-
advads_picker_overlay.css({
|
667 |
-
top: offset.top,
|
668 |
-
left: offset.left,
|
669 |
-
width: width,
|
670 |
-
height: height
|
671 |
-
}).show();
|
672 |
-
|
673 |
-
});
|
674 |
-
// save on click
|
675 |
-
jQuery(document).click(function(e) {
|
676 |
-
var path = jQuery( advads_picker_cur )[fn]();
|
677 |
-
|
678 |
-
if ( advads.is_boundary_reached( advads_picker_cur )) {
|
679 |
-
return;
|
680 |
-
}
|
681 |
-
|
682 |
-
localStorage.setItem( 'advads_frontend_element', path );
|
683 |
-
window.location = localStorage.getItem('advads_prev_url');
|
684 |
-
});
|
685 |
-
};
|
686 |
-
});
|
687 |
-
/*
|
688 |
-
derrived from jQuery-GetPath v0.01, by Dave Cardwell. (2007-04-27)
|
689 |
-
http://davecardwell.co.uk/javascript/jquery/plugins/jquery-getpath/
|
690 |
-
Usage:
|
691 |
-
var path = $('#foo').getPath();
|
692 |
-
*/
|
693 |
-
|
694 |
-
jQuery.fn.extend({
|
695 |
-
getPath: function( path, depth ) {
|
696 |
-
// The first time this function is called, path won't be defined.
|
697 |
-
if ( typeof path === 'undefined' ) path = '';
|
698 |
-
if ( typeof depth === 'undefined' ) depth = 0;
|
699 |
-
|
700 |
-
// If this element is <html> we've reached the end of the path.
|
701 |
-
// also end after 2 elements
|
702 |
-
if ( this.is('html')){
|
703 |
-
return 'html > ' + path;
|
704 |
-
} else if ( 3 === depth ){
|
705 |
-
return path;
|
706 |
-
}
|
707 |
-
|
708 |
-
// Add the element name.
|
709 |
-
var cur = this.get(0).nodeName.toLowerCase();
|
710 |
-
|
711 |
-
// Determine the IDs and path.
|
712 |
-
var el_id = this.attr('id'),
|
713 |
-
el_class = this.attr('class');
|
714 |
-
|
715 |
-
depth = depth + 1;
|
716 |
-
|
717 |
-
// Add the #id if there is one. Ignore ID with number.
|
718 |
-
if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
|
719 |
-
cur += '#' + el_id;
|
720 |
-
} else if ( typeof el_class !== 'undefined' ){
|
721 |
-
// Add classes if there is no id.
|
722 |
-
el_class = el_class.split( /[\s\n]+/ );
|
723 |
-
// Skip classes with numbers.
|
724 |
-
el_class = jQuery.grep( el_class, function( element, index ) {
|
725 |
-
return ! /\d/.test( element )
|
726 |
-
});
|
727 |
-
// Add 2 classes.
|
728 |
-
if ( el_class.length ) {
|
729 |
-
cur += '.' + el_class.slice( 0, 2 ).join( '.' );
|
730 |
-
}
|
731 |
-
}
|
732 |
-
|
733 |
-
// add index if this element is not unique among its siblings
|
734 |
-
if( this.siblings( cur ).length ){
|
735 |
-
cur += ":eq(" + this.siblings( cur ).addBack().not( '#advads-picker-overlay' ).index( this ) + ")";
|
736 |
-
}
|
737 |
-
|
738 |
-
// Recurse up the DOM.
|
739 |
-
if( path === '' ){
|
740 |
-
return this.parent().getPath( cur, depth );
|
741 |
-
} else {
|
742 |
-
return this.parent().getPath( cur + ' > ' + path, depth );
|
743 |
-
}
|
744 |
-
},
|
745 |
-
|
746 |
-
/**
|
747 |
-
* Get XPath.
|
748 |
-
*/
|
749 |
-
getXPath: function( path, depth ) {
|
750 |
-
// The first time this function is called, path won't be defined.
|
751 |
-
if ( typeof path === 'undefined' ) path = '';
|
752 |
-
if ( typeof depth === 'undefined' ) depth = 0;
|
753 |
-
|
754 |
-
// If this element is <html> we've reached the end of the path.
|
755 |
-
// also end after 2 elements
|
756 |
-
if ( this.is('body') || 3 === depth){
|
757 |
-
return path;
|
758 |
-
}
|
759 |
-
|
760 |
-
if ( advads.is_boundary_reached( this )) {
|
761 |
-
return path;
|
762 |
-
}
|
763 |
-
|
764 |
-
// Add the element name.
|
765 |
-
var tag = this.get(0).nodeName.toLowerCase();
|
766 |
-
var cur = tag;
|
767 |
-
|
768 |
-
// Determine the IDs and path.
|
769 |
-
var el_id = this.attr('id'),
|
770 |
-
el_class = this.attr('class');
|
771 |
-
var classes = [];
|
772 |
-
|
773 |
-
// Add the #id if there is one. Ignore ID with number.
|
774 |
-
if ( typeof el_id !== 'undefined' && ! /\d/.test( el_id ) ) {
|
775 |
-
return cur + '[@id and id="' + el_id + '"]/' + path;
|
776 |
-
} else if ( typeof el_class !== 'undefined' ){
|
777 |
-
// Add classes if there is no id.
|
778 |
-
el_class = el_class.split( /[\s\n]+/ );
|
779 |
-
// Skip classes with numbers.
|
780 |
-
el_class = jQuery.grep( el_class, function( element, index ) {
|
781 |
-
return ! /\d/.test( element )
|
782 |
-
});
|
783 |
-
// Add 2 classes.
|
784 |
-
if ( el_class.length ) {
|
785 |
-
depth = depth + 1;
|
786 |
-
var classes = el_class.slice( 0, 2 );
|
787 |
-
|
788 |
-
var xpath_classes = [];
|
789 |
-
for ( var i = 0; i < classes.length; i++ ) {
|
790 |
-
xpath_classes.push( '(@class and contains(concat(" ", normalize-space(@class), " "), " ' + classes[ i ] + ' "))');
|
791 |
-
}
|
792 |
-
cur += '[' + xpath_classes.join( ' and ' ) + ']';
|
793 |
-
}
|
794 |
-
}
|
795 |
-
|
796 |
-
// Add index if this element is not unique among its siblings.
|
797 |
-
if ( classes.length ) {
|
798 |
-
var $siblings = this.siblings( tag + '.' + classes.join( '.' ) );
|
799 |
-
} else {
|
800 |
-
var $siblings = this.siblings( tag );
|
801 |
-
}
|
802 |
-
|
803 |
-
if ( $siblings.length ) {
|
804 |
-
var index = $siblings.addBack().not( '#advads-picker-overlay' ).index( this );
|
805 |
-
cur += '[' + index + ']';
|
806 |
-
}
|
807 |
-
|
808 |
-
// Recurse up the DOM.
|
809 |
-
if( path === '' ){
|
810 |
-
return this.parent().getXPath( cur, depth );
|
811 |
-
} else {
|
812 |
-
return this.parent().getXPath( cur + '/' + path, depth );
|
813 |
-
}
|
814 |
-
}
|
815 |
-
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: ads, ad manager, ad rotation, adsense, banner
|
|
4 |
Requires at least: 4.6
|
5 |
Tested up to: 5.5
|
6 |
Requires PHP: 5.6
|
7 |
-
Stable tag: 1.20.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -317,6 +317,13 @@ Yes. You can use plenty of [hooks](https://wpadvancedads.com/codex/) to customiz
|
|
317 |
|
318 |
== Changelog ==
|
319 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
320 |
= 1.20.2 =
|
321 |
|
322 |
- fixed displaying image ads if privacy method is set to custom cookie
|
4 |
Requires at least: 4.6
|
5 |
Tested up to: 5.5
|
6 |
Requires PHP: 5.6
|
7 |
+
Stable tag: 1.20.3
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
317 |
|
318 |
== Changelog ==
|
319 |
|
320 |
+
= 1.20.3 =
|
321 |
+
|
322 |
+
- whitelist field groups created by Advanced Custom Fields on the ad edit page
|
323 |
+
- prevent including AdSense Auto ads code when the Borlabs Cookie is already adding it
|
324 |
+
- prevented adding unneeded escape characters to ads.txt file
|
325 |
+
- added compatibility with Funding Choices when consent is not needed
|
326 |
+
|
327 |
= 1.20.2 =
|
328 |
|
329 |
- fixed displaying image ads if privacy method is set to custom cookie
|