text: /**
   * @fileoverview Prevent usage of `javascript:` URLs
   * @author Sergei Startsev
   */
  
  'use strict';
  
  const docsUrl = require('../util/docsUrl');
  
  // ------------------------------------------------------------------------------
  // Rule Definition
  // ------------------------------------------------------------------------------
  
  // https://github.com/facebook/react/blob/d0ebde77f6d1232cefc0da184d731943d78e86f2/packages/react-dom/src/shared/sanitizeURL.js#L30
  /* eslint-disable-next-line max-len, no-control-regex */
  const isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;
  
  function hasJavaScriptProtocol(attr) {
    return attr.value.type === 'Literal' &&
      isJavaScriptProtocol.test(attr.value.value);
  }
  
  function shouldVerifyElement(node, config) {
    const name = node.name && node.name.name;
    return name === 'a' || config.find(i => i.name === name);
  }
  
  function shouldVerifyProp(node, config) {
    const name = node.name && node.name.name;
    const parentName = node.parent.name && node.parent.name.name;
  
    if (parentName === 'a' && name === 'href') {
      return true;
    }
  
    const el = config.find(i => i.name === parentName);
    if (!el) {
      return false;
    }
  
    const props = el.props || [];
    return node.name && props.indexOf(name) !== -1;
  }
  
  module.exports = {
    meta: {
      docs: {
        description: 'Forbid `javascript:` URLs',
        category: 'Best Practices',
        recommended: false,
        url: docsUrl('jsx-no-script-url')
      },
      schema: [{
        type: 'array',
        uniqueItems: true,
        items: {
          type: 'object',
          properties: {
            name: {
              type: 'string'
            },
            props: {
              type: 'array',
              items: {
                type: 'string',
                uniqueItems: true
              }
            }
          },
          required: ['name', 'props'],
          additionalProperties: false
        }
      }]
    },
  
    create(context) {
      const config = context.options[0] || [];
      return {
        JSXAttribute(node) {
          const parent = node.parent;
          if (shouldVerifyElement(parent, config) && shouldVerifyProp(node, config) && hasJavaScriptProtocol(node)) {
            context.report({
              node,
              message: 'A future version of React will block javascript: URLs as a security precaution. ' +
                'Use event handlers instead if you can. If you need to generate unsafe HTML, try using dangerouslySetInnerHTML instead.'
            });
          }
        }
      };
    }
  };
  