OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * Returns true if |toTest| contains only digits. Leading and trailing |
| 7 * whitespace is allowed. |
| 8 * @param {string} toTest The string to be tested. |
| 9 */ |
| 10 function isInteger(toTest) { |
| 11 var numericExp = /^\s*[0-9]+\s*$/; |
| 12 return numericExp.test(toTest); |
| 13 } |
| 14 |
| 15 /** |
| 16 * Returns true if |value| is a valid non zero positive integer. |
| 17 * @param {string} value The string to be tested. |
| 18 * |
| 19 * @return {boolean} true if the |value| is valid non zero positive integer. |
| 20 */ |
| 21 function isPositiveInteger(value) { |
| 22 return isInteger(value) && parseInt(value, 10) > 0; |
| 23 } |
| 24 |
| 25 /** |
| 26 * Returns true if the contents of the two arrays are equal. |
| 27 * @param {Array} array1 The first array. |
| 28 * @param {Array} array1 The second array. |
| 29 * |
| 30 * @return {boolean} true if the arrays are equal. |
| 31 */ |
| 32 function areArraysEqual(array1, array2) { |
| 33 if (array1.length != array2.length) |
| 34 return false; |
| 35 for (var i = 0; i < array1.length; i++) |
| 36 if(array1[i] != array2[i]) |
| 37 return false; |
| 38 return true; |
| 39 } |
| 40 |
| 41 /** |
| 42 * Removes duplicate elements from |inArray| and returns a new array. |
| 43 * |inArray| is not affected. It assumes that |inArray| is already sorted. |
| 44 * |
| 45 * @param {Array} inArray The array to be processed. |
| 46 */ |
| 47 function removeDuplicates(inArray) { |
| 48 var out = []; |
| 49 |
| 50 if(inArray.length == 0) |
| 51 return out; |
| 52 |
| 53 out.push(inArray[0]); |
| 54 for (var i = 1; i < inArray.length; ++i) |
| 55 if(inArray[i] != inArray[i - 1]) |
| 56 out.push(inArray[i]); |
| 57 return out; |
| 58 } |
| 59 |
| 60 /** |
| 61 * Checks if |pageRangeText| represents a valid page selection. |
| 62 * A valid selection has a parsable format and every page identifier is |
| 63 * <= |totalPageCount| unless wildcards are used (see examples). |
| 64 * Example: "1-4, 9, 3-6, 10, 11" is valid, assuming |totalPageCount| >= 11. |
| 65 * Example: "1-4, 6-6" is valid, assuming |totalPageCount| >= 6. |
| 66 * Example: "2-" is valid, assuming |totalPageCount| >= 2, means from 2 to the |
| 67 * end. |
| 68 * Example: "1-10000" is valid, regardless of |totalPageCount|, means from 1 to |
| 69 * the end if |totalPageCount| < 10000. |
| 70 * 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 * @return {boolean} true if the |pageRangeText| is valid. |
| 79 */ |
| 80 function isPageRangeTextValid(pageRangeText, totalPageCount) { |
| 81 var regex = /^\s*([0-9]+)\s*-\s*([0-9]*)\s*$/; |
| 82 var successfullyParsed = 0; |
| 83 |
| 84 // Splitting around commas. |
| 85 var parts = pageRangeText.split(/,/); |
| 86 |
| 87 for (var i = 0; i < parts.length; ++i) { |
| 88 var match = parts[i].match(regex); |
| 89 if (parts[i].length == 0) |
| 90 continue; |
| 91 |
| 92 if (match && match[1] && isPositiveInteger(match[1])) { |
| 93 var from = parseInt(match[1], 10); |
| 94 var to = isPositiveInteger(match[2]) ? parseInt(match[2], 10) : |
| 95 totalPageCount; |
| 96 if (from > to) |
| 97 return false; |
| 98 } else if (!isPositiveInteger(parts[i]) || (totalPageCount != -1 && |
| 99 parseInt(parts[i], 10) > totalPageCount)) { |
| 100 return false; |
| 101 } |
| 102 successfullyParsed++; |
| 103 } |
| 104 return successfullyParsed > 0; |
| 105 } |
| 106 |
| 107 /** |
| 108 * Returns a list of all pages specified in |pagesRangeText|. The pages are |
| 109 * listed in the order they appear in |pageRangeText| and duplicates are not |
| 110 * eliminated. If |pageRangeText| is not valid according to |
| 111 * isPageRangeTextValid(), or |totalPageCount| is undefined an empty list is |
| 112 * returned. |
| 113 * |
| 114 * @return {Array} |
| 115 */ |
| 116 function pageRangeTextToPageList(pageRangeText, totalPageCount) { |
| 117 var pageList = []; |
| 118 if ((totalPageCount && !isPageRangeTextValid(pageRangeText, totalPageCount)) |
| 119 || !totalPageCount) { |
| 120 return pageList; |
| 121 } |
| 122 |
| 123 var regex = /^\s*([0-9]+)\s*-\s*([0-9]*)\s*$/; |
| 124 var parts = pageRangeText.split(/,/); |
| 125 |
| 126 for (var i = 0; i < parts.length; ++i) { |
| 127 var match = parts[i].match(regex); |
| 128 |
| 129 if (match && match[1]) { |
| 130 var from = parseInt(match[1], 10); |
| 131 var to = match[2] ? parseInt(match[2], 10) : totalPageCount; |
| 132 |
| 133 for (var j = from; j <= Math.min(to, totalPageCount); ++j) |
| 134 pageList.push(j); |
| 135 } else { |
| 136 var singlePageNumber = parseInt(parts[i], 10); |
| 137 if (isPositiveInteger(singlePageNumber) && |
| 138 singlePageNumber <= totalPageCount) { |
| 139 pageList.push(singlePageNumber); |
| 140 } |
| 141 } |
| 142 } |
| 143 return pageList; |
| 144 } |
| 145 |
| 146 /** |
| 147 * Returns the contents of |pageList| in ascending order and without any |
| 148 * duplicates. |pageList| is not affected. |
| 149 * |
| 150 * @return {Array} |
| 151 */ |
| 152 function pageListToPageSet(pageList) { |
| 153 var pageSet = []; |
| 154 if (pageList.length == 0) |
| 155 return pageSet; |
| 156 pageSet = pageList.slice(0); |
| 157 pageSet.sort(function(a,b) { return a - b; }); |
| 158 pageSet = removeDuplicates(pageSet); |
| 159 return pageSet; |
| 160 } |
| 161 |
| 162 /** |
| 163 * Converts |pageSet| to page ranges. It squashes whenever possible. |
| 164 * Example: '1-2,3,5-7' becomes 1-3,5-7. |
| 165 * |
| 166 * @return {Array} an array of page range objects. A page range object has |
| 167 * fields 'from' and 'to'. |
| 168 */ |
| 169 function pageSetToPageRanges(pageSet) { |
| 170 var pageRanges = []; |
| 171 for (var i = 0; i < pageSet.length; ++i) { |
| 172 tempFrom = pageSet[i]; |
| 173 while (i + 1 < pageSet.length && pageSet[i + 1] == pageSet[i] + 1) |
| 174 ++i; |
| 175 tempTo = pageSet[i]; |
| 176 pageRanges.push({'from': tempFrom, 'to': tempTo}); |
| 177 } |
| 178 return pageRanges; |
| 179 } |
OLD | NEW |