OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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 var localStrings = new LocalStrings(); | 5 var localStrings = new LocalStrings(); |
6 | 6 |
7 // The total page count of the previewed document regardless of which pages the | 7 // The total page count of the previewed document regardless of which pages the |
8 // user has selected. | 8 // user has selected. |
9 var totalPageCount = -1; | 9 var totalPageCount = -1; |
10 | 10 |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 } | 253 } |
254 } | 254 } |
255 | 255 |
256 /** | 256 /** |
257 * Validates the copies text field value. | 257 * Validates the copies text field value. |
258 * NOTE: An empty copies field text is considered valid because the blur event | 258 * NOTE: An empty copies field text is considered valid because the blur event |
259 * listener of this field will set it back to a default value. | 259 * listener of this field will set it back to a default value. |
260 * @return {boolean} true if the number of copies is valid else returns false. | 260 * @return {boolean} true if the number of copies is valid else returns false. |
261 */ | 261 */ |
262 function isNumberOfCopiesValid() { | 262 function isNumberOfCopiesValid() { |
263 var copiesFieldText = $('copies').value.replace(/\s/g, ''); | 263 var copiesFieldText = $('copies').value; |
264 if (copiesFieldText == '') | 264 return copiesFieldText == '' ? true : isPositiveInteger(copiesFieldText); |
265 return true; | |
266 | |
267 return (isInteger(copiesFieldText) && Number(copiesFieldText) > 0); | |
268 } | 265 } |
269 | 266 |
270 /** | 267 /** |
271 * Returns true if |toTest| contains only digits. Leading and trailing | |
272 * whitespace is allowed. | |
273 * @param {string} toTest The string to be tested. | |
274 */ | |
275 function isInteger(toTest) { | |
276 var numericExp = /^\s*[0-9]+\s*$/; | |
277 return numericExp.test(toTest); | |
278 } | |
279 | |
280 /** | |
281 * Checks whether the preview layout setting is set to 'landscape' or not. | 268 * Checks whether the preview layout setting is set to 'landscape' or not. |
282 * | 269 * |
283 * @return {boolean} true if layout is 'landscape'. | 270 * @return {boolean} true if layout is 'landscape'. |
284 */ | 271 */ |
285 function isLandscape() { | 272 function isLandscape() { |
286 return $('landscape').checked; | 273 return $('landscape').checked; |
287 } | 274 } |
288 | 275 |
289 /** | 276 /** |
290 * Checks whether the preview color setting is set to 'color' or not. | 277 * Checks whether the preview color setting is set to 'color' or not. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 /** | 328 /** |
342 * Creates a JSON string based on the values in the printer settings. | 329 * Creates a JSON string based on the values in the printer settings. |
343 * | 330 * |
344 * @return {string} JSON string with print job settings. | 331 * @return {string} JSON string with print job settings. |
345 */ | 332 */ |
346 function getSettingsJSON() { | 333 function getSettingsJSON() { |
347 var printAll = $('all-pages').checked; | 334 var printAll = $('all-pages').checked; |
348 var deviceName = getSelectedPrinterName(); | 335 var deviceName = getSelectedPrinterName(); |
349 var printToPDF = (deviceName == PRINT_TO_PDF); | 336 var printToPDF = (deviceName == PRINT_TO_PDF); |
350 | 337 |
351 return JSON.stringify({'deviceName': deviceName, | 338 return JSON.stringify( |
352 'pageRange': getSelectedPageRanges(), | 339 {'deviceName': deviceName, |
353 'printAll': printAll, | 340 'pageRange': pageSetToPageRanges(getSelectedPagesSet()), |
354 'duplex': getDuplexMode(), | 341 'printAll': printAll, |
355 'copies': getCopies(), | 342 'duplex': getDuplexMode(), |
356 'collate': isCollated(), | 343 'copies': getCopies(), |
357 'landscape': isLandscape(), | 344 'collate': isCollated(), |
358 'color': isColor(), | 345 'landscape': isLandscape(), |
359 'printToPDF': printToPDF}); | 346 'color': isColor(), |
| 347 'printToPDF': printToPDF}); |
360 } | 348 } |
361 | 349 |
362 /** | 350 /** |
363 * Returns the name of the selected printer or the empty string if no | 351 * Returns the name of the selected printer or the empty string if no |
364 * printer is selected. | 352 * printer is selected. |
365 */ | 353 */ |
366 function getSelectedPrinterName() { | 354 function getSelectedPrinterName() { |
367 var printerList = $('printer-list') | 355 var printerList = $('printer-list') |
368 var selectedPrinter = printerList.selectedIndex; | 356 var selectedPrinter = printerList.selectedIndex; |
369 var deviceName = ''; | 357 var deviceName = ''; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 if (hasPendingPrintFileRequest) | 616 if (hasPendingPrintFileRequest) |
629 printFile(); | 617 printFile(); |
630 } | 618 } |
631 | 619 |
632 /** | 620 /** |
633 * Create the PDF plugin or reload the existing one. | 621 * Create the PDF plugin or reload the existing one. |
634 * @param {string} previewUid Preview unique identifier. | 622 * @param {string} previewUid Preview unique identifier. |
635 */ | 623 */ |
636 function createPDFPlugin(previewUid) { | 624 function createPDFPlugin(previewUid) { |
637 // Enable the print button. | 625 // Enable the print button. |
638 if (!$('printer-list').disabled) { | 626 if (!$('printer-list').disabled) |
639 $('print-button').disabled = false; | 627 $('print-button').disabled = false; |
640 } | |
641 | 628 |
642 var pdfViewer = $('pdf-viewer'); | 629 var pdfViewer = $('pdf-viewer'); |
643 if (pdfViewer) { | 630 if (pdfViewer) { |
644 // Need to call this before the reload(), where the plugin resets its | 631 // Need to call this before the reload(), where the plugin resets its |
645 // internal page count. | 632 // internal page count. |
646 pdfViewer.goToPage('0'); | 633 pdfViewer.goToPage('0'); |
647 | 634 |
648 pdfViewer.reload(); | 635 pdfViewer.reload(); |
649 pdfViewer.grayscale(!isColor()); | 636 pdfViewer.grayscale(!isColor()); |
650 return; | 637 return; |
651 } | 638 } |
652 | 639 |
653 var pdfPlugin = document.createElement('embed'); | 640 pdfViewer = document.createElement('embed'); |
654 pdfPlugin.setAttribute('id', 'pdf-viewer'); | 641 pdfViewer.setAttribute('id', 'pdf-viewer'); |
655 pdfPlugin.setAttribute('type', 'application/pdf'); | 642 pdfViewer.setAttribute('type', 'application/pdf'); |
656 pdfPlugin.setAttribute('src', 'chrome://print/' + previewUid + '/print.pdf'); | 643 pdfViewer.setAttribute('src', 'chrome://print/' + previewUid + '/print.pdf'); |
657 var mainView = $('mainview'); | 644 $('mainview').appendChild(pdfViewer); |
658 mainView.appendChild(pdfPlugin); | 645 pdfViewer.onload('onPDFLoad()'); |
659 pdfPlugin.onload('onPDFLoad()'); | 646 pdfViewer.removePrintButton(); |
660 pdfPlugin.removePrintButton(); | 647 pdfViewer.grayscale(true); |
661 pdfPlugin.grayscale(true); | |
662 } | 648 } |
663 | 649 |
664 /** | 650 /** |
665 * Returns true if a compatible pdf plugin exists, false if it doesn't. | 651 * Returns true if a compatible pdf plugin exists, false if it doesn't. |
666 */ | 652 */ |
667 function checkCompatiblePluginExists() { | 653 function checkCompatiblePluginExists() { |
668 var dummyPlugin = $('dummy-viewer') | 654 var dummyPlugin = $('dummy-viewer') |
669 return (dummyPlugin.onload && | 655 return (dummyPlugin.onload && |
670 dummyPlugin.goToPage && | 656 dummyPlugin.goToPage && |
671 dummyPlugin.removePrintButton); | 657 dummyPlugin.removePrintButton); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 if (!printToPDF && !isNumberOfCopiesValid()) { | 750 if (!printToPDF && !isNumberOfCopiesValid()) { |
765 printSummary.innerHTML = localStrings.getString('invalidNumberOfCopies'); | 751 printSummary.innerHTML = localStrings.getString('invalidNumberOfCopies'); |
766 return; | 752 return; |
767 } | 753 } |
768 | 754 |
769 if (!isSelectedPagesValid()) { | 755 if (!isSelectedPagesValid()) { |
770 printSummary.innerHTML = ''; | 756 printSummary.innerHTML = ''; |
771 return; | 757 return; |
772 } | 758 } |
773 | 759 |
774 var pageList = getSelectedPagesSet(); | 760 var pageSet = getSelectedPagesSet(); |
775 var numOfSheets = pageList.length; | 761 var numOfSheets = pageSet.length; |
776 var sheetsLabel = localStrings.getString('printPreviewSheetsLabelSingular'); | 762 var sheetsLabel = localStrings.getString('printPreviewSheetsLabelSingular'); |
777 var numOfPagesText = ''; | 763 var numOfPagesText = ''; |
778 var pagesLabel = ''; | 764 var pagesLabel = ''; |
779 | 765 |
780 if (!printToPDF && isTwoSided()) | 766 if (!printToPDF && isTwoSided()) |
781 numOfSheets = Math.ceil(numOfSheets / 2); | 767 numOfSheets = Math.ceil(numOfSheets / 2); |
782 numOfSheets *= copies; | 768 numOfSheets *= copies; |
783 | 769 |
784 if (numOfSheets > 1) | 770 if (numOfSheets > 1) |
785 sheetsLabel = localStrings.getString('printPreviewSheetsLabelPlural'); | 771 sheetsLabel = localStrings.getString('printPreviewSheetsLabelPlural'); |
786 | 772 |
787 var html = ''; | 773 var html = ''; |
788 if (pageList.length * copies != numOfSheets) { | 774 if (pageSet.length * copies != numOfSheets) { |
789 numOfPagesText = pageList.length * copies; | 775 numOfPagesText = pageSet.length * copies; |
790 pagesLabel = localStrings.getString('printPreviewPageLabelPlural'); | 776 pagesLabel = localStrings.getString('printPreviewPageLabelPlural'); |
791 html = localStrings.getStringF('printPreviewSummaryFormatLong', | 777 html = localStrings.getStringF('printPreviewSummaryFormatLong', |
792 '<b>' + numOfSheets + '</b>', | 778 '<b>' + numOfSheets + '</b>', |
793 '<b>' + sheetsLabel + '</b>', | 779 '<b>' + sheetsLabel + '</b>', |
794 numOfPagesText, pagesLabel); | 780 numOfPagesText, pagesLabel); |
795 } else | 781 } else |
796 html = localStrings.getStringF('printPreviewSummaryFormatShort', | 782 html = localStrings.getStringF('printPreviewSummaryFormatShort', |
797 '<b>' + numOfSheets + '</b>', | 783 '<b>' + numOfSheets + '</b>', |
798 '<b>' + sheetsLabel + '</b>'); | 784 '<b>' + sheetsLabel + '</b>'); |
799 | 785 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 * Sets the default values and sends a request to regenerate preview data. | 822 * Sets the default values and sends a request to regenerate preview data. |
837 */ | 823 */ |
838 function setDefaultValuesAndRegeneratePreview() { | 824 function setDefaultValuesAndRegeneratePreview() { |
839 fadeOutElement($('individual-pages-hint')); | 825 fadeOutElement($('individual-pages-hint')); |
840 totalPageCount = -1; | 826 totalPageCount = -1; |
841 previouslySelectedPages.length = 0; | 827 previouslySelectedPages.length = 0; |
842 requestPrintPreview(); | 828 requestPrintPreview(); |
843 } | 829 } |
844 | 830 |
845 /** | 831 /** |
846 * Returns a list of all pages in the specified ranges. The pages are listed in | 832 * Returns the selected pages in ascending order without any duplicates. |
847 * the order they appear in the 'individual-pages' textbox and duplicates are | |
848 * not eliminated. If the page ranges can't be parsed an empty list is | |
849 * returned. | |
850 * | 833 * |
851 * @return {Array} | 834 * @return {Array} |
852 */ | 835 */ |
853 function getSelectedPages() { | 836 function getSelectedPagesSet() { |
854 var pageText = $('individual-pages').value; | 837 var pageRangeText = $('individual-pages').value; |
855 | 838 |
856 if ($('all-pages').checked || pageText.length == 0) | 839 if ($('all-pages').checked || pageRangeText.length == 0) |
857 pageText = '1-' + totalPageCount; | 840 pageRangeText = '1-' + totalPageCount; |
858 | 841 |
859 var pageList = []; | 842 var pageList = pageRangeTextToPageList(pageRangeText, totalPageCount); |
860 var parts = pageText.split(/,/); | 843 return pageListToPageSet(pageList); |
861 | |
862 for (var i = 0; i < parts.length; ++i) { | |
863 var part = parts[i]; | |
864 var match = part.match(/^\s*([0-9]+)\s*-\s*([0-9]*)\s*$/); | |
865 | |
866 if (match && match[1]) { | |
867 var from = parseInt(match[1], 10); | |
868 var to = match[2] ? parseInt(match[2], 10) : totalPageCount; | |
869 | |
870 if (from && to) { | |
871 for (var j = from; j <= to; ++j) | |
872 if (j <= totalPageCount) | |
873 pageList.push(j); | |
874 } | |
875 } else { | |
876 var singlePageNumber = parseInt(part, 10); | |
877 if (singlePageNumber && singlePageNumber > 0 && | |
878 singlePageNumber <= totalPageCount) { | |
879 pageList.push(parseInt(part, 10)); | |
880 } | |
881 } | |
882 } | |
883 return pageList; | |
884 } | 844 } |
885 | 845 |
886 /** | 846 /** |
887 * Validates the 'individual-pages' text field value. | 847 * Validates the 'individual-pages' text field value. |
888 * | 848 * |
889 * @return {boolean} true if the text is valid. | 849 * @return {boolean} true if the text is valid. |
890 */ | 850 */ |
891 function isSelectedPagesValid() { | 851 function isSelectedPagesValid() { |
892 var pageText = $('individual-pages').value; | 852 var pageRangeText = $('individual-pages').value; |
893 | 853 |
894 if ($('all-pages').checked || pageText.length == 0) | 854 if ($('all-pages').checked || pageRangeText.length == 0) |
895 return true; | 855 return true; |
896 | 856 |
897 var successfullyParsed = 0; | 857 return isPageRangeTextValid(pageRangeText, totalPageCount); |
898 var parts = pageText.split(/,/); | |
899 | |
900 for (var i = 0; i < parts.length; ++i) { | |
901 var part = parts[i].replace(/\s*/g, ''); | |
902 if (part.length == 0) | |
903 continue; | |
904 | |
905 var match = part.match(/^([0-9]+)-([0-9]*)$/); | |
906 if (match && isValidNonZeroPositiveInteger(match[1])) { | |
907 if (!match[2] && totalPageCount == -1) { | |
908 successfullyParsed += 1; | |
909 continue; | |
910 } | |
911 var from = parseInt(match[1], 10); | |
912 var to = match[2] ? parseInt(match[2], 10) : totalPageCount; | |
913 | |
914 if (!to || from > to) | |
915 return false; | |
916 } else if (!isValidNonZeroPositiveInteger(part) || (totalPageCount != -1 && | |
917 !(parseInt(part, 10) <= totalPageCount))) { | |
918 return false; | |
919 } | |
920 successfullyParsed += 1; | |
921 } | |
922 return successfullyParsed > 0 | |
923 } | 858 } |
924 | 859 |
925 /** | 860 /** |
926 * Returns true if |value| is a valid non zero positive integer. | |
927 * @param {string} value The string to be tested. | |
928 */ | |
929 function isValidNonZeroPositiveInteger(value) { | |
930 return isInteger(value) && parseInt(value, 10) > 0; | |
931 } | |
932 | |
933 /** | |
934 * Parses the selected page ranges, processes them and returns the results. | |
935 * It squashes whenever possible. Example '1-2,3,5-7' becomes 1-3,5-7 | |
936 * | |
937 * @return {Array} an array of page range objects. A page range object has | |
938 * fields 'from' and 'to'. | |
939 */ | |
940 function getSelectedPageRanges() { | |
941 var pageList = getSelectedPagesSet(); | |
942 var pageRanges = []; | |
943 for (var i = 0; i < pageList.length; ++i) { | |
944 tempFrom = pageList[i]; | |
945 while (i + 1 < pageList.length && pageList[i + 1] == pageList[i] + 1) | |
946 ++i; | |
947 tempTo = pageList[i]; | |
948 pageRanges.push({'from': tempFrom, 'to': tempTo}); | |
949 } | |
950 return pageRanges; | |
951 } | |
952 | |
953 /** | |
954 * Returns the selected pages in ascending order without any duplicates. | |
955 */ | |
956 function getSelectedPagesSet() { | |
957 var pageList = getSelectedPages(); | |
958 pageList.sort(function(a,b) { return a - b; }); | |
959 pageList = removeDuplicates(pageList); | |
960 return pageList; | |
961 } | |
962 | |
963 /** | |
964 * Removes duplicate elements from |inArray| and returns a new array. | |
965 * |inArray| is not affected. It assumes that the array is already sorted. | |
966 * | |
967 * @param {Array} inArray The array to be processed. | |
968 */ | |
969 function removeDuplicates(inArray) { | |
970 var out = []; | |
971 | |
972 if(inArray.length == 0) | |
973 return out; | |
974 | |
975 out.push(inArray[0]); | |
976 for (var i = 1; i < inArray.length; ++i) | |
977 if(inArray[i] != inArray[i - 1]) | |
978 out.push(inArray[i]); | |
979 return out; | |
980 } | |
981 | |
982 /** | |
983 * Whenever the page range textfield gains focus we add a timer to detect when | 861 * Whenever the page range textfield gains focus we add a timer to detect when |
984 * the user stops typing in order to update the print preview. | 862 * the user stops typing in order to update the print preview. |
985 */ | 863 */ |
986 function addTimerToPageRangeField() { | 864 function addTimerToPageRangeField() { |
987 timerId = window.setTimeout(onPageSelectionMayHaveChanged, 1000); | 865 timerId = window.setTimeout(onPageSelectionMayHaveChanged, 1000); |
988 } | 866 } |
989 | 867 |
990 /** | 868 /** |
991 * As the user types in the page range textfield, we need to reset this timer, | 869 * As the user types in the page range textfield, we need to reset this timer, |
992 * since the page ranges are still being edited. | 870 * since the page ranges are still being edited. |
(...skipping 22 matching lines...) Expand all Loading... |
1015 updatePrintButtonState(); | 893 updatePrintButtonState(); |
1016 updatePrintSummary(); | 894 updatePrintSummary(); |
1017 return; | 895 return; |
1018 } | 896 } |
1019 | 897 |
1020 previouslySelectedPages = currentlySelectedPages; | 898 previouslySelectedPages = currentlySelectedPages; |
1021 requestPrintPreview(); | 899 requestPrintPreview(); |
1022 } | 900 } |
1023 | 901 |
1024 /** | 902 /** |
1025 * Returns true if the contents of the two arrays are equal. | |
1026 */ | |
1027 function areArraysEqual(array1, array2) { | |
1028 if (array1.length != array2.length) | |
1029 return false; | |
1030 for (var i = 0; i < array1.length; i++) | |
1031 if(array1[i] != array2[i]) | |
1032 return false; | |
1033 return true; | |
1034 } | |
1035 | |
1036 /** | |
1037 * Executed when the 'increment' or 'decrement' button is clicked. | 903 * Executed when the 'increment' or 'decrement' button is clicked. |
1038 */ | 904 */ |
1039 function onCopiesButtonsClicked(sign) { | 905 function onCopiesButtonsClicked(sign) { |
1040 var copiesField = $('copies'); | 906 var copiesField = $('copies'); |
1041 if (!isNumberOfCopiesValid()) | 907 if (!isNumberOfCopiesValid()) |
1042 copiesField.value = 1; | 908 copiesField.value = 1; |
1043 else { | 909 else { |
1044 var newValue = getCopies() + sign * 1; | 910 var newValue = getCopies() + sign * 1; |
1045 if (newValue < copiesField.min || newValue > copiesField.max) | 911 if (newValue < copiesField.min || newValue > copiesField.max) |
1046 return; | 912 return; |
(...skipping 10 matching lines...) Expand all Loading... |
1057 this.isLandscape = ''; | 923 this.isLandscape = ''; |
1058 } | 924 } |
1059 | 925 |
1060 /** | 926 /** |
1061 * Takes a snapshot of the print settings. | 927 * Takes a snapshot of the print settings. |
1062 */ | 928 */ |
1063 PrintSettings.prototype.save = function() { | 929 PrintSettings.prototype.save = function() { |
1064 this.deviceName = getSelectedPrinterName(); | 930 this.deviceName = getSelectedPrinterName(); |
1065 this.isLandscape = isLandscape(); | 931 this.isLandscape = isLandscape(); |
1066 } | 932 } |
OLD | NEW |