From 9a5d9a83ab10b89437f05c8d0b6a83e429792451 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Wed, 29 Apr 2015 02:24:03 -0400 Subject: [PATCH] Implemented UI element to jump to specified page of the messages list (#1485235) --- skins/larry/templates/mail.html | 1 CHANGELOG | 1 skins/classic/templates/mail.html | 3 skins/classic/functions.js | 2 skins/classic/common.css | 32 ++++++++++ skins/larry/styles.css | 20 ++++++ program/js/app.js | 87 +++++++++++++++++++++++++++++ skins/larry/ui.js | 2 8 files changed, 146 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0a24125..48c69c7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -7,6 +7,7 @@ - Plugin API: Added message_part_body hook - Plugin API: Added message_ready hook - Plugin API: Add special onload() method to execute plugin actions before startup (session and GUI initialization) +- Implemented UI element to jump to specified page of the messages list (#1485235) - Add option to place signature at bottom of the quoted text even in top-posting mode [sig_below] - Fix handling of %-encoded entities in mailto: URLs (#1490346) - Fix zipped messages downloads after selecting all messages in a folder (#1490339) diff --git a/program/js/app.js b/program/js/app.js index b4b125f..295a511 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -3255,6 +3255,91 @@ this.set_alttext('delete', label); }; + // Initialize input element for list page jump + this.init_pagejumper = function(element) + { + $(element).addClass('rcpagejumper') + .on('focus', function(e) { + // create and display popup with page selection + var i, html = ''; + + for (i = 1; i <= ref.env.pagecount; i++) + html += '<li>' + i + '</li>'; + + html = '<ul class="toolbarmenu">' + html + '</ul>'; + + if (!ref.pagejump) { + ref.pagejump = $('<div id="pagejump-selector" class="popupmenu"></div>') + .appendTo(document.body) + .on('click', 'li', function() { + if (!ref.busy) + $(element).val($(this).text()).change(); + }); + } + + if (ref.pagejump.data('count') != i) + ref.pagejump.html(html); + + ref.pagejump.attr('rel', '#' + this.id).data('count', i); + + // display page selector + ref.show_menu('pagejump-selector', true, e); + $(this).keydown(); + }) + // keyboard navigation + .on('keydown keyup', function(e) { + var current, selector = $('#pagejump-selector'), + ul = $('ul', selector), + list = $('li', ul), + height = ul.height(), + p = parseInt(this.value); + + if (e.type == 'keydown') { + // arrow-down + if (e.which == 40) { + if (!selector.is(':visible')) + return ref.show_menu('pagejump-selector', true, e); + + if (list.length > p) + this.value = (p += 1); + } + // arrow-up + else if (e.which == 38) { + if (!selector.is(':visible')) + return ref.show_menu('pagejump-selector', true, e); + + if (p > 1 && list.length > p - 1) + this.value = (p -= 1); + } + // enter + else if (e.which == 13) { + return $(this).change(); + } + } + + $('li.selected', ul).removeClass('selected'); + + if ((current = $(list[p - 1])).length) { + current.addClass('selected'); + $('#pagejump-selector').scrollTop(((ul.height() / list.length) * (p - 1)) - selector.height() / 2); + } + }) + .on('change', function(e) { + // go to specified page + var p = parseInt(this.value); + if (p && p != ref.env.current_page && !ref.busy) { + ref.hide_menu('pagejump-selector'); + ref.list_page(p); + } + }); + }; + + // Update page-jumper state on list updates + this.update_pagejumper = function() + { + $('input.rcpagejumper').val(this.env.current_page).prop('disabled', this.env.pagecount < 2); + }; + /*********************************************************/ /********* mailbox folders methods *********/ /*********************************************************/ @@ -6673,6 +6758,8 @@ { this.enable_command('nextpage', 'lastpage', this.env.pagecount > this.env.current_page); this.enable_command('previouspage', 'firstpage', this.env.current_page > 1); + + this.update_pagejumper(); }; // mark a mailbox as selected and set environment variable diff --git a/skins/classic/common.css b/skins/classic/common.css index 6d5a333..e97c30d 100644 --- a/skins/classic/common.css +++ b/skins/classic/common.css @@ -481,6 +481,22 @@ background-position: -33px -11px; } +#rcmcountdisplay +{ + float: left; + margin-right: 10px; +} + +#countcontrols #pagejumper +{ + margin: 0 5px; + float: right; + text-align: center; + padding: 0; + cursor: default; + font-size: 10px; +} + .splitter { user-select: none; @@ -1120,7 +1136,8 @@ cursor: pointer; } -#rcmKSearchpane ul li.selected +#rcmKSearchpane ul li.selected, +#pagejump-selector ul li.selected { color: #ffffff; background-color: #CC3333; @@ -1279,6 +1296,19 @@ color: #999; } +#pagejump-selector +{ + max-height: 250px; + overflow-x: hidden; +} + +#pagejump-selector ul li +{ + min-width: 45px; + padding: 2px 5px; + cursor: default; +} + /*** folder selector ***/ diff --git a/skins/classic/functions.js b/skins/classic/functions.js index 5a5ad39..9227001 100644 --- a/skins/classic/functions.js +++ b/skins/classic/functions.js @@ -1027,6 +1027,8 @@ .addEventListener('afterimport-messages', function(){ rcmail_ui.show_popup('uploadform', false); }); } + rcmail.init_pagejumper('#pagejumper'); + // fix message list header on window resize (#1490213) if (bw.ie && rcmail.message_list) $(window).resize(function() { diff --git a/skins/classic/templates/mail.html b/skins/classic/templates/mail.html index 7f1e1b8..b7af014 100644 --- a/skins/classic/templates/mail.html +++ b/skins/classic/templates/mail.html @@ -79,9 +79,10 @@ <roundcube:endif /> </div> <div id="countcontrols" class="pagenav"> + <roundcube:object name="messageCountDisplay" /> <roundcube:button command="lastpage" type="link" class="buttonPas lastpage" classAct="button lastpage" classSel="button lastpageSel" title="lastpage" content=" " /> <roundcube:button command="nextpage" type="link" class="buttonPas nextpage" classAct="button nextpage" classSel="button nextpageSel" title="nextpage" content=" " /> - <roundcube:object name="messageCountDisplay" style="padding:0 .5em; float:right" /> + <input id="pagejumper" class="pagejumper" type="text" size="3" disabled="disabled" title="<roundcube:label name="currpage" />" /> <roundcube:button command="previouspage" type="link" class="buttonPas prevpage" classAct="button prevpage" classSel="button prevpageSel" title="previouspage" content=" " /> <roundcube:button command="firstpage" type="link" class="buttonPas firstpage" classAct="button firstpage" classSel="button firstpageSel" title="firstpage" content=" " /> </div> diff --git a/skins/larry/styles.css b/skins/larry/styles.css index 2f3cefd..327fd37 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -430,6 +430,14 @@ top: -2px; } +.pagenav .pagejumper { + text-align: center; + background: #f8f8f8; + padding: 3px 0; + background: linear-gradient(to bottom, #dddddd 0%, #f8f8f8 100%); + cursor: default; +} + a.iconbutton { display: inline-block; width: 20px; @@ -2340,6 +2348,7 @@ ul.toolbarmenu li a.active:hover, ul.toolbarmenu li a.active:focus, #rcmKSearchpane ul li.selected, +#pagejump-selector ul li.selected, select.decorated option:hover, select.decorated option[selected='selected'] { background-color: #00aad6; @@ -2457,6 +2466,17 @@ background-position: 0 -2150px; } +#pagejump-selector { + max-height: 250px; + overflow-x: hidden; +} + +#pagejump-selector ul li { + min-width: 45px; + padding: 2px 5px; + cursor: default; +} + #snippetslist { max-width: 200px; } diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html index 2c4e0f2..bda3efb 100644 --- a/skins/larry/templates/mail.html +++ b/skins/larry/templates/mail.html @@ -128,6 +128,7 @@ <span class="pagenavbuttons"> <roundcube:button command="firstpage" type="link" class="button firstpage disabled" classAct="button firstpage" classSel="button firstpage pressed" innerClass="inner" title="firstpage" label="first" /> <roundcube:button command="previouspage" type="link" class="button prevpage disabled" classAct="button prevpage" classSel="button prevpage pressed" innerClass="inner" title="previouspage" label="previous" /> + <input id="pagejumper" class="pagejumper" type="text" size="3" disabled="disabled" title="<roundcube:label name="currpage" />" /> <roundcube:button command="nextpage" type="link" class="button nextpage disabled" classAct="button nextpage" classSel="button nextpage pressed" innerClass="inner" title="nextpage" label="next" /> <roundcube:button command="lastpage" type="link" class="button lastpage disabled" classAct="button lastpage" classSel="button lastpage pressed" innerClass="inner" title="lastpage" label="last" /> </span> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index a1c00eb..95efccf 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -231,6 +231,8 @@ if (previewframe) mailviewsplit.init(); + rcmail.init_pagejumper('#pagejumper'); + rcmail.addEventListener('setquota', update_quota) .addEventListener('enable-command', enable_command) .addEventListener('afterimport-messages', show_uploadform); -- Gitblit v1.9.1