Squashed 'yocto-poky/' content from commit ea562de

git-subtree-dir: yocto-poky
git-subtree-split: ea562de57590c966cd5a75fda8defecd397e6436
diff --git a/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
new file mode 100644
index 0000000..c04f7ab
--- /dev/null
+++ b/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -0,0 +1,574 @@
+"use strict";
+/* All shared functionality to go in libtoaster object.
+ * This object really just helps readability since we can then have
+ * a traceable namespace.
+ */
+var libtoaster = (function (){
+
+  /* makeTypeahead parameters
+   * elementSelector: JQuery elementSelector string
+   * xhrUrl: the url to get the JSON from expects JSON in the form:
+   *  { "list": [ { "name": "test", "detail" : "a test thing"  }, .... ] }
+   * xhrParams: the data/parameters to pass to the getJSON url e.g.
+   *  { 'type' : 'projects' } the text typed will be passed as 'search'.
+   *  selectedCB: function to call once an item has been selected one
+   *  arg of the item.
+   */
+  function _makeTypeahead (jQElement, xhrUrl, xhrParams, selectedCB) {
+    if (!xhrUrl || xhrUrl.length === 0)
+      throw("No url to typeahead supplied");
+
+    var xhrReq;
+
+    jQElement.typeahead({
+        source: function(query, process){
+          xhrParams.search = query;
+
+          /* If we have a request in progress don't fire off another one*/
+          if (xhrReq)
+            xhrReq.abort();
+
+          xhrReq = $.getJSON(xhrUrl, this.options.xhrParams, function(data){
+            if (data.error !== "ok") {
+              console.log("Error getting data from server "+data.error);
+              return;
+            }
+
+            xhrReq = null;
+
+            return process(data.results);
+          });
+        },
+        updater: function(item) {
+          var itemObj = this.$menu.find('.active').data('itemObject');
+          selectedCB(itemObj);
+          return item;
+        },
+        matcher: function(item) {
+          if (!item.hasOwnProperty('name')) {
+            console.log("Name property missing in data");
+            return 0;
+          }
+
+          if (this.$element.val().length === 0)
+            return 0;
+
+          return 1;
+        },
+        highlighter: function (item) {
+          /* Use jquery to escape the item name and detail */
+          var current = $("<span></span>").text(item.name + ' '+item.detail);
+          current = current.html();
+
+          var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
+          return current.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
+            return '<strong>' + match + '</strong>'
+          })
+        },
+        sorter: function (items) { return items; },
+        xhrUrl: xhrUrl,
+        xhrParams: xhrParams,
+        xhrReq: xhrReq,
+    });
+
+
+    /* Copy of bootstrap's render func but sets selectedObject value */
+    function customRenderFunc (items) {
+      var that = this;
+
+      items = $(items).map(function (i, item) {
+        i = $(that.options.item).attr('data-value', item.name).data('itemObject', item);
+        i.find('a').html(that.highlighter(item));
+        return i[0];
+      });
+
+      items.first().addClass('active');
+      this.$menu.html(items);
+      return this;
+    }
+
+    jQElement.data('typeahead').render = customRenderFunc;
+  }
+
+  /*
+   * url - the url of the xhr build */
+  function _startABuild (url, project_id, targets, onsuccess, onfail) {
+
+    var data = {
+      project_id : project_id,
+      targets : targets,
+    }
+
+    $.ajax( {
+        type: "POST",
+        url: url,
+        data: data,
+        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+        success: function (_data) {
+          /* No proper reponse YOCTO #7995
+          if (_data.error !== "ok") {
+            console.warn(_data.error);
+          } else { */
+            if (onsuccess !== undefined) onsuccess(_data);
+        //  }
+        },
+        error: function (_data) {
+          console.warn("Call failed");
+          console.warn(_data);
+          if (onfail) onfail(data);
+    } });
+  }
+
+  /* cancelABuild:
+   * url: projectbuilds
+   * builds_ids: space separated list of build request ids
+   * onsuccess: callback for successful execution
+   * onfail: callback for failed execution
+   */
+  function _cancelABuild(url, build_ids, onsuccess, onfail){
+    $.ajax( {
+        type: "POST",
+        url: url,
+        data: { 'buildCancel': build_ids },
+        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+        success: function (_data) {
+          if (_data.error !== "ok") {
+            console.warn(_data.error);
+          } else {
+            if (onsuccess !== undefined) onsuccess(_data);
+          }
+        },
+        error: function (_data) {
+          console.warn("Call failed");
+          console.warn(_data);
+          if (onfail) onfail(_data);
+        }
+    });
+  }
+
+  /* Get a project's configuration info */
+  function _getProjectInfo(url, onsuccess, onfail){
+    $.ajax({
+        type: "GET",
+        data : { format: "json" },
+        url: url,
+        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+        success: function (_data) {
+          if (_data.error !== "ok") {
+            console.warn(_data.error);
+          } else {
+            if (onsuccess !== undefined) onsuccess(_data);
+          }
+        },
+        error: function (_data) {
+          console.warn(_data);
+          if (onfail) onfail(_data);
+        }
+    });
+  }
+
+  /* Properties for data can be:
+   * layerDel (csv)
+   * layerAdd (csv)
+   * projectName
+   * projectVersion
+   * machineName
+   */
+  function _editCurrentProject(data, onSuccess, onFail){
+    $.ajax({
+        type: "POST",
+        url: libtoaster.ctx.projectPageUrl + "?format=json",
+        data: data,
+        headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+        success: function (data) {
+          if (data.error != "ok") {
+            console.log(data.error);
+            if (onFail !== undefined)
+              onFail(data);
+          } else {
+            if (onSuccess !== undefined)
+              onSuccess(data);
+          }
+        },
+        error: function (data) {
+          console.log("Call failed");
+          console.log(data);
+        }
+    });
+  }
+
+  function _getLayerDepsForProject(url, onSuccess, onFail){
+    /* Check for dependencies not in the current project */
+    $.getJSON(url,
+      { format: 'json' },
+      function(data) {
+        if (data.error != "ok") {
+          console.log(data.error);
+          if (onFail !== undefined)
+            onFail(data);
+        } else {
+          var deps = {};
+          /* Filter out layer dep ids which are in the
+           * project already.
+           */
+          deps.list = data.layerdeps.list.filter(function(layerObj){
+            return (data.projectlayers.lastIndexOf(layerObj.id) < 0);
+          });
+
+          onSuccess(deps);
+        }
+      }, function() {
+        console.log("E: Failed to make request");
+    });
+  }
+
+  /* parses the query string of the current window.location to an object */
+  function _parseUrlParams() {
+    var string = window.location.search;
+    string = string.substr(1);
+    var stringArray = string.split ("&");
+    var obj = {};
+
+    for (var i in stringArray) {
+      var keyVal = stringArray[i].split ("=");
+      obj[keyVal[0]] = keyVal[1];
+    }
+
+    return obj;
+  }
+
+  /* takes a flat object and outputs it as a query string
+   * e.g. the output of dumpsUrlParams
+   */
+  function _dumpsUrlParams(obj) {
+    var str = "?";
+
+    for (var key in obj){
+      if (!obj[key])
+        continue;
+
+      str += key+ "="+obj[key].toString();
+      str += "&";
+    }
+
+    /* Maintain the current hash */
+    str += window.location.hash;
+
+    return str;
+  }
+
+  function _addRmLayer(layerObj, add, doneCb){
+    if (add === true) {
+      /* If adding get the deps for this layer */
+      libtoaster.getLayerDepsForProject(layerObj.layerdetailurl,
+        function (layers) {
+
+        /* got result for dependencies */
+        if (layers.list.length === 0){
+          var editData = { layerAdd : layerObj.id };
+          libtoaster.editCurrentProject(editData, function() {
+            doneCb([]);
+          });
+          return;
+        } else {
+          try {
+            showLayerDepsModal(layerObj, layers.list, null, null,  true, doneCb);
+          }  catch (e) {
+            $.getScript(libtoaster.ctx.jsUrl + "layerDepsModal.js", function(){
+              showLayerDepsModal(layerObj, layers.list, null, null,  true, doneCb);
+            }, function(){
+              console.warn("Failed to load layerDepsModal");
+            });
+          }
+        }
+      }, null);
+    } else if (add === false) {
+      var editData = { layerDel : layerObj.id };
+
+      libtoaster.editCurrentProject(editData, function () {
+        doneCb([]);
+      }, function () {
+        console.warn ("Removing layer from project failed");
+        doneCb(null);
+      });
+    }
+  }
+
+  function _makeLayerAddRmAlertMsg(layer, layerDepsList, add) {
+    var alertMsg;
+
+    if (layerDepsList.length > 0 && add === true) {
+      alertMsg = $("<span>You have added <strong>"+(layerDepsList.length+1)+"</strong> layers to your project: <a id=\"layer-affected-name\"></a> and its dependencies </span>");
+
+      /* Build the layer deps list */
+      layerDepsList.map(function(layer, i){
+        var link = $("<a></a>");
+
+        link.attr("href", layer.layerdetailurl);
+        link.text(layer.name);
+        link.tooltip({title: layer.tooltip});
+
+        if (i !== 0)
+          alertMsg.append(", ");
+
+        alertMsg.append(link);
+      });
+    } else if (layerDepsList.length === 0 && add === true) {
+      alertMsg = $("<span>You have added <strong>1</strong> layer to your project: <a id=\"layer-affected-name\"></a></span></span>");
+    } else if (add === false) {
+      alertMsg = $("<span>You have deleted <strong>1</strong> layer from your project: <a id=\"layer-affected-name\"></a></span>");
+    }
+
+    alertMsg.children("#layer-affected-name").text(layer.name);
+    alertMsg.children("#layer-affected-name").attr("href", layer.layerdetailurl);
+
+    return alertMsg.html();
+  }
+
+  function _showChangeNotification(message){
+    var alertMsg = $("#change-notification-msg");
+
+    alertMsg.html(message);
+    $("#change-notification, #change-notification *").fadeIn();
+  }
+
+
+  return {
+    reload_params : reload_params,
+    startABuild : _startABuild,
+    cancelABuild : _cancelABuild,
+    makeTypeahead : _makeTypeahead,
+    getProjectInfo: _getProjectInfo,
+    getLayerDepsForProject : _getLayerDepsForProject,
+    editCurrentProject : _editCurrentProject,
+    debug: false,
+    parseUrlParams : _parseUrlParams,
+    dumpsUrlParams : _dumpsUrlParams,
+    addRmLayer : _addRmLayer,
+    makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg,
+    showChangeNotification : _showChangeNotification,
+  };
+})();
+
+/* keep this in the global scope for compatability */
+function reload_params(params) {
+    var uri = window.location.href;
+    var splitlist = uri.split("?");
+    var url = splitlist[0];
+    var parameters = splitlist[1];
+    // deserialize the call parameters
+    var cparams = [];
+    if(parameters)
+      cparams = parameters.split("&");
+
+    var nparams = {};
+    for (var i = 0; i < cparams.length; i++) {
+        var temp = cparams[i].split("=");
+        nparams[temp[0]] = temp[1];
+    }
+    // update parameter values
+    for (i in params) {
+        nparams[encodeURIComponent(i)] = encodeURIComponent(params[i]);
+    }
+    // serialize the structure
+    var callparams = [];
+    for (i in nparams) {
+        callparams.push(i+"="+nparams[i]);
+    }
+    window.location.href = url+"?"+callparams.join('&');
+}
+
+
+/* Things that happen for all pages */
+$(document).ready(function() {
+
+  var ajaxLoadingTimer;
+
+  /* If we don't have a console object which might be the case in some
+     * browsers, no-op it to avoid undefined errors.
+     */
+    if (!window.console) {
+      window.console = {};
+      window.console.warn = function() {};
+      window.console.error = function() {};
+    }
+
+    /*
+     * PrettyPrint plugin.
+     *
+     */
+    // Init
+    prettyPrint();
+
+    // Prevent invalid links from jumping page scroll
+    $('a[href=#]').click(function() {
+        return false;
+    });
+
+
+    /* START TODO Delete this section now redundant */
+    /* Belen's additions */
+
+    // turn Edit columns dropdown into a multiselect menu
+    $('.dropdown-menu input, .dropdown-menu label').click(function(e) {
+        e.stopPropagation();
+    });
+
+    // enable popovers in any table cells that contain an anchor with the
+    // .btn class applied, and make sure popovers work on click, are mutually
+    // exclusive and they close when your click outside their area
+
+    $('html').click(function(){
+        $('td > a.btn').popover('hide');
+    });
+
+    $('td > a.btn').popover({
+        html:true,
+        placement:'left',
+        container:'body',
+        trigger:'manual'
+    }).click(function(e){
+        $('td > a.btn').not(this).popover('hide');
+        // ideally we would use 'toggle' here
+        // but it seems buggy in our Bootstrap version
+        $(this).popover('show');
+        e.stopPropagation();
+    });
+
+    // enable tooltips for applied filters
+    $('th a.btn-primary').tooltip({container:'body', html:true, placement:'bottom', delay:{hide:1500}});
+
+    // hide applied filter tooltip when you click on the filter button
+    $('th a.btn-primary').click(function () {
+        $('.tooltip').hide();
+    });
+
+    // enable help information tooltip
+    $(".get-help").tooltip({container:'body', html:true, delay:{show:300}});
+
+    // show help bubble only on hover inside tables
+    $(".hover-help").css("visibility","hidden");
+    $("th, td").hover(function () {
+        $(this).find(".hover-help").css("visibility","visible");
+    });
+    $("th, td").mouseleave(function () {
+        $(this).find(".hover-help").css("visibility","hidden");
+    });
+
+    /* END TODO Delete this section now redundant */
+
+    // show task type and outcome in task details pages
+    $(".task-info").tooltip({ container: 'body', html: true, delay: {show: 200}, placement: 'right' });
+
+    // initialise the tooltips for the icon-pencil icons
+    $(".icon-pencil").tooltip({ container: 'body', html: true, delay: {show: 400}, title: "Change" });
+
+    // initialise the tooltips for the download icons
+    $(".icon-download-alt").tooltip({ container: 'body', html: true, delay: { show: 200 } });
+
+    // initialise popover for debug information
+    $(".icon-info-sign").popover( { placement: 'bottom', html: true, container: 'body' });
+
+    // linking directly to tabs
+    $(function(){
+          var hash = window.location.hash;
+          $('ul.nav a[href="' + hash + '"]').tab('show');
+
+          $('.nav-tabs a').click(function () {
+            $(this).tab('show');
+            $('body').scrollTop();
+          });
+    });
+
+    // toggle for long content (variables, python stack trace, etc)
+    $('.full, .full-hide').hide();
+    $('.full-show').click(function(){
+        $('.full').slideDown(function(){
+            $('.full-hide').show();
+        });
+        $(this).hide();
+    });
+    $('.full-hide').click(function(){
+        $(this).hide();
+        $('.full').slideUp(function(){
+            $('.full-show').show();
+        });
+    });
+
+    //toggle the errors and warnings sections
+    $('.show-errors').click(function() {
+        $('#collapse-errors').addClass('in');
+    });
+    $('.toggle-errors').click(function() {
+        $('#collapse-errors').toggleClass('in');
+    });
+    $('.show-warnings').click(function() {
+        $('#collapse-warnings').addClass('in');
+    });
+    $('.toggle-warnings').click(function() {
+        $('#collapse-warnings').toggleClass('in');
+    });
+    $('.show-exceptions').click(function() {
+        $('#collapse-exceptions').addClass('in');
+    });
+    $('.toggle-exceptions').click(function() {
+        $('#collapse-exceptions').toggleClass('in');
+    });
+
+
+    $("#hide-alert").click(function(){
+      $(this).parent().fadeOut();
+    });
+
+    //show warnings section when requested from the previous page
+    if (location.href.search('#warnings') > -1) {
+        $('#collapse-warnings').addClass('in');
+    }
+
+    /* Show the loading notification if nothing has happend after 1.5
+     * seconds
+     */
+    $(document).bind("ajaxStart", function(){
+      if (ajaxLoadingTimer)
+        window.clearTimeout(ajaxLoadingTimer);
+
+      ajaxLoadingTimer = window.setTimeout(function() {
+        $("#loading-notification").fadeIn();
+      }, 1200);
+    });
+
+    $(document).bind("ajaxStop", function(){
+      if (ajaxLoadingTimer)
+        window.clearTimeout(ajaxLoadingTimer);
+
+      $("#loading-notification").fadeOut();
+    });
+
+    $(document).ajaxError(function(event, jqxhr, settings, errMsg){
+      if (errMsg === 'abort')
+        return;
+
+      console.warn("Problem with xhr call");
+      console.warn(errMsg);
+      console.warn(jqxhr.responseText);
+    });
+
+    function check_for_duplicate_ids () {
+      /* warn about duplicate element ids */
+      var ids = {};
+      $("[id]").each(function() {
+        if (this.id && ids[this.id]) {
+          console.warn('Duplicate element id #'+this.id);
+        }
+        ids[this.id] = true;
+      });
+    }
+
+    if (libtoaster.debug) {
+      check_for_duplicate_ids();
+    } else {
+      /* Debug is false so supress warnings by overriding the functions */
+      window.console.warn = function () {};
+      window.console.error = function () {};
+   }
+});