diff --git a/assets/dev/js/admin/admin.js b/assets/dev/js/admin/admin.js index d40ca8338476..caa8025cf6eb 100644 --- a/assets/dev/js/admin/admin.js +++ b/assets/dev/js/admin/admin.js @@ -118,6 +118,22 @@ import FloatingButtonsHandler from 'elementor/modules/floating-buttons/assets/js } ); } ); + $( '.e-notice--cta.e-notice--dismissible[data-notice_id="plugin_image_optimization"] a.e-button--cta' ).on( 'click', function() { + elementorCommon.ajax.addRequest( 'elementor_image_optimization_campaign', { + data: { + source: 'io-wp-media-library-install', + }, + } ); + } ); + + $( '.e-a-apps .e-a-item[data-plugin="image-optimization/image-optimization.php"] a.e-btn' ).on( 'click', function() { + elementorCommon.ajax.addRequest( 'elementor_image_optimization_campaign', { + data: { + source: 'io-esetting-addons-install', + }, + } ); + } ); + $( '#elementor-clear-cache-button' ).on( 'click', function( event ) { event.preventDefault(); var $thisButton = $( this ); diff --git a/assets/dev/js/admin/hints/media.js b/assets/dev/js/admin/hints/media.js index 71ca854d583f..74261481f332 100644 --- a/assets/dev/js/admin/hints/media.js +++ b/assets/dev/js/admin/hints/media.js @@ -108,6 +108,7 @@ dismissId: event.target.closest( '.e-hint__container' ).dataset.event, }, } ); + this.hideHint( event ); }, diff --git a/assets/dev/js/editor/controls/gallery.js b/assets/dev/js/editor/controls/gallery.js index 641f97be3125..6b8ea94612da 100644 --- a/assets/dev/js/editor/controls/gallery.js +++ b/assets/dev/js/editor/controls/gallery.js @@ -258,6 +258,13 @@ ControlMediaItemView = ControlBaseDataView.extend( { if ( actionURL ) { window.open( actionURL, '_blank' ); } + + elementorCommon.ajax.addRequest( 'elementor_image_optimization_campaign', { + data: { + source: 'io-editor-gallery-install', + }, + } ); + this.hidePromotion(); }, diff --git a/assets/dev/js/editor/controls/media.js b/assets/dev/js/editor/controls/media.js index e16003dba521..8dedd3746369 100644 --- a/assets/dev/js/editor/controls/media.js +++ b/assets/dev/js/editor/controls/media.js @@ -221,6 +221,13 @@ ControlMediaItemView = ControlMultipleBaseItemView.extend( { if ( ! eventName ) { eventName = this.getDismissPromotionEventName(); } + + elementorCommon.ajax.addRequest( 'elementor_image_optimization_campaign', { + data: { + source: 'io-editor-image-install', + }, + } ); + // Prevent opening the same promotion again in current editor session. elementor.config.user.dismissed_editor_notices.push( eventName ); }, diff --git a/assets/dev/js/editor/utils/helpers.js b/assets/dev/js/editor/utils/helpers.js index f4cad891672f..7c96591b85f6 100644 --- a/assets/dev/js/editor/utils/helpers.js +++ b/assets/dev/js/editor/utils/helpers.js @@ -1,7 +1,7 @@ import ColorPicker from './color-picker'; import DocumentHelper from 'elementor-editor/document/helper-bc'; import ContainerHelper from 'elementor-editor-utils/container-helper'; -import DOMPurify from 'dompurify'; +import DOMPurify, { isValidAttribute } from 'dompurify'; const allowedHTMLWrapperTags = [ 'article', @@ -704,4 +704,10 @@ module.exports = { sanitize( value, options ) { return DOMPurify.sanitize( value, options ); }, + + sanitizeUrl( url ) { + const isValidUrl = !! url ? isValidAttribute( 'a', 'href', url ) : false; + + return isValidUrl ? url : ''; + }, }; diff --git a/core/admin/admin.php b/core/admin/admin.php index b629b9b409b1..bcbbbebe068d 100644 --- a/core/admin/admin.php +++ b/core/admin/admin.php @@ -878,6 +878,8 @@ public function __construct() { add_action( 'in_plugin_update_message-' . ELEMENTOR_PLUGIN_BASE, function( $plugin_data ) { $this->version_update_warning( ELEMENTOR_VERSION, $plugin_data['new_version'] ); } ); + + add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_hints' ] ); } /** @@ -987,4 +989,22 @@ private function maybe_enqueue_hints() { wp_enqueue_script( 'media-hints' ); } + + public function register_ajax_hints( $ajax_manager ) { + $ajax_manager->register_ajax_action( 'elementor_image_optimization_campaign', [ $this, 'ajax_set_image_optimization_campaign' ] ); + } + + public function ajax_set_image_optimization_campaign( $request ) { + if ( empty( $request['source'] ) ) { + return; + } + + $campaign_data = [ + 'source' => sanitize_key( $request['source'] ), + 'campaign' => 'io-plg', + 'medium' => 'wp-dash', + ]; + + set_transient( 'elementor_image_optimization_campaign', $campaign_data, 30 * DAY_IN_SECONDS ); + } } diff --git a/includes/widgets/heading.php b/includes/widgets/heading.php index 609ea9bf3ffc..d2063050e894 100644 --- a/includes/widgets/heading.php +++ b/includes/widgets/heading.php @@ -390,7 +390,7 @@ protected function content_template() { let title = elementor.helpers.sanitize( settings.title, { ALLOW_DATA_ATTR: false } ); if ( '' !== settings.link.url ) { - title = '' + title + ''; + title = '' + title + ''; } view.addRenderAttribute( 'title', 'class', [ 'elementor-heading-title' ] ); diff --git a/includes/widgets/icon-box.php b/includes/widgets/icon-box.php index be764910d25c..1b4316de9508 100644 --- a/includes/widgets/icon-box.php +++ b/includes/widgets/icon-box.php @@ -789,7 +789,7 @@ protected function content_template() { view.addRenderAttribute( 'icon', 'class', 'elementor-icon elementor-animation-' + settings.hover_animation ); if ( hasLink ) { - view.addRenderAttribute( 'link', 'href', settings.link.url ); + view.addRenderAttribute( 'link', 'href', elementor.helpers.sanitizeUrl( settings.link.url ) ); view.addRenderAttribute( 'icon', 'tabindex', '-1' ); } diff --git a/includes/widgets/icon-list.php b/includes/widgets/icon-list.php index a4a511da93ea..658802b95536 100644 --- a/includes/widgets/icon-list.php +++ b/includes/widgets/icon-list.php @@ -806,7 +806,7 @@ protected function content_template() {