Skip to content

Commit

Permalink
Added fixes to tooltip.js
Browse files Browse the repository at this point in the history
  • Loading branch information
zoltan-dulac committed Aug 11, 2022
1 parent dc3bf38 commit 00f9525
Show file tree
Hide file tree
Showing 6 changed files with 2,341 additions and 189 deletions.
29 changes: 15 additions & 14 deletions bin/checkHTML
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ VNU_JAR="node_modules/vnu-jar/build/dist/vnu.jar"
VNU_CMD="java -jar $VNU_JAR"
MYIP=`ifconfig -a | grep inet | grep -v inet6 | awk '{print $2}' | head -2 | tail -1`
PROJECT_URL="http://$MYIP:8888/index.php"

SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )


echo "Checking if dependencies are installed ..."
Expand Down Expand Up @@ -119,17 +119,7 @@ echo

echo "Checking HTML..."
echo
OUTPUT=`$VNU_CMD $TEMP_FILES 2>&1 |
grep -v autocorrect |
grep -v inputmode |
grep -v 'The “dialog” element is not supported in all browsers' |
grep -v 'Bad value “dialog” for attribute “method”' |
grep -v 'The “button” role is unnecessary' |
grep -v 'The “role” attribute must not be used on a “td” element' |
grep -v 'error: When the “srcset” attribute has any image candidate string with a width descriptor, the “sizes” attribute must also be present.' |
grep -v 'An “img” element which has an “alt” attribute whose value is the empty string must not have a “role” attribute.' |
grep -v 'info warning:'|
grep -v 'Element “img” is missing required attribute “src”'`
OUTPUT=`$VNU_CMD --filterfile $SCRIPT_DIR/../data/vnu-filters --errors-only $TEMP_FILES 2>&1 `
VNU_ERR_CODE="$?"

echo "ERROR CODE: $VNU_ERR_CODE"
Expand Down Expand Up @@ -191,7 +181,7 @@ then
exit 1
fi


<<comment
echo "Running aXe tests..."
#.. Make a list of the delayed URLS
Expand Down Expand Up @@ -219,13 +209,24 @@ then
echo "aXe failed. See information above."
exit 1
fi

comment


echo "Running pa11y tests ..."

DID_PALLY_SUCCEED="0"

echo '{
"urls": [ '

echo "$DOWNLOADED_URLS" | awk '{ printf("\"%s\",\n", $1) }'


echo ' ]
}'

exit

for i in $DOWNLOADED_URLS
do
pa11y $i
Expand Down
110 changes: 57 additions & 53 deletions content/body/tooltip.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,60 @@
</p>


<h2>JavaScript tooltips</h2>

<?php includeStats(array('isForNewBuilds' => true, 'comment' => 'Recommended for new and existing work.')) ?>
<?php includeStats(array('isNPM' => true)) ?>

<p>
This solution can be styled exactly the want, appears on focus, and uses the maximum value of a z-index in the document. It will disappear when keyboard users press the Escape key. <strong>It doesn't work in mobile,</strong> which while consistant with other tooltip solutions, is something that I am still looking to fix. If anyone has any ideas, please feel to <a href="https://twitter.com/zoltandulac">reach out to me on Twitter</a>.
</p>

<div id="example1" class="enable-example">
<p>
<a href="/" data-tooltip="This tooltip is accessible!">This link has a tooltip</a>
<label for="input-tooltip-example2">and so does this input field:</label>
<input id="input-tooltip-example2" type="text" data-tooltip="You can put tooltips on any focusable item.">
</p>
</div>


<?php includeShowcode("example1")?>

<script type="application/json" id="example1-props">
{
"replaceHtmlRules": {},
"steps": [{
"label": "Create markup",
"highlight": "data-tooltip",
"notes": "Our script uses the <code>data-tooltip</code> attribute instead of the <code>title</code> attribute, since <strong>title</strong> is rendered by user agents by default and cannot be styled."
},
{
"label": "Create javascript events for tooltip script",
"highlight": "%JS% tooltip.create; tooltip.init",
"notes": "When the page is loaded, create the tooltip DOM object and initialize the mouse and keyboard events that will display the tooltips. <strong>Note the role of tooltip being added to the tooltip DOM object</strong>."
},
{
"label": "Create the show and hide methods for the tooltip",
"highlight": "%JS% tooltip.show; tooltip.hide",
"notes": "We make sure the element that triggered the tooltip's <code>show</code> method will be connected to it with he aria-describedby attribute, which points to the tooltip. This ensures screenreaders announce the tooltip on focus."
},
{
"label": "Ensure tooltip disappears when Escape key is pressed",
"highlight": "%JS% tooltip.onKeyup",
"notes": "This is to ensure keyboard users can make the tooltip disappear without tabbing out of the component."
},
{
"label": "Set up the CSS",
"highlight": "%CSS%tooltip-css~ .tooltip; .tooltip::before; .tooltip--hidden ||| border[^:]*: 1px solid transparent; ",
"notes": "The arrow that points to this tooltip is CSS generated content. We hide the content ensuring it is still read by screen readers. <strong>Note the highlighted properties</strong>. <a href=\"https://piccalil.li/quick-tip/use-transparent-borders-and-outlines-to-assist-with-high-contrast-mode\">These ensure the tooltips appear in Windows High Contrast Mode</a>."
}
]
}
</script>



<h2>Native HTML Tooltips</h2>

