text: /**
   * @fileoverview Forbid target='_blank' attribute
   * @author Kevin Miller
   */
  
  'use strict';
  
  const docsUrl = require('../util/docsUrl');
  const linkComponentsUtil = require('../util/linkComponents');
  
  // ------------------------------------------------------------------------------
  // Rule Definition
  // ------------------------------------------------------------------------------
  
  function isTargetBlank(attr) {
    return attr.name &&
      attr.name.name === 'target' &&
      attr.value &&
      attr.value.type === 'Literal' &&
      attr.value.value.toLowerCase() === '_blank';
  }
  
  function hasExternalLink(element, linkAttribute) {
    return element.attributes.some(attr => attr.name &&
        attr.name.name === linkAttribute &&
        attr.value.type === 'Literal' &&
        /^(?:\w+:|\/\/)/.test(attr.value.value));
  }
  
  function hasDynamicLink(element, linkAttribute) {
    return element.attributes.some(attr => attr.name &&
      attr.name.name === linkAttribute &&
      attr.value.type === 'JSXExpressionContainer');
  }
  
  function hasSecureRel(element) {
    return element.attributes.find((attr) => {
      if (attr.type === 'JSXAttribute' && attr.name.name === 'rel') {
        const tags = attr.value && attr.value.type === 'Literal' && attr.value.value.toLowerCase().split(' ');
        return tags && (tags.indexOf('noopener') >= 0 && tags.indexOf('noreferrer') >= 0);
      }
      return false;
    });
  }
  
  module.exports = {
    meta: {
      docs: {
        description: 'Forbid target="_blank" attribute without rel="noopener noreferrer"',
        category: 'Best Practices',
        recommended: true,
        url: docsUrl('jsx-no-target-blank')
      },
      schema: [{
        type: 'object',
        properties: {
          enforceDynamicLinks: {
            enum: ['always', 'never']
          }
        },
        additionalProperties: false
      }]
    },
  
    create(context) {
      const configuration = context.options[0] || {};
      const enforceDynamicLinks = configuration.enforceDynamicLinks || 'always';
      const components = linkComponentsUtil.getLinkComponents(context);
  
      return {
        JSXAttribute(node) {
          if (!components.has(node.parent.name.name) || !isTargetBlank(node) || hasSecureRel(node.parent)) {
            return;
          }
  
          const linkAttribute = components.get(node.parent.name.name);
  
          if (hasExternalLink(node.parent, linkAttribute) || (enforceDynamicLinks === 'always' && hasDynamicLink(node.parent, linkAttribute))) {
            context.report({
              node,
              message: 'Using target="_blank" without rel="noopener noreferrer" ' +
                'is a security risk: see https://mathiasbynens.github.io/rel-noopener'
            });
          }
        }
      };
    }
  };
  