The SEO Framework - Version 3.0.6

Version Description

  • Lionize =

Release date

  • May 6th, 2018

Summarized:

  • TSF now integrates completely with attachment pages.
  • Non-personalized Facebook profile links can now be set via the Social SEO settings and user's Authorial Info settings.
  • Seven bugs have been fixed, mainly involving descriptions and the sitemap.
  • The plugin now suggests, once, that you can use Focus keywords via the Extension Manager.

For everyone, about the suggestion:

  • We believe not everyone is up-to-date yet with the current progression of the extensions. Some of which can help you out greatly with SEO.
  • So, from this update, all sites will get a one-time-only auto-dismissing suggestion for TSFEM.
  • This suggestion has many conditions attached before being shown. So, it's likely you won't ever see it.
  • We understand that not everyone welcomes this introduction. However, this suggestion is to help this plugin and your site grow, from which we all will benefit.

For developers, about descriptions:

  • If you're using description-related filters or functions from TSF on your sites, check out the detailed "for developers" log.
  • Many functions have been silently deprecated, and you should now use simple caller functions.
  • No action is needed from your side until the next major release (ETA July 2018).

For developers, about titles ETA July 2018:

  • In the next major release, we're going to change how we handle titles.
  • This change won't affect users directly. But it will allow us to manipulate the titles better.
  • For more information, view and subscribe to issue 202.

View the detailed log.

Download this release

Release Info

Developer Cybr
Plugin Icon 128x128 The SEO Framework
Version 3.0.6
Comparing to
See all releases

Code changes from version 3.0.5 to 3.0.6

autodescription.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
- * Version: 3.0.5
7
  * Author: Sybre Waaijer
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
@@ -33,10 +33,11 @@ defined( 'ABSPATH' ) or die;
33
  //* Debug. Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
34
  // add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
35
  // if ( is_admin() ) {
36
- // define( 'THE_SEO_FRAMEWORK_DEBUG', true );
37
  // define( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN', true );
38
  // define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
39
- // update_option( 'the_seo_framework_upgraded_db_version', '0' );
 
40
  // add_filter( 'the_seo_framework_use_object_cache', '__return_false' );
41
  // }
42
  // }},0);
@@ -51,7 +52,7 @@ defined( 'ABSPATH' ) or die;
51
  *
52
  * @since 1.0.0
53
  */
54
- define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.5' );
55
 
56
  /**
57
  * The plugin Database version.
@@ -60,7 +61,7 @@ define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.5' );
60
  *
61
  * @since 2.7.0
62
  */
63
- define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3001' );
64
 
65
  /**
66
  * The plugin options database option_name.
3
  * Plugin Name: The SEO Framework
4
  * Plugin URI: https://theseoframework.com/
5
  * Description: An automated, advanced, accessible, unbranded and extremely fast SEO solution for any WordPress website.
6
+ * Version: 3.0.6
7
  * Author: Sybre Waaijer
8
  * Author URI: https://theseoframework.com/
9
  * License: GPLv3
33
  //* Debug. Not to be used on production websites as it dumps and/or disables all kinds of stuff everywhere.
34
  // add_action( 'plugins_loaded', function() { if ( is_super_admin() ) {
35
  // if ( is_admin() ) {
36
+ // define( 'THE_SEO_FRAMEWORK_DEBUG', true );
37
  // define( 'THE_SEO_FRAMEWORK_DEBUG_HIDDEN', true );
38
  // define( 'THE_SEO_FRAMEWORK_DISABLE_TRANSIENTS', true );
39
+ // update_option( 'the_seo_framework_upgraded_db_version', '3060' );
40
+ // update_option( 'the_seo_framework_tested_upgrade_version', '0' );
41
  // add_filter( 'the_seo_framework_use_object_cache', '__return_false' );
42
  // }
43
  // }},0);
52
  *
53
  * @since 1.0.0
54
  */
55
+ define( 'THE_SEO_FRAMEWORK_VERSION', '3.0.6' );
56
 
57
  /**
58
  * The plugin Database version.
61
  *
62
  * @since 2.7.0
63
  */
64
+ define( 'THE_SEO_FRAMEWORK_DB_VERSION', '3060' );
65
 
66
  /**
67
  * The plugin options database option_name.
inc/classes/admin-init.class.php CHANGED
@@ -126,6 +126,7 @@ class Admin_Init extends Init {
126
  * Enqueues scripts.
127
  *
128
  * @since 2.0.2
 
129
  *
130
  * @param string $hook The current page hook.
131
  */
