// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// require: cr/ui/print_preview_cloud.js
var localStrings = new LocalStrings();
// If useCloudPrint is true we attempt to connect to cloud print
// and populate the list of printers with cloud print printers.
var useCloudPrint = false;
// Store the last selected printer index.
var lastSelectedPrinterIndex = 0;
// Used to disable some printing options when the preview is not modifiable.
var previewModifiable = false;
// Destination list special value constants.
const MANAGE_CLOUD_PRINTERS = 'manageCloudPrinters';
const MANAGE_LOCAL_PRINTERS = 'manageLocalPrinters';
const SIGN_IN = 'signIn';
const PRINT_TO_PDF = 'Print to PDF';
const PRINT_WITH_CLOUD_PRINT = 'printWithCloudPrint';
// State of the print preview settings.
var printSettings = new PrintSettings();
// Print ready data index.
const PRINT_READY_DATA_INDEX = -1;
// The name of the default or last used printer.
var defaultOrLastUsedPrinterName = '';
// True when a pending print preview request exists.
var hasPendingPreviewRequest = false;
// True when the first page is loaded in the plugin.
var isFirstPageLoaded = false;
// The ID of the last preview request.
var lastPreviewRequestID = -1;
// The ID of the initial preview request.
var initialPreviewRequestID = -1;
// True when a pending print file request exists.
var hasPendingPrintDocumentRequest = false;
// True when the complete metafile for the previewed doc is ready.
var isPrintReadyMetafileReady = false;
// True when preview tab is hidden.
var isTabHidden = false;
// @type {print_preview.PrintHeader} Holds the print and cancel buttons.
var printHeader;
// @type {print_preview.PageSettings} Holds all the pages related settings.
var pageSettings;
// @type {print_preview.CopiesSettings} Holds all the copies related settings.
var copiesSettings;
// @type {print_preview.LayoutSettings} Holds all the layout related settings.
var layoutSettings;
// @type {print_preview.MarginSettings} Holds all the margin related settings.
var marginSettings;
// @type {print_preview.HeaderFooterSettings} Holds all the header footer
// related settings.
var headerFooterSettings;
// @type {print_preview.ColorSettings} Holds all the color related settings.
var colorSettings;
// @type {print_preview.PreviewArea} Holds information related to the preview
// area (on the right).
var previewArea;
// True if the user has click 'Advanced...' in order to open the system print
// dialog.
var showingSystemDialog = false;
// True if the user has clicked 'Open PDF in Preview' option.
var previewAppRequested = false;
// The range of options in the printer dropdown controlled by cloud print.
var firstCloudPrintOptionPos = 0;
var lastCloudPrintOptionPos = firstCloudPrintOptionPos;
// Store the current previewUid.
var currentPreviewUid = '';
// True if we need to generate draft preview data.
var generateDraftData = true;
// A dictionary of cloud printers that have been added to the printer
// dropdown.
var addedCloudPrinters = {};
// The maximum number of cloud printers to allow in the dropdown.
const maxCloudPrinters = 10;
const MIN_REQUEST_ID = 0;
const MAX_REQUEST_ID = 32000;
// Names of all the custom events used.
var customEvents = {
// Fired when the mouse moves while a margin line is being dragged.
MARGIN_LINE_DRAG: 'marginLineDrag',
// Fired when a mousedown event occurs on a margin line.
MARGIN_LINE_MOUSE_DOWN: 'marginLineMouseDown',
// Fired when a margin textbox gains focus.
MARGIN_TEXTBOX_FOCUSED: 'marginTextboxFocused',
// Fired when a new preview might be needed because of margin changes.
MARGINS_MAY_HAVE_CHANGED: 'marginsMayHaveChanged',
// Fired when a pdf generation related error occurs.
PDF_GENERATION_ERROR: 'PDFGenerationError',
// Fired once the first page of the pdf document is loaded in the plugin.
PDF_LOADED: 'PDFLoaded',
// Fired when the selected printer capabilities change.
PRINTER_CAPABILITIES_UPDATED: 'printerCapabilitiesUpdated',
// Fired when the print button needs to be updated.
UPDATE_PRINT_BUTTON: 'updatePrintButton',
// Fired when the print summary needs to be updated.
UPDATE_SUMMARY: 'updateSummary',
}
/**
* Window onload handler, sets up the page and starts print preview by getting
* the printer list.
*/
function onLoad() {
cr.enablePlatformSpecificCSSRules();
initialPreviewRequestID = randomInteger(MIN_REQUEST_ID, MAX_REQUEST_ID);
lastPreviewRequestID = initialPreviewRequestID;
previewArea = print_preview.PreviewArea.getInstance();
printHeader = print_preview.PrintHeader.getInstance();
document.addEventListener(customEvents.PDF_GENERATION_ERROR,
cancelPendingPrintRequest);
if (!checkCompatiblePluginExists()) {
disableInputElementsInSidebar();
$('cancel-button').focus();
previewArea.displayErrorMessageWithButtonAndNotify(
localStrings.getString('noPlugin'),
localStrings.getString('launchNativeDialog'),
launchNativePrintDialog);
$('mainview').parentElement.removeChild($('dummy-viewer'));
return;
}
$('system-dialog-link').addEventListener('click', onSystemDialogLinkClicked);
if (cr.isMac) {
$('open-pdf-in-preview-link').addEventListener(
'click', onOpenPdfInPreviewLinkClicked);
}
$('mainview').parentElement.removeChild($('dummy-viewer'));
$('printer-list').disabled = true;
pageSettings = print_preview.PageSettings.getInstance();
copiesSettings = print_preview.CopiesSettings.getInstance();
layoutSettings = print_preview.LayoutSettings.getInstance();
marginSettings = print_preview.MarginSettings.getInstance();
headerFooterSettings = print_preview.HeaderFooterSettings.getInstance();
colorSettings = print_preview.ColorSettings.getInstance();
$('printer-list').onchange = updateControlsWithSelectedPrinterCapabilities;
previewArea.showLoadingAnimation();
chrome.send('getInitialSettings');
}
/**
* @param {string} initiatorTabTitle The title of the initiator tab.
* @param {object} initialSettings An object containing all the initial
* settings.
*/
function setInitialSettings(initialSettings) {
setInitiatorTabTitle(initialSettings['initiatorTabTitle']);
previewModifiable = initialSettings['previewModifiable'];
if (previewModifiable) {
print_preview.MarginSettings.setNumberFormatAndMeasurementSystem(
initialSettings['numberFormat'],
initialSettings['measurementSystem']);
marginSettings.setLastUsedMargins(initialSettings);
}
setDefaultPrinter(initialSettings['printerName'],
initialSettings['cloudPrintData']);
}
/**
* Disables the input elements in the sidebar.
*/
function disableInputElementsInSidebar() {
var els = $('navbar-container').querySelectorAll('input, button, select');
for (var i = 0; i < els.length; i++) {
if (els[i] == printHeader.cancelButton)
continue;
els[i].disabled = true;
}
}
/**
* Enables the input elements in the sidebar.
*/
function enableInputElementsInSidebar() {
var els = $('navbar-container').querySelectorAll('input, button, select');
for (var i = 0; i < els.length; i++)
els[i].disabled = false;
}
/**
* Disables the controls in the sidebar, shows the throbber and instructs the
* backend to open the native print dialog.
*/
function onSystemDialogLinkClicked() {
if (showingSystemDialog)
return;
showingSystemDialog = true;
disableInputElementsInSidebar();
printHeader.disableCancelButton();
$('system-dialog-throbber').hidden = false;
chrome.send('showSystemDialog');
}
/**
* Disables the controls in the sidebar, shows the throbber and instructs the
* backend to open the pdf in native preview app. This is only for Mac.
*/
function onOpenPdfInPreviewLinkClicked() {
if (previewAppRequested)
return;
previewAppRequested = true;
disableInputElementsInSidebar();
$('open-preview-app-throbber').hidden = false;
printHeader.disableCancelButton();
requestToPrintDocument();
}
/**
* Similar to onSystemDialogLinkClicked(), but specific to the
* 'Launch native print dialog' UI.
*/
function launchNativePrintDialog() {
if (showingSystemDialog)
return;
showingSystemDialog = true;
previewArea.errorButton.disabled = true;
printHeader.disableCancelButton();
$('native-print-dialog-throbber').hidden = false;
chrome.send('showSystemDialog');
}
/**
* Gets the selected printer capabilities and updates the controls accordingly.
*/
function updateControlsWithSelectedPrinterCapabilities() {
var printerList = $('printer-list');
var selectedIndex = printerList.selectedIndex;
if (selectedIndex < 0)
return;
if (cr.isMac)
$('open-pdf-in-preview-link').disabled = false;
var skip_refresh = false;
var selectedValue = printerList.options[selectedIndex].value;
if (cloudprint.isCloudPrint(printerList.options[selectedIndex])) {
cloudprint.updatePrinterCaps(printerList.options[selectedIndex],
doUpdateCloudPrinterCapabilities);
skip_refresh = true;
} else if (selectedValue == SIGN_IN ||
selectedValue == MANAGE_CLOUD_PRINTERS ||
selectedValue == MANAGE_LOCAL_PRINTERS) {
printerList.selectedIndex = lastSelectedPrinterIndex;
chrome.send(selectedValue);
skip_refresh = true;
} else if (selectedValue == PRINT_TO_PDF ||
selectedValue == PRINT_WITH_CLOUD_PRINT) {
updateWithPrinterCapabilities({
'disableColorOption': true,
'setColorAsDefault': true,
'setDuplexAsDefault': false,
'printerColorModelForColor': print_preview.ColorSettings.COLOR,
'printerDefaultDuplexValue': copiesSettings.UNKNOWN_DUPLEX_MODE,
'disableCopiesOption': true});
if (cr.isChromeOS && selectedValue == PRINT_WITH_CLOUD_PRINT)
sendPrintDocumentRequest();
} else {
// This message will call back to 'updateWithPrinterCapabilities'
// function.
chrome.send('getPrinterCapabilities', [selectedValue]);
}
if (!skip_refresh) {
lastSelectedPrinterIndex = selectedIndex;
// Regenerate the preview data based on selected printer settings.
// Do not reset the margins if no preview request has been made.
var resetMargins = lastPreviewRequestID != initialPreviewRequestID;
setDefaultValuesAndRegeneratePreview(resetMargins);
}
}
/**
* Helper function to do the actual work of updating cloud printer
* capabilities.
* @param {Object} printer The printer object to set capabilities for.
*/
function doUpdateCloudPrinterCapabilities(printer) {
var settings = {'disableColorOption': !cloudprint.supportsColor(printer),
'setColorAsDefault': cloudprint.colorIsDefault(printer),
'disableCopiesOption': true,
'disableLandscapeOption': true};
updateWithPrinterCapabilities(settings);
var printerList = $('printer-list');
var selectedIndex = printerList.selectedIndex;
lastSelectedPrinterIndex = selectedIndex;
// Regenerate the preview data based on selected printer settings.
// Do not reset the margins if no preview request has been made.
var resetMargins = lastPreviewRequestID != initialPreviewRequestID;
setDefaultValuesAndRegeneratePreview(resetMargins);
}
/**
* Notifies listeners of |customEvents.PRINTER_CAPABILITIES_UPDATED| about the
* capabilities of the currently selected printer. It is called from C++ too.
* @param {Object} settingInfo printer setting information.
*/
function updateWithPrinterCapabilities(settingInfo) {
var customEvent = new cr.Event(customEvents.PRINTER_CAPABILITIES_UPDATED);
customEvent.printerCapabilities = settingInfo;
document.dispatchEvent(customEvent);
}
/**
* Reloads the printer list.
*/
function reloadPrintersList() {
$('printer-list').length = 0;
firstCloudPrintOptionPos = 0;
lastCloudPrintOptionPos = 0;
chrome.send('getPrinters');
}
/**
* Turn on the integration of Cloud Print.
* @param {string} cloudPrintUrl The URL to use for cloud print servers.
*/
function setUseCloudPrint(cloudPrintURL) {
useCloudPrint = true;
cloudprint.setBaseURL(cloudPrintURL);
}
/**
* Take the PDF data handed to us and submit it to the cloud, closing the print
* preview tab once the upload is successful.
* @param {string} data Data to send as the print job.
*/
function printToCloud(data) {
cloudprint.printToCloud(data, finishedCloudPrinting);
}
/**
* Cloud print upload of the PDF file is finished, time to close the dialog.
*/
function finishedCloudPrinting() {
closePrintPreviewTab();
}
/**
* Checks whether the specified settings are valid.
*
* @return {boolean} true if settings are valid, false if not.
*/
function areSettingsValid() {
var selectedPrinter = getSelectedPrinterName();
return pageSettings.isPageSelectionValid() &&
marginSettings.areMarginSettingsValid() &&
(copiesSettings.isValid() || selectedPrinter == PRINT_TO_PDF ||
selectedPrinter == PRINT_WITH_CLOUD_PRINT);
}
/**
* Creates an object based on the values in the printer settings.
*
* @return {Object} Object containing print job settings.
*/
function getSettings() {
var deviceName = getSelectedPrinterName();
var printToPDF = deviceName == PRINT_TO_PDF;
var printWithCloudPrint = deviceName == PRINT_WITH_CLOUD_PRINT;
var settings =
{'deviceName': deviceName,
'pageRange': pageSettings.selectedPageRanges,
'duplex': copiesSettings.duplexMode,
'copies': copiesSettings.numberOfCopies,
'collate': copiesSettings.isCollated(),
'landscape': layoutSettings.isLandscape(),
'color': colorSettings.colorMode,
'printToPDF': printToPDF,
'printWithCloudPrint': printWithCloudPrint,
'isFirstRequest' : false,
'headerFooterEnabled': headerFooterSettings.hasHeaderFooter(),
'marginsType': marginSettings.selectedMarginsValue,
'requestID': -1,
'generateDraftData': generateDraftData,
'previewModifiable': previewModifiable};
if (marginSettings.isCustomMarginsSelected())
settings['marginsCustom'] = marginSettings.customMargins;
var printerList = $('printer-list');
var selectedPrinter = printerList.selectedIndex;
if (cloudprint.isCloudPrint(printerList.options[selectedPrinter])) {
settings['cloudPrintID'] =
printerList.options[selectedPrinter].value;
}
return settings;
}
/**
* Creates an object based on the values in the printer settings.
* Note: |lastPreviewRequestID| is being modified every time this function is
* called. Only call this function when a preview request is actually sent,
* otherwise (for example when debugging) call getSettings().
*
* @return {Object} Object containing print job settings.
*/
function getSettingsWithRequestID() {
var settings = getSettings();
settings.requestID = generatePreviewRequestID();
settings.isFirstRequest = isFirstPreviewRequest();
return settings;
}
/**
* @return {number} The next unused preview request id.
*/
function generatePreviewRequestID() {
return ++lastPreviewRequestID;
}
/**
* @return {boolean} True iff a preview has been requested.
*/
function hasRequestedPreview() {
return lastPreviewRequestID != initialPreviewRequestID;
}
/**
* @return {boolean} True if |lastPreviewRequestID| corresponds to the initial
* preview request.
*/
function isFirstPreviewRequest() {
return lastPreviewRequestID == initialPreviewRequestID + 1;
}
/**
* Checks if |previewResponseId| matches |lastPreviewRequestId|. Used to ignore
* obsolete preview data responses.
* @param {number} previewResponseId The id to check.
* @return {boolean} True if previewResponseId reffers to the expected response.
*/
function isExpectedPreviewResponse(previewResponseId) {
return lastPreviewRequestID == previewResponseId;
}
/**
* Returns the name of the selected printer or the empty string if no
* printer is selected.
* @return {string} The name of the currently selected printer.
*/
function getSelectedPrinterName() {
var printerList = $('printer-list')
var selectedPrinter = printerList.selectedIndex;
if (selectedPrinter < 0)
return '';
return printerList.options[selectedPrinter].value;
}
/**
* Asks the browser to print the preview PDF based on current print
* settings. If the preview is still loading, printPendingFile() will get
* called once the preview loads.
*/
function requestToPrintDocument() {
hasPendingPrintDocumentRequest = !isPrintReadyMetafileReady;
var selectedPrinterName = getSelectedPrinterName();
var printToPDF = selectedPrinterName == PRINT_TO_PDF;
var printWithCloudPrint = selectedPrinterName == PRINT_WITH_CLOUD_PRINT;
if (hasPendingPrintDocumentRequest) {
if (previewAppRequested) {
previewArea.showCustomMessage(
localStrings.getString('openingPDFInPreview'));
} else if (printToPDF) {
sendPrintDocumentRequest();
} else if (printWithCloudPrint) {
previewArea.showCustomMessage(
localStrings.getString('printWithCloudPrintWait'));
disableInputElementsInSidebar();
} else {
isTabHidden = true;
chrome.send('hidePreview');
}
return;
}
if (printToPDF || previewAppRequested) {
sendPrintDocumentRequest();
} else {
window.setTimeout(function() { sendPrintDocumentRequest(); }, 1000);
}
}
/**
* Sends a message to cancel the pending print request.
*/
function cancelPendingPrintRequest() {
if (isTabHidden)
chrome.send('cancelPendingPrintRequest');
}
/**
* Sends a message to initiate print workflow.
*/
function sendPrintDocumentRequest() {
var printerList = $('printer-list');
var printer = printerList[printerList.selectedIndex];
chrome.send('saveLastPrinter', [printer.value, cloudprint.getData(printer)]);
var settings = getSettings();
if (cr.isMac && previewAppRequested)
settings.OpenPDFInPreview = true;
chrome.send('print', [JSON.stringify(settings),
cloudprint.getPrintTicketJSON(printer)]);
}
/**
* Loads the selected preview pages.
*/
function loadSelectedPages() {
pageSettings.updatePageSelection();
var pageSet = pageSettings.previouslySelectedPages;
var pageCount = pageSet.length;
if (pageCount == 0 || currentPreviewUid == '')
return;
cr.dispatchSimpleEvent(document, customEvents.UPDATE_SUMMARY);
for (var i = 0; i < pageCount; i++)
onDidPreviewPage(pageSet[i] - 1, currentPreviewUid, lastPreviewRequestID);
}
/**
* Asks the browser to generate a preview PDF based on current print settings.
*/
function requestPrintPreview() {
if (!isTabHidden)
previewArea.showLoadingAnimation();
if (!hasPendingPreviewRequest && previewModifiable &&
hasOnlyPageSettingsChanged()) {
loadSelectedPages();
generateDraftData = false;
} else {
hasPendingPreviewRequest = true;
generateDraftData = true;
pageSettings.updatePageSelection();
}
printSettings.save();
layoutSettings.updateState();
previewArea.resetState();
isPrintReadyMetafileReady = false;
isFirstPageLoaded = false;
var totalPageCount = pageSettings.totalPageCount;
if (!previewModifiable && totalPageCount > 0)
generateDraftData = false;
var pageCount = totalPageCount != undefined ? totalPageCount : -1;
chrome.send('getPreview', [JSON.stringify(getSettingsWithRequestID()),
pageCount,
previewModifiable]);
}
/**
* Called from PrintPreviewUI::OnFileSelectionCancelled to notify the print
* preview tab regarding the file selection cancel event.
*/
function fileSelectionCancelled() {
printHeader.enableCancelButton();
}
/**
* Called from PrintPreviewUI::OnFileSelectionCompleted to notify the print
* preview tab regarding the file selection completed event.
*/
function fileSelectionCompleted() {
// If the file selection is completed and the tab is not already closed it
// means that a pending print to pdf request exists.
disableInputElementsInSidebar();
previewArea.showCustomMessage(
localStrings.getString('printingToPDFInProgress'));
}
/**
* Set the default printer. If there is one, generate a print preview.
* @param {string} printer Name of the default printer. Empty if none.
* @param {string} cloudPrintData Cloud print related data to restore if
* the default printer is a cloud printer.
*/
function setDefaultPrinter(printerName, cloudPrintData) {
// Add a placeholder value so the printer list looks valid.
addDestinationListOption('', '', true, true, true);
if (printerName) {
defaultOrLastUsedPrinterName = printerName;
if (cloudPrintData) {
cloudprint.setDefaultPrinter(printerName,
cloudPrintData,
addDestinationListOptionAtPosition,
doUpdateCloudPrinterCapabilities);
} else {
$('printer-list')[0].value = defaultOrLastUsedPrinterName;
updateControlsWithSelectedPrinterCapabilities();
}
}
chrome.send('getPrinters');
}
/**
* Fill the printer list drop down.
* Called from PrintPreviewHandler::SetupPrinterList().
* @param {Array} printers Array of printer info objects.
*/
function setPrinters(printers) {
var printerList = $('printer-list');
// Remove empty entry added by setDefaultPrinter.
if (printerList[0] && printerList[0].textContent == '')
printerList.remove(0);
for (var i = 0; i < printers.length; ++i) {
var isDefault = (printers[i].deviceName == defaultOrLastUsedPrinterName);
addDestinationListOption(printers[i].printerName, printers[i].deviceName,
isDefault, false, false);
}
if (printers.length != 0)
addDestinationListOption('', '', false, true, true);
// Adding option for saving PDF to disk.
addDestinationListOption(localStrings.getString('printToPDF'),
PRINT_TO_PDF,
defaultOrLastUsedPrinterName == PRINT_TO_PDF,
false,
false);
addDestinationListOption('', '', false, true, true);
if (useCloudPrint) {
addDestinationListOption(localStrings.getString('printWithCloudPrint'),
PRINT_WITH_CLOUD_PRINT,
false,
false,
false);
addDestinationListOption('', '', false, true, true);
}
// Add options to manage printers.
if (!cr.isChromeOS) {
addDestinationListOption(localStrings.getString('managePrinters'),
MANAGE_LOCAL_PRINTERS, false, false, false);
} else if (useCloudPrint) {
// Fetch recent printers.
cloudprint.fetchPrinters(addDestinationListOptionAtPosition, false);
// Fetch the full printer list.
cloudprint.fetchPrinters(addDestinationListOptionAtPosition, true);
addDestinationListOption(localStrings.getString('managePrinters'),
MANAGE_CLOUD_PRINTERS, false, false, false);
}
printerList.disabled = false;
if (!hasRequestedPreview())
updateControlsWithSelectedPrinterCapabilities();
}
/**
* Creates an option that can be added to the printer destination list.
* @param {string} optionText specifies the option text content.
* @param {string} optionValue specifies the option value.
* @param {boolean} isDefault is true if the option needs to be selected.
* @param {boolean} isDisabled is true if the option needs to be disabled.
* @param {boolean} isSeparator is true if the option is a visual separator and
* needs to be disabled.
* @return {Object} The created option.
*/
function createDestinationListOption(optionText, optionValue, isDefault,
isDisabled, isSeparator) {
var option = document.createElement('option');
option.textContent = optionText;
option.value = optionValue;
option.selected = isDefault;
option.disabled = isSeparator || isDisabled;
// Adding attribute for improved accessibility.
if (isSeparator)
option.setAttribute('role', 'separator');
return option;
}
/**
* Adds an option to the printer destination list.
* @param {string} optionText specifies the option text content.
* @param {string} optionValue specifies the option value.
* @param {boolean} isDefault is true if the option needs to be selected.
* @param {boolean} isDisabled is true if the option needs to be disabled.
* @return {Object} The created option.
*/
function addDestinationListOption(optionText, optionValue, isDefault,
isDisabled, isSeparator) {
var option = createDestinationListOption(optionText,
optionValue,
isDefault,
isDisabled,
isSeparator);
$('printer-list').add(option);
return option;
}
/**
* Adds an option to the printer destination list at a specified position.
* @param {number} position The index in the printer-list wher the option
should be created.
* @param {string} optionText specifies the option text content.
* @param {string} optionValue specifies the option value.
* @param {boolean} isDefault is true if the option needs to be selected.
* @param {boolean} isDisabled is true if the option needs to be disabled.
* @return {Object} The created option.
*/
function addDestinationListOptionAtPosition(position,
optionText,
optionValue,
isDefault,
isDisabled,
isSeparator) {
var option = createDestinationListOption(optionText,
optionValue,
isDefault,
isDisabled,
isSeparator);
var printerList = $('printer-list');
var before = printerList[position];
printerList.add(option, before);
return option;
}
/**
* Sets the color mode for the PDF plugin.
* Called from PrintPreviewHandler::ProcessColorSetting().
* @param {boolean} color is true if the PDF plugin should display in color.
*/
function setColor(color) {
var pdfViewer = $('pdf-viewer');
if (!pdfViewer) {
return;
}
pdfViewer.grayscale(!color);
var printerList = $('printer-list');
cloudprint.setColor(printerList[printerList.selectedIndex], color);
}
/**
* Display an error message when print preview fails.
* Called from PrintPreviewMessageHandler::OnPrintPreviewFailed().
*/
function printPreviewFailed() {
previewArea.displayErrorMessageWithButtonAndNotify(
localStrings.getString('previewFailed'),
localStrings.getString('launchNativeDialog'),
launchNativePrintDialog);
}
/**
* Display an error message when encountered invalid printer settings.
* Called from PrintPreviewMessageHandler::OnInvalidPrinterSettings().
*/
function invalidPrinterSettings() {
if (cr.isMac) {
if (previewAppRequested) {
$('open-preview-app-throbber').hidden = true;
previewArea.clearCustomMessageWithDots();
previewAppRequested = false;
hasPendingPrintDocumentRequest = false;
enableInputElementsInSidebar();
}
$('open-pdf-in-preview-link').disabled = true;
}
previewArea.displayErrorMessageAndNotify(
localStrings.getString('invalidPrinterSettings'));
}
/**
* Called when the PDF plugin loads its document.
*/
function onPDFLoad() {
if (previewModifiable) {
setPluginPreviewPageCount();
}
cr.dispatchSimpleEvent(document, customEvents.PDF_LOADED);
isFirstPageLoaded = true;
checkAndHideOverlayLayerIfValid();
sendPrintDocumentRequestIfNeeded();
}
function setPluginPreviewPageCount() {
$('pdf-viewer').printPreviewPageCount(
pageSettings.previouslySelectedPages.length);
}
/**
* Update the page count and check the page range.
* Called from PrintPreviewUI::OnDidGetPreviewPageCount().
* @param {number} pageCount The number of pages.
* @param {number} previewResponseId The preview request id that resulted in
* this response.
*/
function onDidGetPreviewPageCount(pageCount, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
return;
pageSettings.updateState(pageCount);
if (!previewModifiable && pageSettings.requestPrintPreviewIfNeeded())
return;
cr.dispatchSimpleEvent(document, customEvents.UPDATE_SUMMARY);
}
/**
* @param {printing::PageSizeMargins} pageLayout The default layout of the page
* in points.
*/
function onDidGetDefaultPageLayout(pageLayout) {
marginSettings.currentDefaultPageLayout = new print_preview.PageLayout(
pageLayout.contentWidth,
pageLayout.contentHeight,
pageLayout.marginLeft,
pageLayout.marginTop,
pageLayout.marginRight,
pageLayout.marginBottom);
}
/**
* This function sends a request to hide the overlay layer only if there is no
* pending print document request and we are not waiting for the print ready
* metafile.
*/
function checkAndHideOverlayLayerIfValid() {
var selectedPrinter = getSelectedPrinterName();
var printToDialog = selectedPrinter == PRINT_TO_PDF ||
selectedPrinter == PRINT_WITH_CLOUD_PRINT;
if ((printToDialog || !previewModifiable) &&
!isPrintReadyMetafileReady && hasPendingPrintDocumentRequest) {
return;
}
previewArea.hideOverlayLayer();
}
/**
* Called when no pipelining previewed pages.
* @param {string} previewUid Preview unique identifier.
* @param {number} previewResponseId The preview request id that resulted in
* this response.
*/
function reloadPreviewPages(previewUid, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
return;
cr.dispatchSimpleEvent(document, customEvents.UPDATE_PRINT_BUTTON);
checkAndHideOverlayLayerIfValid();
var pageSet = pageSettings.previouslySelectedPages;
for (var i = 0; i < pageSet.length; i++)
$('pdf-viewer').loadPreviewPage(getPageSrcURL(previewUid, pageSet[i]-1), i);
hasPendingPreviewRequest = false;
isPrintReadyMetafileReady = true;
previewArea.pdfLoaded = true;
sendPrintDocumentRequestIfNeeded();
}
/**
* Notification that a print preview page has been rendered.
* Check if the settings have changed and request a regeneration if needed.
* Called from PrintPreviewUI::OnDidPreviewPage().
* @param {number} pageNumber The page number, 0-based.
* @param {string} previewUid Preview unique identifier.
* @param {number} previewResponseId The preview request id that resulted in
* this response.
*/
function onDidPreviewPage(pageNumber, previewUid, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
return;
// Refactor
if (!previewModifiable)
return;
if (pageSettings.requestPrintPreviewIfNeeded())
return;
var pageIndex = pageSettings.previouslySelectedPages.indexOf(pageNumber + 1);
if (pageIndex == -1)
return;
currentPreviewUid = previewUid;
if (pageIndex == 0)
createPDFPlugin(pageNumber);
$('pdf-viewer').loadPreviewPage(
getPageSrcURL(previewUid, pageNumber), pageIndex);
if (pageIndex + 1 == pageSettings.previouslySelectedPages.length) {
hasPendingPreviewRequest = false;
if (pageIndex != 0)
sendPrintDocumentRequestIfNeeded();
}
}
/**
* Update the print preview when new preview data is available.
* Create the PDF plugin as needed.
* Called from PrintPreviewUI::PreviewDataIsAvailable().
* @param {boolean} modifiable If the preview is modifiable.
* @param {string} previewUid Preview unique identifier.
* @param {number} previewResponseId The preview request id that resulted in
* this response.
*/
function updatePrintPreview(previewUid, previewResponseId) {
if (!isExpectedPreviewResponse(previewResponseId))
return;
isPrintReadyMetafileReady = true;
if (!previewModifiable) {
// If the preview is not modifiable the plugin has not been created yet.
currentPreviewUid = previewUid;
hasPendingPreviewRequest = false;
createPDFPlugin(PRINT_READY_DATA_INDEX);
}
cr.dispatchSimpleEvent(document, customEvents.UPDATE_PRINT_BUTTON);
if (previewModifiable)
sendPrintDocumentRequestIfNeeded();
}
/**
* Checks to see if the requested print data is available for printing and
* sends a print document request if needed.
*/
function sendPrintDocumentRequestIfNeeded() {
if (!hasPendingPrintDocumentRequest || !isFirstPageLoaded)
return;
// If the selected printer is PRINT_TO_PDF or PRINT_WITH_CLOUD_PRINT or
// the preview source is not modifiable, we need the print ready data for
// printing. If the preview source is modifiable, we need to wait till all
// the requested pages are loaded in the plugin for printing.
var selectedPrinter = getSelectedPrinterName();
var printToDialog = selectedPrinter == PRINT_TO_PDF ||
selectedPrinter == PRINT_WITH_CLOUD_PRINT;
if (((printToDialog || !previewModifiable) && !isPrintReadyMetafileReady) ||
(previewModifiable && hasPendingPreviewRequest)) {
return;
}
hasPendingPrintDocumentRequest = false;
if (!areSettingsValid()) {
cancelPendingPrintRequest();
return;
}
sendPrintDocumentRequest();
}
/**
* Check if only page selection has been changed since the last preview request
* and is valid.
* @return {boolean} true if the new page selection is valid.
*/
function hasOnlyPageSettingsChanged() {
var tempPrintSettings = new PrintSettings();
tempPrintSettings.save();
return !!(printSettings.deviceName == tempPrintSettings.deviceName &&
printSettings.isLandscape == tempPrintSettings.isLandscape &&
printSettings.hasHeaderFooter ==
tempPrintSettings.hasHeaderFooter &&
pageSettings.hasPageSelectionChangedAndIsValid());
}
/**
* Create the PDF plugin or reload the existing one.
* @param {number} srcDataIndex Preview data source index.
*/
function createPDFPlugin(srcDataIndex) {
var pdfViewer = $('pdf-viewer');
var srcURL = getPageSrcURL(currentPreviewUid, srcDataIndex);
if (pdfViewer) {
// Need to call this before the reload(), where the plugin resets its
// internal page count.
pdfViewer.goToPage('0');
pdfViewer.resetPrintPreviewUrl(srcURL);
pdfViewer.reload();
pdfViewer.grayscale(
colorSettings.colorMode == print_preview.ColorSettings.GRAY);
return;
}
pdfViewer = document.createElement('embed');
pdfViewer.setAttribute('id', 'pdf-viewer');
pdfViewer.setAttribute('type',
'application/x-google-chrome-print-preview-pdf');
pdfViewer.setAttribute('src', srcURL);
pdfViewer.setAttribute('aria-live', 'polite');
pdfViewer.setAttribute('aria-atomic', 'true');
$('mainview').appendChild(pdfViewer);
pdfViewer.onload('onPDFLoad()');
pdfViewer.onScroll('onPreviewPositionChanged()');
pdfViewer.onPluginSizeChanged('onPreviewPositionChanged()');
pdfViewer.removePrintButton();
pdfViewer.grayscale(true);
}
/**
* Called either when there is a scroll event or when the plugin size changes.
*/
function onPreviewPositionChanged() {
marginSettings.onPreviewPositionChanged();
}
/**
* @return {boolean} true if a compatible pdf plugin exists.
*/
function checkCompatiblePluginExists() {
var dummyPlugin = $('dummy-viewer');
var pluginInterface = [ dummyPlugin.onload,
dummyPlugin.goToPage,
dummyPlugin.removePrintButton,
dummyPlugin.loadPreviewPage,
dummyPlugin.printPreviewPageCount,
dummyPlugin.resetPrintPreviewUrl,
dummyPlugin.onPluginSizeChanged,
dummyPlugin.onScroll,
dummyPlugin.pageXOffset,
dummyPlugin.pageYOffset,
dummyPlugin.setZoomLevel,
dummyPlugin.setPageXOffset,
dummyPlugin.setPageYOffset,
dummyPlugin.getHorizontalScrollbarThickness,
dummyPlugin.getVerticalScrollbarThickness,
dummyPlugin.getPageLocationNormalized,
dummyPlugin.getHeight,
dummyPlugin.getWidth ];
for (var i = 0; i < pluginInterface.length; i++) {
if (!pluginInterface[i])
return false;
}
return true;
}
/**
* Sets the default values and sends a request to regenerate preview data.
* Resets the margin options only if |resetMargins| is true.
*/
function setDefaultValuesAndRegeneratePreview(resetMargins) {
if (resetMargins)
marginSettings.resetMarginsIfNeeded();
pageSettings.resetState();
requestPrintPreview();
}
/**
* Class that represents the state of the print settings.
*/
function PrintSettings() {
this.deviceName = '';
this.isLandscape = '';
this.hasHeaderFooter = '';
}
/**
* Takes a snapshot of the print settings.
*/
PrintSettings.prototype.save = function() {
this.deviceName = getSelectedPrinterName();
this.isLandscape = layoutSettings.isLandscape();
this.hasHeaderFooter = headerFooterSettings.hasHeaderFooter();
}
/**
* Updates the title of the print preview tab according to |initiatorTabTitle|.
* @param {string} initiatorTabTitle The title of the initiator tab.
*/
function setInitiatorTabTitle(initiatorTabTitle) {
if (initiatorTabTitle == '')
return;
document.title = localStrings.getStringF(
'printPreviewTitleFormat', initiatorTabTitle);
}
/**
* Closes this print preview tab.
*/
function closePrintPreviewTab() {
chrome.send('closePrintPreviewTab');
chrome.send('DialogClose');
}
/**
* Handle keyboard events.
* @param {KeyboardEvent} e The keyboard event.
*/
function onKeyDown(e) {
// Escape key closes the dialog.
if (e.keyCode == 27 && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
printHeader.disableCancelButton();
closePrintPreviewTab();
}
if (e.keyCode == 80) {
if ((cr.isMac && e.metaKey && e.altKey && !e.shiftKey && !e.ctrlKey) ||
(!cr.isMac && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey)) {
window.onkeydown = null;
onSystemDialogLinkClicked();
}
}
}
window.addEventListener('DOMContentLoaded', onLoad);
window.onkeydown = onKeyDown;
/// Pull in all other scripts in a single shot.