Skip to content

Commit 4cd142c

Browse files
Merge pull request #400 from JLG-WOCFR-DEV/codex/review-code-and-accessibility-compliance-iev10o
Improve tooltip keyboard support and helper API
2 parents d05e148 + b2f2d7e commit 4cd142c

File tree

1 file changed

+256
-26
lines changed

1 file changed

+256
-26
lines changed

liens-morts-detector-jlg/assets/js/blc-admin-scripts.js

Lines changed: 256 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4371,6 +4371,107 @@ jQuery(document).ready(function($) {
43714371
var $openWrapper = null;
43724372
var speak = (accessibility && typeof accessibility.speak === 'function') ? accessibility.speak : function() {};
43734373

4374+
function getTooltipId($wrapper) {
4375+
if (!$wrapper || !$wrapper.length) {
4376+
return '';
4377+
}
4378+
4379+
var $bubble = $wrapper.find('.blc-field-help__bubble');
4380+
if (!$bubble.length) {
4381+
return '';
4382+
}
4383+
4384+
return String($bubble.attr('id') || '');
4385+
}
4386+
4387+
function elementHasTooltipReference($element, tooltipId) {
4388+
if (!$element || !$element.length || !tooltipId) {
4389+
return false;
4390+
}
4391+
4392+
var describedbyAttr = ($element.attr('aria-describedby') || '').trim();
4393+
if (describedbyAttr) {
4394+
var tokens = describedbyAttr.split(/\s+/);
4395+
if (tokens.indexOf(tooltipId) !== -1) {
4396+
return true;
4397+
}
4398+
}
4399+
4400+
if ($element.is('label')) {
4401+
var htmlFor = $element.attr('for');
4402+
if (htmlFor) {
4403+
var forElement = document.getElementById(htmlFor);
4404+
if (forElement && elementHasTooltipReference($(forElement), tooltipId)) {
4405+
return true;
4406+
}
4407+
}
4408+
4409+
var foundMatch = false;
4410+
$element.find('[aria-describedby]').each(function() {
4411+
if (elementHasTooltipReference($(this), tooltipId)) {
4412+
foundMatch = true;
4413+
return false;
4414+
}
4415+
});
4416+
4417+
if (foundMatch) {
4418+
return true;
4419+
}
4420+
}
4421+
4422+
return false;
4423+
}
4424+
4425+
function isElementAssociatedWithWrapper(element, $wrapper) {
4426+
if (!$wrapper || !$wrapper.length || !element) {
4427+
return false;
4428+
}
4429+
4430+
var $element = $(element);
4431+
if (!$element.length) {
4432+
return false;
4433+
}
4434+
4435+
if ($element.closest('.blc-field-help-wrapper').get(0) === $wrapper.get(0)) {
4436+
return true;
4437+
}
4438+
4439+
var tooltipId = getTooltipId($wrapper);
4440+
if (!tooltipId) {
4441+
return false;
4442+
}
4443+
4444+
if (elementHasTooltipReference($element, tooltipId)) {
4445+
return true;
4446+
}
4447+
4448+
var isAssociated = false;
4449+
4450+
$element.parents().each(function() {
4451+
var $parent = $(this);
4452+
4453+
if ($parent.closest('.blc-field-help-wrapper').get(0) === $wrapper.get(0)) {
4454+
isAssociated = true;
4455+
return false;
4456+
}
4457+
4458+
if (elementHasTooltipReference($parent, tooltipId)) {
4459+
isAssociated = true;
4460+
return false;
4461+
}
4462+
});
4463+
4464+
if (isAssociated) {
4465+
return true;
4466+
}
4467+
4468+
if ($element.is('label')) {
4469+
return elementHasTooltipReference($element, tooltipId);
4470+
}
4471+
4472+
return false;
4473+
}
4474+
43744475
function closeWrapper($wrapper) {
43754476
if (!$wrapper || !$wrapper.length) {
43764477
return;
@@ -4385,44 +4486,85 @@ jQuery(document).ready(function($) {
43854486
$openWrapper = null;
43864487
}
43874488

4388-
$(document).on('click', '.blc-field-help', function(event) {
4389-
event.preventDefault();
4390-
event.stopPropagation();
4391-
4392-
var $button = $(this);
4393-
var $wrapper = $button.closest('.blc-field-help-wrapper');
4394-
4395-
if (!$wrapper.length) {
4489+
function openWrapper($wrapper, $button) {
4490+
if (!$wrapper || !$wrapper.length || !$button || !$button.length) {
43964491
return;
43974492
}
43984493

4399-
if ($openWrapper && $openWrapper.get(0) !== $wrapper.get(0)) {
4494+
if ($openWrapper && $openWrapper.length && $openWrapper.get(0) !== $wrapper.get(0)) {
44004495
closeWrapper($openWrapper);
44014496
}
44024497

4403-
var isActive = $wrapper.hasClass('is-active');
4404-
if (isActive) {
4405-
closeWrapper($wrapper);
4406-
} else {
4407-
$wrapper.addClass('is-active');
4408-
$button.addClass('is-active').attr('aria-expanded', 'true');
4409-
var $bubble = $wrapper.find('.blc-field-help__bubble');
4410-
if ($bubble.length) {
4411-
var announcement = ($bubble.text() || '').trim();
4412-
if (announcement) {
4413-
speak(announcement, 'polite');
4498+
$wrapper.addClass('is-active');
4499+
$button.addClass('is-active').attr('aria-expanded', 'true');
4500+
4501+
var $bubble = $wrapper.find('.blc-field-help__bubble');
4502+
if ($bubble.length) {
4503+
var announcement = ($bubble.text() || '').trim();
4504+
if (announcement) {
4505+
speak(announcement, 'polite');
4506+
}
4507+
}
4508+
4509+
$openWrapper = $wrapper;
4510+
}
4511+
4512+
function toggleWrapper($button, forceOpen) {
4513+
if (!$button || !$button.length) {
4514+
return false;
4515+
}
4516+
4517+
var $wrapper = $button.closest('.blc-field-help-wrapper');
4518+
if (!$wrapper.length) {
4519+
return false;
4520+
}
4521+
4522+
if (typeof forceOpen === 'boolean') {
4523+
if (forceOpen) {
4524+
if (!$wrapper.hasClass('is-active')) {
4525+
openWrapper($wrapper, $button);
4526+
return true;
4527+
}
4528+
4529+
if ($openWrapper && $openWrapper.length && $openWrapper.get(0) !== $wrapper.get(0)) {
4530+
openWrapper($wrapper, $button);
4531+
return true;
44144532
}
4533+
4534+
return false;
4535+
}
4536+
4537+
if ($wrapper.hasClass('is-active')) {
4538+
closeWrapper($wrapper);
4539+
return true;
44154540
}
4416-
$openWrapper = $wrapper;
4541+
4542+
return false;
4543+
}
4544+
4545+
if ($wrapper.hasClass('is-active')) {
4546+
closeWrapper($wrapper);
4547+
return true;
44174548
}
4549+
4550+
openWrapper($wrapper, $button);
4551+
return true;
4552+
}
4553+
4554+
$(document).on('click', '.blc-field-help', function(event) {
4555+
event.preventDefault();
4556+
event.stopPropagation();
4557+
4558+
var $button = $(this);
4559+
toggleWrapper($button);
44184560
});
44194561

44204562
$(document).on('click', function(event) {
44214563
if (!$openWrapper || !$openWrapper.length) {
44224564
return;
44234565
}
44244566

4425-
if ($(event.target).closest('.blc-field-help-wrapper').length) {
4567+
if (isElementAssociatedWithWrapper(event.target, $openWrapper)) {
44264568
return;
44274569
}
44284570

@@ -4435,11 +4577,88 @@ jQuery(document).ready(function($) {
44354577
}
44364578
});
44374579

4438-
$(document).on('focusout', '.blc-field-help', function() {
4439-
if ($openWrapper) {
4440-
closeWrapper($openWrapper);
4580+
$(document).on('focusout', '.blc-field-help', function(event) {
4581+
if (!$openWrapper || !$openWrapper.length) {
4582+
return;
4583+
}
4584+
4585+
var nextTarget = event.relatedTarget || document.activeElement || null;
4586+
4587+
if (isElementAssociatedWithWrapper(nextTarget, $openWrapper)) {
4588+
return;
4589+
}
4590+
4591+
if (!nextTarget) {
4592+
window.setTimeout(function() {
4593+
if (!$openWrapper || !$openWrapper.length) {
4594+
return;
4595+
}
4596+
4597+
if (isElementAssociatedWithWrapper(document.activeElement, $openWrapper)) {
4598+
return;
4599+
}
4600+
4601+
closeWrapper($openWrapper);
4602+
}, 0);
4603+
return;
44414604
}
4605+
4606+
closeWrapper($openWrapper);
44424607
});
4608+
4609+
$(document).on('focusin', function(event) {
4610+
if (!$openWrapper || !$openWrapper.length) {
4611+
return;
4612+
}
4613+
4614+
if (isElementAssociatedWithWrapper(event.target, $openWrapper)) {
4615+
return;
4616+
}
4617+
4618+
closeWrapper($openWrapper);
4619+
});
4620+
4621+
window.blcAdmin = window.blcAdmin || {};
4622+
window.blcAdmin.helpers = window.blcAdmin.helpers || {};
4623+
4624+
function resolveButton(target) {
4625+
var $button;
4626+
4627+
if (target && target.jquery) {
4628+
$button = target;
4629+
} else {
4630+
$button = $(target);
4631+
}
4632+
4633+
if (!$button.length) {
4634+
return $();
4635+
}
4636+
4637+
if (!$button.hasClass('blc-field-help')) {
4638+
$button = $button.find('.blc-field-help').first();
4639+
}
4640+
4641+
return $button;
4642+
}
4643+
4644+
window.blcAdmin.helpers.getOpenFieldHelp = function() {
4645+
return $openWrapper && $openWrapper.length ? $openWrapper.get(0) : null;
4646+
};
4647+
4648+
window.blcAdmin.helpers.toggleFieldHelp = function(target, forceOpen) {
4649+
var $button = resolveButton(target);
4650+
4651+
if (!$button.length) {
4652+
return false;
4653+
}
4654+
4655+
return toggleWrapper($button, forceOpen);
4656+
};
4657+
4658+
return {
4659+
getOpenFieldHelp: window.blcAdmin.helpers.getOpenFieldHelp,
4660+
toggleFieldHelp: window.blcAdmin.helpers.toggleFieldHelp
4661+
};
44434662
}
44444663

44454664
function applyPersonaSettings(settings, $scope) {
@@ -4630,6 +4849,7 @@ jQuery(document).ready(function($) {
46304849

46314850
window.blcAdmin = window.blcAdmin || {};
46324851
window.blcAdmin.helpers = window.blcAdmin.helpers || {};
4852+
var fieldHelpApi = null;
46334853

46344854
if (typeof initSettingsModeToggle === 'function') {
46354855
window.blcAdmin.initSettingsModeToggle = initSettingsModeToggle;
@@ -5628,11 +5848,21 @@ jQuery(document).ready(function($) {
56285848
});
56295849
}
56305850

5631-
initFieldHelp();
5851+
fieldHelpApi = initFieldHelp();
56325852
initAdvancedSettings();
56335853
initSettingsModeToggle();
56345854
initLinksTableAjax();
56355855

5856+
window.blcAdmin.helpers = window.blcAdmin.helpers || {};
5857+
5858+
if (fieldHelpApi && typeof fieldHelpApi.getOpenFieldHelp === 'function') {
5859+
window.blcAdmin.helpers.getOpenFieldHelp = fieldHelpApi.getOpenFieldHelp;
5860+
}
5861+
5862+
if (fieldHelpApi && typeof fieldHelpApi.toggleFieldHelp === 'function') {
5863+
window.blcAdmin.helpers.toggleFieldHelp = fieldHelpApi.toggleFieldHelp;
5864+
}
5865+
56365866
$(document).on('click', 'a[href*="page=blc-dashboard"]', function() {
56375867
var href = $(this).attr('href');
56385868
if (!href) {

0 commit comments

Comments
 (0)