aboutsummaryrefslogblamecommitdiffstats
path: root/data/lib/util.js
blob: f30ddd50c528bab6ff2740f021c6b7adfd450e81 (plain) (tree)
1
2
3
4
5
6
7
8
9

                           



                                                                 
 
   
                              
  

                                                            
  


                                                                            
  


                                                                              
   
                        









                                         

                                                  












                                                                
 
 
   

                                                                               
  

                                           

                     
                                       

                                                                   
                                                
                                                                                             
           
                          
 

   


                     
                                                                        




                           


   
                                               
  

                                          
                                 
   
                               



                                    
 
 
   
                                            
  

                                                   









                                                                            

                                                                              
  












                                                                            


                                                                                          

                              
 







                                                
 





                                                  
 











                                                                   
 

                                  
                                               
                                                                   

                               
                                                                               
   


                                                                               



                                                                   

 
  

                                                                
                                                                                    
  

                                                                               
  

                                








                                                                                          
     


                       

 
   
                                                  
  


                                         
                              




                                                                    
                      
 

   






















                                                              

                                                                            
  



                                             

                                                                   
                              



                                    


   
                                    
  

                      
  

                                                                              
   
                          
                    

                                   
                             
 


                                                                     
  



                                          
                                   
   
                                  











                                                                    
 


                                                                       
  



                                                        

                                                         
                                     






                                                                        
 



                                                                               
  



                                                                 

                                
                                            
                      
                                







                                                            
                
   
 
 

                                                   
  








                                                                               
   
                                         










                                                                            
 


                                       
  

                                              



                                        



                                              



             


                                               

                                                                          

                             

                   


                   
                                                   


                                                                    

                                     


                                                       
                                                
  

                                         



                                      

   
/* global console: false */
/* jslint onevar: false */
// Released under the MIT/X11 license
// http://www.opensource.org/licenses/mit-license.php
"use strict";
// ==============================================================

/**
 * parse URL to get its parts.
 *
 * @param url
 * @return object with all parsed parts of URL as properties
 *
 * Originally from
 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/ Copyright
 * February 19th, 2009, James Padolsey, <license undeclared>
 *
 * This function creates a new anchor element and uses location properties
 * (inherent) to get the desired URL data. Some String operations are used (to
 * normalize results across browsers).
 */
