Jannis Moßhammer 35c43446d8 Add support for lazy module loading
When the X-Icinga-Module-Enable header is send, the
modulemanager automatically tries to load javascript files for
that module. This is realized by adding the 'registerHeaderListener'
method to the async manager, which allows to listen to specific headers
and firing callbacks if a response with the specified header is retrieved.

Also the tests have changed a bit, requireNow should be used when using
the requiremock, so a require always loads files new.

refs #4092
refs #3753
2013-06-21 15:33:06 +02:00

134 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*global Icinga:false define:false require:false base_url:false console:false */
(function() {
"use strict";
var asyncMgrInstance = null;
define(['icinga/container','logging','jquery'],function(containerMgr,log,$) {
var headerListeners = {};
var pending = {
};
var getDOMForDestination = function(destination) {
var target = destination;
if (typeof destination === "string") {
target = containerMgr.getContainer(destination)[0];
} else if(typeof destination.context !== "undefined") {
target = destination[0];
}
return target;
};
var applyHeaderListeners = function(headers) {
for (var header in headerListeners) {
if (headers.getResponseHeader(header) === null) {
// see if the browser/server converts headers to lowercase
if (headers.getResponseHeader(header.toLowerCase()) === null) {
continue;
}
header = header.toLowerCase();
}
var value = headers.getResponseHeader(header);
var listeners = headerListeners[header];
for (var i=0;i<listeners.length;i++) {
listeners[i].fn.apply(listeners[i].scope, [value, header, headers]);
}
}
};
var handleResponse = function(html, status, response) {
applyHeaderListeners(response);
if(this.destination) {
containerMgr.updateContainer(this.destination,html,this);
} else {
// tbd
// containerMgr.createPopupContainer(html,this);
}
};
var handleFailure = function(result,error) {
if(error === "abort") {
return;
}
log.error("Error loading resource",error,arguments);
if(this.destination) {
containerMgr.updateContainer(this.destination,result.responseText,this);
}
};
var isParent = function(dom,parentToCheck) {
while(dom.parentNode) {
dom = dom.parentNode;
if(dom === parentToCheck) {
return true;
}
}
return false;
};
var CallInterface = function() {
this.__internalXHRImplementation = $.ajax;
this.clearPendingRequestsFor = function(destination) {
if(!$.isArray(pending)) {
pending = [];
return;
}
var resultset = [];
for(var x=0;x<pending.length;x++) {
var container = pending[x].DOM;
if(isParent(container,getDOMForDestination(destination))) {
pending[x].request.abort();
} else {
resultset.push(pending[x]);
}
}
pending = resultset;
};
this.createRequest = function(url,data) {
var req = this.__internalXHRImplementation({
type : data ? 'POST' : 'GET',
url : url,
data : data,
headers: { 'X-Icinga-Accept': 'text/html' }
});
req.url = url;
req.done(handleResponse.bind(req));
req.fail(handleFailure.bind(req));
return req;
};
this.loadToTarget = function(destination,url,data) {
if(destination) {
log.debug("Laoding to container", destination, url);
this.clearPendingRequestsFor(destination);
}
var req = this.createRequest(url,data);
if(destination) {
pending.push({
request: req,
DOM: getDOMForDestination(destination)
});
req.destination = destination;
}
return req;
};
this.loadCSS = function(name) {
};
this.registerHeaderListener = function(header, fn, scope) {
headerListeners[header] = headerListeners[header] || [];
headerListeners[header].push({fn: fn, scope:scope});
};
};
return new CallInterface();
});
})();