summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrb <krb@chromium.org>2016-02-25 08:27:41 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-25 16:28:42 +0000
commitd62c24312fed4aeba5e4412a8f2bd3a83ad55b05 (patch)
tree48163ec398c897016043a5c55493647dc4a17564
parent7dc852fd17cd4ee23e392d99e392a5c4eee7eea3 (diff)
downloadchromium_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}
-rw-r--r--chrome/app/generated_resources.grd8
-rw-r--r--chrome/browser/resources/print_preview/data/ticket_items/page_range.js25
-rw-r--r--chrome/browser/resources/print_preview/print_preview_utils.js35
-rw-r--r--chrome/browser/resources/print_preview/print_preview_utils_unittest.gtestjs18
-rw-r--r--chrome/browser/resources/print_preview/settings/page_settings.js30
-rw-r--r--chrome/browser/ui/webui/print_preview/print_preview_ui.cc9
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",