function parseURL(url) {
  var a =  document.createElement('a');
  a.href = url;
  return {
    source: url,
    protocol: a.protocol.replace(':',''),
    host: a.hostname,
    port: a.port,
    query: a.search,
    params: (function(){
      var ret = {},
      seg = a.search.replace(/^\?/,'').split('&'),
      len = seg.length, i = 0, s;
      for (;i<len;i++) {
        if (!seg[i]) { continue; }
        s = seg[i].split('=');
        ret[s[0]] = s[1];
      }
      return ret;
    })(),
    file: (a.pathname.match(/\/([^\/?#]+)$/i) || [,''])[1],
    hash: a.hash.replace('#',''),
    path: a.pathname.replace(/^([^\/])/,'/$1'),
    relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [,''])[1],
    segments: a.pathname.replace(/^\//,'').split('/')
  };
}

/**
 * parse XML object out of string working around various bugs in Gecko
 * implementation see https://developer.mozilla.org/en/E4X for more information
 *
 * @param inStr
 *          String with unparsed XML string
 * @return XML object
 */
function parseXMLfromString (inStuff) {
  // if (typeof inStuff !== 'string') In future we should recognize
  // this.response
  // and get just .text property out of it. TODO
  var respStr = inStuff.replace(/^<\?xml\s+version\s*=\s*(["'])[^\1]+\1[^?]*\?>/, ""); // bug
  // 336551
  return new XML(respStr);
}

/**
 * Get a bug no
 */
function getBugNo() {
  var bugNoElem = document.forms.namedItem("changeform").elements["id"];
  if (bugNoElem) {
    return bugNoElem.value;
  } else {
    return null;
  }
}

/**
 * Get a bug no from URL ... fails with aliases
 *
 * @param url
 *          String with URL to be analyzed
 * @return String with the bug ID
 */
function getBugNoFromURL(url) {
  var params = parseURL(url).params;
  if (params && params.id) {
    return params.id;
  }
}

/**
 * Send mouse click to the specified element
 *
 * @param String
 *          ID of the element to send mouseclick to
 * @return None
 */
function clickMouse (targetID) {
  var localEvent = document.createEvent("MouseEvents");
  localEvent.initMouseEvent("click", true, true, document.defaultView, 0, 0,
      0, 0, 0, false, false, false, false, 0, null);
  document.getElementById(targetID).dispatchEvent(localEvent);
}

/**
 * Create a A element leadink nowhere, but with listener running a callback on
 * the click
 *
 * @param id
 *          String with a id to be added to the element
 * @param text
 *          String with a string to be added as a textContent of the element
 * @param parent
 *          Node which is a parent of the object
 * @param callback
 *          Function to be called after clicking on the link
 * @param params
 *          Array with parameters of the callback
 * @param Boolean
 *          before if there should be a <br>
 *          element before.
 * @return none
 */
function createDeadLink (id, text, parent, callback, params, before, covered, accesskey) {
  params = valToArray(params);
  var locParent = {};

  // Yes, I want != here, not !==
  if (covered != null) {
    locParent = document.createElement(covered);
    parent.appendChild(locParent);
  }
  else {
    locParent = parent;
  }

  var newAElem = document.createElement("a");
  newAElem.setAttribute("id", id);
  if (accesskey) {
    newAElem.setAttribute("accesskey", accesskey);
  }
  newAElem.textContent = text;

  if (typeof callback === "string") {
    newAElem.setAttribute("href", callback);
  }
  else {
    newAElem.setAttribute("href", "");
    newAElem.addEventListener("click", function(evt) {
      evt.stopPropagation();
      evt.preventDefault();
      // We need apply, because params could be array of parameters
      callback.apply(null, params);
    }, false);
  }

  locParent.appendChild(newAElem);

  if ((before === "br") || (before === true)) {
    locParent.insertBefore(document.createElement("br"), newAElem);
  }
  else if (before === "dash") {
    locParent.insertBefore(document.createTextNode("\u00A0-\u00A0"), newAElem);
  }
  else if (before === "pipe") {
    locParent.insertBefore(document.createTextNode("\u00A0|\u00A0"), newAElem);
  }
  else if (before === "parens") {
    locParent.appendChild(document.createTextNode(")"));
    locParent.insertBefore(document.createTextNode("("), newAElem);
  }
}

/*
 * From <a> element diggs out just plain email address Note that
 * bugzilla.gnome.org doesn't have mailto: url but
 * https://bugzilla.gnome.org/page.cgi?id=describeuser.html&login=mcepl%40redhat.com
 *
 * @param aElement Element with href attribute or something else @return String
 * with the address or null
 *
 */
function parseMailto(aElement) {
  var emailStr = "", hrefStr = "";
  // use url utils
  if (aElement) {
    hrefStr = decodeURIComponent(aElement.getAttribute("href"));
    emailStr = hrefStr.split(":");
    // workaround for Gnome bugzilla ... no mailto: here.
    if (emailStr.length < 2) {
      var params = parseURL("https://" + window.location.hostname + "/" + hrefStr).params;
      return decodeURI(params.login);
    }
    return emailStr[1];
  }
  return null;
}

/**
 * format date to be in ISO format (just day part)
 *
 * @param date
 * @return string with the formatted date
 */
function getISODate(dateStr) {
  function pad(n) {
    return n < 10 ? '0' + n : n;
  }
  var date = new Date(dateStr);
  return date.getFullYear() + '-' + pad(date.getMonth() + 1) + '-' +
  pad(date.getDate());
}

/**
 * format Date object as ISO-8601 formatted date string
 *
 * @param d Date
 * @return String with date formatted
 * @url https://developer.mozilla.org/en/JavaScript/Reference\
   /Global_Objects/Date#Example.3a_ISO_8601_formatted_dates
 * outputs something like 2009-09-28T19:03:12Z
 */
function ISODateString(d) {
  function pad(n) {
    return n<10 ? '0'+n : n
  }

  return d.getUTCFullYear()+'-'
    + pad(d.getUTCMonth()+1)+'-'
    + pad(d.getUTCDate())+'T'
    + pad(d.getUTCHours())+':'
    + pad(d.getUTCMinutes())+':'
    + pad(d.getUTCSeconds())+'Z';
}


/**
 * Check whether an item is member of the list. Idea is just to make long if
 * commands slightly more readable.
 *
 * @param mbr
 *          string to be searched in the list
 * @param list
 *          list
 * @return position of the string in the list, or -1 if none found.
 */
function isInList(mbr, list) {
  if (!list) {
    return false;
  }
  return (list.indexOf(mbr) !== -1);
};

/**
 * Make sure value returned is Array
 *
 * @param Array/String
 * @return Array
 *
 * If something else than Array or String is passed to the function the result
 * will be untouched actual argument of the call.
 */
function valToArray(val) {
  var isArr = val &&
  val.constructor &&
  val.constructor.name === "Array";
  return isArr ? val : [val];
}

/**
 * Merges two comma separated string as a list and returns new string
 *
 * @param str
 *          String with old values
 * @param value
 *          String/Array with other values
 * @return String with merged lists
 */
function addCSVValue(str, value) {
  var parts = (str.trim().length > 0 ? str.split(/[,\s]+/) : []);
  if (!value) {
    return str;
  }
  if (!isInList(value, parts)) {
    var newValue = valToArray(value);
    parts = parts.concat(newValue);
  }
  // this is necessary to get comma-space separated string even when
  // value is an array already
  parts = parts.join(",").split(",");
  return parts.join(", ");
}

/**
 * Treats comma separated string as a list and removes one item from it
 *
 * @param str
 *          String treated as a list
 * @param value
 *          String with the value to be removed from str
 * @return String with the resulting list comma separated
 */
function removeCSVValue(str, value) {
  str = str.trim();
  var parts = str ? str.split(/[,\s]+/) : [];
  var valueArr = value instanceof Array ? value : value.split(/[,\s]+/);
  parts = parts.filter(function (e, i, a) {
    return (!isInList(e, valueArr));
  });
  return parts.join(", ");
}

/**
 * select element of the array where regexp in the first element matches second
 * parameter of this function
 *
 * @param list
 *          Array with regexps and return values
 * @param chosingMark
 *          String by which the element of array is to be matched
 * @return Object chosen element
 */
function filterByRegexp(list, chosingMark) {
  var chosenPair = [];
  if (list && list.length > 0) {
    chosenPair = list.filter(function (pair) {
      return new RegExp(pair.regexp, "i").test(chosingMark);
    });
  }
  if (chosenPair.length > 0) {
    return chosenPair[0].addr;
  }
  else {
    return null;
  }
}

/**
 * remove elements from the page based on their IDs
 *
 * @param doc
 *          Document object
 * @param target
 *          String/Array with ID(s)
 * @param remove
 *          Boolean indicating whether the node should be actually removed or
 *          just hidden.
 * @return none TODO remove parameter could be replaced by function which would
 *         do actual activity.
 */
function killNodes(doc, target, remove) {
  target = target.trim();
  var targetArr = target instanceof Array ? target : target.split(/[,\s]+/);
  targetArr.forEach(function(x) {
    if (remove) {
      var targetNode = doc.getElementById(x);
      targetNode.parentNode.removeChild(targetNode);
    }
    else {
      x.style.display = "none";
    }
  });
}

/**
 * Remove duplicate elements from array
 *
 * @param arr
 *          Array which needs to be cleaned up
 * @return cleaned up array
 */
function removeDuplicates (arr) {
  for (var i = 0; i < arr.length; i++) {
    for (var j = i + 1; j < arr.length; j++) {
      if (arr[i] == arr[j]) {
        arr.splice (j, 1);
      }
    }
  }
  return arr;
}

// ============================================
/**
 * object to pack messaging. Use as in self.postMessage(new
 * Message("GetPassword", { login: login, hostname: location.hostname }));
 */
function Message(cmd, data) {
  this.cmd = cmd;
  this.data = data;
}

function log(msg) {
  self.postMessage(new Message("LogMessage", msg));
}

var NotLoggedinException = function NotLoggedinException (message) {
  this.message = message;
  this.name = "NotLoggedinException";
};

NotLoggedinException.prototype.toString = function () {
  return this.name + ': "' + this.message + '"';
};

console.myDebug = function myDebug(str) {
  if (typeof config !== "undefined") {
    if (config.debuggingVerbose) {
      console.log(str);
    }
  }
};