forked from extern/egroupware
Load all category CSS once when loading the application to avoid missing category colors.
This commit is contained in:
parent
9dd37010d4
commit
8b42f6aeb8
@ -573,8 +573,8 @@ class admin_categories
|
||||
|
||||
if($tmpl instanceof etemplate_widget_template)
|
||||
{
|
||||
// Send categories for row colors
|
||||
$sel_options['cat_id'] = etemplate_widget_menupopup::typeOptions('select-cat', ',,,'.$appname.',0');
|
||||
// Category styles
|
||||
egw_framework::includeCSS('/phpgwapi/categories.php?app='.$appname);
|
||||
}
|
||||
|
||||
$tmpl->exec($this->list_link,$content,$sel_options,$readonlys,array(
|
||||
|
@ -221,6 +221,9 @@ class etemplate_new extends etemplate_widget_template
|
||||
{
|
||||
egw_framework::validate_file('.','app',$app,false);
|
||||
}
|
||||
// Category styles
|
||||
egw_framework::includeCSS('/phpgwapi/categories.php?app='.$app);
|
||||
|
||||
// set action attribute for autocomplete form tag
|
||||
// as firefox complains on about:balnk action, thus we have to literaly submit the form to a blank html
|
||||
$form_action = "about:blank";
|
||||
|
@ -515,58 +515,14 @@ var et2_nextmatch_rowProvider = ClassWithAttributes.extend(
|
||||
cats = classes.match(this.cat_regexp) || [];
|
||||
classes = classes.replace(this.cat_regexp, '');
|
||||
|
||||
// Get category info
|
||||
if(!this.categories)
|
||||
{
|
||||
// Nextmatch category filter should put them here
|
||||
var categories = _mgrs["sel_options"].getEntry('cat_id');
|
||||
// Or they are in the global - 1 level up
|
||||
if(!categories) categories = _mgrs["sel_options"].parentMgr.getEntry('cat_id');
|
||||
// If not using category (tracker, calendar list) look for sel_options in the rows
|
||||
if(!categories) categories = _mgrs["sel_options"].parentMgr.getEntry(category_location);
|
||||
if(!categories) categories = _mgrs["sel_options"].getEntry("${row}["+category_location + "]");
|
||||
|
||||
// Cache
|
||||
if(categories)
|
||||
{
|
||||
if (!jQuery.isArray(categories))
|
||||
{
|
||||
this.categories = categories;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.categories = {};
|
||||
for(var i=0; i < categories.length; ++i)
|
||||
{
|
||||
var cat = categories[i];
|
||||
this.categories[cat.value] = cat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < cats.length && this.categories; i++)
|
||||
// Set category class
|
||||
for(var i = 0; i < cats.length; i++)
|
||||
{
|
||||
// Need cat_, classes can't start with a number
|
||||
var cat_id = cats[i].replace(this.cat_cleanup, '');
|
||||
var cat_class = 'cat_'+cat_id;
|
||||
|
||||
// Check for existing class
|
||||
// TODO
|
||||
|
||||
var cat = this.categories[cat_id] || null;
|
||||
for(var j = 0; cat == null && this.categories && j < this.categories.length; j++)
|
||||
{
|
||||
if(this.categories[j] && this.categories[j].value && this.categories[j].value == cat_id)
|
||||
{
|
||||
cat = this.categories[j];
|
||||
}
|
||||
}
|
||||
// Create class
|
||||
if(cat && cat.color)
|
||||
{
|
||||
this._rootWidget.egw().css('.'+cat_class, "background-color: " + cat.color + ";");
|
||||
classes += ' '+cat_class;
|
||||
}
|
||||
classes += ' '+cat_class;
|
||||
}
|
||||
classes += " row_category";
|
||||
}
|
||||
|
@ -306,13 +306,15 @@ var et2_selectbox = et2_inputWidget.extend(
|
||||
if(option_data.icon)
|
||||
{
|
||||
var img = this.egw().image(option_data.icon);
|
||||
jQuery(document.createElement("img"))
|
||||
jQuery(document.createElement(img ? "img" : "div"))
|
||||
.attr("src", img)
|
||||
.addClass('cat_icon cat_' + _value)
|
||||
.appendTo(label);
|
||||
}
|
||||
if(option_data.color)
|
||||
{
|
||||
label.css("background-color",option_data.color);
|
||||
label.css("background-color",option_data.color)
|
||||
.addClass('cat_' + _value);
|
||||
}
|
||||
}
|
||||
label.append(jQuery("<span>"+_label+"</span>"));
|
||||
|
@ -368,9 +368,12 @@ button#cancel {
|
||||
.et2_selectbox input[type="checkbox"] {
|
||||
margin: 3px;
|
||||
}
|
||||
.et2_selectbox .ui-multiselect-checkboxes img {
|
||||
.et2_selectbox .ui-multiselect-checkboxes img, .et2_selectbox .ui-multiselect-checkboxes div {
|
||||
float: right;
|
||||
height: 1.8em;
|
||||
width: 1.8em;
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
.et2_selectbox .ui-multiselect-checkboxes div.ui-icon-close {
|
||||
visibility: hidden;
|
||||
|
71
phpgwapi/categories.php
Normal file
71
phpgwapi/categories.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* API: loading categories and setting styles
|
||||
*
|
||||
* Usage: /egroupware/phpgwapi/categories.php[?app=calendar]
|
||||
*
|
||||
* @link www.egroupware.org
|
||||
* @author Nathan Gray
|
||||
* @package API
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
// switch evtl. set output-compression off, as we cant calculate a Content-Length header with transparent compression
|
||||
ini_set('zlib.output_compression', 0);
|
||||
|
||||
$GLOBALS['egw_info'] = array(
|
||||
'flags' => array(
|
||||
'currentapp' => 'preferences',
|
||||
'noheader' => true,
|
||||
'nocachecontrol' => true,
|
||||
)
|
||||
);
|
||||
|
||||
include '../header.inc.php';
|
||||
|
||||
// Get appname
|
||||
$appname = $_GET['app'] && $GLOBALS['egw_info']['apps'][$_GET['app']] ? $_GET['app'] : categories::GLOBAL_APPNAME;
|
||||
|
||||
$cats = new categories('', $appname);
|
||||
$categories = $cats->return_array('all',0, false, '', 'ASC','',$appname==categories::GLOBAL_APPNAME);
|
||||
|
||||
$content = "/* Category CSS for $appname */\n\n";
|
||||
|
||||
foreach($categories as $cat)
|
||||
{
|
||||
if($cat['data']['color'])
|
||||
{
|
||||
$content .= ".cat_{$cat['id']} { background-color: {$cat['data']['color']};} /*{$cat['name']}*/\n";
|
||||
}
|
||||
if($cat['data']['icon'])
|
||||
{
|
||||
$content .= ".cat_{$cat['id']} .cat_icon { background-image: url('". admin_categories::icon_url($cat['data']['icon']) ."');} /*{$cat['name']}*/\n";
|
||||
}
|
||||
}
|
||||
|
||||
// use an etag over categories
|
||||
$etag = '"'.md5($content).'"';
|
||||
|
||||
// headers to allow caching, egw_framework specifies etag on url to force reload, even with Expires header
|
||||
egw_session::cache_control(86400); // cache for 1 day
|
||||
Header('Content-Type: text/css; charset=utf-8');
|
||||
Header('ETag: '.$etag);
|
||||
|
||||
// if servers send a If-None-Match header, response with 304 Not Modified, if etag matches
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
|
||||
{
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
common::egw_exit();
|
||||
}
|
||||
|
||||
// we run our own gzip compression, to set a correct Content-Length of the encoded content
|
||||
if (in_array('gzip', explode(',',$_SERVER['HTTP_ACCEPT_ENCODING'])) && function_exists('gzencode'))
|
||||
{
|
||||
$content = gzencode($content);
|
||||
header('Content-Encoding: gzip');
|
||||
}
|
||||
|
||||
// Content-Lenght header is important, otherwise browsers dont cache!
|
||||
Header('Content-Length: '.bytes($content));
|
||||
echo $content;
|
@ -1385,6 +1385,9 @@ abstract class egw_framework
|
||||
// eTemplate2 - load in top so sidebox has styles too
|
||||
self::includeCSS('/etemplate/templates/default/etemplate2.css');
|
||||
|
||||
// Category styles
|
||||
self::includeCSS('/phpgwapi/categories.php');
|
||||
|
||||
// For mobile user-agent we prefer mobile theme over selected one with a final fallback to theme named as template
|
||||
$themes_to_check = array();
|
||||
if (html::$ua_mobile) $themes_to_check[] = $this->template_dir.'/css/mobile.css';
|
||||
@ -1418,11 +1421,13 @@ abstract class egw_framework
|
||||
{
|
||||
foreach(self::resolve_css_includes($path) as $path)
|
||||
{
|
||||
if (($mod = filemtime(EGW_SERVER_ROOT.$path)) > $max_modified) $max_modified = $mod;
|
||||
list($file,$query) = explode('?',$path,2);
|
||||
if (($mod = filemtime(EGW_SERVER_ROOT.$file)) > $max_modified) $max_modified = $mod;
|
||||
|
||||
if ($debug_minify || substr($path, -8) == '/app.css') // do NOT include app.css, as it changes from app to app
|
||||
// do NOT include app.css or categories.php, as it changes from app to app
|
||||
if ($debug_minify || substr($path, -8) == '/app.css' || substr($file,-14) == 'categories.php')
|
||||
{
|
||||
$css_files .= '<link href="'.$GLOBALS['egw_info']['server']['webserver_url'].$path.'?'.$mod.'" type="text/css" rel="StyleSheet" />'."\n";
|
||||
$css_files .= '<link href="'.$GLOBALS['egw_info']['server']['webserver_url'].$path.($query ? '&' : '?').$mod.'" type="text/css" rel="StyleSheet" />'."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1454,7 +1459,9 @@ abstract class egw_framework
|
||||
protected static function resolve_css_includes($path, &$pathes=array())
|
||||
{
|
||||
$matches = null;
|
||||
if (($to_check = file_get_contents (EGW_SERVER_ROOT.$path, false, null, -1, 1024)) &&
|
||||
|
||||
list($file,$query) = explode('?',$path,2);
|
||||
if (($to_check = file_get_contents (EGW_SERVER_ROOT.$file, false, null, -1, 1024)) &&
|
||||
stripos($to_check, '/*@import') !== false && preg_match_all('|/\*@import url\("([^"]+)"|i', $to_check, $matches))
|
||||
{
|
||||
foreach($matches[1] as $import_path)
|
||||
@ -2248,7 +2255,7 @@ abstract class egw_framework
|
||||
{
|
||||
$path = $app;
|
||||
}
|
||||
if (!file_exists(EGW_SERVER_ROOT.$path))
|
||||
if (!file_exists(EGW_SERVER_ROOT.$path) && !file_exists(EGW_SERVER_ROOT . parse_url($path,PHP_URL_PATH)))
|
||||
{
|
||||
//error_log(__METHOD__."($app,$name) $path NOT found!");
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user