@lvce-editor/eslint-plugin-virtual-dom 17.1.0 → 17.2.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 +183 -46
  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$c = {
80
+ const meta$f = {
81
81
  docs: {
82
82
  description: 'Require an explicit role on clickable virtual-dom div nodes'
83
83
  },
@@ -86,7 +86,7 @@ const meta$c = {
86
86
  },
87
87
  type: 'problem'
88
88
  };
89
- const create$c = context => {
89
+ const create$f = context => {
90
90
  return {
91
91
  ObjectExpression(node) {
92
92
  if (!isVirtualDomNode(node)) {
@@ -108,11 +108,11 @@ const create$c = context => {
108
108
 
109
109
  const clickableDivNeedsRole = {
110
110
  __proto__: null,
111
- create: create$c,
112
- meta: meta$c
111
+ create: create$f,
112
+ meta: meta$f
113
113
  };
114
114
 
115
- const meta$b = {
115
+ const meta$e = {
116
116
  docs: {
117
117
  description: 'Require static virtual-dom nodes created inside functions to be hoisted to module scope'
118
118
  },
@@ -223,7 +223,7 @@ const isStaticExpression = (sourceCode, node) => {
223
223
  return false;
224
224
  }
225
225
  };
226
- const create$b = context => {
226
+ const create$e = context => {
227
227
  return {
228
228
  ObjectExpression(node) {
229
229
  if (!isVirtualDomElement(node)) {
@@ -248,11 +248,11 @@ const create$b = context => {
248
248
 
249
249
  const hoistStaticNodes = {
250
250
  __proto__: null,
251
- create: create$b,
252
- meta: meta$b
251
+ create: create$e,
252
+ meta: meta$e
253
253
  };
254
254
 
255
- const meta$a = {
255
+ const meta$d = {
256
256
  docs: {
257
257
  description: 'Disallow empty ARIA values in virtual-dom nodes'
258
258
  },
@@ -264,7 +264,7 @@ const meta$a = {
264
264
  const isAriaProperty = name => {
265
265
  return /^aria[A-Z]/.test(name);
266
266
  };
267
- const create$a = context => {
267
+ const create$d = context => {
268
268
  return {
269
269
  ObjectExpression(node) {
270
270
  if (!isVirtualDomNode(node)) {
@@ -289,11 +289,11 @@ const create$a = context => {
289
289
 
290
290
  const noEmptyAria = {
291
291
  __proto__: null,
292
- create: create$a,
293
- meta: meta$a
292
+ create: create$d,
293
+ meta: meta$d
294
294
  };
295
295
 
296
- const meta$9 = {
296
+ const meta$c = {
297
297
  docs: {
298
298
  description: 'Disallow empty className values in virtual-dom nodes'
299
299
  },
@@ -302,7 +302,7 @@ const meta$9 = {
302
302
  },
303
303
  type: 'problem'
304
304
  };
305
- const create$9 = context => {
305
+ const create$c = context => {
306
306
  return {
307
307
  ObjectExpression(node) {
308
308
  if (!isVirtualDomNode(node)) {
@@ -322,11 +322,11 @@ const create$9 = context => {
322
322
 
323
323
  const noEmptyClassName = {
324
324
  __proto__: null,
325
- create: create$9,
326
- meta: meta$9
325
+ create: create$c,
326
+ meta: meta$c
327
327
  };
328
328
 
329
- const meta$8 = {
329
+ const meta$b = {
330
330
  docs: {
331
331
  description: 'Disallow inline event handlers in virtual-dom nodes'
332
332
  },
@@ -341,7 +341,7 @@ const isEventPropertyName = name => {
341
341
  const isInlineEventHandler = node => {
342
342
  return isStringLiteral(node) || isTemplateLiteralNode(node) || isArrowFunctionExpressionNode(node) || isFunctionExpressionNode(node);
343
343
  };
344
- const create$8 = context => {
344
+ const create$b = context => {
345
345
  return {
346
346
  ObjectExpression(node) {
347
347
  if (!isVirtualDomNode(node)) {
@@ -366,11 +366,11 @@ const create$8 = context => {
366
366
 
367
367
  const noInlineEventHandlers = {
368
368
  __proto__: null,
369
- create: create$8,
370
- meta: meta$8
369
+ create: create$b,
370
+ meta: meta$b
371
371
  };
372
372
 
373
- const meta$7 = {
373
+ const meta$a = {
374
374
  docs: {
375
375
  description: 'Disallow inline style attributes in virtual-dom nodes'
376
376
  },
@@ -379,7 +379,7 @@ const meta$7 = {
379
379
  },
380
380
  type: 'problem'
381
381
  };
382
- const create$7 = context => {
382
+ const create$a = context => {
383
383
  return {
384
384
  ObjectExpression(node) {
385
385
  if (!isVirtualDomNode(node)) {
@@ -399,11 +399,11 @@ const create$7 = context => {
399
399
 
400
400
  const noInlineStyle = {
401
401
  __proto__: null,
402
- create: create$7,
403
- meta: meta$7
402
+ create: create$a,
403
+ meta: meta$a
404
404
  };
405
405
 
406
- const meta$6 = {
406
+ const meta$9 = {
407
407
  docs: {
408
408
  description: 'Disallow object-like attribute values in virtual-dom nodes'
409
409
  },
@@ -416,7 +416,7 @@ const ignoredProperties = new Set(['childCount', 'type']);
416
416
  const isObjectLikeAttributeValue = node => {
417
417
  return isObjectExpressionNode(node) || isArrayExpressionNode(node) || isArrowFunctionExpressionNode(node) || isFunctionExpressionNode(node);
418
418
  };
419
- const create$6 = context => {
419
+ const create$9 = context => {
420
420
  return {
421
421
  ObjectExpression(node) {
422
422
  if (!isVirtualDomNode(node)) {
@@ -441,11 +441,11 @@ const create$6 = context => {
441
441
 
442
442
  const noObjectAttributeValues = {
443
443
  __proto__: null,
444
- create: create$6,
445
- meta: meta$6
444
+ create: create$9,
445
+ meta: meta$9
446
446
  };
447
447
 
448
- const meta$5 = {
448
+ const meta$8 = {
449
449
  docs: {
450
450
  description: 'Disallow raw string children in virtual-dom arrays'
451
451
  },
@@ -457,7 +457,7 @@ const meta$5 = {
457
457
  const isVirtualDomArray = node => {
458
458
  return isArrayExpressionNode(node) && node.elements.some(element => isVirtualDomNode(element) || isTextCall(element));
459
459
  };
460
- const create$5 = context => {
460
+ const create$8 = context => {
461
461
  return {
462
462
  ArrayExpression(node) {
463
463
  if (!isVirtualDomArray(node)) {
@@ -478,11 +478,54 @@ const create$5 = context => {
478
478
 
479
479
  const noRawTextChildren = {
480
480
  __proto__: null,
481
- create: create$5,
482
- meta: meta$5
481
+ create: create$8,
482
+ meta: meta$8
483
483
  };
484
484
 
485
- const meta$4 = {
485
+ const meta$7 = {
486
+ docs: {
487
+ description: 'Require each virtual-dom event listener to call its dedicated handler'
488
+ },
489
+ messages: {
490
+ noSharedEventListenerHandler: 'Use the dedicated handler `{{name}}` as the first event listener parameter instead of `{{handler}}`.'
491
+ },
492
+ type: 'problem'
493
+ };
494
+ const create$7 = context => {
495
+ return {
496
+ ObjectExpression(node) {
497
+ if (!isObjectExpressionNode(node)) {
498
+ return;
499
+ }
500
+ const nameProperty = getProperty(node, 'name');
501
+ const paramsProperty = getProperty(node, 'params');
502
+ if (!nameProperty || !paramsProperty || !isStringLiteral(nameProperty.value) || !isArrayExpressionNode(paramsProperty.value)) {
503
+ return;
504
+ }
505
+ const name = nameProperty.value.value;
506
+ const firstParameter = paramsProperty.value.elements[0];
507
+ if (!name.startsWith('handle') || !isStringLiteral(firstParameter) || firstParameter.value === name) {
508
+ return;
509
+ }
510
+ context.report({
511
+ data: {
512
+ handler: firstParameter.value,
513
+ name
514
+ },
515
+ messageId: 'noSharedEventListenerHandler',
516
+ node: firstParameter
517
+ });
518
+ }
519
+ };
520
+ };
521
+
522
+ const noSharedEventListenerHandlers = {
523
+ __proto__: null,
524
+ create: create$7,
525
+ meta: meta$7
526
+ };
527
+
528
+ const meta$6 = {
486
529
  docs: {
487
530
  description: 'Prefer virtual-dom constants over raw type, role, aria boolean, and tabIndex values'
488
531
  },
@@ -497,7 +540,7 @@ const meta$4 = {
497
540
  const isAriaBooleanProperty = name => {
498
541
  return /^aria[A-Z]/.test(name);
499
542
  };
500
- const create$4 = context => {
543
+ const create$6 = context => {
501
544
  return {
502
545
  ObjectExpression(node) {
503
546
  if (!isVirtualDomNode(node)) {
@@ -545,11 +588,11 @@ const create$4 = context => {
545
588
 
546
589
  const preferConstants = {
547
590
  __proto__: null,
548
- create: create$4,
549
- meta: meta$4
591
+ create: create$6,
592
+ meta: meta$6
550
593
  };
551
594
 
552
- const meta$3 = {
595
+ const meta$5 = {
553
596
  docs: {
554
597
  description: 'Require Intl.DateTimeFormat instances to be created lazily'
555
598
  },
@@ -564,7 +607,7 @@ const isFunctionNode = node => {
564
607
  const isDateTimeFormat = node => {
565
608
  return node.type === 'MemberExpression' && !node.computed && node.object.type === 'Identifier' && node.object.name === 'Intl' && node.property.type === 'Identifier' && node.property.name === 'DateTimeFormat';
566
609
  };
567
- const create$3 = context => {
610
+ const create$5 = context => {
568
611
  const isCreatedLazily = node => {
569
612
  return context.sourceCode.getAncestors(node).some(isFunctionNode);
570
613
  };
@@ -585,8 +628,8 @@ const create$3 = context => {
585
628
 
586
629
  const preferLazyDateTimeFormat = {
587
630
  __proto__: null,
588
- create: create$3,
589
- meta: meta$3
631
+ create: create$5,
632
+ meta: meta$5
590
633
  };
591
634
 
592
635
  const isClassNameKey = node => {
@@ -634,7 +677,7 @@ const getParent = node => {
634
677
  }
635
678
  return undefined;
636
679
  };
637
- const meta$2 = {
680
+ const meta$4 = {
638
681
  docs: {
639
682
  description: 'Prefer mergeClassNames for composing virtual-dom className values'
640
683
  },
@@ -643,7 +686,7 @@ const meta$2 = {
643
686
  },
644
687
  type: 'suggestion'
645
688
  };
646
- const create$2 = context => {
689
+ const create$4 = context => {
647
690
  const reportNamespacedClassNameComposition = node => {
648
691
  if (!isManualClassNameConcatenation(node) || !hasClassNamesReference(node)) {
649
692
  return;
@@ -674,11 +717,11 @@ const create$2 = context => {
674
717
 
675
718
  const preferMergeClassNames = {
676
719
  __proto__: null,
677
- create: create$2,
678
- meta: meta$2
720
+ create: create$4,
721
+ meta: meta$4
679
722
  };
680
723
 
681
- const meta$1 = {
724
+ const meta$3 = {
682
725
  docs: {
683
726
  description: 'Prefer destructuring state properties before use'
684
727
  },
@@ -705,7 +748,7 @@ const isWriteExpression = node => {
705
748
  }
706
749
  return parent.type === 'UnaryExpression' && parent.operator === 'delete' && parent.argument === node;
707
750
  };
708
- const create$1 = context => {
751
+ const create$3 = context => {
709
752
  return {
710
753
  MemberExpression(node) {
711
754
  if (node.computed) {
@@ -732,6 +775,94 @@ const create$1 = context => {
732
775
  };
733
776
 
734
777
  const preferStateDestructuring = {
778
+ __proto__: null,
779
+ create: create$3,
780
+ meta: meta$3
781
+ };
782
+
783
+ const meta$2 = {
784
+ docs: {
785
+ description: 'Require event listener options for handlers with specific browser event behavior'
786
+ },
787
+ messages: {
788
+ requirePreventDefault: '`{{name}}` event listeners must set `preventDefault` to `true`.'
789
+ },
790
+ type: 'problem'
791
+ };
792
+ const listenersRequiringPreventDefault = new Set(['handleDragOver', 'handleDrop']);
793
+ const create$2 = context => {
794
+ return {
795
+ ObjectExpression(node) {
796
+ if (!isObjectExpressionNode(node) || !getProperty(node, 'params')) {
797
+ return;
798
+ }
799
+ const nameProperty = getProperty(node, 'name');
800
+ if (!nameProperty || !isStringLiteral(nameProperty.value) || !listenersRequiringPreventDefault.has(nameProperty.value.value)) {
801
+ return;
802
+ }
803
+ const preventDefaultProperty = getProperty(node, 'preventDefault');
804
+ if (preventDefaultProperty && isLiteralNode(preventDefaultProperty.value) && preventDefaultProperty.value.value === true) {
805
+ return;
806
+ }
807
+ context.report({
808
+ data: {
809
+ name: nameProperty.value.value
810
+ },
811
+ messageId: 'requirePreventDefault',
812
+ node: preventDefaultProperty ? preventDefaultProperty.value : nameProperty
813
+ });
814
+ }
815
+ };
816
+ };
817
+
818
+ const requireEventListenerOptions = {
819
+ __proto__: null,
820
+ create: create$2,
821
+ meta: meta$2
822
+ };
823
+
824
+ const meta$1 = {
825
+ docs: {
826
+ description: 'Require secure attributes on virtual-dom links'
827
+ },
828
+ messages: {
829
+ secureLinkRel: 'Set `rel` to `noopener noreferrer` on virtual-dom links.',
830
+ secureLinkTarget: 'Set `target` to `_blank` on virtual-dom links.'
831
+ },
832
+ type: 'problem'
833
+ };
834
+ const hasStringPropertyValue = (node, name, value) => {
835
+ const property = getProperty(node, name);
836
+ return Boolean(property && isStringLiteral(property.value) && property.value.value === value);
837
+ };
838
+ const create$1 = context => {
839
+ return {
840
+ ObjectExpression(node) {
841
+ if (!isVirtualDomNode(node)) {
842
+ return;
843
+ }
844
+ const typeProperty = getProperty(node, 'type');
845
+ const hrefProperty = getProperty(node, 'href');
846
+ if (!typeProperty || !hrefProperty || !isMemberExpressionWithProperty(typeProperty.value, 'A')) {
847
+ return;
848
+ }
849
+ if (!hasStringPropertyValue(node, 'target', '_blank')) {
850
+ context.report({
851
+ messageId: 'secureLinkTarget',
852
+ node
853
+ });
854
+ }
855
+ if (!hasStringPropertyValue(node, 'rel', 'noopener noreferrer')) {
856
+ context.report({
857
+ messageId: 'secureLinkRel',
858
+ node
859
+ });
860
+ }
861
+ }
862
+ };
863
+ };
864
+
865
+ const secureLinks = {
735
866
  __proto__: null,
736
867
  create: create$1,
737
868
  meta: meta$1
@@ -861,10 +992,13 @@ const plugin = {
861
992
  'no-inline-style': noInlineStyle,
862
993
  'no-object-attribute-values': noObjectAttributeValues,
863
994
  'no-raw-text-children': noRawTextChildren,
995
+ 'no-shared-event-listener-handlers': noSharedEventListenerHandlers,
864
996
  'prefer-constants': preferConstants,
865
997
  'prefer-lazy-date-time-format': preferLazyDateTimeFormat,
866
998
  'prefer-merge-class-names': preferMergeClassNames,
867
999
  'prefer-state-destructuring': preferStateDestructuring,
1000
+ 'require-event-listener-options': requireEventListenerOptions,
1001
+ 'secure-links': secureLinks,
868
1002
  'valid-child-count': validChildCount
869
1003
  }
870
1004
  };
@@ -882,10 +1016,13 @@ const recommended = [{
882
1016
  'virtual-dom/no-inline-style': 'error',
883
1017
  'virtual-dom/no-object-attribute-values': 'error',
884
1018
  'virtual-dom/no-raw-text-children': 'error',
1019
+ 'virtual-dom/no-shared-event-listener-handlers': 'error',
885
1020
  'virtual-dom/prefer-constants': 'error',
886
1021
  'virtual-dom/prefer-lazy-date-time-format': 'error',
887
1022
  'virtual-dom/prefer-merge-class-names': 'error',
888
1023
  'virtual-dom/prefer-state-destructuring': 'error',
1024
+ 'virtual-dom/require-event-listener-options': 'error',
1025
+ 'virtual-dom/secure-links': 'error',
889
1026
  'virtual-dom/valid-child-count': 'error'
890
1027
  }
891
1028
  }, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/eslint-plugin-virtual-dom",
3
- "version": "17.1.0",
3
+ "version": "17.2.0",
4
4
  "main": "dist/index.js",
5
5
  "repository": {
6
6
  "type": "git",