Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Side by Side Diff: chrome/browser/resources/print_preview/print_preview_utils.js

Issue 12209086: Page range comparisons should use document size. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @param {string} toTest The string to be tested. 6 * @param {string} toTest The string to be tested.
7 * @return {boolean} True if |toTest| contains only digits. Leading and trailing 7 * @return {boolean} True if |toTest| contains only digits. Leading and trailing
8 * whitespace is allowed. 8 * whitespace is allowed.
9 */ 9 */
10 function isInteger(toTest) { 10 function isInteger(toTest) {
11 var numericExp = /^\s*[0-9]+\s*$/; 11 var numericExp = /^\s*[0-9]+\s*$/;
12 return numericExp.test(toTest); 12 return numericExp.test(toTest);
13 } 13 }
14 14
15 /** 15 /**
16 * Returns true if |value| is a valid non zero positive integer. 16 * Returns true if |value| is a valid non zero positive integer.
17 * @param {string} value The string to be tested. 17 * @param {string} value The string to be tested.
18 *
19 * @return {boolean} true if the |value| is valid non zero positive integer. 18 * @return {boolean} true if the |value| is valid non zero positive integer.
20 */ 19 */
21 function isPositiveInteger(value) { 20 function isPositiveInteger(value) {
22 return isInteger(value) && parseInt(value, 10) > 0; 21 return isInteger(value) && parseInt(value, 10) > 0;
23 } 22 }
24 23
25 /** 24 /**
26 * Returns true if the contents of the two arrays are equal. 25 * Returns true if the contents of the two arrays are equal.
27 * @param {Array} array1 The first array. 26 * @param {Array.<{from: number, to: number}>} array1 The first array.
28 * @param {Array} array2 The second array. 27 * @param {Array.<{from: number, to: number}>} array2 The second array.
29 *
30 * @return {boolean} true if the arrays are equal. 28 * @return {boolean} true if the arrays are equal.
31 */ 29 */
32 function areArraysEqual(array1, array2) { 30 function areArraysEqual(array1, array2) {
33 if (array1.length != array2.length) 31 if (array1.length != array2.length)
34 return false; 32 return false;
35 for (var i = 0; i < array1.length; i++) 33 for (var i = 0; i < array1.length; i++)
36 if (array1[i] !== array2[i]) 34 if (array1[i] !== array2[i])
37 return false; 35 return false;
38 return true; 36 return true;
39 } 37 }
40 38
41 /** 39 /**
40 * Returns true if the contents of the two page ranges are equal.
41 * @param {Array} array1 The first array.
42 * @param {Array} array2 The second array.
43 * @return {boolean} true if the arrays are equal.
44 */
45 function areRangesEqual(array1, array2) {
46 if (array1.length != array2.length)
47 return false;
48 for (var i = 0; i < array1.length; i++)
49 if (array1[i].from != array2[i].from ||
50 array1[i].to != array2[i].to) {
51 return false;
52 }
53 return true;
54 }
55
56 /**
42 * Removes duplicate elements from |inArray| and returns a new array. 57 * Removes duplicate elements from |inArray| and returns a new array.
43 * |inArray| is not affected. It assumes that |inArray| is already sorted. 58 * |inArray| is not affected. It assumes that |inArray| is already sorted.
44 * @param {Array.<number>} inArray The array to be processed. 59 * @param {Array.<number>} inArray The array to be processed.
45 * @return {Array.<number>} The array after processing. 60 * @return {Array.<number>} The array after processing.
46 */ 61 */
47 function removeDuplicates(inArray) { 62 function removeDuplicates(inArray) {
48 var out = []; 63 var out = [];
49 64
50 if (inArray.length == 0) 65 if (inArray.length == 0)
51 return out; 66 return out;
52 67
53 out.push(inArray[0]); 68 out.push(inArray[0]);
54 for (var i = 1; i < inArray.length; ++i) 69 for (var i = 1; i < inArray.length; ++i)
55 if (inArray[i] != inArray[i - 1]) 70 if (inArray[i] != inArray[i - 1])
56 out.push(inArray[i]); 71 out.push(inArray[i]);
57 return out; 72 return out;
58 } 73 }
59 74
60 /** 75 /**
61 * Checks if |pageRangeText| represents a valid page selection. 76 * Returns a list of ranges in |pageRangeText|. The ranges are
77 * listed in the order they appear in |pageRangeText| and duplicates are not
78 * eliminated. If |pageRangeText| is not valid null is returned.
62 * A valid selection has a parsable format and every page identifier is 79 * A valid selection has a parsable format and every page identifier is
63 * <= |totalPageCount| unless wildcards are used (see examples). 80 * greater the 0 and less or equal to |totalPageCount| unless wildcards are
81 * used(see examples).
82 * If |totalPageCount| is 0 or undefined function uses impossibly large number
83 * instead.
84 * Wildcards the first number must be larger then 0 and less or equal then
85 * |totalPageCount|. If it's missed then 1 is used as the first number.
86 * Wildcards the second number must be larger then the first number. If it's
87 * missed then |totalPageCount| is used as the second number.
64 * Example: "1-4, 9, 3-6, 10, 11" is valid, assuming |totalPageCount| >= 11. 88 * Example: "1-4, 9, 3-6, 10, 11" is valid, assuming |totalPageCount| >= 11.
65 * Example: "1-4, 6-6" is valid, assuming |totalPageCount| >= 6. 89 * Example: "1-4, -6" is valid, assuming |totalPageCount| >= 6.
66 * Example: "2-" is valid, assuming |totalPageCount| >= 2, means from 2 to the 90 * Example: "2-" is valid, assuming |totalPageCount| >= 2, means from 2 to the
67 * end. 91 * end.
68 * Example: "1-10000" is valid, regardless of |totalPageCount|, means from 1 to 92 * Example: "4-2, 11, -6" is invalid.
69 * the end if |totalPageCount| < 10000. 93 * Example: "-" is valid, assuming |totalPageCount| >= 1.
70 * Example: "1-4dsf, 11" is invalid regardless of |totalPageCount|. 94 * Example: "1-4dsf, 11" is invalid regardless of |totalPageCount|.
71 * Example: "4-2, 11, -6" is invalid regardless of |totalPageCount|.
72 *
73 * Note: If |totalPageCount| is undefined the validation does not take
74 * |totalPageCount| into account.
75 * Example: "34853253" is valid.
76 * Example: "1-4, 9, 3-6, 10, 11" is valid.
77 *
78 * @param {string} pageRangeText The text to be checked. 95 * @param {string} pageRangeText The text to be checked.
79 * @param {number} totalPageCount The total number of pages. 96 * @param {number} totalPageCount The total number of pages.
80 * @return {boolean} true if the |pageRangeText| is valid. 97 * @return {Array.<{from: number, to: number}>} An array of page range objects.
81 */ 98 */
82 function isPageRangeTextValid(pageRangeText, totalPageCount) { 99 function pageRangeTextToPageRanges(pageRangeText, totalPageCount) {
83 var regex = /^\s*([0-9]+)\s*-\s*([0-9]*)\s*$/; 100 var MAX_PAGE_NUMBER = 1000000000;
84 var successfullyParsed = 0; 101 totalPageCount = totalPageCount ? totalPageCount : MAX_PAGE_NUMBER;
85 102
86 // Splitting around commas. 103 var regex = /^\s*([0-9]*)\s*-\s*([0-9]*)\s*$/;
87 var parts = pageRangeText.split(/,/); 104 var parts = pageRangeText.split(/,/);
88 105
106 var pageRanges = [];
89 for (var i = 0; i < parts.length; ++i) { 107 for (var i = 0; i < parts.length; ++i) {
90 // Removing whitespace.
91 parts[i] = parts[i].replace(/\s*/g, '');
92 var match = parts[i].match(regex); 108 var match = parts[i].match(regex);
93 if (parts[i].length == 0) 109 if (match) {
94 continue; 110 if (!isPositiveInteger(match[1]) && match[1] !== '')
95 111 return null;
96 if (match && match[1] && isPositiveInteger(match[1])) { 112 if (!isPositiveInteger(match[2]) && match[2] !== '')
97 var from = parseInt(match[1], 10); 113 return null;
98 var to = isPositiveInteger(match[2]) ? parseInt(match[2], 10) : 114 var from = match[1] ? parseInt(match[1], 10) : 1;
99 totalPageCount; 115 var to = match[2] ? parseInt(match[2], 10) : totalPageCount;
100 if (from > to || from > totalPageCount) 116 if (from > to || from > totalPageCount)
101 return false; 117 return null;
102 } else if (!isPositiveInteger(parts[i]) || (totalPageCount != -1 && 118 pageRanges.push({'from': from, 'to': to});
103 parseInt(parts[i], 10) > totalPageCount)) { 119 } else {
104 return false; 120 if (!isPositiveInteger(parts[i]))
121 return null;
122 var singlePageNumber = parseInt(parts[i], 10);
123 if (singlePageNumber > totalPageCount)
124 return null;
125 pageRanges.push({'from': singlePageNumber, 'to': singlePageNumber});
105 } 126 }
106 successfullyParsed++;
107 } 127 }
108 return successfullyParsed > 0; 128 return pageRanges;
109 } 129 }
110 130
111 /** 131 /**
112 * Returns a list of all pages specified in |pagesRangeText|. The pages are 132 * Returns a list of pages defined by |pagesRangeText|. The pages are
113 * listed in the order they appear in |pageRangeText| and duplicates are not 133 * listed in the order they appear in |pageRangeText| and duplicates are not
114 * eliminated. If |pageRangeText| is not valid according to 134 * eliminated. If |pageRangeText| is not valid according or
115 * isPageRangeTextValid(), or |totalPageCount| is undefined an empty list is 135 * |totalPageCount| undefined [1,2,...,totalPageCount] is returned.
116 * returned. 136 * See pageRangeTextToPageRanges for details.
117 * @param {string} pageRangeText The text to be checked. 137 * @param {string} pageRangeText The text to be checked.
118 * @param {number} totalPageCount The total number of pages. 138 * @param {number} totalPageCount The total number of pages.
119 * @return {Array.<number>} A list of all pages. 139 * @return {Array.<number>} A list of all pages.
120 */ 140 */
121 function pageRangeTextToPageList(pageRangeText, totalPageCount) { 141 function pageRangeTextToPageList(pageRangeText, totalPageCount) {
122 var pageList = []; 142 var pageRanges = pageRangeTextToPageRanges(pageRangeText, totalPageCount);
123 if ((totalPageCount && 143 pageList = [];
124 !isPageRangeTextValid(pageRangeText, totalPageCount)) || 144 if (pageRanges) {
125 !totalPageCount) { 145 for (var i = 0; i < pageRanges.length; ++i) {
126 return pageList; 146 for (var j = pageRanges[i].from; j <= Math.min(pageRanges[i].to,
127 } 147 totalPageCount); ++j) {
128
129 var regex = /^\s*([0-9]+)\s*-\s*([0-9]*)\s*$/;
130 var parts = pageRangeText.split(/,/);
131
132 for (var i = 0; i < parts.length; ++i) {
133 var match = parts[i].match(regex);
134
135 if (match && match[1]) {
136 var from = parseInt(match[1], 10);
137 var to = match[2] ? parseInt(match[2], 10) : totalPageCount;
138
139 for (var j = from; j <= Math.min(to, totalPageCount); ++j)
140 pageList.push(j); 148 pageList.push(j);
141 } else {
142 var singlePageNumber = parseInt(parts[i], 10);
143 if (isPositiveInteger(singlePageNumber.toString()) &&
144 singlePageNumber <= totalPageCount) {
145 pageList.push(singlePageNumber);
146 } 149 }
147 } 150 }
148 } 151 }
152 if (pageList.length == 0) {
153 for (var j = 1; j <= totalPageCount; ++j)
154 pageList.push(j);
155 }
149 return pageList; 156 return pageList;
150 } 157 }
151 158
152 /** 159 /**
153 * @param {Array.<number>} pageList The list to be processed. 160 * @param {Array.<number>} pageList The list to be processed.
154 * @return {Array.<number>} The contents of |pageList| in ascending order and 161 * @return {Array.<number>} The contents of |pageList| in ascending order and
155 * without any duplicates. |pageList| is not affected. 162 * without any duplicates. |pageList| is not affected.
156 */ 163 */
157 function pageListToPageSet(pageList) { 164 function pageListToPageSet(pageList) {
158 var pageSet = []; 165 var pageSet = [];
159 if (pageList.length == 0) 166 if (pageList.length == 0)
160 return pageSet; 167 return pageSet;
161 pageSet = pageList.slice(0); 168 pageSet = pageList.slice(0);
162 pageSet.sort(function(a, b) { 169 pageSet.sort(function(a, b) {
163 return (/** @type {number} */ a) - (/** @type {number} */ b); 170 return (/** @type {number} */ a) - (/** @type {number} */ b);
164 }); 171 });
165 pageSet = removeDuplicates(pageSet); 172 pageSet = removeDuplicates(pageSet);
166 return pageSet; 173 return pageSet;
167 } 174 }
168 175
169 /** 176 /**
170 * Converts |pageSet| to page ranges. It squashes whenever possible.
171 * Example: '1-2,3,5-7' becomes 1-3,5-7.
172 *
173 * @param {Array.<number>} pageSet The set of pages to be processed. Callers
174 * should ensure that no duplicates exist.
175 * @return {Array.<{from: number, to: number}>} An array of page range objects.
176 */
177 function pageSetToPageRanges(pageSet) {
178 var pageRanges = [];
179 for (var i = 0; i < pageSet.length; ++i) {
180 var tempFrom = pageSet[i];
181 while (i + 1 < pageSet.length && pageSet[i + 1] == pageSet[i] + 1)
182 ++i;
183 var tempTo = pageSet[i];
184 pageRanges.push({'from': tempFrom, 'to': tempTo});
185 }
186 return pageRanges;
187 }
188
189 /**
190 * @param {!HTMLElement} element Element to check for visibility. 177 * @param {!HTMLElement} element Element to check for visibility.
191 * @return {boolean} Whether the given element is visible. 178 * @return {boolean} Whether the given element is visible.
192 */ 179 */
193 function getIsVisible(element) { 180 function getIsVisible(element) {
194 return !element.hidden; 181 return !element.hidden;
195 } 182 }
196 183
197 /** 184 /**
198 * Shows or hides an element. 185 * Shows or hides an element.
199 * @param {!HTMLElement} element Element to show or hide. 186 * @param {!HTMLElement} element Element to show or hide.
200 * @param {boolean} isVisible Whether the element should be visible or not. 187 * @param {boolean} isVisible Whether the element should be visible or not.
201 */ 188 */
202 function setIsVisible(element, isVisible) { 189 function setIsVisible(element, isVisible) {
203 element.hidden = !isVisible; 190 element.hidden = !isVisible;
204 } 191 }
205 192
206 /** 193 /**
207 * @param {!Array} array Array to check for item. 194 * @param {!Array} array Array to check for item.
208 * @param {*} item Item to look for in array. 195 * @param {*} item Item to look for in array.
209 * @return {boolean} Whether the item is in the array. 196 * @return {boolean} Whether the item is in the array.
210 */ 197 */
211 function arrayContains(array, item) { 198 function arrayContains(array, item) {
212 return array.indexOf(item) != -1; 199 return array.indexOf(item) != -1;
213 } 200 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698