@@ -140,8 +141,11 @@ class Admin_Init extends Init {
140
  //* Register the script.
141
  $this->_register_admin_javascript();
142
 
143
- if ( $this->is_post_edit() || $this->is_seo_settings_page() )
 
 
144
  \wp_enqueue_media();
 
145
 
146
  if ( $this->is_seo_settings_page() )
147
  \wp_enqueue_script( 'wp-color-picker' );
@@ -221,7 +225,7 @@ class Admin_Init extends Init {
221
  $id = $this->get_the_real_ID();
222
  $blog_name = $this->get_blogname();
223
  $description = $this->get_blogdescription();
224
- $object_title = '';
225
  $additions = '';
226
 
227
  $use_additions = (bool) $this->get_option( 'homepage_tagline' );
@@ -261,7 +265,7 @@ class Admin_Init extends Init {
261
  if ( isset( $this->page_base_file ) && $this->page_base_file ) {
262
  // We're somewhere within default WordPress pages.
263
  if ( $this->is_static_frontpage( $id ) ) {
264
- $object_title = $this->get_option( 'homepage_title' ) ?: $blog_name;
265
  $title_location = $this->get_option( 'home_title_location' );
266
  $ishome = true;
267
 
@@ -278,7 +282,7 @@ class Admin_Init extends Init {
278
  'get_custom_field' => false,
279
  );
280
 
281
- $object_title = $this->title( '', '', '', $generated_doctitle_args );
282
 
283
  if ( $title_add_additions ) {
284
  $additions = $blog_name;
@@ -290,13 +294,13 @@ class Admin_Init extends Init {
290
  } elseif ( $is_term_edit ) {
291
  //* Category or Tag.
292
  if ( isset( $GLOBALS['current_screen']->taxonomy ) && $id ) {
293
- $object_title = $this->single_term_title( '', false, $this->fetch_the_term( $id ) );
294
  $additions = $title_add_additions ? $blog_name : '';
295
  }
296
  } else {
297
  //* We're in a special place.
298
  // Can't fetch title.
299
- $object_title = '';
300
  $additions = $title_add_additions ? $blog_name : '';
301
  }
302
  } elseif ( $is_settings_page ) {
@@ -309,7 +313,7 @@ class Admin_Init extends Init {
309
  // Home is a blog.
310
  $inpost_title = '';
311
  }
312
- $object_title = $inpost_title ?: $blog_name;
313
  $additions = $home_tagline ?: $description;
314
  }
315
 
@@ -361,7 +365,8 @@ class Admin_Init extends Init {
361
  'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
362
  ),
363
  'params' => array(
364
- 'objectTitle' => $object_title,
 
365
  'titleAdditions' => $additions,
366
  'blogDescription' => $description,
367
  'termName' => $term_name,
@@ -569,7 +574,6 @@ class Admin_Init extends Init {
569
  $color = $colors[2];
570
  $color_accent = $colors[3];
571
 
572
- // TODO fix this.
573
  // $bg_alt_font = '#' . $this->get_relative_fontcolor( $bg );
574
  $bg_accent_alt_font = '#' . $this->get_relative_fontcolor( $bg_accent );
575
 
126
  * Enqueues scripts.
127
  *
128
  * @since 2.0.2
129
+ * @since 3.0.6 Now attaches the post ID to `wp_enqueue_media` on post edit.
130
  *
131
  * @param string $hook The current page hook.
132
  */
141
  //* Register the script.
142
  $this->_register_admin_javascript();
143
 
144
+ if ( $this->is_post_edit() ) {
145
+ \wp_enqueue_media( array( 'post' => $this->get_the_real_admin_ID() ) );
146
+ } elseif ( $this->is_seo_settings_page() ) {
147
  \wp_enqueue_media();
148
+ }
149
 
150
  if ( $this->is_seo_settings_page() )
151
  \wp_enqueue_script( 'wp-color-picker' );
225
  $id = $this->get_the_real_ID();
226
  $blog_name = $this->get_blogname();
227
  $description = $this->get_blogdescription();
228
+ $default_title = '';
229
  $additions = '';
230
 
231
  $use_additions = (bool) $this->get_option( 'homepage_tagline' );
265
  if ( isset( $this->page_base_file ) && $this->page_base_file ) {
266
  // We're somewhere within default WordPress pages.
267
  if ( $this->is_static_frontpage( $id ) ) {
268
+ $default_title = $this->get_option( 'homepage_title' ) ?: $blog_name;
269
  $title_location = $this->get_option( 'home_title_location' );
270
  $ishome = true;
271
 
282
  'get_custom_field' => false,
283
  );
284
 
285
+ $default_title = $this->title( '', '', '', $generated_doctitle_args );
286
 
287
  if ( $title_add_additions ) {
288
  $additions = $blog_name;
294
  } elseif ( $is_term_edit ) {
295
  //* Category or Tag.
296
  if ( isset( $GLOBALS['current_screen']->taxonomy ) && $id ) {
297
+ $default_title = $this->single_term_title( '', false, $this->fetch_the_term( $id ) );
298
  $additions = $title_add_additions ? $blog_name : '';
299
  }
300
  } else {
301
  //* We're in a special place.
302
  // Can't fetch title.
303
+ $default_title = '';
304
  $additions = $title_add_additions ? $blog_name : '';
305
  }
306
  } elseif ( $is_settings_page ) {
313
  // Home is a blog.
314
  $inpost_title = '';
315
  }
316
+ $default_title = $inpost_title ?: $blog_name;
317
  $additions = $home_tagline ?: $description;
318
  }
319
 
365
  'pixelsUsed' => $has_input ? \__( '%1$d out of %2$d pixels are used.', 'autodescription' ) : '',
366
  ),
367
  'params' => array(
368
+ 'objectTitle' => $default_title,
369
+ 'defaultTitle' => $default_title,
370
  'titleAdditions' => $additions,
371
  'blogDescription' => $description,
372
  'termName' => $term_name,
574
  $color = $colors[2];
575
  $color_accent = $colors[3];
576
 
 
577
  // $bg_alt_font = '#' . $this->get_relative_fontcolor( $bg );
578
  $bg_accent_alt_font = '#' . $this->get_relative_fontcolor( $bg_accent );
579
 
inc/classes/cache.class.php CHANGED
@@ -159,6 +159,7 @@ class Cache extends Sitemaps {
159
 
160
  //* Excluded IDs cache.
161
  \add_action( 'save_post', array( $this, 'delete_excluded_ids_cache' ) );
 
162
 
163
  $run = true;
164
  }
@@ -777,6 +778,7 @@ class Cache extends Sitemaps {
777
  $query = '';
778
 
779
  //* TODO figure out why this check is here... admin compat maybe?
 
780
  if ( function_exists( 'get_search_query' ) ) {
781
  $search_query = \get_search_query( $_escaped = true );
782
 
159
 
160
  //* Excluded IDs cache.
161
  \add_action( 'save_post', array( $this, 'delete_excluded_ids_cache' ) );
162
+ \add_action( 'edit_attachment', array( $this, 'delete_excluded_ids_cache' ) );
163
 
164
  $run = true;
165
  }
778
  $query = '';
779
 
780
  //* TODO figure out why this check is here... admin compat maybe?
781
+ //! TODO convert the search query to a hash: search_(hash)... encode first!
782
  if ( function_exists( 'get_search_query' ) ) {
783
  $search_query = \get_search_query( $_escaped = true );
784
 
inc/classes/core.class.php CHANGED
@@ -115,9 +115,6 @@ class Core {
115
  * Latest Class. Doesn't have parent.
116
  */
117
  protected function __construct() {
118
-
119
- \add_action( 'current_screen', array( $this, 'post_type_support' ), 0 );
120
-
121
  if ( $this->the_seo_framework_debug ) {
122
 
123
  $debug_instance = Debug::get_instance();
@@ -205,36 +202,6 @@ class Core {
205
  return round( $i );
206
  }
207
 
208
- /**
209
- * Adds post type support for The SEO Framework.
210
- *
211
- * @since 2.1.6
212
- */
213
- public function post_type_support() {
214
-
215
- $defaults = array(
216
- 'post',
217
- 'page',
218
- 'product',
219
- 'forum',
220
- 'topic',
221
- 'jetpack-testimonial',
222
- 'jetpack-portfolio',
223
- );
224
-
225
- /**
226
- * Applies filters the_seo_framework_supported_post_types : Array The supported post types.
227
- * @since 2.3.1
228
- */
229
- $post_types = (array) \apply_filters( 'the_seo_framework_supported_post_types', $defaults );
230
-
231
- $types = \wp_parse_args( $defaults, $post_types );
232
-
233
- foreach ( $types as $type ) {
234
- \add_post_type_support( $type, array( 'autodescription-meta' ) );
235
- }
236
- }
237
-
238
  /**
239
  * Adds link from plugins page to SEO Settings page.
240
  *
@@ -290,6 +257,7 @@ class Core {
290
  * Also loads scripts and styles if out of The SEO Framework's context.
291
  *
292
  * @since 2.6.0
 
293
  *
294
  * @param string $message The notice message. Expected to be escaped if $escape is false.
295
  * @param string $type The notice type : 'updated', 'error', 'warning'. Expected to be escaped.
@@ -302,9 +270,6 @@ class Core {
302
  if ( empty( $message ) )
303
  return '';
304
 
305
- if ( $escape )
306
- $message = \esc_html( $message );
307
-
308
  //* Make sure the scripts are loaded.
309
  $this->init_admin_scripts( true );
310
 
@@ -315,7 +280,7 @@ class Core {
315
 
316
  $notice = '<div class="notice ' . \esc_attr( $type ) . ' tsf-notice ' . $a11y . '"><p>';
317
  $notice .= '<a class="hide-if-no-js tsf-dismiss" title="' . \esc_attr__( 'Dismiss', 'autodescription' ) . '"></a>';
318
- $notice .= '<strong>' . $message . '</strong>';
319
  $notice .= '</p></div>';
320
 
321
  return $notice;
@@ -627,7 +592,7 @@ class Core {
627
  *
628
  * @param bool $guess : If true, the timezone will be guessed from the
629
  * WordPress core gmt_offset option.
630
- * @return string PHP Timezone String.
631
  */
632
  public function get_timezone_string( $guess = false ) {
633
 
@@ -672,6 +637,7 @@ class Core {
672
  * Sets and resets the timezone.
673
  *
674
  * @since 2.6.0
 
675
  *
676
  * @param string $tzstring Optional. The PHP Timezone string. Best to leave empty to always get a correct one.
677
  * @link http://php.net/manual/en/timezones.php
@@ -692,7 +658,7 @@ class Core {
692
  return date_default_timezone_set( $old_tz );
693
 
694
  if ( empty( $tzstring ) )
695
- $tzstring = $this->get_timezone_string( true );
696
 
697
  return date_default_timezone_set( $tzstring );
698
  }
115
  * Latest Class. Doesn't have parent.
116
  */
117
  protected function __construct() {
 
 
 
118
  if ( $this->the_seo_framework_debug ) {
119
 
120
  $debug_instance = Debug::get_instance();
202
  return round( $i );
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  /**
206
  * Adds link from plugins page to SEO Settings page.
207
  *
257
  * Also loads scripts and styles if out of The SEO Framework's context.
258
  *
259
  * @since 2.6.0
260
+ * @since 3.0.6 The messages are no longer auto-styled to "strong".
261
  *
262
  * @param string $message The notice message. Expected to be escaped if $escape is false.
263
  * @param string $type The notice type : 'updated', 'error', 'warning'. Expected to be escaped.
270
  if ( empty( $message ) )
271
  return '';
272
 
 
 
 
273
  //* Make sure the scripts are loaded.
274
  $this->init_admin_scripts( true );
275
 
280
 
281
  $notice = '<div class="notice ' . \esc_attr( $type ) . ' tsf-notice ' . $a11y . '"><p>';
282
  $notice .= '<a class="hide-if-no-js tsf-dismiss" title="' . \esc_attr__( 'Dismiss', 'autodescription' ) . '"></a>';
283
+ $notice .= $escape ? \esc_html( $message ) : $message;
284
  $notice .= '</p></div>';
285
 
286
  return $notice;
592
  *
593
  * @param bool $guess : If true, the timezone will be guessed from the
594
  * WordPress core gmt_offset option.
595
+ * @return string PHP Timezone String. May be empty (thus invalid).
596
  */
597
  public function get_timezone_string( $guess = false ) {
598
 
637
  * Sets and resets the timezone.
638
  *
639
  * @since 2.6.0
640
+ * @since 3.0.6 Now uses the old timezone string when a new one can't be generated.
641
  *
642
  * @param string $tzstring Optional. The PHP Timezone string. Best to leave empty to always get a correct one.
643
  * @link http://php.net/manual/en/timezones.php
658
  return date_default_timezone_set( $old_tz );
659
 
660
  if ( empty( $tzstring ) )
661
+ $tzstring = $this->get_timezone_string( true ) ?: $old_tz;
662
 
663
  return date_default_timezone_set( $tzstring );
664
  }
inc/classes/detect.class.php CHANGED
@@ -44,6 +44,7 @@ class Detect extends Render {
44
  /**
45
  * Determines if we're doing ajax.
46
  *
 
47
  * @since 2.9.0
48
  * @staticvar bool $cache
49
  *
@@ -126,6 +127,7 @@ class Detect extends Render {
126
  * Filterable list of conflicting plugins.
127
  *
128
  * @since 2.6.0
 
129
  * @credits JetPack for most code.
130
  *
131
  * @return array List of conflicting plugins.
@@ -157,7 +159,6 @@ class Detect extends Render {
157
  'Facebook Open Graph Meta Tags for WordPress' => 'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
158
  'Facebook Thumb Fixer' => 'facebook-thumb-fixer/_facebook-thumb-fixer.php',
159
  'Fedmichs Facebook Open Graph Meta' => 'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
160
- 'Header and Footer' => 'header-footer/plugin.php',
161
  'NextGEN Facebook OG' => 'nextgen-facebook/nextgen-facebook.php',
162
  'Open Graph' => 'opengraph/opengraph.php',
163
  'Open Graph Protocol Framework' => 'open-graph-protocol-framework/open-graph-protocol-framework.php',
44
  /**
45
  * Determines if we're doing ajax.
46
  *
47
+ * @todo use wp_doing_ajax() in a future version. Requires WP 4.7+.
48
  * @since 2.9.0
49
  * @staticvar bool $cache
50
  *
127
  * Filterable list of conflicting plugins.
128
  *
129
  * @since 2.6.0
130
+ * @TODO consider removing "Header and Footer"
131
  * @credits JetPack for most code.
132
  *
133
  * @return array List of conflicting plugins.
159
  'Facebook Open Graph Meta Tags for WordPress' => 'wonderm00ns-simple-facebook-open-graph-tags/wonderm00n-open-graph.php',
160
  'Facebook Thumb Fixer' => 'facebook-thumb-fixer/_facebook-thumb-fixer.php',
161
  'Fedmichs Facebook Open Graph Meta' => 'facebook-and-digg-thumbnail-generator/facebook-and-digg-thumbnail-generator.php',
 
162
  'NextGEN Facebook OG' => 'nextgen-facebook/nextgen-facebook.php',
163
  'Open Graph' => 'opengraph/opengraph.php',
164
  'Open Graph Protocol Framework' => 'open-graph-protocol-framework/open-graph-protocol-framework.php',
inc/classes/doing-it-right.class.php CHANGED
@@ -760,6 +760,7 @@ class Doing_It_Right extends Generate_Ldjson {
760
  *
761
  * @since 2.6.0
762
  * @since 2.9.0 Now also returns noindex value.
 
763
  * @staticvar array $data
764
  *
765
  * @param array $args The term args.
@@ -782,7 +783,7 @@ class Doing_It_Right extends Generate_Ldjson {
782
  $data = $this->get_term_meta( $term_id );
783
 
784
  $title_custom_field = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
785
- $description_custom_field = isset( $data['description'] ) ? $data['description'] : '';
786
  $noindex = isset( $data['noindex'] ) ? $data['noindex'] : '';
787
  $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
788
  $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
@@ -795,21 +796,13 @@ class Doing_It_Right extends Generate_Ldjson {
795
  }
796
 
797
  $description_is_from_custom_field = (bool) $description_custom_field;
 
798
  if ( $description_is_from_custom_field ) {
799
- $taxonomy = ! empty( $term->taxonomy ) ? $term->taxonomy : '';
800
- $description_args = $taxonomy ? array( 'id' => $term_id, 'taxonomy' => $term->taxonomy, 'get_custom_field' => true ) : array( 'get_custom_field' => true );
801
-
802
- $description = $this->generate_description( '', $description_args );
803
  } else {
804
- $taxonomy = ! empty( $term->taxonomy ) ? $term->taxonomy : '';
805
- $description_args = $taxonomy ? array( 'id' => $term_id, 'taxonomy' => $term->taxonomy, 'get_custom_field' => false ) : array( 'get_custom_field' => false );
806
-
807
- $description = $this->generate_description( '', $description_args );
808
  }
809
 
810
- /**
811
- * No longer uses is_checked. As it strict checks 1/0 strings.
812
- */
813
  $noindex = (bool) $noindex;
814
  $nofollow = (bool) $nofollow;
815
  $noarchive = (bool) $noarchive;
@@ -830,6 +823,7 @@ class Doing_It_Right extends Generate_Ldjson {
830
  *
831
  * @since 2.6.0
832
  * @since 2.9.0 Now also returns noindex value.
 
833
  * @staticvar array $data
834
  *
835
  * @param array $args The post args.
@@ -849,14 +843,14 @@ class Doing_It_Right extends Generate_Ldjson {
849
  $page_on_front = $this->is_static_frontpage( $post_id );
850
 
851
  $title_custom_field = $this->get_custom_field( '_genesis_title', $post_id );
852
- $description_custom_field = $this->get_custom_field( '_genesis_description', $post_id );
853
  $noindex = $this->get_custom_field( '_genesis_noindex', $post_id );
854
  $nofollow = $this->get_custom_field( '_genesis_nofollow', $post_id );
855
  $noarchive = $this->get_custom_field( '_genesis_noarchive', $post_id );
856
 
857
  if ( $page_on_front ) {
858
  $title_custom_field = $this->get_option( 'homepage_title' ) ?: $title_custom_field;
859
- $description_custom_field = $this->get_option( 'homepage_description' ) ?: $description_custom_field;
860
  $noindex = $this->get_option( 'homepage_noindex' ) ?: $nofollow;
861
  $nofollow = $this->get_option( 'homepage_nofollow' ) ?: $nofollow;
862
  $noarchive = $this->get_option( 'homepage_noarchive' ) ?: $noarchive;
@@ -870,10 +864,11 @@ class Doing_It_Right extends Generate_Ldjson {
870
  }
871
 
872
  $description_is_from_custom_field = (bool) $description_custom_field;
 
873
  if ( $description_is_from_custom_field ) {
874
- $description = $this->generate_description( '', array( 'id' => $post_id, 'get_custom_field' => true ) );
875
  } else {
876
- $description = $this->generate_description( '', array( 'id' => $post_id, 'get_custom_field' => false ) );
877
  }
878
 
879
  $noindex = (bool) $noindex;
@@ -1435,10 +1430,10 @@ class Doing_It_Right extends Generate_Ldjson {
1435
  $arc_notice = $archive_i18n . ' ' . sprintf( \esc_attr__( "Search Engines aren't allowed to archive this %s.", 'autodescription' ), $post_low );
1436
  $arc_class = $unknown;
1437
  $archived = false;
1438
- $arc_but = true;
1439
  } else {
1440
  $arc_notice = $archive_i18n . ' ' . sprintf( \esc_attr__( 'Search Engines are allowed to archive this %s.', 'autodescription' ), $post_low );
1441
  $arc_class = $good;
 
1442
  }
1443
 
1444
  /**
@@ -1449,7 +1444,7 @@ class Doing_It_Right extends Generate_Ldjson {
1449
  if ( $this->is_option_checked( 'site_noarchive' ) ) {
1450
  $but_and = isset( $arc_but ) ? $and_i18n : $but_i18n;
1451
 
1452
- $arc_notice .= '<br>' . sprintf( \esc_attr__( "But you've discouraged archiving for the whole site.", 'autodescription' ), $but_and );
1453
  $arc_class = $unknown;
1454
  $arc_but = true;
1455
 
760
  *
761
  * @since 2.6.0
762
  * @since 2.9.0 Now also returns noindex value.
763
+ * @since 3.0.6 Now considers custom field filters for the description.
764
  * @staticvar array $data
765
  *
766
  * @param array $args The term args.
783
  $data = $this->get_term_meta( $term_id );
784
 
785
  $title_custom_field = isset( $data['doctitle'] ) ? $data['doctitle'] : '';
786
+ $description_custom_field = $this->get_description_from_custom_field( $term_id );
787
  $noindex = isset( $data['noindex'] ) ? $data['noindex'] : '';
788
  $nofollow = isset( $data['nofollow'] ) ? $data['nofollow'] : '';
789
  $noarchive = isset( $data['noarchive'] ) ? $data['noarchive'] : '';
796
  }
797
 
798
  $description_is_from_custom_field = (bool) $description_custom_field;
799
+ //= Call sanitized version.
800
  if ( $description_is_from_custom_field ) {
801
+ $description = $this->get_description_from_custom_field( $term_id );
 
 
 
802
  } else {
803
+ $description = $this->get_generated_description( $term_id );
 
 
 
804
  }
805
 
 
 
 
806
  $noindex = (bool) $noindex;
807
  $nofollow = (bool) $nofollow;
808
  $noarchive = (bool) $noarchive;
823
  *
824
  * @since 2.6.0
825
  * @since 2.9.0 Now also returns noindex value.
826
+ * @since 3.0.6 Now considers custom field filters for the description.
827
  * @staticvar array $data
828
  *
829
  * @param array $args The post args.
843
  $page_on_front = $this->is_static_frontpage( $post_id );
844
 
845
  $title_custom_field = $this->get_custom_field( '_genesis_title', $post_id );
846
+ $description_custom_field = $this->get_description_from_custom_field( $post_id );
847
  $noindex = $this->get_custom_field( '_genesis_noindex', $post_id );
848
  $nofollow = $this->get_custom_field( '_genesis_nofollow', $post_id );
849
  $noarchive = $this->get_custom_field( '_genesis_noarchive', $post_id );
850
 
851
  if ( $page_on_front ) {
852
  $title_custom_field = $this->get_option( 'homepage_title' ) ?: $title_custom_field;
853
+ // $description_custom_field = $description_custom_field; // We already got this.
854
  $noindex = $this->get_option( 'homepage_noindex' ) ?: $nofollow;
855
  $nofollow = $this->get_option( 'homepage_nofollow' ) ?: $nofollow;
856
  $noarchive = $this->get_option( 'homepage_noarchive' ) ?: $noarchive;
864
  }
865
 
866
  $description_is_from_custom_field = (bool) $description_custom_field;
867
+ //= Call sanitized version.
868
  if ( $description_is_from_custom_field ) {
869
+ $description = $this->get_description_from_custom_field( $post_id );
870
  } else {
871
+ $description = $this->get_generated_description( $post_id );
872
  }
873
 
874
  $noindex = (bool) $noindex;
1430
  $arc_notice = $archive_i18n . ' ' . sprintf( \esc_attr__( "Search Engines aren't allowed to archive this %s.", 'autodescription' ), $post_low );
1431
  $arc_class = $unknown;
1432
  $archived = false;
 
1433
  } else {
1434
  $arc_notice = $archive_i18n . ' ' . sprintf( \esc_attr__( 'Search Engines are allowed to archive this %s.', 'autodescription' ), $post_low );
1435
  $arc_class = $good;
1436
+ $arc_but = true;
1437
  }
1438
 
1439
  /**
1444
  if ( $this->is_option_checked( 'site_noarchive' ) ) {
1445
  $but_and = isset( $arc_but ) ? $and_i18n : $but_i18n;
1446
 
1447
+ $arc_notice .= '<br>' . sprintf( \esc_attr__( "%s you've discouraged archiving for the whole site.", 'autodescription' ), $but_and );
1448
  $arc_class = $unknown;
1449
  $arc_but = true;
1450
 
inc/classes/generate-description.class.php CHANGED
@@ -39,15 +39,83 @@ class Generate_Description extends Generate {
39
  parent::__construct();
40
  }
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  /**
43
  * Returns the Twitter meta description. Falls back to Open Graph description.
44
  *
45
  * @since 3.0.4
46
  * @uses $this->get_open_graph_description()
47
  *
48
- * @param int|null $id The post or term ID. Falls back to queried ID.
49
  * @param bool $escape Whether to escape the description.
50
- * @return string Twitter Description.
51
  */
52
  public function get_twitter_description( $id = null, $escape = true ) {
53
 
@@ -66,9 +134,9 @@ class Generate_Description extends Generate {
66
  * @since 3.0.4
67
  * @uses $this->get_generated_open_graph_description()
68
  *
69
- * @param int|null $id The post or term ID. Falls back to queried ID.
70
  * @param bool $escape Whether to escape the description.
71
- * @return string Open Graph Description.
72
  */
73
  public function get_open_graph_description( $id = null, $escape = true ) {
74
 
@@ -81,15 +149,40 @@ class Generate_Description extends Generate {
81
  return $escape ? $this->escape_description( $desc ) : $desc;
82
  }
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  /**
85
  * Returns the autogenerated open graph meta description. Falls back to meta description.
86
  *
87
  * @since 3.0.4
88
  * @uses $this->get_generated_open_graph_description()
89
  *
90
- * @param int|null $id The post or term ID. Falls back to queried ID.
91
  * @param bool $escape Whether to escape the description.
92
- * @return string Autogenerated Twitter Description.
93
  */
94
  public function get_generated_twitter_description( $id = null, $escape = true ) {
95
  return $this->get_generated_open_graph_description( $id, $escape );
@@ -102,9 +195,9 @@ class Generate_Description extends Generate {
102
  * @uses $this->generate_description()
103
  * @staticvar array $cache
104
  *
105
- * @param int|null $id The post or term ID. Falls back to queried ID.
106
  * @param bool $escape Whether to escape the description.
107
- * @return string Autogenerated Open Graph Description.
108
  */
109
  public function get_generated_open_graph_description( $id = null, $escape = true ) {
110
 
@@ -125,6 +218,9 @@ class Generate_Description extends Generate {
125
  *
126
  * @since 1.0.0
127
  * @since 2.9.0 Added two filters.
 
 
 
128
  *
129
  * @param string $description The optional description to simply parse.
130
  * @param array $args description args : {
@@ -154,6 +250,8 @@ class Generate_Description extends Generate {
154
  * Filters the description from custom field, if any.
155
  *
156
  * @since 2.9.0
 
 
157
  *
158
  * @param string $description The description.
159
  * @param array $args The description arguments.
@@ -198,6 +296,8 @@ class Generate_Description extends Generate {
198
  * Parses and sanitizes description arguments.
199
  *
200
  * @since 2.5.0
 
 
201
  *
202
  * @param array $args required The passed arguments.
203
  * @param array $defaults The default arguments.
@@ -229,6 +329,8 @@ class Generate_Description extends Generate {
229
  *
230
  * @since 2.5.0
231
  * @since 3.0.4 Added escape parameter.
 
 
232
  *
233
  * @param array $defaults The description defaults.
234
  * @param array $args The input args.
@@ -256,6 +358,8 @@ class Generate_Description extends Generate {
256
  *
257
  * @since 2.6.0
258
  * @since 2.9.2 Now passes args to filter.
 
 
259
  *
260
  * @param array $args required The passed arguments.
261
  * @return array $args parsed args.
@@ -283,6 +387,8 @@ class Generate_Description extends Generate {
283
  * Creates description from custom fields.
284
  *
285
  * @since 2.4.1
 
 
286
  *
287
  * @param array $args description args : {
288
  * @param int $id the term or page id.
@@ -323,7 +429,8 @@ class Generate_Description extends Generate {
323
  * @since 2.6.0
324
  * @since 2.9.0 1. Removed $args['taxonomy'] check.
325
  * 2. Added $this->is_archive() check.
326
- * Use $this->description_from_custom_field() instead.
 
327
  *
328
  * @param array $args Description args.
329
  * @return string The Description
@@ -342,7 +449,8 @@ class Generate_Description extends Generate {
342
  * Fetches Singular Description from custom field.
343
  *
344
  * @since 2.6.0
345
- * Use $this->description_from_custom_field() instead.
 
346
  *
347
  * @param int $id The page ID.
348
  * @return string The Description
@@ -362,7 +470,8 @@ class Generate_Description extends Generate {
362
  * Fetch Archive Description from custom field.
363
  *
364
  * @since 2.6.0
365
- * Use $this->description_from_custom_field() instead.
 
366
  *
367
  * @param array $args
368
  * @return string The Description
@@ -390,11 +499,13 @@ class Generate_Description extends Generate {
390
  * @since 2.3.3
391
  * @since 3.0.0 No longer checks for protected posts.
392
  * Check is moved to $this->generate_the_description().
 
 
393
  *
394
  * @param array $args description args : {
395
  * @param int $id the term or page id.
396
  * @param string $taxonomy taxonomy name.
397
- * @param bool $is_home We're generating for the home page.
398
  * @param bool $get_custom_field Do not fetch custom title when false.
399
  * @param bool $social Generate Social Description when true.
400
  * }
@@ -434,6 +545,8 @@ class Generate_Description extends Generate {
434
  * @since 2.8.0 : The output is always trimmed if $escape is false.
435
  * : The cache will no longer be maintained on previews or search.
436
  * @since 3.0.0 : Now checks for protected posts.
 
 
437
  *
438
  * @param array $args description args : {
439
  * @param int $id the term or page id.
@@ -639,6 +752,8 @@ class Generate_Description extends Generate {
639
  * Generates the home page description.
640
  *
641
  * @since 2.6.0
 
 
642
  *
643
  * @param bool $custom_field whether to check the Custom Field.
644
  * @param bool $escape Whether to escape the output.
@@ -686,7 +801,7 @@ class Generate_Description extends Generate {
686
  * @since 2.6.0
687
  * @since 2.7.0 Removed cache.
688
  * Whether an excerpt is available is no longer part of this check.
689
- *
690
  * @param int $id The current page or post ID.
691
  * @param object|string $term The current Term.
692
  * @return bool Whether to add description additions.
@@ -753,9 +868,12 @@ class Generate_Description extends Generate {
753
  *
754
  * @since 2.6.0
755
  * @since 2.9.2 Added filter.
 
756
  * @staticvar array $title string of titles.
757
  * @staticvar string $on
758
  * @access private
 
 
759
  *
760
  * @param int $id The post or term ID
761
  * @param object|string $term The term object
@@ -773,8 +891,8 @@ class Generate_Description extends Generate {
773
 
774
  if ( $ignore || $this->add_description_additions( $id, $term ) ) {
775
 
776
- if ( ! isset( $title[ $id ] ) ) {
777
- $title[ $id ] = $this->generate_description_title( $id, $term, $this->is_real_front_page() );
778
  }
779
 
780
  if ( $ignore || $this->is_option_checked( 'description_blogname' ) ) {
@@ -795,7 +913,7 @@ class Generate_Description extends Generate {
795
  //* Already cached.
796
  $sep = $this->get_description_separator();
797
  } else {
798
- $title[ $id ] = '';
799
  $on = '';
800
  $blogname = '';
801
  $sep = '';
@@ -814,7 +932,7 @@ class Generate_Description extends Generate {
814
  */
815
  $data = \apply_filters_ref_array( 'the_seo_framework_generated_description_additions', array(
816
  array(
817
- 'title' => $title[ $id ],
818
  'on' => $on,
819
  'blogname' => $blogname,
820
  'sep' => $sep,
@@ -825,7 +943,7 @@ class Generate_Description extends Generate {
825
  ) );
826
  } else {
827
  $data = array(
828
- 'title' => $title[ $id ],
829
  'on' => $on,
830
  'blogname' => $blogname,
831
  'sep' => $sep,
@@ -839,6 +957,8 @@ class Generate_Description extends Generate {
839
  * Generates the Title for description.
840
  *
841
  * @since 2.5.2
 
 
842
  *
843
  * @param int $id The page ID.
844
  * @param object|string $term The term object.
@@ -850,6 +970,8 @@ class Generate_Description extends Generate {
850
  if ( '' === $id )
851
  $id = $this->get_the_real_ID();
852
 
 
 
853
  if ( $page_on_front || $this->is_front_page_by_id( $id ) ) :
854
  $title = $this->get_home_page_tagline();
855
  else :
@@ -894,7 +1016,7 @@ class Generate_Description extends Generate {
894
  * @since 2.2.8
895
  */
896
  /* translators: Front-end output. */
897
- $title = empty( $title ) ? $this->untitled() : trim( $title );
898
 
899
  return $title;
900
  }
39
  parent::__construct();
40
  }
41
 
42
+ /**
43
+ * Returns the meta description from custom fields. Falls back to autogenerated description.
44
+ *
45
+ * @since 3.0.6
46
+ * @uses $this->get_description_from_custom_field()
47
+ * @uses $this->get_generated_description()
48
+ *
49
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
50
+ * @param bool $escape Whether to escape the description.
51
+ * @return string The real description output.
52
+ */
53
+ public function get_description( $id = null, $escape = true ) {
54
+
55
+ if ( is_null( $id ) )
56
+ $id = $this->get_the_real_ID();
57
+
58
+ $desc = $this->get_description_from_custom_field( $id )
59
+ ?: $this->get_generated_description( $id, false );
60
+
61
+ return $escape ? $this->escape_description( $desc ) : $desc;
62
+ }
63
+
64
+ /**
65
+ * Returns the custom user-inputted description.
66
+ *
67
+ * @since 3.0.6
68
+ * @uses $this->get_generated_open_graph_description()
69
+ *
70
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
71
+ * @param bool $escape Whether to escape the description.
72
+ * @return string The custom field description.
73
+ */
74
+ public function get_description_from_custom_field( $id = null, $escape = true ) {
75
+
76
+ if ( is_null( $id ) )
77
+ $id = $this->get_the_real_ID();
78
+
79
+ $desc = '';
80
+
81
+ if ( $this->is_front_page_by_id( $id ) ) {
82
+ $desc = $this->get_option( 'homepage_description' );
83
+ }
84
+ if ( ! $desc ) {
85
+ if ( $this->is_singular( $id ) ) {
86
+ $desc = $this->get_custom_field( '_genesis_description', $id );
87
+ } elseif ( $id ) {
88
+ $data = $this->get_term_meta( $id );
89
+ $desc = ! empty( $data['description'] ) ? $data['description'] : '';
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Applies filters 'the_seo_framework_custom_field_description' : string
95
+ *
96
+ * Filters the description from custom field, if any.
97
+ *
98
+ * @since 2.9.0
99
+ * @since 3.0.6 1. Duplicated from $this->generate_description() (to be deprecated)
100
+ * 2. Removed all arguments but the 'id' argument.
101
+ *
102
+ * @param string $desc The description.
103
+ * @param array $args The description arguments.
104
+ */
105
+ $desc = (string) \apply_filters( 'the_seo_framework_custom_field_description', $desc, array( 'id' => $id ) );
106
+
107
+ return $escape ? $this->escape_description( $desc ) : $desc;
108
+ }
109
+
110
  /**
111
  * Returns the Twitter meta description. Falls back to Open Graph description.
112
  *
113
  * @since 3.0.4
114
  * @uses $this->get_open_graph_description()
115
  *
116
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
117
  * @param bool $escape Whether to escape the description.
118
+ * @return string The real Twitter description output.
119
  */
120
  public function get_twitter_description( $id = null, $escape = true ) {
121
 
134
  * @since 3.0.4
135
  * @uses $this->get_generated_open_graph_description()
136
  *
137
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
138
  * @param bool $escape Whether to escape the description.
139
+ * @return string The real Open Graph description output.
140
  */
141
  public function get_open_graph_description( $id = null, $escape = true ) {
142
 
149
  return $escape ? $this->escape_description( $desc ) : $desc;
150
  }
151
 
152
+ /**
153
+ * Returns the autogenerated meta description.
154
+ *
155
+ * @since 3.0.6
156
+ * @uses $this->generate_description()
157
+ * @staticvar array $cache
158
+ *
159
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
160
+ * @param bool $escape Whether to escape the description.
161
+ * @return string The generated description output.
162
+ */
163
+ public function get_generated_description( $id = null, $escape = true ) {
164
+
165
+ if ( is_null( $id ) )
166
+ $id = $this->get_the_real_ID();
167
+
168
+ static $cache = array();
169
+
170
+ $desc = isset( $cache[ $id ] )
171
+ ? $cache[ $id ]
172
+ : $cache[ $id ] = $this->generate_description( '', array( 'id' => $id, 'social' => false, 'get_custom_field' => false, 'escape' => false ) );
173
+
174
+ return $escape ? $this->escape_description( $desc ) : $desc;
175
+ }
176
+
177
  /**
178
  * Returns the autogenerated open graph meta description. Falls back to meta description.
179
  *
180
  * @since 3.0.4
181
  * @uses $this->get_generated_open_graph_description()
182
  *
183
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
184
  * @param bool $escape Whether to escape the description.
185
+ * @return string The generated Twitter description output.
186
  */
187
  public function get_generated_twitter_description( $id = null, $escape = true ) {
188
  return $this->get_generated_open_graph_description( $id, $escape );
195
  * @uses $this->generate_description()
196
  * @staticvar array $cache
197
  *
198
+ * @param int|null $id The post or term ID. Falls back to queried ID if null.
199
  * @param bool $escape Whether to escape the description.
200
+ * @return string The generated Open Graph description output.
201
  */
202
  public function get_generated_open_graph_description( $id = null, $escape = true ) {
203
 
218
  *
219
  * @since 1.0.0
220
  * @since 2.9.0 Added two filters.
221
+ * @since 3.0.6 Silently deprecated.
222
+ * @deprecated Use `get_description()` instead.
223
+ * @deprecated Use `get_generated_description()` instead.
224
  *
225
  * @param string $description The optional description to simply parse.
226
  * @param array $args description args : {
250
  * Filters the description from custom field, if any.
251
  *
252
  * @since 2.9.0
253
+ * NOTE: MOVED!!
254
+ * @see get_description_from_custom_field()
255
  *
256
  * @param string $description The description.
257
  * @param array $args The description arguments.
296
  * Parses and sanitizes description arguments.
297
  *
298
  * @since 2.5.0
299
+ * @since 3.0.6 Silently deprecated.
300
+ * @deprecated
301
  *
302
  * @param array $args required The passed arguments.
303
  * @param array $defaults The default arguments.
329
  *
330
  * @since 2.5.0
331
  * @since 3.0.4 Added escape parameter.
332
+ * @since 3.0.6 Silently deprecated.
333
+ * @deprecated
334
  *
335
  * @param array $defaults The description defaults.
336
  * @param array $args The input args.
358
  *
359
  * @since 2.6.0
360
  * @since 2.9.2 Now passes args to filter.
361
+ * @since 3.0.6 Silently deprecated.
362
+ * @deprecated
363
  *
364
  * @param array $args required The passed arguments.
365
  * @return array $args parsed args.
387
  * Creates description from custom fields.
388
  *
389
  * @since 2.4.1
390
+ * @since 3.0.6 Silently deprecated.
391
+ * @deprecated Use `get_description_from_custom_field()` instead.
392
  *
393
  * @param array $args description args : {
394
  * @param int $id the term or page id.
429
  * @since 2.6.0
430
  * @since 2.9.0 1. Removed $args['taxonomy'] check.
431
  * 2. Added $this->is_archive() check.
432
+ * @since 3.0.6 Silently deprecated.
433
+ * @deprecated Use `get_description_from_custom_field()` instead.
434
  *
435
  * @param array $args Description args.
436
  * @return string The Description
449
  * Fetches Singular Description from custom field.
450
  *
451
  * @since 2.6.0
452
+ * @since 3.0.6 Silently deprecated.
453
+ * @deprecated Use `get_description_from_custom_field()` instead.
454
  *
455
  * @param int $id The page ID.
456
  * @return string The Description
470
  * Fetch Archive Description from custom field.
471
  *
472
  * @since 2.6.0
473
+ * @since 3.0.6 Silently deprecated.
474
+ * @deprecated Use `get_description_from_custom_field()` instead.
475
  *
476
  * @param array $args
477
  * @return string The Description
499
  * @since 2.3.3
500
  * @since 3.0.0 No longer checks for protected posts.
501
  * Check is moved to $this->generate_the_description().
502
+ * @since 3.0.6 Silently deprecated.
503
+ * @deprecated Use `get_generated_description()` instead.
504
  *
505
  * @param array $args description args : {
506
  * @param int $id the term or page id.
507
  * @param string $taxonomy taxonomy name.
508
+ * @param bool $is_home Whether we're generating for the home page.
509
  * @param bool $get_custom_field Do not fetch custom title when false.
510
  * @param bool $social Generate Social Description when true.
511
  * }
545
  * @since 2.8.0 : The output is always trimmed if $escape is false.
546
  * : The cache will no longer be maintained on previews or search.
547
  * @since 3.0.0 : Now checks for protected posts.
548
+ * @since 3.0.6 Silently deprecated.
549
+ * @deprecated Use `get_generated_description()` instead.
550
  *
551
  * @param array $args description args : {
552
  * @param int $id the term or page id.
752
  * Generates the home page description.
753
  *
754
  * @since 2.6.0
755
+ * @since 3.0.6 Silently deprecated.
756
+ * @deprecated Use `generate_description()` in combination with `get_custom_field( '_genesis_description' )` instead.
757
  *
758
  * @param bool $custom_field whether to check the Custom Field.
759
  * @param bool $escape Whether to escape the output.
801
  * @since 2.6.0
802
  * @since 2.7.0 Removed cache.
803
  * Whether an excerpt is available is no longer part of this check.
804
+
805
  * @param int $id The current page or post ID.
806
  * @param object|string $term The current Term.
807
  * @return bool Whether to add description additions.
868
  *
869
  * @since 2.6.0
870
  * @since 2.9.2 Added filter.
871
+ * @since 3.0.6 The $ignore parameter is now considered in caching.
872
  * @staticvar array $title string of titles.
873
  * @staticvar string $on
874
  * @access private
875
+ * @TODO deprecate and rewrite -- or completely remove.
876
+ * @see https://github.com/sybrew/the-seo-framework/issues/282
877
  *
878
  * @param int $id The post or term ID
879
  * @param object|string $term The term object
891
 
892
  if ( $ignore || $this->add_description_additions( $id, $term ) ) {
893
 
894
+ if ( ! isset( $title[ $id ][ $ignore ] ) ) {
895
+ $title[ $id ][ $ignore ] = $this->generate_description_title( $id, $term, $this->is_real_front_page() );
896
  }
897
 
898
  if ( $ignore || $this->is_option_checked( 'description_blogname' ) ) {
913
  //* Already cached.
914
  $sep = $this->get_description_separator();
915
  } else {
916
+ $title[ $id ][ $ignore ] = '';
917
  $on = '';
918
  $blogname = '';
919
  $sep = '';
932
  */
933
  $data = \apply_filters_ref_array( 'the_seo_framework_generated_description_additions', array(
934
  array(
935
+ 'title' => $title[ $id ][ $ignore ],
936
  'on' => $on,
937
  'blogname' => $blogname,
938
  'sep' => $sep,
943
  ) );
944
  } else {
945
  $data = array(
946
+ 'title' => $title[ $id ][ $ignore ],
947
  'on' => $on,
948
  'blogname' => $blogname,
949
  'sep' => $sep,
957
  * Generates the Title for description.
958
  *
959
  * @since 2.5.2
960
+ * @since 3.0.6 Silently deprecated.
961
+ * @deprecated
962
  *
963
  * @param int $id The page ID.
964
  * @param object|string $term The term object.
970
  if ( '' === $id )
971
  $id = $this->get_the_real_ID();
972
 
973
+ $title = '';
974
+
975
  if ( $page_on_front || $this->is_front_page_by_id( $id ) ) :
976
  $title = $this->get_home_page_tagline();
977
  else :
1016
  * @since 2.2.8
1017
  */
1018
  /* translators: Front-end output. */
1019
+ $title = trim( $title ) ?: $this->untitled();
1020
 
1021
  return $title;
1022
  }
inc/classes/generate-image.class.php CHANGED
@@ -132,6 +132,7 @@ class Generate_Image extends Generate_Url {
132
  * Returns social image URL and sets $this->image_dimensions.
133
  *
134
  * @since 2.9.0
 
135
  *
136
  * @todo listen to attached images within post.
137
  * @todo listen to archive images.
@@ -166,11 +167,16 @@ class Generate_Image extends Generate_Url {
166
  goto end;
167
  }
168
 
169
- //* 3. Fetch image from featured.
170
  if ( $all_allowed || false === in_array( 'featured', $args['disallowed'], true ) ) {
171
  if ( $image = $this->get_social_image_url_from_post_thumbnail( $args['post_id'], $args, true ) )
172
  goto end;
173
  }
 
 
 
 
 
174
  }
175
 
176
  if ( $args['skip_fallback'] )
@@ -273,11 +279,16 @@ class Generate_Image extends Generate_Url {
273
  * @param mixed $size The image size
274
  * @param bool $icon Fetch Image icon
275
  * @param bool 'skip_fallback' Whether to skip fallback images.
276
- * @param array $disallowed Disallowed image types : {
277
  * array (
278
- * string 'featured'
279
- * string 'header'
280
- * string 'icon'
 
 
 
 
 
281
  * )
282
  * }
283
  * @param bool 'escape' Whether to escape output.
@@ -481,6 +492,32 @@ class Generate_Image extends Generate_Url {
481
  return $src;
482
  }
483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
  /**
485
  * Fetches images id's from WooCommerce gallery
486
  *
132
  * Returns social image URL and sets $this->image_dimensions.
133
  *
134
  * @since 2.9.0
135
+ * @since 3.0.6 Added attachment page compatibility.
136
  *
137
  * @todo listen to attached images within post.
138
  * @todo listen to archive images.
167
  goto end;
168
  }
169
 
170
+ //* 3.a. Fetch image from featured.
171
  if ( $all_allowed || false === in_array( 'featured', $args['disallowed'], true ) ) {
172
  if ( $image = $this->get_social_image_url_from_post_thumbnail( $args['post_id'], $args, true ) )
173
  goto end;
174
  }
175
+ //* 3.b. Fetch image from attachment page.
176
+ if ( $all_allowed || false === in_array( 'attachment', $args['disallowed'], true ) ) {
177
+ if ( $image = $this->get_social_image_url_from_attachment( $args['post_id'], $args, true ) )
178
+ goto end;
179
+ }
180
  }
181
 
182
  if ( $args['skip_fallback'] )
279
  * @param mixed $size The image size
280
  * @param bool $icon Fetch Image icon
281
  * @param bool 'skip_fallback' Whether to skip fallback images.
282
+ * @param array $disallowed Disallowed image types : Allowed values {
283
  * array (
284
+ * 'homemeta',
285
+ * 'postmeta',
286
+ * 'featured',
287
+ * 'attachment',
288
+ * 'option',
289
+ * 'header',
290
+ * 'logo',
291
+ * 'icon',
292
  * )
293
  * }
294
  * @param bool 'escape' Whether to escape output.
492
  return $src;
493
  }
494
 
495
+ /**
496
+ * Returns the social image URL from an attachment page.
497
+ *
498
+ * @since 3.0.6
499
+ *
500
+ * @param int $id The post ID. Required.
501
+ * @param array $args The image args.
502
+ * @param bool $set_og_dimensions Whether to set Open Graph image dimensions.
503
+ * @return string The attachment URL.
504
+ */
505
+ public function get_social_image_url_from_attachment( $id, $args = array(), $set_og_dimensions = false ) {
506
+
507
+ if ( ! \wp_attachment_is_image( $id ) )
508
+ return '';
509
+
510
+ $args = $this->reparse_image_args( $args );
511
+ $args['get_the_real_ID'] = true;
512
+
513
+ $src = $this->parse_og_image( $id, $args, $set_og_dimensions );
514
+
515
+ if ( $src && $this->matches_this_domain( $src ) )
516
+ $src = $this->set_preferred_url_scheme( $src );
517
+
518
+ return $src;
519
+ }
520
+
521
  /**
522
  * Fetches images id's from WooCommerce gallery
523
  *
inc/classes/generate.class.php CHANGED
@@ -395,7 +395,7 @@ class Generate extends User_Data {
395
  if ( isset( $cache ) )
396
  return $cache;
397
 
398
- if ( ! $this->description_from_cache( true ) ) {
399
  $retval = array();
400
  } elseif ( ! $this->title_from_cache( '', '', '', true ) ) {
401
  $retval = array();
395
  if ( isset( $cache ) )
396
  return $cache;
397
 
398
+ if ( ! $this->get_twitter_description() ) {
399
  $retval = array();
400
  } elseif ( ! $this->title_from_cache( '', '', '', true ) ) {
401
  $retval = array();
inc/classes/init.class.php CHANGED
@@ -181,6 +181,7 @@ class Init extends Query {
181
 
182
  //* Save post data.
183
  \add_action( 'save_post', array( $this, 'inpost_seo_save' ), 1, 2 );
 
184
  \add_action( 'save_post', array( $this, '_save_inpost_primary_term' ), 1, 2 );
185
 
186
  //* Enqueues admin scripts.
@@ -557,8 +558,6 @@ class Init extends Query {
557
  return;
558
  }
559
 
560
- $allow_external = $this->allow_external_redirect();
561
-
562
  /**
563
  * Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
564
  *
@@ -571,7 +570,7 @@ class Init extends Query {
571
  if ( $redirect_type > 399 || $redirect_type < 300 )
572
  $this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
573
 
574
- if ( false === $allow_external ) {
575
  //= Only HTTP/HTTPS and home URLs are allowed.
576
  $path = $this->set_url_scheme( $url, 'relative' );
577
  $url = \trailingslashit( $this->get_home_host() ) . ltrim( $path, ' /' );
@@ -625,7 +624,7 @@ class Init extends Query {
625
 
626
  if ( $this->is_subdirectory_installation() || $home_path ) {
627
  $output .= '# This is an invalid robots.txt location.' . "\r\n";
628
- $output .= '# Please visit: ' . \esc_url( trailingslashit( $this->set_preferred_url_scheme( $this->get_home_host() ) ) . 'robots.txt' ) . "\r\n";
629
  $output .= "\r\n";
630
  }
631
 
181
 
182
  //* Save post data.
183
  \add_action( 'save_post', array( $this, 'inpost_seo_save' ), 1, 2 );
184
+ \add_action( 'edit_attachment', array( $this, 'inattachment_seo_save' ), 1 );
185
  \add_action( 'save_post', array( $this, '_save_inpost_primary_term' ), 1, 2 );
186
 
187
  //* Enqueues admin scripts.
558
  return;
559
  }
560
 
 
 
561
  /**
562
  * Applies filters 'the_seo_framework_redirect_status_code' : Absolute integer.
563
  *
570
  if ( $redirect_type > 399 || $redirect_type < 300 )
571
  $this->_doing_it_wrong( __METHOD__, 'You should use 3xx HTTP Status Codes. Recommended 301 and 302.', '2.8.0' );
572
 
573
+ if ( ! $this->allow_external_redirect() ) {
574
  //= Only HTTP/HTTPS and home URLs are allowed.
575
  $path = $this->set_url_scheme( $url, 'relative' );
576
  $url = \trailingslashit( $this->get_home_host() ) . ltrim( $path, ' /' );
624
 
625
  if ( $this->is_subdirectory_installation() || $home_path ) {
626
  $output .= '# This is an invalid robots.txt location.' . "\r\n";
627
+ $output .= '# Please visit: ' . \esc_url( \trailingslashit( $this->set_preferred_url_scheme( $this->get_home_host() ) ) . 'robots.txt' ) . "\r\n";
628
  $output .= "\r\n";
629
  }
630
 
inc/classes/inpost.class.php CHANGED
@@ -457,11 +457,12 @@ class Inpost extends Profile {
457
  'get_custom_field' => false,
458
  );
459
 
460
- $generated_description_args = array(
461
- 'id' => $post_id,
462
- 'is_home' => true,
463
- 'get_custom_field' => true,
464
- );
 
465
  } elseif ( $this->is_blog_page( $post_id ) ) {
466
  //* Page for posts.
467
  $generated_doctitle_args = array(
@@ -469,24 +470,16 @@ class Inpost extends Profile {
469
  'meta' => true,
470
  'get_custom_field' => false,
471
  );
472
-
473
- $generated_description_args = array(
474
- 'id' => $post_id,
475
- 'page_for_posts' => true,
476
- );
477
  } else {
478
  $generated_doctitle_args = array(
479
  'placeholder' => true,
480
  'meta' => true,
481
  'get_custom_field' => false,
482
  );
483
-
484
- $generated_description_args = array(
485
- 'id' => $post_id,
486
- );
487
  }
488
  $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
489
- $generated_description = $this->generate_description( '', $generated_description_args );
490
 
491
  /**
492
  * Start Title vars
@@ -523,30 +516,6 @@ class Inpost extends Profile {
523
  }
524
  }
525
 
526
- /**
527
- * Start Description vars
528
- */
529
-
530
- //* Fetch description from option.
531
- $description = $this->get_custom_field( '_genesis_description' );
532
-
533
- /**
534
- * Calculate current description length
535
- *
536
- * Reworked.
537
- * @since 2.3.4
538
- */
539
- if ( $is_static_frontpage ) {
540
- //* The homepage description takes precedence.
541
- if ( $description ) {
542
- $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $description;
543
- } else {
544
- $desc_len_pre = $this->get_option( 'homepage_description' ) ?: $generated_description;
545
- }
546
- } else {
547
- $desc_len_pre = $description ?: $generated_description;
548
- }
549
-
550
  /**
551
  * Convert to what Google outputs.
552
  *
@@ -554,7 +523,7 @@ class Inpost extends Profile {
554
  * @since 2.3.4
555
  */
556
  $tit_len_parsed = html_entity_decode( $tit_len_pre );
557
- $desc_len_parsed = html_entity_decode( $desc_len_pre );
558
 
559
  /**
560
  * Generate static placeholder for when title or description is emptied
457
  'get_custom_field' => false,
458
  );
459
 
460
+ $_home_desc_from_option = $this->get_option( 'homepage_description' );
461
+ if ( $_home_desc_from_option ) {
462
+ $generated_description = $this->escape_description( $_home_desc_from_option );
463
+ } else {
464
+ $generated_description = $this->get_generated_description( $post_id );
465
+ }
466
  } elseif ( $this->is_blog_page( $post_id ) ) {
467
  //* Page for posts.
468
  $generated_doctitle_args = array(
470
  'meta' => true,
471
  'get_custom_field' => false,
472
  );
473
+ $generated_description = $this->get_generated_description( $post_id );
 
 
 
 
474
  } else {
475
  $generated_doctitle_args = array(
476
  'placeholder' => true,
477
  'meta' => true,
478
  'get_custom_field' => false,
479
  );
480
+ $generated_description = $this->get_generated_description( $post_id );
 
 
 
481
  }
482
  $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
 
483
 
484
  /**
485
  * Start Title vars
516
  }
517
  }
518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  /**
520
  * Convert to what Google outputs.
521
  *
523
  * @since 2.3.4
524
  */
525
  $tit_len_parsed = html_entity_decode( $tit_len_pre );
526
+ $desc_len_parsed = html_entity_decode( $this->get_description( $post_id ) );
527
 
528
  /**
529
  * Generate static placeholder for when title or description is emptied
inc/classes/load.class.php CHANGED
@@ -58,11 +58,8 @@ final class Load extends Feed implements Debug_Interface {
58
 
59
  static $count = 0;
60
 
61
- if ( $count > 0 ) {
62
  return null;
63
- }
64
-
65
- $count++;
66
 
67
  //* Setup debug vars before initializing parents.
68
  $this->init_debug_vars();
58
 
59
  static $count = 0;
60
 
61
+ if ( $count++ )
62
  return null;
 
 
 
63
 
64
  //* Setup debug vars before initializing parents.
65
  $this->init_debug_vars();
inc/classes/post-data.class.php CHANGED
@@ -79,7 +79,23 @@ class Post_Data extends Detect {
79
  }
80
 
81
  /**
82
- * Save the SEO settings when we save a post or page.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  * Some values get sanitized, the rest are pulled from identically named subkeys in the $_POST['autodescription'] array.
84
  *
85
  * @since 2.0.0
@@ -142,7 +158,7 @@ class Post_Data extends Detect {
142
  * Also, they will only cause bugs.
143
  * Query parameters are also only used when no pretty permalinks are used. Which is bad.
144
  */
145
- $data[ $key ] = $this->s_url( $value );
146
  continue 2;
147
 
148
  case '_social_image_id' :
79
  }
80
 
81
  /**
82
+ * Saves the SEO settings when we save an attachment.
83
+ *
84
+ * This is a passthrough method for `inpost_seo_save()`.
85
+ * Sanity check is handled at `save_custom_fields()`, which `inpost_seo_save()` uses.
86
+ *
87
+ * @since 3.0.6
88
+ * @uses $this->inpost_seo_save()
89
+ *
90
+ * @param integer $post_id Post ID.
91
+ * @return void
92
+ */
93
+ public function inattachment_seo_save( $post_id ) {
94
+ $this->inpost_seo_save( $post_id, \get_post( $post_id ) );
95
+ }
96
+
97
+ /**
98
+ * Saves the SEO settings when we save a post or page.
99
  * Some values get sanitized, the rest are pulled from identically named subkeys in the $_POST['autodescription'] array.
100
  *
101
  * @since 2.0.0
158
  * Also, they will only cause bugs.
159
  * Query parameters are also only used when no pretty permalinks are used. Which is bad.
160
  */
161
+ $data[ $key ] = $this->s_url_query( $value );
162
  continue 2;
163
 
164
  case '_social_image_id' :
inc/classes/render.class.php CHANGED
@@ -101,6 +101,8 @@ class Render extends Admin_Init {
101
  * Must be called inside the loop
102
  *
103
  * @since 2.2.2
 
 
104
  * @staticvar array $description_cache
105
  *
106
  * @return string The description
@@ -203,7 +205,8 @@ class Render extends Admin_Init {
203
  * Renders the description meta tag.
204
  *
205
  * @since 1.3.0
206
- * @uses $this->description_from_cache()
 
207
  * @uses $this->detect_seo_plugins()
208
  *
209
  * @return string The description meta tag.
@@ -218,7 +221,7 @@ class Render extends Admin_Init {
218
  * @since 2.3.0
219
  * @since 2.7.0 : Added output within filter.
220
  */
221
- $description = (string) \apply_filters( 'the_seo_framework_description_output', $this->description_from_cache(), $this->get_the_real_ID() );
222
 
223
  if ( $description )
224
  return '<meta name="description" content="' . \esc_attr( $description ) . '" />' . "\r\n";
101
  * Must be called inside the loop
102
  *
103
  * @since 2.2.2
104
+ * @deprecated
105
+ * @since 3.0.6 Silently deprecated.
106
  * @staticvar array $description_cache
107
  *
108
  * @return string The description
205
  * Renders the description meta tag.
206
  *
207
  * @since 1.3.0
208
+ * @since 3.0.6 No longer uses $this->description_from_cache()
209
+ * @uses $this->get_description()
210
  * @uses $this->detect_seo_plugins()
211
  *
212
  * @return string The description meta tag.
221
  * @since 2.3.0
222
  * @since 2.7.0 : Added output within filter.
223
  */
224
+ $description = (string) \apply_filters( 'the_seo_framework_description_output', $this->get_description(), $this->get_the_real_ID() );
225
 
226
  if ( $description )
227
  return '<meta name="description" content="' . \esc_attr( $description ) . '" />' . "\r\n";
inc/classes/sanitize.class.php CHANGED
@@ -82,6 +82,7 @@ class Sanitize extends Admin_Pages {
82
  * Handles settings field update POST actions.
83
  *
84
  * @since 2.8.0
 
85
  *
86
  * @return void Early if nonce failed.
87
  */
@@ -101,6 +102,19 @@ class Sanitize extends Admin_Pages {
101
  //* Flush transients after options have changed.
102
  \add_action( "update_option_{$this->settings_field}", array( $this, 'delete_main_cache' ) );
103
  \add_action( "update_option_{$this->settings_field}", array( $this, 'reinitialize_rewrite' ), 11 );
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
105
 
106
  /**
@@ -1014,7 +1028,7 @@ class Sanitize extends Admin_Pages {
1014
  }
1015
 
1016
  /**
1017
- * Makes URLs safe.
1018
  *
1019
  * @since 2.2.2
1020
  * @since 2.8.0 Method is now public.
@@ -1035,7 +1049,7 @@ class Sanitize extends Admin_Pages {
1035
  }
1036
 
1037
  /**
1038
- * Makes URLs safe and removes query args.
1039
  *
1040
  * @since 2.2.8
1041
  * @since 2.8.0 Method is now public.
@@ -1105,10 +1119,10 @@ class Sanitize extends Admin_Pages {
1105
  *
1106
  * @since 2.2.2
1107
  * @since 2.8.0 Method is now public.
1108
- * @since 3.0.0 Now removed '@' from the URL path.
1109
  *
1110
- * @param string $new_value String with potentially wrong Twitter username.
1111
- * @return string String with 'correct' Twitter username
1112
  */
1113
  public function s_facebook_profile( $new_value ) {
1114
 
@@ -1120,7 +1134,21 @@ class Sanitize extends Admin_Pages {
1120
  $link = 'https://www.facebook.com/' . $this->s_relative_url( $link );
1121
  $link = rtrim( $link, ' /' );
1122
 
1123
- return $this->s_url( $link );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1124
  }
1125
 
1126
  /**
@@ -1172,6 +1200,7 @@ class Sanitize extends Admin_Pages {
1172
  *
1173
  * @since 2.2.4
1174
  * @since 2.8.0 Method is now public.
 
1175
  *
1176
  * @param string $new_value String with potentially unwanted redirect URL.
1177
  * @return string The Sanitized Redirect URL
@@ -1182,24 +1211,22 @@ class Sanitize extends Admin_Pages {
1182
 
1183
  if ( $url ) :
1184
 
1185
- $allow_external = $this->allow_external_redirect();
1186
-
1187
  /**
1188
  * Sanitize the redirect URL to only a relative link and removes first slash
1189
  * @requires WP 4.1.0 and up to prevent adding upon itself.
1190
  */
1191
- if ( ! $allow_external )
1192
  $url = $this->s_relative_url( $url );
1193
 
1194
  //* URL pattern excluding path.
1195
- $pattern = '/'
1196
- . '((((http)(s)?)?)\:)?' // 1: maybe http: https:
1197
- . '(\/\/)?' // 2: maybe slash slash
1198
- . '((www.)?)' // 3: maybe www.
1199
- . '(.*\.[a-zA-Z0-9]*)' // 4: any legal domain with tld
1200
- . '(?:\/)?' // 5: trailing slash
1201
- . '/'
1202
- ;
1203
 
1204
  //* If link is relative, make it full again
1205
  if ( ! preg_match( $pattern, $url ) ) {
@@ -1215,11 +1242,11 @@ class Sanitize extends Admin_Pages {
1215
  * @param array : { 'url' => The full URL built from $path, 'scheme' => The preferred scheme }
1216
  * @param string $path the URL path.
1217
  */
1218
- $filter = (array) \apply_filters( 'the_seo_framework_sanitize_redirect_args', array(), $path );
1219
 
1220
- if ( $filter ) {
1221
- $url = $filter['url'];
1222
- $scheme = $filter['scheme'];
1223
  } else {
1224
  $url = \trailingslashit( $this->get_homepage_permalink() ) . ltrim( $path, ' /' );
1225
  $scheme = $this->is_ssl() ? 'https' : 'http';
@@ -1236,14 +1263,15 @@ class Sanitize extends Admin_Pages {
1236
  * Applies filters 'the_seo_framework_301_noqueries'
1237
  *
1238
  * @since 2.5.0
 
1239
  * @param bool $noqueries
1240
  */
1241
- $noqueries = (bool) \apply_filters( 'the_seo_framework_301_noqueries', true );
1242
 
1243
  /**
1244
  * Remove queries from the URL
1245
  *
1246
- * Returns plain Home URL if $allow_external is set to false and only a query has been supplied
1247
  * But that's okay. The URL was rogue anyway :)
1248
  */
1249
  if ( $noqueries ) {
@@ -1258,7 +1286,7 @@ class Sanitize extends Admin_Pages {
1258
  /**
1259
  * Allow query string parameters. XSS safe.
1260
  */
1261
- $new_value = \esc_url_raw( $url );
1262
  }
1263
 
1264
  //* Save url
82
  * Handles settings field update POST actions.
83
  *
84
  * @since 2.8.0
85
+ * @since 3.0.6 Now updates db version, too.
86
  *
87
  * @return void Early if nonce failed.
88
  */
102
  //* Flush transients after options have changed.
103
  \add_action( "update_option_{$this->settings_field}", array( $this, 'delete_main_cache' ) );
104
  \add_action( "update_option_{$this->settings_field}", array( $this, 'reinitialize_rewrite' ), 11 );
105
+ \add_action( "update_option_{$this->settings_field}", array( $this, 'update_db_version' ), 12 );
106
+ }
107
+
108
+ /**
109
+ * Updates the database version to the defined one.
110
+ *
111
+ * This prevents errors when users go back to an earlier version, where options
112
+ * might be different from a future one.
113
+ *
114
+ * @since 3.0.6
115
+ */
116
+ public function update_db_version() {
117
+ \update_option( 'the_seo_framework_upgraded_db_version', THE_SEO_FRAMEWORK_DB_VERSION );
118
  }
119
 
120
  /**
1028
  }
1029
 
1030
  /**
1031
+ * Makes URLs safe and removes query args.
1032
  *
1033
  * @since 2.2.2
1034
  * @since 2.8.0 Method is now public.
1049
  }
1050
 
1051
  /**
1052
+ * Makes URLs safe, maintaining queries.
1053
  *
1054
  * @since 2.2.8
1055
  * @since 2.8.0 Method is now public.
1119
  *
1120
  * @since 2.2.2
1121
  * @since 2.8.0 Method is now public.
1122
+ * @since 3.0.6 Now allows a sole query argument when profile.php is used.
1123
  *
1124
+ * @param string $new_value String with potentially wrong Facebook profile URL.
1125
+ * @return string String with 'correct' Facebook profile URL.
1126
  */
1127
  public function s_facebook_profile( $new_value ) {
1128
 
1134
  $link = 'https://www.facebook.com/' . $this->s_relative_url( $link );
1135
  $link = rtrim( $link, ' /' );
1136
 
1137
+ if ( strpos( $link, 'profile.php' ) ) {
1138
+ //= Gets query parameters.
1139
+ $q = strtok( substr( $link, strpos( $link, '?' ) ), '?' );
1140
+ parse_str( $q, $r );
1141
+ if ( isset( $r['id'] ) ) {
1142
+ $link = 'https://www.facebook.com/profile.php?id=' . \absint( $r['id'] );
1143
+ $link = $this->s_url_query( $link );
1144
+ } else {
1145
+ $link = '';
1146
+ }
1147
+ } else {
1148
+ $link = $this->s_url( $link );
1149
+ }
1150
+
1151
+ return $link;
1152
  }
1153
 
1154
  /**
1200
  *
1201
  * @since 2.2.4
1202
  * @since 2.8.0 Method is now public.
1203
+ * @since 3.0.6 Noqueries is now disabled by default.
1204
  *
1205
  * @param string $new_value String with potentially unwanted redirect URL.
1206
  * @return string The Sanitized Redirect URL
1211
 
1212
  if ( $url ) :
1213
 
 
 
1214
  /**
1215
  * Sanitize the redirect URL to only a relative link and removes first slash
1216
  * @requires WP 4.1.0 and up to prevent adding upon itself.
1217
  */
1218
+ if ( ! $this->allow_external_redirect() )
1219
  $url = $this->s_relative_url( $url );
1220
 
1221
  //* URL pattern excluding path.
1222
+ $pattern = '/'
1223
+ . '((((http)(s)?)?)\:)?' // 1: maybe http: https:
1224
+ . '(\/\/)?' // 2: maybe slash slash
1225
+ . '((www.)?)' // 3: maybe www.
1226
+ . '(.*\.[a-zA-Z0-9]*)' // 4: any legal domain with tld
1227
+ . '(?:\/)?' // 5: maybe trailing slash
1228
+ . '/'
1229
+ ;
1230
 
1231
  //* If link is relative, make it full again
1232
  if ( ! preg_match( $pattern, $url ) ) {
1242
  * @param array : { 'url' => The full URL built from $path, 'scheme' => The preferred scheme }
1243
  * @param string $path the URL path.
1244
  */
1245
+ $custom_sanitize = (array) \apply_filters( 'the_seo_framework_sanitize_redirect_args', array(), $path );
1246
 
1247
+ if ( $custom_sanitize ) {
1248
+ $url = $custom_sanitize['url'];
1249
+ $scheme = $custom_sanitize['scheme'];
1250
  } else {
1251
  $url = \trailingslashit( $this->get_homepage_permalink() ) . ltrim( $path, ' /' );
1252
  $scheme = $this->is_ssl() ? 'https' : 'http';
1263
  * Applies filters 'the_seo_framework_301_noqueries'
1264
  *
1265
  * @since 2.5.0
1266
+ * @since 3.0.6 Now false by default.
1267
  * @param bool $noqueries
1268
  */
1269
+ $noqueries = (bool) \apply_filters( 'the_seo_framework_301_noqueries', false );
1270
 
1271
  /**
1272
  * Remove queries from the URL
1273
  *
1274
+ * Returns plain Home URL if $this->allow_external_redirect() is set to false and only a query has been supplied
1275
  * But that's okay. The URL was rogue anyway :)
1276
  */
1277
  if ( $noqueries ) {
1286
  /**
1287
  * Allow query string parameters. XSS safe.
1288
  */
1289
+ $new_value = $this->s_url_query( $url );
1290
  }
1291
 
1292
  //* Save url
inc/classes/sitemaps.class.php CHANGED
@@ -236,7 +236,6 @@ class Sitemaps extends Metaboxes {
236
  }
237
 
238
  $this->the_seo_framework_debug and $freed_memory = $memory - memory_get_usage();
239
-
240
  }
241
 
242
  /**
@@ -513,6 +512,7 @@ class Sitemaps extends Metaboxes {
513
  * Create sitemap.xml content transient.
514
  *
515
  * @since 2.6.0
 
516
  *
517
  * @param string|bool $content required The sitemap transient content.
518
  * @return string The sitemap content.
@@ -529,7 +529,8 @@ class Sitemaps extends Metaboxes {
529
  */
530
  $expiration = WEEK_IN_SECONDS;
531
 
532
- $this->set_transient( $this->sitemap_transient, $sitemap_content, $expiration );
 
533
  }
534
 
535
  return $sitemap_content;
@@ -608,7 +609,7 @@ class Sitemaps extends Metaboxes {
608
  'has_password' => false,
609
  'fields' => 'ids',
610
  'cache_results' => false,
611
- 'suppress_filters' => true,
612
  'no_found_rows' => true,
613
  );
614
 
@@ -616,6 +617,7 @@ class Sitemaps extends Metaboxes {
616
  * Applies filters 'the_seo_framework_sitemap_pages_query_args' : array
617
  *
618
  * @since 2.8.0
 
619
  *
620
  * @param array $args The new query arguments.
621
  * @param array $defaults The default query arguments
@@ -633,7 +635,7 @@ class Sitemaps extends Metaboxes {
633
  $page_on_front_id = (int) \get_option( 'page_on_front' );
634
  $page_for_posts_id = (int) \get_option( 'page_for_posts' );
635
 
636
- $id_on_front = $page_on_front ? $page_on_front_id : (int) $page_for_posts_id;
637
 
638
  //* Remove ID on front from list and add frontpage to list.
639
  if ( $page_on_front && false !== $key_on_front = array_search( $id_on_front, $latest_pages, true ) ) {
@@ -780,7 +782,7 @@ class Sitemaps extends Metaboxes {
780
  'has_password' => false,
781
  'fields' => 'ids',
782
  'cache_results' => false,
783
- 'suppress_filters' => true,
784
  'no_found_rows' => true,
785
  );
786
 
@@ -788,6 +790,7 @@ class Sitemaps extends Metaboxes {
788
  * Applies filters 'the_seo_framework_sitemap_posts_query_args' : array
789
  *
790
  * @since 2.8.0
 
791
  *
792
  * @param array $args The new query arguments.
793
  * @param array $defaults The default query arguments
@@ -894,7 +897,7 @@ class Sitemaps extends Metaboxes {
894
  'has_password' => false,
895
  'fields' => 'ids',
896
  'cache_results' => false,
897
- 'suppress_filters' => true,
898
  'no_found_rows' => true,
899
  );
900
 
@@ -902,6 +905,7 @@ class Sitemaps extends Metaboxes {
902
  * Applies filters 'the_seo_framework_sitemap_cpt_query_args' : array
903
  *
904
  * @since 2.8.0
 
905
  *
906
  * @param array $args The new query arguments.
907
  * @param array $defaults The default query arguments
@@ -1040,6 +1044,7 @@ class Sitemaps extends Metaboxes {
1040
  * The URL also isn't checked, nor the position.
1041
  *
1042
  * @since 3.0.4
 
1043
  *
1044
  * @param int $id The post ID to check. When 0, the custom field will not be checked.
1045
  * @return bool True if included, false otherwise.
@@ -1049,7 +1054,7 @@ class Sitemaps extends Metaboxes {
1049
  static $excluded = null;
1050
  if ( null === $excluded ) {
1051
  /**
1052
- * Applies filters the_seo_framework_sitemap_exclude_ids : array of id's
1053
  *
1054
  * @since 2.5.2
1055
  * @since 2.8.0 : No longer accepts '0' as entry.
@@ -1063,8 +1068,7 @@ class Sitemaps extends Metaboxes {
1063
  }
1064
  }
1065
 
1066
- $included = empty( $excluded[ $id ] );
1067
- if ( $included && $id ) {
1068
  $included = ! $this->get_custom_field( '_genesis_noindex', $id );
1069
  }
1070
 
236
  }
237
 
238
  $this->the_seo_framework_debug and $freed_memory = $memory - memory_get_usage();
 
239
  }
240
 
241
  /**
512
  * Create sitemap.xml content transient.
513
  *
514
  * @since 2.6.0
515
+ * @since 3.0.6 Now only sets transient when the option is checked.
516
  *
517
  * @param string|bool $content required The sitemap transient content.
518
  * @return string The sitemap content.
529
  */
530
  $expiration = WEEK_IN_SECONDS;
531
 
532
+ if ( $this->is_option_checked( 'cache_sitemap' ) )
533
+ $this->set_transient( $this->sitemap_transient, $sitemap_content, $expiration );
534
  }
535
 
536
  return $sitemap_content;
609
  'has_password' => false,
610
  'fields' => 'ids',
611
  'cache_results' => false,
612
+ 'suppress_filters' => false,
613
  'no_found_rows' => true,
614
  );
615
 
617
  * Applies filters 'the_seo_framework_sitemap_pages_query_args' : array
618
  *
619
  * @since 2.8.0
620
+ * @since 3.0.6: $args['suppress_filters'] now defaults to false.
621
  *
622
  * @param array $args The new query arguments.
623
  * @param array $defaults The default query arguments
635
  $page_on_front_id = (int) \get_option( 'page_on_front' );
636
  $page_for_posts_id = (int) \get_option( 'page_for_posts' );
637
 
638
+ $id_on_front = $page_on_front ? $page_on_front_id : $page_for_posts_id;
639
 
640
  //* Remove ID on front from list and add frontpage to list.
641
  if ( $page_on_front && false !== $key_on_front = array_search( $id_on_front, $latest_pages, true ) ) {
782
  'has_password' => false,
783
  'fields' => 'ids',
784
  'cache_results' => false,
785
+ 'suppress_filters' => false,
786
  'no_found_rows' => true,
787
  );
788
 
790
  * Applies filters 'the_seo_framework_sitemap_posts_query_args' : array
791
  *
792
  * @since 2.8.0
793
+ * @since 3.0.6: $args['suppress_filters'] now defaults to false.
794
  *
795
  * @param array $args The new query arguments.
796
  * @param array $defaults The default query arguments
897
  'has_password' => false,
898
  'fields' => 'ids',
899
  'cache_results' => false,
900
+ 'suppress_filters' => false,
901
  'no_found_rows' => true,
902
  );
903
 
905
  * Applies filters 'the_seo_framework_sitemap_cpt_query_args' : array
906
  *
907
  * @since 2.8.0
908
+ * @since 3.0.6: $args['suppress_filters'] now defaults to false.
909
  *
910
  * @param array $args The new query arguments.
911
  * @param array $defaults The default query arguments
1044
  * The URL also isn't checked, nor the position.
1045
  *
1046
  * @since 3.0.4
1047
+ * @since 3.1.0 : First filter value now works as intended.
1048
  *
1049
  * @param int $id The post ID to check. When 0, the custom field will not be checked.
1050
  * @return bool True if included, false otherwise.
1054
  static $excluded = null;
1055
  if ( null === $excluded ) {
1056
  /**
1057
+ * Applies filters the_seo_framework_sitemap_exclude_ids : sequential array of id's
1058
  *
1059
  * @since 2.5.2
1060
  * @since 2.8.0 : No longer accepts '0' as entry.
1068
  }
1069
  }
1070
 
1071
+ if ( ! isset( $excluded[ $id ] ) && $id ) {
 
1072
  $included = ! $this->get_custom_field( '_genesis_noindex', $id );
1073
  }
1074
 
inc/functions/optionsapi.php CHANGED
@@ -178,6 +178,8 @@ function the_seo_framework_title_from_cache( $title = null ) {
178
  * Fetch description from cache. Only works within Loop.
179
  *
180
  * @since 2.4.2
 
 
181
  *
182
  * @param bool $social Fetch social description.
183
  * @return string|null The current page description.
178
  * Fetch description from cache. Only works within Loop.
179
  *
180
  * @since 2.4.2
181
+ * @deprecated
182
+ * @since 3.0.6 Silently deprecated.
183
  *
184
  * @param bool $social Fetch social description.
185
  * @return string|null The current page description.
inc/functions/tsfem-suggestion.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The SEO Framework plugin
4
+ * Copyright (C) 2018 Sybre Waaijer, CyberWire (https://cyberwire.nl/)
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License version 3 as published
8
+ * by the Free Software Foundation.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU General Public License
16
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ */
18
+
19
+ defined( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME' ) or die;
20
+
21
+ /**
22
+ * This file holds functions for installing TSFEM.
23
+ * This file will only be called ONCE on plugin install, or upgrade from pre-v3.0.6.
24
+ *
25
+ * @since 3.0.6
26
+ * @access private
27
+ */
28
+
29
+ /**
30
+ * Prepares a "look at TSFEM" notification to ALL applicable plugin users on upgrade;
31
+ * when:
32
+ * 0. The upgrade happens when an applicable user is on the admin pages. (always true w/ default actions)
33
+ * 1. The constant 'TSF_DISABLE_SUGGESTIONS' is not defined or false.
34
+ * 2. The current dashboard is the main site's.
35
+ * 3. The applicable user can install plugins.
36
+ * 4. TSFEM isn't already installed.
37
+ * 5. PHP and WP requirements of TSFEM are met.
38
+ * This notice is automatically dismissed, and can be ignored without reappearing.
39
+ *
40
+ * @since 3.0.6
41
+ * @access private
42
+ * @uses the_seo_framework_add_upgrade_notice();
43
+ */
44
+ function the_seo_framework_load_extension_manager_suggestion() {
45
+
46
+ //? 1
47
+ if ( defined( 'TSF_DISABLE_SUGGESTIONS' ) && TSF_DISABLE_SUGGESTIONS ) return;
48
+ //? 2
49
+ if ( ! is_main_site() ) return;
50
+ //? 3
51
+ if ( ! current_user_can( 'install_plugins' ) ) return;
52
+ //? 4a
53
+ if ( defined( 'TSF_EXTENSION_MANAGER_VERSION' ) ) return;
54
+ //= PHP<5.5 can't write in empty()
55
+ $plugin = get_plugins( '/the-seo-framework-extension-manager' );
56
+ //? 4b
57
+ if ( ! empty( $plugin ) ) return;
58
+
59
+ /** @source https://github.com/sybrew/The-SEO-Framework-Extension-Manager/blob/34674828a9e79bf72584e23aaa4a82ea1f154229/bootstrap/envtest.php#L51-L62 */
60
+ $_req = array(
61
+ 'php' => array(
62
+ '5.5' => 50521,
63
+ '5.6' => 50605,
64
+ ),
65
+ 'wp' => '37965',
66
+ );
67
+ $envtest = false;
68
+
69
+ ! defined( 'PHP_VERSION_ID' ) || PHP_VERSION_ID < $_req['php']['5.5'] and $envtest = 1
70
+ or PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < $_req['php']['5.6'] and $envtest = 2
71
+ or $GLOBALS['wp_db_version'] < $_req['wp'] and $envtest = 3
72
+ or $envtest = true;
73
+
74
+ //? 5
75
+ if ( true !== $envtest ) return;
76
+
77
+ the_seo_framework_enqueue_installer_scripts();
78
+
79
+ add_action( 'admin_notices', 'the_seo_framework_suggest_extension_manager' );
80
+ }
81
+
82
+ /**
83
+ * Outputs "look at TSFEM" notification to ALL applicable plugin users on upgrade.
84
+ *
85
+ * @since 3.0.6
86
+ * @access private
87
+ */
88
+ function the_seo_framework_suggest_extension_manager() {
89
+
90
+ $plugin_slug = 'the-seo-framework-extension-manager';
91
+ $em_text = __( 'Extension Manager', 'autodescription' );
92
+
93
+ /**
94
+ * @source https://github.com/WordPress/WordPress/blob/4.9-branch/wp-admin/import.php#L162-L178
95
+ * @uses Spaghetti.
96
+ * @see WP Core class Plugin_Installer_Skin
97
+ */
98
+ $url = add_query_arg( array(
99
+ 'tab' => 'plugin-information',
100
+ 'plugin' => $plugin_slug,
101
+ 'from' => 'plugins',
102
+ 'TB_iframe' => 'true',
103
+ 'width' => 600,
104
+ 'height' => 550,
105
+ ), network_admin_url( 'plugin-install.php' ) );
106
+ $tsfem_details_link = sprintf(
107
+ '<a href="%1$s" id=tsf-tsfem-tb class="thickbox open-plugin-details-modal" aria-label="%2$s">%3$s</a>',
108
+ esc_url( $url ),
109
+ /* translators: %s: Plugin name */
110
+ esc_attr( sprintf( __( 'More information about %s', 'autodescription' ), $em_text ) ),
111
+ esc_html( $em_text )
112
+ );
113
+ $suggestion = sprintf(
114
+ /* translators: 1. "A feature, e.g. Focus keywords", 2: Extension Manager. */
115
+ esc_html__( 'Looking for %1$s? Try out the %2$s for free.', 'autodescription' ),
116
+ sprintf(
117
+ '<strong>%s</strong>',
118
+ esc_html__( 'Focus keywords', 'autodescription' )
119
+ ),
120
+ $tsfem_details_link
121
+ );
122
+
123
+ /**
124
+ * @source https://github.com/WordPress/WordPress/blob/4.9-branch/wp-admin/import.php#L125-L138
125
+ * @uses Bolognese sauce.
126
+ * @see The closest bowl of spaghetti. Or WordPress\Administration\wp.updates/updates.js
127
+ * This joke was brought to you by the incomplete API of WP Shiny Updates, where
128
+ * WP's import.php has been directly injected into, rather than "calling" it via its API.
129
+ * Therefore, leaving the incompleteness undiscovered internally.
130
+ * @TODO Open core track ticket.
131
+ */
132
+ $url = wp_nonce_url( add_query_arg( array(
133
+ 'action' => 'install-plugin',
134
+ 'plugin' => $plugin_slug,
135
+ 'from' => 'plugins',
136
+ ), self_admin_url( 'update.php' ) ), 'install-plugin_' . $plugin_slug );
137
+ $action = sprintf(
138
+ '<a href="%1$s" id=tsf-tsfem-install class="install-now button button-small" data-slug="%2$s" data-name="%3$s" aria-label="%4$s">%5$s</a>',
139
+ esc_url( $url ),
140
+ esc_attr( $plugin_slug ),
141
+ esc_attr( $em_text ),
142
+ /* translators: %s: Extension Manager */
143
+ esc_attr( sprintf( __( 'Install the %s', 'autodescription' ), $em_text ) ),
144
+ esc_html__( 'Install Now', 'autodescription' )
145
+ );
146
+
147
+ $text = is_rtl() ? $action . ' ' . $suggestion : $suggestion . ' ' . $action;
148
+
149
+ //= This loads the JS files.
150
+ the_seo_framework()->do_dismissible_notice( $text, 'updated', false, false );
151
+ }
152
+
153
+ /**
154
+ * Loads scripts for TSFEM "Shiny Updates" implementation for WP 4.6 and later.
155
+ *
156
+ * @since 3.0.6
157
+ * @access private
158
+ */
159
+ function the_seo_framework_enqueue_installer_scripts() {
160
+
161
+ $deps = array(
162
+ 'plugin-install',
163
+ 'updates',
164
+ );
165
+ $scriptname = 'tsfinstaller';
166
+ $suffix = the_seo_framework()->script_debug ? '' : '.min';
167
+
168
+ $strings = array(
169
+ 'slug' => 'the-seo-framework-extension-manager',
170
+ 'canEnhance' => the_seo_framework()->wp_version( '4.6' ),
171
+ );
172
+
173
+ wp_register_script( $scriptname, THE_SEO_FRAMEWORK_DIR_URL . "lib/js/installer/{$scriptname}{$suffix}.js", $deps, THE_SEO_FRAMEWORK_VERSION, true );
174
+ wp_localize_script( $scriptname, "{$scriptname}L10n", $strings );
175
+
176
+ add_action( 'admin_print_styles', 'the_seo_framework_print_installer_styles' );
177
+ add_action( 'admin_footer', 'wp_print_request_filesystem_credentials_modal' );
178
+ add_action( 'admin_footer', 'wp_print_admin_notice_templates' );
179
+
180
+ wp_enqueue_style( 'plugin-install' );
181
+ wp_enqueue_script( $scriptname );
182
+ add_thickbox();
183
+ }
184
+
185
+ /**
186
+ * Outputs "button-small" "Shiny Updates" compatibility style.
187
+ *
188
+ * @since 3.0.6
189
+ * @staticvar bool $printed Prevents duplicate writing.
190
+ * @access private
191
+ */
192
+ function the_seo_framework_print_installer_styles() {
193
+ static $printed = false;
194
+ if ( $printed ) return;
195
+ echo '<style type="text/css">#tsf-tsfem-install.updating-message:before{font-size:16px;vertical-align:top}</style>';
196
+ $printed = true;
197
+ }
inc/functions/upgrade.php CHANGED
@@ -16,7 +16,7 @@
16
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
  */
18
 
19
- defined( 'ABSPATH' ) or die;
20
 
21
  /**
22
  * This file holds functions for upgrading the plugin.
@@ -85,6 +85,10 @@ function the_seo_framework_do_upgrade() {
85
  the_seo_framework_do_upgrade_3001();
86
  $version = '3001';
87
  }
 
 
 
 
88
 
89
  do_action( 'the_seo_framework_upgraded' );
90
  }
@@ -141,6 +145,7 @@ function the_seo_framework_output_upgrade_notices() {
141
  }
142
  }
143
 
 
144
  /**
145
  * Upgrades term metadata for version 2701.
146
  *
@@ -202,33 +207,44 @@ function the_seo_framework_do_upgrade_2900() {
202
  * Invalidates object cache.
203
  *
204
  * @since 3.0.0
 
205
  */
206
  function the_seo_framework_do_upgrade_3001() {
207
 
208
  $tsf = the_seo_framework();
209
- $previous_version = the_seo_framework_previous_db_version();
210
 
211
  $timestamp_format = $tsf->get_option( 'sitemap_timestamps', false );
212
  //= Only change if option exists. Falls back to default upgrader instead.
213
  if ( '' !== $timestamp_format ) {
214
  $tsf->update_option( 'timestamps_format', (string) (int) $timestamp_format );
215
  //= Only set notice if an actual upgrade took place. (redundancy check)
216
- if ( $previous_version > '0' ) {
217
  the_seo_framework_add_upgrade_notice(
218
  esc_html__( 'The previous sitemap timestamp settings have been converted into new global timestamp settings.', 'autodescription' )
219
  );
220
  }
221
  }
222
 
223
- if ( $previous_version > '0' ) {
224
- $tsf->update_option( 'display_character_counter', 1 );
225
- $tsf->update_option( 'display_pixel_counter', 1 );
226
- } else {
227
- $tsf->update_option( 'display_character_counter', 0 );
228
- $tsf->update_option( 'display_pixel_counter', 1 );
229
- }
230
 
231
  $tsf->delete_object_cache();
232
 
233
  update_option( 'the_seo_framework_upgraded_db_version', '3001' );
234
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17
  */
18
 
19
+ defined( 'THE_SEO_FRAMEWORK_PLUGIN_BASENAME' ) or die;
20
 
21
  /**
22
  * This file holds functions for upgrading the plugin.
85
  the_seo_framework_do_upgrade_3001();
86
  $version = '3001';
87
  }
88
+ if ( $version < '3060' ) {
89
+ the_seo_framework_do_upgrade_3060();
90
+ $version = '3060';
91
+ }
92
 
93
  do_action( 'the_seo_framework_upgraded' );
94
  }
145
  }
146
  }
147
 
148
+
149
  /**
150
  * Upgrades term metadata for version 2701.
151
  *
207
  * Invalidates object cache.
208
  *
209
  * @since 3.0.0
210
+ * @since 3.0.6 'display_character_counter' option now correctly defaults to 1.
211
  */
212
  function the_seo_framework_do_upgrade_3001() {
213
 
214
  $tsf = the_seo_framework();
 
215
 
216
  $timestamp_format = $tsf->get_option( 'sitemap_timestamps', false );
217
  //= Only change if option exists. Falls back to default upgrader instead.
218
  if ( '' !== $timestamp_format ) {
219
  $tsf->update_option( 'timestamps_format', (string) (int) $timestamp_format );
220
  //= Only set notice if an actual upgrade took place. (redundancy check)
221
+ if ( the_seo_framework_previous_db_version() > '0' ) {
222
  the_seo_framework_add_upgrade_notice(
223
  esc_html__( 'The previous sitemap timestamp settings have been converted into new global timestamp settings.', 'autodescription' )
224
  );
225
  }
226
  }
227
 
228
+ $tsf->update_option( 'display_character_counter', 1 );
229
+ $tsf->update_option( 'display_pixel_counter', 1 );
 
 
 
 
 
230
 
231
  $tsf->delete_object_cache();
232
 
233
  update_option( 'the_seo_framework_upgraded_db_version', '3001' );
234
  }
235
+
236
+ /**
237
+ * Loads suggestion for TSFEM.
238
+ * Also deletes sitemap cache.
239
+ *
240
+ * @since 3.0.6
241
+ */
242
+ function the_seo_framework_do_upgrade_3060() {
243
+
244
+ the_seo_framework()->delete_cache( 'sitemap' );
245
+
246
+ require THE_SEO_FRAMEWORK_DIR_PATH_FUNCT . 'tsfem-suggestion.php';
247
+ the_seo_framework_load_extension_manager_suggestion();
248
+
249
+ update_option( 'the_seo_framework_upgraded_db_version', '3060' );
250
+ }
inc/interfaces/debug.interface.php CHANGED
@@ -39,9 +39,9 @@ interface Debug_Interface {
39
  * @access private
40
  * @see @this->_deprecated_function().
41
  *
42
- * @param string $filter The function that was called.
43
- * @param string $version The version of WordPress that deprecated the function.
44
- * @param string $replacement Optional. The function that should have been called. Default null.
45
  */
46
  public function _deprecated_filter( $filter, $version, $replacement = null );
47
 
@@ -55,9 +55,9 @@ interface Debug_Interface {
55
  * @since 2.6.0
56
  * @access private
57
  *
58
- * @param string $function The function that was called.
59
- * @param string $version The version of WordPress that deprecated the function.
60
- * @param string $replacement Optional. The function that should have been called. Default null.
61
  */
62
  public function _deprecated_function( $function, $version, $replacement = null );
63
 
@@ -71,9 +71,9 @@ interface Debug_Interface {
71
  * @since 2.6.0
72
  * @access private
73
  *
74
- * @param string $function The function that was called.
75
- * @param string $message A message explaining what has been done incorrectly.
76
- * @param string $version The version of WordPress where the message was added.
77
  */
78
  public function _doing_it_wrong( $function, $message, $version );
79
 
@@ -85,8 +85,8 @@ interface Debug_Interface {
85
  * @since 2.7.0
86
  * @access private
87
  *
88
- * @param string $p_or_m The Property or Method.
89
- * @param string $message A message explaining what has been done incorrectly.
90
  */
91
  public function _inaccessible_p_or_m( $p_or_m, $message = '' );
92
 
39
  * @access private
40
  * @see @this->_deprecated_function().
41
  *
42
+ * @param string $filter The function that was called.
43
+ * @param string $version The version of WordPress that deprecated the function.
44
+ * @param string $replacement Optional. The function that should have been called. Default null.
45
  */
46
  public function _deprecated_filter( $filter, $version, $replacement = null );
47
 
55
  * @since 2.6.0
56
  * @access private
57
  *
58
+ * @param string $function The function that was called.
59
+ * @param string $version The version of WordPress that deprecated the function.
60
+ * @param string $replacement Optional. The function that should have been called. Default null.
61
  */
62
  public function _deprecated_function( $function, $version, $replacement = null );
63
 
71
  * @since 2.6.0
72
  * @access private
73
  *
74
+ * @param string $function The function that was called.
75
+ * @param string $message A message explaining what has been done incorrectly.
76
+ * @param string $version he version of WordPress where the message was added.
77
  */
78
  public function _doing_it_wrong( $function, $message, $version );
79
 
85
  * @since 2.7.0
86
  * @access private
87
  *
88
+ * @param string $p_or_m The Property or Method.
89
+ * @param string $message A message explaining what has been done incorrectly.
90
  */
91
  public function _inaccessible_p_or_m( $p_or_m, $message = '' );
92
 
inc/views/inpost/seo-settings-singular.php CHANGED
@@ -119,7 +119,7 @@ switch ( $instance ) :
119
  </div>
120
  <div class="tsf-flex-setting-input tsf-flex">
121
  <div id="tsf-title-wrap">
122
- <input class="large-text" type="text" name="autodescription[_genesis_title]" id="autodescription_title" placeholder="<?php echo esc_attr( $doctitle_placeholder ); ?>" value="<?php echo esc_attr( $this->get_custom_field( '_genesis_title' ) ); ?>" autocomplete=off />
123
  <?php echo $this->output_js_title_elements(); ?>
124
  </div>
125
  </div>
@@ -145,7 +145,7 @@ switch ( $instance ) :
145
  </div>
146
  </div>
147
  <div class="tsf-flex-setting-input tsf-flex">
148
- <textarea class="large-text" name="autodescription[_genesis_description]" id="autodescription_description" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="4" cols="4"><?php echo esc_attr( $this->get_custom_field( '_genesis_description' ) ); ?></textarea>
149
  <?php echo $this->output_js_description_elements(); ?>
150
  </div>
151
  </div>
119
  </div>
120
  <div class="tsf-flex-setting-input tsf-flex">
121
  <div id="tsf-title-wrap">
122
+ <input class="large-text" type="text" name="autodescription[_genesis_title]" id="autodescription_title" placeholder="<?php echo esc_attr( $doctitle_placeholder ); ?>" value="<?php echo esc_attr( $this->get_custom_field( '_genesis_title', $post_id ) ); ?>" autocomplete=off />
123
  <?php echo $this->output_js_title_elements(); ?>
124
  </div>
125
  </div>
145
  </div>
146
  </div>
147
  <div class="tsf-flex-setting-input tsf-flex">
148
+ <textarea class="large-text" name="autodescription[_genesis_description]" id="autodescription_description" placeholder="<?php echo esc_attr( $description_placeholder ); ?>" rows="4" cols="4"><?php echo esc_attr( $this->get_custom_field( '_genesis_description', $post_id ) ); ?></textarea>
149
  <?php echo $this->output_js_description_elements(); ?>
150
  </div>
151
  </div>
inc/views/inpost/seo-settings-tt.php CHANGED
@@ -26,15 +26,9 @@ $generated_doctitle_args = array(
26
  'get_custom_field' => false,
27
  );
28
 
29
- $generated_description_args = array(
30
- 'id' => $term_id,
31
- 'taxonomy' => $taxonomy,
32
- 'get_custom_field' => false,
33
- );
34
-
35
  //* Generate title and description.
36
  $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
37
- $generated_description = $this->generate_description( '', $generated_description_args );
38
 
39
  $blog_name = $this->get_blogname();
40
  $add_additions = $this->add_title_additions();
26
  'get_custom_field' => false,
27
  );
28
 
 
 
 
 
 
 
29
  //* Generate title and description.
30
  $generated_doctitle = $this->title( '', '', '', $generated_doctitle_args );
31
+ $generated_description = $this->get_generated_description( $term_id );
32
 
33
  $blog_name = $this->get_blogname();
34
  $add_additions = $this->add_title_additions();
inc/views/metaboxes/homepage-metabox.php CHANGED
@@ -105,13 +105,7 @@ switch ( $instance ) :
105
  if ( $frompost_description ) {
106
  $description_placeholder = $frompost_description;
107
  } else {
108
- $description_args = array(
109
- 'id' => $home_id,
110
- 'is_home' => true,
111
- 'get_custom_field' => false,
112
- );
113
-
114
- $description_placeholder = $this->generate_description( '', $description_args );
115
  }
116
 
117
  /**
105
  if ( $frompost_description ) {
106
  $description_placeholder = $frompost_description;
107
  } else {
108
+ $description_placeholder = $this->get_generated_description( $home_id );
 
 
 
 
 
 
109
  }
110
 
111
  /**
language/autodescription.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the same license as the The SEO Framework package.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: The SEO Framework 3.0.4\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/autodescription\n"
7
- "POT-Creation-Date: 2018-02-26 01:19:08+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -14,61 +14,61 @@ msgstr ""
14
 
15
  #. translators: %s = term name
16
 
17
- #: inc/classes/admin-init.class.php:253
18
  msgid "Make primary %s"
19
  msgstr ""
20
 
21
  #. translators: %s = term name
22
 
23
- #: inc/classes/admin-init.class.php:255
24
  msgid "Primary %s"
25
  msgstr ""
26
 
27
- #: inc/classes/admin-init.class.php:352
28
  msgid "The changes you made will be lost if you navigate away from this page."
29
  msgstr ""
30
 
31
- #: inc/classes/admin-init.class.php:353
32
  msgid "Are you sure you want to reset all SEO settings to their defaults?"
33
  msgstr ""
34
 
35
- #: inc/classes/admin-init.class.php:354
36
  msgid "Good"
37
  msgstr ""
38
 
39
- #: inc/classes/admin-init.class.php:355
40
  msgid "Okay"
41
  msgstr ""
42
 
43
- #: inc/classes/admin-init.class.php:356
44
  msgid "Bad"
45
  msgstr ""
46
 
47
- #: inc/classes/admin-init.class.php:357
48
  msgid "Unknown"
49
  msgstr ""
50
 
51
- #: inc/classes/admin-init.class.php:358
52
  msgid "Private:"
53
  msgstr ""
54
 
55
- #: inc/classes/admin-init.class.php:359
56
  msgid "Protected:"
57
  msgstr ""
58
 
59
  #. translators: Pixel counter. 1: width, 2: guideline
60
 
61
- #: inc/classes/admin-init.class.php:361
62
  msgid "%1$d out of %2$d pixels are used."
63
  msgstr ""
64
 
65
  #. translators: %s = Redirect URL markdown
66
 
67
- #: inc/classes/admin-init.class.php:703
68
  msgid "There has been an error redirecting. Refresh the page or follow [this link](%s)."
69
  msgstr ""
70
 
71
- #: inc/classes/admin-init.class.php:789 inc/classes/admin-init.class.php:850
72
  msgid "Image could not be processed."
73
  msgstr ""
74
 
@@ -130,7 +130,7 @@ msgstr ""
130
 
131
  #: inc/classes/admin-pages.class.php:295
132
  #: inc/views/inpost/seo-settings-singular.php:187
133
- #: inc/views/inpost/seo-settings-tt.php:164
134
  msgid "Robots Meta Settings"
135
  msgstr ""
136
 
@@ -203,29 +203,29 @@ msgstr ""
203
  msgid "Characters Used: %s"
204
  msgstr ""
205
 
206
- #: inc/classes/core.class.php:254
207
  msgid "Settings"
208
  msgstr ""
209
 
210
- #: inc/classes/core.class.php:256
211
  msgctxt "As in: The Plugin Home Page"
212
  msgid "Home"
213
  msgstr ""
214
 
215
- #: inc/classes/core.class.php:265
216
  msgid "https://wordpress.org/plugins/the-seo-framework-extension-manager/"
217
  msgstr ""
218
 
219
- #: inc/classes/core.class.php:265
220
  msgctxt "Plugin extensions"
221
  msgid "Extensions"
222
  msgstr ""
223
 
224
- #: inc/classes/core.class.php:317
225
  msgid "Dismiss"
226
  msgstr ""
227
 
228
- #: inc/classes/core.class.php:460
229
  msgctxt "e.g. en for English, nl for Dutch, fi for Finish, de for German"
230
  msgid "en"
231
  msgstr ""
@@ -299,204 +299,204 @@ msgstr ""
299
 
300
  #. translators: %s = But or And
301
 
302
- #: inc/classes/doing-it-right.class.php:956
303
  msgid "%s the Title contains the Blogname multiple times."
304
  msgstr ""
305
 
306
  #. translators: 1: Word, 2: Occurrences
307
 
308
- #: inc/classes/doing-it-right.class.php:1129
309
  msgid "%1$s is used %2$d times."
310
  msgstr ""
311
 
312
  #. Translators: %s = Post / Page / Category, etc.
313
 
314
- #: inc/classes/doing-it-right.class.php:1174
315
  msgid "%s is being indexed."
316
  msgstr ""
317
 
318
- #: inc/classes/doing-it-right.class.php:1183
319
  msgid "But you've discouraged indexing for the whole site."
320
  msgstr ""
321
 
322
  #. translators: 1: But or And, 2: Current taxonomy term plural label
323
 
324
- #: inc/classes/doing-it-right.class.php:1207
325
  msgid "%1$s indexing for %2$s have been discouraged."
326
  msgstr ""
327
 
328
  #. translators: 1 = But or And, 1 = Post/Page
329
 
330
- #: inc/classes/doing-it-right.class.php:1220
331
  msgid "%1$s the %2$s is protected from public visibility. This means indexing is discouraged."
332
  msgstr ""
333
 
334
  #. translators: %s = But or And
335
 
336
- #: inc/classes/doing-it-right.class.php:1229
337
  msgid "%s the blog isn't set to public. This means WordPress discourages indexing."
338
  msgstr ""
339
 
340
  #. translators: %s = But or And
341
 
342
- #: inc/classes/doing-it-right.class.php:1243
343
  msgid "%s there are no posts in this term; therefore, indexing has been discouraged."
344
  msgstr ""
345
 
346
- #: inc/classes/doing-it-right.class.php:1327
347
  msgid "%s links aren't being followed."
348
  msgstr ""
349
 
350
- #: inc/classes/doing-it-right.class.php:1333
351
  msgid "%s links are being followed."
352
  msgstr ""
353
 
354
  #. translators: %s = But or And
355
 
356
- #: inc/classes/doing-it-right.class.php:1345
357
  msgid "%s you've discouraged the following of links for the whole site."
358
  msgstr ""
359
 
360
  #. translators: 1: But or And, 2: Current taxonomy term plural label
361
 
362
- #: inc/classes/doing-it-right.class.php:1371
363
  msgid "%1$s following for %2$s have been discouraged."
364
  msgstr ""
365
 
366
  #. translators: %s = But or And
367
 
368
- #: inc/classes/doing-it-right.class.php:1383
369
  msgid "%s the blog isn't set to public. This means WordPress allows the links to be followed regardless."
370
  msgstr ""
371
 
372
- #: inc/classes/doing-it-right.class.php:1435
373
  msgid "Search Engines aren't allowed to archive this %s."
374
  msgstr ""
375
 
376
- #: inc/classes/doing-it-right.class.php:1440
377
  msgid "Search Engines are allowed to archive this %s."
378
  msgstr ""
379
 
380
- #: inc/classes/doing-it-right.class.php:1452
381
- msgid "But you've discouraged archiving for the whole site."
382
  msgstr ""
383
 
384
  #. translators: 1: But or And, 2: Current taxonomy term plural label
385
 
386
- #: inc/classes/doing-it-right.class.php:1478
387
  msgid "%1$s archiving for %2$s have been discouraged."
388
  msgstr ""
389
 
390
  #. translators: %s = But or And
391
 
392
- #: inc/classes/doing-it-right.class.php:1491
393
  msgid "%s the blog isn't set to public. This means WordPress allows the blog to be archived regardless."
394
  msgstr ""
395
 
396
- #: inc/classes/doing-it-right.class.php:1537
397
  msgid "%s isn't being redirected."
398
  msgstr ""
399
 
400
- #: inc/classes/doing-it-right.class.php:1579
401
- #: inc/classes/doing-it-right.class.php:1608
402
  msgid "%s is being redirected. This means no SEO values have to be set."
403
  msgstr ""
404
 
405
- #: inc/classes/doing-it-right.class.php:1582
406
- #: inc/classes/doing-it-right.class.php:1624
407
  msgid "%s is not being indexed. This means no SEO values have to be set."
408
  msgstr ""
409
 
410
- #: inc/classes/doing-it-right.class.php:1738
411
  msgid "Title:"
412
  msgstr ""
413
 
414
- #: inc/classes/doing-it-right.class.php:1739
415
  msgid "Description:"
416
  msgstr ""
417
 
418
- #: inc/classes/doing-it-right.class.php:1740
419
  msgid "Index:"
420
  msgstr ""
421
 
422
- #: inc/classes/doing-it-right.class.php:1741
423
  msgid "Follow:"
424
  msgstr ""
425
 
426
- #: inc/classes/doing-it-right.class.php:1742
427
  msgid "Archive:"
428
  msgstr ""
429
 
430
- #: inc/classes/doing-it-right.class.php:1743
431
  msgid "Redirect:"
432
  msgstr ""
433
 
434
- #: inc/classes/doing-it-right.class.php:1745
435
  msgid "Generated: Automatically generated."
436
  msgstr ""
437
 
438
- #: inc/classes/doing-it-right.class.php:1747
439
  msgctxt "Generated"
440
  msgid "G"
441
  msgstr ""
442
 
443
- #: inc/classes/doing-it-right.class.php:1748
444
  msgctxt "Title"
445
  msgid "T"
446
  msgstr ""
447
 
448
- #: inc/classes/doing-it-right.class.php:1749
449
  msgctxt "Description"
450
  msgid "D"
451
  msgstr ""
452
 
453
- #: inc/classes/doing-it-right.class.php:1750
454
  msgctxt "no-Index"
455
  msgid "I"
456
  msgstr ""
457
 
458
- #: inc/classes/doing-it-right.class.php:1751
459
  msgctxt "no-Follow"
460
  msgid "F"
461
  msgstr ""
462
 
463
- #: inc/classes/doing-it-right.class.php:1752
464
  msgctxt "no-Archive"
465
  msgid "A"
466
  msgstr ""
467
 
468
- #: inc/classes/doing-it-right.class.php:1753
469
  msgctxt "Redirect"
470
  msgid "R"
471
  msgstr ""
472
 
473
- #: inc/classes/doing-it-right.class.php:1755
474
  msgctxt "But there are..."
475
  msgid "But"
476
  msgstr ""
477
 
478
- #: inc/classes/doing-it-right.class.php:1756
479
  msgctxt "And there are..."
480
  msgid "And"
481
  msgstr ""
482
 
483
- #: inc/classes/doing-it-right.class.php:1758
484
  msgid "Length is far too short."
485
  msgstr ""
486
 
487
- #: inc/classes/doing-it-right.class.php:1759
488
  msgid "Length is too short."
489
  msgstr ""
490
 
491
- #: inc/classes/doing-it-right.class.php:1760
492
  msgid "Length is too long."
493
  msgstr ""
494
 
495
- #: inc/classes/doing-it-right.class.php:1761
496
  msgid "Length is far too long."
497
  msgstr ""
498
 
499
- #: inc/classes/doing-it-right.class.php:1762
500
  msgid "Length is good."
501
  msgstr ""
502
 
@@ -507,21 +507,21 @@ msgstr ""
507
 
508
  #. translators: 1: Title, 2: Separator, 3: Excerpt
509
 
510
- #: inc/classes/generate-description.class.php:539
511
  msgctxt "1: Title, 2: Separator, 3: Excerpt"
512
  msgid "%1$s %2$s %3$s"
513
  msgstr ""
514
 
515
  #. translators: 1: Title, 2: on, 3: Blogname
516
 
517
- #: inc/classes/generate-description.class.php:748
518
  msgctxt "1: Title, 2: on, 3: Blogname"
519
  msgid "%1$s %2$s %3$s"
520
  msgstr ""
521
 
522
  #. translators: Front-end output.
523
 
524
- #: inc/classes/generate-description.class.php:785
525
  #: inc/views/metaboxes/description-metabox.php:18
526
  msgctxt "Placement. e.g. Post Title \"on\" Blog Name"
527
  msgid "on"
@@ -529,7 +529,7 @@ msgstr ""
529
 
530
  #. translators: Front-end output.
531
 
532
- #: inc/classes/generate-description.class.php:873
533
  msgid "Latest posts:"
534
  msgstr ""
535
 
@@ -707,7 +707,7 @@ msgstr ""
707
  #. translators: %s = Post Type
708
  #. translators: %s = Term type
709
 
710
- #: inc/classes/inpost.class.php:230 inc/views/inpost/seo-settings-tt.php:100
711
  msgid "%s SEO Settings"
712
  msgstr ""
713
 
@@ -731,17 +731,17 @@ msgstr ""
731
 
732
  #. translators: %s = 'The SEO Framework'
733
 
734
- #: inc/classes/render.class.php:1103
735
  msgid "Start %s"
736
  msgstr ""
737
 
738
  #. translators: %s = 'The SEO Framework'
739
 
740
- #: inc/classes/render.class.php:1105
741
  msgid "End %s"
742
  msgstr ""
743
 
744
- #: inc/classes/render.class.php:1106
745
  msgid "by Sybre Waaijer"
746
  msgstr ""
747
 
@@ -754,15 +754,15 @@ msgctxt "%s = here"
754
  msgid "View the new options %s."
755
  msgstr ""
756
 
757
- #: inc/classes/sitemaps.class.php:297
758
  msgid "Sitemap is generated for this view"
759
  msgstr ""
760
 
761
- #: inc/classes/sitemaps.class.php:299
762
  msgid "Sitemap is served from cache"
763
  msgstr ""
764
 
765
- #: inc/classes/sitemaps.class.php:594
766
  msgid "Sitemap is generated on"
767
  msgstr ""
768
 
@@ -770,11 +770,41 @@ msgstr ""
770
  msgid "Pages"
771
  msgstr ""
772
 
773
- #: inc/functions/upgrade.php:192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
774
  msgid "Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable."
775
  msgstr ""
776
 
777
- #: inc/functions/upgrade.php:218
778
  msgid "The previous sitemap timestamp settings have been converted into new global timestamp settings."
779
  msgstr ""
780
 
@@ -798,8 +828,8 @@ msgid "Visibility"
798
  msgstr ""
799
 
800
  #: inc/views/inpost/seo-settings-singular.php:87
801
- #: inc/views/inpost/seo-settings-tt.php:108
802
- #: inc/views/inpost/seo-settings-tt.php:206
803
  msgid "Doing it Right"
804
  msgstr ""
805
 
@@ -807,14 +837,14 @@ msgstr ""
807
  #. translators: %s = Post type
808
 
809
  #: inc/views/inpost/seo-settings-singular.php:108
810
- #: inc/views/metaboxes/homepage-metabox.php:174
811
  msgid "Custom %s Title"
812
  msgstr ""
813
 
814
  #. translators: %s = Post type name
815
 
816
  #: inc/views/inpost/seo-settings-singular.php:135
817
- #: inc/views/metaboxes/homepage-metabox.php:230
818
  msgid "Custom %s Description"
819
  msgstr ""
820
 
@@ -910,32 +940,32 @@ msgstr ""
910
  msgid "Set preferred %s Social Image URL location."
911
  msgstr ""
912
 
913
- #: inc/views/inpost/seo-settings-tt.php:73
914
- #: inc/views/metaboxes/homepage-metabox.php:362
915
  msgid "This tells search engines not to show this page in their search results."
916
  msgstr ""
917
 
918
- #: inc/views/inpost/seo-settings-tt.php:81
919
- #: inc/views/inpost/seo-settings-tt.php:89
920
- #: inc/views/metaboxes/homepage-metabox.php:372
921
  msgid "This tells search engines not to follow links on this page."
922
  msgstr ""
923
 
924
  #. translators: %s = Term type
925
 
926
- #: inc/views/inpost/seo-settings-tt.php:121
927
  msgid "%s Title"
928
  msgstr ""
929
 
930
  #. translators: %s = Term type
931
 
932
- #: inc/views/inpost/seo-settings-tt.php:146
933
  msgid "%s Meta Description"
934
  msgstr ""
935
 
936
  #. translators: %s = noindex/nofollow/noarchive
937
 
938
- #: inc/views/inpost/seo-settings-tt.php:181
939
  msgid "Apply %s to this term?"
940
  msgstr ""
941
 
@@ -952,7 +982,7 @@ msgid "Automated Description Settings"
952
  msgstr ""
953
 
954
  #: inc/views/metaboxes/description-metabox.php:42
955
- #: inc/views/metaboxes/homepage-metabox.php:245
956
  msgid "The meta description can be used to determine the text used under the title on Search Engine results pages."
957
  msgstr ""
958
 
@@ -1336,119 +1366,119 @@ msgid "Description"
1336
  msgstr ""
1337
 
1338
  #: inc/views/metaboxes/homepage-metabox.php:71
1339
- #: inc/views/metaboxes/homepage-metabox.php:282
1340
- #: inc/views/metaboxes/homepage-metabox.php:329
1341
  #: inc/views/metaboxes/social-metabox.php:318
1342
  msgid "Home Page"
1343
  msgstr ""
1344
 
1345
- #: inc/views/metaboxes/homepage-metabox.php:141
1346
- #: inc/views/metaboxes/homepage-metabox.php:199
1347
  msgid "Page SEO Settings"
1348
  msgstr ""
1349
 
1350
  #. translators: 1: Option, 2: Page SEO Settings, 3: Home Page
1351
 
1352
- #: inc/views/metaboxes/homepage-metabox.php:143
1353
- #: inc/views/metaboxes/homepage-metabox.php:197
1354
  msgid "Note: The %1$s is fetched from the %2$s on the %3$s."
1355
  msgstr ""
1356
 
1357
- #: inc/views/metaboxes/homepage-metabox.php:160
1358
  msgid "Custom %s Title Tagline"
1359
  msgstr ""
1360
 
1361
  #. translators: %s = Home page URL markdown
1362
 
1363
- #: inc/views/metaboxes/homepage-metabox.php:215
1364
- #: inc/views/metaboxes/homepage-metabox.php:261
1365
  msgid "A plugin has been detected that suggests to maintain this option on the [Home Page](%s)."
1366
  msgstr ""
1367
 
1368
- #: inc/views/metaboxes/homepage-metabox.php:287
1369
  #: inc/views/metaboxes/title-metabox.php:135
1370
  msgid "Title Additions Location"
1371
  msgstr ""
1372
 
1373
- #: inc/views/metaboxes/homepage-metabox.php:288
1374
  #: inc/views/metaboxes/title-metabox.php:136
1375
  msgid "This setting determines which side the added title text will go on."
1376
  msgstr ""
1377
 
1378
- #: inc/views/metaboxes/homepage-metabox.php:295
1379
  #: inc/views/metaboxes/title-metabox.php:142
1380
  msgid "Left:"
1381
  msgstr ""
1382
 
1383
- #: inc/views/metaboxes/homepage-metabox.php:305
1384
  #: inc/views/metaboxes/title-metabox.php:149
1385
  msgid "Right:"
1386
  msgstr ""
1387
 
1388
- #: inc/views/metaboxes/homepage-metabox.php:316
1389
  msgid "%s Tagline"
1390
  msgstr ""
1391
 
1392
- #: inc/views/metaboxes/homepage-metabox.php:320
1393
  msgid "Add site description (tagline) to the Title on the %s?"
1394
  msgstr ""
1395
 
1396
- #: inc/views/metaboxes/homepage-metabox.php:346
1397
  msgid "View Home Page Settings"
1398
  msgstr ""
1399
 
1400
- #: inc/views/metaboxes/homepage-metabox.php:346
1401
  msgid "Checked in Page"
1402
  msgstr ""
1403
 
1404
- #: inc/views/metaboxes/homepage-metabox.php:350
1405
  msgid "Home Page Robots Meta Settings"
1406
  msgstr ""
1407
 
1408
  #. translators: 1: Option, 2: Location
1409
 
1410
- #: inc/views/metaboxes/homepage-metabox.php:359
1411
- #: inc/views/metaboxes/homepage-metabox.php:369
1412
- #: inc/views/metaboxes/homepage-metabox.php:379
1413
  msgid "Apply %1$s to the %2$s?"
1414
  msgstr ""
1415
 
1416
- #: inc/views/metaboxes/homepage-metabox.php:382
1417
  msgid "This tells search engines not to save a cached copy of this page."
1418
  msgstr ""
1419
 
1420
- #: inc/views/metaboxes/homepage-metabox.php:414
1421
  msgid "Note: If any of these options are unchecked, but are checked on the Home Page, they will be outputted regardless."
1422
  msgstr ""
1423
 
1424
- #: inc/views/metaboxes/homepage-metabox.php:420
1425
  msgid "Home Page Pagination Robots Settings"
1426
  msgstr ""
1427
 
1428
- #: inc/views/metaboxes/homepage-metabox.php:421
1429
  msgid "If your Home Page is paginated and outputs content that's also found elsewhere on the website, enabling this option might prevent duplicate content."
1430
  msgstr ""
1431
 
1432
  #. translators: 1: Option, 2: Location
1433
 
1434
- #: inc/views/metaboxes/homepage-metabox.php:429
1435
  msgid "Apply %1$s to every second or later page on the %2$s?"
1436
  msgstr ""
1437
 
1438
- #: inc/views/metaboxes/homepage-metabox.php:439
1439
  #: inc/views/metaboxes/social-metabox.php:115
1440
  msgid "Social Image Settings"
1441
  msgstr ""
1442
 
1443
- #: inc/views/metaboxes/homepage-metabox.php:441
1444
  msgid "A social image can be displayed when your homepage is shared. It is a great way to grab attention."
1445
  msgstr ""
1446
 
1447
- #: inc/views/metaboxes/homepage-metabox.php:470
1448
  msgid "Custom Homepage Image URL"
1449
  msgstr ""
1450
 
1451
- #: inc/views/metaboxes/homepage-metabox.php:471
1452
  msgid "Set preferred homepage Social Image URL location."
1453
  msgstr ""
1454
 
2
  # This file is distributed under the same license as the The SEO Framework package.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: The SEO Framework 3.0.6\n"
6
  "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/autodescription\n"
7
+ "POT-Creation-Date: 2018-05-06 16:46:10+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=UTF-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
14
 
15
  #. translators: %s = term name
16
 
17
+ #: inc/classes/admin-init.class.php:257
18
  msgid "Make primary %s"
19
  msgstr ""
20
 
21
  #. translators: %s = term name
22
 
23
+ #: inc/classes/admin-init.class.php:259
24
  msgid "Primary %s"
25
  msgstr ""
26
 
27
+ #: inc/classes/admin-init.class.php:356
28
  msgid "The changes you made will be lost if you navigate away from this page."
29
  msgstr ""
30
 
31
+ #: inc/classes/admin-init.class.php:357
32
  msgid "Are you sure you want to reset all SEO settings to their defaults?"
33
  msgstr ""
34
 
35
+ #: inc/classes/admin-init.class.php:358
36
  msgid "Good"
37
  msgstr ""
38
 
39
+ #: inc/classes/admin-init.class.php:359
40
  msgid "Okay"
41
  msgstr ""
42
 
43
+ #: inc/classes/admin-init.class.php:360
44
  msgid "Bad"
45
  msgstr ""
46
 
47
+ #: inc/classes/admin-init.class.php:361
48
  msgid "Unknown"
49
  msgstr ""
50
 
51
+ #: inc/classes/admin-init.class.php:362
52
  msgid "Private:"
53
  msgstr ""
54
 
55
+ #: inc/classes/admin-init.class.php:363
56
  msgid "Protected:"
57
  msgstr ""
58
 
59
  #. translators: Pixel counter. 1: width, 2: guideline
60
 
61
+ #: inc/classes/admin-init.class.php:365
62
  msgid "%1$d out of %2$d pixels are used."
63
  msgstr ""
64
 
65
  #. translators: %s = Redirect URL markdown
66
 
67
+ #: inc/classes/admin-init.class.php:707
68
  msgid "There has been an error redirecting. Refresh the page or follow [this link](%s)."
69
  msgstr ""
70
 
71
+ #: inc/classes/admin-init.class.php:793 inc/classes/admin-init.class.php:854
72
  msgid "Image could not be processed."
73
  msgstr ""
74
 
130
 
131
  #: inc/classes/admin-pages.class.php:295
132
  #: inc/views/inpost/seo-settings-singular.php:187
133
+ #: inc/views/inpost/seo-settings-tt.php:158
134
  msgid "Robots Meta Settings"
135
  msgstr ""
136
 
203
  msgid "Characters Used: %s"
204
  msgstr ""
205
 
206
+ #: inc/classes/core.class.php:221
207
  msgid "Settings"
208
  msgstr ""
209
 
210
+ #: inc/classes/core.class.php:223
211
  msgctxt "As in: The Plugin Home Page"
212
  msgid "Home"
213
  msgstr ""
214
 
215
+ #: inc/classes/core.class.php:232
216
  msgid "https://wordpress.org/plugins/the-seo-framework-extension-manager/"
217
  msgstr ""
218
 
219
+ #: inc/classes/core.class.php:232
220
  msgctxt "Plugin extensions"
221
  msgid "Extensions"
222
  msgstr ""
223
 
224
+ #: inc/classes/core.class.php:282
225
  msgid "Dismiss"
226
  msgstr ""
227
 
228
+ #: inc/classes/core.class.php:425
229
  msgctxt "e.g. en for English, nl for Dutch, fi for Finish, de for German"
230
  msgid "en"
231
  msgstr ""
299
 
300
  #. translators: %s = But or And
301
 
302
+ #: inc/classes/doing-it-right.class.php:951
303
  msgid "%s the Title contains the Blogname multiple times."
304
  msgstr ""
305
 
306
  #. translators: 1: Word, 2: Occurrences
307
 
308
+ #: inc/classes/doing-it-right.class.php:1124
309
  msgid "%1$s is used %2$d times."
310
  msgstr ""
311
 
312
  #. Translators: %s = Post / Page / Category, etc.
313
 
314
+ #: inc/classes/doing-it-right.class.php:1169
315
  msgid "%s is being indexed."
316
  msgstr ""
317
 
318
+ #: inc/classes/doing-it-right.class.php:1178
319
  msgid "But you've discouraged indexing for the whole site."
320
  msgstr ""
321
 
322
  #. translators: 1: But or And, 2: Current taxonomy term plural label
323
 
324
+ #: inc/classes/doing-it-right.class.php:1202
325
  msgid "%1$s indexing for %2$s have been discouraged."
326
  msgstr ""
327
 
328
  #. translators: 1 = But or And, 1 = Post/Page
329
 
330
+ #: inc/classes/doing-it-right.class.php:1215
331
  msgid "%1$s the %2$s is protected from public visibility. This means indexing is discouraged."
332
  msgstr ""
333
 
334
  #. translators: %s = But or And
335
 
336
+ #: inc/classes/doing-it-right.class.php:1224
337
  msgid "%s the blog isn't set to public. This means WordPress discourages indexing."
338
  msgstr ""
339
 
340
  #. translators: %s = But or And
341
 
342
+ #: inc/classes/doing-it-right.class.php:1238
343
  msgid "%s there are no posts in this term; therefore, indexing has been discouraged."
344
  msgstr ""
345
 
346
+ #: inc/classes/doing-it-right.class.php:1322
347
  msgid "%s links aren't being followed."
348
  msgstr ""
349
 
350
+ #: inc/classes/doing-it-right.class.php:1328
351
  msgid "%s links are being followed."
352
  msgstr ""
353
 
354
  #. translators: %s = But or And
355
 
356
+ #: inc/classes/doing-it-right.class.php:1340
357
  msgid "%s you've discouraged the following of links for the whole site."
358
  msgstr ""
359
 
360
  #. translators: 1: But or And, 2: Current taxonomy term plural label
361
 
362
+ #: inc/classes/doing-it-right.class.php:1366
363
  msgid "%1$s following for %2$s have been discouraged."
364
  msgstr ""
365
 
366
  #. translators: %s = But or And
367
 
368
+ #: inc/classes/doing-it-right.class.php:1378
369
  msgid "%s the blog isn't set to public. This means WordPress allows the links to be followed regardless."
370
  msgstr ""
371
 
372
+ #: inc/classes/doing-it-right.class.php:1430
373
  msgid "Search Engines aren't allowed to archive this %s."
374
  msgstr ""
375
 
376
+ #: inc/classes/doing-it-right.class.php:1434
377
  msgid "Search Engines are allowed to archive this %s."
378
  msgstr ""
379
 
380
+ #: inc/classes/doing-it-right.class.php:1447
381
+ msgid "%s you've discouraged archiving for the whole site."
382
  msgstr ""
383
 
384
  #. translators: 1: But or And, 2: Current taxonomy term plural label
385
 
386
+ #: inc/classes/doing-it-right.class.php:1473
387
  msgid "%1$s archiving for %2$s have been discouraged."
388
  msgstr ""
389
 
390
  #. translators: %s = But or And
391
 
392
+ #: inc/classes/doing-it-right.class.php:1486
393
  msgid "%s the blog isn't set to public. This means WordPress allows the blog to be archived regardless."
394
  msgstr ""
395
 
396
+ #: inc/classes/doing-it-right.class.php:1532
397
  msgid "%s isn't being redirected."
398
  msgstr ""
399
 
400
+ #: inc/classes/doing-it-right.class.php:1574
401
+ #: inc/classes/doing-it-right.class.php:1603
402
  msgid "%s is being redirected. This means no SEO values have to be set."
403
  msgstr ""
404
 
405
+ #: inc/classes/doing-it-right.class.php:1577
406
+ #: inc/classes/doing-it-right.class.php:1619
407
  msgid "%s is not being indexed. This means no SEO values have to be set."
408
  msgstr ""
409
 
410
+ #: inc/classes/doing-it-right.class.php:1733
411
  msgid "Title:"
412
  msgstr ""
413
 
414
+ #: inc/classes/doing-it-right.class.php:1734
415
  msgid "Description:"
416
  msgstr ""
417
 
418
+ #: inc/classes/doing-it-right.class.php:1735
419
  msgid "Index:"
420
  msgstr ""
421
 
422
+ #: inc/classes/doing-it-right.class.php:1736
423
  msgid "Follow:"
424
  msgstr ""
425
 
426
+ #: inc/classes/doing-it-right.class.php:1737
427
  msgid "Archive:"
428
  msgstr ""
429
 
430
+ #: inc/classes/doing-it-right.class.php:1738
431
  msgid "Redirect:"
432
  msgstr ""
433
 
434
+ #: inc/classes/doing-it-right.class.php:1740
435
  msgid "Generated: Automatically generated."
436
  msgstr ""
437
 
438
+ #: inc/classes/doing-it-right.class.php:1742
439
  msgctxt "Generated"
440
  msgid "G"
441
  msgstr ""
442
 
443
+ #: inc/classes/doing-it-right.class.php:1743
444
  msgctxt "Title"
445
  msgid "T"
446
  msgstr ""
447
 
448
+ #: inc/classes/doing-it-right.class.php:1744
449
  msgctxt "Description"
450
  msgid "D"
451
  msgstr ""
452
 
453
+ #: inc/classes/doing-it-right.class.php:1745
454
  msgctxt "no-Index"
455
  msgid "I"
456
  msgstr ""
457
 
458
+ #: inc/classes/doing-it-right.class.php:1746
459
  msgctxt "no-Follow"
460
  msgid "F"
461
  msgstr ""
462
 
463
+ #: inc/classes/doing-it-right.class.php:1747
464
  msgctxt "no-Archive"
465
  msgid "A"
466
  msgstr ""
467
 
468
+ #: inc/classes/doing-it-right.class.php:1748
469
  msgctxt "Redirect"
470
  msgid "R"
471
  msgstr ""
472
 
473
+ #: inc/classes/doing-it-right.class.php:1750
474
  msgctxt "But there are..."
475
  msgid "But"
476
  msgstr ""
477
 
478
+ #: inc/classes/doing-it-right.class.php:1751
479
  msgctxt "And there are..."
480
  msgid "And"
481
  msgstr ""
482
 
483
+ #: inc/classes/doing-it-right.class.php:1753
484
  msgid "Length is far too short."
485
  msgstr ""
486
 
487
+ #: inc/classes/doing-it-right.class.php:1754
488
  msgid "Length is too short."
489
  msgstr ""
490
 
491
+ #: inc/classes/doing-it-right.class.php:1755
492
  msgid "Length is too long."
493
  msgstr ""
494
 
495
+ #: inc/classes/doing-it-right.class.php:1756
496
  msgid "Length is far too long."
497
  msgstr ""
498
 
499
+ #: inc/classes/doing-it-right.class.php:1757
500
  msgid "Length is good."
501
  msgstr ""
502
 
507
 
508
  #. translators: 1: Title, 2: Separator, 3: Excerpt
509
 
510
+ #: inc/classes/generate-description.class.php:652
511
  msgctxt "1: Title, 2: Separator, 3: Excerpt"
512
  msgid "%1$s %2$s %3$s"
513
  msgstr ""
514
 
515
  #. translators: 1: Title, 2: on, 3: Blogname
516
 
517
+ #: inc/classes/generate-description.class.php:863
518
  msgctxt "1: Title, 2: on, 3: Blogname"
519
  msgid "%1$s %2$s %3$s"
520
  msgstr ""
521
 
522
  #. translators: Front-end output.
523
 
524
+ #: inc/classes/generate-description.class.php:903
525
  #: inc/views/metaboxes/description-metabox.php:18
526
  msgctxt "Placement. e.g. Post Title \"on\" Blog Name"
527
  msgid "on"
529
 
530
  #. translators: Front-end output.
531
 
532
+ #: inc/classes/generate-description.class.php:995
533
  msgid "Latest posts:"
534
  msgstr ""
535
 
707
  #. translators: %s = Post Type
708
  #. translators: %s = Term type
709
 
710
+ #: inc/classes/inpost.class.php:230 inc/views/inpost/seo-settings-tt.php:94
711
  msgid "%s SEO Settings"
712
  msgstr ""
713
 
731
 
732
  #. translators: %s = 'The SEO Framework'
733
 
734
+ #: inc/classes/render.class.php:1106
735
  msgid "Start %s"
736
  msgstr ""
737
 
738
  #. translators: %s = 'The SEO Framework'
739
 
740
+ #: inc/classes/render.class.php:1108
741
  msgid "End %s"
742
  msgstr ""
743
 
744
+ #: inc/classes/render.class.php:1109
745
  msgid "by Sybre Waaijer"
746
  msgstr ""
747
 
754
  msgid "View the new options %s."
755
  msgstr ""
756
 
757
+ #: inc/classes/sitemaps.class.php:296
758
  msgid "Sitemap is generated for this view"
759
  msgstr ""
760
 
761
+ #: inc/classes/sitemaps.class.php:298
762
  msgid "Sitemap is served from cache"
763
  msgstr ""
764
 
765
+ #: inc/classes/sitemaps.class.php:595
766
  msgid "Sitemap is generated on"
767
  msgstr ""
768
 
770
  msgid "Pages"
771
  msgstr ""
772
 
773
+ #: inc/functions/tsfem-suggestion.php:91
774
+ msgid "Extension Manager"
775
+ msgstr ""
776
+
777
+ #. translators: %s: Plugin name
778
+
779
+ #: inc/functions/tsfem-suggestion.php:110
780
+ msgid "More information about %s"
781
+ msgstr ""
782
+
783
+ #. translators: 1. "A feature, e.g. Focus keywords", 2: Extension Manager.
784
+
785
+ #: inc/functions/tsfem-suggestion.php:115
786
+ msgid "Looking for %1$s? Try out the %2$s for free."
787
+ msgstr ""
788
+
789
+ #: inc/functions/tsfem-suggestion.php:118
790
+ msgid "Focus keywords"
791
+ msgstr ""
792
+
793
+ #. translators: %s: Extension Manager
794
+
795
+ #: inc/functions/tsfem-suggestion.php:143
796
+ msgid "Install the %s"
797
+ msgstr ""
798
+
799
+ #: inc/functions/tsfem-suggestion.php:144
800
+ msgid "Install Now"
801
+ msgstr ""
802
+
803
+ #: inc/functions/upgrade.php:197
804
  msgid "Twitter Photo Cards have been deprecated. Your site now uses Summary Cards when applicable."
805
  msgstr ""
806
 
807
+ #: inc/functions/upgrade.php:223
808
  msgid "The previous sitemap timestamp settings have been converted into new global timestamp settings."
809
  msgstr ""
810
 
828
  msgstr ""
829
 
830
  #: inc/views/inpost/seo-settings-singular.php:87
831
+ #: inc/views/inpost/seo-settings-tt.php:102
832
+ #: inc/views/inpost/seo-settings-tt.php:200
833
  msgid "Doing it Right"
834
  msgstr ""
835
 
837
  #. translators: %s = Post type
838
 
839
  #: inc/views/inpost/seo-settings-singular.php:108
840
+ #: inc/views/metaboxes/homepage-metabox.php:168
841
  msgid "Custom %s Title"
842
  msgstr ""
843
 
844
  #. translators: %s = Post type name
845
 
846
  #: inc/views/inpost/seo-settings-singular.php:135
847
+ #: inc/views/metaboxes/homepage-metabox.php:224
848
  msgid "Custom %s Description"
849
  msgstr ""
850
 
940
  msgid "Set preferred %s Social Image URL location."
941
  msgstr ""
942
 
943
+ #: inc/views/inpost/seo-settings-tt.php:67
944
+ #: inc/views/metaboxes/homepage-metabox.php:356
945
  msgid "This tells search engines not to show this page in their search results."
946
  msgstr ""
947
 
948
+ #: inc/views/inpost/seo-settings-tt.php:75
949
+ #: inc/views/inpost/seo-settings-tt.php:83
950
+ #: inc/views/metaboxes/homepage-metabox.php:366
951
  msgid "This tells search engines not to follow links on this page."
952
  msgstr ""
953
 
954
  #. translators: %s = Term type
955
 
956
+ #: inc/views/inpost/seo-settings-tt.php:115
957
  msgid "%s Title"
958
  msgstr ""
959
 
960
  #. translators: %s = Term type
961
 
962
+ #: inc/views/inpost/seo-settings-tt.php:140
963
  msgid "%s Meta Description"
964
  msgstr ""
965
 
966
  #. translators: %s = noindex/nofollow/noarchive
967
 
968
+ #: inc/views/inpost/seo-settings-tt.php:175
969
  msgid "Apply %s to this term?"
970
  msgstr ""
971
 
982
  msgstr ""
983
 
984
  #: inc/views/metaboxes/description-metabox.php:42
985
+ #: inc/views/metaboxes/homepage-metabox.php:239
986
  msgid "The meta description can be used to determine the text used under the title on Search Engine results pages."
987
  msgstr ""
988
 
1366
  msgstr ""
1367
 
1368
  #: inc/views/metaboxes/homepage-metabox.php:71
1369
+ #: inc/views/metaboxes/homepage-metabox.php:276
1370
+ #: inc/views/metaboxes/homepage-metabox.php:323
1371
  #: inc/views/metaboxes/social-metabox.php:318
1372
  msgid "Home Page"
1373
  msgstr ""
1374
 
1375
+ #: inc/views/metaboxes/homepage-metabox.php:135
1376
+ #: inc/views/metaboxes/homepage-metabox.php:193
1377
  msgid "Page SEO Settings"
1378
  msgstr ""
1379
 
1380
  #. translators: 1: Option, 2: Page SEO Settings, 3: Home Page
1381
 
1382
+ #: inc/views/metaboxes/homepage-metabox.php:137
1383
+ #: inc/views/metaboxes/homepage-metabox.php:191
1384
  msgid "Note: The %1$s is fetched from the %2$s on the %3$s."
1385
  msgstr ""
1386
 
1387
+ #: inc/views/metaboxes/homepage-metabox.php:154
1388
  msgid "Custom %s Title Tagline"
1389
  msgstr ""
1390
 
1391
  #. translators: %s = Home page URL markdown
1392
 
1393
+ #: inc/views/metaboxes/homepage-metabox.php:209
1394
+ #: inc/views/metaboxes/homepage-metabox.php:255
1395
  msgid "A plugin has been detected that suggests to maintain this option on the [Home Page](%s)."
1396
  msgstr ""
1397
 
1398
+ #: inc/views/metaboxes/homepage-metabox.php:281
1399
  #: inc/views/metaboxes/title-metabox.php:135
1400
  msgid "Title Additions Location"
1401
  msgstr ""
1402
 
1403
+ #: inc/views/metaboxes/homepage-metabox.php:282
1404
  #: inc/views/metaboxes/title-metabox.php:136
1405
  msgid "This setting determines which side the added title text will go on."
1406
  msgstr ""
1407
 
1408
+ #: inc/views/metaboxes/homepage-metabox.php:289
1409
  #: inc/views/metaboxes/title-metabox.php:142
1410
  msgid "Left:"
1411
  msgstr ""
1412
 
1413
+ #: inc/views/metaboxes/homepage-metabox.php:299
1414
  #: inc/views/metaboxes/title-metabox.php:149
1415
  msgid "Right:"
1416
  msgstr ""
1417
 
1418
+ #: inc/views/metaboxes/homepage-metabox.php:310
1419
  msgid "%s Tagline"
1420
  msgstr ""
1421
 
1422
+ #: inc/views/metaboxes/homepage-metabox.php:314
1423
  msgid "Add site description (tagline) to the Title on the %s?"
1424
  msgstr ""
1425
 
1426
+ #: inc/views/metaboxes/homepage-metabox.php:340
1427
  msgid "View Home Page Settings"
1428
  msgstr ""
1429
 
1430
+ #: inc/views/metaboxes/homepage-metabox.php:340
1431
  msgid "Checked in Page"
1432
  msgstr ""
1433
 
1434
+ #: inc/views/metaboxes/homepage-metabox.php:344
1435
  msgid "Home Page Robots Meta Settings"
1436
  msgstr ""
1437
 
1438
  #. translators: 1: Option, 2: Location
1439
 
1440
+ #: inc/views/metaboxes/homepage-metabox.php:353
1441
+ #: inc/views/metaboxes/homepage-metabox.php:363
1442
+ #: inc/views/metaboxes/homepage-metabox.php:373
1443
  msgid "Apply %1$s to the %2$s?"
1444
  msgstr ""
1445
 
1446
+ #: inc/views/metaboxes/homepage-metabox.php:376
1447
  msgid "This tells search engines not to save a cached copy of this page."
1448
  msgstr ""
1449
 
1450
+ #: inc/views/metaboxes/homepage-metabox.php:408
1451
  msgid "Note: If any of these options are unchecked, but are checked on the Home Page, they will be outputted regardless."
1452
  msgstr ""
1453
 
1454
+ #: inc/views/metaboxes/homepage-metabox.php:414
1455
  msgid "Home Page Pagination Robots Settings"
1456
  msgstr ""
1457
 
1458
+ #: inc/views/metaboxes/homepage-metabox.php:415
1459
  msgid "If your Home Page is paginated and outputs content that's also found elsewhere on the website, enabling this option might prevent duplicate content."
1460
  msgstr ""
1461
 
1462
  #. translators: 1: Option, 2: Location
1463
 
1464
+ #: inc/views/metaboxes/homepage-metabox.php:423
1465
  msgid "Apply %1$s to every second or later page on the %2$s?"
1466
  msgstr ""
1467
 
1468
+ #: inc/views/metaboxes/homepage-metabox.php:433
1469
  #: inc/views/metaboxes/social-metabox.php:115
1470
  msgid "Social Image Settings"
1471
  msgstr ""
1472
 
1473
+ #: inc/views/metaboxes/homepage-metabox.php:435
1474
  msgid "A social image can be displayed when your homepage is shared. It is a great way to grab attention."
1475
  msgstr ""
1476
 
1477
+ #: inc/views/metaboxes/homepage-metabox.php:464
1478
  msgid "Custom Homepage Image URL"
1479
  msgstr ""
1480
 
1481
+ #: inc/views/metaboxes/homepage-metabox.php:465
1482
  msgid "Set preferred homepage Social Image URL location."
1483
  msgstr ""
1484
 
lib/js/installer/tsfinstaller.js ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This file holds the TSF's TSFEM installer JS code.
3
+ * Serve JavaScript as an addition, not as a means.
4
+ *
5
+ * @author Sybre Waaijer <https://cyberwire.nl/>
6
+ * @link https://wordpress.org/plugins/autodescription/
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ /**
12
+ * Hooks into WordPress' updates handler.
13
+ * This is a self-constructed function assigned as an object.
14
+ *
15
+ * @since 3.0.6
16
+ *
17
+ * @constructor
18
+ * @param {!jQuery} $ jQuery object.
19
+ */
20
+ window.tsfinstaller = function( $ ) {
21
+
22
+ var $document = $( document );
23
+
24
+ /**
25
+ * Updates the UI appropriately after a successful TSFEM install.
26
+ *
27
+ * @since 3.0.6
28
+ * @credit wp.updates.installImporterSuccess
29
+ *
30
+ * @function
31
+ * @typedef {object} installTsfemSuccess
32
+ * @param {object} response Response from the server.
33
+ * @param {string} response.slug Slug of the installed plugin.
34
+ * @param {string} response.pluginName Name of the installed plugin.
35
+ * @param {string} response.activateUrl URL to activate the just installed plugin.
36
+ */
37
+ const installTsfemSuccess = function( response ) {
38
+ wp.updates.addAdminNotice( {
39
+ id: 'install-success',
40
+ className: 'notice-success is-dismissible',
41
+ message: wp.updates.l10n.installedMsg.replace( '%s', response.activateUrl + '&from=plugins' )
42
+ } );
43
+
44
+ $( '[data-slug="' + response.slug + '"]' )
45
+ .removeClass( 'install-now updating-message' )
46
+ .addClass( 'activate-now' )
47
+ .attr({
48
+ 'href': response.activateUrl + '&from=plugins',
49
+ 'aria-label': wp.updates.l10n.activatePluginLabel.replace( '%s', response.pluginName )
50
+ })
51
+ .text( wp.updates.l10n.activatePlugin );
52
+
53
+ wp.a11y.speak( wp.updates.l10n.installedMsg, 'polite' );
54
+
55
+ $document.trigger( 'tsf-tsfem-install-success', response );
56
+ }
57
+
58
+ /**
59
+ * Updates the UI appropriately after a failed TSFEM install.
60
+ *
61
+ * @since 3.0.6
62
+ * @credit wp.updates.installImporterError
63
+ *
64
+ * @function
65
+ * @typedef {object} installTsfemError
66
+ * @param {object} response Response from the server.
67
+ * @param {string} response.slug Slug of the plugin to be installed.
68
+ * @param {string=} response.pluginName Optional. Name of the plugin to be installed.
69
+ * @param {string} response.errorCode Error code for the error that occurred.
70
+ * @param {string} response.errorMessage The error that occurred.
71
+ */
72
+ const installTsfemError = function( response ) {
73
+ var errorMessage = wp.updates.l10n.installFailed.replace( '%s', response.errorMessage ),
74
+ $installLink = $( '[data-slug="' + response.slug + '"]' ),
75
+ pluginName = $installLink.data( 'name' );
76
+
77
+ if ( ! wp.updates.isValidResponse( response, 'install' ) ) {
78
+ return;
79
+ }
80
+
81
+ if ( wp.updates.maybeHandleCredentialError( response, 'install-plugin' ) ) {
82
+ return;
83
+ }
84
+
85
+ wp.updates.addAdminNotice( {
86
+ id: response.errorCode,
87
+ className: 'notice-error is-dismissible',
88
+ message: errorMessage
89
+ } );
90
+
91
+ $installLink
92
+ .removeClass( 'updating-message' )
93
+ .text( wp.updates.l10n.installNow )
94
+ .attr( 'aria-label', wp.updates.l10n.pluginInstallNowLabel.replace( '%s', pluginName ) );
95
+
96
+ wp.a11y.speak( errorMessage, 'assertive' );
97
+
98
+ $document.trigger( 'tsf-tsfem-install-error', response );
99
+ }
100
+
101
+ /**
102
+ * Adds installation hooks on DOMContentLoaded.
103
+ *
104
+ * @since 3.0.6
105
+ *
106
+ * @function
107
+ * @param {event} event
108
+ */
109
+ const onReady = ( event ) => {
110
+ if ( ! wp || ! wp.updates ) return;
111
+
112
+ var prev_addCallbacks = wp.updates._addCallbacks;
113
+
114
+ /**
115
+ * Hooks into the installation button, to prevent redirect.
116
+ *
117
+ * WordPress normally enforces a redirect when the actionable page uses index.php.
118
+ * Indicating that it's not a "valid" installation page. Which is odd, as
119
+ * it perfectly allows any other action. Plus it allows this action on any other page,
120
+ * but the admin "main === index.php" dashboard page, too.
121
+ *
122
+ * @source https://github.com/WordPress/WordPress/blob/4.9-branch/wp-admin/js/updates.js#L2395-L2415
123
+ */
124
+ $( '#plugin_install_from_iframe' ).on( 'click', function( event ) {
125
+ var target = window.parent === window ? null : window.parent,
126
+ install;
127
+
128
+ //= Let the default handler take over.
129
+ if ( -1 === window.parent.location.pathname.indexOf( 'index.php' ) )
130
+ return;
131
+
132
+ //= Only enact when the slug matches.
133
+ if ( $( this ).data( 'slug' ) !== tsfinstallerL10n.slug )
134
+ return;
135
+
136
+ $.support.postMessage = !! window.postMessage;
137
+
138
+ if ( false === $.support.postMessage || null === target ) {
139
+ return;
140
+ }
141
+
142
+ event.preventDefault();
143
+
144
+ install = {
145
+ action: 'install-plugin',
146
+ data: {
147
+ slug: $( this ).data( 'slug' )
148
+ }
149
+ };
150
+
151
+ target.postMessage( JSON.stringify( install ), window.location.origin );
152
+ } );
153
+
154
+ //= Direct attach as WP is using preventDefault() when capturing.
155
+ $( '#tsf-tsfem-tb' ).on( 'click', function( event ) {
156
+ var canReset = false;
157
+
158
+ /**
159
+ * Overwrite installer callback catcher.
160
+ *
161
+ * This could ONLY possibly conflict with import.php as of WP-4.6.0~4.9.6.
162
+ * Even then, it recovers itself via the resetter (fail-secures/safes).
163
+ * Making only super-humans (if even) viable for a UI bug.
164
+ */
165
+ wp.updates._addCallbacks = function( data, action ) {
166
+ if ( 'install-plugin' === action && tsfinstallerL10n.slug === data.slug ) {
167
+ data.success = installTsfemSuccess;
168
+ data.error = installTsfemError;
169
+
170
+ let $button = $( '[data-slug="' + data.slug + '"]' );
171
+ $button
172
+ .addClass( 'updating-message' )
173
+ .attr( 'aria-label', wp.updates.l10n.pluginInstallingLabel.replace( '%s', $button.data( 'name' ) ) )
174
+ .text( wp.updates.l10n.installing );
175
+
176
+ canReset = true;
177
+ // console.log( 'overwritten' );
178
+ }
179
+ // console.log( 'slug: ' + data.slug );
180
+
181
+ return data;
182
+ }
183
+
184
+ // Thread lightly: Pure magic below.
185
+ $( window ).on( 'message', ( event ) => {
186
+ let message;
187
+ try {
188
+ message = $.parseJSON( event.originalEvent.data );
189
+ } catch ( e ) {
190
+ return;
191
+ }
192
+ if ( ! message || 'undefined' === typeof message.action ) {
193
+ return;
194
+ }
195
+ if ( message.action === 'install-plugin' ) {
196
+ //= Fail safe.
197
+ canReset = false;
198
+ } else {
199
+ //= Fail secure.
200
+ canReset = true;
201
+ }
202
+ } );
203
+ var resetTicker, cbs;
204
+ const resetCb = () => {
205
+ wp.updates._addCallbacks = prev_addCallbacks;
206
+ clearInterval( resetTicker );
207
+ $document.off( cbs, resetCb );
208
+ // console.log( 'reset' );
209
+ }
210
+ const checkReset = () => {
211
+ canReset && resetCb;
212
+ // console.log( 'checked' );
213
+ }
214
+ const prepareReset = () => {
215
+ resetTicker = setInterval( checkReset, 100 );
216
+ setTimeout( resetCb, 750 );
217
+ // console.log( 'prepared' );
218
+ }
219
+ cbs = 'wp-plugin-installing wp-plugin-install-error wp-plugin-install-success';
220
+ //= Fail secure.
221
+ $( 'body' ).one( 'thickbox:removed', prepareReset );
222
+ $document.one( cbs, resetCb );
223
+ } );
224
+
225
+ $document.on( 'click', '#tsf-tsfem-install', function( event ) {
226
+ var $button = $( event.target );
227
+
228
+ if ( $button.hasClass( 'activate-now' ) ) {
229
+ //? Follow link, activating the plugin.
230
+ return;
231
+ }
232
+ event.preventDefault();
233
+
234
+ if ( $button.hasClass( 'updating-message' ) || $button.hasClass( 'button-disabled' ) ) {
235
+ return;
236
+ }
237
+
238
+ if ( $button.html() !== wp.updates.l10n.installing ) {
239
+ $button.data( 'originaltext', $button.html() );
240
+ }
241
+
242
+ $button
243
+ .addClass( 'updating-message' )
244
+ .attr( 'aria-label', wp.updates.l10n.pluginInstallingLabel.replace( '%s', $button.data( 'name' ) ) )
245
+ .text( wp.updates.l10n.installing );
246
+
247
+ if ( wp.updates.shouldRequestFilesystemCredentials && ! wp.updates.ajaxLocked ) {
248
+ wp.updates.requestFilesystemCredentials( event );
249
+
250
+ $document.on( 'credential-modal-cancel', function() {
251
+ $button
252
+ .removeClass( 'updating-message' )
253
+ .text( wp.updates.l10n.installNow )
254
+ .attr( 'aria-label', wp.updates.l10n.installNowLabel.replace( '%s', $button.data( 'name' ) ) );
255
+
256
+ wp.a11y.speak( wp.updates.l10n.updateCancel, 'polite' );
257
+ } );
258
+ }
259
+
260
+ wp.updates.installPlugin( {
261
+ slug: $button.data( 'slug' ),
262
+ pagenow: pagenow,
263
+ success: installTsfemSuccess,
264
+ error: installTsfemError
265
+ } );
266
+ } );
267
+ }
268
+
269
+ return {
270
+ /**
271
+ * Runs this script on DOMContentLoaded when WordPress Shiny Updates is
272
+ * available.
273
+ *
274
+ * @since 3.0.6
275
+ *
276
+ * @function
277
+ */
278
+ load: function() {
279
+ tsfinstallerL10n.canEnhance
280
+ && $( document.body ).ready( onReady );
281
+ }
282
+ };
283
+ }( jQuery );
284
+ //= Run before jQuery.ready() === DOMContentLoaded
285
+ jQuery( window.tsfinstaller.load );
lib/js/installer/tsfinstaller.min.js ADDED
@@ -0,0 +1 @@
 
1
+ 'use strict';window.tsfinstaller=function(a){var b=a(document),c=function(g){wp.updates.addAdminNotice({id:'install-success',className:'notice-success is-dismissible',message:wp.updates.l10n.installedMsg.replace('%s',g.activateUrl+'&from=plugins')}),a('[data-slug="'+g.slug+'"]').removeClass('install-now updating-message').addClass('activate-now').attr({href:g.activateUrl+'&from=plugins','aria-label':wp.updates.l10n.activatePluginLabel.replace('%s',g.pluginName)}).text(wp.updates.l10n.activatePlugin),wp.a11y.speak(wp.updates.l10n.installedMsg,'polite'),b.trigger('tsf-tsfem-install-success',g)},d=function(g){var h=wp.updates.l10n.installFailed.replace('%s',g.errorMessage),i=a('[data-slug="'+g.slug+'"]'),j=i.data('name');!wp.updates.isValidResponse(g,'install')||wp.updates.maybeHandleCredentialError(g,'install-plugin')||(wp.updates.addAdminNotice({id:g.errorCode,className:'notice-error is-dismissible',message:h}),i.removeClass('updating-message').text(wp.updates.l10n.installNow).attr('aria-label',wp.updates.l10n.pluginInstallNowLabel.replace('%s',j)),wp.a11y.speak(h,'assertive'),b.trigger('tsf-tsfem-install-error',g))},f=function(){if(wp&&wp.updates){var h=wp.updates._addCallbacks;a('#plugin_install_from_iframe').on('click',function(i){var k,j=window.parent===window?null:window.parent;-1!==window.parent.location.pathname.indexOf('index.php')&&a(this).data('slug')===tsfinstallerL10n.slug&&(a.support.postMessage=!!window.postMessage,!1===a.support.postMessage||null===j||(i.preventDefault(),k={action:'install-plugin',data:{slug:a(this).data('slug')}},j.postMessage(JSON.stringify(k),window.location.origin)))}),a('#tsf-tsfem-tb').on('click',function(){var j=!1;wp.updates._addCallbacks=function(p,q){if('install-plugin'===q&&tsfinstallerL10n.slug===p.slug){p.success=c,p.error=d;var r=a('[data-slug="'+p.slug+'"]');r.addClass('updating-message').attr('aria-label',wp.updates.l10n.pluginInstallingLabel.replace('%s',r.data('name'))).text(wp.updates.l10n.installing),j=!0}return p},a(window).on('message',function(p){var q;try{q=a.parseJSON(p.originalEvent.data)}catch(r){return}q&&'undefined'!=typeof q.action&&('install-plugin'===q.action?j=!1:j=!0)});var k,l,m=function(){wp.updates._addCallbacks=h,clearInterval(k),b.off(l,m)},n=function(){};l='wp-plugin-installing wp-plugin-install-error wp-plugin-install-success',a('body').one('thickbox:removed',function o(){k=setInterval(n,100),setTimeout(m,750)}),b.one(l,m)}),b.on('click','#tsf-tsfem-install',function(i){var j=a(i.target);j.hasClass('activate-now')||(i.preventDefault(),j.hasClass('updating-message')||j.hasClass('button-disabled')||(j.html()!==wp.updates.l10n.installing&&j.data('originaltext',j.html()),j.addClass('updating-message').attr('aria-label',wp.updates.l10n.pluginInstallingLabel.replace('%s',j.data('name'))).text(wp.updates.l10n.installing),wp.updates.shouldRequestFilesystemCredentials&&!wp.updates.ajaxLocked&&(wp.updates.requestFilesystemCredentials(i),b.on('credential-modal-cancel',function(){j.removeClass('updating-message').text(wp.updates.l10n.installNow).attr('aria-label',wp.updates.l10n.installNowLabel.replace('%s',j.data('name'))),wp.a11y.speak(wp.updates.l10n.updateCancel,'polite')})),wp.updates.installPlugin({slug:j.data('slug'),pagenow:pagenow,success:c,error:d})))})}};return{load:function load(){tsfinstallerL10n.canEnhance&&a(document.body).ready(f)}}}(jQuery),jQuery(window.tsfinstaller.load);
lib/js/tsf.js CHANGED
@@ -331,7 +331,7 @@ window.tsf = {
331
  hoverAdditionsElement,
332
  hoverAdditionsValue = '',
333
  separator = tsf.params.titleSeparator,
334
- defaultTitle = tsf.params.objectTitle;
335
 
336
  let useTagline = tsf.states.useTagline,
337
  isRTL = tsf.states.isRTL,
@@ -1121,7 +1121,7 @@ window.tsf = {
1121
  $title = jQuery( '.tsf-custom-title-js' );
1122
 
1123
  if ( 0 === val.length ) {
1124
- $title.text( tsf.params.objectTitle );
1125
  } else {
1126
  $title.text( val );
1127
  }
331
  hoverAdditionsElement,
332
  hoverAdditionsValue = '',
333
  separator = tsf.params.titleSeparator,
334
+ defaultTitle = tsf.params.defaultTitle;
335
 
336
  let useTagline = tsf.states.useTagline,
337
  isRTL = tsf.states.isRTL,
1121
  $title = jQuery( '.tsf-custom-title-js' );
1122
 
1123
  if ( 0 === val.length ) {
1124
+ $title.text( tsf.params.defaultTitle );
1125
  } else {
1126
  $title.text( val );
1127
  }
lib/js/tsf.min.js CHANGED
@@ -1 +1 @@
1
- 'use strict';window.tsf={nonces:tsfL10n.nonces,i18n:tsfL10n.i18n,states:tsfL10n.states,params:tsfL10n.params,other:tsfL10n.other,settingsChanged:!1,counterType:0,hasInput:!1,additionsClass:'',cropper:{},confirm:function(t){function s(){return t.apply(this,arguments)}return s.toString=function(){return t.toString()},s}(function(t){return confirm(t)}),escapeString:function escapeString(t){if(!t.length)return'';var s={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#039;'};return t.replace(/[&<>"']/g,function(a){return s[a]})},unescapeString:function unescapeString(t){if(!t.length)return'';var s={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#039;'},a=Object.keys(s).map(function(n){return s[n]}),o=new RegExp(a.map(function(n){return n.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&')}).join('|'),'g');return t.replace(o,function(n){return Object.keys(s).find(function(r){return s[r]===n})})},getStringLength:function getStringLength(t){var s,a=0;return t.length&&(s=document.createElement('span'),s.innerHTML=tsf.escapeString(t),a=s.childNodes[0].nodeValue.length),+a},updatePixelCounter:function updatePixelCounter(t){var s=t.e,a=t.text,o=t.guideline,n=s.parentElement;if(n){var r=n.querySelector('.tsf-pixel-counter-bar'),l=n.querySelector('.tsf-pixel-counter-shadow');if(r&&l){l.innerHTML=tsf.escapeString(a);var d=l.offsetWidth,c='',g='',f='tsf-pixel-counter-fit',u='tsf-pixel-counter-overflown';d>o?(g=100*(o/(d+2*(d-o)/3))+'%',c=u):(g=100*(d/o)+'%',c=f);var x,y=r.querySelector('.tsf-pixel-counter-fluid');x=tsf.i18n.pixelsUsed.replace(/%1\$d/g,d),x=x.replace(/%2\$d/g,o),r.classList.remove(f,u),r.classList.add(c),r.dataset.desc=x,r.setAttribute('aria-label',x),y.style.width=g,tsf._triggerTooltipUpdate(r)}}},_initTitleInputs:function _initTitleInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]');if(t.length){var o,n,r,d,s=!1,a=!!navigator.userAgent.match(/Trident\/7\./),l='',c='',g=tsf.params.titleSeparator,f=tsf.params.objectTitle,u=tsf.states.useTagline,y=tsf.states.isRTL,x=tsf.states.isPrivate,b=tsf.states.isPasswordProtected;o=y?'after':'before';var T=function(){var Y='before';tsf.states.isSettingsPage?y?'right'===jQuery('#tsf-home-title-location input:checked').val()&&(Y='after'):'left'===jQuery('#tsf-home-title-location input:checked').val()&&(Y='after'):tsf.states.isHome?y?'right'===tsf.params.titleLocation&&(Y='after'):'left'===tsf.params.titleLocation&&(Y='after'):y?'left'===tsf.params.titleLocation&&(Y='after'):'right'===tsf.params.titleLocation&&(Y='after'),n=Y};T();var C=function(){var Y='';if(!tsf.states.isSettingsPage)tsf.states.isHome?u&&(Y=tsf.params.titleAdditions):u&&(Y=tsf.params.titleAdditions);else if(u){var Z=document.getElementById('autodescription-site-settings[homepage_title_tagline]'),Q=Z?Z.value:'';Y=Q.length?Q:tsf.params.blogDescription}Y.length&&(Y=tsf.escapeString(Y),'before'===n?Y=Y+' '+g+' ':'after'===n?Y=' '+g+' '+Y:void 0),c=Y.length?Y:'',d=document.getElementById('tsf-title-placeholder'),c.length&&d&&(d.innerHTML=c)};C();var S=function(){var Y='';x?Y=tsf.i18n.privateTitle:b&&(Y=tsf.i18n.protectedTitle),Y.length&&(Y=tsf.escapeString(Y),'before'===o?Y+=' ':'after'===o?Y=' '+Y:void 0),l=Y.length?Y:'',l.length&&r&&(r.innerHTML=l),r=document.getElementById('tsf-title-placeholder-prefix'),l.length&&r&&(r.innerHTML=l)};S();var I=function(Y){if(d||r){var Z=jQuery(Y.target),Q=Z.val(),tt=!!c.length,et=!!l.length;if(!tt&&d&&(d.style.display='none'),!et&&r&&(r.style.display='none'),!tt&&!et)return void Z.css('text-indent','initial');if(!Q.length)return Z.css('text-indent','initial'),d&&(d.style.display='none'),void(r&&(r.style.display='none'));var it=Z.outerWidth(!0),st=(Z.outerHeight(!0)-Z.height())/2,at=(it-Z.innerWidth())/2,ot=y?'right':'left',nt=(Z.outerWidth(!0)-Z.width())/2,rt={display:Z.css('display'),lineHeight:Z.css('lineHeight'),fontFamily:Z.css('fontFamily'),fontWeight:Z.css('fontWeight'),fontSize:Z.css('fontSize'),letterSpacing:Z.css('letterSpacing'),paddingTop:st+'px',paddingBottom:st+'px'},lt=jQuery(r),pt=jQuery(d),dt=0,ct=0,gt=0,ft=0,ut=0,ht=0;if(et&&(lt.css(rt),lt.css({maxWidth:'initial'}),ut=lt[0].getBoundingClientRect().width,ut<ht&&(ut=0)),tt){var mt=0;switch(function(){var vt=jQuery('#tsf-title-offset');vt.text(Q),vt.css({fontFamily:rt.fontFamily,fontWeight:rt.fontWeight,letterSpacing:rt.letterSpacing,fontSize:rt.fontSize}),mt=vt[0].getBoundingClientRect().width}(),dt=Z[0].getBoundingClientRect().width-at-nt-mt-ut,dt<ht&&(ut+=dt,dt=0),pt.css(rt),pt.css({maxWidth:'initial'}),n){case'before':var yt=pt[0].getBoundingClientRect().width;yt=dt<yt?dt:yt,yt<ht&&(yt=0),dt=yt,ft+=dt,gt+=dt,ct+=nt;break;case'after':ct+=nt+mt+ut;}}gt+=nt,ut=0>ut?0:ut,ft+=ut;var xt;et&&(xt={},xt[ot]=gt+'px',xt.maxWidth=ut+'px',lt.css(xt)),tt&&(xt={},xt[ot]=ct+'px',xt.maxWidth=dt+'px',pt.css(xt)),xt={},xt['text-indent']=ft+'px',Z.css(xt)}},L=function(){var Z='',Q=!!c.length,tt=!!l.length,et=c,it=l;tsf.states.isTermEdit&&tsf.params.termName&&(it=y?' :'+tsf.params.termName:tsf.params.termName+': ',tt=tsf.states.useTermPrefix),Z=f,tt&&('before'===o?Z=it+Z:'after'===o?Z+=it:void 0),Q&&('before'===n?Z=et+Z:'after'===n?Z+=et:void 0),a&&(s=!0);var st=document.createElement('span');st.innerHTML=Z,t.prop('placeholder',st.textContent),a&&setTimeout(function(){s=!1},0)},E=function(Y){var Z=document.getElementById('tsf-title-reference'),Q='';Z&&(1>Y.target.value.length?Q=Y.target.placeholder:(Q=Y.target.value,l.length&&('before'===o?Q=l+Q:'after'===o?Q+=l:void 0),c.length&&('before'===n?Q=c+Q:'after'===n?Q+=c:void 0)),Z.innerHTML=tsf.escapeString(Q),setTimeout(function(){jQuery(Z).change()},0))},W=function(Y){var Z=document.getElementById(Y.target.id+'_chars'),Q=document.getElementById('tsf-title-reference');if(Z&&Q){var tt=tsf.getStringLength(tsf.unescapeString(Q.innerHTML)),et=Y.target,it='',st=tsf.counterType,at='',ot='';25>tt||75<=tt?(it+='tsf-count-bad',at=tsf.i18n.bad):42>tt||55<tt?(it+='tsf-count-okay',at=tsf.i18n.okay):(it+='tsf-count-good',at=tsf.i18n.good),st&&1!=st?2==st?ot=at:3==st&&(ot=tt.toString()+' - '+at):ot=tt.toString(),Z.innerHTML=ot,tsf.additionsClass&&(it+=' '+tsf.additionsClass),Z.className!==it&&(Z.className=it)}},j=function(Y){var Z=document.getElementById(Y.target.id+'_pixels'),Q=document.getElementById('tsf-title-reference');if(Z&&Q){var tt={e:Z,text:tsf.unescapeString(Q.innerHTML),guideline:tsf.params.titlePixelGuideline};tsf.updatePixelCounter(tt)}};t.on('input.tsfUpdateTitles',function H(Y){return!s&&void(I(Y),L(),E(Y),W(Y),j(Y))});t.on('tsf-update-title-counter',function R(Y){E(Y),W(Y),j(Y)});var P=function(){t.trigger('tsf-update-title-counter')},D=function(){t.trigger('input.tsfUpdateTitles')};D();var A=function(){C(),D()};jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').on('input',A),jQuery('#autodescription-site-settings\\[homepage_tagline\\]').on('change',A);var B=0,O=function(){clearTimeout(B),B=setTimeout(function(){D()},50)};jQuery(window).on('tsf-counter-updated',O);jQuery('#tsf-title-tagline-toggle :input').on('click',function U(Y){var Z=u;jQuery(Y.target).is(':checked')?(jQuery('.tsf-custom-blogname-js').css('display','inline'),u=!0):(jQuery('.tsf-custom-blogname-js').css('display','none'),u=!1),Z^u&&(C(),O())});jQuery('#visibility .save-post-visibility').on('click',function z(){var Z=jQuery('#visibility').find('input:radio:checked').val();switch(x=!1,b=!1,Z){case'password':var Q=jQuery('#visibility').find('#post_password').val();b=!!Q&&!!Q.length;break;case'private':x=!0;break;default:case'public':}S(),O()});jQuery('#tsf-title-separator :input').on('click',function q(Y){var Z=jQuery(Y.target).val(),Q='';Q='pipe'===Z?'|':'dash'===Z?'-':jQuery('<div/>').html('&'+Z+';').text(),g=Q,jQuery('.tsf-sep-js').text(' '+g+' '),C(),O()});var M=function(){var Y=tsf.settingsChanged;D(!0),tsf.settingsChanged=Y};jQuery('#homepage-tab-general').on('tsf-tab-toggled',M),jQuery('#tsf-flex-inpost-tab-general').on('tsf-flex-tab-toggled',M);var N=0,F=function(){clearTimeout(N),N=setTimeout(M,50)};jQuery(window).one('tsf-ready',function(){jQuery(window).on('tsf-flex-resize',F)});var X=['autodescription-homepage-settings','tsf-inpost-box'];jQuery(document).on('postbox-toggled',function V(Y,Z){if(0<=X.indexOf(Z.id)){var Q=Z.querySelector('.inside');0<Q.offsetHeight&&0<Q.offsetWidth&&M()}});jQuery('#tsf-home-title-location :input').on('click',function G(){T(),C(),O()});tsf.states.isHome||jQuery('#edittag #name, #titlewrap #title').on('input',function J(Y){var Z=Y.target.value;Z=Z.trim(),f=Z.length?tsf.escapeString(Z):tsf.params.untitledTitle,L(),P()});(function K(){var Y=0,Z=window.innerWidth;window.addEventListener('resize',function(){clearTimeout(Y),Y=setTimeout(function(){var Q=window.innerWidth;Z<Q?782>=Z&&782<=Q&&M():782<=Z&&782>=Q&&M(),Z=Q},50)})})()}}},_initUnboundTitleSettings:function _initUnboundTitleSettings(){if(tsf.hasInput){var t=jQuery('#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]');jQuery('#tsf-title-placeholder, #tsf-title-placeholder-prefix').on('click',function s(d){var c=jQuery(d.target).siblings(t)[0];if('function'==typeof c.setSelectionRange){c.focus();var g=2*c.value.length;c.setSelectionRange(g,g)}else{var f=c.value;c.value='',c.focus(),c.value=f}});jQuery('#autodescription-site-settings\\[title_rem_additions\\]').on('click',function a(d){jQuery(d.target).is(':checked')?jQuery('.tsf-title-additions-js').css('display','none'):jQuery('.tsf-title-additions-js').css('display','inline')});jQuery('#tsf-title-location input').on('click',function o(d){var c=jQuery('.tsf-title-additions-example-left'),g=jQuery('.tsf-title-additions-example-right');'right'===jQuery(d.target).val()?(c.css('display','none'),g.css('display','inline')):(c.css('display','inline'),g.css('display','none'))});jQuery('#autodescription-site-settings\\[homepage_title\\]').on('input',function n(d){var c=d.target.value||'',g=jQuery('.tsf-custom-title-js');0===c.length?g.text(tsf.params.objectTitle):g.text(c)});jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').on('input.tsfInputTagline',function r(d){var c=d.target.value||'',g=jQuery('.tsf-custom-tagline-js');0===c.length?(g.text(tsf.params.blogDescription),0===tsf.params.blogDescription.length?jQuery('#tsf-home-title-location .tsf-sep-js').hide():jQuery('#tsf-home-title-location .tsf-sep-js').show()):(g.text(c),jQuery('#tsf-home-title-location .tsf-sep-js').show())}),jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').trigger('input.tsfInputTagline');jQuery('#title-prefixes-toggle :input').on('click',function l(d){var c=jQuery(d.target),g=jQuery('.tsf-title-prefix-example');c.is(':checked')?g.css('display','none'):g.css('display','inline')})}},_initDescInputs:function _initDescInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]');if(t.length){var s=tsf.params.descriptionSeparator;jQuery('#tsf-description-separator input').on('click',function a(x){var b=jQuery(x.target).val(),T='';T='pipe'===b?'|':'dash'===b?'-':jQuery('<div/>').html('&'+b+';').text(),s=T,jQuery('#autodescription-descsep-js').text(' '+s+' '),g()});var o=function(x){var b=document.getElementById(x.target.id+'_chars');if(b){var T=0,C=x.target,S='',I=tsf.counterType,L='',E='';T=1>C.value.length?tsf.getStringLength(C.placeholder):tsf.getStringLength(C.value),100>T||330<=T?(S+='tsf-count-bad',L=tsf.i18n.bad):137>T||300<T?(S+='tsf-count-okay',L=tsf.i18n.okay):(S+='tsf-count-good',L=tsf.i18n.good),I&&1!=I?2==I?E=L:3==I&&(E=T.toString()+' - '+L):E=T.toString(),b.innerHTML=E,tsf.additionsClass&&(S+=' '+tsf.additionsClass),b.className!==S&&(b.className=S)}},n=function(x){var b=document.getElementById('tsf-description-reference'),T='';b&&(T=1>x.target.value.length?x.target.placeholder:x.target.value,b.innerHTML=tsf.escapeString(T),setTimeout(function(){jQuery(b).change()},0))},r=function(x){var b=document.getElementById(x.target.id+'_pixels'),T=document.getElementById('tsf-description-reference');if(b&&T){var C={e:b,text:tsf.unescapeString(T.innerHTML),guideline:tsf.params.descPixelGuideline};tsf.updatePixelCounter(C)}};t.on('input.tsfUpdateDescriptions',function l(x){n(x),o(x),r(x)});var d=function(){t.trigger('input.tsfUpdateDescriptions')};d();var c=0,g=function(){clearTimeout(c),c=setTimeout(function(){d()},50)};jQuery(window).on('tsf-counter-updated',g);var u=['autodescription-homepage-settings','tsf-inpost-box'];jQuery(document).on('postbox-toggled',function y(x,b){if(0<=u.indexOf(b.id)){var T=b.querySelector('.inside');0<T.offsetHeight&&0<T.offsetWidth&&g()}})}}},_initSocialTitleInputs:function _initSocialTitleInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_og_title'),s=jQuery('#autodescription_twitter_title'),a=jQuery('#tsf-title-reference');if(t.length&&s.length&&a.length){var o=!1,n=!!navigator.userAgent.match(/Trident\/7\./),r=tsf.escapeString(t.val()),l=tsf.escapeString(s.val()),d=a.text(),c=function(x){var b='';switch(x){case'twitter':b=l;case'og':b=b.length?b:r;case'reference':b=b.length?b:d;}return b},g=function(){n&&(o=!0),t.attr('placeholder',c('reference')),s.attr('placeholder',c('og')),n&&setTimeout(function(){o=!1},0)},f=function(x,b,T){x&&b&&T?tsf.updateSocialCounter(x,b,T):(t.each(function(C,S){return f(S,c('og'),88)}),s.each(function(C,S){return f(S,c('twitter'),70)}))};a.on('change',function(){d=a.text(),g(),f()});t.on('input.tsfUpdateOgTitle',function u(x){o||(r=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())}),s.on('input.tsfUpdateOgTitle',function y(x){o||(l=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())})}}},_initSocialDescInputs:function _initSocialDescInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_og_description'),s=jQuery('#autodescription_twitter_description'),a=jQuery('#tsf-description-reference');if(t.length&&s.length&&a.length){var o=!1,n=!!navigator.userAgent.match(/Trident\/7\./),r=tsf.escapeString(t.val()),l=tsf.escapeString(s.val()),d=a.text(),c=function(x){var b='';switch(x){case'twitter':b=l;case'og':b=b.length?b:r;case'reference':b=b.length?b:d;}return b},g=function(){n&&(o=!0),t.attr('placeholder',c('reference')),s.attr('placeholder',c('og')),n&&setTimeout(function(){o=!1},0)},f=function(x,b,T){x&&b&&T?tsf.updateSocialCounter(x,b,T):(t.each(function(C,S){return f(S,c('og'),300)}),s.each(function(C,S){return f(S,c('twitter'),200)}))};a.on('change',function(){d=a.text(),g(),f()});t.on('input.tsfUpdateOgDesc',function u(x){o||(r=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())}),s.on('input.tsfUpdateOgDesc',function y(x){o||(l=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())})}}},updateSocialCounter:function updateSocialCounter(t,s,a){var o=document.getElementById(t.id+'_chars');if(o){var n=tsf.getStringLength(tsf.unescapeString(s)),r='',l=tsf.counterType,d='',c='';n>a?(r+='tsf-count-bad',d=tsf.i18n.bad):(r+='tsf-count-good',d=tsf.i18n.good),l&&1!=l?2==l?c=d:3==l&&(c=n.toString()+' - '+d):c=n.toString(),o.innerHTML=c,tsf.additionsClass&&(r+=' '+tsf.additionsClass),o.className!==r&&(o.className=r)}},_initCounters:function _initCounters(){if(tsf.hasInput){jQuery('.tsf-counter').on('click',function t(){++tsf.counterType,3<tsf.counterType&&(tsf.counterType=0),s();var r='.tsf-counter-wrap .tsf-ajax',l=0;tsf.resetAjaxLoader(r),tsf.setAjaxLoader(r);var d={method:'POST',url:ajaxurl,datatype:'json',data:{action:'the_seo_framework_update_counter',nonce:tsf.nonces.edit_posts,val:tsf.counterType},async:!0,success:function success(c){switch(c=jQuery.parseJSON(c),'success'===c.type&&(l=1),l){case 0:tsf.unsetAjaxLoader(r,!1);break;case 1:tsf.unsetAjaxLoader(r,!0);break;default:tsf.resetAjaxLoader(r);}}};jQuery.ajax(d)});var s=function(){var n=tsf.counterType;1==n?(tsf.additionsClass='tsf-counter-one',tsf.counterType=1):2==n?(tsf.additionsClass='tsf-counter-two',tsf.counterType=2):3==n?(tsf.additionsClass='tsf-counter-three',tsf.counterType=3):(tsf.additionsClass='tsf-counter-zero',tsf.counterType=0),tsf._triggerCounterUpdate()};s();jQuery('#autodescription-site-settings\\[display_character_counter\\]').on('click',function a(n){jQuery(n.target).is(':checked')?jQuery('.tsf-counter-wrap').show():jQuery('.tsf-counter-wrap').hide()});jQuery('#autodescription-site-settings\\[display_pixel_counter\\]').on('click',function o(n){jQuery(n.target).is(':checked')?(jQuery('.tsf-pixel-counter-wrap').show(),tsf._triggerCounterUpdate()):jQuery('.tsf-pixel-counter-wrap').hide()})}},_initPrimaryTerm:function _initPrimaryTerm(){if(tsf.hasInput&&Object.keys(tsf.states.taxonomies).length){var t=tsf.states.taxonomies,s=wp.template('tsf-primary-term-selector'),a=wp.template('tsf-primary-term-selector-help'),o=document.createElement('span');o.classList.add('tsf-primary-term-selector'),o.classList.add('tsf-set-primary-term'),function(){var q=document.createElement('input');q.setAttribute('type','radio'),o.appendChild(q)}();var n={},r={},l={},d={},c={},g=function(q){var M=jQuery('#'+q+'div'),N=s({taxonomy:t[q]});M.append(N)},f=function(q){var M=jQuery('#taxonomy-'+q),N=a({taxonomy:t[q]});M.append(N),u(q)},u=function(q){var M=document.getElementById('taxonomy-'+q),N=M.querySelectorAll('.tabs-panel'),F=jQuery(M).closest('.postbox');if(!(F.length&&F.hasClass('closed'))){var X=Array.prototype.slice.call(N).filter(function(G){return 0<G.offsetWidth||0<G.offsetHeight||0<G.getClientRects().length})[0];if(X){var V=X.scrollHeight>X.clientHeight?X.offsetWidth-X.clientWidth+25-2:25;tsf.states.isRTL?M.querySelector('.tsf-primary-term-selector-help-wrap').style.left=V+'px':M.querySelector('.tsf-primary-term-selector-help-wrap').style.right=V+'px'}}},y=function(q){u(q.data.taxonomy)},x=function(q){var M=o.cloneNode(!0);return M.setAttribute('title',t[q].i18n.makePrimary),M.setAttribute('aria-label',t[q].i18n.makePrimary),M},b=function(q,M){var N=document.getElementById('autodescription[_primary_term_'+q+']');N&&N instanceof Element&&(N.value=M)},T=function(q,M){return!M&&d[q]?d[q]:(d[q]=jQuery('#'+q+'checklist, #'+q+'checklist-pop'),d[q])},C=function(q,M){return n[q].filter('[value="'+M+'"]')},S=function(q,M){var N=C(q,M).closest('label');N.length?(N.addClass('tsf-is-primary-term'),N.find('.tsf-set-primary-term').each(function(F,X){X.setAttribute('title',t[q].i18n.primary),X.setAttribute('aria-label',t[q].i18n.primary),X.querySelector('input').checked=!0}),b(q,M),c[q]=M):L(q)},I=function(q){var M=T(q).find('label');M.removeClass('tsf-is-primary-term'),M.find('.tsf-set-primary-term').each(function(N,F){F.setAttribute('title',t[q].i18n.makePrimary),F.setAttribute('aria-label',t[q].i18n.makePrimary),F.querySelector('input').checked=!1}),b(q,'')},L=function(q){var N,M=l[q].first();M.length&&(N=M.val()||'',S(q,N),c[q]=N)},E=function(q){var M=q.data.taxonomy,N=jQuery(q.target).closest('label').find('input[type=checkbox]').val();return I(M),S(M,N),!1},W=function(q){var M=q.data.taxonomy;switch(q.target.checked?(R(M,q.target),j(M,q.target)):(P(M,q.target),H(M,q.target)),l[M].length){case 0:b(M,'');break;case 1:L(M);}},j=function(q,M){var N;C(q,M.value).each(function(F,X){N=jQuery(X).closest('label'),N.find('.tsf-primary-term-selector').length||N.append(x(q))})},H=function(q,M){var N,F;C(q,M.value).each(function(X,V){N=jQuery(V).closest('label'),F=N.hasClass('tsf-is-primary-term'),N.removeClass('tsf-is-primary-term'),N.find('.tsf-primary-term-selector').remove(),F&&L(q)})},R=function(q,M){r[q]=r[q].add('[value="'+M.value+'"]'),l[q]=l[q].add(M)},P=function(q,M){r[q]=r[q].not('[value="'+M.value+'"]'),l[q]=l[q].not('[value="'+M.value+'"]')},D=function(q){u(q.data.taxonomy)},A=function(q){var M=T(q,1);n[q]=M.find('input[type=checkbox]'),r[q]=M.find('input[type=checkbox]:checked');var F,N={};l[q]=r[q],l[q].each(function(X,V){F=jQuery(V).val(),N[F]?l[q].splice(X,1):N[F]=!0})},B=function(q,M,N){N.hasOwnProperty('settings')&&N.settings.hasOwnProperty('what')&&(A(N.settings.what),O(N.settings.what),U(N.settings.what),u(N.settings.what))},O=function(q){var M='tsfShowPrimary'+q,N={taxonomy:q},F=T(q),X=jQuery('#'+q+'div'),V=jQuery('#'+q+'-tabs'),G=F.closest('.postbox');F.off('click.'+M),F.on('click.'+M,'input[type="checkbox"]',N,W),F.on('click.'+M,'.tsf-primary-term-selector',N,E),X.off('wpListAddEnd.'+M),X.on('wpListAddEnd.'+M,'#'+q+'checklist',B),V.off('click.'+M),V.on('click.'+M,'a',N,y),G.off('click.postboxes.'+M),G.on('click.postboxes.'+M,N,D)},U=function(q){T(q).find('input[type="checkbox"]:checked').each(function(M,N){j(q,N)}),t[q].primary?S(q,t[q].primary):L(q)};(function z(){for(var q in t)T(q).length&&(g(q),f(q),A(q),O(q),U(q))})()}},_initToolTips:function _initToolTips(){var t=0,s=!1,a=function(){s=!0,clearTimeout(t),t=setTimeout(function(){s=!1},250)},o=function(y,x){x=x||!1;var b='pointerdown.tsfTT touchstart.tsfTT click.tsfTT',T=jQuery(y);x?(T.off('mousemove mouseleave mouseout tsf-tooltip-update'),jQuery(document.body).off(b)):(T.on({mousemove:d,mouseleave:c,mouseout:c}),jQuery(document.body).off(b).on(b,g)),T.on('tsf-tooltip-update',r)},n=function(y){o(y,!0)},r=function(y){if(y.target.classList.contains('tsf-tooltip-item')){var x=y.target.querySelector('.tsf-tooltip-text');x instanceof Element&&(x.innerHTML=y.target.dataset.desc)}},l=function(y){var x=jQuery(y.target),b=y.target.dataset.desc;if(b&&0===x.find('div').length){y.target.title='';var T=jQuery('<div class="tsf-tooltip"><span class="tsf-tooltip-text-wrap"><span class="tsf-tooltip-text">'+b+'</span></span><div class="tsf-tooltip-arrow"></div></div>');x.append(T);var C=x.closest('.tsf-tooltip-boundary');C=C.length&&C||jQuery(document.body);var S=x.outerHeight()+9,I=T.offset().top-S,L=C.offset().top-(C.prop('scrolltop')||0);L>I?(T.addClass('tsf-tooltip-down'),T.css('top',S+'px')):T.css('bottom',S+'px');var E=x.closest('.tsf-tooltip-wrap'),W=T.find('.tsf-tooltip-text-wrap'),j=W.find('.tsf-tooltip-text'),H=E.width(),R=W.outerWidth(!0),P=j.outerWidth(!0),D=W.offset().left,A=D+P,B=C.offset().left-(C.prop('scrollLeft')||0),O=B+C.outerWidth(),U='left';if(D<B){var z=B-D+12,q=parseInt(W.css('flex-basis'),10);z<-q&&(z=-q),T.css(U,z+'px'),T.data('overflow',z),T.data('overflowDir',U)}else if(A>O){var M=O-A-H-12,N=parseInt(W.css('flex-basis'),10);M<-N&&(M=-N),T.css(U,M+'px'),T.data('overflow',M),T.data('overflowDir',U)}else if(42>H){var F=-15;T.css(U,F+'px'),T.data('overflow',F),T.data('overflowDir',U)}else if(H>R){var X=y.originalEvent&&y.originalEvent.pageX||y.pageX,V=E.offset().left,J=X-V-R/2,K=J+R;0>J?J=0:K>H&&(J=H-P),T.css(U,J+'px'),T.data('adjust',J),T.data('adjustDir',U)}}},d=function(y){var x=jQuery(y.target),b=x.find('.tsf-tooltip'),T=b.find('.tsf-tooltip-arrow'),C=b.data('overflow'),S=b.data('overflowDir');if(C=parseInt(C,10),C=isNaN(C)?0:-Math.round(C),C)T.css(S,C+'px');else{var I=y.originalEvent&&y.originalEvent.pageX||y.pageX,L=7,E=16,W=x.closest('.tsf-tooltip-wrap'),j=I-W.offset().left-E/2,R=b.find('.tsf-tooltip-text-wrap'),P=R.outerWidth(!0),D=b.data('adjust'),A=b.data('adjustDir'),B=P-E-L;if(D=parseInt(D,10),D=isNaN(D)?0:Math.round(D),D&&(D='left'===A?-D:D,j+=D,B-D>W.outerWidth(!0))){var O=R.find('.tsf-tooltip-text'),U=O.outerWidth(!0);B=U-E-L}j<=L?T.css('left',L+'px'):j>=B?T.css('left',B+'px'):T.css('left',j+'px')}},c=function(y){s||(jQuery(y.target).find('.tsf-tooltip').remove(),n(y.target))},g=function(y){a();var C,b='.tsf-tooltip',T=jQuery(y.target);if(T.hasClass('tsf-tooltip-item')&&(C=T.find(b)),!C){var S=T.children('.tsf-tooltip-item');S.length&&(C=S.find(b))}C&&C.length?jQuery(b).not(C).remove():jQuery(b).remove()},f=function(y){if(!s){var x=!1;switch(y.type){case'mouseenter':break;case'pointerdown':case'touchstart':x=!0;break;default:}if(y.target.classList.contains('tsf-tooltip-item'))x&&g(y),l(y),d(y),o(y.target);else{var b=y.target.querySelector('.tsf-tooltip-item:hover'),T=new jQuery.Event(y.type);T.pageX=y.originalEvent&&y.originalEvent.pageX||y.pageX,b?(tsfL10n.states.debug&&console.log('Tooltip event warning: delegation'),jQuery(b).trigger(T)):(tsfL10n.states.debug&&console.log('Tooltip event warning: bubbling'),jQuery(y.target).closest('.tsf-tooltip-wrap').find('.tsf-tooltip-item:hover').trigger(T))}y.stopPropagation()}},u=function(){var y=jQuery('.tsf-tooltip-wrap');y.off('mouseenter pointerdown touchstart'),y.on('mouseenter pointerdown touchstart','.tsf-tooltip-item',f)};u(),jQuery(window).on('tsf-reset-tooltips',u),function(){var y=jQuery('#wpcontent');tsf.addTooltipBoundary(y)}()},addTooltipBoundary:function addTooltipBoundary(t){jQuery(t).addClass('tsf-tooltip-boundary')},tabToggle:function tabToggle(t){var s=jQuery(t.target);if(s.is(':checked')){var a=s.prop('id'),o=s.prop('name');if('undefined'!=typeof o){var n='tsf-active-tab-content',r=jQuery('#'+a+'-content'),l=jQuery('.'+n);if(!r.is(l)&&'undefined'!=typeof r){var d=jQuery('.'+o+'-content');d.fadeOut(150,function(){jQuery(this).removeClass(n)}),setTimeout(function(){r.addClass(n).fadeIn(250)},150),setTimeout(function(){jQuery('#'+a).trigger('tsf-tab-toggled')},175)}}}},flexTabToggle:function flexTabToggle(t){var s=jQuery(t.target);if(s.is(':checked')){var a=s.prop('id'),o=s.prop('name');if('undefined'!=typeof o){var n='tsf-flex-tab-content-active',r=jQuery('#'+a+'-content'),l=jQuery('.'+n);if(!r.is(l)&&'undefined'!=typeof r){var d=jQuery('.'+o+'-content');d.fadeOut(150,function(){jQuery(this).removeClass(n)}),setTimeout(function(){r.addClass(n).fadeIn(250)},150),setTimeout(function(){jQuery('#'+a).trigger('tsf-flex-tab-toggled')},175)}}}},setTabsOnload:function setTabsOnload(){if(tsf.hasInput)if(tsf.states.isPostEdit&&jQuery('.tsf-flex-nav-tab-radio').trigger('change'),tsf.states.isSettingsPage){var t=jQuery('.tsf-nav-tab-wrapper .tsf-tab:nth-of-type(n+2) input:checked');t.length&&t.each(function(){var a=jQuery(this),o=a.prop('id'),n=a.prop('name');if('undefined'!=typeof n){var r='tsf-active-tab-content',l=jQuery('#'+o+'-content');if('undefined'!=typeof l){var d=jQuery('.'+n+'-content');d.removeClass(r),l.addClass(r),setTimeout(function(){jQuery('#'+o).trigger('tsf-tab-toggled')},20)}}})}else;},taglineToggleDesc:function taglineToggleDesc(t){var s=jQuery(t.target),a=jQuery('#tsf-on-blogname-js');s.is(':checked')?a.css('display','inline'):a.css('display','none')},additionsToggleDesc:function additionsToggleDesc(t){var s=jQuery(t.target),a=jQuery('#tsf-description-additions-js');s.is(':checked')?a.css('display','inline'):a.css('display','none')},taglineToggleOnload:function taglineToggleOnload(){if(tsf.hasInput){var t=jQuery('#tsf-title-tagline-toggle :input'),s=jQuery('.tsf-custom-blogname-js'),a=jQuery('#tsf-description-additions-toggle :input'),o=jQuery('#tsf-description-additions-js'),n=jQuery('#tsf-description-onblogname-toggle :input'),r=jQuery('#tsf-on-blogname-js'),l=jQuery('#tsf-title-additions-toggle :input'),d=jQuery('.tsf-title-additions-js');t.is(':checked')?s.css('display','inline'):s.css('display','none'),a.is(':checked')?o.css('display','inline'):o.css('display','none'),n.is(':checked')?r.css('display','inline'):r.css('display','none'),l.is(':checked')?d.css('display','none'):d.css('display','inline')}},attachUnsavedChangesListener:function attachUnsavedChangesListener(){if(tsf.hasInput){var t=function(o){tsf.settingsChanged||tsf.registerChange(),jQuery(s).not(a).off(o.type,t)},s='.tsf-metaboxes :input, #tsf-inpost-box .inside :input',a='.tsf-tab :input, .tsf-flex-nav-tab :input';jQuery(s).not(a).on('change',t),s='.tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea',a='.tsf-nav-tab-wrapper input, .tsf-flex-nav-tab-wrapper input',jQuery(s).not(a).on('input',t),window.onbeforeunload=function(){if(tsf.settingsChanged)return tsf.i18n.saveAlert},jQuery('.tsf-metaboxes input[type="submit"], #publishing-action input[type="submit"], #save-action input[type="submit"], a.submitdelete').click(function(){window.onbeforeunload=null})}},registerChange:function registerChange(){tsf.settingsChanged=!0},confirmedReset:function confirmedReset(){return confirm(tsf.i18n.confirmReset)},onLoadUnregisterChange:function onLoadUnregisterChange(){tsf.settingsChanged=!1},dismissNotice:function dismissNotice(t){jQuery(t.target).parents('.tsf-notice').slideUp(200,function(){this.remove()})},setAjaxLoader:function setAjaxLoader(t){jQuery(t).toggleClass('tsf-loading')},unsetAjaxLoader:function unsetAjaxLoader(t,s){var a='tsf-success',o=2500;s||(a='tsf-error',o=5e3),jQuery(t).removeClass('tsf-loading').addClass(a).fadeOut(o)},resetAjaxLoader:function resetAjaxLoader(t){jQuery(t).stop().empty().prop('class','tsf-ajax').css('opacity','1').removeProp('style')},openImageEditor:function openImageEditor(t){if(jQuery(t.target).prop('disabled')||'undefined'==typeof wp.media)return t.preventDefault(),void t.stopPropagation();var s=jQuery(t.target),a=s.data('inputid'),o;if(o)return void o.open();t.preventDefault(),t.stopPropagation(),tsf.extendCropper();var n={suggestedWidth:s.data('width')||1200,suggestedHeight:s.data('height')||630,isFlex:'undefined'==typeof s.data('flex')?1:s.data('flex')};tsf.cropper.control={params:{flex_width:n.isFlex?4096:0,flex_height:n.isFlex?4096:0,width:n.suggestedWidth,height:n.suggestedHeight,isFlex:n.isFlex}},o=wp.media({button:{text:tsf.other[a].frame_button,close:!1},states:[new wp.media.controller.Library({title:tsf.other[a].frame_title,library:wp.media.query({type:'image'}),multiple:!1,date:!1,priority:20,suggestedWidth:n.suggestedWidth,suggestedHeight:n.suggestedHeight}),new tsf.cropper({imgSelectOptions:tsf.calculateImageSelectOptions})]});var r=function(){o.setState('cropper')};o.off('select',r),o.on('select',r);var l=function(g){var f=g.url,u=g.id,y=g.width,x=g.height;jQuery('#'+a+'-url').val(f),jQuery('#'+a+'-id').val(u)};o.off('cropped',l),o.on('cropped',l);var d=function(g){var f=g.get('url'),u=g.get('id'),y=g.get('width'),x=g.get('height');jQuery('#'+a+'-url').val(f),jQuery('#'+a+'-id').val(u)};o.off('skippedcrop',d),o.on('skippedcrop',d);var c=function(){jQuery('#'+a+'-select').text(tsf.other[a].change),jQuery('#'+a+'-url').prop('readonly',!0).css('opacity',0).animate({opacity:1},{queue:!0,duration:1000},'swing'),tsf.appendRemoveButton(s,a,!0),tsf.registerChange()};o.off('skippedcrop cropped',c),o.on('skippedcrop cropped',c),o.open()},appendRemoveButton:function appendRemoveButton(t,s,a){t&&s&&!jQuery('#'+s+'-remove').length&&(t.after('<a href="javascript:void(0)" id="'+s+'-remove" class="tsf-remove-social-image button button-small" data-inputid="'+s+'" title="'+tsf.other[s].remove_title+'">'+tsf.other[s].remove+'</a>'),a&&jQuery('#'+s+'-remove').css('opacity',0).animate({opacity:1},{queue:!0,duration:1000},'swing')),tsf.resetImageEditorActions()},removeEditorImage:function removeEditorImage(t){var s=jQuery(t.target).data('inputid');if(!jQuery('#'+s+'-select').prop('disabled')){jQuery('#'+s+'-select').addClass('disabled').prop('disabled',!0),jQuery('#'+s+'-remove').addClass('disabled').prop('disabled',!0).fadeOut(500,function(){jQuery(this).remove(),jQuery('#'+s+'-select').text(tsf.other[s].select).removeClass('disabled').removeProp('disabled')});var a=jQuery('#'+s+'-url');a.val(''),a.data('readonly')||a.removeProp('readonly'),a.css('opacity',0).animate({opacity:1},{queue:!0,duration:500},'swing'),jQuery('#'+s+'-id').val(''),tsf.registerChange()}},extendCropper:function extendCropper(){if('undefined'==typeof tsf.cropper.control){var t,a,s=wp.media.controller,o=wp.media.view;return a=o.Cropper.extend({className:'crop-content tsf-image',ready:function ready(){o.Cropper.prototype.ready.apply(this,arguments)},onImageLoad:function onImageLoad(){var r,n=this.controller.get('imgSelectOptions');'function'==typeof n&&(n=n(this.options.attachment,this.controller)),'undefined'==typeof n.aspectRatio&&(n=_.extend(n,{parent:this.$el,onInit:function onInit(){this.parent.children().on('mousedown touchstart',function(l){l.shiftKey?r.setOptions({aspectRatio:'1:1'}):r.setOptions({aspectRatio:!1})})}})),this.trigger('image-loaded'),r=this.controller.imgSelect=this.$image.imgAreaSelect(n)}}),t=s.Cropper.extend({createCropContent:function createCropContent(){this.cropperView=new a({controller:this,attachment:this.get('selection').first()}),this.cropperView.on('image-loaded',this.createCropToolbar,this),this.frame.content.set(this.cropperView)},doCrop:function doCrop(n){var r=n.get('cropDetails'),l=tsf.cropper.control;if(l.params.flex_width&&l.params.flex_height)if(r.width===r.height)r.width>l.params.flex_width&&(r.dst_width=r.dst_height=l.params.flex_width);else if(r.width>l.params.flex_width||r.height>l.params.flex_height)if(r.width>r.height){var d=r.width/l.params.flex_width;r.dst_width=l.params.flex_width,r.dst_height=Math.round(r.height/d)}else{var c=r.height/l.params.flex_height;r.dst_height=l.params.flex_height,r.dst_width=Math.round(r.width/c)}return'undefined'==typeof r.dst_width&&(r.dst_width=0,r.dst_height=0),wp.ajax.post('tsf-crop-image',{nonce:tsf.nonces.upload_files,id:n.get('id'),context:'tsf-image',cropDetails:r})}}),t.prototype.control={},void(tsf.cropper=t)}},calculateImageSelectOptions:function calculateImageSelectOptions(t,s){var y,x,b,T,a=tsf.cropper.control,o=!!parseInt(a.params.flex_width,10),n=!!parseInt(a.params.flex_height,10),r=parseInt(a.params.width,10),l=parseInt(a.params.height,10),d=t.get('width'),c=t.get('height'),g=r/l,f=r,u=l;return T=a.params.isFlex?!tsf.mustBeCropped(a.params.flex_width,a.params.flex_height,d,c):g==d/c,s.set('control',a.params),s.set('canSkipCrop',T),d/c>g?(l=c,r=l*g):(r=d,l=r/g),y=(d-r)/2,x=(c-l)/2,b={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:d,imageHeight:c,minWidth:f>r?r:f,minHeight:u>l?l:u,x1:y,y1:x,x2:r+y,y2:l+x},a.params.isFlex?n||o?(n&&(b.minHeight=200,b.maxWidth=d),o&&(b.minWidth=200,b.maxHeight=c)):b.aspectRatio=r+':'+l:(b.handles='corners',b.aspectRatio=r+':'+l),b},mustBeCropped:function mustBeCropped(t,s,a,o){return a<=t&&o<=s?!1:!0},resetImageEditorActions:function resetImageEditorActions(){jQuery('.tsf-remove-social-image').off('click',tsf.removeEditorImage),jQuery('.tsf-remove-social-image').on('click',tsf.removeEditorImage)},setupImageEditorActions:function setupImageEditorActions(){jQuery('.tsf-set-social-image').off('click',tsf.openImageEditor),jQuery('.tsf-remove-social-image').off('click',tsf.removeEditorImage),jQuery('.tsf-set-social-image').on('click',tsf.openImageEditor),jQuery('.tsf-remove-social-image').on('click',tsf.removeEditorImage)},checkImageEditorInput:function checkImageEditorInput(){var t=jQuery('.tsf-set-social-image');if(t.length){var s='',a='';jQuery.each(t,function(o,n){s=jQuery(n).data('inputid'),a=jQuery('#'+s+'-id'),a.length&&0<a.val()&&(jQuery('#'+s+'-url').prop('readonly',!0),tsf.appendRemoveButton(jQuery(n),s,!1)),jQuery('#'+s+'-url').val()&&jQuery('#'+s+'-select').text(tsf.other[s].change)})}},setColorOnload:function setColorOnload(){var t=jQuery('.tsf-color-picker');t.length&&jQuery.each(t,function(s,a){var o=jQuery(a),n='',r=o.data('tsf-default-color');o.wpColorPicker({defaultColor:r,width:238,change:function change(){n=o.wpColorPicker('color'),''==n&&(n=r),o.val(n),tsf.registerChange()},clear:function clear(){o.parent().siblings('.wp-color-result').css('backgroundColor',r),tsf.registerChange()},palettes:!1})})},_doFlexResizeListener:function _doFlexResizeListener(){if(jQuery('.tsf-flex').length){tsf._setResizeListeners();var t=0,s={},a=0,o=jQuery('.tsf-flex-nav-tab-wrapper'),n=jQuery(window);n.on('tsf-flex-resize',function(){clearTimeout(t);var r=0;t=setTimeout(function(){if(o.length){var l=jQuery('.tsf-flex-nav-tab-inner'),d=o.width(),c=l.width(),g=jQuery('.tsf-flex-nav-name');s.tabWrapper||(s.tabWrapper={},s.tabWrapper.outer=0,s.tabWrapper.inner=0,s.tabWrapper.shown=1),!s.tabWrapper.shown&&s.tabWrapper.outer<d&&(g.fadeIn(250),setTimeout(function(){c=l.width()},r)),setTimeout(function(){c>d?(g.hide(),s.tabWrapper.shown=0):s.tabWrapper.outer<d&&(g.fadeIn(250),s.tabWrapper.shown=1)},2*r),setTimeout(function(){s.tabWrapper.outer=d,s.tabWrapper.inner=c},3*r)}},a),r=10,a=75}),n.trigger('tsf-flex-resize')}},_setResizeListeners:function _setResizeListeners(){jQuery(window).on('resize orientationchange',tsf._triggerResize),jQuery('#collapse-menu').click(tsf._triggerResize),jQuery('.columns-prefs :input[type=radio]').change(tsf._triggerResize),jQuery('.meta-box-sortables').on('sortupdate',tsf._triggerResize)},_triggerTooltipReset:function _triggerTooltipReset(){jQuery(window).trigger('tsf-reset-tooltips')},_triggerTooltipUpdate:function _triggerTooltipUpdate(t){jQuery(t).trigger('tsf-tooltip-update')},_triggerResize:function _triggerResize(){jQuery(window).trigger('tsf-flex-resize')},_triggerCounterUpdate:function _triggerCounterUpdate(){jQuery(window).trigger('tsf-counter-updated')},_triggerReady:function _triggerReady(){jQuery(document.body).trigger('tsf-ready')},_doReady:function _doReady(){tsf._initCounters(),tsf._initTitleInputs(),tsf._initUnboundTitleSettings(),tsf._initSocialTitleInputs(),tsf._initDescInputs(),tsf._initSocialDescInputs(),tsf._initPrimaryTerm(),tsf.setTabsOnload(),tsf.taglineToggleOnload(),tsf._initToolTips(),tsf.setupImageEditorActions(),tsf.checkImageEditorInput(),tsf.setColorOnload(),tsf.attachUnsavedChangesListener(),tsf.onLoadUnregisterChange(),tsf._doFlexResizeListener(),tsf._triggerReady()},setupVars:function setupVars(){tsf.counterType=parseInt(tsf.states.counterType),tsf.hasInput=tsf.states.hasInput},ready:function ready(t){tsf.setupVars(),t('div.updated, div.error, div.notice-warning').insertAfter('div.tsf-top-wrap'),t(document.body).ready(tsf._doReady),t('.tsf-js-confirm-reset').on('click',tsf.confirmedReset),t('.tsf-tabs-radio').on('change',tsf.tabToggle),t('.tsf-flex-nav-tab-radio').on('change',tsf.flexTabToggle),t('#tsf-description-onblogname-toggle :input').on('click',tsf.taglineToggleDesc),t('#tsf-description-additions-toggle :input').on('click',tsf.additionsToggleDesc),t('.tsf-dismiss').on('click',tsf.dismissNotice)}},jQuery(tsf.ready);
1
+ 'use strict';window.tsf={nonces:tsfL10n.nonces,i18n:tsfL10n.i18n,states:tsfL10n.states,params:tsfL10n.params,other:tsfL10n.other,settingsChanged:!1,counterType:0,hasInput:!1,additionsClass:'',cropper:{},confirm:function(t){function s(){return t.apply(this,arguments)}return s.toString=function(){return t.toString()},s}(function(t){return confirm(t)}),escapeString:function escapeString(t){if(!t.length)return'';var s={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#039;'};return t.replace(/[&<>"']/g,function(a){return s[a]})},unescapeString:function unescapeString(t){if(!t.length)return'';var s={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;','\'':'&#039;'},a=Object.keys(s).map(function(n){return s[n]}),o=new RegExp(a.map(function(n){return n.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&')}).join('|'),'g');return t.replace(o,function(n){return Object.keys(s).find(function(r){return s[r]===n})})},getStringLength:function getStringLength(t){var s,a=0;return t.length&&(s=document.createElement('span'),s.innerHTML=tsf.escapeString(t),a=s.childNodes[0].nodeValue.length),+a},updatePixelCounter:function updatePixelCounter(t){var s=t.e,a=t.text,o=t.guideline,n=s.parentElement;if(n){var r=n.querySelector('.tsf-pixel-counter-bar'),l=n.querySelector('.tsf-pixel-counter-shadow');if(r&&l){l.innerHTML=tsf.escapeString(a);var d=l.offsetWidth,c='',g='',f='tsf-pixel-counter-fit',u='tsf-pixel-counter-overflown';d>o?(g=100*(o/(d+2*(d-o)/3))+'%',c=u):(g=100*(d/o)+'%',c=f);var x,y=r.querySelector('.tsf-pixel-counter-fluid');x=tsf.i18n.pixelsUsed.replace(/%1\$d/g,d),x=x.replace(/%2\$d/g,o),r.classList.remove(f,u),r.classList.add(c),r.dataset.desc=x,r.setAttribute('aria-label',x),y.style.width=g,tsf._triggerTooltipUpdate(r)}}},_initTitleInputs:function _initTitleInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]');if(t.length){var o,n,r,d,s=!1,a=!!navigator.userAgent.match(/Trident\/7\./),l='',c='',g=tsf.params.titleSeparator,f=tsf.params.defaultTitle,u=tsf.states.useTagline,y=tsf.states.isRTL,x=tsf.states.isPrivate,b=tsf.states.isPasswordProtected;o=y?'after':'before';var T=function(){var Y='before';tsf.states.isSettingsPage?y?'right'===jQuery('#tsf-home-title-location input:checked').val()&&(Y='after'):'left'===jQuery('#tsf-home-title-location input:checked').val()&&(Y='after'):tsf.states.isHome?y?'right'===tsf.params.titleLocation&&(Y='after'):'left'===tsf.params.titleLocation&&(Y='after'):y?'left'===tsf.params.titleLocation&&(Y='after'):'right'===tsf.params.titleLocation&&(Y='after'),n=Y};T();var C=function(){var Y='';if(!tsf.states.isSettingsPage)tsf.states.isHome?u&&(Y=tsf.params.titleAdditions):u&&(Y=tsf.params.titleAdditions);else if(u){var Z=document.getElementById('autodescription-site-settings[homepage_title_tagline]'),Q=Z?Z.value:'';Y=Q.length?Q:tsf.params.blogDescription}Y.length&&(Y=tsf.escapeString(Y),'before'===n?Y=Y+' '+g+' ':'after'===n?Y=' '+g+' '+Y:void 0),c=Y.length?Y:'',d=document.getElementById('tsf-title-placeholder'),c.length&&d&&(d.innerHTML=c)};C();var S=function(){var Y='';x?Y=tsf.i18n.privateTitle:b&&(Y=tsf.i18n.protectedTitle),Y.length&&(Y=tsf.escapeString(Y),'before'===o?Y+=' ':'after'===o?Y=' '+Y:void 0),l=Y.length?Y:'',l.length&&r&&(r.innerHTML=l),r=document.getElementById('tsf-title-placeholder-prefix'),l.length&&r&&(r.innerHTML=l)};S();var I=function(Y){if(d||r){var Z=jQuery(Y.target),Q=Z.val(),tt=!!c.length,et=!!l.length;if(!tt&&d&&(d.style.display='none'),!et&&r&&(r.style.display='none'),!tt&&!et)return void Z.css('text-indent','initial');if(!Q.length)return Z.css('text-indent','initial'),d&&(d.style.display='none'),void(r&&(r.style.display='none'));var it=Z.outerWidth(!0),st=(Z.outerHeight(!0)-Z.height())/2,at=(it-Z.innerWidth())/2,ot=y?'right':'left',nt=(Z.outerWidth(!0)-Z.width())/2,rt={display:Z.css('display'),lineHeight:Z.css('lineHeight'),fontFamily:Z.css('fontFamily'),fontWeight:Z.css('fontWeight'),fontSize:Z.css('fontSize'),letterSpacing:Z.css('letterSpacing'),paddingTop:st+'px',paddingBottom:st+'px'},lt=jQuery(r),pt=jQuery(d),dt=0,ct=0,gt=0,ft=0,ut=0,ht=0;if(et&&(lt.css(rt),lt.css({maxWidth:'initial'}),ut=lt[0].getBoundingClientRect().width,ut<ht&&(ut=0)),tt){var mt=0;switch(function(){var vt=jQuery('#tsf-title-offset');vt.text(Q),vt.css({fontFamily:rt.fontFamily,fontWeight:rt.fontWeight,letterSpacing:rt.letterSpacing,fontSize:rt.fontSize}),mt=vt[0].getBoundingClientRect().width}(),dt=Z[0].getBoundingClientRect().width-at-nt-mt-ut,dt<ht&&(ut+=dt,dt=0),pt.css(rt),pt.css({maxWidth:'initial'}),n){case'before':var yt=pt[0].getBoundingClientRect().width;yt=dt<yt?dt:yt,yt<ht&&(yt=0),dt=yt,ft+=dt,gt+=dt,ct+=nt;break;case'after':ct+=nt+mt+ut;}}gt+=nt,ut=0>ut?0:ut,ft+=ut;var xt;et&&(xt={},xt[ot]=gt+'px',xt.maxWidth=ut+'px',lt.css(xt)),tt&&(xt={},xt[ot]=ct+'px',xt.maxWidth=dt+'px',pt.css(xt)),xt={},xt['text-indent']=ft+'px',Z.css(xt)}},L=function(){var Z='',Q=!!c.length,tt=!!l.length,et=c,it=l;tsf.states.isTermEdit&&tsf.params.termName&&(it=y?' :'+tsf.params.termName:tsf.params.termName+': ',tt=tsf.states.useTermPrefix),Z=f,tt&&('before'===o?Z=it+Z:'after'===o?Z+=it:void 0),Q&&('before'===n?Z=et+Z:'after'===n?Z+=et:void 0),a&&(s=!0);var st=document.createElement('span');st.innerHTML=Z,t.prop('placeholder',st.textContent),a&&setTimeout(function(){s=!1},0)},E=function(Y){var Z=document.getElementById('tsf-title-reference'),Q='';Z&&(1>Y.target.value.length?Q=Y.target.placeholder:(Q=Y.target.value,l.length&&('before'===o?Q=l+Q:'after'===o?Q+=l:void 0),c.length&&('before'===n?Q=c+Q:'after'===n?Q+=c:void 0)),Z.innerHTML=tsf.escapeString(Q),setTimeout(function(){jQuery(Z).change()},0))},W=function(Y){var Z=document.getElementById(Y.target.id+'_chars'),Q=document.getElementById('tsf-title-reference');if(Z&&Q){var tt=tsf.getStringLength(tsf.unescapeString(Q.innerHTML)),et=Y.target,it='',st=tsf.counterType,at='',ot='';25>tt||75<=tt?(it+='tsf-count-bad',at=tsf.i18n.bad):42>tt||55<tt?(it+='tsf-count-okay',at=tsf.i18n.okay):(it+='tsf-count-good',at=tsf.i18n.good),st&&1!=st?2==st?ot=at:3==st&&(ot=tt.toString()+' - '+at):ot=tt.toString(),Z.innerHTML=ot,tsf.additionsClass&&(it+=' '+tsf.additionsClass),Z.className!==it&&(Z.className=it)}},j=function(Y){var Z=document.getElementById(Y.target.id+'_pixels'),Q=document.getElementById('tsf-title-reference');if(Z&&Q){var tt={e:Z,text:tsf.unescapeString(Q.innerHTML),guideline:tsf.params.titlePixelGuideline};tsf.updatePixelCounter(tt)}};t.on('input.tsfUpdateTitles',function H(Y){return!s&&void(I(Y),L(),E(Y),W(Y),j(Y))});t.on('tsf-update-title-counter',function R(Y){E(Y),W(Y),j(Y)});var P=function(){t.trigger('tsf-update-title-counter')},D=function(){t.trigger('input.tsfUpdateTitles')};D();var A=function(){C(),D()};jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').on('input',A),jQuery('#autodescription-site-settings\\[homepage_tagline\\]').on('change',A);var B=0,O=function(){clearTimeout(B),B=setTimeout(function(){D()},50)};jQuery(window).on('tsf-counter-updated',O);jQuery('#tsf-title-tagline-toggle :input').on('click',function U(Y){var Z=u;jQuery(Y.target).is(':checked')?(jQuery('.tsf-custom-blogname-js').css('display','inline'),u=!0):(jQuery('.tsf-custom-blogname-js').css('display','none'),u=!1),Z^u&&(C(),O())});jQuery('#visibility .save-post-visibility').on('click',function z(){var Z=jQuery('#visibility').find('input:radio:checked').val();switch(x=!1,b=!1,Z){case'password':var Q=jQuery('#visibility').find('#post_password').val();b=!!Q&&!!Q.length;break;case'private':x=!0;break;default:case'public':}S(),O()});jQuery('#tsf-title-separator :input').on('click',function q(Y){var Z=jQuery(Y.target).val(),Q='';Q='pipe'===Z?'|':'dash'===Z?'-':jQuery('<div/>').html('&'+Z+';').text(),g=Q,jQuery('.tsf-sep-js').text(' '+g+' '),C(),O()});var M=function(){var Y=tsf.settingsChanged;D(!0),tsf.settingsChanged=Y};jQuery('#homepage-tab-general').on('tsf-tab-toggled',M),jQuery('#tsf-flex-inpost-tab-general').on('tsf-flex-tab-toggled',M);var N=0,F=function(){clearTimeout(N),N=setTimeout(M,50)};jQuery(window).one('tsf-ready',function(){jQuery(window).on('tsf-flex-resize',F)});var X=['autodescription-homepage-settings','tsf-inpost-box'];jQuery(document).on('postbox-toggled',function V(Y,Z){if(0<=X.indexOf(Z.id)){var Q=Z.querySelector('.inside');0<Q.offsetHeight&&0<Q.offsetWidth&&M()}});jQuery('#tsf-home-title-location :input').on('click',function G(){T(),C(),O()});tsf.states.isHome||jQuery('#edittag #name, #titlewrap #title').on('input',function J(Y){var Z=Y.target.value;Z=Z.trim(),f=Z.length?tsf.escapeString(Z):tsf.params.untitledTitle,L(),P()});(function K(){var Y=0,Z=window.innerWidth;window.addEventListener('resize',function(){clearTimeout(Y),Y=setTimeout(function(){var Q=window.innerWidth;Z<Q?782>=Z&&782<=Q&&M():782<=Z&&782>=Q&&M(),Z=Q},50)})})()}}},_initUnboundTitleSettings:function _initUnboundTitleSettings(){if(tsf.hasInput){var t=jQuery('#autodescription_title, #autodescription-meta\\[doctitle\\], #autodescription-site-settings\\[homepage_title\\]');jQuery('#tsf-title-placeholder, #tsf-title-placeholder-prefix').on('click',function s(d){var c=jQuery(d.target).siblings(t)[0];if('function'==typeof c.setSelectionRange){c.focus();var g=2*c.value.length;c.setSelectionRange(g,g)}else{var f=c.value;c.value='',c.focus(),c.value=f}});jQuery('#autodescription-site-settings\\[title_rem_additions\\]').on('click',function a(d){jQuery(d.target).is(':checked')?jQuery('.tsf-title-additions-js').css('display','none'):jQuery('.tsf-title-additions-js').css('display','inline')});jQuery('#tsf-title-location input').on('click',function o(d){var c=jQuery('.tsf-title-additions-example-left'),g=jQuery('.tsf-title-additions-example-right');'right'===jQuery(d.target).val()?(c.css('display','none'),g.css('display','inline')):(c.css('display','inline'),g.css('display','none'))});jQuery('#autodescription-site-settings\\[homepage_title\\]').on('input',function n(d){var c=d.target.value||'',g=jQuery('.tsf-custom-title-js');0===c.length?g.text(tsf.params.defaultTitle):g.text(c)});jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').on('input.tsfInputTagline',function r(d){var c=d.target.value||'',g=jQuery('.tsf-custom-tagline-js');0===c.length?(g.text(tsf.params.blogDescription),0===tsf.params.blogDescription.length?jQuery('#tsf-home-title-location .tsf-sep-js').hide():jQuery('#tsf-home-title-location .tsf-sep-js').show()):(g.text(c),jQuery('#tsf-home-title-location .tsf-sep-js').show())}),jQuery('#autodescription-site-settings\\[homepage_title_tagline\\]').trigger('input.tsfInputTagline');jQuery('#title-prefixes-toggle :input').on('click',function l(d){var c=jQuery(d.target),g=jQuery('.tsf-title-prefix-example');c.is(':checked')?g.css('display','none'):g.css('display','inline')})}},_initDescInputs:function _initDescInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_description, #autodescription-meta\\[description\\], #autodescription-site-settings\\[homepage_description\\]');if(t.length){var s=tsf.params.descriptionSeparator;jQuery('#tsf-description-separator input').on('click',function a(x){var b=jQuery(x.target).val(),T='';T='pipe'===b?'|':'dash'===b?'-':jQuery('<div/>').html('&'+b+';').text(),s=T,jQuery('#autodescription-descsep-js').text(' '+s+' '),g()});var o=function(x){var b=document.getElementById(x.target.id+'_chars');if(b){var T=0,C=x.target,S='',I=tsf.counterType,L='',E='';T=1>C.value.length?tsf.getStringLength(C.placeholder):tsf.getStringLength(C.value),100>T||330<=T?(S+='tsf-count-bad',L=tsf.i18n.bad):137>T||300<T?(S+='tsf-count-okay',L=tsf.i18n.okay):(S+='tsf-count-good',L=tsf.i18n.good),I&&1!=I?2==I?E=L:3==I&&(E=T.toString()+' - '+L):E=T.toString(),b.innerHTML=E,tsf.additionsClass&&(S+=' '+tsf.additionsClass),b.className!==S&&(b.className=S)}},n=function(x){var b=document.getElementById('tsf-description-reference'),T='';b&&(T=1>x.target.value.length?x.target.placeholder:x.target.value,b.innerHTML=tsf.escapeString(T),setTimeout(function(){jQuery(b).change()},0))},r=function(x){var b=document.getElementById(x.target.id+'_pixels'),T=document.getElementById('tsf-description-reference');if(b&&T){var C={e:b,text:tsf.unescapeString(T.innerHTML),guideline:tsf.params.descPixelGuideline};tsf.updatePixelCounter(C)}};t.on('input.tsfUpdateDescriptions',function l(x){n(x),o(x),r(x)});var d=function(){t.trigger('input.tsfUpdateDescriptions')};d();var c=0,g=function(){clearTimeout(c),c=setTimeout(function(){d()},50)};jQuery(window).on('tsf-counter-updated',g);var u=['autodescription-homepage-settings','tsf-inpost-box'];jQuery(document).on('postbox-toggled',function y(x,b){if(0<=u.indexOf(b.id)){var T=b.querySelector('.inside');0<T.offsetHeight&&0<T.offsetWidth&&g()}})}}},_initSocialTitleInputs:function _initSocialTitleInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_og_title'),s=jQuery('#autodescription_twitter_title'),a=jQuery('#tsf-title-reference');if(t.length&&s.length&&a.length){var o=!1,n=!!navigator.userAgent.match(/Trident\/7\./),r=tsf.escapeString(t.val()),l=tsf.escapeString(s.val()),d=a.text(),c=function(x){var b='';switch(x){case'twitter':b=l;case'og':b=b.length?b:r;case'reference':b=b.length?b:d;}return b},g=function(){n&&(o=!0),t.attr('placeholder',c('reference')),s.attr('placeholder',c('og')),n&&setTimeout(function(){o=!1},0)},f=function(x,b,T){x&&b&&T?tsf.updateSocialCounter(x,b,T):(t.each(function(C,S){return f(S,c('og'),88)}),s.each(function(C,S){return f(S,c('twitter'),70)}))};a.on('change',function(){d=a.text(),g(),f()});t.on('input.tsfUpdateOgTitle',function u(x){o||(r=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())}),s.on('input.tsfUpdateOgTitle',function y(x){o||(l=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())})}}},_initSocialDescInputs:function _initSocialDescInputs(){if(tsf.hasInput){var t=jQuery('#autodescription_og_description'),s=jQuery('#autodescription_twitter_description'),a=jQuery('#tsf-description-reference');if(t.length&&s.length&&a.length){var o=!1,n=!!navigator.userAgent.match(/Trident\/7\./),r=tsf.escapeString(t.val()),l=tsf.escapeString(s.val()),d=a.text(),c=function(x){var b='';switch(x){case'twitter':b=l;case'og':b=b.length?b:r;case'reference':b=b.length?b:d;}return b},g=function(){n&&(o=!0),t.attr('placeholder',c('reference')),s.attr('placeholder',c('og')),n&&setTimeout(function(){o=!1},0)},f=function(x,b,T){x&&b&&T?tsf.updateSocialCounter(x,b,T):(t.each(function(C,S){return f(S,c('og'),300)}),s.each(function(C,S){return f(S,c('twitter'),200)}))};a.on('change',function(){d=a.text(),g(),f()});t.on('input.tsfUpdateOgDesc',function u(x){o||(r=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())}),s.on('input.tsfUpdateOgDesc',function y(x){o||(l=x.target.value.length?tsf.escapeString(x.target.value):'',g(),f())})}}},updateSocialCounter:function updateSocialCounter(t,s,a){var o=document.getElementById(t.id+'_chars');if(o){var n=tsf.getStringLength(tsf.unescapeString(s)),r='',l=tsf.counterType,d='',c='';n>a?(r+='tsf-count-bad',d=tsf.i18n.bad):(r+='tsf-count-good',d=tsf.i18n.good),l&&1!=l?2==l?c=d:3==l&&(c=n.toString()+' - '+d):c=n.toString(),o.innerHTML=c,tsf.additionsClass&&(r+=' '+tsf.additionsClass),o.className!==r&&(o.className=r)}},_initCounters:function _initCounters(){if(tsf.hasInput){jQuery('.tsf-counter').on('click',function t(){++tsf.counterType,3<tsf.counterType&&(tsf.counterType=0),s();var r='.tsf-counter-wrap .tsf-ajax',l=0;tsf.resetAjaxLoader(r),tsf.setAjaxLoader(r);var d={method:'POST',url:ajaxurl,datatype:'json',data:{action:'the_seo_framework_update_counter',nonce:tsf.nonces.edit_posts,val:tsf.counterType},async:!0,success:function success(c){switch(c=jQuery.parseJSON(c),'success'===c.type&&(l=1),l){case 0:tsf.unsetAjaxLoader(r,!1);break;case 1:tsf.unsetAjaxLoader(r,!0);break;default:tsf.resetAjaxLoader(r);}}};jQuery.ajax(d)});var s=function(){var n=tsf.counterType;1==n?(tsf.additionsClass='tsf-counter-one',tsf.counterType=1):2==n?(tsf.additionsClass='tsf-counter-two',tsf.counterType=2):3==n?(tsf.additionsClass='tsf-counter-three',tsf.counterType=3):(tsf.additionsClass='tsf-counter-zero',tsf.counterType=0),tsf._triggerCounterUpdate()};s();jQuery('#autodescription-site-settings\\[display_character_counter\\]').on('click',function a(n){jQuery(n.target).is(':checked')?jQuery('.tsf-counter-wrap').show():jQuery('.tsf-counter-wrap').hide()});jQuery('#autodescription-site-settings\\[display_pixel_counter\\]').on('click',function o(n){jQuery(n.target).is(':checked')?(jQuery('.tsf-pixel-counter-wrap').show(),tsf._triggerCounterUpdate()):jQuery('.tsf-pixel-counter-wrap').hide()})}},_initPrimaryTerm:function _initPrimaryTerm(){if(tsf.hasInput&&Object.keys(tsf.states.taxonomies).length){var t=tsf.states.taxonomies,s=wp.template('tsf-primary-term-selector'),a=wp.template('tsf-primary-term-selector-help'),o=document.createElement('span');o.classList.add('tsf-primary-term-selector'),o.classList.add('tsf-set-primary-term'),function(){var q=document.createElement('input');q.setAttribute('type','radio'),o.appendChild(q)}();var n={},r={},l={},d={},c={},g=function(q){var M=jQuery('#'+q+'div'),N=s({taxonomy:t[q]});M.append(N)},f=function(q){var M=jQuery('#taxonomy-'+q),N=a({taxonomy:t[q]});M.append(N),u(q)},u=function(q){var M=document.getElementById('taxonomy-'+q),N=M.querySelectorAll('.tabs-panel'),F=jQuery(M).closest('.postbox');if(!(F.length&&F.hasClass('closed'))){var X=Array.prototype.slice.call(N).filter(function(G){return 0<G.offsetWidth||0<G.offsetHeight||0<G.getClientRects().length})[0];if(X){var V=X.scrollHeight>X.clientHeight?X.offsetWidth-X.clientWidth+25-2:25;tsf.states.isRTL?M.querySelector('.tsf-primary-term-selector-help-wrap').style.left=V+'px':M.querySelector('.tsf-primary-term-selector-help-wrap').style.right=V+'px'}}},y=function(q){u(q.data.taxonomy)},x=function(q){var M=o.cloneNode(!0);return M.setAttribute('title',t[q].i18n.makePrimary),M.setAttribute('aria-label',t[q].i18n.makePrimary),M},b=function(q,M){var N=document.getElementById('autodescription[_primary_term_'+q+']');N&&N instanceof Element&&(N.value=M)},T=function(q,M){return!M&&d[q]?d[q]:(d[q]=jQuery('#'+q+'checklist, #'+q+'checklist-pop'),d[q])},C=function(q,M){return n[q].filter('[value="'+M+'"]')},S=function(q,M){var N=C(q,M).closest('label');N.length?(N.addClass('tsf-is-primary-term'),N.find('.tsf-set-primary-term').each(function(F,X){X.setAttribute('title',t[q].i18n.primary),X.setAttribute('aria-label',t[q].i18n.primary),X.querySelector('input').checked=!0}),b(q,M),c[q]=M):L(q)},I=function(q){var M=T(q).find('label');M.removeClass('tsf-is-primary-term'),M.find('.tsf-set-primary-term').each(function(N,F){F.setAttribute('title',t[q].i18n.makePrimary),F.setAttribute('aria-label',t[q].i18n.makePrimary),F.querySelector('input').checked=!1}),b(q,'')},L=function(q){var N,M=l[q].first();M.length&&(N=M.val()||'',S(q,N),c[q]=N)},E=function(q){var M=q.data.taxonomy,N=jQuery(q.target).closest('label').find('input[type=checkbox]').val();return I(M),S(M,N),!1},W=function(q){var M=q.data.taxonomy;switch(q.target.checked?(R(M,q.target),j(M,q.target)):(P(M,q.target),H(M,q.target)),l[M].length){case 0:b(M,'');break;case 1:L(M);}},j=function(q,M){var N;C(q,M.value).each(function(F,X){N=jQuery(X).closest('label'),N.find('.tsf-primary-term-selector').length||N.append(x(q))})},H=function(q,M){var N,F;C(q,M.value).each(function(X,V){N=jQuery(V).closest('label'),F=N.hasClass('tsf-is-primary-term'),N.removeClass('tsf-is-primary-term'),N.find('.tsf-primary-term-selector').remove(),F&&L(q)})},R=function(q,M){r[q]=r[q].add('[value="'+M.value+'"]'),l[q]=l[q].add(M)},P=function(q,M){r[q]=r[q].not('[value="'+M.value+'"]'),l[q]=l[q].not('[value="'+M.value+'"]')},D=function(q){u(q.data.taxonomy)},A=function(q){var M=T(q,1);n[q]=M.find('input[type=checkbox]'),r[q]=M.find('input[type=checkbox]:checked');var F,N={};l[q]=r[q],l[q].each(function(X,V){F=jQuery(V).val(),N[F]?l[q].splice(X,1):N[F]=!0})},B=function(q,M,N){N.hasOwnProperty('settings')&&N.settings.hasOwnProperty('what')&&(A(N.settings.what),O(N.settings.what),U(N.settings.what),u(N.settings.what))},O=function(q){var M='tsfShowPrimary'+q,N={taxonomy:q},F=T(q),X=jQuery('#'+q+'div'),V=jQuery('#'+q+'-tabs'),G=F.closest('.postbox');F.off('click.'+M),F.on('click.'+M,'input[type="checkbox"]',N,W),F.on('click.'+M,'.tsf-primary-term-selector',N,E),X.off('wpListAddEnd.'+M),X.on('wpListAddEnd.'+M,'#'+q+'checklist',B),V.off('click.'+M),V.on('click.'+M,'a',N,y),G.off('click.postboxes.'+M),G.on('click.postboxes.'+M,N,D)},U=function(q){T(q).find('input[type="checkbox"]:checked').each(function(M,N){j(q,N)}),t[q].primary?S(q,t[q].primary):L(q)};(function z(){for(var q in t)T(q).length&&(g(q),f(q),A(q),O(q),U(q))})()}},_initToolTips:function _initToolTips(){var t=0,s=!1,a=function(){s=!0,clearTimeout(t),t=setTimeout(function(){s=!1},250)},o=function(y,x){x=x||!1;var b='pointerdown.tsfTT touchstart.tsfTT click.tsfTT',T=jQuery(y);x?(T.off('mousemove mouseleave mouseout tsf-tooltip-update'),jQuery(document.body).off(b)):(T.on({mousemove:d,mouseleave:c,mouseout:c}),jQuery(document.body).off(b).on(b,g)),T.on('tsf-tooltip-update',r)},n=function(y){o(y,!0)},r=function(y){if(y.target.classList.contains('tsf-tooltip-item')){var x=y.target.querySelector('.tsf-tooltip-text');x instanceof Element&&(x.innerHTML=y.target.dataset.desc)}},l=function(y){var x=jQuery(y.target),b=y.target.dataset.desc;if(b&&0===x.find('div').length){y.target.title='';var T=jQuery('<div class="tsf-tooltip"><span class="tsf-tooltip-text-wrap"><span class="tsf-tooltip-text">'+b+'</span></span><div class="tsf-tooltip-arrow"></div></div>');x.append(T);var C=x.closest('.tsf-tooltip-boundary');C=C.length&&C||jQuery(document.body);var S=x.outerHeight()+9,I=T.offset().top-S,L=C.offset().top-(C.prop('scrolltop')||0);L>I?(T.addClass('tsf-tooltip-down'),T.css('top',S+'px')):T.css('bottom',S+'px');var E=x.closest('.tsf-tooltip-wrap'),W=T.find('.tsf-tooltip-text-wrap'),j=W.find('.tsf-tooltip-text'),H=E.width(),R=W.outerWidth(!0),P=j.outerWidth(!0),D=W.offset().left,A=D+P,B=C.offset().left-(C.prop('scrollLeft')||0),O=B+C.outerWidth(),U='left';if(D<B){var z=B-D+12,q=parseInt(W.css('flex-basis'),10);z<-q&&(z=-q),T.css(U,z+'px'),T.data('overflow',z),T.data('overflowDir',U)}else if(A>O){var M=O-A-H-12,N=parseInt(W.css('flex-basis'),10);M<-N&&(M=-N),T.css(U,M+'px'),T.data('overflow',M),T.data('overflowDir',U)}else if(42>H){var F=-15;T.css(U,F+'px'),T.data('overflow',F),T.data('overflowDir',U)}else if(H>R){var X=y.originalEvent&&y.originalEvent.pageX||y.pageX,V=E.offset().left,J=X-V-R/2,K=J+R;0>J?J=0:K>H&&(J=H-P),T.css(U,J+'px'),T.data('adjust',J),T.data('adjustDir',U)}}},d=function(y){var x=jQuery(y.target),b=x.find('.tsf-tooltip'),T=b.find('.tsf-tooltip-arrow'),C=b.data('overflow'),S=b.data('overflowDir');if(C=parseInt(C,10),C=isNaN(C)?0:-Math.round(C),C)T.css(S,C+'px');else{var I=y.originalEvent&&y.originalEvent.pageX||y.pageX,L=7,E=16,W=x.closest('.tsf-tooltip-wrap'),j=I-W.offset().left-E/2,R=b.find('.tsf-tooltip-text-wrap'),P=R.outerWidth(!0),D=b.data('adjust'),A=b.data('adjustDir'),B=P-E-L;if(D=parseInt(D,10),D=isNaN(D)?0:Math.round(D),D&&(D='left'===A?-D:D,j+=D,B-D>W.outerWidth(!0))){var O=R.find('.tsf-tooltip-text'),U=O.outerWidth(!0);B=U-E-L}j<=L?T.css('left',L+'px'):j>=B?T.css('left',B+'px'):T.css('left',j+'px')}},c=function(y){s||(jQuery(y.target).find('.tsf-tooltip').remove(),n(y.target))},g=function(y){a();var C,b='.tsf-tooltip',T=jQuery(y.target);if(T.hasClass('tsf-tooltip-item')&&(C=T.find(b)),!C){var S=T.children('.tsf-tooltip-item');S.length&&(C=S.find(b))}C&&C.length?jQuery(b).not(C).remove():jQuery(b).remove()},f=function(y){if(!s){var x=!1;switch(y.type){case'mouseenter':break;case'pointerdown':case'touchstart':x=!0;break;default:}if(y.target.classList.contains('tsf-tooltip-item'))x&&g(y),l(y),d(y),o(y.target);else{var b=y.target.querySelector('.tsf-tooltip-item:hover'),T=new jQuery.Event(y.type);T.pageX=y.originalEvent&&y.originalEvent.pageX||y.pageX,b?(tsfL10n.states.debug&&console.log('Tooltip event warning: delegation'),jQuery(b).trigger(T)):(tsfL10n.states.debug&&console.log('Tooltip event warning: bubbling'),jQuery(y.target).closest('.tsf-tooltip-wrap').find('.tsf-tooltip-item:hover').trigger(T))}y.stopPropagation()}},u=function(){var y=jQuery('.tsf-tooltip-wrap');y.off('mouseenter pointerdown touchstart'),y.on('mouseenter pointerdown touchstart','.tsf-tooltip-item',f)};u(),jQuery(window).on('tsf-reset-tooltips',u),function(){var y=jQuery('#wpcontent');tsf.addTooltipBoundary(y)}()},addTooltipBoundary:function addTooltipBoundary(t){jQuery(t).addClass('tsf-tooltip-boundary')},tabToggle:function tabToggle(t){var s=jQuery(t.target);if(s.is(':checked')){var a=s.prop('id'),o=s.prop('name');if('undefined'!=typeof o){var n='tsf-active-tab-content',r=jQuery('#'+a+'-content'),l=jQuery('.'+n);if(!r.is(l)&&'undefined'!=typeof r){var d=jQuery('.'+o+'-content');d.fadeOut(150,function(){jQuery(this).removeClass(n)}),setTimeout(function(){r.addClass(n).fadeIn(250)},150),setTimeout(function(){jQuery('#'+a).trigger('tsf-tab-toggled')},175)}}}},flexTabToggle:function flexTabToggle(t){var s=jQuery(t.target);if(s.is(':checked')){var a=s.prop('id'),o=s.prop('name');if('undefined'!=typeof o){var n='tsf-flex-tab-content-active',r=jQuery('#'+a+'-content'),l=jQuery('.'+n);if(!r.is(l)&&'undefined'!=typeof r){var d=jQuery('.'+o+'-content');d.fadeOut(150,function(){jQuery(this).removeClass(n)}),setTimeout(function(){r.addClass(n).fadeIn(250)},150),setTimeout(function(){jQuery('#'+a).trigger('tsf-flex-tab-toggled')},175)}}}},setTabsOnload:function setTabsOnload(){if(tsf.hasInput)if(tsf.states.isPostEdit&&jQuery('.tsf-flex-nav-tab-radio').trigger('change'),tsf.states.isSettingsPage){var t=jQuery('.tsf-nav-tab-wrapper .tsf-tab:nth-of-type(n+2) input:checked');t.length&&t.each(function(){var a=jQuery(this),o=a.prop('id'),n=a.prop('name');if('undefined'!=typeof n){var r='tsf-active-tab-content',l=jQuery('#'+o+'-content');if('undefined'!=typeof l){var d=jQuery('.'+n+'-content');d.removeClass(r),l.addClass(r),setTimeout(function(){jQuery('#'+o).trigger('tsf-tab-toggled')},20)}}})}else;},taglineToggleDesc:function taglineToggleDesc(t){var s=jQuery(t.target),a=jQuery('#tsf-on-blogname-js');s.is(':checked')?a.css('display','inline'):a.css('display','none')},additionsToggleDesc:function additionsToggleDesc(t){var s=jQuery(t.target),a=jQuery('#tsf-description-additions-js');s.is(':checked')?a.css('display','inline'):a.css('display','none')},taglineToggleOnload:function taglineToggleOnload(){if(tsf.hasInput){var t=jQuery('#tsf-title-tagline-toggle :input'),s=jQuery('.tsf-custom-blogname-js'),a=jQuery('#tsf-description-additions-toggle :input'),o=jQuery('#tsf-description-additions-js'),n=jQuery('#tsf-description-onblogname-toggle :input'),r=jQuery('#tsf-on-blogname-js'),l=jQuery('#tsf-title-additions-toggle :input'),d=jQuery('.tsf-title-additions-js');t.is(':checked')?s.css('display','inline'):s.css('display','none'),a.is(':checked')?o.css('display','inline'):o.css('display','none'),n.is(':checked')?r.css('display','inline'):r.css('display','none'),l.is(':checked')?d.css('display','none'):d.css('display','inline')}},attachUnsavedChangesListener:function attachUnsavedChangesListener(){if(tsf.hasInput){var t=function(o){tsf.settingsChanged||tsf.registerChange(),jQuery(s).not(a).off(o.type,t)},s='.tsf-metaboxes :input, #tsf-inpost-box .inside :input',a='.tsf-tab :input, .tsf-flex-nav-tab :input';jQuery(s).not(a).on('change',t),s='.tsf-metaboxes input[type=text], .tsf-metaboxes textarea, #tsf-inpost-box .inside input[type=text], #tsf-inpost-box .inside textarea',a='.tsf-nav-tab-wrapper input, .tsf-flex-nav-tab-wrapper input',jQuery(s).not(a).on('input',t),window.onbeforeunload=function(){if(tsf.settingsChanged)return tsf.i18n.saveAlert},jQuery('.tsf-metaboxes input[type="submit"], #publishing-action input[type="submit"], #save-action input[type="submit"], a.submitdelete').click(function(){window.onbeforeunload=null})}},registerChange:function registerChange(){tsf.settingsChanged=!0},confirmedReset:function confirmedReset(){return confirm(tsf.i18n.confirmReset)},onLoadUnregisterChange:function onLoadUnregisterChange(){tsf.settingsChanged=!1},dismissNotice:function dismissNotice(t){jQuery(t.target).parents('.tsf-notice').slideUp(200,function(){this.remove()})},setAjaxLoader:function setAjaxLoader(t){jQuery(t).toggleClass('tsf-loading')},unsetAjaxLoader:function unsetAjaxLoader(t,s){var a='tsf-success',o=2500;s||(a='tsf-error',o=5e3),jQuery(t).removeClass('tsf-loading').addClass(a).fadeOut(o)},resetAjaxLoader:function resetAjaxLoader(t){jQuery(t).stop().empty().prop('class','tsf-ajax').css('opacity','1').removeProp('style')},openImageEditor:function openImageEditor(t){if(jQuery(t.target).prop('disabled')||'undefined'==typeof wp.media)return t.preventDefault(),void t.stopPropagation();var s=jQuery(t.target),a=s.data('inputid'),o;if(o)return void o.open();t.preventDefault(),t.stopPropagation(),tsf.extendCropper();var n={suggestedWidth:s.data('width')||1200,suggestedHeight:s.data('height')||630,isFlex:'undefined'==typeof s.data('flex')?1:s.data('flex')};tsf.cropper.control={params:{flex_width:n.isFlex?4096:0,flex_height:n.isFlex?4096:0,width:n.suggestedWidth,height:n.suggestedHeight,isFlex:n.isFlex}},o=wp.media({button:{text:tsf.other[a].frame_button,close:!1},states:[new wp.media.controller.Library({title:tsf.other[a].frame_title,library:wp.media.query({type:'image'}),multiple:!1,date:!1,priority:20,suggestedWidth:n.suggestedWidth,suggestedHeight:n.suggestedHeight}),new tsf.cropper({imgSelectOptions:tsf.calculateImageSelectOptions})]});var r=function(){o.setState('cropper')};o.off('select',r),o.on('select',r);var l=function(g){var f=g.url,u=g.id,y=g.width,x=g.height;jQuery('#'+a+'-url').val(f),jQuery('#'+a+'-id').val(u)};o.off('cropped',l),o.on('cropped',l);var d=function(g){var f=g.get('url'),u=g.get('id'),y=g.get('width'),x=g.get('height');jQuery('#'+a+'-url').val(f),jQuery('#'+a+'-id').val(u)};o.off('skippedcrop',d),o.on('skippedcrop',d);var c=function(){jQuery('#'+a+'-select').text(tsf.other[a].change),jQuery('#'+a+'-url').prop('readonly',!0).css('opacity',0).animate({opacity:1},{queue:!0,duration:1000},'swing'),tsf.appendRemoveButton(s,a,!0),tsf.registerChange()};o.off('skippedcrop cropped',c),o.on('skippedcrop cropped',c),o.open()},appendRemoveButton:function appendRemoveButton(t,s,a){t&&s&&!jQuery('#'+s+'-remove').length&&(t.after('<a href="javascript:void(0)" id="'+s+'-remove" class="tsf-remove-social-image button button-small" data-inputid="'+s+'" title="'+tsf.other[s].remove_title+'">'+tsf.other[s].remove+'</a>'),a&&jQuery('#'+s+'-remove').css('opacity',0).animate({opacity:1},{queue:!0,duration:1000},'swing')),tsf.resetImageEditorActions()},removeEditorImage:function removeEditorImage(t){var s=jQuery(t.target).data('inputid');if(!jQuery('#'+s+'-select').prop('disabled')){jQuery('#'+s+'-select').addClass('disabled').prop('disabled',!0),jQuery('#'+s+'-remove').addClass('disabled').prop('disabled',!0).fadeOut(500,function(){jQuery(this).remove(),jQuery('#'+s+'-select').text(tsf.other[s].select).removeClass('disabled').removeProp('disabled')});var a=jQuery('#'+s+'-url');a.val(''),a.data('readonly')||a.removeProp('readonly'),a.css('opacity',0).animate({opacity:1},{queue:!0,duration:500},'swing'),jQuery('#'+s+'-id').val(''),tsf.registerChange()}},extendCropper:function extendCropper(){if('undefined'==typeof tsf.cropper.control){var t,a,s=wp.media.controller,o=wp.media.view;return a=o.Cropper.extend({className:'crop-content tsf-image',ready:function ready(){o.Cropper.prototype.ready.apply(this,arguments)},onImageLoad:function onImageLoad(){var r,n=this.controller.get('imgSelectOptions');'function'==typeof n&&(n=n(this.options.attachment,this.controller)),'undefined'==typeof n.aspectRatio&&(n=_.extend(n,{parent:this.$el,onInit:function onInit(){this.parent.children().on('mousedown touchstart',function(l){l.shiftKey?r.setOptions({aspectRatio:'1:1'}):r.setOptions({aspectRatio:!1})})}})),this.trigger('image-loaded'),r=this.controller.imgSelect=this.$image.imgAreaSelect(n)}}),t=s.Cropper.extend({createCropContent:function createCropContent(){this.cropperView=new a({controller:this,attachment:this.get('selection').first()}),this.cropperView.on('image-loaded',this.createCropToolbar,this),this.frame.content.set(this.cropperView)},doCrop:function doCrop(n){var r=n.get('cropDetails'),l=tsf.cropper.control;if(l.params.flex_width&&l.params.flex_height)if(r.width===r.height)r.width>l.params.flex_width&&(r.dst_width=r.dst_height=l.params.flex_width);else if(r.width>l.params.flex_width||r.height>l.params.flex_height)if(r.width>r.height){var d=r.width/l.params.flex_width;r.dst_width=l.params.flex_width,r.dst_height=Math.round(r.height/d)}else{var c=r.height/l.params.flex_height;r.dst_height=l.params.flex_height,r.dst_width=Math.round(r.width/c)}return'undefined'==typeof r.dst_width&&(r.dst_width=0,r.dst_height=0),wp.ajax.post('tsf-crop-image',{nonce:tsf.nonces.upload_files,id:n.get('id'),context:'tsf-image',cropDetails:r})}}),t.prototype.control={},void(tsf.cropper=t)}},calculateImageSelectOptions:function calculateImageSelectOptions(t,s){var y,x,b,T,a=tsf.cropper.control,o=!!parseInt(a.params.flex_width,10),n=!!parseInt(a.params.flex_height,10),r=parseInt(a.params.width,10),l=parseInt(a.params.height,10),d=t.get('width'),c=t.get('height'),g=r/l,f=r,u=l;return T=a.params.isFlex?!tsf.mustBeCropped(a.params.flex_width,a.params.flex_height,d,c):g==d/c,s.set('control',a.params),s.set('canSkipCrop',T),d/c>g?(l=c,r=l*g):(r=d,l=r/g),y=(d-r)/2,x=(c-l)/2,b={handles:!0,keys:!0,instance:!0,persistent:!0,imageWidth:d,imageHeight:c,minWidth:f>r?r:f,minHeight:u>l?l:u,x1:y,y1:x,x2:r+y,y2:l+x},a.params.isFlex?n||o?(n&&(b.minHeight=200,b.maxWidth=d),o&&(b.minWidth=200,b.maxHeight=c)):b.aspectRatio=r+':'+l:(b.handles='corners',b.aspectRatio=r+':'+l),b},mustBeCropped:function mustBeCropped(t,s,a,o){return a<=t&&o<=s?!1:!0},resetImageEditorActions:function resetImageEditorActions(){jQuery('.tsf-remove-social-image').off('click',tsf.removeEditorImage),jQuery('.tsf-remove-social-image').on('click',tsf.removeEditorImage)},setupImageEditorActions:function setupImageEditorActions(){jQuery('.tsf-set-social-image').off('click',tsf.openImageEditor),jQuery('.tsf-remove-social-image').off('click',tsf.removeEditorImage),jQuery('.tsf-set-social-image').on('click',tsf.openImageEditor),jQuery('.tsf-remove-social-image').on('click',tsf.removeEditorImage)},checkImageEditorInput:function checkImageEditorInput(){var t=jQuery('.tsf-set-social-image');if(t.length){var s='',a='';jQuery.each(t,function(o,n){s=jQuery(n).data('inputid'),a=jQuery('#'+s+'-id'),a.length&&0<a.val()&&(jQuery('#'+s+'-url').prop('readonly',!0),tsf.appendRemoveButton(jQuery(n),s,!1)),jQuery('#'+s+'-url').val()&&jQuery('#'+s+'-select').text(tsf.other[s].change)})}},setColorOnload:function setColorOnload(){var t=jQuery('.tsf-color-picker');t.length&&jQuery.each(t,function(s,a){var o=jQuery(a),n='',r=o.data('tsf-default-color');o.wpColorPicker({defaultColor:r,width:238,change:function change(){n=o.wpColorPicker('color'),''==n&&(n=r),o.val(n),tsf.registerChange()},clear:function clear(){o.parent().siblings('.wp-color-result').css('backgroundColor',r),tsf.registerChange()},palettes:!1})})},_doFlexResizeListener:function _doFlexResizeListener(){if(jQuery('.tsf-flex').length){tsf._setResizeListeners();var t=0,s={},a=0,o=jQuery('.tsf-flex-nav-tab-wrapper'),n=jQuery(window);n.on('tsf-flex-resize',function(){clearTimeout(t);var r=0;t=setTimeout(function(){if(o.length){var l=jQuery('.tsf-flex-nav-tab-inner'),d=o.width(),c=l.width(),g=jQuery('.tsf-flex-nav-name');s.tabWrapper||(s.tabWrapper={},s.tabWrapper.outer=0,s.tabWrapper.inner=0,s.tabWrapper.shown=1),!s.tabWrapper.shown&&s.tabWrapper.outer<d&&(g.fadeIn(250),setTimeout(function(){c=l.width()},r)),setTimeout(function(){c>d?(g.hide(),s.tabWrapper.shown=0):s.tabWrapper.outer<d&&(g.fadeIn(250),s.tabWrapper.shown=1)},2*r),setTimeout(function(){s.tabWrapper.outer=d,s.tabWrapper.inner=c},3*r)}},a),r=10,a=75}),n.trigger('tsf-flex-resize')}},_setResizeListeners:function _setResizeListeners(){jQuery(window).on('resize orientationchange',tsf._triggerResize),jQuery('#collapse-menu').click(tsf._triggerResize),jQuery('.columns-prefs :input[type=radio]').change(tsf._triggerResize),jQuery('.meta-box-sortables').on('sortupdate',tsf._triggerResize)},_triggerTooltipReset:function _triggerTooltipReset(){jQuery(window).trigger('tsf-reset-tooltips')},_triggerTooltipUpdate:function _triggerTooltipUpdate(t){jQuery(t).trigger('tsf-tooltip-update')},_triggerResize:function _triggerResize(){jQuery(window).trigger('tsf-flex-resize')},_triggerCounterUpdate:function _triggerCounterUpdate(){jQuery(window).trigger('tsf-counter-updated')},_triggerReady:function _triggerReady(){jQuery(document.body).trigger('tsf-ready')},_doReady:function _doReady(){tsf._initCounters(),tsf._initTitleInputs(),tsf._initUnboundTitleSettings(),tsf._initSocialTitleInputs(),tsf._initDescInputs(),tsf._initSocialDescInputs(),tsf._initPrimaryTerm(),tsf.setTabsOnload(),tsf.taglineToggleOnload(),tsf._initToolTips(),tsf.setupImageEditorActions(),tsf.checkImageEditorInput(),tsf.setColorOnload(),tsf.attachUnsavedChangesListener(),tsf.onLoadUnregisterChange(),tsf._doFlexResizeListener(),tsf._triggerReady()},setupVars:function setupVars(){tsf.counterType=parseInt(tsf.states.counterType),tsf.hasInput=tsf.states.hasInput},ready:function ready(t){tsf.setupVars(),t('div.updated, div.error, div.notice-warning').insertAfter('div.tsf-top-wrap'),t(document.body).ready(tsf._doReady),t('.tsf-js-confirm-reset').on('click',tsf.confirmedReset),t('.tsf-tabs-radio').on('change',tsf.tabToggle),t('.tsf-flex-nav-tab-radio').on('change',tsf.flexTabToggle),t('#tsf-description-onblogname-toggle :input').on('click',tsf.taglineToggleDesc),t('#tsf-description-additions-toggle :input').on('click',tsf.additionsToggleDesc),t('.tsf-dismiss').on('click',tsf.dismissNotice)}},jQuery(tsf.ready);
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: Cybr
3
  Donate link: https://theseoframework.com/donate/
4
  Tags: SEO, XML Sitemap, Google, Open Graph, Schema.org, Twitter
5
  Requires at least: 4.4.0
6
- Tested up to: 4.9.4
7
  Requires PHP: 5.3.0
8
- Stable tag: 3.0.5
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -91,7 +91,7 @@ Nobody has to know about the tools you've used to create your or someone else's
91
  * Automated description output options.
92
  * Schema.org structured data output options.
93
  * Various robots meta output options.
94
- * Many homepage specific options.
95
  * Facebook, Twitter, and Pinterest social integration options.
96
  * Google, Bing, Pinterest and Yandex webmaster verification codes.
97
  * Sitemap integration with personalization.
@@ -131,7 +131,7 @@ A caching plugin isn't even needed for this plugin as you won't notice a differe
131
  * Detection of robots.txt and sitemap.xml files.
132
  * Both up-to-date and outdated themes.
133
  * Detection of various other popular SEO tools to prevent duplicated output.
134
- * Translation plugins like WPML, Polylang, and qTranslate X.
135
  * WooCommerce, for free, in all its glory.
136
 
137
  = An additional sitemap =
@@ -151,7 +151,7 @@ The Breadcrumb script generated by this plugin on Posts will also make sure Goog
151
 
152
  = Installation instructions: =
153
 
154
- 1. Install The SEO Framework either via the WordPress.org plugin directory or by uploading the files to your server.
155
  1. Either Network Activate this plugin or activate it on a single site.
156
  1. That's it!
157
 
@@ -159,7 +159,7 @@ The Breadcrumb script generated by this plugin on Posts will also make sure Goog
159
 
160
  * Check out the SEO settings page to fine-tune your settings.
161
  * Do fill in the Schema "General" and "Presence" settings.
162
- * Do fill in the Homepage "General" settings.
163
  * Do fill in the Social Meta "General", "Facebook" and "Twitter" settings.
164
  * Notice that red checkboxes are recommended to be left unchecked. And green checkboxes are recommended to be checked.
165
  * These color-coded boxes are shown in non-Gecko browsers, i.e. everything but Firefox.
@@ -241,11 +241,45 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
241
 
242
  == Changelog ==
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  = 3.0.5 - Rectified =
245
 
246
  **Release date:**
247
 
248
- * February 27th, 2017
249
 
250
  **Summarized:**
251
 
@@ -257,7 +291,7 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
257
 
258
  **Release date:**
259
 
260
- * February 25th, 2017
261
 
262
  **Did you know?**
263
 
@@ -267,7 +301,7 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
267
 
268
  **Summarized:**
269
 
270
- * This is a maintenance release with over 10 bugs fixed. Most notoriously were pixel guideline calculation errors and homepage title errors.
271
  * Open Graph and Twitter custom title and description options have been added to every post, page, and CPT.
272
  * The description character count and pixel length guidelines have been updated.
273
  * All publicly queryable CPT posts and pages now support SEO settings and are included in the sitemap. No more messing with filters is needed.
@@ -275,7 +309,7 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
275
  **About the new description guidelines:**
276
 
277
  * Google increased their SERP's description length a few months ago, so we've updated the upper-limit guidelines.
278
- * We recommend enforcing these new guidelines for new pages, cornerstone pages, and the homepage.
279
  * Although the description lengths have been updated, the transient cache isn't invalidated.
280
  * Over time the cache will refresh itself, this is done automatically by WordPress, or via your caching plugin's transients handler (if applicable).
281
 
@@ -364,7 +398,7 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
364
  * It now uses WordPress' 4.6+ canonical URL generation (backward-compatibility is provided), instead of an in-house "guessing" version.
365
  * **So, the Canonical URL should now always be compatible with any plugin, out of the box.** This is great news for translation plugin users!
366
  * Note that canonical URLs are no longer outputted on private or unpublished posts.
367
- * Note that if a query isn't registered correctly, the URL will also stay empty. Or, in unlikely cases, it will link to the homepage.
368
  * Contact the respective plugin author on such issues. I'd love to help them correct this.
369
 
370
  **Finally, author SEO:**
@@ -439,7 +473,7 @@ Transporting Categories, Tags and other terms' SEO data isn't supported.
439
  A major update. Make a backup of your database before upgrading.
440
 
441
  = 2.9.3 =
442
- A highly recommended update that fixes "Homepage as Blog" query issues.
443
 
444
  = 2.8.0 =
445
  In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.
3
  Donate link: https://theseoframework.com/donate/
4
  Tags: SEO, XML Sitemap, Google, Open Graph, Schema.org, Twitter
5
  Requires at least: 4.4.0
6
+ Tested up to: 4.9.8
7
  Requires PHP: 5.3.0
8
+ Stable tag: 3.0.6
9
  License: GPLv3
10
  License URI: http://www.gnu.org/licenses/gpl-3.0.html
11
 
91
  * Automated description output options.
92
  * Schema.org structured data output options.
93
  * Various robots meta output options.
94
+ * Many home page specific options.
95
  * Facebook, Twitter, and Pinterest social integration options.
96
  * Google, Bing, Pinterest and Yandex webmaster verification codes.
97
  * Sitemap integration with personalization.
131
  * Detection of robots.txt and sitemap.xml files.
132
  * Both up-to-date and outdated themes.
133
  * Detection of various other popular SEO tools to prevent duplicated output.
134
+ * Translation plugins like WPML, Polylang, WPGlobus and MultilingualPress.
135
  * WooCommerce, for free, in all its glory.
136
 
137
  = An additional sitemap =
151
 
152
  = Installation instructions: =
153
 
154
+ 1. Install "The SEO Framework" either via the WordPress.org plugin directory or by uploading the files to your server.
155
  1. Either Network Activate this plugin or activate it on a single site.
156
  1. That's it!
157
 
159
 
160
  * Check out the SEO settings page to fine-tune your settings.
161
  * Do fill in the Schema "General" and "Presence" settings.
162
+ * Do fill in the Home Page "General" settings.
163
  * Do fill in the Social Meta "General", "Facebook" and "Twitter" settings.
164
  * Notice that red checkboxes are recommended to be left unchecked. And green checkboxes are recommended to be checked.
165
  * These color-coded boxes are shown in non-Gecko browsers, i.e. everything but Firefox.
241
 
242
  == Changelog ==
243
 
244
+ = 3.0.6 - Lionize =
245
+
246
+ **Release date**
247
+
248
+ * May 6th, 2018
249
+
250
+ **Summarized:**
251
+
252
+ * TSF now integrates completely with attachment pages.
253
+ * Non-personalized Facebook profile links can now be set via the Social SEO settings and user's Authorial Info settings.
254
+ * Seven bugs have been fixed, mainly involving descriptions and the sitemap.
255
+ * The plugin now suggests, **once**, that you can use Focus keywords via the Extension Manager.
256
+
257
+ **For everyone, about the suggestion:**
258
+
259
+ * We believe not everyone is up-to-date yet with the current progression of the extensions. Some of which can help you out greatly with SEO.
260
+ * So, from this update, all sites will get a one-time-only auto-dismissing suggestion for [TSFEM](https://wordpress.org/plugins/the-seo-framework-extension-manager/).
261
+ * This suggestion has many conditions attached before being shown. So, it's likely you won't ever see it.
262
+ * We understand that not everyone welcomes this introduction. However, this suggestion is to help this plugin and your site grow, from which we all will benefit.
263
+
264
+ **For developers, about descriptions:**
265
+
266
+ * If you're using description-related filters or functions from TSF on your sites, check out the detailed "for developers" log.
267
+ * Many functions have been silently deprecated, and you should now use simple caller functions.
268
+ * No action is needed from your side until the next major release (ETA July 2018).
269
+
270
+ **For developers, about titles ETA July 2018:**
271
+
272
+ * In the next major release, we're going to change how we handle titles.
273
+ * This change won't affect users directly. But it will allow us to manipulate the titles better.
274
+ * For more information, [view and subscribe to issue 202](https://github.com/sybrew/the-seo-framework/issues/202).
275
+
276
+ [View the detailed log](https://theseoframework.com/?p=2365#detailed).
277
+
278
  = 3.0.5 - Rectified =
279
 
280
  **Release date:**
281
 
282
+ * February 27th, 2018
283
 
284
  **Summarized:**
285
 
291
 
292
  **Release date:**
293
 
294
+ * February 25th, 2018
295
 
296
  **Did you know?**
297
 
301
 
302
  **Summarized:**
303
 
304
+ * This is a maintenance release with over 10 bugs fixed. Most notoriously were pixel guideline calculation errors and home page title errors.
305
  * Open Graph and Twitter custom title and description options have been added to every post, page, and CPT.
306
  * The description character count and pixel length guidelines have been updated.
307
  * All publicly queryable CPT posts and pages now support SEO settings and are included in the sitemap. No more messing with filters is needed.
309
  **About the new description guidelines:**
310
 
311
  * Google increased their SERP's description length a few months ago, so we've updated the upper-limit guidelines.
312
+ * We recommend enforcing these new guidelines for new pages, cornerstone pages, and the home page.
313
  * Although the description lengths have been updated, the transient cache isn't invalidated.
314
  * Over time the cache will refresh itself, this is done automatically by WordPress, or via your caching plugin's transients handler (if applicable).
315
 
398
  * It now uses WordPress' 4.6+ canonical URL generation (backward-compatibility is provided), instead of an in-house "guessing" version.
399
  * **So, the Canonical URL should now always be compatible with any plugin, out of the box.** This is great news for translation plugin users!
400
  * Note that canonical URLs are no longer outputted on private or unpublished posts.
401
+ * Note that if a query isn't registered correctly, the URL will also stay empty. Or, in unlikely cases, it will link to the home page.
402
  * Contact the respective plugin author on such issues. I'd love to help them correct this.
403
 
404
  **Finally, author SEO:**
473
  A major update. Make a backup of your database before upgrading.
474
 
475
  = 2.9.3 =
476
+ A highly recommended update that fixes "Home Page as Blog" query issues.
477
 
478
  = 2.8.0 =
479
  In the 2.8.0 update WordPress 4.3 and PHP 5.2 support have been dropped for better code quality.