• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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