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 3// found in the LICENSE file. 4 5/** 6 * @param {string} toTest The string to be tested. 7 * @return {boolean} True if |toTest| contains only digits. Leading and trailing 8 * whitespace is allowed. 9 */ 10function 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 * @return {boolean} true if the |value| is valid non zero positive integer. 19 */ 20function isPositiveInteger(value) { 21 return isInteger(value) && parseInt(value, 10) > 0; 22} 23 24/** 25 * Returns true if the contents of the two arrays are equal. 26 * @param {Array.<{from: number, to: number}>} array1 The first array. 27 * @param {Array.<{from: number, to: number}>} array2 The second array. 28 * @return {boolean} true if the arrays are equal. 29 */ 30function areArraysEqual(array1, array2) { 31 if (array1.length != array2.length) 32 return false; 33 for (var i = 0; i < array1.length; i++) 34 if (array1[i] !== array2[i]) 35 return false; 36 return true; 37} 38 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 */ 45function 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/** 57 * Removes duplicate elements from |inArray| and returns a new array. 58 * |inArray| is not affected. It assumes that |inArray| is already sorted. 59 * @param {Array.<number>} inArray The array to be processed. 60 * @return {Array.<number>} The array after processing. 61 */ 62function removeDuplicates(inArray) { 63 var out = []; 64 65 if (inArray.length == 0) 66 return out; 67 68 out.push(inArray[0]); 69 for (var i = 1; i < inArray.length; ++i) 70 if (inArray[i] != inArray[i - 1]) 71 out.push(inArray[i]); 72 return out; 73} 74 75/** 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. 79 * A valid selection has a parsable format and every page identifier is 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 * Wildcard 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 * Wildcard the second number must be larger then the first number. If it's 87 * missed then |totalPageCount| is used as the second number. 88 * Example: "1-4, 9, 3-6, 10, 11" is valid, assuming |totalPageCount| >= 11. 89 * Example: "1-4, -6" is valid, assuming |totalPageCount| >= 6. 90 * Example: "2-" is valid, assuming |totalPageCount| >= 2, means from 2 to the 91 * end. 92 * Example: "4-2, 11, -6" is invalid. 93 * Example: "-" is valid, assuming |totalPageCount| >= 1. 94 * Example: "1-4dsf, 11" is invalid regardless of |totalPageCount|. 95 * @param {string} pageRangeText The text to be checked. 96 * @param {number} totalPageCount The total number of pages. 97 * @return {Array.<{from: number, to: number}>} An array of page range objects. 98 */ 99function pageRangeTextToPageRanges(pageRangeText, totalPageCount) { 100 if (pageRangeText == '') { 101 return []; 102 } 103 104 var MAX_PAGE_NUMBER = 1000000000; 105 totalPageCount = totalPageCount ? totalPageCount : MAX_PAGE_NUMBER; 106 107 var regex = /^\s*([0-9]*)\s*-\s*([0-9]*)\s*$/; 108 var parts = pageRangeText.split(/,/); 109 110 var pageRanges = []; 111 for (var i = 0; i < parts.length; ++i) { 112 var match = parts[i].match(regex); 113 if (match) { 114 if (!isPositiveInteger(match[1]) && match[1] !== '') 115 return null; 116 if (!isPositiveInteger(match[2]) && match[2] !== '') 117 return null; 118 var from = match[1] ? parseInt(match[1], 10) : 1; 119 var to = match[2] ? parseInt(match[2], 10) : totalPageCount; 120 if (from > to || from > totalPageCount) 121 return null; 122 pageRanges.push({'from': from, 'to': to}); 123 } else { 124 if (!isPositiveInteger(parts[i])) 125 return null; 126 var singlePageNumber = parseInt(parts[i], 10); 127 if (singlePageNumber > totalPageCount) 128 return null; 129 pageRanges.push({'from': singlePageNumber, 'to': singlePageNumber}); 130 } 131 } 132 return pageRanges; 133} 134 135/** 136 * Returns a list of pages defined by |pagesRangeText|. The pages are 137 * listed in the order they appear in |pageRangeText| and duplicates are not 138 * eliminated. If |pageRangeText| is not valid according or 139 * |totalPageCount| undefined [1,2,...,totalPageCount] is returned. 140 * See pageRangeTextToPageRanges for details. 141 * @param {string} pageRangeText The text to be checked. 142 * @param {number} totalPageCount The total number of pages. 143 * @return {Array.<number>} A list of all pages. 144 */ 145function pageRangeTextToPageList(pageRangeText, totalPageCount) { 146 var pageRanges = pageRangeTextToPageRanges(pageRangeText, totalPageCount); 147 pageList = []; 148 if (pageRanges) { 149 for (var i = 0; i < pageRanges.length; ++i) { 150 for (var j = pageRanges[i].from; j <= Math.min(pageRanges[i].to, 151 totalPageCount); ++j) { 152 pageList.push(j); 153 } 154 } 155 } 156 if (pageList.length == 0) { 157 for (var j = 1; j <= totalPageCount; ++j) 158 pageList.push(j); 159 } 160 return pageList; 161} 162 163/** 164 * @param {Array.<number>} pageList The list to be processed. 165 * @return {Array.<number>} The contents of |pageList| in ascending order and 166 * without any duplicates. |pageList| is not affected. 167 */ 168function pageListToPageSet(pageList) { 169 var pageSet = []; 170 if (pageList.length == 0) 171 return pageSet; 172 pageSet = pageList.slice(0); 173 pageSet.sort(function(a, b) { 174 return (/** @type {number} */ a) - (/** @type {number} */ b); 175 }); 176 pageSet = removeDuplicates(pageSet); 177 return pageSet; 178} 179 180/** 181 * @param {!HTMLElement} element Element to check for visibility. 182 * @return {boolean} Whether the given element is visible. 183 */ 184function getIsVisible(element) { 185 return !element.hidden; 186} 187 188/** 189 * Shows or hides an element. 190 * @param {!HTMLElement} element Element to show or hide. 191 * @param {boolean} isVisible Whether the element should be visible or not. 192 */ 193function setIsVisible(element, isVisible) { 194 element.hidden = !isVisible; 195} 196 197/** 198 * @param {!Array} array Array to check for item. 199 * @param {*} item Item to look for in array. 200 * @return {boolean} Whether the item is in the array. 201 */ 202function arrayContains(array, item) { 203 return array.indexOf(item) != -1; 204} 205