Add javascript autoloading

the js/modules/%modulename%/%file% is now mapped to the module
path (if existing). To prevent name clashing, the modules folder
has been renamed to components.
This commit is contained in:
Jannis Moßhammer 2013-06-21 11:36:12 +02:00 committed by Marius Hein
parent 3a5a4bf273
commit d94d89e1cf
6 changed files with 239 additions and 12 deletions

View File

@ -9,6 +9,7 @@ use Icinga\Web\ActionController;
use Icinga\Application\Icinga;
use Zend_Controller_Action_Exception as ActionException;
use Icinga\Application\Benchmark;
/**
* Class StaticController
* @package Icinga\Web\Form
@ -69,7 +70,7 @@ class StaticController extends ActionController
*/
public function javascriptAction()
{
$module = $this->_getParam('moduleName');
$module = $this->_getParam('module_name');
$file = $this->_getParam('file');
$basedir = Icinga::app()->getModule($module)->getBaseDir();
@ -96,15 +97,16 @@ class StaticController extends ActionController
) . ' GMT'
);
$hash = md5_file($filePath);
if ($hash === $this->getRequest()->getHeader('If-None-Match')) {
$response->setHttpResponseCode(304);
return;
} else {
readfile($filePath);
}
// TODO: get rid of exit:
exit;
return;
}
}
// @codingStandardsIgnoreEnd
// @codingStandardsIgnoreEnd

View File