<?php includeStats(array('doNot' => true, 'comment' => 'Although this is a common method to make tooltips, I would advise using the JavaScript method instead.')) ?>
Expand Down Expand Up @@ -79,63 +133,13 @@



<h2>JavaScript tooltips</h2>

<?php includeStats(array('isForNewBuilds' => true, 'comment' => 'Recommended for new and existing work.')) ?>
<?php includeStats(array('isNPM' => true)) ?>

<p>
This solution can be styled exactly the want, appears on focus, and uses the maximum value of a z-index in the document. It will disappear when keyboard users press the Escape key. <strong>It doesn't work in mobile,</strong> which while consistant with other tooltip solutions, is something that I am still looking to fix. If anyone has any ideas, please feel to <a href="https://twitter.com/zoltandulac">reach out to me on Twitter</a>.
</p>

<div id="example1" class="enable-example">
<p>
<a href="/" data-tooltip="This tooltip is accessible!">This link has a tooltip</a>
<label for="input-tooltip-example2">and so does this input field:</label>
<input id="input-tooltip-example2" type="text" data-tooltip="You can put tooltips on any focusable item.">
</p>
</div>


<?php includeShowcode("example1")?>

<script type="application/json" id="example1-props">
{
"replaceHtmlRules": {},
"steps": [{
"label": "Create markup",
"highlight": "data-tooltip",
"notes": "Our script uses the <code>data-tooltip</code> attribute instead of the <code>title</code> attribute, since <strong>title</strong> is rendered by user agents by default and cannot be styled."
},
{
"label": "Create javascript events for tooltip script",
"highlight": "%JS% tooltip.create; tooltip.init",
"notes": "When the page is loaded, create the tooltip DOM object and initialize the mouse and keyboard events that will display the tooltips. <strong>Note the role of tooltip being added to the tooltip DOM object</strong>."
},
{
"label": "Create the show and hide methods for the tooltip",
"highlight": "%JS% tooltip.show; tooltip.hide",
"notes": "We make sure the element that triggered the tooltip's <code>show</code> method will be connected to it with he aria-describedby attribute, which points to the tooltip. This ensures screenreaders announce the tooltip on focus."
},
{
"label": "Ensure tooltip disappears when Escape key is pressed",
"highlight": "%JS% tooltip.onKeyup",
"notes": "This is to ensure keyboard users can make the tooltip disappear without tabbing out of the component."
},
{
"label": "Set up the CSS",
"highlight": "%CSS%tooltip-css~ .tooltip; .tooltip::before; .tooltip--hidden ||| border[^:]*: 1px solid transparent; ",
"notes": "The arrow that points to this tooltip is CSS generated content. We hide the content ensuring it is still read by screen readers. <strong>Note the highlighted properties</strong>. <a href=\"https://piccalil.li/quick-tip/use-transparent-borders-and-outlines-to-assist-with-high-contrast-mode\">These ensure the tooltips appear in Windows High Contrast Mode</a>."
}
]
}
</script>

<?= includeNPMInstructions(
'tooltip',
array(),
false,
array(),
null,
true
) ?>
) ?>


10 changes: 10 additions & 0 deletions data/vnu-filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Attribute “autocorrect” not allowed on element “input” at this point.
inputmode
The “dialog” element is not supported in all browsers
Bad value “dialog” for attribute “method” on element “form”.
The “button” role is unnecessary
The “role” attribute must not be used on a “td” element which has a “table” ancestor with no “role” attribute, or with a “role” attribute whose value is “table”, “grid”, or “treegrid”.
When the “srcset” attribute has any image candidate string with a width descriptor, the “sizes” attribute must also be present.
An “img” element which has an “alt” attribute whose value is the empty string must not have a “role” attribute.
info warning:
Element “img” is missing required attribute “src”.
32 changes: 31 additions & 1 deletion js/modules/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ const tooltip = new function () {
let isTooltipVisible;
let tooltipBelongsTo;

/*!
* Determine if an element is in the viewport
* (c) 2017 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} elem The element
* @return {Boolean} Returns true if element is in the viewport
*/
function isInViewport(elem) {
var distance = elem.getBoundingClientRect();
return (
distance.top >= 0 &&
distance.left >= 0 &&
distance.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
distance.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}

this.init = () => {
this.create();

Expand Down Expand Up @@ -94,6 +110,20 @@ const tooltip = new function () {
tooltipStyle.left = (tooltipTargetRect.left + window.pageXOffset) + 'px';
isTooltipVisible = true;
tooltipBelongsTo = tooltipTarget;

// if the tooltip element is not in the viewport, we should scroll the page down so the user can see it.
// Note that this always assumes that the tooltip is below the focused element.
if (!isInViewport(tooltipEl)) {
const afterStyle = window.getComputedStyle(tooltipEl, '::after');
const afterHeight = parseInt(afterStyle.height);
const tooltipY = element.getBoundingClientRect().top;

if (window.scrollY < tooltipY) {
window.scrollTo(window.scrollX, tooltipY);
}


}
}

tooltipTarget.addEventListener('mouseleave', this.hide);
Expand All @@ -112,7 +142,7 @@ const tooltip = new function () {
}

this.hide = (e) => {
if (e.type === 'mouseleave') {
if (e && e.type === 'mouseleave') {
const hoveredElement = document.elementFromPoint(e.clientX, e.clientY);
if (hoveredElement === tooltipEl) {
return;
Expand Down
Loading

0 comments on commit 00f9525

Please sign in to comment.