From 72f7712ed38f0988f82ce0efac815f2fc2d95832 Mon Sep 17 00:00:00 2001 From: Cristian Rossi Date: Thu, 25 Jul 2024 10:29:08 -0300 Subject: [PATCH] 4.6.7.1 Release --- all_in_one_seo_pack.php | 2 +- app/Common/Admin/Notices/Notices.php | 2 +- app/Common/Admin/PostSettings.php | 2 +- app/Common/Api/PostsTerms.php | 4 +- app/Common/Main/Filters.php | 45 +- app/Common/Main/Updates.php | 24 +- app/Common/Models/Post.php | 5 + app/Common/Options/Options.php | 22 + .../Graphs/KnowledgeGraph/KgOrganization.php | 5 +- app/Common/SearchStatistics/Api/Auth.php | 3 + .../Standalone/AdminBarNoindexWarning.php | 82 + app/Common/Standalone/HeadlineAnalyzer.php | 4 +- app/Common/Standalone/Standalone.php | 5 +- app/Common/Tools/RobotsTxt.php | 2 +- app/Common/Traits/Helpers/Url.php | 17 + app/Lite/Admin/Connect.php | 7 - app/Lite/Admin/PostSettings.php | 2 +- ...xonomy-upsell.html => taxonomy-upsell.php} | 43 +- languages/aioseo-lite.php | 606 +- package-lock.json | 26717 ++++++++-------- package.json | 204 +- readme.txt | 31 +- .../HeadlinePanelCharacterCount.jsx | 100 - .../components/HeadlinePanelNewScore.jsx | 121 - .../HeadlinePanelPreviousScores.jsx | 81 - .../components/HeadlinePanelSearchPreview.jsx | 39 - .../components/HeadlinePanelSentiment.jsx | 102 - .../components/HeadlinePanelStartEndWords.jsx | 75 - .../components/HeadlinePanelType.jsx | 34 - .../components/HeadlinePanelWordBalance.jsx | 194 - .../components/HeadlinePanelWordCount.jsx | 98 - .../components/HeadlinePieChart.jsx | 44 - .../components/HeadlineSwitcher.jsx | 75 - .../components/HeadlineTabCurrentScore.jsx | 74 - .../components/HeadlineTabNewScore.jsx | 106 - .../components/HeadlineWordsBlock.jsx | 56 - src/react/headline-analyzer/constants.js | 49 - src/react/headline-analyzer/icons.jsx | 76 - src/react/headline-analyzer/index.jsx | 285 - src/react/headline-analyzer/main.js | 1 - src/vue/assets/scss/app/variables.scss | 1 + src/vue/assets/scss/integrations/_divi.scss | 66 +- src/vue/assets/scss/post-settings.scss | 8 +- src/vue/components/common/base/Input.vue | 4 - src/vue/components/common/base/Select.vue | 6 + .../components/common/core/GettingStarted.vue | 2 +- src/vue/components/common/core/Loader.vue | 3 +- src/vue/components/common/core/Popper.vue | 24 +- .../components/common/core/ScoreButton.vue | 4 +- .../common/core/SingleRobotsMeta.vue | 3 +- src/vue/components/common/core/Tooltip.vue | 4 +- .../common/core/add-redirection/Index.vue | 98 +- .../components/common/core/headline/Score.vue | 2 +- src/vue/mixins/GoogleSearchConsole.js | 16 +- src/vue/mixins/WpTable.js | 5 +- .../views/GlobalSettings.vue | 2 +- .../views/partials/AddAdditionalPage.vue | 22 +- .../admin-bar-noindex-warning/App.vue | 146 + .../admin-bar-noindex-warning/main.js | 16 + src/vue/standalone/headline-analyzer/App.vue | 16 + .../assets/js/HeadlineCurrentScore.js | 81 + .../headline-analyzer/assets/js}/functions.js | 6 + .../assets/js/initAnalyzerData.js | 68 + .../assets/scss/_global.scss | 0 .../assets/scss/headline-analyzer.scss | 73 +- .../headline-analyzer/assets/scss/main.scss | 0 .../components/CharacterCount.vue | 180 + .../headline-analyzer/components/Main.vue | 112 + .../components/PanelNewScore.vue | 127 + .../components/PanelType.vue | 53 + .../components/PreviousScores.vue | 91 + .../components/SearchPreview.vue | 70 + .../components/Sentiment.vue | 80 + .../components/StartEndWords.vue | 89 + .../components/TabCurrentScore.vue | 92 + .../components/TabNewScore.vue | 79 + .../components/WordBalance.vue | 214 + .../components/WordCount.vue | 162 + .../components/partials/Accordion.vue | 113 + .../components/partials/PieChart.vue | 51 + .../components/partials/WordsBlock.vue | 88 + src/vue/standalone/headline-analyzer/main.js | 111 + .../registerHeadlineAnalyzer.js | 110 + .../standalone/limit-modified-date/App.vue | 19 +- src/vue/standalone/page-builders/Modal.vue | 2 +- .../page-builders/elementor/main.js | 2 +- .../siteorigin/components/Sidebar.vue | 2 +- .../thrive-architect/components/Sidebar.vue | 2 +- src/vue/standalone/post-settings/main.js | 7 + .../post-settings/views/General.vue | 6 +- .../standalone/post-settings/views/Main.vue | 3 +- .../views/lite/partials-ai/Modal.vue | 3 +- .../views/partials/GraphCard.vue | 1 + .../partials/general/AdditionalKeyphrases.vue | 3 +- .../general/MetaboxAnalysisDetail.vue | 3 +- .../standalone/primary-term/classicEditor.js | 7 +- src/vue/stores/PostEditorStore.js | 79 + src/vue/stores/RedirectsStore.js | 10 +- src/vue/stores/SchemaStore.js | 15 +- vendor/autoload.php | 2 +- vendor/composer/InstalledVersions.php | 33 +- vendor/composer/autoload_classmap.php | 456 + vendor/composer/autoload_real.php | 14 +- vendor/composer/autoload_static.php | 466 +- vendor/composer/installed.json | 42 +- vendor/composer/installed.php | 48 +- vendor/symfony/polyfill-mbstring/Mbstring.php | 77 +- .../symfony/polyfill-mbstring/bootstrap.php | 8 + .../symfony/polyfill-mbstring/bootstrap80.php | 8 + vite.config.js | 63 +- 110 files changed, 17488 insertions(+), 15835 deletions(-) create mode 100644 app/Common/Standalone/AdminBarNoindexWarning.php rename app/Lite/Views/{taxonomy-upsell.html => taxonomy-upsell.php} (93%) delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelCharacterCount.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelNewScore.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelPreviousScores.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelSearchPreview.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelSentiment.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelStartEndWords.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelType.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelWordBalance.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePanelWordCount.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlinePieChart.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlineSwitcher.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlineTabCurrentScore.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlineTabNewScore.jsx delete mode 100644 src/react/headline-analyzer/components/HeadlineWordsBlock.jsx delete mode 100644 src/react/headline-analyzer/constants.js delete mode 100644 src/react/headline-analyzer/icons.jsx delete mode 100644 src/react/headline-analyzer/index.jsx delete mode 100644 src/react/headline-analyzer/main.js create mode 100644 src/vue/standalone/admin-bar-noindex-warning/App.vue create mode 100644 src/vue/standalone/admin-bar-noindex-warning/main.js create mode 100644 src/vue/standalone/headline-analyzer/App.vue create mode 100644 src/vue/standalone/headline-analyzer/assets/js/HeadlineCurrentScore.js rename src/{react/headline-analyzer => vue/standalone/headline-analyzer/assets/js}/functions.js (87%) create mode 100644 src/vue/standalone/headline-analyzer/assets/js/initAnalyzerData.js rename src/{react => vue/standalone}/headline-analyzer/assets/scss/_global.scss (100%) rename src/{react => vue/standalone}/headline-analyzer/assets/scss/headline-analyzer.scss (94%) rename src/{react => vue/standalone}/headline-analyzer/assets/scss/main.scss (100%) create mode 100644 src/vue/standalone/headline-analyzer/components/CharacterCount.vue create mode 100644 src/vue/standalone/headline-analyzer/components/Main.vue create mode 100644 src/vue/standalone/headline-analyzer/components/PanelNewScore.vue create mode 100644 src/vue/standalone/headline-analyzer/components/PanelType.vue create mode 100644 src/vue/standalone/headline-analyzer/components/PreviousScores.vue create mode 100644 src/vue/standalone/headline-analyzer/components/SearchPreview.vue create mode 100644 src/vue/standalone/headline-analyzer/components/Sentiment.vue create mode 100644 src/vue/standalone/headline-analyzer/components/StartEndWords.vue create mode 100644 src/vue/standalone/headline-analyzer/components/TabCurrentScore.vue create mode 100644 src/vue/standalone/headline-analyzer/components/TabNewScore.vue create mode 100644 src/vue/standalone/headline-analyzer/components/WordBalance.vue create mode 100644 src/vue/standalone/headline-analyzer/components/WordCount.vue create mode 100644 src/vue/standalone/headline-analyzer/components/partials/Accordion.vue create mode 100644 src/vue/standalone/headline-analyzer/components/partials/PieChart.vue create mode 100644 src/vue/standalone/headline-analyzer/components/partials/WordsBlock.vue create mode 100644 src/vue/standalone/headline-analyzer/main.js create mode 100644 src/vue/standalone/headline-analyzer/registerHeadlineAnalyzer.js diff --git a/all_in_one_seo_pack.php b/all_in_one_seo_pack.php index 72ff7f56b..df464db28 100644 --- a/all_in_one_seo_pack.php +++ b/all_in_one_seo_pack.php @@ -5,7 +5,7 @@ * Description: SEO for WordPress. Features like XML Sitemaps, SEO for custom post types, SEO for blogs, business sites, ecommerce sites, and much more. More than 100 million downloads since 2007. * Author: All in One SEO Team * Author URI: https://aioseo.com/ - * Version: 4.6.5 + * Version: 4.6.7 * Text Domain: all-in-one-seo-pack * Domain Path: /languages * diff --git a/app/Common/Admin/Notices/Notices.php b/app/Common/Admin/Notices/Notices.php index 8b656dab1..fd31e02d1 100644 --- a/app/Common/Admin/Notices/Notices.php +++ b/app/Common/Admin/Notices/Notices.php @@ -457,7 +457,7 @@ private function blogVisibility() { return; } - if ( $notification->exists() ) { + if ( $notification->exists() || ! current_user_can( 'manage_options' ) ) { return; } diff --git a/app/Common/Admin/PostSettings.php b/app/Common/Admin/PostSettings.php index 1a7958e62..3ea246adf 100644 --- a/app/Common/Admin/PostSettings.php +++ b/app/Common/Admin/PostSettings.php @@ -350,7 +350,7 @@ public function getPostTypeOverview( $postType ) { } } - aioseo()->core->cache->update( $postType . '_overview_data', $overview, WEEK_IN_SECONDS ); + aioseo()->core->cache->update( $postType . '_overview_data', $overview, HOUR_IN_SECONDS ); return $overview; } diff --git a/app/Common/Api/PostsTerms.php b/app/Common/Api/PostsTerms.php index 30a677a1c..abc878b0c 100644 --- a/app/Common/Api/PostsTerms.php +++ b/app/Common/Api/PostsTerms.php @@ -264,7 +264,9 @@ public static function loadPostDetailsColumn( $request ) { $posts = []; foreach ( $ids as $postId ) { - $headlineResult = aioseo()->standalone->headlineAnalyzer->getResult( html_entity_decode( get_the_title( $postId ) ) ); + $postTitle = get_the_title( $postId ); + $headline = ! empty( $postTitle ) ? sanitize_text_field( $postTitle ) : ''; // We need this to achieve consistency for the score when using special characters in titles + $headlineResult = aioseo()->standalone->headlineAnalyzer->getResult( $headline ); $posts[] = [ 'id' => $postId, diff --git a/app/Common/Main/Filters.php b/app/Common/Main/Filters.php index 6792e260e..15d25a305 100644 --- a/app/Common/Main/Filters.php +++ b/app/Common/Main/Filters.php @@ -40,6 +40,9 @@ abstract class Filters { public function __construct() { add_filter( 'wp_optimize_get_tables', [ $this, 'wpOptimizeAioseoTables' ] ); + // This action needs to run on AJAX/cron for scheduled rewritten posts in Yoast Duplicate Post. + add_action( 'duplicate_post_after_rewriting', [ $this, 'updateRescheduledPostMeta' ], 10, 2 ); + if ( wp_doing_ajax() || wp_doing_cron() ) { return; } @@ -171,19 +174,16 @@ function_exists( 'bbp_get_reply_post_type' ) && * * @since 4.1.1 * - * @param integer $newPostId The new post ID. - * @param \WP_Post $originalPost The original post object. + * @param integer $targetPostId The target post ID. + * @param \WP_Post $sourcePost The source post object. * @return void */ - public function duplicatePost( $newPostId, $originalPost = null ) { - $originalPostId = is_object( $originalPost ) ? $originalPost->ID : $originalPost; - $originalAioseoPost = Models\Post::getPost( $originalPostId ); - if ( ! $originalAioseoPost->exists() ) { - return; - } + public function duplicatePost( $targetPostId, $sourcePost = null ) { + $sourcePostId = ! empty( $sourcePost->ID ) ? $sourcePost->ID : $sourcePost; + $sourceAioseoPost = Models\Post::getPost( $sourcePostId ); + $targetPost = Models\Post::getPost( $targetPostId ); - $newAioseoPost = Models\Post::getPost( $newPostId ); - $columns = $originalAioseoPost->getColumns(); + $columns = $sourceAioseoPost->getColumns(); foreach ( $columns as $column => $value ) { // Skip the ID column. if ( 'id' === $column ) { @@ -191,13 +191,14 @@ public function duplicatePost( $newPostId, $originalPost = null ) { } if ( 'post_id' === $column ) { - $newAioseoPost->$column = $newPostId; + $targetPost->$column = $targetPostId; continue; } - $newAioseoPost->$column = $originalAioseoPost->$column; + $targetPost->$column = $sourceAioseoPost->$column; } - $newAioseoPost->save(); + + $targetPost->save(); } /** @@ -223,6 +224,24 @@ public function rewriteAndRepublish( $postId, $metaKey = '', $metaValue = '' ) { $this->duplicatePost( (int) $metaValue, $originalPost ); } + /** + * Updates the model when a post is republished. + * Yoast Duplicate Post doesn't do this since we store our data in a custom table. + * + * @since 4.6.7 + * + * @param int $scheduledPostId The ID of the scheduled post. + * @param int $originalPostId The ID of the original post. + * @return void + */ + public function updateRescheduledPostMeta( $scheduledPostId, $originalPostId ) { + $this->duplicatePost( $originalPostId, $scheduledPostId ); + + // Delete the AIOSEO post record for the scheduled post. + $scheduledAioseoPost = Models\Post::getPost( $scheduledPostId ); + $scheduledAioseoPost->delete(); + } + /** * Schedules an action to duplicate our meta after the duplicated WooCommerce product has been saved. * diff --git a/app/Common/Main/Updates.php b/app/Common/Main/Updates.php index e490e509f..488dc5a39 100644 --- a/app/Common/Main/Updates.php +++ b/app/Common/Main/Updates.php @@ -1228,7 +1228,12 @@ public function migratePostSchemaHelper( $aioseoPost ) { 'preparation' => ! empty( $schemaTypeOptions->recipe->preparationTime ) ? $schemaTypeOptions->recipe->preparationTime : '', 'cooking' => ! empty( $schemaTypeOptions->recipe->cookingTime ) ? $schemaTypeOptions->recipe->cookingTime : '' ], - 'instructions' => [] + 'instructions' => [], + 'rating' => [ + 'minimum' => 1, + 'maximum' => 5 + ], + 'reviews' => [] ] ]; @@ -1247,6 +1252,23 @@ public function migratePostSchemaHelper( $aioseoPost ) { ]; } } + + $reviews = ! empty( $schemaTypeOptions->recipe->reviews ) ? $schemaTypeOptions->recipe->reviews : []; + if ( ! empty( $reviews ) ) { + foreach ( $reviews as $reviewData ) { + $reviewData = json_decode( $reviewData ); + if ( empty( $reviewData ) ) { + continue; + } + + $graph['properties']['reviews'][] = [ + 'rating' => $reviewData->rating, + 'headline' => $reviewData->headline, + 'content' => $reviewData->content, + 'author' => $reviewData->author + ]; + } + } break; case 'SoftwareApplication': $graph = [ diff --git a/app/Common/Models/Post.php b/app/Common/Models/Post.php index e303dc2af..097681ddc 100644 --- a/app/Common/Models/Post.php +++ b/app/Common/Models/Post.php @@ -219,6 +219,11 @@ private static function runDynamicSchemaMigration( $post ) { // is correctly propagated on the frontend after changing it. $post->schema = self::getDefaultSchemaOptions( $post->schema ); + // Filter out null or empty graphs. + $post->schema->graphs = array_filter( $post->schema->graphs, function( $graph ) { + return ! empty( $graph ); + } ); + foreach ( $post->schema->graphs as $graph ) { // If the first character of the graph ID isn't a pound, add one. // We have to do this because the schema migration in 4.2.5 didn't add the pound for custom graphs. diff --git a/app/Common/Options/Options.php b/app/Common/Options/Options.php index d82798236..2e56bafb0 100644 --- a/app/Common/Options/Options.php +++ b/app/Common/Options/Options.php @@ -571,6 +571,8 @@ public function translateDefaults() { * @return void */ public function sanitizeAndSave( $options ) { + // Decode urls for additional pages to fix localization issues. + $options = $this->decodeAdditionalPagesUrl( $options ); $sitemapOptions = ! empty( $options['sitemap'] ) ? $options['sitemap'] : null; $oldSitemapOptions = aioseo()->options->sitemap->all(); $generalSitemapOptions = ! empty( $options['sitemap']['general'] ) ? $options['sitemap']['general'] : null; @@ -742,4 +744,24 @@ public function maybeFlushRewriteRules() { delete_option( 'aioseo_flush_rewrite_rules_flag' ); } } + + /** + * Decode the URLs for additional pages to fix Unicode characters. + * + * @since 4.6.7 + * + * @param array $options The options array. + * @return array $options The options array with the decoded URLs. + */ + public function decodeAdditionalPagesUrl( $options ) { + if ( ! empty( $options['sitemap']['general']['additionalPages']['pages'] ) ) { + foreach ( $options['sitemap']['general']['additionalPages']['pages'] as &$page ) { + $page = json_decode( $page, true ); + $page['url'] = aioseo()->helpers->decodeUrl( $page['url'] ); + $page = wp_json_encode( $page, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ); + } + } + + return $options; + } } \ No newline at end of file diff --git a/app/Common/Schema/Graphs/KnowledgeGraph/KgOrganization.php b/app/Common/Schema/Graphs/KnowledgeGraph/KgOrganization.php index 212fcc6f2..a729287d6 100644 --- a/app/Common/Schema/Graphs/KnowledgeGraph/KgOrganization.php +++ b/app/Common/Schema/Graphs/KnowledgeGraph/KgOrganization.php @@ -41,8 +41,9 @@ public function get() { if ( $numberOfEmployeesData['isRange'] && - ! empty( $numberOfEmployeesData['from'] ) && - ! empty( $numberOfEmployeesData['to'] ) + isset( $numberOfEmployeesData['from'] ) && + isset( $numberOfEmployeesData['to'] ) && + 0 < $numberOfEmployeesData['to'] ) { $data['numberOfEmployees'] = [ '@type' => 'QuantitativeValue', diff --git a/app/Common/SearchStatistics/Api/Auth.php b/app/Common/SearchStatistics/Api/Auth.php index 869b24957..61a729ed8 100644 --- a/app/Common/SearchStatistics/Api/Auth.php +++ b/app/Common/SearchStatistics/Api/Auth.php @@ -192,6 +192,9 @@ public function delete( $force = false ) { aioseo()->searchStatistics->api->auth->deleteProfile(); aioseo()->searchStatistics->reset(); + // Resets the results for the Google meta tag. + aioseo()->options->webmasterTools->google = ''; + return true; } } \ No newline at end of file diff --git a/app/Common/Standalone/AdminBarNoindexWarning.php b/app/Common/Standalone/AdminBarNoindexWarning.php new file mode 100644 index 000000000..3cdf52bda --- /dev/null +++ b/app/Common/Standalone/AdminBarNoindexWarning.php @@ -0,0 +1,82 @@ +core->assets->load( 'src/vue/standalone/admin-bar-noindex-warning/main.js', [], [ + 'optionsReadingUrl' => admin_url( 'options-reading.php' ), + ], 'aioseoAdminBarNoindexWarning' ); + } + + /** + * Adds the admin bar element. + * + * @since 4.6.7 + * + * @param \WP_Admin_Bar $wpAdminBar The admin bar object. + * @return void + */ + public function addAdminBarElement( $wpAdminBar ) { + $wpAdminBar->add_node( + [ + 'id' => 'aioseo-admin-bar-noindex-warning', + 'title' => __( 'Search Engines Blocked!', 'all-in-one-seo-pack' ), + 'href' => admin_url( 'options-reading.php' ) + ] + ); + } +} \ No newline at end of file diff --git a/app/Common/Standalone/HeadlineAnalyzer.php b/app/Common/Standalone/HeadlineAnalyzer.php index 25531be84..27edf863a 100644 --- a/app/Common/Standalone/HeadlineAnalyzer.php +++ b/app/Common/Standalone/HeadlineAnalyzer.php @@ -57,7 +57,7 @@ public function enqueue() { } require AIOSEO_DIR . $path; - aioseo()->core->assets->load( 'src/react/headline-analyzer/main.js' ); + aioseo()->core->assets->load( 'src/vue/standalone/headline-analyzer/main.js' ); } /** @@ -69,7 +69,7 @@ public function enqueue() { * @return array The result. */ public function getResult( $title ) { - $result = $this->getHeadlineScore( $title ); + $result = $this->getHeadlineScore( html_entity_decode( $title ) ); if ( ! empty( $result->err ) ) { return false; diff --git a/app/Common/Standalone/Standalone.php b/app/Common/Standalone/Standalone.php index 1088b9b3d..80dfd5a7c 100644 --- a/app/Common/Standalone/Standalone.php +++ b/app/Common/Standalone/Standalone.php @@ -96,10 +96,11 @@ public function __construct() { aioseo()->pro ? new ProStandalone\DetailsColumn() : new DetailsColumn(); - new UserProfileTab(); - new PublishPanel(); + new AdminBarNoindexWarning(); new LimitModifiedDate(); new Notifications(); + new PublishPanel(); + new UserProfileTab(); new WpCode(); $this->pageBuilderIntegrations = [ diff --git a/app/Common/Tools/RobotsTxt.php b/app/Common/Tools/RobotsTxt.php index 676c901ec..897e0e56d 100644 --- a/app/Common/Tools/RobotsTxt.php +++ b/app/Common/Tools/RobotsTxt.php @@ -285,7 +285,7 @@ public function extractRules( $lines ) { } $userAgent = $value; - $rules[ $userAgent ] = []; + $rules[ $userAgent ] = ! empty( $rules[ $userAgent ] ) ? $rules[ $userAgent ] : []; } else { $rules[ $userAgent ][] = "$directive: $value"; if ( $siblingsUserAgents ) { diff --git a/app/Common/Traits/Helpers/Url.php b/app/Common/Traits/Helpers/Url.php index dfd15147c..4af45671c 100644 --- a/app/Common/Traits/Helpers/Url.php +++ b/app/Common/Traits/Helpers/Url.php @@ -241,4 +241,21 @@ public function getTld( $domain ) { return $domain; } + + /** + * Returns a decoded URL string. + * + * @since 4.6.7 + * + * @param string $url The URL string. + * @return string The decoded URL. + */ + public function decodeUrl( $url ) { + // Check if URL was encoded multiple times. + while ( rawurldecode( $url ) !== $url ) { + $url = rawurldecode( $url ); + } + + return $url; + } } \ No newline at end of file diff --git a/app/Lite/Admin/Connect.php b/app/Lite/Admin/Connect.php index b64037b7d..363e51aca 100644 --- a/app/Lite/Admin/Connect.php +++ b/app/Lite/Admin/Connect.php @@ -222,9 +222,6 @@ public function generateConnectUrl( $key, $redirect = null ) { $active = activate_plugin( 'all-in-one-seo-pack-pro/all_in_one_seo_pack_pro', false, false, true ); if ( ! is_wp_error( $active ) ) { - // Deactivate plugin. - deactivate_plugins( plugin_basename( AIOSEO_FILE ), false, false ); - return [ 'error' => esc_html__( 'Pro version is already installed.', 'all-in-one-seo-pack' ) ]; @@ -343,8 +340,6 @@ public function process() { // Because the regular activation hooks won't run, we need to add capabilities for the installing user so that he doesn't run into an error on the first request. aioseo()->activate->addCapabilitiesOnUpgrade(); - deactivate_plugins( plugin_basename( AIOSEO_FILE ), false, $network ); - wp_send_json_success( $success ); } @@ -393,8 +388,6 @@ public function process() { // Because the regular activation hooks won't run, we need to add capabilities for the installing user so that he doesn't run into an error on the first request. aioseo()->activate->addCapabilitiesOnUpgrade(); - deactivate_plugins( plugin_basename( AIOSEO_FILE ), false, $network ); - wp_send_json_success( $success ); } } \ No newline at end of file diff --git a/app/Lite/Admin/PostSettings.php b/app/Lite/Admin/PostSettings.php index 6e1cde8bc..767d14511 100644 --- a/app/Lite/Admin/PostSettings.php +++ b/app/Lite/Admin/PostSettings.php @@ -69,6 +69,6 @@ public function addTaxonomyUpsell() { return; } - include_once AIOSEO_DIR . '/app/Lite/Views/taxonomy-upsell.html'; + include_once AIOSEO_DIR . '/app/Lite/Views/taxonomy-upsell.php'; } } \ No newline at end of file diff --git a/app/Lite/Views/taxonomy-upsell.html b/app/Lite/Views/taxonomy-upsell.php similarity index 93% rename from app/Lite/Views/taxonomy-upsell.html rename to app/Lite/Views/taxonomy-upsell.php index 633106a46..9afcc1fdc 100644 --- a/app/Lite/Views/taxonomy-upsell.html +++ b/app/Lite/Views/taxonomy-upsell.php @@ -1,3 +1,6 @@ + \ No newline at end of file diff --git a/src/vue/standalone/admin-bar-noindex-warning/main.js b/src/vue/standalone/admin-bar-noindex-warning/main.js new file mode 100644 index 000000000..b8f16f719 --- /dev/null +++ b/src/vue/standalone/admin-bar-noindex-warning/main.js @@ -0,0 +1,16 @@ +import { createApp } from 'vue' + +import loadPlugins from '@/vue/plugins' + +import { loadPiniaStores } from '@/vue/stores' + +import App from './App.vue' + +let app = createApp(App) +app = loadPlugins(app) + +loadPiniaStores(app) + +app.mount('#wp-admin-bar-aioseo-admin-bar-noindex-warning') + +export default app \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/App.vue b/src/vue/standalone/headline-analyzer/App.vue new file mode 100644 index 000000000..8dfa506dd --- /dev/null +++ b/src/vue/standalone/headline-analyzer/App.vue @@ -0,0 +1,16 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/assets/js/HeadlineCurrentScore.js b/src/vue/standalone/headline-analyzer/assets/js/HeadlineCurrentScore.js new file mode 100644 index 000000000..5dbb68804 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/assets/js/HeadlineCurrentScore.js @@ -0,0 +1,81 @@ +import { + usePostEditorStore +} from '@/vue/stores' +import { fetchData } from './initAnalyzerData' + +/** + * Update the current score on the headline analyzer button and save the data to the Post Editor store + * + * @param {boolean} reload - Whether to reload the data + * @returns {void} + */ +export async function HeadlineCurrentScore (reload = false) { + const postEditorStore = usePostEditorStore() + + const fetchAndUpdate = async () => { + const response = await fetchData() + const seoButton = document.querySelector('button[aria-controls="aioseo-headline-analyzer:aioseo-headline-analyzer"]') + const btnScore = document.querySelector('#aioseo-headline-analyzer-sidebar-button-score') + + if (response) { + const headlineResult = JSON.parse(response.data[Object.keys(response.data)[0]]) + + if (!headlineResult) { + if (seoButton) { + seoButton.style.display = 'block' + seoButton.setAttribute('aioseo-button-color', 'gray') + } + + if (btnScore) { + btnScore.innerHTML = 'N/A' + } + return + } + + // Save data to store + postEditorStore.updatePostHeadlineAnalyzerData(response.data, response.headline) + + const currentScore = headlineResult.score + const classOnScore = 40 > currentScore ? 'red' : 70 > currentScore ? 'orange' : 'green' + + // Set latest score + postEditorStore.updateLatestScore(currentScore) + if (seoButton) { + seoButton.style.display = 'block' + seoButton.setAttribute('aioseo-button-color', classOnScore) + } + + if (btnScore) { + btnScore.innerHTML = `${currentScore}/100` + } + } else { + postEditorStore.updatePostHeadlineAnalyzerData({}, '') + + if (seoButton) { + seoButton.style.display = 'block' + seoButton.setAttribute('aioseo-button-color', 'gray') + } + + if (btnScore) { + btnScore.innerHTML = 'N/A' + } + } + } + + if (reload) { + fetchAndUpdate() + } + + const callback = async function (mutationsList, observer) { + const pinnedItemsDiv = document.querySelector('.interface-pinned-items') + + if (pinnedItemsDiv) { + observer.disconnect() // disconnect so we don't fetch data multiple times + fetchAndUpdate() + } + } + + const observer = new MutationObserver(callback) + const config = { childList: true, subtree: true } + observer.observe(document.body, config) +} \ No newline at end of file diff --git a/src/react/headline-analyzer/functions.js b/src/vue/standalone/headline-analyzer/assets/js/functions.js similarity index 87% rename from src/react/headline-analyzer/functions.js rename to src/vue/standalone/headline-analyzer/assets/js/functions.js index 9225cce3a..a061a8323 100644 --- a/src/react/headline-analyzer/functions.js +++ b/src/vue/standalone/headline-analyzer/assets/js/functions.js @@ -34,4 +34,10 @@ export const restUrl = (path) => { path = rootStore.aioseo.data.hasUrlTrailingSlash ? trailingSlashIt(path) : unTrailingSlashIt(path) return trailingSlashIt(rootStore.aioseo.urls.restUrl) + trailingSlashIt('aioseo/v1') + unForwardSlashIt(path) +} + +export const decodeHtml = html => { + const txt = document.createElement('textarea') + txt.innerHTML = html + return txt.value } \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/assets/js/initAnalyzerData.js b/src/vue/standalone/headline-analyzer/assets/js/initAnalyzerData.js new file mode 100644 index 000000000..1d81abe70 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/assets/js/initAnalyzerData.js @@ -0,0 +1,68 @@ +import { http, restUrl } from './functions' +import { sanitizeString } from '@/vue/utils/strings' +import { HeadlineCurrentScore } from './HeadlineCurrentScore' +import { + usePostEditorStore +} from '@/vue/stores' +const { select } = window.wp.data + +let timeout, postTitle = select('core/editor').getEditedPostAttribute('title') +export const debounceContext = (fn, time) => { + return ((...args) => { + const functionCall = () => fn(...args) + + clearTimeout(timeout) + timeout = setTimeout(functionCall, time) + }).call() +} + +// Fetch data from the API. +export const fetchData = async (newHeadline = null) => { + let headline = postTitle + if (newHeadline) { + headline = newHeadline + } + + // Trim headline from whitespaces. + headline = sanitizeString(headline.trim()) + + if (!headline) { + return null + } + + return http(window.aioseo.nonce).post(restUrl('analyze-headline')) + .send({ + headline : headline, + shouldStoreHeadline : false + }) + .then(response => { + return { + data : response.body, + headline : headline + } + }) + .catch(error => { + console.error('Couldn\'t fetch score for headline:', error) + return null + }) +} + +// Fetch new results after the title was changed. +window.wp.data.subscribe(() => { + // If the title is the same, abort. + if (postTitle === select('core/editor').getEditedPostAttribute('title')) { + return + } + postTitle = select('core/editor').getEditedPostAttribute('title') + + debounceContext(() => { + const postEditorStore = usePostEditorStore() + if (postEditorStore.currentPost?.headlineAnalyzer?.newData) { + postEditorStore.toggleShowNewHeadlineAnalyzerPreview(false) + } + if (postEditorStore.currentPost?.headlineAnalyzer?.showNewData) { + postEditorStore.toggleShowNewHeadlineAnalyzerData(false) + } + HeadlineCurrentScore(true) + }, 2000) +}) \ No newline at end of file diff --git a/src/react/headline-analyzer/assets/scss/_global.scss b/src/vue/standalone/headline-analyzer/assets/scss/_global.scss similarity index 100% rename from src/react/headline-analyzer/assets/scss/_global.scss rename to src/vue/standalone/headline-analyzer/assets/scss/_global.scss diff --git a/src/react/headline-analyzer/assets/scss/headline-analyzer.scss b/src/vue/standalone/headline-analyzer/assets/scss/headline-analyzer.scss similarity index 94% rename from src/react/headline-analyzer/assets/scss/headline-analyzer.scss rename to src/vue/standalone/headline-analyzer/assets/scss/headline-analyzer.scss index d3af866f4..bfbbebeba 100644 --- a/src/react/headline-analyzer/assets/scss/headline-analyzer.scss +++ b/src/vue/standalone/headline-analyzer/assets/scss/headline-analyzer.scss @@ -19,7 +19,6 @@ .components-panel__body { svg.components-panel__arrow { - transform: rotate(-90deg); top: 50%; margin-top: -12px; transition: .3s; @@ -67,6 +66,10 @@ background: #df2a4a; } + .gray-bg { + background: #a1a1a1; + } + .components-panel__body-toggle.components-button { font-size: 14px; line-height: 22px; @@ -341,14 +344,7 @@ .components-panel__body { &.aioseo-headline-analyzer-panel-has-icon { - .components-panel__body-toggle { - .components-panel__icon { - position: absolute; - right: 52px; - top: 50%; - margin-top: -10px; - } - } + &.red { .components-panel__body-toggle .components-panel__icon path { @@ -710,15 +706,35 @@ } } -.edit-post-header__settings { - button.components-button[aioseo-button-color] { - display: flex; - align-items: center; +.edit-post-header__settings, +.editor-header__settings { + button.components-button[aria-label*="SEO Headline Analyzer"] { + + background: #fff; + border: none; + width: auto !important; + padding: 6px !important; + max-width: 160px; + min-width: 82px !important; + display: none; + svg { + path { + fill: #fff + } + } + + #aioseo-headline-analyzer-sidebar-button { + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + width: 100%; + } svg { max-width: 22px; max-height: 20px; - margin-right: 8px; + // margin-right: 8px; } span { @@ -791,9 +807,33 @@ } } + &[aioseo-button-color="gray"] { + border: 1px solid #a1a1a1; + &:active, + &.is-pressed { + background: #a1a1a1 !important; + svg { + path { + fill: #fff; + } + } + } + + svg { + path { + fill: #a1a1a1; + } + } + + span { + color: #a1a1a1; + } + } + &[aioseo-button-color="red"], &[aioseo-button-color="green"], - &[aioseo-button-color="orange"] { + &[aioseo-button-color="orange"], + &[aioseo-button-color="gray"] { &:active, &.is-pressed { box-shadow: none !important; @@ -814,7 +854,8 @@ } } -.edit-post-sidebar { +.edit-post-sidebar, +.editor-sidebar { scroll-behavior: smooth; } diff --git a/src/react/headline-analyzer/assets/scss/main.scss b/src/vue/standalone/headline-analyzer/assets/scss/main.scss similarity index 100% rename from src/react/headline-analyzer/assets/scss/main.scss rename to src/vue/standalone/headline-analyzer/assets/scss/main.scss diff --git a/src/vue/standalone/headline-analyzer/components/CharacterCount.vue b/src/vue/standalone/headline-analyzer/components/CharacterCount.vue new file mode 100644 index 000000000..04ba5d912 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/CharacterCount.vue @@ -0,0 +1,180 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/Main.vue b/src/vue/standalone/headline-analyzer/components/Main.vue new file mode 100644 index 000000000..9b257f765 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/Main.vue @@ -0,0 +1,112 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/PanelNewScore.vue b/src/vue/standalone/headline-analyzer/components/PanelNewScore.vue new file mode 100644 index 000000000..f678f54a2 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/PanelNewScore.vue @@ -0,0 +1,127 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/PanelType.vue b/src/vue/standalone/headline-analyzer/components/PanelType.vue new file mode 100644 index 000000000..c772be2cc --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/PanelType.vue @@ -0,0 +1,53 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/PreviousScores.vue b/src/vue/standalone/headline-analyzer/components/PreviousScores.vue new file mode 100644 index 000000000..90c015050 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/PreviousScores.vue @@ -0,0 +1,91 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/SearchPreview.vue b/src/vue/standalone/headline-analyzer/components/SearchPreview.vue new file mode 100644 index 000000000..54c02cec6 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/SearchPreview.vue @@ -0,0 +1,70 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/Sentiment.vue b/src/vue/standalone/headline-analyzer/components/Sentiment.vue new file mode 100644 index 000000000..52d74a694 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/Sentiment.vue @@ -0,0 +1,80 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/StartEndWords.vue b/src/vue/standalone/headline-analyzer/components/StartEndWords.vue new file mode 100644 index 000000000..096edade7 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/StartEndWords.vue @@ -0,0 +1,89 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/TabCurrentScore.vue b/src/vue/standalone/headline-analyzer/components/TabCurrentScore.vue new file mode 100644 index 000000000..cc0f1dfca --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/TabCurrentScore.vue @@ -0,0 +1,92 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/TabNewScore.vue b/src/vue/standalone/headline-analyzer/components/TabNewScore.vue new file mode 100644 index 000000000..11c6bd1ed --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/TabNewScore.vue @@ -0,0 +1,79 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/WordBalance.vue b/src/vue/standalone/headline-analyzer/components/WordBalance.vue new file mode 100644 index 000000000..c3414239f --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/WordBalance.vue @@ -0,0 +1,214 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/WordCount.vue b/src/vue/standalone/headline-analyzer/components/WordCount.vue new file mode 100644 index 000000000..410eb242a --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/WordCount.vue @@ -0,0 +1,162 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/partials/Accordion.vue b/src/vue/standalone/headline-analyzer/components/partials/Accordion.vue new file mode 100644 index 000000000..345373e67 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/partials/Accordion.vue @@ -0,0 +1,113 @@ + + + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/partials/PieChart.vue b/src/vue/standalone/headline-analyzer/components/partials/PieChart.vue new file mode 100644 index 000000000..4268ea533 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/partials/PieChart.vue @@ -0,0 +1,51 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/components/partials/WordsBlock.vue b/src/vue/standalone/headline-analyzer/components/partials/WordsBlock.vue new file mode 100644 index 000000000..6e372c937 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/components/partials/WordsBlock.vue @@ -0,0 +1,88 @@ + + + \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/main.js b/src/vue/standalone/headline-analyzer/main.js new file mode 100644 index 000000000..02f5b2dd3 --- /dev/null +++ b/src/vue/standalone/headline-analyzer/main.js @@ -0,0 +1,111 @@ +import { h, createApp } from 'vue' +// import { createRouter, createWebHistory } from 'vue-router' + +import loadPlugins from '@/vue/plugins' + +import loadComponents from '@/vue/components/common' +import loadVersionedComponents from '@/vue/components/AIOSEO_VERSION' + +import { loadPiniaStores } from '@/vue/stores' + +import { elemLoaded } from '@/vue/utils/elemLoaded' +import HeadLineAnalyzer from './registerHeadlineAnalyzer' +import { HeadlineCurrentScore } from './assets/js/HeadlineCurrentScore' + +import App from './App.vue' + +// import scss +import './assets/scss/main.scss' + +// Register Headline Analyzer Plugin +HeadLineAnalyzer() +const vueAppId = '#aioseo-headline-analyzer-sidebar-vue' +const headlineSidebar = 'aioseo-headline-analyzer/aioseo-headline-analyzer' + +let app, isPinBtnEventAttached = false +const localCreateApp = () => { + if (app) { + app.unmount() + } + + // Load App + app = createApp({ + name : 'Standalone/HeadlineAnalyzer/Sidebar', + data () { + return { + tableContext : 'post', + screenContext : 'sidebar' + } + }, + render : () => h(App) + }) + + app = loadPlugins(app) + app = loadComponents(app) + app = loadVersionedComponents(app) + + // Use the pinia store. + loadPiniaStores(app) + + // unmount postSettingsSidebar if it exists + if (window.aioseo.postSettingsSidebarApp) { + window.aioseo.postSettingsSidebarApp.unmount() + } + + HeadlineCurrentScore() + + app.mount(vueAppId) + + window.aioseo.headlineAnalyzerSidebarApp = app + + return app +} + +if (window.aioseo.currentPost) { + const currentContext = window.aioseo.currentPost.context + + if (!window.wp.blockEditor && window.wp.blocks && window.wp.oldEditor) { + window.wp.blockEditor = window.wp.editor + } + + if ('post' === currentContext) { + const sidebar = document.querySelector(vueAppId) + if (!sidebar) { + elemLoaded(vueAppId, 'headlineAnalyzerSidebarLoaded') + document.addEventListener('animationstart', function (event) { + if ('headlineAnalyzerSidebarLoaded' === event.animationName) { + localCreateApp() + } + }, { passive: true }) + } else { + localCreateApp() + } + } +} + +const { select } = window.wp.data + +function attachEventListener (element) { + if (!isPinBtnEventAttached) { + element.addEventListener('click', () => { + HeadlineCurrentScore() + }) + + isPinBtnEventAttached = true + } +} + +window.wp.data.subscribe(() => { + const activeSidebarName = select('core/edit-post').getActiveGeneralSidebarName() + + if (activeSidebarName) { + const sidebarParent = document.querySelector('.interface-interface-skeleton__sidebar') + if (headlineSidebar !== activeSidebarName) { + // Unmount when opening other sidebars + if (window.aioseo.headlineAnalyzerSidebarApp) { + window.aioseo.headlineAnalyzerSidebarApp.unmount() + } + } + attachEventListener(sidebarParent) + } +}) \ No newline at end of file diff --git a/src/vue/standalone/headline-analyzer/registerHeadlineAnalyzer.js b/src/vue/standalone/headline-analyzer/registerHeadlineAnalyzer.js new file mode 100644 index 000000000..76df7b7be --- /dev/null +++ b/src/vue/standalone/headline-analyzer/registerHeadlineAnalyzer.js @@ -0,0 +1,110 @@ +import { + useRootStore +} from '@/vue/stores' + +import { shouldShowMetaBox } from '@/vue/utils/metabox' +import { isBlockEditor } from '@/vue/utils/context' +import { __ } from '@wordpress/i18n' + +export default function registerHeadlineAnalyzer () { + const td = import.meta.env.VITE_TEXTDOMAIN + if (!isBlockEditor() || !shouldShowMetaBox()) { + return + } + + const rootStore = useRootStore() + if (rootStore.aioseo.registerHeadlineAnalyzerSet) { + return + } + + rootStore.aioseo.registerHeadlineAnalyzerSet = true + + const registerPlugin = window.wp.plugins.registerPlugin + const PluginSidebarMoreMenuItem = window.wp.editPost.PluginSidebarMoreMenuItem + const PluginSidebar = window.wp.editPost.PluginSidebar + const Fragment = window.wp.element.Fragment + const el = window.wp.element.createElement + const useEffect = window.wp.element.useEffect + // const useState = window.wp.element.useState + + const HeadlineAnalyzerIcon = el('svg', + { + width : 24, + height : 24, + fill : 'none', + viewBox : '0 0 24 24', + xmlns : 'http://www.w3.org/2000/svg' + }, + el('path', + { + d : 'M15.817 2H22v.038l-6.183 4.226V2.001zm-7.62 9.473V2H2.016v4.683-.267l6.126 5.094.057-.038zm-6.182 5.061l6.183 4.213v1.252H2.015v-5.465zm13.802-.857L22 11.559v10.437h-6.183v-6.32z', + fillRule : 'evenodd', + clipRule : 'evenodd', + fill : '#F18200' + } + ), + el('path', + { + d : 'M8.198 11.435l-.057.039L2.016 6.38v.265-4.644h6.182v9.434zm0 9.226L2.015 16.45v5.55h6.183v-1.337zm7.62-5.07L22 11.474v10.522h-6.183v-6.405zM22 2.001l-6.183 4.226V2H22z', + fillRule : 'evenodd', + clipRule : 'evenodd', + fill : '#F18200' + } + ), + el('path', + { + d : 'M8.141 13.537L22 4.064v5.432l-13.8 9.19L2 14.46l.016-6.018 6.125 5.094z', + fill : '#F18200' + } + ) + ) + const HeadlineAnalyzerButton = el('div', + { id: 'aioseo-headline-analyzer-sidebar-button' }, + HeadlineAnalyzerIcon, + el('span', + { id: 'aioseo-headline-analyzer-sidebar-button-score' }, + '/100' + ) + ) + + const user = rootStore.aioseo.user + + registerPlugin('aioseo-headline-analyzer', { + render : () => { + if ( + !user.capabilities.aioseo_page_analysis && + !user.capabilities.aioseo_page_general_settings && + !user.capabilities.aioseo_page_social_settings && + !user.capabilities.aioseo_page_schema_settings && + !user.capabilities.aioseo_page_advanced_settings + ) { + return null + } + + useEffect(() => { + + }) + + return el(Fragment, {}, + el(PluginSidebarMoreMenuItem, + { + target : 'aioseo-headline-analyzer', + icon : HeadlineAnalyzerIcon + }, + __('SEO Headline Analyzer', td) + ), + el(PluginSidebar, + { + name : 'aioseo-headline-analyzer', + icon : HeadlineAnalyzerButton, + title : __('SEO Headline Analyzer', td), + className : 'aioseo-headline-analyzer-wrapper' + }, + el('div', + { id: 'aioseo-headline-analyzer-sidebar-vue', className: 'aioseo-headline-analyzer-sidebar-vue' } + ) + ) + ) + } + }) +} \ No newline at end of file diff --git a/src/vue/standalone/limit-modified-date/App.vue b/src/vue/standalone/limit-modified-date/App.vue index 8c878b98a..328feb5bf 100644 --- a/src/vue/standalone/limit-modified-date/App.vue +++ b/src/vue/standalone/limit-modified-date/App.vue @@ -23,6 +23,7 @@ + @@ -71,4 +72,20 @@ export default { } } } - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/vue/standalone/page-builders/Modal.vue b/src/vue/standalone/page-builders/Modal.vue index adcba2d4c..e9c39d827 100644 --- a/src/vue/standalone/page-builders/Modal.vue +++ b/src/vue/standalone/page-builders/Modal.vue @@ -27,7 +27,7 @@ - diff --git a/src/vue/standalone/page-builders/elementor/main.js b/src/vue/standalone/page-builders/elementor/main.js index a2a240920..387a13d9f 100644 --- a/src/vue/standalone/page-builders/elementor/main.js +++ b/src/vue/standalone/page-builders/elementor/main.js @@ -117,7 +117,7 @@ const initAioseoEditor = (selector) => { const wrapper = document.querySelector(selector) // Add the class to the wrapper. - wrapper.classList.add('edit-post-sidebar', 'aioseo-elementor-panel') + wrapper.classList.add('edit-post-sidebar', 'editor-sidebar', 'aioseo-elementor-panel') // Add the div that will contain our Vue component. wrapper.appendChild(document.createElement('div')) diff --git a/src/vue/standalone/page-builders/siteorigin/components/Sidebar.vue b/src/vue/standalone/page-builders/siteorigin/components/Sidebar.vue index 8f3ee5130..105fbaf6a 100644 --- a/src/vue/standalone/page-builders/siteorigin/components/Sidebar.vue +++ b/src/vue/standalone/page-builders/siteorigin/components/Sidebar.vue @@ -1,5 +1,5 @@