@ -59,6 +59,17 @@ class Web extends ApplicationBootstrap
)
)
);
$this->frontController->getRouter()->addRoute(
'module_javascript',
new Route(
'js/modules/:module_name/:file',
array(
'controller' => 'static',
'action' => 'javascript'
)
)
);
return $this;
}
@ -162,6 +173,7 @@ class Web extends ApplicationBootstrap
*/
protected function configurePagination()
{
Paginator::addScrollingStylePrefixPath(
'Icinga_Web_Paginator_ScrollingStyle',
'Icinga/Web/Paginator/ScrollingStyle'

View File

@ -0,0 +1,118 @@
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
/**
* ActionTable behaviour as described in
* https://wiki.icinga.org/display/cranberry/Frontend+Components#FrontendComponents-ActionTable
*
* @TODO: Row selection
*/
define(['jquery','logging','icinga/util/async'],function($,log,async) {
"use strict";
var ActionTableBehaviour = function() {
var onTableHeaderClick;
var TABLE_BASE_MATCHER = '.icinga-container table.action';
var linksInActionTable = TABLE_BASE_MATCHER+" tbody tr > a";
var actionTableRow = TABLE_BASE_MATCHER+" tbody tr";
var headerRow = TABLE_BASE_MATCHER+" > th a";
var searchField = ".icinga-container .actiontable.controls input[type=search]";
onTableHeaderClick = function (ev) {
var target = ev.currentTarget,
href = $(target).attr('href'),
destination;
if ($(target).parents('.layout-main-detail').length) {
if ($(target).parents("#icinga-main").length) {
destination = 'icinga-main';
}
else {
destination = 'icinga-detail';
}
} else {
destination = 'icinga-main';
}
async.loadToTarget(destination, href);
ev.preventDefault();
ev.stopImmediatePropagation();
return false;
};
var onLinkTagClick = function(ev) {
var target = ev.currentTarget,
href = $(target).attr('href'),
destination;
if ($(target).parents('.layout-main-detail').length) {
destination = 'icinga-detail';
} else {
destination = 'icinga-main';
}
async.loadToTarget(destination,href);
ev.preventDefault();
ev.stopImmediatePropagation();
return false;
};
var onTableRowClick = function(ev) {
ev.stopImmediatePropagation();
var target = $(ev.currentTarget),
href = target.attr('href'),
destination;
$('tr.active',target.parent('tbody').first()).removeClass("active");
target.addClass('active');
// When the tr has a href, act like it is a link
if(href) {
ev.currentTarget = target.first();
return onLinkTagClick(ev);
}
// Try to find a designated row action
var links = $("a.row-action",target);
if(links.length) {
ev.currentTarget = links.first();
return onLinkTagClick(ev);
}
// otherwise use the first anchor tag
links = $("a",target);
if(links.length) {
ev.currentTarget = links.first();
return onLinkTagClick(ev);
}
log.debug("No target for this table row found");
return false;
};
var onSearchInput = function(ev) {
ev.stopImmediatePropagation();
var txt = $(this).val();
};
this.eventHandler = {};
this.eventHandler[linksInActionTable] = {
'click' : onLinkTagClick
};
this.eventHandler[actionTableRow] = {
'click' : onTableRowClick
};
this.eventHandler[headerRow] = {
'click' : onTableHeaderClick
};
this.eventHandler[searchField] = {
'keyup' : onSearchInput
};
this.enable = function() {
};
};
return new ActionTableBehaviour();
});

View File

@ -0,0 +1,99 @@
/*global Icinga:false, document: false, define:false require:false base_url:false console:false */
/**
* Main-Detail layout behaviour as described in
* https://wiki.icinga.org/display/cranberry/Frontend+Components#FrontendComponents-Behaviour
*
*/
define(['jquery','logging','icinga/util/async'],function($,log,async) {
"use strict";
var MainDetailBehaviour = function() {
var onOuterLinkClick = function(ev) {
var a = $(ev.currentTarget),
target = a.attr("target"),
href = a.attr("href");
ev.stopImmediatePropagation();
collapseDetailView();
async.loadToTarget("icinga-main",href);
return false;
};
var onLinkTagClick = function(ev) {
var a = $(ev.currentTarget),
target = a.attr("target"),
href = a.attr("href");
// check for protocol://
if(/^[A-Z]{2,10}\:\/\//i.test(href)) {
window.open(href);
ev.stopImmediatePropagation();
return false;
}
// check for link in table header
if(a.parents('th').length > 0) {
ev.stopImmediatePropagation();
return false;
}
if(typeof target === "undefined") {
if(a.parents("#icinga-detail").length) {
log.debug("Parent is detail, loading into detail");
async.loadToTarget("icinga-detail",href);
} else {
log.debug("Parent is not detail, loading into main");
async.loadToTarget("icinga-main",href);
}
} else {
switch(target) {
case "body":
async.loadToTarget("body", href);
break;
case "main":
async.loadToTarget("icinga-main",href);
collapseDetailView();
break;
case "detail":
log.debug("Target: detail");
async.loadToTarget("icinga-detail",href);
break;
case "popup":
log.debug("No target");
async.loadToTarget(null,href);
break;
default:
return true;
}
}
ev.stopImmediatePropagation();
return false;
};
var expandDetailView = function() {
$("#icinga-detail").parents(".collapsed").removeClass('collapsed');
};
var collapseDetailView = function(elementInDetailView) {
$("#icinga-detail").parents(".layout-main-detail").addClass('collapsed');
};
this.expandDetailView = expandDetailView;
this.collapseDetailView = collapseDetailView;
this.eventHandler = {
'.layout-main-detail * a' : {
'click' : onLinkTagClick
},
'a' : {
'click' : onOuterLinkClick
},
'.layout-main-detail .icinga-container#icinga-detail' : {
'focus' : expandDetailView
}
};
};
return new MainDetailBehaviour();
});

View File

@ -5,7 +5,7 @@
var containerMgrInstance = null;
var async;
var ContainerMgr = function($,log,Widgets,SubTable,holder) {
var ContainerMgr = function($,log,Widgets,SubTable) {
var enhanceDetachLinks = function() {
@ -34,14 +34,12 @@
}
target.focus();
this.initializeContainers(target);
};
this.updateControlTargets = function(ctrl, req) {
$('a',ctrl).each(function() {
$(this).attr("href",req.url);
});
};
this.initControlBehaviour = function(root) {
@ -86,7 +84,6 @@
this.initExpandables(root);
this.drawImplicitWidgets(root);
this.loadAsyncContainers(root);
};
this.createPopupContainer = function(content,req) {
@ -96,7 +93,6 @@
.append($("<div>").addClass('modal-body').html(content)).appendTo(document.body);
closeButton.on("click",function() {container.remove();});
};
this.getContainer = function(id) {
@ -107,7 +103,7 @@
};
};
define(['jquery','logging','icinga/widgets/checkIcons','icinga/widgets/subTable'], function($,log,widgets,subTable) {
define(['jquery','logging','icinga/widgets/checkIcons','icinga/widgets/subTable'],function($,log,widgets,subTable) {
if (containerMgrInstance === null) {
containerMgrInstance = new ContainerMgr($,log,widgets,subTable);
}

View File

@ -13,7 +13,7 @@ define([
* Icinga prototype
*/
var Icinga = function() {
var internalModules = ['icinga/modules/actionTable','icinga/modules/mainDetail'];
var internalModules = ['icinga/components/actionTable','icinga/components/mainDetail'];
this.modules = {};
var failedModules = [];
@ -37,7 +37,7 @@ define([
};
var loadModuleScript = function(name) {
moduleMgr.enableModule("modules/"+name, function(error) {
moduleMgr.enableModule("modules/"+name+"/"+name, function(error) {
failedModules.push({
name: name,
errorMessage: error