forked from extern/egroupware
switching on Content-Security-Policy: script-src 'self' 'unsafe-eval' for all templates, old non-et2 apps can call egw_framework::csp_script_src_attrs('unsafe-inline') to enable inline scripts in their scope, et2 does it for CK editor which does not support CSP currently and old etemplate does it for all apps using it
This commit is contained in:
parent
b1d5dad6b9
commit
43e1bfcc12
@ -477,16 +477,7 @@ class calendar_ui
|
||||
*/
|
||||
function _select_box($title,$name,$options,$baseurl='')
|
||||
{
|
||||
if ($baseurl) // we append the value to the baseurl
|
||||
{
|
||||
if (substr($baseurl,-1) != '=') $baseurl .= strpos($baseurl,'?') === False ? '?' : '&';
|
||||
$onchange="egw_appWindow('calendar').location='$baseurl'+this.value;";
|
||||
}
|
||||
else // we add $name=value to the actual location
|
||||
{
|
||||
$onchange="var win=egw_appWindow('calendar'); win.location=win.location+(win.location.search.length ? '&' : '?')+'".$name."='+this.value;";
|
||||
}
|
||||
$select = ' <select style="width: 100%;" name="'.$name.'" onchange="'.$onchange.'" title="'.
|
||||
$select = ' <select style="width: 100%;" name="'.$name.'" id="calendar_'.$name.'" title="'.
|
||||
lang('Select a %1',lang($title)).'">'.
|
||||
$options."</select>\n";
|
||||
|
||||
@ -665,11 +656,10 @@ class calendar_ui
|
||||
|
||||
// Search
|
||||
$blur = addslashes(html::htmlspecialchars(lang('Search').'...'));
|
||||
$value = @$_POST['keywords'] ? html::htmlspecialchars($_POST['keywords']) : $blur;
|
||||
$value = @$_POST['keywords'] ? html::htmlspecialchars($_POST['keywords']) : '';
|
||||
$file[++$n] = array(
|
||||
'text' => html::form('<input name="keywords" value="'.$value.'" style="width: 97.5%;"'.
|
||||
' onFocus="if(this.value==\''.$blur.'\') this.value=\'\';"'.
|
||||
' onBlur="if(this.value==\'\') this.value=\''.$blur.'\';" title="'.lang('Search').'">',
|
||||
' placeholder="'.$blur.'" title="'.lang('Search').'">',
|
||||
'','/index.php',array('menuaction'=>'calendar.calendar_uilist.listview')),
|
||||
'no_lang' => True,
|
||||
'link' => False,
|
||||
@ -717,34 +707,13 @@ class calendar_ui
|
||||
}
|
||||
|
||||
// Category Selection
|
||||
$onchange = "var value = '';
|
||||
if(selectBox = document.getElementById('cat_id')) {
|
||||
for(i=0; i < selectBox.length; ++i) {
|
||||
if (selectBox.options[i].selected) {
|
||||
value += (value ? ',' : '') + selectBox.options[i].value;
|
||||
}
|
||||
}
|
||||
}";
|
||||
if ($baseurl) // we append the value to the baseurl
|
||||
{
|
||||
$cat_baseurl = $baseurl ? $baseurl.'&cat_id=' : '';
|
||||
if (substr($cat_baseurl,-1) != '=') $cat_baseurl .= strpos($cat_baseurl,'?') === False ? '?' : '&';
|
||||
$onchange.="egw_appWindow('calendar').location='$cat_baseurl'+value;";
|
||||
}
|
||||
else // we add $name=value to the actual location
|
||||
{
|
||||
$onchange.="var win=egw_appWindow('calendar'); win.location=win.location+(win.location.search.length ? '&' : '?')+'cat_id='+value;";
|
||||
}
|
||||
|
||||
$cat_id = explode(',',$this->cat_id);
|
||||
$options = '<option value="0">'.lang('All categories').'</option>'.
|
||||
$this->categories->formatted_list('select','all',$cat_id,'True');
|
||||
$icon_onclick = "if(selectBox = document.getElementById('cat_id')) {
|
||||
if (!selectBox.multiple) {selectBox.size=4; selectBox.multiple=true;}}";
|
||||
|
||||
$select = ' <select style="width: 87%;" id="cat_id" name="cat_id" onchange="'.$onchange.'" title="'.
|
||||
$select = ' <select style="width: 87%;" id="calendar_cat_id" name="cat_id" title="'.
|
||||
lang('Select a %1',lang('Category')). '"'.($cat_id && count($cat_id) > 1 ? ' multiple=true size=4':''). '>'.
|
||||
$options."</select>\n" . html::image('phpgwapi','attach','','onclick="'.$icon_onclick.'"');
|
||||
$options."</select>\n" . html::image('phpgwapi','attach','','id="calendar_cat_id_multiple"');
|
||||
|
||||
$file[++$n] = array(
|
||||
'text' => $select,
|
||||
@ -790,32 +759,17 @@ class calendar_ui
|
||||
}
|
||||
// we no longer exclude non-accounts from the account-selection: it shows all types of participants
|
||||
$accounts = explode(',',$this->owner);
|
||||
$current_view_url = egw::link('/index.php',array(
|
||||
'menuaction' => $this->view_menuaction,
|
||||
'date' => $this->date,
|
||||
),false);
|
||||
$file[] = array(
|
||||
'text' => "
|
||||
<script type=\"text/javascript\">
|
||||
function load_cal(url,id,no_reset) {
|
||||
var owner='';
|
||||
var i = 0;
|
||||
selectBox = document.getElementById(id);
|
||||
for(i=0; i < selectBox.length; ++i) {
|
||||
if (selectBox.options[i].selected) {
|
||||
owner += (owner ? ',' : '') + selectBox.options[i].value;
|
||||
}
|
||||
}
|
||||
if (owner) {
|
||||
if (typeof no_reset == 'unknown') no_reset = false;
|
||||
egw_appWindow('calendar').location=url+'&owner='+(no_reset?'':'0,')+owner;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
".
|
||||
<script type=\"text/javascript\" src=\"{$GLOBALS['egw_info']['server']['webserver_url']}/calendar/js/navigation.js\" id=\"calendar-navigation-script\" data-current-view-url=\"".htmlspecialchars($current_view_url)."\"/></script>\n".
|
||||
|
||||
$this->accountsel->selection('owner','uical_select_owner',$accounts,'calendar+',count($accounts) > 1 ? 4 : 1,False,
|
||||
' style="width: '.(count($accounts) > 1 && in_array($this->common_prefs['account_selection'],array('selectbox','groupmembers')) ? '100%' : '87%').';"'.
|
||||
' title="'.lang('select a %1',lang('user')).'" onchange="load_cal(\''.
|
||||
egw::link('/index.php',array(
|
||||
'menuaction' => $this->view_menuaction,
|
||||
'date' => $this->date,
|
||||
),false).'\',\'uical_select_owner\');"','',$grants,false,array($this->bo,'participant_name')),
|
||||
' title="'.lang('select a %1',lang('user')).'"','',$grants,false,array($this->bo,'participant_name')),
|
||||
'no_lang' => True,
|
||||
'link' => False
|
||||
);
|
||||
@ -839,10 +793,8 @@ function load_cal(url,id,no_reset) {
|
||||
}
|
||||
if($options != '') {
|
||||
$options = '<option value="">'.lang('Insert in document')."</option>\n" . $options;
|
||||
$name = 'merge';
|
||||
$onchange="var win=egw_appWindow('calendar'); win.location=win.location+(win.location.search.length ? '&' : '?')+'".$name."='+this.value;this.value='';";
|
||||
$select = ' <select style="width: 100%;" name="'.$name.'" onchange="'.$onchange.'" title="'.
|
||||
lang('Select a %1',lang('merge document...')).'">'.
|
||||
$select = ' <select style="width: 100%;" name="merge" id="calendar_merge" title="'.
|
||||
html::htmlspecialchars(lang('Select a %1',lang('merge document...'))).'">'.
|
||||
$options."</select>\n";
|
||||
|
||||
$file[] = array(
|
||||
|
@ -146,6 +146,9 @@ class calendar_uiviews extends calendar_ui
|
||||
*/
|
||||
function __construct($set_states=null)
|
||||
{
|
||||
// tell framework calendar needs eval and inline javascript :(
|
||||
egw_framework::csp_script_src_attrs(array('unsafe-eval', 'unsafe-inline'));
|
||||
|
||||
parent::__construct(false,$set_states); // call the parent's constructor
|
||||
$this->extraRowsOriginal = $this->extraRows; //save original extraRows value
|
||||
|
||||
|
76
calendar/js/navigation.js
Normal file
76
calendar/js/navigation.js
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Calendar - sidebox navigation
|
||||
*
|
||||
* @link http://www.egroupware.org
|
||||
* @author Ralf Becker <RalfBecker@stylite.de>
|
||||
* @package calendar
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sidebox navigation for calendar
|
||||
*
|
||||
* @todo add code from jscalendar->flat(), or better replace it altogether ...
|
||||
*/
|
||||
(function()
|
||||
{
|
||||
var script_tag = document.getElementById('calendar-navigation-script');
|
||||
var current_view_url;
|
||||
if (script_tag)
|
||||
{
|
||||
current_view_url = script_tag.getAttribute('data-current-view-url');
|
||||
}
|
||||
function load_cal(url,id,no_reset) {
|
||||
var owner='';
|
||||
var i = 0;
|
||||
selectBox = document.getElementById(id);
|
||||
for(i=0; i < selectBox.length; ++i) {
|
||||
if (selectBox.options[i].selected) {
|
||||
owner += (owner ? ',' : '') + selectBox.options[i].value;
|
||||
}
|
||||
}
|
||||
if (owner) {
|
||||
if (typeof no_reset == 'unknown') no_reset = false;
|
||||
egw_appWindow('calendar').location=url+'&owner='+(no_reset?'':'0,')+owner;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialisation after DOM *and* jQuery is loaded
|
||||
*/
|
||||
egw_LAB.wait(function() {
|
||||
$j(function(){
|
||||
var calendar_window = egw_appWindow('calendar');
|
||||
// change handlers setting a certain url, eg. view
|
||||
$j('#calendar_view').change(function(){
|
||||
calendar_window.location = egw_webserverUrl+'/index.php?'+this.value;
|
||||
});
|
||||
// calendar owner selection change
|
||||
$j('#uical_select_owner,#uical_select_resource').change(function(e){
|
||||
if (this.value != 'popup')
|
||||
{
|
||||
load_cal(current_view_url, this.id, this.id != 'uical_select_owner');
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
// diverse change handlers appending a name=value to url
|
||||
$j('#calendar_merge,#calendar_filter,#calendar_cat_id').change(function(){
|
||||
var val = $j(this).val();
|
||||
if ($j.isArray(val)) val = val.join(',');
|
||||
calendar_window.location = current_view_url+
|
||||
(current_view_url.search.length ? '&' : '?')+this.name+'='+val;
|
||||
if (this.name == 'merge') this.value='';
|
||||
});
|
||||
// click handler to switch selectbox to multiple
|
||||
$j('#calendar_cat_id_multiple').click(function(){
|
||||
var selectBox = document.getElementById(this.id.replace('_multiple', ''));
|
||||
if (selectBox && !selectBox.multiple)
|
||||
{
|
||||
selectBox.size=4;
|
||||
selectBox.multiple=true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
@ -136,6 +136,9 @@ class etemplate_old extends boetemplate
|
||||
*/
|
||||
function __construct($name='',$load_via='')
|
||||
{
|
||||
// tell framework old eTemplate apps needs eval and inline javascript :(
|
||||
egw_framework::csp_script_src_attrs(array('unsafe-eval', 'unsafe-inline'));
|
||||
|
||||
parent::__construct($name,$load_via);
|
||||
|
||||
$this->sitemgr = isset($GLOBALS['Common_BO']) && is_object($GLOBALS['Common_BO']);
|
||||
|
@ -31,8 +31,10 @@ class etemplate_widget_htmlarea extends etemplate_widget
|
||||
public function beforeSendToClient($cname)
|
||||
{
|
||||
$form_name = self::form_name($cname, $this->id);
|
||||
|
||||
|
||||
|
||||
// tell framework CK Editor needs eval and inline javascript :(
|
||||
egw_framework::csp_script_src_attrs(array('unsafe-eval', 'unsafe-inline'));
|
||||
|
||||
$config = egw_ckeditor_config::get_ckeditor_config_array($this->attrs['mode'], $this->attrs['height'],
|
||||
$this->attrs['expand_toolbar'],$this->attrs['base_href']
|
||||
);
|
||||
|
@ -83,6 +83,59 @@ abstract class egw_framework
|
||||
$this->template_dir = '/phpgwapi/templates/'.$template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional attributes for CSP script-src 'self'
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $csp_script_src_attrs = array('unsafe-eval');
|
||||
|
||||
/**
|
||||
* Set/get Content-Security-Policy attributes for script-src: 'unsafe-eval' and/or 'unsafe-inline'
|
||||
*
|
||||
* Using CK-Editor currently requires both to be set :(
|
||||
*
|
||||
* Old pre-et2 apps might need to call egw_framework::csp_script_src_attrs(array('unsafe-eval','unsafe-inline'))
|
||||
*
|
||||
* EGroupware itself currently still requires 'unsafe-eval'!
|
||||
*
|
||||
* @param string|array $set=array() 'unsafe-eval' and/or 'unsafe-inline' (without quotes!)
|
||||
* @return string with attributes eg. "'unsafe-eval' 'unsafe-inline'"
|
||||
*/
|
||||
public static function csp_script_src_attrs($set=null)
|
||||
{
|
||||
foreach((array)$set as $attr)
|
||||
{
|
||||
if (!in_array($attr, self::$csp_script_src_attrs))
|
||||
{
|
||||
self::$csp_script_src_attrs[] = $attr;
|
||||
//error_log(__METHOD__."() swiching CSP OFF for script-src '$attr' ".function_backtrace());
|
||||
}
|
||||
}
|
||||
return self::$csp_script_src_attrs ? "'".implode("' '", self::$csp_script_src_attrs)."'" : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Send HTTP headers: Content-Type and Content-Security-Policy
|
||||
*/
|
||||
protected function _send_headers()
|
||||
{
|
||||
// add a content-type header to overwrite an existing default charset in apache (AddDefaultCharset directiv)
|
||||
header('Content-type: text/html; charset='.translation::charset());
|
||||
|
||||
// content-security-policy header:
|
||||
// - "script-src 'self' 'unsafe-eval'" allows only self and eval (eg. ckeditor), but forbids inline scripts, onchange, etc
|
||||
// - "connect-src 'self'" allows ajax requests only to self
|
||||
// - "style-src 'self' 'unsave-inline'" allows only self and inline style, which we need
|
||||
// - "frame-src 'self' manual.egroupware.org" allows frame and iframe content only for self or manual.egroupware.org
|
||||
$csp = "script-src 'self' ".($script_attrs=self::csp_script_src_attrs())."; connect-src 'self'; style-src 'self' 'unsafe-inline'; frame-src 'self' manual.egroupware.org";
|
||||
//error_log(__METHOD__."() script_attrs=$script_attrs");
|
||||
//$csp = "default-src * 'unsafe-eval' 'unsafe-inline'"; // allow everything
|
||||
header("Content-Security-Policy: $csp");
|
||||
header("X-Webkit-CSP: $csp"); // Chrome: <= 24, Safari incl. iOS
|
||||
header("X-Content-Security-Policy: $csp"); // FF <= 22
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for static variables
|
||||
*/
|
||||
|
@ -531,6 +531,9 @@ class html
|
||||
return self::textarea($_name,$_content,'style="width: '.$_width.'; height: '.$_height.';" id="'.htmlspecialchars($_name).'"');
|
||||
}
|
||||
|
||||
// tell framework CK Editor needs eval and inline javascript :(
|
||||
egw_framework::csp_script_src_attrs(array('unsafe-eval', 'unsafe-inline'));
|
||||
|
||||
//include the ckeditor js file
|
||||
egw_framework::validate_file('ckeditor','ckeditor','phpgwapi');
|
||||
|
||||
|
@ -52,10 +52,6 @@ class uiaccountsel
|
||||
{
|
||||
$this->account_selection = 'primary_group';
|
||||
}
|
||||
|
||||
// Include these here, framework may have already sent header by the time the account select is made
|
||||
egw_framework::validate_file('/phpgwapi/js/jquery/chosen/chosen.jquery.js');
|
||||
egw_framework::includeCSS('/phpgwapi/js/jquery/chosen/chosen.css',null,false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,6 +92,8 @@ class uiaccountsel
|
||||
$multi_size = abs($lines);
|
||||
$lines = 1;
|
||||
}
|
||||
$options .= ' class="uiaccountselection '.$this->account_selection.'"'; // to be able to style and select it with jQuery
|
||||
|
||||
if ($this->account_selection == 'none') // dont show user-selection at all!
|
||||
{
|
||||
return html::input_hidden($name,$selected);
|
||||
@ -249,26 +247,16 @@ class uiaccountsel
|
||||
'element_id' => $element_id,
|
||||
'multiple' => $lines, // single selection (multiple=0), closes after the first selection
|
||||
),false);
|
||||
$popup_options = 'width=600,height=420,toolbar=no,scrollbars=yes,resizable=yes';
|
||||
$app = $GLOBALS['egw_info']['flags']['currentapp'];
|
||||
if (!$only_groups && ($lines <= 1 && $this->account_selection == 'popup' || !$lines && $this->account_selection == 'primary_group'))
|
||||
{
|
||||
if (!$lines)
|
||||
{
|
||||
$options .= ' onchange="if (this.value==\'popup\') '."window.open('$link','uiaccountsel','$popup_options');".
|
||||
($onchange ? " else { $onchange }" : '' ).'" onclick="if (this.value==\'popup\') '."window.open('$link','uiaccountsel','$popup_options');\"";
|
||||
$select['popup'] = lang('Search').' ...';
|
||||
}
|
||||
elseif ($onchange)
|
||||
{
|
||||
$options .= ' onchange="if (this.value[0]!=\',\') { '.$onchange.' }"';
|
||||
}
|
||||
$need_js_popup = True;
|
||||
}
|
||||
elseif ($onchange)
|
||||
{
|
||||
$options .= ' onchange="'.$onchange.'"';
|
||||
}
|
||||
if ($onchange) $options .= ' onchange="'.$onchange.'"'; // no working under CSP without 'unsafe-inline'
|
||||
|
||||
if ($extra_label)
|
||||
{
|
||||
//in php5 this put's the extra-label at the end: $select = array($extra_label) + $select;
|
||||
@ -286,77 +274,30 @@ class uiaccountsel
|
||||
);
|
||||
}
|
||||
//echo "<p>html::select('$name',".print_r($selected,True).",".print_r($select,True).",True,'$options')</p>\n";
|
||||
$html = html::select($name,$selected,$select,True,$options.' id="'.$element_id.'"',$lines > 1 ? $lines : 0,true);
|
||||
$html = html::select($name,$selected,$select,True,$options.' id="'.$element_id.
|
||||
'" data-popup-link="'.htmlspecialchars($link).'"',$lines > 1 ? $lines : 0,false);
|
||||
|
||||
if (!$only_groups && ($lines > 0 && $this->account_selection == 'popup' || $lines > 1 && $this->account_selection == 'primary_group'))
|
||||
{
|
||||
$js = "window.open('$link','uiaccountsel','$popup_options'); return false;";
|
||||
$html .= html::submit_button('search','Search accounts',$js,false,
|
||||
' title="'.html::htmlspecialchars(lang('Search accounts')).'"','search','phpgwapi');
|
||||
' title="'.html::htmlspecialchars(lang('Search accounts')).
|
||||
'" class="uiaccountselection_trigger" id="'.$element_id.'_popup"','search','phpgwapi','button');
|
||||
$need_js_popup = True;
|
||||
}
|
||||
elseif (!$only_groups && ($lines == 1 || $lines > 0 && $this->account_selection == 'primary_group'))
|
||||
{
|
||||
$js = "if (selectBox = document.getElementById('$element_id')) if (!selectBox.multiple) { if(\$j(selectBox).unchosen) \$j(selectBox).unchosen(); selectBox.size=$multi_size; selectBox.multiple=true; if (selectBox.options[0].value=='') selectBox.options[0] = null;";
|
||||
if(count($select) > html::SELECT_ENHANCED_ROW_COUNT || true)
|
||||
{
|
||||
$js .= "\$j(selectBox).css('width','100%'); ";
|
||||
}
|
||||
if (!in_array($this->account_selection,array('groupmembers','selectbox'))) // no popup!
|
||||
{
|
||||
$js .= " this.src='".common::image('phpgwapi','search')."'; this.title='".
|
||||
html::htmlspecialchars(lang('Search accounts'))."';} else {window.open('$link','uiaccountsel','$popup_options');";
|
||||
$need_js_popup = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
$js .= "this.style.display='none'; selectBox.style.width='100%';";
|
||||
}
|
||||
$js .= "} return false;";
|
||||
$html .= html::submit_button('search','Select multiple accounts',$js,false,
|
||||
' title="'.html::htmlspecialchars(lang('Select multiple accounts')).'"','users','phpgwapi');
|
||||
}
|
||||
// jDots needs a little re-do, since it plays with the layout
|
||||
$html .= "<script>
|
||||
egw_LAB.wait(function() {
|
||||
if (\$j().chosen)
|
||||
window.setTimeout(function() {
|
||||
\$j('#$element_id').unchosen().chosen({width:'90%', placeholder_text: '".lang('Select multiple accounts')."'});
|
||||
},200);
|
||||
});
|
||||
</script>";
|
||||
if($need_js_popup && !$GLOBALS['egw_info']['flags']['uiaccountsel']['addOption_installed'])
|
||||
{
|
||||
$html .= '<script language="JavaScript">
|
||||
function addOption(id,label,value,do_onchange)
|
||||
{
|
||||
selectBox = document.getElementById(id);
|
||||
for (i=0; i < selectBox.length; i++) {
|
||||
'.// check existing entries if they're already there and only select them in that case
|
||||
' if (selectBox.options[i].value == value) {
|
||||
selectBox.options[i].selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= selectBox.length) {
|
||||
if (!do_onchange) {
|
||||
if (selectBox.length && selectBox.options[0].value=="") selectBox.options[0] = null;
|
||||
selectBox.multiple=true;
|
||||
selectBox.size='.$multi_size.';
|
||||
}
|
||||
selectBox.options[selectBox.length] = new Option(label,value,false,true);
|
||||
}
|
||||
if (selectBox.onchange && do_onchange) selectBox.onchange();
|
||||
$j(selectBox).trigger("liszt:updated");
|
||||
}
|
||||
</script>';
|
||||
$GLOBALS['egw_info']['flags']['uiaccountsel']['addOption_installed'] = True;
|
||||
$html .= html::submit_button('search','Select multiple accounts','',false,
|
||||
' title="'.html::htmlspecialchars(lang('Select multiple accounts')).
|
||||
'" class="uiaccountselection_trigger" id="'.$element_id.'_multiple"','users','phpgwapi','button');
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
|
||||
function popup()
|
||||
{
|
||||
// switch CSP to script-src 'unsafe-inline', until code get fixed here to work without
|
||||
egw_framework::csp_script_src_attrs('unsafe-inline');
|
||||
|
||||
global $query; // nextmatch requires that !!!
|
||||
|
||||
$app = get_var('app',array('POST','GET'));
|
||||
@ -477,7 +418,7 @@ function addOption(id,label,value,do_onchange)
|
||||
{
|
||||
$link_data['group_id'] = $group['account_id'];
|
||||
|
||||
$GLOBALS['egw']->template->set_var('onclick',"addOption('$element_id','".
|
||||
$GLOBALS['egw']->template->set_var('onclick',"ownAddOption('$element_id','".
|
||||
addslashes(common::grab_owner_name($group['account_id']))."','$group[account_id]',".(int)($multiple==1).")".
|
||||
(!$multiple ? '; window.close()' : ''));
|
||||
|
||||
@ -491,7 +432,7 @@ function addOption(id,label,value,do_onchange)
|
||||
if($use == 'both') // allow selection of groups
|
||||
{
|
||||
$GLOBALS['egw']->template->fp('cal','group_cal',True);
|
||||
$GLOBALS['egw']->template->set_var('js_addAllGroups',"addOption('$element_id','".
|
||||
$GLOBALS['egw']->template->set_var('js_addAllGroups',"ownAddOption('$element_id','".
|
||||
addslashes(common::grab_owner_name($group['account_id']))."','$group[account_id]',".(int)($multiple==1).")".
|
||||
(!$multiple ? '; window.close();' : ';'));
|
||||
$GLOBALS['egw']->template->fp('selectAllGroups','group_selectAll',True);
|
||||
@ -555,12 +496,12 @@ function addOption(id,label,value,do_onchange)
|
||||
'lid' => $user['account_lid'],
|
||||
'firstname' => $user['account_firstname'] ? $user['account_firstname'] : ' ',
|
||||
'lastname' => $user['account_lastname'] ? $user['account_lastname'] : ' ',
|
||||
'onclick' => "addOption('$element_id','".
|
||||
'onclick' => "ownAddOption('$element_id','".
|
||||
addslashes(common::grab_owner_name($user['account_id']))."','$user[account_id]',".(int)($multiple==1).")".
|
||||
(!$multiple ? '; window.close()' : ''),
|
||||
));
|
||||
$GLOBALS['egw']->template->fp('list','accounts_list',True);
|
||||
$GLOBALS['egw']->template->set_var('js_addAllAccounts',"addOption('$element_id','".
|
||||
$GLOBALS['egw']->template->set_var('js_addAllAccounts',"ownAddOption('$element_id','".
|
||||
addslashes(common::grab_owner_name($user['account_id']))."','$user[account_id]',".(int)($multiple==1).")".
|
||||
(!$multiple ? '; window.close()' : ';'));
|
||||
$GLOBALS['egw']->template->fp('selectAllAccounts','accounts_selectAll',True);
|
||||
|
@ -794,7 +794,14 @@ function dropdown_menu_hack(el)
|
||||
*/
|
||||
function egw_link_handler(_link, _app)
|
||||
{
|
||||
window.location.href = _link;
|
||||
if (window.framework)
|
||||
{
|
||||
window.framework.linkHandler(_link, _app);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location.href = _link;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -843,3 +850,72 @@ function egw_preferences(name, apps)
|
||||
egw_link_handler(egw_webserverUrl+url, current_app);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Support functions for uiaccountselection class
|
||||
*
|
||||
* @ToDo: should be removed if uiaccountsel class is no longer in use
|
||||
*/
|
||||
function addOption(id,label,value,do_onchange)
|
||||
{
|
||||
selectBox = document.getElementById(id);
|
||||
for (var i=0; i < selectBox.length; i++) {
|
||||
// check existing entries if they're already there and only select them in that case
|
||||
if (selectBox.options[i].value == value) {
|
||||
selectBox.options[i].selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= selectBox.length) {
|
||||
if (!do_onchange) {
|
||||
if (selectBox.length && selectBox.options[0].value=='') selectBox.options[0] = null;
|
||||
selectBox.multiple=true;
|
||||
selectBox.size=4;
|
||||
}
|
||||
selectBox.options[selectBox.length] = new Option(label,value,false,true);
|
||||
}
|
||||
if (selectBox.onchange && do_onchange) selectBox.onchange();
|
||||
}
|
||||
/**
|
||||
* Install click handlers for popup and multiple triggers of uiaccountselection
|
||||
*/
|
||||
$j(function(){
|
||||
$j(document).on('click', 'input.uiaccountselection_trigger',function(){
|
||||
var selectBox = document.getElementById(this.id.replace(/(_multiple|_popup)$/, ''));
|
||||
if (selectBox)
|
||||
{
|
||||
var link = selectBox.getAttribute('data-popup-link');
|
||||
|
||||
if (selectBox.multiple || this.id.match(/_popup$/))
|
||||
{
|
||||
window.open(link, 'uiaccountsel', 'width=600,height=420,toolbar=no,scrollbars=yes,resizable=yes');
|
||||
}
|
||||
else
|
||||
{
|
||||
selectBox.size = 4;
|
||||
selectBox.multiple = true;
|
||||
if (selectBox.options[0].value=='') selectBox.options[0] = null;
|
||||
|
||||
if (!$j(selectBox).hasClass('groupmembers') && !$j(selectBox).hasClass('selectbox')) // no popup!
|
||||
{
|
||||
this.src = egw.image('search');
|
||||
this.title = egw.lang('Search accounts');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.style.display = 'none';
|
||||
selectBox.style.width = '100%';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
$j(document).on('change', 'select.uiaccountselection',function(e){
|
||||
if (this.value == 'popup')
|
||||
{
|
||||
var link = this.getAttribute('data-popup-link');
|
||||
window.open(link, 'uiaccountsel', 'width=600,height=420,toolbar=no,scrollbars=yes,resizable=yes');
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<script LANGUAGE="JavaScript">
|
||||
window.focus();
|
||||
|
||||
function addOption(id,label,value,multiple)
|
||||
function ownAddOption(id,label,value,multiple)
|
||||
{
|
||||
openerSelectBox = opener.document.getElementById(id);
|
||||
|
||||
@ -99,7 +99,7 @@
|
||||
border: 1px solid white;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
cusror: hand;
|
||||
cursor: hand;
|
||||
}
|
||||
.letter_box_active {
|
||||
font-weight: bold;
|
||||
|
@ -91,8 +91,7 @@ class idots_framework extends egw_framework
|
||||
if (self::$header_done) return '';
|
||||
self::$header_done = true;
|
||||
|
||||
// add a content-type header to overwrite an existing default charset in apache (AddDefaultCharset directiv)
|
||||
header('Content-type: text/html; charset='.translation::charset());
|
||||
self::_send_headers();
|
||||
|
||||
// catch error echo'ed before the header, ob_start'ed in the header.inc.php
|
||||
$content = ob_get_contents();
|
||||
|
@ -43,10 +43,11 @@
|
||||
}
|
||||
|
||||
/**
|
||||
* Installing resize handler for divAppbox and et2_container, as et2 otherwise can not correctly size nextmatch
|
||||
* Initialisation, when DOM is ready
|
||||
*/
|
||||
$j(function()
|
||||
{
|
||||
// Installing resize handler for divAppbox and et2_container, as et2 otherwise can not correctly size nextmatch
|
||||
$j(window).resize(function(){
|
||||
var appbox_height = $j(window).height()-$j('#topmenu').height()-$j('#divAppIconBar').height()-
|
||||
$j('#divStatusBar').height()-$j('#divAppboxHeader').height()-$j('#divPoweredBy').height()-20;
|
||||
@ -55,5 +56,25 @@
|
||||
$j('.et2_container').height(appbox_height);
|
||||
});
|
||||
$j(window).resize();
|
||||
$j(window).load(function(){ // fixes sometimes not called resize, probably due to timing issues
|
||||
$j(window).resize();
|
||||
});
|
||||
|
||||
// allowing javascript urls in topmenu and sidebox only under CSP by binding click handlers to them
|
||||
var href_regexp = /^javascript:([^\(]+)\((.*)?\);?$/;
|
||||
jQuery('#topmenu_items,#thesideboxcolumn').on('click','a[href^="javascript:"]',function(){
|
||||
var matches = this.href.match(href_regexp);
|
||||
if (matches && typeof window[matches[1]] == 'function') {
|
||||
var args = [];
|
||||
if (matches.length > 1 && matches[2] !== undefined) args = JSON.parse('['+matches[2].replace(/'/g,'"')+']');
|
||||
window[matches[1]].apply(window.framework, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
alert('Do NOT know how to execute '+this.href);
|
||||
}
|
||||
// return false to not execute link itself, which would violate CSP
|
||||
return false;
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
@ -838,15 +838,14 @@ class resources_ui
|
||||
$selected,
|
||||
array_merge($resources,$res_cats),
|
||||
$no_lang=true,
|
||||
$options='data-placeholder="'.lang('select resources').'" style="width: 100%;" onchange="load_cal(\''.
|
||||
egw::link('/index.php',$param,false).'\',\'uical_select_resource\',true);" id="uical_select_resource"',
|
||||
$options=' style="width: 100%;" id="uical_select_resource"',
|
||||
$multiple=4,
|
||||
true
|
||||
false
|
||||
);
|
||||
return array(
|
||||
array(
|
||||
// Add some jQuery to make sure dropdown is displayed
|
||||
'text' => $selectbox . "<script>var lab = egw_LAB || \$LAB; lab.wait(function(){ \$j('select[name=\"owner\[\]\"]').parent('td').css('overflow','visible').parents('div.divSidebox').css('overflow','visible');});</script>",
|
||||
'text' => $selectbox,
|
||||
'no_lang' => True,
|
||||
'link' => False
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user