@lvce-editor/eslint-plugin-virtual-dom 16.5.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +105 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -77,7 +77,7 @@ const isStringLiteral = node => {
77
77
  return isLiteralNode(node) && typeof node.value === 'string';
78
78
  };
79
79
 
80
- const meta$b = {
80
+ const meta$c = {
81
81
  docs: {
82
82
  description: 'Require an explicit role on clickable virtual-dom div nodes'
83
83
  },
@@ -86,7 +86,7 @@ const meta$b = {
86
86
  },
87
87
  type: 'problem'
88
88
  };
89
- const create$b = context => {
89
+ const create$c = context => {
90
90
  return {
91
91
  ObjectExpression(node) {
92
92
  if (!isVirtualDomNode(node)) {
@@ -107,6 +107,107 @@ const create$b = context => {
107
107
  };
108
108
 
109
109
  const clickableDivNeedsRole = {
110
+ __proto__: null,
111
+ create: create$c,
112
+ meta: meta$c
113
+ };
114
+
115
+ const meta$b = {
116
+ docs: {
117
+ description: 'Require static virtual-dom nodes created inside functions to be hoisted to module scope'
118
+ },
119
+ messages: {
120
+ hoistStaticNode: 'Hoist this static virtual-dom node to module scope.'
121
+ },
122
+ type: 'suggestion'
123
+ };
124
+ const isFunctionNode$1 = node => {
125
+ return ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(node.type);
126
+ };
127
+ const findVariable = (sourceCode, identifier) => {
128
+ let scope = sourceCode.getScope(identifier);
129
+ while (scope) {
130
+ const variable = scope.set.get(identifier.name);
131
+ if (variable) {
132
+ return variable;
133
+ }
134
+ scope = scope.upper;
135
+ }
136
+ return undefined;
137
+ };
138
+ const isStaticModuleVariable = variable => {
139
+ if (!['global', 'module'].includes(variable.scope.type)) {
140
+ return false;
141
+ }
142
+ return variable.defs.every(definition => {
143
+ if (['ClassName', 'FunctionName', 'ImportBinding'].includes(definition.type)) {
144
+ return true;
145
+ }
146
+ return definition.type === 'Variable' && definition.parent.kind === 'const';
147
+ });
148
+ };
149
+ const isStaticIdentifier = (sourceCode, node) => {
150
+ const variable = findVariable(sourceCode, node);
151
+ return Boolean(variable && isStaticModuleVariable(variable));
152
+ };
153
+ const isStaticProperty = (sourceCode, node) => {
154
+ if (node.type === 'SpreadElement' || node.kind !== 'init' || node.method) {
155
+ return false;
156
+ }
157
+ if (node.computed && !isStaticExpression(sourceCode, node.key)) {
158
+ return false;
159
+ }
160
+ return isStaticExpression(sourceCode, node.value);
161
+ };
162
+ const isStaticExpression = (sourceCode, node) => {
163
+ if (!node) {
164
+ return true;
165
+ }
166
+ switch (node.type) {
167
+ case 'ArrayExpression':
168
+ return node.elements.every(element => !element || element.type !== 'SpreadElement' && isStaticExpression(sourceCode, element));
169
+ case 'BinaryExpression':
170
+ case 'LogicalExpression':
171
+ return isStaticExpression(sourceCode, node.left) && isStaticExpression(sourceCode, node.right);
172
+ case 'ConditionalExpression':
173
+ return isStaticExpression(sourceCode, node.test) && isStaticExpression(sourceCode, node.consequent) && isStaticExpression(sourceCode, node.alternate);
174
+ case 'Identifier':
175
+ return isStaticIdentifier(sourceCode, node);
176
+ case 'Literal':
177
+ return true;
178
+ case 'MemberExpression':
179
+ return isStaticExpression(sourceCode, node.object) && (!node.computed || node.property.type !== 'PrivateIdentifier' && isStaticExpression(sourceCode, node.property));
180
+ case 'ObjectExpression':
181
+ return node.properties.every(property => isStaticProperty(sourceCode, property));
182
+ case 'TemplateLiteral':
183
+ return node.expressions.every(expression => isStaticExpression(sourceCode, expression));
184
+ case 'UnaryExpression':
185
+ return node.operator !== 'delete' && isStaticExpression(sourceCode, node.argument);
186
+ default:
187
+ return false;
188
+ }
189
+ };
190
+ const create$b = context => {
191
+ return {
192
+ ObjectExpression(node) {
193
+ if (!isVirtualDomNode(node)) {
194
+ return;
195
+ }
196
+ if (!context.sourceCode.getAncestors(node).some(isFunctionNode$1)) {
197
+ return;
198
+ }
199
+ if (!isStaticExpression(context.sourceCode, node)) {
200
+ return;
201
+ }
202
+ context.report({
203
+ messageId: 'hoistStaticNode',
204
+ node
205
+ });
206
+ }
207
+ };
208
+ };
209
+
210
+ const hoistStaticNodes = {
110
211
  __proto__: null,
111
212
  create: create$b,
112
213
  meta: meta$b
@@ -678,6 +779,7 @@ const plugin = {
678
779
  },
679
780
  rules: {
680
781
  'clickable-div-needs-role': clickableDivNeedsRole,
782
+ 'hoist-static-nodes': hoistStaticNodes,
681
783
  'no-empty-aria': noEmptyAria,
682
784
  'no-empty-class-name': noEmptyClassName,
683
785
  'no-inline-event-handlers': noInlineEventHandlers,
@@ -698,6 +800,7 @@ const recommended = [{
698
800
  },
699
801
  rules: {
700
802
  'virtual-dom/clickable-div-needs-role': 'error',
803
+ 'virtual-dom/hoist-static-nodes': 'error',
701
804
  'virtual-dom/no-empty-aria': 'error',
702
805
  'virtual-dom/no-empty-class-name': 'error',
703
806
  'virtual-dom/no-inline-event-handlers': 'error',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/eslint-plugin-virtual-dom",
3
- "version": "16.5.0",
3
+ "version": "17.0.0",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",