Skip to content

Commit

Permalink
Merge pull request #8893 from google/enhancement/8384-refactor-como-js
Browse files Browse the repository at this point in the history
  • Loading branch information
aaemnnosttv committed Jul 9, 2024
2 parents 30e4c03 + a2efa32 commit 5cf1018
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 80 deletions.
78 changes: 78 additions & 0 deletions assets/js/consent-mode/consent-mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

( function () {
function actionConsentChange( event ) {
if ( event.detail ) {
const consentParameters = {};
let hasConsentParameters = false;
Object.keys( event.detail ).forEach( ( category ) => {
if ( global._googlesitekitConsentCategoryMap[ category ] ) {
const status = event.detail[ category ];
const mappedStatus =
status === 'allow' ? 'granted' : 'denied';
const parameters =
global._googlesitekitConsentCategoryMap[ category ];
parameters.forEach( ( parameter ) => {
consentParameters[ parameter ] = mappedStatus;
} );
hasConsentParameters = !! parameters.length;
}
} );
if ( hasConsentParameters ) {
global.gtag( 'consent', 'update', consentParameters );
}
}
}
document.addEventListener(
'wp_listen_for_consent_change',
actionConsentChange
);

function updateGrantedConsent() {
if ( ! ( global.wp_consent_type || global.wp_fallback_consent_type ) ) {
return;
}
const consentParameters = {};
let hasConsentParameters = false;
Object.entries( global._googlesitekitConsentCategoryMap ).forEach(
( [ category, parameters ] ) => {
if (
global.wp_has_consent &&
global.wp_has_consent( category )
) {
parameters.forEach( ( parameter ) => {
consentParameters[ parameter ] = 'granted';
} );
hasConsentParameters =
hasConsentParameters || !! parameters.length;
}
}
);
if ( hasConsentParameters ) {
global.gtag( 'consent', 'update', consentParameters );
}
}
document.addEventListener(
'wp_consent_type_defined',
updateGrantedConsent
);
document.addEventListener( 'DOMContentLoaded', function () {
if ( ! global.waitfor_consent_hook ) {
updateGrantedConsent();
}
} );
} )();
72 changes: 72 additions & 0 deletions assets/js/consent-mode/consent-mode.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Consent Mode tests
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Internal dependencies
*/
import './consent-mode';

describe( 'Consent Mode', () => {
const gtagMock = jest.fn();

beforeEach( () => {
global.gtag = gtagMock;
global._googlesitekitConsentCategoryMap = {
'test-category': [ 'test-parameter' ],
};
} );

afterEach( () => {
delete global.gtag;
delete global._googlesitekitConsentCategoryMap;
} );

it( 'should call gtag with the correct parameters when wp_listen_for_consent_change event is triggered', () => {
document.dispatchEvent(
new CustomEvent( 'wp_listen_for_consent_change', {
detail: {
'test-category': 'allow',
},
} )
);

expect( gtagMock ).toHaveBeenCalledWith( 'consent', 'update', {
'test-parameter': 'granted',
} );
} );

it( 'should call gtag with the correct parameters when wp_consent_type_defined event is triggered', () => {
document.dispatchEvent(
new CustomEvent( 'wp_consent_type_defined', {
detail: {
'test-category': 'allow',
},
} )
);
expect( gtagMock ).toHaveBeenCalledWith( 'consent', 'update', {
'test-parameter': 'granted',
} );
} );

it( 'should call gtag with the correct parameters when DOMContentLoaded event is triggered', () => {
document.dispatchEvent( new Event( 'DOMContentLoaded' ) );
expect( gtagMock ).toHaveBeenCalledWith( 'consent', 'update', {
'test-parameter': 'granted',
} );
} );
} );
101 changes: 37 additions & 64 deletions includes/Core/Consent_Mode/Consent_Mode.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
namespace Google\Site_Kit\Core\Consent_Mode;

use Google\Site_Kit\Context;
use Google\Site_Kit\Core\Assets\Script;
use Google\Site_Kit\Core\Storage\Options;
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;

