Skip to content

Commit

Permalink
feat: allow opening via click on any [data-cookieman-show]
Browse files Browse the repository at this point in the history
Fixes: #205

(cherry picked from commit 1ce0f8d)
  • Loading branch information
jonaseberle committed Mar 6, 2024
1 parent f7db021 commit ee57f6f
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
page.5 = TEXT
page.5.value = <button data-cookieman-show>Example button: Adjust your cookie preferences</button>
2 changes: 2 additions & 0 deletions Build/cookieman_test/ext_typoscript_setup.typoscript
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@import 'EXT:cookieman_test/Configuration/TypoScript/setup.typoscript'

@import 'EXT:cookieman/Configuration/TypoScript/setup.typoscript'
@import 'EXT:cookieman/Configuration/TypoScript/Example/setup.typoscript'

Expand Down
20 changes: 20 additions & 0 deletions Documentation/Configuration/Customization/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,23 @@ Uncheck all checkboxes
data-cookieman-save>
{f:translate(key: 'deny')}
</button>


Global functionality with data-attributes
=========================================

<* data-cookieman-show>
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

Opens the cookieman dialog
It can be added to any HTML element. The element does not have to be there on
initial load (thus it should work with web components, VueJS, react, etc.).

Example:

.. code-block:: HTML

<button data-cookieman-show>
Adjust your cookie preferences
</button>
78 changes: 38 additions & 40 deletions Documentation/Developer/JavaScript.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,106 +5,104 @@
JavaScript API
==============

cookieman.js exposes these methods:
:file:`cookieman.js` exposes these methods:


cookieman.showOnce()
^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
void
cookieman.showOnce()
:sep:`|` :aspect:`Data type:` void
:sep:`|`

:aspect:`Description`
Shows the confirmation modal when consent has not been saved yet.

It is automatically called on each page from `cookieman-init.js` (with an aditional condition, see :ref:`when-is-it-shown`

It is automatically called on each page from :file:`cookieman-init.js` (with an aditional condition, see :ref:`when-is-it-shown`)

cookieman.show()
^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
void
cookieman.show()
:sep:`|` :aspect:`Data type:` void
:sep:`|`

:aspect:`Description`
Shows the confirmation modal. You can call that from anywhere you need it (e.g. with a link from your data protection declaration page).
Shows the confirmation modal.

You can also use the attribute `data-cookieman-show` on any element to show the modal when clicked.

.. code-block:: HTML

<button onclick="cookieman.show()">
<button data-cookieman-show>
Adjust your cookie preferences
</button>

.. attention::

If your website uses a strict `Content-Security-Policy` (see `Mozilla Developer Network <https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP>`__) the onclick= needs to be replaced with registering a click-handler from an external <script> (also see :ref:`how cookieman supports Content-Security-Policy <content-security-policy>`).


cookieman.hide()
^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
void
cookieman.hide()
:sep:`|` :aspect:`Data type:` void
:sep:`|`

:aspect:`Description`
Hides the confirmation modal.


cookieman.consent(groupKey)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Description`
cookieman.consent(groupKey)
:sep:`|`
Adds the given group (e.g. 'marketing') to the consented groups, updates the CookieConsent cookie
and injects all items given each corresponding trackingObject's `inject` section.

This is meant as a programmatic way to implement banners before showing content from external sources such as YouTube
videos, Google Maps, facebook posts, ... – clicking the "yes, show the content"-button would call this function and a
`<script>` in trackingObject's `inject` section would take care of actually loading the content.


cookieman.consenteds()
^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
array

:aspect:`Example`
["mandatory", "ads"]
cookieman.consenteds()
:sep:`|` :aspect:`Data type:` array
:sep:`|` :aspect:`Example:` ["mandatory", "ads"]
:sep:`|`

:aspect:`Description`
Returns all groups keys the user has consented to.


cookieman.hasConsented(groupKey)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
boolean
cookieman.hasConsented(groupKey)
:sep:`|` :aspect:`Data type:` boolean
:sep:`|`

:aspect:`Description`
Returns `true` if the user has consented to the given group (e.g. 'marketing'), else false.


cookieman.hasConsentedTrackingObject(trackingObjectKey)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
boolean
cookieman.hasConsentedTrackingObject(trackingObjectKey)
:sep:`|` :aspect:`Data type:` boolean
:sep:`|`

:aspect:`Description`
Returns `true` if the user has consented to all groups (A group is any name of a checkbox in the popup, e.g.
'marketing') that contain the given trackingObject, else false.

`trackingObjectKey` is the trackingObjects.‹tracking object key› from TypoScript, e.g. 'Matomo'.


cookieman.onScriptLoaded(String trackingObjectKey, int scriptId, function callback)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. rst-class:: dl-parameters

:aspect:`Data type`
void
cookieman.onScriptLoaded(String trackingObjectKey, int scriptId, function callback)
:sep:`|` :aspect:`Data type:` void
:sep:`|`

:aspect:`Description`
Do things after an external script has been loaded. This is useful if you are interacting with external scripts
that are loaded by Cookieman.

Expand Down
22 changes: 22 additions & 0 deletions Resources/Public/Js/cookieman.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ var cookieman = (function () {
}
}

/**
* Intercepts clicks on elements with `data-cookieman-show` attribute
* even when they are not yet in the DOM.
*/
function onBodyClick(e) {
const target = e.target
if (!target) {
return
}

if (target.dataset.hasOwnProperty('cookiemanShow')) {
cookieman.show()
}
}

function onSaveClick(e) {
e.preventDefault()
saveSelections()
Expand Down Expand Up @@ -380,6 +395,13 @@ var cookieman = (function () {
)
}

// Intercepts clicks on elements with `data-cookieman-show` attribute
// even when they are not yet in the DOM.
document.body.addEventListener(
'click',
onBodyClick
)

// load form state
loadCheckboxStates()
setDntTextIfEnabled()
Expand Down
51 changes: 51 additions & 0 deletions Tests/Acceptance/Frontend/OpenPopupCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/*
* This file is part of the package dmind/cookieman.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace Dmind\Cookieman\Tests\Acceptance\Frontend;

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

use Codeception\Util\Locator;
use Dmind\Cookieman\Tests\Acceptance\Support\AcceptanceTester;
use Exception;

/**
* Tests opening the popup
*/
class OpenPopupCest
{
public const PATH_imprint = '/imprint';
public const SELECTOR_modal = '#cookieman-modal';
public const SELECTOR_btnDataCookiemanShow = '[data-cookieman-show]';

/**
* @param AcceptanceTester $I
* @throws Exception
*/
public function openViaClickOnDataCookiemanShowElement(AcceptanceTester $I)
{
$I->amOnPage(self::PATH_imprint);
$I->waitForJS('return typeof cookieman === "object"', 10);
$I->clickWithLeftButton(['css' => self::SELECTOR_btnDataCookiemanShow]);
$I->waitForElementVisible(self::SELECTOR_modal);
}
}

0 comments on commit ee57f6f

Please sign in to comment.