diff --git a/composer.lock b/composer.lock index 3443da60b..0e698aa3e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7c0fc78d754aadd6d4f452a6d17fc1d7", + "content-hash": "6534682eac1f8ac8063f575e036146bf", "packages": [ { "name": "codeinwp/themeisle-sdk", - "version": "3.2.32", + "version": "3.2.34", "source": { "type": "git", "url": "https://github.com/Codeinwp/themeisle-sdk.git", - "reference": "76c09a05d01b83f620db230146e264bdb9a38af6" + "reference": "f8d3a16d65a77d4f31dbfa1ffcb5ca3ac5c9979b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/76c09a05d01b83f620db230146e264bdb9a38af6", - "reference": "76c09a05d01b83f620db230146e264bdb9a38af6", + "url": "https://api.github.com/repos/Codeinwp/themeisle-sdk/zipball/f8d3a16d65a77d4f31dbfa1ffcb5ca3ac5c9979b", + "reference": "f8d3a16d65a77d4f31dbfa1ffcb5ca3ac5c9979b", "shasum": "" }, "require-dev": { @@ -42,9 +42,9 @@ ], "support": { "issues": "https://github.com/Codeinwp/themeisle-sdk/issues", - "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.2.32" + "source": "https://github.com/Codeinwp/themeisle-sdk/tree/v3.2.34" }, - "time": "2022-11-30T20:49:33+00:00" + "time": "2023-01-31T08:26:01+00:00" }, { "name": "masterminds/html5", diff --git a/inc/class-registration.php b/inc/class-registration.php index 8a7f0c448..d96e8fd6a 100644 --- a/inc/class-registration.php +++ b/inc/class-registration.php @@ -270,6 +270,7 @@ public function enqueue_block_editor_assets() { 'isAncestorTypeAvailable' => version_compare( get_bloginfo( 'version' ), '5.9.22', '>=' ), 'version' => OTTER_BLOCKS_VERSION, 'isRTL' => is_rtl(), + 'highlightDynamicText' => get_option( 'themeisle_blocks_settings_highlight_dynamic', true ), ) ); diff --git a/inc/plugins/class-options-settings.php b/inc/plugins/class-options-settings.php index 40be447e6..9c9ad41d8 100644 --- a/inc/plugins/class-options-settings.php +++ b/inc/plugins/class-options-settings.php @@ -90,6 +90,17 @@ public function register_settings() { ) ); + register_setting( + 'themeisle_blocks_settings', + 'themeisle_blocks_settings_highlight_dynamic', + array( + 'type' => 'boolean', + 'description' => __( 'Easily differentiate between dynamic and normal text in the editor.', 'otter-blocks' ), + 'show_in_rest' => true, + 'default' => true, + ) + ); + register_setting( 'themeisle_blocks_settings', 'themeisle_blocks_settings_optimize_animations_css', diff --git a/inc/render/class-sharing-icons-block.php b/inc/render/class-sharing-icons-block.php index 1a05f530b..a427c7e59 100644 --- a/inc/render/class-sharing-icons-block.php +++ b/inc/render/class-sharing-icons-block.php @@ -17,44 +17,58 @@ class Sharing_Icons_Block { /** * Return attributes for social media services. * + * @param string|null $context Context of the sharing icons block. + * * @return array */ - public static function get_social_profiles() { + public static function get_social_profiles( $context = null ) { + $current_url = home_url( add_query_arg( null, null ) ); + $title = get_the_title( get_queried_object_id() ); + + if ( is_archive() ) { + $title = get_the_archive_title(); + } elseif ( 'query' === $context ) { + $current_url = get_the_permalink(); + $title = get_the_title(); + } elseif ( null === get_queried_object() && is_home() ) { + $title = get_bloginfo( 'name' ); + } + $social_attributes = array( 'facebook' => array( 'label' => esc_html__( 'Facebook', 'otter-blocks' ), 'icon' => 'facebook-f', - 'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . esc_url( get_the_permalink() ) . '&title=' . esc_attr( get_the_title() ), + 'url' => 'https://www.facebook.com/sharer/sharer.php?u=' . esc_url( $current_url ) . '&title=' . esc_attr( $title ), ), 'twitter' => array( 'label' => esc_html__( 'Twitter', 'otter-blocks' ), 'icon' => 'twitter', - 'url' => 'http://twitter.com/share?url=' . esc_url( get_the_permalink() ) . '&text=' . esc_attr( get_the_title() ), + 'url' => 'http://twitter.com/share?url=' . esc_url( $current_url ) . '&text=' . esc_attr( $title ), ), 'linkedin' => array( 'label' => esc_html__( 'Linkedin', 'otter-blocks' ), 'icon' => 'linkedin-in', - 'url' => 'https://www.linkedin.com/shareArticle?mini=true&url=' . esc_url( get_the_permalink() ) . '&title=' . esc_attr( get_the_title() ), + 'url' => 'https://www.linkedin.com/shareArticle?mini=true&url=' . esc_url( $current_url ) . '&title=' . esc_attr( $title ), ), 'pinterest' => array( 'label' => esc_html__( 'Pinterest', 'otter-blocks' ), 'icon' => 'pinterest-p', - 'url' => 'https://pinterest.com/pin/create/button/?url=' . esc_url( get_the_permalink() ) . '&description=' . esc_attr( get_the_title() ), + 'url' => 'https://pinterest.com/pin/create/button/?url=' . esc_url( $current_url ) . '&description=' . esc_attr( $title ), ), 'tumblr' => array( 'label' => esc_html__( 'Tumblr', 'otter-blocks' ), 'icon' => 'tumblr', - 'url' => 'https://tumblr.com/share/link?url=' . esc_url( get_the_permalink() ) . '&name=' . esc_attr( get_the_title() ), + 'url' => 'https://tumblr.com/share/link?url=' . esc_url( $current_url ) . '&name=' . esc_attr( $title ), ), 'reddit' => array( 'label' => esc_html__( 'Reddit', 'otter-blocks' ), 'icon' => 'reddit-alien', - 'url' => 'https://www.reddit.com/submit?url=' . esc_url( get_the_permalink() ), + 'url' => 'https://www.reddit.com/submit?url=' . esc_url( $current_url ), ), ); @@ -82,7 +96,7 @@ private function is_active( $icon ) { * @return mixed|string */ public function render( $attributes ) { - $social_attributes = $this->get_social_profiles(); + $social_attributes = $this->get_social_profiles( isset( $attributes['context'] ) ? $attributes['context'] : null ); $class = ''; diff --git a/package-lock.json b/package-lock.json index b784cb087..2f6b564fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4465,6 +4465,24 @@ "@types/wordpress__keycodes": "*", "@wordpress/element": "^4.0.0", "react-autosize-textarea": "^7.1.0" + }, + "dependencies": { + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + } } }, "@types/wordpress__blocks": { @@ -4561,6 +4579,24 @@ "@wordpress/element": "^4.1.0", "downshift": "^6.0.15", "re-resizable": "^6.4.0" + }, + "dependencies": { + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + } } }, "@types/wordpress__data": { @@ -5133,6 +5169,24 @@ "@wordpress/warning": "^2.15.0", "browserslist": "^4.17.6", "core-js": "^3.19.1" + }, + "dependencies": { + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + } } }, "@wordpress/base-styles": { @@ -5234,6 +5288,22 @@ } } } + }, + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } } } }, @@ -5432,6 +5502,22 @@ } } } + }, + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } } } }, @@ -5453,6 +5539,24 @@ "clipboard": "^2.0.8", "mousetrap": "^1.6.5", "use-memo-one": "^1.1.1" + }, + "dependencies": { + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + } } }, "@wordpress/data": { @@ -5514,6 +5618,22 @@ } } } + }, + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } } } }, @@ -5560,9 +5680,9 @@ } }, "@wordpress/dom-ready": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-3.20.0.tgz", - "integrity": "sha512-UVnm2QGZNgtvHycAknQxToQw5jLno+cYJKxk9oIgI6QOm6mx1PErjg08b5iGlLTGRUW+K+w7HhHR7WdON244ZA==", + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/@wordpress/dom-ready/-/dom-ready-3.26.0.tgz", + "integrity": "sha512-ku51n9qjSjT33wi1NB0KRVZBa9KHpN9VrC4mMgEBsjtJGJeEMeaH2SJq556TcQPjEPl6OGGGmmA0qSCuRxNKoA==", "dev": true, "requires": { "@babel/runtime": "^7.16.0" @@ -5584,18 +5704,78 @@ } }, "@wordpress/element": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.18.0.tgz", - "integrity": "sha512-+3gA4RTD/EDj1h2y/qikh+h0uCUxhShfM7QoDngKOBNSTZHqc0W2p6IMEe+AMdrmu8tyZboTJW/eONjUHE4n7g==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-5.3.0.tgz", + "integrity": "sha512-sgBrPm9suYx9sAtMLnfqgJem54Vew+BvVRpQoKQjpoXAKklGKSr52xOERek2TZQuZl/hMCCdvScrLIIW96UNAw==", + "dev": true, "requires": { "@babel/runtime": "^7.16.0", - "@types/react": "^17.0.37", - "@types/react-dom": "^17.0.11", - "@wordpress/escape-html": "^2.20.0", + "@types/react": "^18.0.21", + "@types/react-dom": "^18.0.6", + "@wordpress/escape-html": "^2.26.0", "change-case": "^4.1.2", "is-plain-object": "^5.0.0", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "dependencies": { + "@types/react": { + "version": "18.0.27", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", + "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.0.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", + "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@wordpress/escape-html": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-2.26.0.tgz", + "integrity": "sha512-uWumpNH4hnmeepTw9K3gC5LmoZECom5L1P6HuZXYXyld8eU5L9p/JdvAPOwLmjffHyJO3hiB2JqYd+nKElbtrw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.16.0" + } + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + } + }, + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } + } } }, "@wordpress/env": { @@ -5839,6 +6019,23 @@ "@babel/runtime": "^7.16.0", "@wordpress/element": "^4.18.0", "@wordpress/primitives": "^3.18.0" + }, + "dependencies": { + "@wordpress/element": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-4.20.0.tgz", + "integrity": "sha512-Ou7EoGtGe4FUL6fKALINXJLKoSfyWTBJzkJfN2HzSgM1wira9EuWahl8MQN0HAUaWeOoDqMKPvnglfS+kC8JLA==", + "requires": { + "@babel/runtime": "^7.16.0", + "@types/react": "^17.0.37", + "@types/react-dom": "^17.0.11", + "@wordpress/escape-html": "^2.22.0", + "change-case": "^4.1.2", + "is-plain-object": "^5.0.0", + "react": "^17.0.2", + "react-dom": "^17.0.2" + } + } } }, "@wordpress/is-shallow-equal": { diff --git a/package.json b/package.json index b7b65f8ed..9a2e7e09b 100644 --- a/package.json +++ b/package.json @@ -76,9 +76,9 @@ "@wordpress/components": "^21.3.0", "@wordpress/compose": "^5.14.0", "@wordpress/data": "^7.4.0", - "@wordpress/dom-ready": "^3.20.0", + "@wordpress/dom-ready": "^3.26.0", "@wordpress/e2e-test-utils": "^8.0.0", - "@wordpress/element": "^4.18.0", + "@wordpress/element": "^5.3.0", "@wordpress/env": "^5.5.0", "@wordpress/scripts": "^22.5.0", "conventional-changelog-simple-preset": "^1.0.20", diff --git a/readme.txt b/readme.txt index 558de3249..dfa1ff8d1 100644 --- a/readme.txt +++ b/readme.txt @@ -205,6 +205,28 @@ You can check Otter documentation [here](https://docs.themeisle.com/article/1478 4. Google Map Block 5. Section Block +== Frequently Asked Questions == + += Is Otter Blocks free? = + +Otter comes in both free and premium versions. The [premium version](https://themeisle.com/plugins/otter-blocks/upgrade/) offers a wider variety of blocks and multiple options to customise them, [compared to the free version](https://docs.themeisle.com/article/1487-whats-the-difference-between-otter-free-and-otter-neve-pro). + += What page builder is compatible with Otter? = + +Otter provides blocks for Gutenberg, the default WordPress editor and page builder. + += Can I use Otter with any WordPress theme? = + +Sure, Otter is compatible with any WordPress theme. + += Where can I get help? = + +If you encounter any difficulties or if you have questions about Otter, you can create a ticket on our [support forum](https://wordpress.org/support/plugin/otter-blocks/). Also, feel free to check our [documentation](https://docs.themeisle.com/article/1478-otter-blocks-documentation) to find out more about the features within the plugin and how to use it to its full potential. + += What are the Patterns and how can I use them? = + +The Patterns have been designed to make it easier for you to build your site using predefined blocks that can be then customised according to your needs. You can take a look at our [dedicated documentation](https://docs.themeisle.com/article/1785-block-patterns-otter-features-library) to find out all you need to know about the Patterns. + == Changelog == ##### [Version 2.2.1](https://github.com/Codeinwp/otter-blocks/compare/v2.2.0...v2.2.1) (2023-01-30) diff --git a/src/animation/editor.scss b/src/animation/editor.scss index dfbc35273..bca00861d 100644 --- a/src/animation/editor.scss +++ b/src/animation/editor.scss @@ -120,6 +120,11 @@ .hidden-animated { visibility: hidden; } + + .animated .wp-block-navigation, + .animated.wp-block-navigation { + animation-fill-mode: none; + } } @media ( max-width: 782px ) { diff --git a/src/blocks/blocks/posts/components/layout/thumbnail.js b/src/blocks/blocks/posts/components/layout/thumbnail.js index cc70058fc..4bc2475f5 100644 --- a/src/blocks/blocks/posts/components/layout/thumbnail.js +++ b/src/blocks/blocks/posts/components/layout/thumbnail.js @@ -10,6 +10,8 @@ import { Fragment } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; +import { isEmpty } from 'lodash'; + const Thumbnail = ({ id, link, @@ -24,7 +26,7 @@ const Thumbnail = ({ const image = select( 'core' ).getMedia( id, { context: 'view' }); const featuredImage = image ? - 0 < Object.keys( image.media_details.sizes ).length ? + ( 'string' !== typeof image && ! isEmpty( image.media_details ) && 0 < Object.keys( image.media_details.sizes ).length ) ? image.media_details.sizes[size] ? image.media_details.sizes[size].source_url : image.source_url : diff --git a/src/blocks/blocks/sharing-icons/block.json b/src/blocks/blocks/sharing-icons/block.json index 279763fc7..3b2f3b76d 100644 --- a/src/blocks/blocks/sharing-icons/block.json +++ b/src/blocks/blocks/sharing-icons/block.json @@ -58,6 +58,9 @@ }, "textColor" : { "type": "string" + }, + "context": { + "type": "string" } }, "styles": [ diff --git a/src/blocks/blocks/sharing-icons/edit.js b/src/blocks/blocks/sharing-icons/edit.js index 1b6f42b7c..e11ef57f3 100644 --- a/src/blocks/blocks/sharing-icons/edit.js +++ b/src/blocks/blocks/sharing-icons/edit.js @@ -12,6 +12,8 @@ import { import ServerSideRender from '@wordpress/server-side-render'; +import { useSelect } from '@wordpress/data'; + /** * Internal dependencies */ @@ -38,6 +40,25 @@ const Edit = ({ return () => unsubscribe( attributes.id ); }, [ attributes.id ]); + const { isQueryChild } = useSelect( select => { + const { + getBlock, + getBlockParentsByBlockName + } = select( 'core/block-editor' ); + + const currentBlock = getBlock( clientId ); + + return { + isQueryChild: 0 < getBlockParentsByBlockName( currentBlock?.clientId, 'core/query' ).length + }; + }, []); + + useEffect( () => { + if ( isQueryChild ) { + setAttributes({ context: 'query' }); + } + }, [ isQueryChild ]); + const blockProps = useBlockProps(); return ( diff --git a/src/blocks/blocks/sharing-icons/types.d.ts b/src/blocks/blocks/sharing-icons/types.d.ts index 2f30bdab8..9518bdf55 100644 --- a/src/blocks/blocks/sharing-icons/types.d.ts +++ b/src/blocks/blocks/sharing-icons/types.d.ts @@ -13,6 +13,7 @@ type Attributes = { textDeco: string backgroundColor: string textColor: string + context: string } export type SharingIconsAttrs = Partial diff --git a/src/blocks/global.d.ts b/src/blocks/global.d.ts index 7d938eb20..dbd4c8537 100644 --- a/src/blocks/global.d.ts +++ b/src/blocks/global.d.ts @@ -38,6 +38,7 @@ declare global { } blocksIDs: string[] isAncestorTypeAvailable: boolean + highlightDynamicText: boolean } otterPro?: Readonly<{ isActive: boolean diff --git a/src/blocks/helpers/helper-functions.js b/src/blocks/helpers/helper-functions.js index 0373a2445..a928f24bb 100644 --- a/src/blocks/helpers/helper-functions.js +++ b/src/blocks/helpers/helper-functions.js @@ -311,6 +311,10 @@ export const isColorDark = color => { value = hex2rgba( value ); } + if ( ! Boolean( value ) ) { + return false; + } + // Extract the red, green, and blue values const [ r, g, b ] = value.match( /\d+/g ).map( Number ); diff --git a/src/blocks/helpers/icons.js b/src/blocks/helpers/icons.js index 7feacec35..728cde01c 100644 --- a/src/blocks/helpers/icons.js +++ b/src/blocks/helpers/icons.js @@ -67,7 +67,7 @@ export const otterIconColored = ({ className }) => { export const accordionIcon = () => { return ( - + ); }; @@ -76,7 +76,7 @@ export const accordionItemIcon = () => { return ( - + ); }; @@ -85,8 +85,8 @@ export const headingIcon = () => { return ( - - + + ); }; @@ -94,9 +94,9 @@ export const headingIcon = () => { export const buttonsIcon = () => { return ( - - - + + + ); }; @@ -104,8 +104,8 @@ export const buttonsIcon = () => { export const buttonIcon = () => { return ( - - + + ); }; @@ -113,10 +113,10 @@ export const buttonIcon = () => { export const circleIcon = () => { return ( - - + + - + ); }; @@ -124,7 +124,7 @@ export const circleIcon = () => { export const countdownIcon = () => { return ( - + ); @@ -133,8 +133,8 @@ export const countdownIcon = () => { export const flipIcon = () => { return ( - - + + ); }; @@ -142,7 +142,7 @@ export const flipIcon = () => { export const faIcon = () => { return ( - + ); @@ -151,8 +151,8 @@ export const faIcon = () => { export const formIcon = () => { return ( - - + + ); }; @@ -160,7 +160,7 @@ export const formIcon = () => { export const formFieldIcon = () => { return ( - + ); @@ -169,7 +169,7 @@ export const formFieldIcon = () => { export const googleMapIcon = () => { return ( - + ); }; @@ -177,7 +177,7 @@ export const googleMapIcon = () => { export const iconListIcon = () => { return ( - + ); }; @@ -185,11 +185,11 @@ export const iconListIcon = () => { export const iconListItemIcon = () => { return ( - + - + - + ); }; @@ -197,9 +197,9 @@ export const iconListItemIcon = () => { export const mapIcon = () => { return ( - - - + + + ); }; @@ -207,8 +207,8 @@ export const mapIcon = () => { export const lottieIcon = () => { return ( - - + + ); }; @@ -216,9 +216,9 @@ export const lottieIcon = () => { export const popupIcon = () => { return ( - - - + + + ); }; @@ -226,7 +226,7 @@ export const popupIcon = () => { export const postsIcon = () => { return ( - + ); }; @@ -234,8 +234,8 @@ export const postsIcon = () => { export const progressIcon = () => { return ( - - + + ); }; @@ -243,8 +243,8 @@ export const progressIcon = () => { export const reviewIcon = () => { return ( - - + + ); @@ -253,8 +253,8 @@ export const reviewIcon = () => { export const columnsIcon = () => { return ( - - + + ); }; @@ -262,9 +262,9 @@ export const columnsIcon = () => { export const columnIcon = () => { return ( - + - + ); }; @@ -272,8 +272,8 @@ export const columnIcon = () => { export const sharingIcon = () => { return ( - - + + ); }; @@ -281,8 +281,8 @@ export const sharingIcon = () => { export const sliderIcon = () => { return ( - - + + ); }; @@ -290,9 +290,9 @@ export const sliderIcon = () => { export const tabsIcon = () => { return ( - - - + + + ); }; @@ -300,7 +300,7 @@ export const tabsIcon = () => { export const tabsItemIcon = () => { return ( - + ); }; @@ -308,7 +308,7 @@ export const tabsItemIcon = () => { export const masonryIcon = () => { return ( - + ); }; @@ -316,7 +316,7 @@ export const masonryIcon = () => { export const searchIcon = () => { return ( - + ); }; @@ -325,7 +325,7 @@ export const cartIcon = () => { return ( - + ); }; @@ -333,9 +333,9 @@ export const cartIcon = () => { export const businessHoursIcon = () => { return ( - - - + + + ); diff --git a/src/blocks/plugins/copy-paste/adaptors.ts b/src/blocks/plugins/copy-paste/adaptors.ts index c26f94f59..5dbbf252b 100644 --- a/src/blocks/plugins/copy-paste/adaptors.ts +++ b/src/blocks/plugins/copy-paste/adaptors.ts @@ -5,7 +5,7 @@ import { coreAdaptors } from './core-adaptors'; import { ColumnAttrs } from '../../blocks/section/column/types'; import { ButtonGroupAttrs } from '../../blocks/button-group/group/types'; import { ButtonAttrs } from '../../blocks/button-group/button/types'; -import { addUnit, getInt, makeBox, getSingleValueFromBox } from './utils'; +import { addUnit, getInt, makeBox, getSingleValueFromBox, createBoxFrom } from './utils'; import { IconAttrs } from '../../blocks/font-awesome-icons/types'; import { IconListAttrs } from '../../blocks/icon-list/types'; import { IconListItemAttrs } from '../../blocks/icon-list/item/types'; @@ -480,10 +480,15 @@ export const adaptors = { size: addUnit( attrs?.labelFontSize, 'px' ) }, border: { - width: makeBox( addUnit( attrs?.inputBorderWidth, 'px' ) ), + width: createBoxFrom( attrs?.inputBorderWidth ), radius: { - desktop: makeBox( addUnit( attrs?.inputBorderRadius, 'px' ) ) + desktop: createBoxFrom( attrs?.inputBorderRadius ) } + }, + padding: { + desktop: attrs?.inputPadding, + tablet: attrs?.inputPaddingTablet, + mobile: attrs?.inputPaddingMobile } }, private: { @@ -501,7 +506,10 @@ export const adaptors = { labelFontSize: getInt( s?.font?.size ), inputBorderColor: s?.colors?.border, inputBorderRadius: getInt( s?.border?.radius?.desktop?.top ), - inputBorderWidth: getInt( getSingleValueFromBox( s?.border?.width ) ) + inputBorderWidth: getInt( getSingleValueFromBox( s?.border?.width ) ), + inputPadding: s?.padding?.desktop, + inputPaddingTablet: s?.padding?.tablet, + inputPaddingMobile: s?.padding?.mobile }; } }, diff --git a/src/blocks/plugins/copy-paste/copy-paste.ts b/src/blocks/plugins/copy-paste/copy-paste.ts index f19ecb5dc..d450d1988 100644 --- a/src/blocks/plugins/copy-paste/copy-paste.ts +++ b/src/blocks/plugins/copy-paste/copy-paste.ts @@ -3,6 +3,8 @@ import { OtterBlock } from '../../helpers/blocks'; import { compactObject } from '../../helpers/helper-functions'; import { adaptors } from './adaptors'; import { CopyPasteStorage, Storage } from './models'; +import { copyAnimations, pasteAnimations } from './plugins'; + type Adaptors = Record Storage @@ -43,6 +45,7 @@ class CopyPaste { this.storage.shared = copied?.shared; this.storage.core = copied?.core; this.storage.private = copied?.private; + this.storage.animations = copyAnimations( block?.attributes?.className ); this.sync(); success = 'SUCCESS'; @@ -69,6 +72,15 @@ class CopyPaste { }; pasted = ( adaptors as Adaptors )?.[block.name]?.paste( attrs ); + pasted.className = pasteAnimations( block.attributes?.className, this.storage.animations ); + + if ( block.name !== this.storage.copiedBlock ) { + + /** + * If the blocks are not the same type, copy only the defined values. This will prevent some unwanted override. + */ + pasted = compactObject( pasted ); + } } catch ( e ) { console.error( e ); diff --git a/src/blocks/plugins/copy-paste/core-adaptors.ts b/src/blocks/plugins/copy-paste/core-adaptors.ts index 9dac0435f..ad9c548d5 100644 --- a/src/blocks/plugins/copy-paste/core-adaptors.ts +++ b/src/blocks/plugins/copy-paste/core-adaptors.ts @@ -1,4 +1,4 @@ -import { isObjectLike, merge, pick } from 'lodash'; +import { merge, pick } from 'lodash'; import { BoxType } from '../../helpers/blocks'; import { getChoice } from '../../helpers/helper-functions'; import { Storage } from './models'; @@ -52,13 +52,14 @@ const commonExtractor = ( attrs: any ): Storage => { }, margin: { desktop: attrs?.style?.spacing?.margin - }, - border: { - width: makeBox( attrs?.style?.border?.width ), - radius: { - desktop: ! isObjectLike( attrs?.style?.border?.radius ) ? makeBox( attrs?.style?.border?.radius ) : radiusExtract( attrs?.style?.border?.radius ) - } } + + // border: { + // width: makeBox( attrs?.style?.border?.width ), + // radius: { + // desktop: ! isObjectLike( attrs?.style?.border?.radius ) ? makeBox( attrs?.style?.border?.radius ) : radiusExtract( attrs?.style?.border?.radius ) + // } + // } }, core: { textColor: attrs?.textColor, diff --git a/src/blocks/plugins/copy-paste/models.d.ts b/src/blocks/plugins/copy-paste/models.d.ts index d41836679..0c4c1ba09 100644 --- a/src/blocks/plugins/copy-paste/models.d.ts +++ b/src/blocks/plugins/copy-paste/models.d.ts @@ -70,4 +70,5 @@ type CopyPasteStorage = { shared?: SharedAttrs core?: SharedCore private?: any + animations?: string[] } diff --git a/src/blocks/plugins/copy-paste/plugins.ts b/src/blocks/plugins/copy-paste/plugins.ts new file mode 100644 index 000000000..19d24e6d1 --- /dev/null +++ b/src/blocks/plugins/copy-paste/plugins.ts @@ -0,0 +1,53 @@ +import { uniq } from 'lodash'; +import { animationsList, outAnimation, delayList, speedList } from '../../../animation/data'; + +export const copyAnimations = ( className: string | undefined ) => { + if ( className === undefined || ! className?.includes( 'animated' ) ) { + return undefined; + } + + const allClasses = uniq( className.split( ' ' ) ); + + const animations = [ + 'animated', + ...animationsList.map( x => x.value ), + ...outAnimation, + ...delayList.map( x => x.value ), + ...speedList + ]; + + const otterAnim = allClasses.filter( c => { + return 0 < c.length && animations.some( a => c === a ); + }); + + return 0 === otterAnim.length ? undefined : otterAnim; +}; + +export const pasteAnimations = ( className: string | undefined, animList: string[] | undefined ) => { + + if ( animList === undefined ) { + return className; + } + + const currentClasses = uniq( ( className ?? '' ).split( ' ' ) ); + + const animations = [ + 'animated', + ...animationsList.map( x => x.value ), + ...outAnimation, + ...delayList.map( x => x.value ), + ...speedList + ]; + + const cleaned = currentClasses + .filter( c => { + return ! animations.some( a => c === a ) && 0 < c.length; + }); + + return uniq([ ...( cleaned ?? []), ...( animList ?? []) ]).join( ' ' ).trim(); +}; + +export default { + copyAnimations, + pasteAnimations +}; diff --git a/src/blocks/plugins/copy-paste/utils.ts b/src/blocks/plugins/copy-paste/utils.ts index 35d878d2f..fda6807b4 100644 --- a/src/blocks/plugins/copy-paste/utils.ts +++ b/src/blocks/plugins/copy-paste/utils.ts @@ -1,4 +1,5 @@ import { color } from '@wordpress/icons/build-types'; +import { isNumber, isString } from 'lodash'; import { BoxType } from '../../helpers/blocks'; /** @@ -184,3 +185,15 @@ export const getColorFromThemeStyles = ( type: 'color' | 'gradient' | 'duotone' const isCSSVar = Boolean( color?.includes( '--wp--preset--' ) ); return isCSSVar ? `var(${color})` : color; }; + +export const createBoxFrom = ( x: string | number | undefined | BoxType ) => { + if ( isNumber( x ) ) { + return makeBox( addUnit( x, 'px' ) ); + } + + if ( isString( x ) ) { + return makeBox( x ); + } + + return x; +}; diff --git a/src/blocks/plugins/dynamic-content/editor.scss b/src/blocks/plugins/dynamic-content/editor.scss index ae91a112c..13307d606 100644 --- a/src/blocks/plugins/dynamic-content/editor.scss +++ b/src/blocks/plugins/dynamic-content/editor.scss @@ -45,13 +45,16 @@ o-dynamic-link { .wp-block:not(.is-selected) { o-dynamic[data-preview]:not([data-preview=""]) { - text-decoration-line: underline; - text-decoration-style: double; - text-decoration-color: var(--wp-admin-theme-color); + &:not(.hide-highlight) { + text-decoration-line: underline; + text-decoration-style: dashed; + text-decoration-thickness: 7%; + text-decoration-color: var(--wp-admin-theme-color); + } span { display: none; } - + &:after { content: attr(data-preview); } diff --git a/src/blocks/plugins/dynamic-content/value/index.js b/src/blocks/plugins/dynamic-content/value/index.js index d5d8d8ead..f0ad9a3b9 100644 --- a/src/blocks/plugins/dynamic-content/value/index.js +++ b/src/blocks/plugins/dynamic-content/value/index.js @@ -61,6 +61,10 @@ const displayData = ( element, value ) => { el.innerHTML = value; value = el.textContent || el.innerText; + if ( ! Boolean( window.themeisleGutenberg.highlightDynamicText ) ) { + element.classList.add( 'hide-highlight' ); + } + element.innerHTML = '' + element.innerHTML + ''; element.dataset.preview = value; }; diff --git a/src/dashboard/components/pages/Dashboard.js b/src/dashboard/components/pages/Dashboard.js index 531a613ca..8ca2d765d 100644 --- a/src/dashboard/components/pages/Dashboard.js +++ b/src/dashboard/components/pages/Dashboard.js @@ -137,6 +137,16 @@ const Dashboard = ({ /> + + updateOption( 'themeisle_blocks_settings_highlight_dynamic', ! Boolean( getOption( 'themeisle_blocks_settings_highlight_dynamic' ) ) ) } + /> + +