Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(frame-tested): run without respondable #2942

Merged
merged 6 commits into from Jun 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions lib/checks/media/frame-tested-after.js
@@ -0,0 +1,31 @@
const joinStr = ' > ';

function frameTestedAfter(results) {
straker marked this conversation as resolved.
Show resolved Hide resolved
const iframes = {};

return results.filter(result => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I'll be damned! I did not know you could do a filter in after.

const frameResult =
result.node.ancestry[result.node.ancestry.length - 1] !== 'html';

if (frameResult) {
const ancestry = result.node.ancestry.flat(Infinity).join(joinStr);
iframes[ancestry] = result;
return true;
}

// remove the `html` from the path to get the iframe path
const ancestry = result.node.ancestry
.slice(0, result.node.ancestry.length - 1)
.flat(Infinity)
.join(joinStr);

// pass for each iframe that has an html result
if (iframes[ancestry]) {
iframes[ancestry].result = true;
}

return false;
});
}

export default frameTestedAfter;
26 changes: 2 additions & 24 deletions lib/checks/media/frame-tested-evaluate.js
@@ -1,28 +1,6 @@
import { respondable } from '../../core/utils';

function frameTestedEvaluate(node, options) {
const resolve = this.async();
const { isViolation, timeout } = Object.assign(
{ isViolation: false, timeout: 500 },
options
);

// give the frame .5s to respond to 'axe.ping', else log failed response
let timer = setTimeout(() => {
// This double timeout is important for allowing iframes to respond
// DO NOT REMOVE
timer = setTimeout(() => {
timer = null;
resolve(isViolation ? false : undefined);
}, 0);
}, timeout);

respondable(node.contentWindow, 'axe.ping', null, undefined, () => {
if (timer !== null) {
clearTimeout(timer);
resolve(true);
}
});
// assume iframe is not tested
return options.isViolation ? false : undefined;
}

export default frameTestedEvaluate;
1 change: 1 addition & 0 deletions lib/checks/media/frame-tested.json
@@ -1,6 +1,7 @@
{
"id": "frame-tested",
"evaluate": "frame-tested-evaluate",
"after": "frame-tested-after",
"options": {
"isViolation": false
},
Expand Down
2 changes: 2 additions & 0 deletions lib/core/base/metadata-function-map.js
Expand Up @@ -126,6 +126,7 @@ import structuredDlitemsEvaluate from '../../checks/lists/structured-dlitems-eva
// media
import captionEvaluate from '../../checks/media/caption-evaluate';
import frameTestedEvaluate from '../../checks/media/frame-tested-evaluate';
import frameTestedAfter from '../../checks/media/frame-tested-after';
import noAutoplayAudioEvaluate from '../../checks/media/no-autoplay-audio-evaluate';

// rule matches
Expand Down Expand Up @@ -299,6 +300,7 @@ const metadataFunctionMap = {
// media
'caption-evaluate': captionEvaluate,
'frame-tested-evaluate': frameTestedEvaluate,
'frame-tested-after': frameTestedAfter,
'no-autoplay-audio-evaluate': noAutoplayAudioEvaluate,

// rule matches
Expand Down
27 changes: 27 additions & 0 deletions lib/core/utils/pollyfills.js
Expand Up @@ -294,3 +294,30 @@ if (!String.prototype.includes) {
}
};
}

// @see https://github.com/jonathantneal/array-flat-polyfill/blob/master/src/polyfill-flat.js
if (!Array.prototype.flat) {
Object.defineProperty(Array.prototype, 'flat', {
configurable: true,
value: function flat() {
var depth = isNaN(arguments[0]) ? 1 : Number(arguments[0]);

return depth
? Array.prototype.reduce.call(
this,
function(acc, cur) {
if (Array.isArray(cur)) {
acc.push.apply(acc, flat.call(cur, depth - 1));
} else {
acc.push(cur);
}

return acc;
},
[]
)
: Array.prototype.slice.call(this);
},
writable: true
});
}
2 changes: 1 addition & 1 deletion lib/rules/frame-tested.json
@@ -1,6 +1,6 @@
{
"id": "frame-tested",
"selector": "frame, iframe",
"selector": "html, frame, iframe",
"tags": ["cat.structure", "review-item", "best-practice"],
"metadata": {
"description": "Ensures <iframe> and <frame> elements contain the axe-core script",
Expand Down