Expand All @@ -24,6 +25,14 @@
class Consent_Mode {
use Method_Proxy_Trait;

/**
* Context instance.
*
* @since n.e.x.t
* @var Context
*/
protected $context;

/**
* Consent_Mode_Settings instance.
*
Expand All @@ -49,6 +58,7 @@ class Consent_Mode {
* @param Options $options Optional. Option API instance. Default is a new instance.
*/
public function __construct( Context $context, Options $options = null ) {
$this->context = $context;
$options = $options ?: new Options( $context );
$this->consent_mode_settings = new Consent_Mode_Settings( $options );
$this->rest_controller = new REST_Consent_Mode_Controller( $this->consent_mode_settings );
Expand All @@ -73,9 +83,11 @@ public function register() {
// The `wp_head` action is used to ensure the snippets are printed in the head on the front-end only, not admin pages.
add_action(
'wp_head',
$this->get_method_proxy( 'render_gtag_consent_snippet' ),
$this->get_method_proxy( 'render_gtag_consent_data_layer_snippet' ),
1 // Set priority to 1 to ensure the snippet is printed with top priority in the head.
);

add_action( 'wp_enqueue_scripts', fn () => $this->register_and_enqueue_script() );
}

add_filter(
Expand All @@ -88,12 +100,29 @@ function () use ( $consent_mode_enabled ) {
add_filter( 'googlesitekit_inline_base_data', $this->get_method_proxy( 'inline_js_base_data' ) );
}

/**
* Registers and Enqueues the consent mode script.
*
* @since n.e.x.t
*/
protected function register_and_enqueue_script() {
$consent_mode_script = new Script(
'googlesitekit-consent-mode',
array(
'src' => $this->context->url( 'dist/assets/js/googlesitekit-consent-mode.js' ),
)
);
$consent_mode_script->register( $this->context );
$consent_mode_script->enqueue();
}

/**
* Prints the gtag consent snippet.
*
* @since 1.122.0
* @since n.e.x.t Refactored core script to external js file transpiled with webpack.
*/
protected function render_gtag_consent_snippet() {
protected function render_gtag_consent_data_layer_snippet() {
/**
* Filters the consent mode defaults.
*
Expand Down Expand Up @@ -137,73 +166,17 @@ protected function render_gtag_consent_snippet() {
'preferences' => array( 'personalization_storage' ),
)
);
// TODO: We may want to extract some of this JS so it can be transpiled and rewrite it using modern language features.

// The core Consent Mode code is in assets/js/consent-mode/consent-mode.js.
// Only code that passes data from PHP to JS should be in this file.
?>
<!-- <?php echo esc_html__( 'Google tag (gtag.js) Consent Mode snippet added by Site Kit', 'google-site-kit' ); ?> -->
<script id='google_gtagjs-js-consent-mode'>
<!-- <?php echo esc_html__( 'Google tag (gtag.js) Consent Mode dataLayer added by Site Kit', 'google-site-kit' ); ?> -->
<script id='google_gtagjs-js-consent-mode-data-layer'>
window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', <?php echo wp_json_encode( $consent_defaults ); ?>);
window._googlesitekitConsentCategoryMap = <?php echo wp_json_encode( $consent_category_map ); ?>;
( function () {
document.addEventListener(
'wp_listen_for_consent_change',
function ( event ) {
if ( event.detail ) {
var consentParameters = {};
var hasConsentParameters = false;
for ( var category in event.detail ) {
if ( window._googlesitekitConsentCategoryMap[ category ] ) {
var status = event.detail[ category ];
var mappedStatus =
status === 'allow' ? 'granted' : 'denied';
var parameters =
window._googlesitekitConsentCategoryMap[ category ];
for ( var i = 0; i < parameters.length; i++ ) {
consentParameters[ parameters[ i ] ] = mappedStatus;
}
hasConsentParameters = !! parameters.length;
}
}
if ( hasConsentParameters ) {
gtag( 'consent', 'update', consentParameters );
}
}
}
);

function updateGrantedConsent() {
if ( ! ( window.wp_consent_type || window.wp_fallback_consent_type ) ) {
return;
}
var consentParameters = {};
var hasConsentParameters = false;
for ( var category in window._googlesitekitConsentCategoryMap ) {
if ( window.wp_has_consent && window.wp_has_consent( category ) ) {
var parameters =
window._googlesitekitConsentCategoryMap[ category ];
for ( var i = 0; i < parameters.length; i++ ) {
consentParameters[ parameters[ i ] ] = 'granted';
}
hasConsentParameters =
hasConsentParameters || !! parameters.length;
}
}
if ( hasConsentParameters ) {
gtag( 'consent', 'update', consentParameters );
}
}
document.addEventListener(
'wp_consent_type_defined',
updateGrantedConsent
);
document.addEventListener( 'DOMContentLoaded', function () {
if ( ! window.waitfor_consent_hook ) {
updateGrantedConsent();
}
} );
} )();
</script>
<!-- <?php echo esc_html__( 'End Google tag (gtag.js) Consent Mode snippet added by Site Kit', 'google-site-kit' ); ?> -->
<!-- <?php echo esc_html__( 'End Google tag (gtag.js) Consent Mode dataLayer added by Site Kit', 'google-site-kit' ); ?> -->
<?php
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/contact-form-7.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-contact-form-7.js' ),
'execution' => 'defer',
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/easy-digital-downloads.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-easy-digital-downloads.js' ),
'execution' => 'defer',
'dependencies' => array( 'edd-ajax' ),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/mailchimp.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-mailchimp.js' ),
'execution' => 'defer',
'dependencies' => array( 'mc4wp-forms-api' ),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/ninja-forms.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-ninja-forms.js' ),
'execution' => 'defer',
'dependencies' => array( 'nf-front-end-deps' ),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/optin-monster.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-optin-monster.js' ),
'execution' => 'defer',
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/popup-maker.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-popup-maker.js' ),
'dependencies' => array( 'popup-maker-site' ),
'execution' => 'defer',
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/wpforms.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-wpforms.js' ),
'execution' => 'defer',
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function register_script() {
$script = new Script(
'googlesitekit-events-provider-' . self::CONVERSION_EVENT_PROVIDER_SLUG,
array(
'src' => $this->context->url( 'dist/assets/js/woocommerce.js' ),
'src' => $this->context->url( 'dist/assets/js/googlesitekit-events-provider-woocommerce.js' ),
'execution' => 'defer',
'dependencies' => array( 'woocommerce' ),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function test_renders_consent_mode_snippet_when_enabled() {

$output = $this->capture_action( 'wp_head' );

$this->assertStringContainsString( 'Google tag (gtag.js) Consent Mode snippet added by Site Kit', $output );
$this->assertStringContainsString( 'Google tag (gtag.js) Consent Mode dataLayer added by Site Kit', $output );
}

public function test_does_not_render_consent_mode_snippet_when_disabled() {
Expand All @@ -60,7 +60,7 @@ public function test_does_not_render_consent_mode_snippet_when_disabled() {

$output = $this->capture_action( 'wp_head' );

$this->assertStringNotContainsString( 'Google tag (gtag.js) Consent Mode snippet added by Site Kit', $output );
$this->assertStringNotContainsString( 'Google tag (gtag.js) Consent Mode dataLayer added by Site Kit', $output );
}

public function test_register__googlesitekit_consent_mode_status() {
Expand Down
Loading

0 comments on commit 5cf1018

Please sign in to comment.