summaryrefslogtreecommitdiffstats
path: root/poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
diff options
context:
space:
mode:
Diffstat (limited to 'poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js')
-rw-r--r--poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js735
1 files changed, 735 insertions, 0 deletions
diff --git a/poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js b/poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
new file mode 100644
index 000000000..6f9b5d0f0
--- /dev/null
+++ b/poky/bitbake/lib/toaster/toastergui/static/js/libtoaster.js
@@ -0,0 +1,735 @@
+"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 () {
+ // prevent conflicts with Bootstrap 2's typeahead (required during
+ // transition from v2 to v3)
+ var typeahead = jQuery.fn.typeahead.noConflict();
+ jQuery.fn._typeahead = typeahead;
+
+ /* Make a typeahead from an input element
+ *
+ * _makeTypeahead parameters
+ * jQElement: input element as selected by $('selector')
+ * xhrUrl: the url to get the JSON from; this URL should return JSON in the
+ * format:
+ * { "results": [ { "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; has
+ * signature selectedCB(item), where item is an item in the format shown
+ * in the JSON list above, i.e.
+ * { "name": "name", "detail": "detail" }.
+ */
+ function _makeTypeahead(jQElement, xhrUrl, xhrParams, selectedCB) {
+ if (!xhrUrl || xhrUrl.length === 0) {
+ throw("No url supplied for typeahead");
+ }
+
+ var xhrReq;
+
+ jQElement._typeahead(
+ {
+ highlight: true,
+ classNames: {
+ open: "dropdown-menu",
+ cursor: "active"
+ }
+ },
+ {
+ source: function (query, syncResults, asyncResults) {
+ xhrParams.search = query;
+
+ // if we have a request in progress, cancel it and start another
+ if (xhrReq) {
+ xhrReq.abort();
+ }
+
+ xhrReq = $.getJSON(xhrUrl, xhrParams, function (data) {
+ if (data.error !== "ok") {
+ console.error("Error getting data from server: " + data.error);
+ return;
+ }
+
+ xhrReq = null;
+
+ asyncResults(data.results);
+ });
+ },
+
+ // how the selected item is shown in the input
+ display: function (item) {
+ return item.name;
+ },
+
+ templates: {
+ // how the item is displayed in the dropdown
+ suggestion: function (item) {
+ var elt = document.createElement("div");
+ elt.innerHTML = item.name + " " + item.detail;
+ return elt;
+ }
+ }
+ }
+ );
+
+ // when an item is selected using the typeahead, invoke the callback
+ jQElement.on("typeahead:select", function (event, item) {
+ selectedCB(item);
+ });
+ }
+
+ /* startABuild:
+ * url: xhr_buildrequest or null for current project
+ * targets: an array or space separated list of targets to build
+ * onsuccess: callback for successful execution
+ * onfail: callback for failed execution
+ */
+ function _startABuild (url, targets, onsuccess, onfail) {
+
+ if (!url)
+ url = libtoaster.ctx.xhrBuildRequestUrl;
+
+ /* Flatten the array of targets into a space spearated list */
+ if (targets instanceof Array){
+ targets = targets.reduce(function(prevV, nextV){
+ return prev + ' ' + next;
+ });
+ }
+
+ $.ajax( {
+ type: "POST",
+ url: url,
+ data: { 'targets' : targets },
+ 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);
+ } });
+ }
+
+ /* cancelABuild:
+ * url: xhr_buildrequest url or null for current project
+ * buildRequestIds: space separated list of build request ids
+ * onsuccess: callback for successful execution
+ * onfail: callback for failed execution
+ */
+ function _cancelABuild(url, buildRequestIds, onsuccess, onfail){
+ if (!url)
+ url = libtoaster.ctx.xhrBuildRequestUrl;
+
+ $.ajax( {
+ type: "POST",
+ url: url,
+ data: { 'buildCancel': buildRequestIds },
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (_data) {
+ if (_data.error !== "ok") {
+ console.warn(_data.error);
+ } else {
+ if (onsuccess) onsuccess(_data);
+ }
+ },
+ error: function (_data) {
+ console.warn("Call failed");
+ console.warn(_data);
+ if (onfail) onfail(_data);
+ }
+ });
+ }
+
+ function _getMostRecentBuilds(url, onsuccess, onfail) {
+ $.ajax({
+ url: url,
+ type: 'GET',
+ data : {format: 'json'},
+ headers: {'X-CSRFToken': $.cookie('csrftoken')},
+ success: function (data) {
+ onsuccess ? onsuccess(data) : console.log(data);
+ },
+ error: function (data) {
+ onfail ? onfail(data) : console.error(data);
+ }
+ });
+ }
+
+ /* Get a project's configuration info */
+ function _getProjectInfo(url, onsuccess, onfail){
+ $.ajax({
+ type: "GET",
+ 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.xhrProjectUrl,
+ 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 (layerObj.xhrLayerUrl === undefined){
+ throw("xhrLayerUrl is undefined")
+ }
+
+ if (add === true) {
+ /* If adding get the deps for this layer */
+ libtoaster.getLayerDepsForProject(layerObj.xhrLayerUrl,
+ 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 class=\"alert-link\" id=\"layer-affected-name\"></a> and its dependencies </span>");
+
+ /* Build the layer deps list */
+ layerDepsList.map(function(layer, i){
+ var link = $("<a class=\"alert-link\"></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 class=\"alert-link\" id=\"layer-affected-name\"></a></span></span>");
+ } else if (add === false) {
+ alertMsg = $("<span>You have removed <strong>1</strong> layer from your project: <a class=\"alert-link\" 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){
+ $(".alert-dismissible").fadeOut().promise().done(function(){
+ var alertMsg = $("#change-notification-msg");
+
+ alertMsg.html(message);
+ $("#change-notification, #change-notification *").fadeIn();
+ });
+ }
+
+ function _createCustomRecipe(name, baseRecipeId, doneCb){
+ var data = {
+ 'name' : name,
+ 'project' : libtoaster.ctx.projectId,
+ 'base' : baseRecipeId,
+ };
+
+ $.ajax({
+ type: "POST",
+ url: libtoaster.ctx.xhrCustomRecipeUrl,
+ data: data,
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function (ret) {
+ if (doneCb){
+ doneCb(ret);
+ } else if (ret.error !== "ok") {
+ console.warn(ret.error);
+ }
+ },
+ error: function (ret) {
+ console.warn("Call failed");
+ console.warn(ret);
+ }
+ });
+ }
+
+ /* Validate project names. Use unique project names
+
+ All arguments accepted by this function are JQeury objects.
+
+ For example if the HTML element has "hint-error-project-name", then
+ it is passed to this function as $("#hint-error-project-name").
+
+ Arg1 - projectName : This is a string object. In the HTML, project name will be entered here.
+ Arg2 - hintEerror : This is a jquery object which will accept span which throws error for
+ duplicate project
+ Arg3 - ctrlGrpValidateProjectName : This object holds the div with class "control-group"
+ Arg4 - enableOrDisableBtn : This object will help the API to enable or disable the form.
+ For example in the new project the create project button will be hidden if the
+ duplicate project exist. Similarly in the projecttopbar the save button will be
+ disabled if the project name already exist.
+
+ Return - This function doesn't return anything. It sets/unsets the behavior of the elements.
+ */
+
+ function _makeProjectNameValidation(projectName, hintError,
+ ctrlGrpValidateProjectName, enableOrDisableBtn ) {
+
+ function checkProjectName(projectName){
+ $.ajax({
+ type: "GET",
+ url: libtoaster.ctx.projectsTypeAheadUrl,
+ data: { 'search' : projectName },
+ headers: { 'X-CSRFToken' : $.cookie('csrftoken')},
+ success: function(data){
+ if (data.results.length > 0 &&
+ data.results[0].name === projectName) {
+ // This project name exists hence show the error and disable
+ // the save button
+ ctrlGrpValidateProjectName.addClass('has-error');
+ hintError.show();
+ enableOrDisableBtn.attr('disabled', 'disabled');
+ } else {
+ ctrlGrpValidateProjectName.removeClass('has-error');
+ hintError.hide();
+ enableOrDisableBtn.removeAttr('disabled');
+ }
+ },
+ error: function (data) {
+ console.log(data);
+ },
+ });
+ }
+
+ /* The moment user types project name remove the error */
+ projectName.on("input", function() {
+ var projectName = $(this).val();
+ checkProjectName(projectName)
+ });
+
+ /* Validate new project name */
+ projectName.on("blur", function(){
+ var projectName = $(this).val();
+ checkProjectName(projectName)
+ });
+ }
+
+ // if true, the loading spinner for Ajax requests will be displayed
+ // if requests take more than 1200ms
+ var ajaxLoadingTimerEnabled = true;
+
+ // turn on the page-level loading spinner for Ajax requests
+ function _enableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = true;
+ }
+
+ // turn off the page-level loading spinner for Ajax requests
+ function _disableAjaxLoadingTimer() {
+ ajaxLoadingTimerEnabled = false;
+ }
+
+ /* Utility function to set a notification for the next page load */
+ function _setNotification(name, message){
+ var data = {
+ name: name,
+ message: message
+ };
+
+ $.cookie('toaster-notification', JSON.stringify(data), { path: '/'});
+ }
+
+ return {
+ enableAjaxLoadingTimer: _enableAjaxLoadingTimer,
+ disableAjaxLoadingTimer: _disableAjaxLoadingTimer,
+ reload_params : reload_params,
+ startABuild : _startABuild,
+ cancelABuild : _cancelABuild,
+ getMostRecentBuilds: _getMostRecentBuilds,
+ makeTypeahead : _makeTypeahead,
+ getProjectInfo: _getProjectInfo,
+ getLayerDepsForProject : _getLayerDepsForProject,
+ editCurrentProject : _editCurrentProject,
+ debug: false,
+ parseUrlParams : _parseUrlParams,
+ dumpsUrlParams : _dumpsUrlParams,
+ addRmLayer : _addRmLayer,
+ makeLayerAddRmAlertMsg : _makeLayerAddRmAlertMsg,
+ showChangeNotification : _showChangeNotification,
+ createCustomRecipe: _createCustomRecipe,
+ makeProjectNameValidation: _makeProjectNameValidation,
+ setNotification: _setNotification,
+ };
+})();
+
+/* 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() {
+
+ (function showNotificationRequest(){
+ var cookie = $.cookie('toaster-notification');
+
+ if (!cookie)
+ return;
+
+ var notificationData = JSON.parse(cookie);
+
+ libtoaster.showChangeNotification(notificationData.message);
+
+ $.removeCookie('toaster-notification', { path: "/"});
+ })();
+
+
+
+ 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() {};
+ }
+
+ /*
+ * highlight plugin.
+ */
+ hljs.initHighlightingOnLoad();
+
+ // 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();
+ });
+
+ /* Initialise bootstrap tooltips */
+ $(".get-help, [data-toggle=tooltip]").tooltip({
+ container : 'body',
+ html : true,
+ delay: { show : 300 }
+ });
+
+ // show help bubble on hover inside tables
+ $("table").on("mouseover", "th, td", function () {
+ $(this).find(".hover-help").css("visibility","visible");
+ });
+
+ $("table").on("mouseleave", "th, td", 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 edit icons
+ $(".glyphicon-edit").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
+ $(".glyphicon-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() {
+ if (libtoaster.ajaxLoadingTimerEnabled) {
+ $("#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;
+ });
+ }
+
+ /* Make sure we don't have a notification overlay a modal */
+ $(".modal").on('show.bs.modal', function(){
+ $(".alert-dismissible").fadeOut();
+ });
+
+ 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 () {};
+ }
+});
OpenPOWER on IntegriCloud