From 96af5622fad7c8055b300c8ff90c643d3f6465e0 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Thu, 13 Feb 2020 16:56:14 +0800 Subject: [PATCH] Disable auto-fix `.onmessage` in `prefer-add-event-listener` rule (#543) --- rules/prefer-add-event-listener.js | 41 +++++++++++++++++----------- test/prefer-add-event-listener.js | 43 +++++++++++++++++++----------- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/rules/prefer-add-event-listener.js b/rules/prefer-add-event-listener.js index 52636a91c7..6015696251 100644 --- a/rules/prefer-add-event-listener.js +++ b/rules/prefer-add-event-listener.js @@ -3,14 +3,17 @@ const getDocumentationUrl = require('./utils/get-documentation-url'); const domEventsJson = require('./utils/dom-events.json'); const message = 'Prefer `{{replacement}}` over `{{method}}`.{{extra}}'; -const beforeUnloadMessage = ' Use `event.preventDefault(); event.returnValue = \'foo\'` to trigger the prompt.'; +const extraMessages = { + beforeunload: 'Use `event.preventDefault(); event.returnValue = \'foo\'` to trigger the prompt.', + message: 'Note that there is difference between `SharedWorker#onmessage` and `SharedWorker#addEventListener(\'message\')`.' +}; -const nestedEvents = Object.keys(domEventsJson).map(key => domEventsJson[key]); +const nestedEvents = Object.values(domEventsJson); const eventTypes = new Set(nestedEvents.reduce((accumulatorEvents, events) => accumulatorEvents.concat(events), [])); const getEventMethodName = memberExpression => memberExpression.property.name; const getEventTypeName = eventMethodName => eventMethodName.slice('on'.length); -const fix = (fixer, sourceCode, assignmentNode, memberExpression) => { +const fixCode = (fixer, sourceCode, assignmentNode, memberExpression) => { const eventTypeName = getEventTypeName(getEventMethodName(memberExpression)); const eventObjectCode = sourceCode.getText(memberExpression.object); const fncCode = sourceCode.getText(assignmentNode.right); @@ -106,28 +109,34 @@ const create = context => { return; } - const problem = { - node, - message, - data: { - replacement: 'addEventListener', - method: eventMethodName, - extra: '' - } - }; + let replacement = 'addEventListener'; + let extra = ''; + let fix; if (isClearing(assignedExpression)) { - problem.data.replacement = 'removeEventListener'; + replacement = 'removeEventListener'; } else if ( eventTypeName === 'beforeunload' && !shouldFixBeforeUnload(assignedExpression, nodeReturnsSomething) ) { - problem.data.extra = beforeUnloadMessage; + extra = extraMessages.beforeunload; + } else if (eventTypeName === 'message') { + // Disable `onmessage` fix, see #537 + extra = extraMessages.message; } else { - problem.fix = fixer => fix(fixer, context.getSourceCode(), node, memberExpression); + fix = fixer => fixCode(fixer, context.getSourceCode(), node, memberExpression); } - context.report(problem); + context.report({ + node, + message, + data: { + replacement, + method: eventMethodName, + extra: extra ? ` ${extra}` : '' + }, + fix + }); } }; }; diff --git a/test/prefer-add-event-listener.js b/test/prefer-add-event-listener.js index 27c7bcdf54..2c1d016c8c 100644 --- a/test/prefer-add-event-listener.js +++ b/test/prefer-add-event-listener.js @@ -43,6 +43,11 @@ const expectedBeforeUnloadWithReturnMessage = [ 'Use `event.preventDefault(); event.returnValue = \'foo\'` to trigger the prompt.' ].join(' '); +const expectedMessageEventWithReturnMessage = [ + 'Prefer `addEventListener` over `onmessage`.', + 'Note that there is difference between `SharedWorker#onmessage` and `SharedWorker#addEventListener(\'message\')`.' +].join(' '); + ruleTester.run('prefer-add-event-listener', rule, { valid: [ 'foo.addEventListener(\'click\', () => {})', @@ -147,38 +152,38 @@ ruleTester.run('prefer-add-event-listener', rule, { ), invalidTestCase( 'foo.onclick = null', - null, - null, + undefined, + undefined, 'Prefer `removeEventListener` over `onclick`.' ), invalidTestCase( 'foo.onclick = undefined', - null, - null, + undefined, + undefined, 'Prefer `removeEventListener` over `onclick`.' ), invalidTestCase( 'window.onbeforeunload = null', - null, - null, + undefined, + undefined, 'Prefer `removeEventListener` over `onbeforeunload`.' ), invalidTestCase( 'window.onbeforeunload = undefined', - null, - null, + undefined, + undefined, 'Prefer `removeEventListener` over `onbeforeunload`.' ), invalidTestCase( 'window.onbeforeunload = foo', - null, - null, + undefined, + undefined, expectedBeforeUnloadWithReturnMessage ), invalidTestCase( 'window.onbeforeunload = () => \'foo\'', - null, - null, + undefined, + undefined, expectedBeforeUnloadWithReturnMessage ), invalidTestCase( @@ -187,8 +192,8 @@ ruleTester.run('prefer-add-event-listener', rule, { return bar; } `, - null, - null, + undefined, + undefined, expectedBeforeUnloadWithReturnMessage ), invalidTestCase( @@ -197,8 +202,8 @@ ruleTester.run('prefer-add-event-listener', rule, { return 'bar'; } `, - null, - null, + undefined, + undefined, expectedBeforeUnloadWithReturnMessage ), invalidTestCase( @@ -338,6 +343,12 @@ ruleTester.run('prefer-add-event-listener', rule, { `, 'onerror', [{excludedPackages: []}] + ), + invalidTestCase( + 'myWorker.port.onmessage = function(e) {}', + undefined, + undefined, + expectedMessageEventWithReturnMessage ) ] });