Unverified Commit 3070c83b authored by lauriii's avatar lauriii
Browse files

Issue #3101922 by bnjmnm, nod_, lauriii: Find replacement for Modernizr...

Issue #3101922 by bnjmnm, nod_, lauriii: Find replacement for Modernizr touchevent test and deprecate
parent 06f6126b
......@@ -713,6 +713,7 @@ drupal.tabledrag:
- core/drupalSettings
- core/once
- core/jquery.once.bc
- core/drupal.touchevents-test
drupal.tableheader:
version: VERSION
......@@ -758,6 +759,17 @@ drupal.timezone:
- core/jquery.once.bc
- core/drupal
drupal.touchevents-test:
header: true
version: VERSION
js:
# Set weight to -22 so it loads before the Modernizr test it is
# replacing, located in modernizr-additional-tests.js. If the deprecated
# Modernizr test sees either of the classes this test adds to <body>, the
# test will not be added to Modernizr and deprecation warnings will not be
# triggered.
misc/touchevents-test.js: { weight: -22 }
drupal.vertical-tabs:
version: VERSION
js:
......@@ -1219,6 +1231,7 @@ drupal.dialog.off_canvas:
- core/drupal.announce
- core/drupal.dialog
- core/drupal.dialog.ajax
- core/drupal.touchevents-test
js-cookie:
remote: https://github.com/js-cookie/js-cookie
......
......@@ -3,6 +3,81 @@
* Provides additional Modernizr tests.
*/
((Modernizr) => {
/**
* Triggers deprecation error.
*
* Deprecation errors are only triggered if deprecation errors haven't
* been suppressed.
*
* For performance concerns this method is inlined here to avoid adding a
* dependency to core/drupal that would force drupal.js to be loaded in the
* header like this script is.
*
* @param {Object} deprecation
* The deprecation options.
* @param {string} deprecation.message
* The deprecation message.
*
* @see https://www.drupal.org/core/deprecation#javascript
*/
const _deprecationErrorModernizrCopy = ({ message }) => {
if (typeof console !== 'undefined' && console.warn) {
console.warn(`[Deprecation] ${message}`);
}
};
/**
* Triggers deprecation error when object property is being used.
*
* @param {Object} deprecation
* The deprecation options.
* @param {Object} deprecation.target
* The targeted object.
* @param {string} deprecation.deprecatedProperty
* A key of the deprecated property.
* @param {string} deprecation.message
* The deprecation message.
*
* @return {Object}
*
* @see https://www.drupal.org/core/deprecation#javascript
*/
const _deprecatedPropertyModernizrCopy = ({
target,
deprecatedProperty,
message,
}) => {
// Proxy and Reflect are not supported by all browsers. Unsupported browsers
// are ignored since this is a development feature.
if (!Proxy || !Reflect) {
return target;
}
return new Proxy(target, {
// eslint-disable-next-line no-shadow
get: (target, key, ...rest) => {
if (key === deprecatedProperty) {
_deprecationErrorModernizrCopy({ message });
}
return Reflect.get(target, key, ...rest);
},
});
};
window.Modernizr = _deprecatedPropertyModernizrCopy({
target: Modernizr,
deprecatedProperty: 'touchevents',
message:
'The touchevents property of Modernizr has been deprecated in drupal:9.4.0 and is removed from drupal:10.0.0. There will be no replacement for this feature. See https://www.drupal.org/node/3277381.',
});
if (
document.documentElement.classList.contains('touchevents') ||
document.documentElement.classList.contains('no-touchevents')
) {
return;
}
// This is a copy of Modernizr's touchevents test from version 3.3.1. Drupal
// core has updated Modernizr to a version newer than 3.3.1, but this newer
// version does not include the touchevents test in its build. Modernizr's
......@@ -13,10 +88,12 @@
// changes are refactoring the code to meet Drupal's JavaScript coding
// standards and calling prefixes and testStyles() via the Modernizr object
// as they are not in scope when adding a test via Modernizr.addTest();
// @todo find alternative to Modernizr's deprecated touchevent test in
// http://drupal.org/node/3101922
// @see https://github.com/Modernizr/Modernizr/blob/v3.3.1/feature-detects/touchevents.js
Modernizr.addTest('touchevents', () => {
_deprecationErrorModernizrCopy({
message:
'The Modernizr touch events test is deprecated in Drupal 9.4.0 and will be removed in Drupal 10.0.0. See https://www.drupal.org/node/3277381 for information on its replacement and how it should be used.',
});
let bool;
if (
......
......@@ -6,7 +6,55 @@
**/
(function (Modernizr) {
var _deprecationErrorModernizrCopy = function _deprecationErrorModernizrCopy(_ref) {
var message = _ref.message;
if (typeof console !== 'undefined' && console.warn) {
console.warn("[Deprecation] ".concat(message));
}
};
var _deprecatedPropertyModernizrCopy = function _deprecatedPropertyModernizrCopy(_ref2) {
var target = _ref2.target,
deprecatedProperty = _ref2.deprecatedProperty,
message = _ref2.message;
if (!Proxy || !Reflect) {
return target;
}
return new Proxy(target, {
get: function get(target, key) {
if (key === deprecatedProperty) {
_deprecationErrorModernizrCopy({
message: message
});
}
for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
rest[_key - 2] = arguments[_key];
}
return Reflect.get.apply(Reflect, [target, key].concat(rest));
}
});
};
window.Modernizr = _deprecatedPropertyModernizrCopy({
target: Modernizr,
deprecatedProperty: 'touchevents',
message: 'The touchevents property of Modernizr has been deprecated in drupal:9.4.0 and is removed from drupal:10.0.0. There will be no replacement for this feature. See https://www.drupal.org/node/3277381.'
});
if (document.documentElement.classList.contains('touchevents') || document.documentElement.classList.contains('no-touchevents')) {
return;
}
Modernizr.addTest('touchevents', function () {
_deprecationErrorModernizrCopy({
message: 'The Modernizr touch events test is deprecated in Drupal 9.4.0 and will be removed in Drupal 10.0.0. See https://www.drupal.org/node/3277381 for information on its replacement and how it should be used.'
});
var bool;
if ('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch) {
......
/**
* @file
* A replacement for Modernizr touch events detection.
*/
document.documentElement.classList.add(
'ontouchstart' in window ||
(window.DocumentTouch && document instanceof window.DocumentTouch)
? 'touchevents'
: 'no-touchevents',
);
/**
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
document.documentElement.classList.add('ontouchstart' in window || window.DocumentTouch && document instanceof window.DocumentTouch ? 'touchevents' : 'no-touchevents');
\ No newline at end of file
......@@ -26,6 +26,8 @@ drupal.contextual-links:
- core/internal.backbone
- core/once
- core/jquery.once.bc
- core/drupal.touchevents-test
drupal.contextual-toolbar:
version: VERSION
......
/**
* @file
* For testing a Modernizr deprecated property.
*/
((Drupal, once, Modernizr) => {
Drupal.behaviors.unsupportedModernizrProperty = {
attach() {
once('unsupported-modernizr-property', 'body').forEach(() => {
const triggerDeprecationButton = document.createElement('button');
triggerDeprecationButton.id = 'trigger-a-deprecation';
triggerDeprecationButton.textContent = 'trigger a deprecation';
triggerDeprecationButton.addEventListener('click', () => {
// eslint-disable-next-line no-unused-vars
const thisShouldTriggerWarning = Modernizr.touchevents;
});
document.querySelector('main').append(triggerDeprecationButton);
});
},
};
})(Drupal, once, Modernizr);
/**
* DO NOT EDIT THIS FILE.
* See the following change record for more information,
* https://www.drupal.org/node/2815083
* @preserve
**/
(function (Drupal, once, Modernizr) {
Drupal.behaviors.unsupportedModernizrProperty = {
attach: function attach() {
once('unsupported-modernizr-property', 'body').forEach(function () {
var triggerDeprecationButton = document.createElement('button');
triggerDeprecationButton.id = 'trigger-a-deprecation';
triggerDeprecationButton.textContent = 'trigger a deprecation';
triggerDeprecationButton.addEventListener('click', function () {
var thisShouldTriggerWarning = Modernizr.touchevents;
});
document.querySelector('main').append(triggerDeprecationButton);
});
}
};
})(Drupal, once, Modernizr);
\ No newline at end of file
name: 'Modernizr deprecation test'
type: module
description: 'Test Modernizr deprecations via a basic page that loads a library based on the path.'
package: Testing
version: VERSION
modernizr_and_touchevents:
dependencies:
- core/modernizr
- core/drupal.touchevents-test
access_unsupported_property:
js:
js/access-unsupported-property.js: {}
dependencies:
- core/drupal
- core/once
- core/modernizr
<?php
/**
* @file
* Helper module for checking Modernizr related deprecations.
*/
/**
* Implements hook_library_info_alter().
*/
function modernizr_deprecation_test_library_info_alter(&$libraries, $extension) {
if ($extension === 'core') {
unset($libraries['modernizr']['header']);
$libraries['modernizr']['js']['assets/vendor/modernizr/modernizr.min.js']['weight'] = -15;
$libraries['modernizr']['js']['misc/modernizr-additional-tests.js']['weight'] = -14;
}
if ($extension === 'js_testing_log_test') {
$libraries['deprecation_log']['js']['js/js_testing_log.js']['weight'] = -16;
}
}
modernizr_deprecation_test.a_page:
path: '/load-a-library/{extension}/{library}'
defaults:
_controller: '\Drupal\modernizr_deprecation_test\Controller\LoadLibraryController::build'
_title: 'Load a library'
requirements:
_access: 'TRUE'
<?php
namespace Drupal\modernizr_deprecation_test\Controller;
use Drupal\Core\Asset\LibraryDiscoveryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Extension\ModuleExtensionList;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A page to facilitate library loading.
*/
class LoadLibraryController implements ContainerInjectionInterface {
/**
* The module extension list.
*
* @var \Drupal\Core\Extension\ModuleExtensionList
*/
protected $moduleExtensionList;
/**
* The library discovery service.
*
* @var \Drupal\Core\Asset\LibraryDiscoveryInterface
*/
protected $libraryDiscovery;
/**
* A simple page with a library attached.
*
* @return array
* A render array.
*/
public function build($extension, $library) {
// Confirm the extension and library are valid before proceeding.
$extension_list = array_keys($this->moduleExtensionList->getList());
array_push($extension_list, 'core');
assert(in_array($extension, $extension_list), "Extension $extension not available.");
$available_libraries = $this->libraryDiscovery->getLibrariesByExtension($extension);
assert(isset($available_libraries[$library]), "Library $library not available in extension $extension");
$build = [
'#markup' => "Attaching $extension/$library",
'#cache' => [
'max-age' => 0,
],
];
$build['#attached']['library'][] = "$extension/$library";
if ($library === 'modernizr') {
$build['#attached']['library'][] = 'modernizr_deprecation_test/access_unsupported_property';
}
return $build;
}
/**
* Constructs a new LoadLibraryController.
*
* @param \Drupal\Core\Extension\ModuleExtensionList $module_extension_list
* The module extension list.
* @param \Drupal\Core\Asset\LibraryDiscoveryInterface $library_discovery
* The library discovery service.
*/
public function __construct(ModuleExtensionList $module_extension_list, LibraryDiscoveryInterface $library_discovery) {
$this->moduleExtensionList = $module_extension_list;
$this->libraryDiscovery = $library_discovery;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('extension.list.module'),
$container->get('library.discovery')
);
}
}
......@@ -38,7 +38,6 @@ public function testDialog($position) {
// Set up variables for this test.
$dialog_renderable = AjaxTestController::dialogContents();
$dialog_contents = \Drupal::service('renderer')->renderRoot($dialog_renderable);
$off_canvas_expected_response = [
'command' => 'openDialog',
'selector' => '#drupal-off-canvas',
......@@ -65,7 +64,7 @@ public function testDialog($position) {
$wrapper_format = $position && ($position !== 'side') ? 'drupal_dialog.off_canvas_' . $position : 'drupal_dialog.off_canvas';
$ajax_result = $this->drupalGet('ajax-test/dialog-contents', ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => $wrapper_format]]);
$ajax_result = Json::decode($ajax_result);
$this->assertEquals($off_canvas_expected_response, $ajax_result[3], 'off-canvas dialog JSON response matches.');
$this->assertEquals($off_canvas_expected_response, $ajax_result[4], 'off-canvas dialog JSON response matches.');
}
/**
......
......@@ -19,6 +19,12 @@ toolbar:
css/toolbar.icons.theme.css: {}
dependencies:
- core/modernizr
# Toolbar does not use touchevents detection, nor does it use Modernizr.
# Despite not using Modernizr, it loads it. Sites that expect modernizr to
# be available may be getting it due to it being part of Toolbar. Because
# of this, we must include drupal.touchevents-test so the expected
# `touchevents/no-touchevents` classes are still added to the page.
- core/drupal.touchevents-test
- core/jquery
- core/drupal
- core/drupalSettings
......
module.exports = {
'@tags': ['core'],
before(browser) {
browser
.drupalInstall()
.drupalInstallModule('modernizr_deprecation_test')
.drupalLoginAsAdmin(() => {
browser
.drupalRelativeURL('/admin/config/development/performance')
.click('#edit-clear')
.waitForElementVisible('[data-drupal-messages]', 1000)
.assert.containsText('body', 'Caches cleared')
.execute(() => {
sessionStorage.setItem(
'js_testing_log_test.warnings',
JSON.stringify([]),
);
});
});
},
after(browser) {
browser.drupalUninstall();
},
'Touchevents from core library': (browser) => {
browser
.drupalRelativeURL('/load-a-library/core/drupal.touchevents-test')
.assert.containsText('body', 'Attaching core/drupal.touchevents-test')
.waitForElementVisible('html.no-touchevents')
.assert.noDeprecationErrors();
},
'drupal.touchevents.test is used if loaded alongside Modernizr': (
browser,
) => {
browser
.drupalRelativeURL(
'/load-a-library/modernizr_deprecation_test/modernizr_and_touchevents',
)
.waitForElementVisible('html.no-touchevents')
.findElement('script[src*="touchevents-test.js"]')
.findElement('script[src*="modernizr.min.js"]')
.assert.containsText(
'body',
'Attaching modernizr_deprecation_test/modernizr_and_touchevents',
)
.assert.noDeprecationErrors();
},
'Touchevents from Modernizr': (browser) => {
browser.drupalLoginAsAdmin(() => {
browser
.drupalRelativeURL('/load-a-library/core/modernizr')
.waitForElementVisible('html.no-touchevents', 1000)
.assert.containsText('body', 'Attaching core/modernizr')
.assert.deprecationErrorExists(
'The Modernizr touch events test is deprecated in Drupal 9.4.0 and will be removed in Drupal 10.0.0. See https://www.drupal.org/node/3277381 for information on its replacement and how it should be used.',
)
.waitForElementVisible('#trigger-a-deprecation')
.click('#trigger-a-deprecation')
.assert.deprecationErrorExists(
'The touchevents property of Modernizr has been deprecated in drupal:9.4.0 and is removed from drupal:10.0.0. There will be no replacement for this feature. See https://www.drupal.org/node/3277381.',
)
.drupalLogAndEnd({ onlyOnError: false });
});
},
};
......@@ -71,12 +71,13 @@ global-styling:
# such as inputs, action links, buttons, dropbuttons. For usability and
# accessibility reasons, we keep target sizes big enough on touch screen
# devices (by not making these elements smaller than their default size).
# Modernizr is used for recognizing whether user is using a touch device or
# Modernizr was used for recognizing whether user is using a touch device or
# not. This allows conditionally rendering small variation of the control
# elements on non-touch devices. In some cases, such as when rendering
# links, it is hard recognize when Modernizr should be attached, therefore
# it has to be always attached.
- core/modernizr
# elements on non-touch devices. Modernizr's touch detection has since been
# replaced by core/drupal.touchevents-test.
# In some cases, such as when rendering links, it is hard recognize when
# this detection should be attached, therefore it is always attached.
- core/drupal.touchevents-test
node-form:
version: VERSION
......
......@@ -118,17 +118,17 @@ function seven_preprocess_menu_local_action(array &$variables) {
$variables['link']['#options']['attributes']['class'][] = 'button--primary';
$variables['link']['#options']['attributes']['class'][] = 'button--small';
// We require Modernizr's touch test for button styling.
$variables['#attached']['library'][] = 'core/modernizr';
// We require the touchevents test for button styling.
$variables['#attached']['library'][] = 'core/drupal.touchevents-test';
}
/**
* Implements hook_element_info_alter().
*/
function seven_element_info_alter(&$type) {
// We require Modernizr for button styling.
// We require the touchevents test for button styling.
if (isset($type['button'])) {
$type['button']['#attached']['library'][] = 'core/modernizr';
$type['button']['#attached']['library'][] = 'core/drupal.touchevents-test';
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment