diff options
-rw-r--r-- | CHANGELOG | 1 | ||||
-rw-r--r-- | program/js/app.js | 4 | ||||
-rw-r--r-- | program/js/treelist.js | 3 | ||||
-rw-r--r-- | program/localization/en_US/labels.inc | 24 | ||||
-rw-r--r-- | skins/classic/common.css | 19 | ||||
-rw-r--r-- | skins/classic/functions.js | 35 | ||||
-rw-r--r-- | skins/classic/settings.css | 10 | ||||
-rw-r--r-- | skins/classic/templates/folders.html | 12 | ||||
-rw-r--r-- | skins/larry/settings.css | 13 | ||||
-rw-r--r-- | skins/larry/styles.css | 1 | ||||
-rw-r--r-- | skins/larry/templates/folders.html | 14 | ||||
-rw-r--r-- | skins/larry/ui.js | 32 |
12 files changed, 154 insertions, 14 deletions
@@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Added folder searching in Folder Manager - Added config option 'imap_log_session' to enable Roundcube <-> IMAP session ID logging - Added config option 'log_session_id' to control the lengh of the session identifer in logs - Implemented 'storage_connected' API hook after successful IMAP login (#1490025) diff --git a/program/js/app.js b/program/js/app.js index 8ac5ca2e9..346c4f75d 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -5743,13 +5743,15 @@ function rcube_webmail() selectable: true, id_prefix: 'rcmli', id_encode: this.html_identifier_encode, - id_decode: this.html_identifier_decode + id_decode: this.html_identifier_decode, + searchbox: '#foldersearch' }); this.subscription_list .addEventListener('select', function(node) { ref.subscription_select(node.id); }) .addEventListener('collapse', function(node) { ref.folder_collapsed(node) }) .addEventListener('expand', function(node) { ref.folder_collapsed(node) }) + .addEventListener('search', function(p) { if (p.query) ref.subscription_select(); }) .draggable({cancel: 'li.mailbox.root'}) .droppable({ // @todo: find better way, accept callback is executed for every folder diff --git a/program/js/treelist.js b/program/js/treelist.js index 916cf0e2d..7d13143cd 100644 --- a/program/js/treelist.js +++ b/program/js/treelist.js @@ -525,7 +525,8 @@ function rcube_treelist_widget(node, p) .attr('id', li.attr('id') + '--xsR') .attr('class', li.attr('class')) .addClass('searchresult__') - .append(li.children().first().clone(true, true)) + // append all elements like links and inputs, but not sub-trees + .append(li.children(':not(div.treetoggle,ul)').clone(true, true)) .appendTo(container); hits.push(node.id); } diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index 1e179cbcf..e3fe76b2b 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -528,14 +528,14 @@ $labels['replyallmode'] = 'Default action of [Reply all] button'; $labels['replyalldefault'] = 'reply to all'; $labels['replyalllist'] = 'reply to mailing list only (if found)'; -$labels['folder'] = 'Folder'; -$labels['folders'] = 'Folders'; -$labels['foldername'] = 'Folder name'; -$labels['subscribed'] = 'Subscribed'; +$labels['folder'] = 'Folder'; +$labels['folders'] = 'Folders'; +$labels['foldername'] = 'Folder name'; +$labels['subscribed'] = 'Subscribed'; $labels['messagecount'] = 'Messages'; -$labels['create'] = 'Create'; -$labels['createfolder'] = 'Create new folder'; -$labels['managefolders'] = 'Manage folders'; +$labels['create'] = 'Create'; +$labels['createfolder'] = 'Create new folder'; +$labels['managefolders'] = 'Manage folders'; $labels['specialfolders'] = 'Special Folders'; $labels['properties'] = 'Properties'; $labels['folderproperties'] = 'Folder properties'; @@ -545,9 +545,10 @@ $labels['info'] = 'Information'; $labels['getfoldersize'] = 'Click to get folder size'; $labels['changesubscription'] = 'Click to change subscription'; $labels['foldertype'] = 'Folder Type'; -$labels['personalfolder'] = 'Private Folder'; -$labels['otherfolder'] = 'Other User\'s Folder'; -$labels['sharedfolder'] = 'Public Folder'; +$labels['personalfolder'] = 'Private Folder'; +$labels['otherfolder'] = 'Other User\'s Folder'; +$labels['sharedfolder'] = 'Public Folder'; +$labels['findfolders'] = 'Find folders'; $labels['sortby'] = 'Sort by'; $labels['sortasc'] = 'Sort ascending'; @@ -597,6 +598,8 @@ $labels['arialabelmailsearchform'] = 'Email message search form'; $labels['arialabelcontactsearchform'] = 'Contacts search form'; $labels['arialabelmailquicksearchbox'] = 'Email search input'; $labels['arialabelquicksearchbox'] = 'Search input'; +$labels['arialabelfoldersearchfilter'] = 'Folder listing filter'; +$labels['arialabelfoldersearchform'] = 'Folder search form'; $labels['arialabelfolderlist'] = 'Email folder selection'; $labels['arialabelmessagelist'] = 'Email Messages Listing'; $labels['arialabelmailpreviewframe'] = 'Message preview'; @@ -625,6 +628,7 @@ $labels['arialabelabookgroupoptions'] = 'Addressbook/group options'; $labels['arialabelpreferencesform'] = 'Preferences form'; $labels['arialabelidentityeditfrom'] = 'Identity edit form'; $labels['arialabelresonseeditfrom'] = 'Response edit form'; +$labels['arialabelsearchterms'] = 'Search terms'; $labels['helplistnavigation'] = 'List keyboard navigation'; $labels['helplistkeyboardnavigation'] = "Arrows up/down: Move row focus/selection. diff --git a/skins/classic/common.css b/skins/classic/common.css index 74de5e407..1edc1fa16 100644 --- a/skins/classic/common.css +++ b/skins/classic/common.css @@ -1010,6 +1010,25 @@ div.searchbox > input width: 97%; } +.listsearchbox +{ + border-bottom: solid 1px #ddd; + padding: 2px 4px 1px; + display: none; + background-color: #f2f2f2; +} + +.listsearchbox a.iconbutton.reset +{ + background: url(images/icons/reset.gif) no-repeat 0 0; + width: 13px; + height: 13px; + text-indent: 50000px; + position: absolute; + top: 3px; + left: 165px; + overflow: hidden; +} /***** roundcube webmail pre-defined classes *****/ diff --git a/skins/classic/functions.js b/skins/classic/functions.js index b521be3bb..f17f393c2 100644 --- a/skins/classic/functions.js +++ b/skins/classic/functions.js @@ -636,6 +636,36 @@ enable_command: function(p) var label = rcmail.gettext(p.status ? 'replylist' : 'replyall'); $('a.button.replyAll').attr('title', label); } +}, + +folder_search_init: function(container) +{ + // animation to unfold list search box + $('.boxtitle a.search', container).click(function(e) { + var title = $('.boxtitle', container), + box = $('.listsearchbox', container), + dir = box.is(':visible') ? -1 : 1; + + box.slideToggle({ + duration: 160, + progress: function(animation, progress) { + if (dir < 0) progress = 1 - progress; + $('.boxlistcontent', container).css('top', (title.outerHeight() + 24 * progress) + 'px'); + }, + complete: function() { + box.toggleClass('expanded'); + if (box.is(':visible')) { + box.find('input[type=text]').focus(); + } + else { + $('a.reset', box).click(); + } + // TODO: save state in cookie + } + }); + + return false; + }); } }; @@ -1012,5 +1042,10 @@ function rcube_init_mail_ui() rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); }) .gui_object('dragmenu', 'dragmenu'); } + else if (rcmail.env.task == 'settings') { + if (rcmail.env.action == 'folders') { + rcmail_ui.folder_search_init($('#folder-manager')); + } + } }); } diff --git a/skins/classic/settings.css b/skins/classic/settings.css index fb4303f2b..cd250d57e 100644 --- a/skins/classic/settings.css +++ b/skins/classic/settings.css @@ -11,6 +11,16 @@ background-color: #FFFFA6; } +#folderlist-title a.iconbutton.search { + background: url(images/icons/glass.png) no-repeat 0 0; + cursor: pointer; + position: absolute; + right: 4px; + top: 2px; + width: 16px; + text-indent: 50000px; +} + #identities-table, #sections-table { diff --git a/skins/classic/templates/folders.html b/skins/classic/templates/folders.html index 7ca4ac49f..8ed0b5fdc 100644 --- a/skins/classic/templates/folders.html +++ b/skins/classic/templates/folders.html @@ -19,7 +19,17 @@ <div id="mainscreen"> <div id="folder-manager"> -<div id="folderlist-title" class="boxtitle"><span class="rightalign"><roundcube:label name="subscribed" /></span><roundcube:label name="folders" /></div> +<div id="folderlist-title" class="boxtitle"> + <roundcube:label name="folders" /> + <a href="#folders" class="iconbutton search" title="<roundcube:label name='findfolders' />" tabindex="0"><roundcube:label name='findfolders' /></a> +</div> +<div class="listsearchbox"> + <div class="searchbox" role="search"> + <input type="text" name="q" id="foldersearch" placeholder="<roundcube:label name='findfolders' />" /> + <a class="iconbutton searchicon"></a> + <roundcube:button command="reset-foldersearch" id="folderlistsearch-reset" class="iconbutton reset" title="resetsearch" width="13" height="13" /> + </div> +</div> <div id="folderlist-content" class="boxlistcontent"> <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table" summary="Folder subscription table" class="treelist folderlist" /> diff --git a/skins/larry/settings.css b/skins/larry/settings.css index b5b05c235..cda47b631 100644 --- a/skins/larry/settings.css +++ b/skins/larry/settings.css @@ -211,6 +211,19 @@ background-position: 4px -550px; } +#folderslist .boxtitle a.iconbutton.search { + background-position: -2px -317px; + cursor: pointer; + position: absolute; + right: 8px; + top: 8px; + width: 16px; +} + +#folderslist .listsearchbox + .scroller { + top: 34px; +} + #folderslist, #identitieslist { position: absolute; diff --git a/skins/larry/styles.css b/skins/larry/styles.css index 529eb199d..456ce4924 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -1959,6 +1959,7 @@ ul.proplist li { position: relative; padding: 4px; background: #c7e3ef; + display: none; } .listsearchbox input { diff --git a/skins/larry/templates/folders.html b/skins/larry/templates/folders.html index f48169cd4..3d016cad1 100644 --- a/skins/larry/templates/folders.html +++ b/skins/larry/templates/folders.html @@ -17,7 +17,19 @@ <div id="settings-right" role="main"> <div id="folderslist" class="uibox listbox"> -<h2 id="folderslist-header" class="boxtitle"><span style="float:right"><roundcube:label name="subscribed" /></span><roundcube:label name="folders" /></h2> +<h2 id="folderslist-header" class="boxtitle"> + <roundcube:label name="folders" /> + <a href="#folders" class="iconbutton search" title="<roundcube:label name='findfolders' />" tabindex="0"><roundcube:label name='findfolders' /></a> +</h2> +<div class="listsearchbox"> + <div class="searchbox" role="search" aria-labelledby="aria-label-foldersearchform"> + <h3 id="aria-label-foldersearchform" class="voice"><roundcube:label name="arialabelfoldersearchform" /></h3> + <label for="foldersearch" class="voice"><roundcube:label name="arialabelsearchterms" /></label> + <input type="text" name="q" id="foldersearch" placeholder="<roundcube:label name='findfolders' />" /> + <a class="iconbutton searchicon"></a> + <roundcube:button command="reset-foldersearch" id="folderlistsearch-reset" class="iconbutton reset" title="resetsearch" label="resetsearch" /> + </div> +</div> <div id="folderslist-content" class="scroller withfooter"> <roundcube:object name="foldersubscription" form="subscriptionform" id="subscription-table" class="treelist listing folderlist" /> </div> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index f6c390929..1eb8e899a 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -47,6 +47,7 @@ function rcube_mail_ui() this.update_quota = update_quota; this.get_pref = get_pref; this.save_pref = save_pref; + this.folder_search_init = folder_search_init; // set minimal mode on small screens (don't wait for document.ready) @@ -255,6 +256,8 @@ function rcube_mail_ui() orientation:'v', relative:true, start:266, min:180, size:12 }).init(); rcmail.addEventListener('setquota', update_quota); + + folder_search_init($('#folderslist')); } else if (rcmail.env.action == 'identities') { new rcube_splitter({ id:'identviewsplitter', p1:'#identitieslist', p2:'#identity-details', @@ -531,6 +534,35 @@ function rcube_mail_ui() } } + function folder_search_init(container) + { + // animation to unfold list search box + $('.boxtitle a.search', container).click(function(e) { + var title = $('.boxtitle', container), + box = $('.listsearchbox', container), + dir = box.is(':visible') ? -1 : 1; + + box.slideToggle({ + duration: 160, + progress: function(animation, progress) { + if (dir < 0) progress = 1 - progress; + $('.scroller', container).css('top', (title.outerHeight() + 34 * progress) + 'px'); + }, + complete: function() { + box.toggleClass('expanded'); + if (box.is(':visible')) { + box.find('input[type=text]').focus(); + } + else { + $('a.reset', box).click(); + } + // TODO: save state in localStorage + } + }); + + return false; + }); + } function enable_command(p) { |