I just invested serveral hours in digging deep into the structures how Cookiebots auto-blocking works and why Drupal 8 scripts are not working correctly in combination with it.
Today there isn't much time left for this topic, so I'll try to sum up what's the problem and what may be our workaround. Finally we should further investigate if there are safe ways to fix this (perhaps with the Cookiebot team, because they would also have a huge benefit for their script for non jQuery environments) or live with that workaround and harden it for edge-cases.
Context
Using Cookiebot in Drupal 8 with data-blockingmode="auto" (https://www.cookiebot.com/en/automatic-cookie-control/) which is very helpful in general. Also see
#3090518: Make blocking mode configurable →
for a switch for the blockingmode.
Drupal 7 uses regular jQuery document.ready() so this problem will not exist here.
Problem / TLDR:
Due to
#1974580: Introduce domReady to remove jQuery dependency from drupal.js and clean it up. →
Drupal 8 uses https://github.com/ded/domready instad of jQuery document.ready() while Cookiebot relies on https://api.jquery.com/jQuery.holdReady to trigger Script execution after everything has been loaded (it postpones the regular event, until all external scripts have been handled, which is very clever).
In core/misc/drupal.init.js you can find this code:
(function (domready, Drupal, drupalSettings) {
domready(function () {
Drupal.attachBehaviors(document, drupalSettings);
});
})(domready, Drupal, window.drupalSettings);
Which in former times was jQuery, as described here: https://www.lullabot.com/articles/understanding-javascript-behaviors-in-...
Because the jQuery.holdReady(0) from cookiebot has no effect on this, Drupal.attachBehaviors(document, drupalSettings); already runs to early, when no scripts have been loaded.
Perhaps we may even have race conditions here, which would be worse.
UPDATE: SEE
https://www.drupal.org/node/3086669 →
Proposed solution:
We won't change core so I only see three possible solutions for us (best to worst):
- Instead of relying on jQuery, Cookiebot uses Vanilla JS which halts the the code behind jQuery AND vanilla solutions like the one in domready: https://github.com/ded/domready/blob/master/src/ready.js setting the readystate unready - All projects without jQuery would be fixed then!
- We find a safe way for this Drupal 8 module to ensure that domready() is only executed once AFTER Cookiebot did its job. It should then be bulletproof to also work if Cookiebot doesn't work or can't be loaded due to any reasons.
- We use the following workaround and HOPE that there are no side-effects or race conditions. I'd hope I could believe in that, but I can't yet...
Short version: Add the following code to cookiebot.js in this module:
jQuery(function () {
Drupal.attachBehaviors(document, Drupal.settings);
});
which will be automatically called by the Cookiebot script after all scripts have been handled.
I'll create a long version with a variable to ensure it's only called once as patch.
Tasks
- After
#3090518: Make blocking mode configurable →
has been fixed: Only run the P-O-C code if autoblocking is enabled
- Review & test if the fix works
- Implement a clean solution based on the working code
- Commit and create a new release
Sidenote:
Before I used
$window.on('CookiebotOnTagsExecuted', function () {}
instead, but I think that's less stable and may be called several times on several events (load, accept, ...)
Suggestions:
I guess we should encapsulate that workaround into
#3090518: Make blocking mode configurable →
to only be executed if block mode is set to "auto".
Thank you!
PS: Is anyone in contact with the Team from Cookiebot? They might have a look and help to find a clever JS solution!