Files: Accessibility improvements (#3087), Display dialogs from frames in main window.

This commit is contained in:
Aleksander Machniak 2014-06-12 12:55:34 +02:00
parent 6d1ffc345d
commit d1e3acf1ad
9 changed files with 268 additions and 120 deletions

View file

@ -30,22 +30,21 @@ window.rcmail && rcmail.addEventListener('init', function() {
// mail compose
if (rcmail.env.action == 'compose') {
var elem = $('#compose-attachments > div'),
input = $('<input class="button" type="button">');
input.val(rcmail.gettext('kolab_files.fromcloud'))
.click(function() { kolab_files_selector_dialog(); })
.appendTo(elem);
input = $('<input class="button" type="button">')
.attr('tabindex', $('input', elem).attr('tabindex') || 0)
.val(rcmail.gettext('kolab_files.fromcloud'))
.click(function() { kolab_files_selector_dialog(); })
.appendTo(elem);
if (rcmail.gui_objects.filelist) {
rcmail.file_list = new rcube_list_widget(rcmail.gui_objects.filelist, {
multiselect: true,
// draggable: true,
keyboard: true,
column_movable: false,
dblclick_time: rcmail.dblclick_time
});
rcmail.file_list.addEventListener('select', function(o) { kolab_files_list_select(o); });
rcmail.file_list.addEventListener('listupdate', function(e) { rcmail.triggerEvent('listupdate', e); });
rcmail.file_list.addEventListener('select', function(o) { kolab_files_list_select(o); })
.addEventListener('listupdate', function(e) { rcmail.triggerEvent('listupdate', e); });
rcmail.gui_objects.filelist.parentNode.onmousedown = function(e){ return kolab_files_click_on_list(e); };
rcmail.enable_command('files-sort', 'files-search', 'files-search-reset', true);
@ -90,16 +89,16 @@ window.rcmail && rcmail.addEventListener('init', function() {
rcmail.file_list.addEventListener('dragstart', function(o){ p.drag_start(o); });
rcmail.file_list.addEventListener('dragmove', function(e){ p.drag_move(e); });
*/
rcmail.file_list.addEventListener('dblclick', function(o){ kolab_files_list_dblclick(o); });
rcmail.file_list.addEventListener('select', function(o){ kolab_files_list_select(o); });
rcmail.file_list.addEventListener('dragend', function(e){ kolab_files_drag_end(e); });
rcmail.file_list.addEventListener('column_replace', function(e){ kolab_files_set_coltypes(e); });
rcmail.file_list.addEventListener('listupdate', function(e){ rcmail.triggerEvent('listupdate', e); });
rcmail.file_list.addEventListener('dblclick', function(o) { kolab_files_list_dblclick(o); })
.addEventListener('select', function(o) { kolab_files_list_select(o); })
.addEventListener('keypress', function(o) { kolab_files_list_keypress(o); })
.addEventListener('dragend', function(e) { kolab_files_drag_end(e); })
.addEventListener('column_replace', function(e) { kolab_files_set_coltypes(e); })
.addEventListener('listupdate', function(e) { rcmail.triggerEvent('listupdate', e); });
// document.onmouseup = function(e){ return p.doc_mouse_up(e); };
rcmail.gui_objects.filelist.parentNode.onmousedown = function(e){ return kolab_files_click_on_list(e); };
rcmail.gui_objects.filelist.parentNode.onmousedown = function(e) { return kolab_files_click_on_list(e); };
rcmail.enable_command('menu-open', 'menu-save', 'files-sort', 'files-search', 'files-search-reset', true);
rcmail.enable_command('menu-open', 'menu-save', 'files-sort', 'files-search', 'files-search-reset', 'folder-create', true);
rcmail.file_list.init();
kolab_files_list_coltypes();
@ -154,7 +153,7 @@ function kolab_files_token()
{
// consider the token from parent window more reliable (fresher) than in framed window
// it's because keep-alive is not requested in frames
return (window.parent && parent.rcmail && parent.rcmail.env.files_token) || rcmail.env.files_token;
return window.parent && parent.rcmail && parent.rcmail.env.files_token ? parent.rcmail.env.files_token : rcmail.env.files_token;
};
// folder selection dialog
@ -164,11 +163,20 @@ function kolab_directory_selector_dialog(id)
input = $('#file-save-as-input'),
form = $('#file-save-as'),
list = $('#folderlistbox'),
buttons = {}, label = 'saveto';
buttons = {}, label = 'saveto',
win = window, fn;
// attachment is specified
if (id) {
var attach = $('#attach'+id), filename = attach.attr('title') || attach.text();
var attach = $('#attach' + id + '> a').first(),
filename = attach.attr('title');
if (!filename) {
attach = attach.clone();
$('.attachment-size', attach).remove();
filename = attach.text();
}
form.show();
dialog.addClass('saveas');
input.val(filename);
@ -186,6 +194,8 @@ function kolab_directory_selector_dialog(id)
label = 'saveall';
}
$('#foldercreatelink').attr('tabindex', 0);
buttons[rcmail.gettext('kolab_files.save')] = function () {
var lock = rcmail.set_busy(true, 'saving'),
request = {
@ -201,12 +211,20 @@ function kolab_directory_selector_dialog(id)
}
rcmail.http_post('plugin.kolab_files', request, lock);
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
buttons[rcmail.gettext('kolab_files.cancel')] = function () {
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
if (!rcmail.env.folders_loaded) {
fn = function() {
file_api.folder_list();
rcmail.env.folders_loaded = true;
};
}
// show dialog window
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.' + label),
@ -215,11 +233,14 @@ function kolab_directory_selector_dialog(id)
minHeight: 300,
height: 350,
width: 300
});
}, fn);
if (!rcmail.env.folders_loaded) {
file_api.folder_list();
rcmail.env.folders_loaded = true;
// "enable" folder creation when dialog is displayed in parent window
if (rcmail.is_framed() && !parent.rcmail.folder_create) {
parent.rcmail.enable_command('folder-create', true);
parent.rcmail.folder_create = function() {
win.kolab_files_folder_create_dialog();
};
}
};
@ -234,7 +255,7 @@ function kolab_files_selector_dialog()
list.push($(this).data('file'));
});
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
if (list.length) {
// display upload indicator and cancel button
@ -252,8 +273,9 @@ function kolab_files_selector_dialog()
});
}
};
buttons[rcmail.gettext('kolab_files.cancel')] = function () {
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
// show dialog window
@ -270,8 +292,9 @@ function kolab_files_selector_dialog()
file_api.folder_list();
rcmail.env.files_loaded = true;
}
else
else {
rcmail.file_list.clear_selection();
}
};
function kolab_files_attach_menu_open(p)
@ -306,10 +329,11 @@ function kolab_files_folder_create_dialog()
folder += name;
file_api.folder_create(folder);
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
buttons[rcmail.gettext('kolab_files.cancel')] = function () {
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
// show dialog window
@ -358,10 +382,10 @@ function kolab_files_file_edit_dialog(file)
// @TODO: now we only update filename
if (name != file)
file_api.file_rename(file, name);
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
buttons[rcmail.gettext('kolab_files.cancel')] = function () {
dialog.dialog('destroy').hide();
kolab_dialog_close(this);
};
// Fix submitting form with Enter
@ -374,11 +398,11 @@ function kolab_files_file_edit_dialog(file)
});
};
function kolab_dialog_show(dialog, params)
function kolab_dialog_show(content, params, onopen)
{
params = $.extend({
modal: true,
resizable: !bw.ie6,
resizable: true,
closeOnEscape: (!bw.ie6 && !bw.ie7), // disabled for performance reasons
minWidth: 400,
minHeight: 300,
@ -386,7 +410,36 @@ function kolab_dialog_show(dialog, params)
height: 400
}, params || {});
dialog.dialog(params).show();
// dialog close handler
params.close = function(e, ui) {
var elem, stack = rcmail.dialog_stack;
content.appendTo(document.body).hide();
$(this).parent().remove(); // remove dialog
// focus previously focused element (guessed)
stack.pop();
if (stack.length) {
elem = stack[stack.length-1].find('input[type!="hidden"]:not(:hidden):first');
if (!elem.length)
elem = stack[stack.length-1].parent().find('button:first');
}
(elem && elem.length ? elem : window).focus();
};
// display it as popup
var dialog = rcmail.show_popup_dialog('', params.title, params.buttons, params);
content.appendTo(dialog).show().find('input[type!="hidden"]:not(:hidden):first').focus();
if (onopen) onopen(content);
// save dialog reference, to handle focus when closing one of opened dialogs
if (!rcmail.dialog_stack)
rcmail.dialog_stack = [];
rcmail.dialog_stack.push(dialog);
};
// Handle form submit with Enter key, click first dialog button instead
@ -396,6 +449,12 @@ function kolab_dialog_submit_handler()
return false;
};
// Hides dialog
function kolab_dialog_close(dialog)
{
(rcmail.is_framed() ? window.parent : window).$(dialog).dialog('close');
};
// smart upload button
function kolab_files_upload_input(button)
{
@ -407,7 +466,7 @@ function kolab_files_upload_input(button)
file.css({top: (e.pageY - offset.top - 10) + 'px', left: (e.pageX - offset.left - 10) + 'px'});
}
file.attr({name: 'file[]', type: 'file', multiple: 'multiple', size: 5, title: link.attr('title')})
file.attr({name: 'file[]', type: 'file', multiple: 'multiple', size: 5, title: link.attr('title'), tabindex: "-1"})
.change(function() { rcmail.files_upload('#filesuploadform'); })
.click(function() { setTimeout(function() { link.mouseleave(); }, 20); })
// opacity:0 does the trick, display/visibility doesn't work
@ -579,6 +638,17 @@ kolab_files_list_select = function(list)
rcmail.enable_command('files-open', rcmail.env.viewer);
};
kolab_files_list_keypress = function(list)
{
if (list.modkey == CONTROL_KEY)
return;
if (list.key_pressed == list.ENTER_KEY)
rcmail.command('files-open');
else if (list.key_pressed == list.DELETE_KEY || list.key_pressed == list.BACKSPACE_KEY)
rcmail.command('files-delete');
};
kolab_files_drag_end = function(e)
{
var folder = $('#files-folder-list li.droptarget').removeClass('droptarget');
@ -791,6 +861,11 @@ rcube_webmail.prototype.files_set_quota = function(p)
this.set_quota(p);
};
rcube_webmail.prototype.folder_create = function()
{
kolab_files_folder_create_dialog();
};
/**********************************************************/
/********* Files API handler **********/
@ -850,6 +925,12 @@ function kolab_files_ui()
list = $('<ul class="listing"></ul>'),
collections = !rcmail.env.action.match(/^(preview|show)$/) ? ['audio', 'video', 'image', 'document'] : [];
// try parent window if the list element does not exist
// i.e. called from dialog in parent window
if (!elem.length && window.parent && parent.rcmail) {
elem = $('#files-folder-list', window.parent.document.body);
}
elem.html('').append(list);
this.env.folders = this.folder_list_parse(response.result);
@ -868,7 +949,9 @@ function kolab_files_ui()
if (f.virtual)
row.addClass('virtual');
else
row.click(function() { file_api.folder_select(i); })
row.attr('tabindex', 0)
.keypress(function(e) { if (e.which == 13 || e.which == 32) file_api.folder_select(i); })
.click(function() { file_api.folder_select(i); })
.mouseenter(function() {
if (rcmail.file_list && rcmail.file_list.drag_active && !$(this).hasClass('selected'))
$(this).addClass('droptarget');
@ -888,7 +971,7 @@ function kolab_files_ui()
$.each(collections, function(i, n) {
var row = $('<li class="mailbox collection ' + n + '"></li>');
row.attr('id', 'folder-collection-' + n)
row.attr({id: 'folder-collection-' + n, tabindex: 0})
.append($('<span class="name"></span>').text(rcmail.gettext('kolab_files.collection_' + n)))
.click(function() { file_api.folder_select(n, true); });
@ -909,11 +992,17 @@ function kolab_files_ui()
this.folder_select = function(folder, is_collection)
{
var list = $('#files-folder-list > ul');
if (rcmail.busy)
return;
var list = $('#files-folder-list > ul');
// try parent window if the list element does not exist
// i.e. called from dialog in parent window
if (!list.length && window.parent && parent.rcmail) {
list = $('#files-folder-list > ul', window.parent.document.body);
}
$('li.selected', list).removeClass('selected');
rcmail.enable_command('files-list', true);

View file

@ -298,7 +298,7 @@ class kolab_files_engine
$thead = '';
foreach ($this->file_list_head($attrib, $a_show_cols) as $cell) {
$thead .= html::tag('td', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
$thead .= html::tag('th', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
}
return html::tag('table', $attrib,
@ -332,14 +332,21 @@ class kolab_files_engine
$a_sort_cols = $this->sort_cols;
if (!empty($attrib['optionsmenuicon'])) {
$onclick = 'return ' . JS_OBJECT_NAME . ".command('menu-open', 'filelistmenu')";
if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true')
$list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu',
'id' => 'listmenulink', 'title' => $this->rc->gettext('listoptions')));
else
$list_menu = html::a(array('href' => '#', 'onclick' => $onclick),
html::img(array('src' => $skin_path . $attrib['optionsmenuicon'],
'id' => 'listmenulink', 'title' => $this->rc->gettext('listoptions'))));
$onclick = 'return ' . JS_OBJECT_NAME . ".command('menu-open', 'filelistmenu', this, event)";
$inner = $this->rc->gettext('listoptions');
if (is_string($attrib['optionsmenuicon']) && $attrib['optionsmenuicon'] != 'true') {
$inner = html::img(array('src' => $skin_path . $attrib['optionsmenuicon'], 'alt' => $RCMAIL->gettext('listoptions')));
}
$list_menu = html::a(array(
'href' => '#list-options',
'onclick' => $onclick,
'class' => 'listmenu',
'id' => 'listmenulink',
'title' => $this->rc->gettext('listoptions'),
'tabindex' => '0',
), $inner);
}
else {
$list_menu = '';

View file

@ -1,6 +1,7 @@
<?php
$labels['files'] = 'Files';
$labels['filepreview'] = 'File preview';
$labels['saveall'] = 'Save all to cloud...';
$labels['saveto'] = 'Save to cloud...';
$labels['saveas'] = 'Save as:';
@ -67,4 +68,17 @@ $labels['fileoverwrite'] = 'Overwrite';
$labels['fileoverwriteall'] = 'Overwrite all';
$labels['filemoveconfirm'] = 'This action is going to overwrite the destination file: <b>$file</b>.';
$labels['arialabelsearchform'] = 'Files search form';
$labels['arialabelquicksearchbox'] = 'Search input';
$labels['arialabellistoptions'] = 'Files list options';
$labels['arialabelfolderoptions'] = 'Folder actions';
$labels['arialabelfileeditform'] = 'File editing form';
$labels['arialabelfoldercreateform'] = 'Folder creation form';
$labels['arialabelfolderlist'] = 'Folder/Collection selection';
$labels['arialabelfileselectdialog'] = 'File selection dialog';
$labels['arialabelattachmentoptions'] = 'Attachment save options';
$labels['arialabelfilesavedialog'] = 'File(s) saving dialog';
$labels['arialabelfileprops'] = 'File properties';
$labels['arialabelfilecontent'] = 'File content';
?>

View file

@ -53,7 +53,9 @@
}
#filestoolbar a.button.print {
background: url(../../../../skins/larry/images/buttons.png) center -810px no-repeat;
background-image: url(../../../../skins/larry/images/buttons.png);
background-position: center -810px;
background-repeat: no-repeat;
}
#filestoolbar form {
@ -152,7 +154,7 @@
color: #aaa;
}
.filelist thead tr td {
.filelist thead tr th {
padding: 0;
}
@ -161,50 +163,52 @@
height: 18px;
}
.filelist tr td.size {
.filelist tr > .size {
width: 80px;
text-align: right;
}
.filelist thead tr td.size {
.filelist thead tr > .size {
text-align: left;
}
.filelist tr td.mtime {
.filelist tr > .mtime {
width: 125px;
}
.filelist tr td.options {
width: 26px;
.filelist tr > .options {
width: 32px;
cursor: pointer;
}
.filelist thead tr td.filename,
.filelist thead tr th.filename,
.filelist tbody tr td.filename {
width: 99%;
white-space: nowrap;
}
.filelist thead tr td.sortedASC a,
.filelist thead tr td.sortedDESC a {
.filelist thead tr th.sortedASC a,
.filelist thead tr th.sortedDESC a {
color: #004458;
text-decoration: underline;
background: url(../../../../skins/larry/images/listicons.png) right -912px no-repeat;
background-image: url(../../../../skins/larry/images/listicons.png);
background-position: right -912px;
background-repeat: no-repeat;
}
.filelist thead tr td.sortedASC a {
.filelist thead tr th.sortedASC a {
background-position: right -944px;
}
.filelist td img {
.filelist img {
vertical-align: middle;
display: inline-block;
}
.filelist tr td.options div.listmenu,
.filelist tr td.flag span.flagged,
.filelist tr td.flag span.unflagged,
.filelist tr td.flag span.unflagged:hover {
.filelist tr > .options a.listmenu,
.filelist tr > .flag span.flagged,
.filelist tr > .flag span.unflagged,
.filelist tr > .flag span.unflagged:hover {
display: inline-block;
vertical-align: middle;
height: 18px;
@ -213,21 +217,26 @@
background: url(../../../../skins/larry/images/listicons.png) -100px 0 no-repeat;
}
.filelist thead tr td.options div.listmenu {
background-position: 0 -976px;
.filelist thead tr th.options {
padding: 0;
border-left: none;
}
.filelist thead tr th.options .listmenu {
background-position: 3px -970px;
cursor: pointer;
width: 26px;
width: 24px;
height: 20px;
padding: 4px 4px 5px;
text-indent: -5000px;
}
.filelist thead tr td.options {
padding: 0 3px;
.filelist thead tr th.options .listmenu:focus {
outline: none;
background-color: rgba(73,180,210,0.7);
}
.filelist thead tr td.options {
padding: 2px 3px;
}
.filelist thead tr td:first-child {
.filelist thead tr th:first-child {
border-radius: 4px 0 0 0;
}

View file

@ -1,21 +1,27 @@
<div id="files-compose-dialog" class="uidialog">
<div id="quicksearchbar" class="searchbox">
<div id="files-compose-dialog" class="uidialog" role="dialog" aria-labelledby="aria-label-fileselect" aria-hidden="true">
<h2 id="aria-label-fileselect" class="voice"><roundcube:label name="kolab_files.arialabelfileselectdialog" /></h2>
<div id="quicksearchbar" class="searchbox" role="search" aria-labelledby="aria-label-searchform">
<h3 id="aria-label-searchform" class="voice"><roundcube:label name="kolab_files.arialabelsearchform" /></h3>
<label for="quicksearchbox" class="voice"><roundcube:label name="arialabelquicksearchbox" /></label>
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="return UI.toggle_popup('filesearchmenu', event)" title="searchmod" label="options" aria-haspopup="true" aria-expanded="false" aria-owns="filesearchmenu-menu" />
<roundcube:object name="file-search-form" id="filesearchbox" />
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('filesearchmenu');return false" title="searchmod" content=" " />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
</div>
<div id="folderlistbox" class="uibox listbox">
<div id="folderlistbox" class="uibox listbox" role="navigation" aria-labelledby="aria-label-folderlist">
<h3 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h3>
<div id="files-folder-list" class="scroller"></div>
</div>
<div id="filelistcontainer" class="boxlistcontent uibox">
<roundcube:object name="filelist" id="filelist" class="records-table filelist sortheader fixedheader" />
<h3 id="aria-label-filelist" class="voice"><roundcube:label name="arialabelfilelist" /></h3>
<roundcube:object name="filelist" id="filelist" class="records-table filelist sortheader fixedheader" aria-labelledby="aria-label-filelist" />
</div>
</div>
<div id="filesearchmenu" class="popupmenu" style="z-index: 2000">
<ul class="toolbarmenu">
<li><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
<div id="filesearchmenu" class="popupmenu" style="z-index: 2000" data-editable="true" aria-hidden="true">
<h4 id="aria-label-searchmenu" class="voice"><roundcube:label name="searchmod" /></h4>
<ul id="filesearchmenu-menu" class="toolbarmenu" role="menu" aria-labelledby="aria-label-searchmenu">
<li role="menuitem"><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
</ul>
</div>

View file

@ -9,10 +9,12 @@
<roundcube:include file="/includes/header.html" />
<div id="mainscreen">
<div id="filestoolbar" class="toolbar">
<h1 class="voice"><roundcube:label name="kolab_files.filepreview" /></h1>
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
<div id="filestoolbar" class="toolbar" role="toolbar" aria-labelledby="aria-label-toolbar">
<roundcube:button command="files-get" type="link" class="button get disabled" classAct="button get" classSel="button get pressed" label="kolab_files.get" title="kolab_files.getfile" />
<roundcube:button command="files-edit" type="link" class="button edit disabled" classAct="button edit" classSel="button edit pressed" label="kolab_files.edit" title="kolab_files.editfile" />
<roundcube:button command="files-save" type="link" class="button save disabled" classAct="button save" classSel="button save pressed" label="kolab_files.save" title="kolab_files.savefile" style="display:none" />
@ -20,13 +22,14 @@
<roundcube:button command="files-print" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" title="kolab_files.printfile" />
</div>
<div id="fileinfobox" class="uibox listbox">
<h2 id="aria-label-fileprops" class="voice"><roundcube:label name="kolab_files.arialabelfileprops" /></h2>
<div id="fileinfobox" class="uibox listbox" aria-labelledby="aria-label-toolbar">
<roundcube:object name="fileinfobox" id="fileinfo" class="listing" />
</div>
<div id="filecontent" class="uibox">
<div class="iframebox">
<roundcube:object name="filepreviewframe" id="fileframe" frameborder="0" />
<roundcube:object name="filepreviewframe" id="fileframe" frameborder="0" title="kolab_files.arialabelfilecontent" />
</div>
</div>

View file

@ -11,7 +11,10 @@
<div id="mainscreen">
<div id="filestoolbar" class="toolbar">
<h1 class="voice"><roundcube:label name="kolab_files.files" /></h1>
<div id="filestoolbar" class="toolbar" role="toolbar" aria-labelledby="aria-label-toolbar">
<h2 id="aria-label-toolbar" class="voice"><roundcube:label name="arialabeltoolbar" /></h2>
<form id="filesuploadform">
<roundcube:button command="files-upload" type="link" class="button upload disabled" classAct="button upload" classSel="button upload pressed" label="kolab_files.upload" title="kolab_files.uploadfile" />
</form>
@ -20,50 +23,59 @@
<roundcube:button command="files-delete" type="link" class="button delete disabled" classAct="button delete" classSel="button delete pressed" label="delete" title="kolab_files.deletefile" />
</div>
<div id="quicksearchbar" class="quicksearchbox">
<div id="quicksearchbar" class="quicksearchbox" role="search" aria-labelledby="aria-label-searchform">
<h2 id="aria-label-searchform" class="voice"><roundcube:label name="kolab_files.arialabelsearchform" /></h2>
<label for="quicksearchbox" class="voice"><roundcube:label name="arialabelquicksearchbox" /></label>
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="return UI.toggle_popup('filesearchmenu', event)" title="searchmod" label="options" aria-haspopup="true" aria-expanded="false" aria-owns="filesearchmenu-menu" />
<roundcube:object name="file-search-form" id="quicksearchbox" />
<roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="UI.show_popup('filesearchmenu');return false" title="searchmod" content=" " />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" content=" " />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" label="resetsearch" />
</div>
<div id="folderlistbox" class="uibox listbox">
<div id="folderlistbox" class="uibox listbox" role="navigation" aria-labelledby="aria-label-folderlist">
<h2 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h2>
<div id="files-folder-list" class="scroller withfooter">
</div>
<div id="folderlist-footer" class="boxfooter">
<roundcube:button name="folder-create" type="link" title="kolab_files.foldercreate" class="listbutton add" classAct="listbutton add" innerClass="inner" content="+" onclick="kolab_files_folder_create_dialog()" /><roundcube:button name="folderoptions" id="folderoptionslink" type="link" title="moreactions" class="listbutton groupactions" onclick="UI.show_popup('folderoptions', undefined, {above: 1});return false" innerClass="inner" content="&#9881;" />
<roundcube:button command="folder-create" type="link" title="kolab_files.foldercreate" class="listbutton add" classAct="listbutton add" innerClass="inner" content="+" /><roundcube:button name="folderoptions" id="folderoptionslink" type="link" title="moreactions" class="listbutton groupactions" onclick="return UI.toggle_popup('folderoptions', event)" innerClass="inner" content="&#9881;" aria-haspopup="true" aria-expanded="false" aria-owns="folderoptionsmenu" />
<roundcube:if condition="env:files_quota" />
<span class="voice"><roundcube:label name="quota"></span>
<roundcube:object name="filequotadisplay" id="quotadisplay" class="countdisplay" display="text" />
<roundcube:endif />
</div>
</div>
<div id="filelistcontainer" class="uibox">
<h2 id="aria-label-filelist" class="voice"><roundcube:label name="arialabelfilelist" /></h2>
<div id="filelistbox" class="boxlistcontent">
<roundcube:object name="filelist" id="filelist" class="records-table filelist sortheader fixedheader" optionsmenuIcon="true" />
<roundcube:object name="filelist" id="filelist" class="records-table filelist sortheader fixedheader" optionsmenuIcon="true" aria-labelledby="aria-label-filelist" />
</div>
</div>
</div>
<div id="folderoptions" class="popupmenu">
<ul id="folderoptionsmenu" class="toolbarmenu">
<div id="folderoptions" class="popupmenu" data-editable="true" aria-hidden="true">
<h3 id="aria-label-folderoptions" class="voice"><roundcube:label name="kolab_files.folderoptions" /></h3>
<ul id="folderoptionsmenu" class="toolbarmenu" role="menu" aria-labelledby="aria-label-folderoptions">
<!--
<li><roundcube:button command="files-folder-edit" label="edit" classAct="active" /></li>
<li role="menuitem"><roundcube:button command="files-folder-edit" label="edit" classAct="active" /></li>
-->
<li><roundcube:button command="files-folder-delete" label="delete" classAct="active" /></li>
<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<li role="menuitem"><roundcube:button command="files-folder-delete" label="delete" classAct="active" /></li>
<li role="menuitem"><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="filesfolderoptions" id="folderoptionsmenu" />
</ul>
</div>
<div id="files-folder-create-dialog">
<div id="files-folder-create-dialog" role="dialog" aria-labelledby="aria-label-foldercreateform" aria-hidden="true">
<h3 id="aria-label-foldercreateform" class="voice"><roundcube:label name="kolab_files.arialabelfoldercreateform" /></h3>
<roundcube:object name="folder-create-form" />
</div>
<div id="files-file-edit-dialog">
<div id="files-file-edit-dialog" role="dialog" aria-labelledby="aria-label-fileeditform" aria-hidden="true">
<h3 id="aria-label-fileeditform" class="voice"><roundcube:label name="kolab_files.arialabelfileeditform" /></h3>
<roundcube:object name="file-edit-form" />
</div>
<div id="listoptions" class="propform popupdialog">
<div id="listoptions" class="propform popupdialog" data-editable="true" role="dialog" aria-labelledby="aria-label-listoptions" aria-hidden="true">
<h3 id="aria-label-listoptions" class="voice"><roundcube:label name="kolab_files.arialabellistoptions" /></h3>
<roundcube:if condition="!in_array('kolab_files_list_cols', (array)config:dont_override)" />
<fieldset class="floating">
<legend><roundcube:label name="listcolumns" /></legend>
@ -97,20 +109,21 @@
<br style="clear:both" />
<div class="formbuttons">
<roundcube:button command="menu-save" id="listmenusave" type="input" class="button mainaction" label="save" />
<roundcube:button command="menu-open" id="listmenucancel" type="input" class="button" label="cancel" />
<roundcube:button command="menu-close" prop="filelistmenu" id="listmenucancel" type="input" class="button" label="cancel" />
</div>
</div>
<div id="dragfilemenu" class="popupmenu">
<ul class="toolbarmenu">
<li><roundcube:button command="files-move" onclick="return kolab_files_drag_menu_action('files-move')" label="move" classAct="active" /></li>
<li><roundcube:button command="files-copy" onclick="return kolab_files_drag_menu_action('files-copy')" label="copy" classAct="active" /></li>
<div id="dragfilemenu" class="popupmenu" aria-hidden="true">
<ul class="toolbarmenu" role="menu">
<li role="menuitem"><roundcube:button command="files-move" onclick="return kolab_files_drag_menu_action('files-move')" label="move" classAct="active" /></li>
<li role="menuitem"><roundcube:button command="files-copy" onclick="return kolab_files_drag_menu_action('files-copy')" label="copy" classAct="active" /></li>
</ul>
</div>
<div id="filesearchmenu" class="popupmenu">
<ul class="toolbarmenu">
<li><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
<div id="filesearchmenu" class="popupmenu" data-editable="true" aria-hidden="true">
<h3 id="aria-label-searchmenu" class="voice"><roundcube:label name="searchmod" /></h3>
<ul id="filesearchmenu-menu" class="toolbarmenu" role="menu" aria-labelledby="aria-label-searchmenu">
<li role="menuitem"><label><input type="checkbox" name="all_folders" value="1" id="search_all_folders" /> <span><roundcube:label name="kolab_files.allfolders" /></span></label></li>
</ul>
</div>

View file

@ -1,16 +1,21 @@
<div id="files-dialog" class="uidialog">
<div id="files-dialog" class="uidialog" data-editable="true" role="dialog" aria-labelledby="aria-label-filesavedialog" aria-hidden="true">
<h3 id="aria-label-filesavedialog" class="voice"><roundcube:label name="kolab_files.arialabelfilesavedialog" /></h3>
<div id="file-save-as">
<label for="file-save-as-input"><roundcube:label name="kolab_files.saveas" /></label>
<input id="file-save-as-input" type="text" value="">
</div>
<div id="folderlistbox" class="uibox listbox">
<div id="folderlistbox" class="uibox listbox" role="navigation" aria-labelledby="aria-label-folderlist">
<h3 id="aria-label-folderlist" class="voice"><roundcube:label name="kolab_files.arialabelfolderlist" /></h3>
<div id="files-folder-list" class="scroller withfooter"></div>
<div id="folderlist-footer" class="boxfooter">
<roundcube:button name="foldercreatelink" id="foldercreatelink" type="link" onclick="kolab_files_folder_create_dialog()" title="createfolder" class="listbutton add" classAct="listbutton add" innerClass="inner" content="+" />
<roundcube:button command="folder-create" name="foldercreatelink" id="foldercreatelink" type="link" title="createfolder" class="listbutton add" classAct="listbutton add" innerClass="inner" content="+" />
</div>
</div>
</div>
<div id="files-folder-create-dialog">
<div id="files-folder-create-dialog" role="dialog" aria-labelledby="aria-label-foldercreateform" aria-hidden="true">
<h3 id="aria-label-foldercreateform" class="voice"><roundcube:label name="kolab_files.arialabelfoldercreateform" /></h3>
<roundcube:object name="folder-create-form" />
</div>
<script src="plugins/kolab_files/skins/larry/ui.js" type="text/javascript"></script>

View file

@ -13,6 +13,7 @@ function kolab_files_ui_init()
$(document).ready(function() {
rcmail.addEventListener('menu-open', kolab_files_show_listoptions);
rcmail.addEventListener('menu-save', kolab_files_save_listoptions);
rcmail.addEventListener('menu-close', kolab_files_show_listoptions);
rcmail.addEventListener('setquota', kolab_files_update_quota);
var menu = $('#dragfilemenu');
@ -24,7 +25,6 @@ function kolab_files_ui_init()
menu = $('#filesearchmenu');
if (menu.length) {
rcmail.gui_object('file_searchmenu', 'filesearchmenu');
UI.add_popup('filesearchmenu', {sticky: 1});
}
});
@ -45,8 +45,12 @@ function kolab_files_update_quota(p)
return UI.update_quota(p);
};
function kolab_files_show_listoptions()
function kolab_files_show_listoptions(p)
{
if (!p || p.name != 'filelistmenu') {
return;
}
var $dialog = $('#listoptions');
// close the dialog
@ -69,10 +73,8 @@ function kolab_files_show_listoptions()
modal: true,
resizable: false,
closeOnEscape: true,
close: function() { rcmail.file_list.focus(); },
title: null,
close: function() {
$dialog.dialog('destroy').hide();
},
minWidth: 400,
width: $dialog.width()+20
}).show();