Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint no-nested-ternary: off */
import browserslist from "browserslist";
import globals from "globals";
import { AstNodeTypes, TargetNameMappings } from "./constants";
import {
AstMetadataApiWithTargetsResolver,
Expand Down Expand Up @@ -165,6 +166,8 @@ function protoChainFromMemberExpression(node: ESLintNode): string[] {
return [...protoChain, node.property!.name];
}

const browserGlobals = new Set(Object.keys(globals.browser));

export function lintMemberExpression(
context: Context,
handleFailingRule: HandleFailingRule,
Expand Down Expand Up @@ -200,11 +203,20 @@ export function lintMemberExpression(
} else {
const objectName = node.object.name;
const propertyName = node.property.name;
const failingRule = rules.find(
(rule) =>
rule.object.toLowerCase() === objectName.toLowerCase() &&
const isBrowserGlobal = browserGlobals.has(objectName);
const objectNameLower = objectName.toLowerCase();

const failingRule = rules.find((rule) => {
// Match case-insensitively IF the objectName was case-sentively found in browserGlobals
const objectNameMatches = isBrowserGlobal
? rule.object.toLowerCase() === objectNameLower
: rule.object === objectName;
return (
objectNameMatches &&
(rule.property == null || rule.property === propertyName)
);
);
});

if (failingRule)
checkNotInsideIfStatementAndReport(
context,
Expand Down
159 changes: 159 additions & 0 deletions test/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,51 @@ ruleTester.run("compat", rule, {
code: "document.fonts()",
settings: { browsers: ["edge 79"] },
},
{
code: `
import * as serviceWorker from './serviceWorker';
serviceWorker.register(false);
`,
settings: { browsers: ["chrome 52", "android 145"] },
},
{
code: `
navigator.permissions
.query({ name: 'local-network-access' })
.then((permissionStatus) => {
permissionStatus.addEventListener('change', () => {});
});
`,
settings: { browsers: ["chrome 52", "android 145"] },
},
{
code: `
const abortController = new AbortController();
abortController.abort();
`,
settings: { browsers: ["chrome 70"] },
},
{
code: `
const mutationObserver = new MutationObserver(() => {});
mutationObserver.observe(document.body, { childList: true });
`,
settings: { browsers: ["chrome 52"] },
},
{
code: `
const intersectionObserver = new IntersectionObserver(() => {});
intersectionObserver.observe(document.body);
`,
settings: { browsers: ["chrome 70"] },
},
{
code: `
const IntersectionObserver = "test";
IntersectionObserver.trim();
`,
settings: { browsers: ["chrome 30"] },
},
// Import cases
{
code: `
Expand Down Expand Up @@ -730,5 +775,119 @@ ruleTester.run("compat", rule, {
},
],
},
{
code: "[].includes()",
settings: { browsers: ["ie 11"] },
errors: [
{
message: "Array.includes() is not supported in IE 11",
},
],
},
{
code: "'strsd'.includes()",
settings: { browsers: ["ie 11"] },
errors: [
{
message: "String.includes() is not supported in IE 11",
},
],
},
{
code: "[1, 2, [3, 4]].flat()",
settings: { browsers: ["ie 11"] },
errors: [
{
message: "Array.flat() is not supported in IE 11",
},
],
},
{
code: "[1,2,3].flatMap(x => [x, x])",
settings: { browsers: ["chrome 68"] },
errors: [
{
message: "Array.flatMap() is not supported in Chrome 68",
},
],
},
{
code: "Object.fromEntries([])",
settings: { browsers: ["chrome 72"] },
errors: [
{
message: "Object.fromEntries() is not supported in Chrome 72",
},
],
},
{
code: "'text'.replaceAll('x', 's')",
settings: { browsers: ["chrome 84"] },
errors: [
{
message: "String.replaceAll() is not supported in Chrome 84",
},
],
},
{
code: `navigator.serviceWorker.register("/service_worker.js");`,
settings: { browsers: ["chrome 39"] },
errors: [
{
message: "navigator.serviceWorker() is not supported in Chrome 39",
},
],
},
{
code: `
const abortController = new AbortController();
abortController.abort();
`,
settings: { browsers: ["chrome 65"] },
errors: [
{
message: "AbortController is not supported in Chrome 65",
},
],
},
{
code: `
const mutationObserver = new MutationObserver(() => {});
mutationObserver.observe(document.body, { childList: true });
`,
settings: { browsers: ["chrome 25"] },
errors: [
{
message: "MutationObserver is not supported in Chrome 25",
},
],
},
{
code: `
const intersectionObserver = new IntersectionObserver(() => {});
intersectionObserver.observe(document.body);
`,
settings: { browsers: ["chrome 50"] },
errors: [
{
message: "IntersectionObserver is not supported in Chrome 50",
},
],
},
{
code: `
navigator.permissions
.query({ name: 'local-network-access' })
.then((permissionStatus) => {
permissionStatus.addEventListener('change', () => {});
});
`,
settings: { browsers: ["chrome 41"] },
errors: [
{
message: "navigator.permissions() is not supported in Chrome 41",
},
],
},
],
});
Loading