diff --git a/README.md b/README.md index f0e00538..7ea98f5e 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Alternatively, you can pick out rules individually: "jquery/no-class": 2, "jquery/no-clone": 2, "jquery/no-closest": 2, + "jquery/no-context-prop": 2, "jquery/no-css": 2, "jquery/no-data": 2, "jquery/no-deferred": 2, @@ -92,6 +93,7 @@ Alternatively, you can pick out rules individually: "jquery/no-proxy": 2, "jquery/no-ready": 2, "jquery/no-global-selector": 2, + "jquery/no-selector-prop": 2, "jquery/no-serialize": 2, "jquery/no-show": 2, "jquery/no-size": 2, diff --git a/index.js b/index.js index daf4b72f..7c67261c 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,7 @@ module.exports = { 'no-class': require('./rules/no-class'), 'no-clone': require('./rules/no-clone'), 'no-closest': require('./rules/no-closest'), + 'no-context-prop': require('./rules/no-context-prop'), 'no-css': require('./rules/no-css'), 'no-data': require('./rules/no-data'), 'no-deferred': require('./rules/no-deferred'), @@ -52,6 +53,7 @@ module.exports = { 'no-prop': require('./rules/no-prop'), 'no-proxy': require('./rules/no-proxy'), 'no-ready': require('./rules/no-ready'), + 'no-selector-prop': require('./rules/no-selector-prop'), 'no-serialize': require('./rules/no-serialize'), 'no-global-selector': require('./rules/no-global-selector'), 'no-show': require('./rules/no-show'), @@ -101,7 +103,7 @@ module.exports = { 'deprecated-1.10': { extends: 'plugin:jquery/deprecated-1.9', rules: { - // FIXME: `$(...).context` + 'jquery/no-context-prop': 2 } }, // Use this profile if you're writing code targetting jQuery 1.9.x environments. @@ -130,9 +132,9 @@ module.exports = { rules: { // FIXME: `deferred.isRejected()/isResolved()` 'jquery/no-die': 2, - 'jquery/no-live': 2 + 'jquery/no-live': 2, // FIXME: `$.sub()` - // FIXME: `$(...).selector` + 'jquery/no-selector-prop': 2 } }, // Use this profile if you're writing code targetting jQuery 1.3.x environments. diff --git a/rules/no-context-prop.js b/rules/no-context-prop.js new file mode 100644 index 00000000..024deb76 --- /dev/null +++ b/rules/no-context-prop.js @@ -0,0 +1,26 @@ +'use strict' + +const utils = require('./utils.js') + +module.exports = { + meta: { + docs: {}, + schema: [] + }, + + create: function(context) { + return { + MemberExpression: function(node) { + if (node.property.name !== 'context') return + if (node.parent.callee === node) return + + if (utils.isjQuery(node)) { + context.report({ + node: node, + message: '$.context is not allowed' + }) + } + } + } + } +} diff --git a/rules/no-selector-prop.js b/rules/no-selector-prop.js new file mode 100644 index 00000000..38dcf9aa --- /dev/null +++ b/rules/no-selector-prop.js @@ -0,0 +1,26 @@ +'use strict' + +const utils = require('./utils.js') + +module.exports = { + meta: { + docs: {}, + schema: [] + }, + + create: function(context) { + return { + MemberExpression: function(node) { + if (node.property.name !== 'selector') return + if (node.parent.callee === node) return + + if (utils.isjQuery(node)) { + context.report({ + node: node, + message: '$.selector is not allowed' + }) + } + } + } + } +} diff --git a/tests/no-context-prop.js b/tests/no-context-prop.js new file mode 100644 index 00000000..1a24745a --- /dev/null +++ b/tests/no-context-prop.js @@ -0,0 +1,47 @@ +'use strict' + +const rule = require('../rules/no-context-prop') +const RuleTester = require('eslint').RuleTester + +const error = '$.context is not allowed' + +const ruleTester = new RuleTester() +ruleTester.run('no-context-prop', rule, { + valid: [ + 'context', + 'div.context', + '$div.prop.context', + '$div.context()', + '$div.context(arg)' + ], + invalid: [ + { + code: '$("div").context', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.context', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.context.prop', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.context.method()', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$("div").first().context', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: 'f($div.context)', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$("div").append($("input").context)', + errors: [{message: error, type: 'MemberExpression'}] + } + ] +}) diff --git a/tests/no-selector-prop.js b/tests/no-selector-prop.js new file mode 100644 index 00000000..9405bfbf --- /dev/null +++ b/tests/no-selector-prop.js @@ -0,0 +1,47 @@ +'use strict' + +const rule = require('../rules/no-selector-prop') +const RuleTester = require('eslint').RuleTester + +const error = '$.selector is not allowed' + +const ruleTester = new RuleTester() +ruleTester.run('no-selector-prop', rule, { + valid: [ + 'selector', + 'div.selector', + '$div.prop.selector', + '$div.selector()', + '$div.selector(arg)' + ], + invalid: [ + { + code: '$("div").selector', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.selector', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.selector.prop', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$div.selector.method()', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$("div").first().selector', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: 'f($div.selector)', + errors: [{message: error, type: 'MemberExpression'}] + }, + { + code: '$("div").append($("input").selector)', + errors: [{message: error, type: 'MemberExpression'}] + } + ] +})