UNPKG

2.95 kBJavaScriptView Raw
1/*
2 * Since AngularJS 1.5, we can use a new API when creating directives.
3 * This new API should be use when creating directive without DOM manipulation.
4 *
5 * @version 0.16.0
6 * @category bestPractice
7 * @sinceAngularVersion 1.5
8 */
9'use strict';
10
11var angularRule = require('./utils/angular-rule');
12var allowedProperties = ['compile', 'link', 'multiElement', 'priority', 'templateNamespace', 'terminal'];
13
14module.exports = {
15 meta: {
16 schema: []
17 },
18 create: angularRule(function(context) {
19 var potentialReplaceNodes = {};
20
21 function addPotentialLinkNode(variableName, node) {
22 var nodeList = potentialReplaceNodes[variableName] || [];
23
24 nodeList.push({
25 name: variableName,
26 node: node,
27 block: context.getScope().block.body
28 });
29
30 potentialReplaceNodes[variableName] = nodeList;
31 }
32
33 return {
34 'angular?directive': function(callExpressionNode, fnNode) {
35 if (!fnNode || !fnNode.body) {
36 return;
37 }
38 fnNode.body.body.forEach(function(statement) {
39 if (statement.type === 'ReturnStatement' && !potentialReplaceNodes[statement.argument.name || '']) {
40 context.report(statement, 'Directive should be implemented with the component method.');
41 }
42 });
43 },
44 AssignmentExpression: function(node) {
45 // Only check for literal member property assignments.
46 if (node.left.type !== 'MemberExpression') {
47 return;
48 }
49
50 if (allowedProperties.indexOf(node.left.property.name) < 0) {
51 return;
52 }
53
54 addPotentialLinkNode(node.left.object.name, node);
55 },
56 Property: function(node) {
57 if (node.key.name === 'restrict') {
58 if (node.value.raw && node.value.raw.indexOf('C') < 0 && node.value.raw.indexOf('A') < 0) {
59 return;
60 }
61 } else if (allowedProperties.indexOf(node.key.name) < 0) {
62 return;
63 }
64
65 // assumption: Property always belongs to a ObjectExpression
66 var objectExpressionParent = node.parent.parent;
67
68 // add to potential link nodes if the object is defined in a variable
69 if (objectExpressionParent.type === 'VariableDeclarator') {
70 addPotentialLinkNode(objectExpressionParent.id.name, node);
71 }
72
73 // report directly if object is part of a return statement and inside a directive body
74 if (objectExpressionParent.type === 'ReturnStatement') {
75 addPotentialLinkNode('', node);
76 }
77 }
78 };
79 })
80};