diff options
author | krb <krb@chromium.org> | 2016-02-25 08:27:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-25 16:28:42 +0000 |
commit | d62c24312fed4aeba5e4412a8f2bd3a83ad55b05 (patch) | |
tree | 48163ec398c897016043a5c55493647dc4a17564 | |
parent | 7dc852fd17cd4ee23e392d99e392a5c4eee7eea3 (diff) | |
download | chromium_src-d62c24312fed4aeba5e4412a8f2bd3a83ad55b05.zip chromium_src-d62c24312fed4aeba5e4412a8f2bd3a83ad55b05.tar.gz chromium_src-d62c24312fed4aeba5e4412a8f2bd3a83ad55b05.tar.bz2 |
Print preview: Distinguish between errors in page range input
Inform the user whether they entered unclear, unparsable
input or whether a page referenced was too large, and what
the limit is.
BUG=467930
Review URL: https://codereview.chromium.org/1713733003
Cr-Commit-Position: refs/heads/master@{#377585}
6 files changed, 93 insertions, 32 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index e0d7556..fdc84b3 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -8339,9 +8339,15 @@ I don't think this site should be blocked! Print using system dialog... <ph name="SHORTCUT_KEY">$1<ex>(Shift+Ctrl+P)</ex></ph> </message> </if> - <message name="IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION" desc="Instruction shown when the user enters an invalid page range."> + <message name="IDS_PRINT_PREVIEW_PAGE_RANGE_SYNTAX_INSTRUCTION" desc="Instruction shown when the user enters an invalid page range."> Invalid page range, use <ph name="EXAMPLE_PAGE_RANGE">$1<ex>e.g. 1-5, 8, 11-13</ex></ph> </message> + <message name="IDS_PRINT_PREVIEW_PAGE_RANGE_LIMIT_INSTRUCTION" desc="Instruction shown when the user enters an excessive page range."> + Out of bounds page reference + </message> + <message name="IDS_PRINT_PREVIEW_PAGE_RANGE_LIMIT_INSTRUCTION_WITH_VALUE" desc="Instruction shown when the user enters an excessive page number, and the maximum page."> + Out of bounds page reference, limit is <ph name="MAXIMUM_PAGE">$1<ex>1</ex></ph> + </message> <message name="IDS_PRINT_PREVIEW_COPIES_INSTRUCTION" desc="Instruction shown when the user enters an invalid number of copies."> Use a number to indicate how many copies to print (1 or more). </message> diff --git a/chrome/browser/resources/print_preview/data/ticket_items/page_range.js b/chrome/browser/resources/print_preview/data/ticket_items/page_range.js index bbb3f82..db20e71 100644 --- a/chrome/browser/resources/print_preview/data/ticket_items/page_range.js +++ b/chrome/browser/resources/print_preview/data/ticket_items/page_range.js @@ -35,8 +35,9 @@ cr.define('print_preview.ticket_items', function() { /** @override */ wouldValueBeValid: function(value) { - return null != pageRangeTextToPageRanges( + var result = pageRangeTextToPageRanges( value, this.getDocumentInfoInternal().pageCount); + return result instanceof Array; }, /** @@ -69,7 +70,8 @@ cr.define('print_preview.ticket_items', function() { * ranges. */ getPageRanges: function() { - return pageRangeTextToPageRanges(this.getValue()) || []; + var pageRanges = pageRangeTextToPageRanges(this.getValue()); + return pageRanges instanceof Array ? pageRanges : []; }, /** @@ -81,7 +83,24 @@ cr.define('print_preview.ticket_items', function() { getDocumentPageRanges: function() { var pageRanges = pageRangeTextToPageRanges( this.getValue(), this.getDocumentInfoInternal().pageCount); - return pageRanges || []; + return pageRanges instanceof Array ? pageRanges : []; + }, + + /** + * @return {!number} Number of pages reported by the document. + */ + getDocumentNumPages: function() { + return this.getDocumentInfoInternal().pageCount; + }, + + /** + * @return {!PageRangeStatus} + */ + checkValidity: function() { + var pageRanges = pageRangeTextToPageRanges( + this.getValue(), this.getDocumentInfoInternal().pageCount); + return pageRanges instanceof Array ? + PageRangeStatus.NO_ERROR : pageRanges; }, }; diff --git a/chrome/browser/resources/print_preview/print_preview_utils.js b/chrome/browser/resources/print_preview/print_preview_utils.js index 0cacb70..2ab83dc 100644 --- a/chrome/browser/resources/print_preview/print_preview_utils.js +++ b/chrome/browser/resources/print_preview/print_preview_utils.js @@ -72,16 +72,25 @@ function removeDuplicates(inArray) { return out; } +/** @enum {number} */ +var PageRangeStatus = { + NO_ERROR: 0, + SYNTAX_ERROR: -1, + LIMIT_ERROR: -2 +}; + /** * Returns a list of ranges in |pageRangeText|. The ranges are * listed in the order they appear in |pageRangeText| and duplicates are not - * eliminated. If |pageRangeText| is not valid null is returned. + * eliminated. If |pageRangeText| is not valid, PageRangeStatus.SYNTAX_ERROR + * is returned. * A valid selection has a parsable format and every page identifier is - * greater the 0 and less or equal to |totalPageCount| unless wildcards are - * used(see examples). + * greater than 0 unless wildcards are used(see examples). + * If a page is greater than |totalPageCount|, PageRangeStatus.LIMIT_ERROR + * is returned. * If |totalPageCount| is 0 or undefined function uses impossibly large number * instead. - * Wildcard the first number must be larger then 0 and less or equal then + * Wildcard the first number must be larger than 0 and less or equal then * |totalPageCount|. If it's missed then 1 is used as the first number. * Wildcard the second number must be larger then the first number. If it's * missed then |totalPageCount| is used as the second number. @@ -94,7 +103,7 @@ function removeDuplicates(inArray) { * Example: "1-4dsf, 11" is invalid regardless of |totalPageCount|. * @param {string} pageRangeText The text to be checked. * @param {number=} opt_totalPageCount The total number of pages. - * @return {?Array<{from: number, to: number}>} An array of page range objects. + * @return {!PageRangeStatus|!Array<{from: number, to: number}>} */ function pageRangeTextToPageRanges(pageRangeText, opt_totalPageCount) { if (pageRangeText == '') { @@ -113,20 +122,22 @@ function pageRangeTextToPageRanges(pageRangeText, opt_totalPageCount) { var match = parts[i].match(regex); if (match) { if (!isPositiveInteger(match[1]) && match[1] !== '') - return null; + return PageRangeStatus.SYNTAX_ERROR; if (!isPositiveInteger(match[2]) && match[2] !== '') - return null; + return PageRangeStatus.SYNTAX_ERROR; var from = match[1] ? parseInt(match[1], 10) : 1; var to = match[2] ? parseInt(match[2], 10) : totalPageCount; - if (from > to || to > totalPageCount) - return null; + if (from > to) + return PageRangeStatus.SYNTAX_ERROR; + if (to > totalPageCount) + return PageRangeStatus.LIMIT_ERROR; pageRanges.push({'from': from, 'to': to}); } else { if (!isPositiveInteger(parts[i])) - return null; + return PageRangeStatus.SYNTAX_ERROR; var singlePageNumber = parseInt(parts[i], 10); if (singlePageNumber > totalPageCount) - return null; + return PageRangeStatus.LIMIT_ERROR; pageRanges.push({'from': singlePageNumber, 'to': singlePageNumber}); } } @@ -146,7 +157,7 @@ function pageRangeTextToPageRanges(pageRangeText, opt_totalPageCount) { function pageRangeTextToPageList(pageRangeText, totalPageCount) { var pageRanges = pageRangeTextToPageRanges(pageRangeText, totalPageCount); var pageList = []; - if (pageRanges) { + if (pageRanges instanceof Array) { for (var i = 0; i < pageRanges.length; ++i) { for (var j = pageRanges[i].from; j <= Math.min(pageRanges[i].to, totalPageCount); ++j) { diff --git a/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs b/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs index dd17e6e..ff15d6f 100644 --- a/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs +++ b/chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs @@ -89,12 +89,18 @@ TEST_F('PrintPreviewUtilsUnitTest', 'PageRanges', function() { }); TEST_F('PrintPreviewUtilsUnitTest', 'InvalidPageRanges', function() { - assertTrue(pageRangeTextToPageRanges("10-100000", 100) === null); - assertTrue(pageRangeTextToPageRanges("1,100000", 100) === null); - assertTrue(pageRangeTextToPageRanges("1,2,0,56", 100) === null); - assertTrue(pageRangeTextToPageRanges("-1,1,2,,56", 100) === null); - assertTrue(pageRangeTextToPageRanges("1,2,56-40", 100) === null); - assertTrue(pageRangeTextToPageRanges("101-110", 100) === null); + assertEquals(PageRangeStatus.LIMIT_ERROR, + pageRangeTextToPageRanges("10-100000", 100)); + assertEquals(PageRangeStatus.LIMIT_ERROR, + pageRangeTextToPageRanges("1,100000", 100)); + assertEquals(PageRangeStatus.SYNTAX_ERROR, + pageRangeTextToPageRanges("1,2,0,56", 100)); + assertEquals(PageRangeStatus.SYNTAX_ERROR, + pageRangeTextToPageRanges("-1,1,2,,56", 100)); + assertEquals(PageRangeStatus.SYNTAX_ERROR, + pageRangeTextToPageRanges("1,2,56-40", 100)); + assertEquals(PageRangeStatus.LIMIT_ERROR, + pageRangeTextToPageRanges("101-110", 100)); }); TEST_F('PrintPreviewUtilsUnitTest', 'PageRangeTextToPageList', function() { diff --git a/chrome/browser/resources/print_preview/settings/page_settings.js b/chrome/browser/resources/print_preview/settings/page_settings.js index 78aeeb8..ef1cf17 100644 --- a/chrome/browser/resources/print_preview/settings/page_settings.js +++ b/chrome/browser/resources/print_preview/settings/page_settings.js @@ -138,17 +138,30 @@ cr.define('print_preview', function() { PageSettings.Classes_.CUSTOM_RADIO)[0]; this.customHintEl_ = this.getElement().getElementsByClassName( PageSettings.Classes_.CUSTOM_HINT)[0]; - this.customHintEl_.textContent = loadTimeData.getStringF( - 'pageRangeInstruction', - loadTimeData.getString('examplePageRangeText')); }, /** - * @param {boolean} isVisible Whether the custom hint is visible. + * @param {!PageRangeStatus} validity (of page range) * @private */ - setInvalidStateVisible_: function(isVisible) { - if (isVisible) { + setInvalidStateVisible_: function(validity) { + if (validity !== PageRangeStatus.NO_ERROR) { + var message; + if (validity === PageRangeStatus.LIMIT_ERROR) { + if (this.pageRangeTicketItem_.getDocumentNumPages()) { + message = loadTimeData.getStringF( + 'pageRangeLimitInstructionWithValue', + this.pageRangeTicketItem_.getDocumentNumPages()); + } else { + message = loadTimeData.getString( + 'pageRangeLimitInstruction'); + } + } else { + message = loadTimeData.getStringF( + 'pageRangeSyntaxInstruction', + loadTimeData.getString('examplePageRangeText')); + } + this.customHintEl_.textContent = message; this.customInput_.classList.add('invalid'); fadeInElement(this.customHintEl_); } else { @@ -247,10 +260,11 @@ cr.define('print_preview', function() { this.customInput_.value = pageRangeStr; } this.customRadio_.checked = true; - this.setInvalidStateVisible_(!this.pageRangeTicketItem_.isValid()); + this.setInvalidStateVisible_( + this.pageRangeTicketItem_.checkValidity()); } else { this.allRadio_.checked = true; - this.setInvalidStateVisible_(false); + this.setInvalidStateVisible_(PageRangeStatus.NO_ERROR); } } this.updateUiStateInternal(); diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index 67daffd..f568688 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc @@ -243,8 +243,13 @@ content::WebUIDataSource* CreatePrintPreviewUISource() { source->AddString( "noDestsPromoLearnMoreUrl", chrome::kCloudPrintNoDestinationsLearnMoreURL); - source->AddLocalizedString("pageRangeInstruction", - IDS_PRINT_PREVIEW_PAGE_RANGE_INSTRUCTION); + source->AddLocalizedString("pageRangeLimitInstruction", + IDS_PRINT_PREVIEW_PAGE_RANGE_LIMIT_INSTRUCTION); + source->AddLocalizedString( + "pageRangeLimitInstructionWithValue", + IDS_PRINT_PREVIEW_PAGE_RANGE_LIMIT_INSTRUCTION_WITH_VALUE); + source->AddLocalizedString("pageRangeSyntaxInstruction", + IDS_PRINT_PREVIEW_PAGE_RANGE_SYNTAX_INSTRUCTION); source->AddLocalizedString("copiesInstruction", IDS_PRINT_PREVIEW_COPIES_INSTRUCTION); source->AddLocalizedString("incrementTitle", |