Source: src/js/common/Utilities.js

/*global define */
define(['jquery', 'underscore'],
	function($, _) {
	'use strict';

	/**
  * @namespace Utilities
  * @description A generic utility object that contains functions used throughout MetacatUI to perform useful functions,
  * but not used to store or manipulate any state about the application.
  * @type {object}
  * @since 2.14.0
  */
	var Utilities = /** @lends Utilities.prototype */ {

    /**
    * HTML-encodes the given string so it can be inserted into an HTML page without running
    * any embedded Javascript.
    * @param {string} s
    * @returns {string}
    */
    encodeHTML: function(s) {

      try{
        if( !s || typeof s !== "string" ){
          return "";
        }

        return s.replace(/&/g, '&')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/'/g, "&apos;")
                .replace(/\//g, "/")
                .replace(/"/g, '&quot;');
      }
      catch(e){
        console.error("Could not encode HTML: ", e);
        return "";
      }
    },

    /**
    * Validates that the given string is a valid DOI
    * @param {string} identifier
    * @returns {boolean}
    * @since 2.15.0
    */
    isValidDOI: function(identifier) {
      // generate doi regex
      var doiRGEX = new RegExp(/^\s*(http:\/\/|https:\/\/)?(doi.org\/|dx.doi.org\/)?(doi: ?|DOI: ?)?(10\.\d{4,}(\.\d)*)\/(\w+).*$/ig)

      return doiRGEX.test(identifier);
    },

    /**
     * Read the first part of a file
     *
     * @param {File} file - A reference to a file
     * @param {Backbone.View} context - The View to bind `callback` to
     * @param {function} callback - A function to run after the read is
     *   complete. The function is bound to `context`.
     * @param {number} bytes - The number of bytes to read from the start of the
     *   file
     * @since 2.15.0
     */
    readSlice: function (file, context, callback, bytes = 1024) {
      if (typeof callback !== "function") {
        return;
      }

      var reader = new FileReader(),
        blob = file.slice(0, bytes);

      reader.onloadend = callback.bind(context);
      reader.readAsBinaryString(blob);
    },
    /**
     * Attempt to parse the header/column names from a chunk of a CSV file
     *
     * Doesn't handle:
     * - UTF BOM (garbles first col name)
     * - Commas inside quoted headers
     *
     * @param {string} text - A chunk of a file
     * @return {Array} A list of names
     * @since 2.15.0
     */
    tryParseCSVHeader: function (text) {
      // The order is important here
      var strategies = ["\r\\n", "\r", "\n"];

      var index = -1;

      for (var i = 1; i < strategies.length; i++) {
        var result = text.indexOf(strategies[i]);

        if (result >= 0) {
          index = result;

          break;
        }
      }

      if (index === -1) {
        return [];
      }

      var header_line = text.slice(0, index);
      var names = header_line.split(",");

      // Remove surrounding parens and double-quotes
      names = names.map(function(name) {
        return name.replaceAll(/^["']|["']$/gm, "");
      });

      // Filter out zero-length values (headers like a,b,c,,,,,)
      names = names.filter(function(name) {
        return name.length > 0;
      });

      return names;
    }

  }

  return Utilities;
});