all files / src/ sputils.helpers.js

71.43% Statements 35/49
50% Branches 9/18
100% Functions 13/13
71.43% Lines 35/49
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199                                                                                                                                                                                                                                                                                                                                        
(function () {
  'use strict';
 
  /**
   * @ignore
   * @summary
   * Uses SP builtin dependency management to load a specific dependency.
   * @function sputils.helpers.resolveDependency
   * @param {object} dep
   * <pre>
   * {
   *   file: {string},
   *   namespace: {string}
   * }
   * - `file` is the filename of the module, e.g. sp.taxonomy.js
   * - `namespace` is the namespace provided by the SP module, e.g. SP.Taxonomy
   * </pre>
   * @returns {Promise<Void>} - resolved when the SP dependency is loaded.
   */
  var resolveDependency = function (dep) {
    var file = dep.file,
        namespace = dep.namespace;
 
    return new Promise(function (resolve, reject) {
      SP.SOD.registerSod(file, SP.Utilities.Utility.getLayoutsPageUrl(file));
      SP.SOD.executeFunc(file, namespace, resolve);
    });
  };
 
 
  /**
   * Returns a promise which resolves when
   * all the specified dependencies are loaded.
   *
   * Takes a list of strings which correspond
   * to SP JS dependencies. Each dependency is
   * registered and loaded.
   *
   * Uses SP builtin dependency management to load a specific dependency.
   *
   * @function sputils.helpers.withSharePointDependencies
   * @param {Array<dep>} deps
   * An array containing hashes with the following keys: {file, namespace}
   * <pre>
   * [ { file: string, namespace: string } ]
   * </pre>
   * @returns {Promise<Void>} - resolved when all deps are loaded.
   */
  var withSharePointDependencies = function (deps) {
    return new Promise(function (resolve, reject) {
      // sp.js is a dependency for our resolveDependency
      // function, so we load it separately before
      // the rest.
      SP.SOD.executeFunc('sp.js', 'SP.ClientContext', function () {
        var promises = deps.map(resolveDependency);
        Promise.all(promises).then(resolve);
      });
    });
  };
 
 
  /**
  * Get the relative (to the root) portion of an absolute url.
  *
  * @function sputils.helpers.abs2rel
  * @param {string} - the absolute url
  * @returns {string} - the relative url
  * @example
  * var aurl = 'http://example.com/a/path/to.html';
  * var rurl = sputils.helpers.abs2rel(aurl);
  * rurl === '/a/path/to.html';
  **/
  var abs2rel = function (absUrl) {
    var hostname = sputils.lib.getval('location.hostname');
 
    // splitting on the hostname should yield an array with 2 elements
    // the 1st element should be empty string and the second the rel path.
    // coalesce into an array with the result being a '/'
    var parts = (absUrl || '').split(hostname);
 
    return parts[1] || '/';
  };
 
  /**
   * @function sputils.helpers.parseQueryString
   * @param {Optional<string>} optArg
   * a query string, as in the form of "?k1=v1&k2=v2"
   * @returns {Object}
   * an object representing the dictionary of the query string.
   * @example
   * console.log(location.search); // => '?a=1&b=some value'
   * var qsHash = parseQueryString(); // no argument, will use the current browsing context's location.search
   * // qsHash ~=~ {a:1, b: 'some value'};
   * parseQueryString('?a=1&b=some value'); // ~=~ qsHash
   **/
  var parseQueryString = function (optArg) {
    var result = {};
    var qs = (optArg || sputils.lib.getval('location.search')).replace('?', '');
    var parts = qs.split('&');
    parts = fjs.filter(function (a) {
      return a !== '';
    }, parts);
    fjs.each(function (part) {
      var kvp = part.split('=');
      result[kvp[0]] = kvp[1];
    }, parts);
    return result;
  };
 
  /**
  * Get a promise for a client context that could be on another
  * site/web.
  *
  * This client context is augmented to contain extra info in the
  * `_info` property.
  *
  * @function sputils.helpers.clientContextForWeb
  * @param {string} absoluteUrl the absolute url of the listitem, file or other asset.
  * @returns {Promise<SP.ClientContext>} - the promise of a client context
  * @example
  * console.log(location);// => http://contoso.com/sub1
  * var fileUrl = 'http://contoso.com/sub21231/Shared Documents/file1.docx';
  * var cctxPromise = sputils.helpers.clientContext(fileUrl);
  * cctxPromise.then(function (cctx) {
  *   var webUrl = cctx._info.WebFullUrl;
  *   var web = cctx.get_web();
  *   var file = web.getFileByServerRelativeUrl(sputils.helpers.abs2rel(fileUrl));
  *   // ...
  * });
  **/
  var clientContext = function (absoluteUrl) {
    // TODO: handle URLs to sites/webs
    var url = absoluteUrl.substring(
      0, absoluteUrl.lastIndexOf('/')) ;
 
    return sputils.rest.contextInfo(url).then(function (info) {
      // create the context and set the extra prop.
      var cctx = new SP.ClientContext(info.WebFullUrl);
      cctx._info = info;
 
      return cctx;
    });
  };
  /**
  * Download a file using javascript
  * Useful to implement Export functionality in Search.
  *
  * You can download as csv or text. The function triggers the download
  * not the actual csv creation.
  *
  * Works with utf-8
  *
  * @function sputils.helpers.downloadContent
  * @param {Array<string>} options.
  * @returns {nil}
  * @example
  * var separator = ';';
  * downloadContent({
  *   type: 'text/csv;charset=utf-8',
  *   filename: 'results.csv',
  *   content: ['ASCII', separator,
  *      'Åbäcka sig', separator,
  *      'to się podoba: żźćąęłć',
  *      separator, 'Яшлӑхӑма туйаймарӑм'].join('')
  * });
  **/
  var downloadContent = function (options) {
    Eif (!options || !options.content) {
      throw new Error('You have at least to provide content to download');
    }
    options.filename = options.filename || 'download.txt';
    options.type = options.type || 'text/plain;charset=utf-8';
    options.bom = options.bom || decodeURIComponent('%ef%bb%bf');
    if (window.navigator.msSaveBlob) {
      var blob = new Blob([options.bom + options.content], {type: options.type});
      window.navigator.msSaveBlob(blob, options.filename);
    } else {
      var link = document.createElement('a');
      var content = options.bom + options.content;
      var uriScheme = ['data:', options.type, ','].join('');
      link.href = uriScheme + content;
      link.download = options.filename;
      //FF requires appending it to the DOM to make it clickable
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  };
 
  /** @namespace */
  sputils.helpers = {
    withSharePointDependencies: withSharePointDependencies,
    abs2rel: abs2rel,
    clientContext: clientContext,
    parseQueryString: parseQueryString,
    downloadContent: downloadContent
  };
})();