Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1605)

Unified Diff: chrome/browser/resources/print_preview/data/print_ticket_store.js

Issue 10108001: Refactor print preview web ui (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review feedback Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/print_preview/data/print_ticket_store.js
diff --git a/chrome/browser/resources/print_preview/data/print_ticket_store.js b/chrome/browser/resources/print_preview/data/print_ticket_store.js
new file mode 100644
index 0000000000000000000000000000000000000000..67bc86f82371395a5d3255edb01dd42ead80cc6a
--- /dev/null
+++ b/chrome/browser/resources/print_preview/data/print_ticket_store.js
@@ -0,0 +1,608 @@
+// Copyright (c) 2012 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.
+
+// TODO Optimize this to not dispatch CHANGE events when nothing really changed.
+
+cr.define('print_preview', function() {
+ 'use strict';
+
+ /**
+ * Storage of the print ticket and document statistics.
+ *
+ * Dispatches events when the contents of the print ticket or document
+ * statistics change. Also handles validation of the print ticket against
+ * destination capabilities and against the document.
+ *
+ * @constructor
+ * @extends {cr.EventTarget}
+ */
+ function PrintTicketStore() {
+ cr.EventTarget.call(this);
+
+ /**
+ * Information about the document to print.
+ * @type {DocumentInfo}
+ * @private
+ */
+ this.documentInfo_ = new DocumentInfo();
+
+ /**
+ * Printing capabilities of Chromium and the currently selected destination.
+ * @type {print_preview.ChromiumCapabilities}
+ * @private
+ */
+ this.capabilities_ = null;
+
+ /**
+ * Print ticket information. Used to print and generate previews.
+ * @type {print_preview.ChromiumPrintTicket}
+ * @private
+ */
+ this.ticket_ = null;
+
+ /**
+ * Current measurement system. Used to work with margin measurements.
+ * @type {print_preview.MeasurementSystem}
+ * @private
+ */
+ this.measurementSystem_ = null;
+
+ /**
+ * Cached page number set. Used to not have to parse page range string
+ * everytime its requested.
+ * @type {print_preview.PageNumberSet}
+ * @private
+ */
+ this.pageNumberSet_ = null;
+ };
+
+ /**
+ * Events dispatched by the print ticket store.
+ * @enum {string}
+ */
+ PrintTicketStore.Event = {
+ CAPABILITIES_CHANGE: 'print_preview.PrintTicketStore.CAPABILITIES_CHANGE',
+ DOCUMENT_CHANGE: 'print_preview.PrintTicketStore.DOCUMENT_CHANGE',
+ INITIALIZE: 'print_preview.PrintTicketStore.INITIALIZE',
+ TICKET_CHANGE: 'print_preview.PrintTicketStore.TICKET_CHANGE'
+ };
+
+ /**
+ * Minimum size in points the margins need to be to fit a header or footer.
+ * TODO: Figure out someway to actually calculate this value.
+ * @type {number}
+ * @const
+ * @private
+ */
+ PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_ = 0;
+
+ PrintTicketStore.prototype = {
+ __proto__: cr.EventTarget.prototype,
+
+ /** @override */
+ dispatchEvent: function(evt) {
+ // TODO REMOVE ME
+ log(evt.type);
+ cr.EventTarget.prototype.dispatchEvent.call(this, evt);
+ },
+
+ /**
+ * @return {boolean} Whether the print ticket store has been initialized.
+ */
+ get isInitialized() {
+ return !!this.ticket_;
+ },
+
+ /** @return {boolean} Whether the document is modifiable. */
+ get isDocumentModifiable() {
+ return this.documentInfo_.isModifiable;
+ },
+
+ /** @return {number} Number of pages in the document. */
+ get pageCount() {
+ return this.documentInfo_.pageCount;
+ },
+
+ /**
+ * @param {number} pageCount New number of pages in the document.
+ * Dispatches a DOCUMENT_CHANGE event if the value changes.
+ */
+ updatePageCount: function(pageCount) {
+ if (this.documentInfo_.pageCount != pageCount) {
+ this.documentInfo_.pageCount = pageCount;
+ this.pageNumberSet_ = null;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
+ }
+ },
+
+ /**
+ * @return {!print_preview.PrintableArea} Printable area of the document in
+ * points.
+ */
+ get printableArea() {
+ return this.documentInfo_.printableArea;
+ },
+
+ /**
+ * @param {!print_preview.PrintableArea} printableArea New printable area of
+ * the document in points. Dispatches a DOCUMENT_CHANGE event if the
+ * value changes.
+ */
+ updatePrintableArea: function(printableArea) {
+ if (!this.documentInfo_.printableArea.equals(printableArea)) {
+ log('PrintableArea: ' + printableArea.origin.x + ' ' +
+ printableArea.origin.y + ' ' + printableArea.size.width + ' ' +
+ printableArea.size.height);
+ this.documentInfo_.printableArea = printableArea;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
+ }
+ },
+
+ /** @return {!print_preview.Size} Size of the document in points. */
+ get pageSize() {
+ return this.documentInfo_.pageSize;
+ },
+
+ /**
+ * @param {!print_preview.Size} pageSize New size of the document.
+ * Dispatches a DOCUMENT_CHANGE event if the value changes.
+ */
+ updatePageSize: function(pageSize) {
+ if (!this.documentInfo_.pageSize.equals(pageSize)) {
+ log('Updating page size to: ' + pageSize.width + ' ' + pageSize.height);
+ this.documentInfo_.pageSize = pageSize;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.DOCUMENT_CHANGE);
+ }
+ },
+
+ /**
+ * @return {!print_preview.MeasurementSystem} Measurement system of the
+ * local system.
+ */
+ get measurementSystem() {
+ if (!this.isInitialized) {
+ throw Error(
+ 'Trying to get measurement system before ticket is initialized');
+ }
+ return /** @type {!print_preview.MeasurementSystem} */ (this.
+ measurementSystem_);
+ },
+
+ /**
+ * Initializes the print ticket store. Dispatches an INITIALIZE event.
+ * @param {boolean} isDocumentModifiable Whether the document to print is
+ * modifiable (i.e. can be re-flowed by Chromium).
+ * @param {boolean} isDuplexEnabled Previous duplex setting.
+ * @param {boolean} isHeaderFooterEnabled Previous header-footer setting.
+ * @param {print_preview.Margins.Type} marginsType Previous margins type.
+ * @param {print_preview.Margins} customMargins Initial custom margins.
+ * @param {!print_preview.MeasurementSystem} measurementSystem Measurement
+ * system of the local system.
+ */
+ initialize: function(
+ isDocumentModifiable,
+ isDuplexEnabled,
+ isHeaderFooterEnabled,
+ marginsType,
+ customMargins,
+ measurementSystem) {
+
+ this.documentInfo_.isModifiable = isDocumentModifiable;
+
+ // Create capabilities that can be handled by Chromium before any
+ // particular print destination is selected.
+ this.capabilities_ = new print_preview.ChromiumCapabilities(
+ true /*hasCopiesCapability*/,
+ '1' /*defaultCopiesStr*/,
+ true /*hasCollateCapability*/,
+ true /*defaultIsCollateEnabled*/,
+ true /*hasDuplexCapability*/,
+ true /*defaultIsDuplexEnabled*/,
+ true /*hasOrientationCapability*/,
+ false /*defaultIsLandscapeEnabled*/,
+ true /*hasColorCapability*/,
+ true /*defaultIsColorEnabled*/);
+
+ // Initialize ticket with user's previous values.
+ this.ticket_ = new print_preview.ChromiumPrintTicket(this.capabilities_);
+ this.ticket_.isDuplexEnabled = isDuplexEnabled;
+ this.ticket_.marginsType = marginsType;
+ this.ticket_.customMargins = customMargins;
+ this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
+
+ // Initialize measurement system.
+ this.measurementSystem_ = measurementSystem;
+
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.INITIALIZE);
+ },
+
+ /**
+ * Updates the capabilities of the destination the print ticket is for.
+ * Dispatches a CAPABILITIES_CHANGE event.
+ * @param {!print_preview.ChromiumCapabilities} caps New capabilities.
+ */
+ updateDestinationCapabilities: function(caps) {
+ this.capabilities_ = caps;
+ this.ticket_.capabilities = caps;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.CAPABILITIES_CHANGE);
+ },
+
+ /** @return {boolean} Whether the ticket store has the copies capability. */
+ hasCopiesCapability: function() {
+ return this.capabilities_.hasCopiesCapability;
+ },
+
+ /**
+ * @return {boolean} Whether the string representation of the copies value
+ * currently in the ticket store is valid.
+ */
+ isCopiesValid: function() {
+ return this.isCopiesValidForValue(this.ticket_.copiesStr);
+ },
+
+ /**
+ * @param {string} value String representation of the number of print
+ * copies.
+ * @return {boolean} Whether the given value is valid--an integer in the
+ * range [1, 999].
+ */
+ isCopiesValidForValue: function(value) {
+ if (/[^\d]+/.test(value)) {
+ return false;
+ }
+ var copies = parseInt(value);
+ if (copies > 999 || copies < 1) {
+ return false;
+ }
+ return true;
+ },
+
+ /** @return {number} Number of copies to print. */
+ getCopies: function() {
+ return parseInt(this.ticket_.copiesStr);
+ },
+
+ /**
+ * @return {string} String representation of the number of copies to print.
+ */
+ getCopiesStr: function() {
+ return this.ticket_.copiesStr;
+ },
+
+ /**
+ * Updates the string representation of the number of copies to print.
+ * Dispatches a TICKET_CHANGE event if the string value has changed.
+ * @param {string} New string representation of the number of copies to
+ * print.
+ */
+ updateCopies: function(copies) {
+ if (!this.hasCopiesCapability()) {
+ throw Error(
+ 'Updating copies capability but destination does not have a ' +
+ 'copies capability');
+ }
+ if (this.ticket_.copiesStr != copies) {
+ this.ticket_.copiesStr = copies;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {boolean} Whether the ticket store has a collate capability. */
+ hasCollateCapability: function() {
+ return this.capabilities_.hasCollateCapability;
+ },
+
+ /** @return {boolean} Whether collate is enabled. */
+ isCollateEnabled: function() {
+ return this.ticket_.isCollateEnabled;
+ },
+
+ /**
+ * Updates whether collate is enabled. Dispatches a TICKET_CHANGE event if
+ * collate has changed.
+ * @param {boolean} isCollate Whether collate is enabled.
+ */
+ updateCollate: function(isCollate) {
+ if (!this.hasCollateCapability()) {
+ throw Error(
+ 'Updating collate capability but destination does not have a ' +
+ 'collate capability');
+ }
+ if (this.ticket_.isCollateEnabled != isCollate) {
+ this.ticket_.isCollateEnabled = isCollate;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /**
+ * @return {boolean} Whether the ticket store has color printing capability.
+ */
+ hasColorCapability: function() {
+ return this.capabilities_.hasColorCapability;
+ },
+
+ /**
+ * @return {boolean} Whether color printing is enabled.
+ */
+ isColorEnabled: function() {
+ return this.ticket_.isColorEnabled;
+ },
+
+ /**
+ * Updates whether color printing is enabled. Dispatches a TICKET_CHANGE if
+ * color has changed.
+ * @param {boolean} isColor Whether the color printing is enabled.
+ */
+ updateColor: function(isColor) {
+ if (!this.hasColorCapability()) {
+ throw Error(
+ 'Updating color capability but destination does not have a color ' +
+ 'capability');
+ }
+ if (this.ticket_.isColorEnabled != isColor) {
+ this.ticket_.isColorEnabled = isColor;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {boolean} Whether the header-footer capability is available. */
+ hasHeaderFooterCapability: function() {
+ // Checks the printable area and updates the visibility of header footer
+ // option based on the selected margins.
+ if (!this.documentInfo_.isModifiable ||
+ this.ticket_.marginsType == print_preview.Margins.Type.NO_MARGINS) {
+ return false;
+ }
+ if (this.ticket_.marginsType == print_preview.Margins.Type.CUSTOM) {
+ var margins = this.ticket_.customMargins;
+ // TODO This condition only checks if the margin is non-zero. It should
+ // check whether the margin is large enough to render the header-footer.
+ var availableTopMargin = this.documentInfo_.printableArea.origin.y -
+ PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_;
+ var availbleBottomMargin = this.documentInfo_.pageSize.height -
+ this.documentInfo_.printableArea.origin.y -
+ this.documentInfo_.printableArea.size.height -
+ PrintTicketStore.MINIMUM_HEADER_FOOTER_HEIGHT_;
+ if (margins.top < availableTopMargin ||
+ margins.bottom < availbleBottomMargin) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @return {boolean} Whether the header-footer setting is enabled. */
+ isHeaderFooterEnabled: function() {
+ return this.ticket_.isHeaderFooterEnabled;
+ },
+
+ /**
+ * Updates the whether the header-footer setting is enabled. Dispatches a
+ * TICKET_CHANGE event if the setting changed.
+ * @param {boolean} isHeaderFooterEnabled Whether the header-footer setting
+ * is enabled.
+ */
+ updateHeaderFooter: function(isHeaderFooterEnabled) {
+ if (!this.hasHeaderFooterCapability()) {
+ throw Error(
+ 'Updating header-footer capability but destination does not have ' +
+ 'a header-footer capability');
+ }
+ if (this.ticket_.isHeaderFooterEnabled != isHeaderFooterEnabled) {
+ this.ticket_.isHeaderFooterEnabled = isHeaderFooterEnabled;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /**
+ * @return {boolean} Whether the page orientation capability is available.
+ */
+ hasOrientationCapability: function() {
+ // TODO Technically, the print destination can still change the
+ // orientation of the print out (at least for cloud printers). But the
+ // preview wouldn't update in the case where the document is not
+ // modifiable so this is a bad user experience.
+ return this.documentInfo_.isModifiable;
+ },
+
+ /**
+ * @return {boolean} Whether the document should be printed in landscape.
+ */
+ isLandscapeEnabled: function() {
+ return this.ticket_.isLandscapeEnabled;
+ },
+
+ /**
+ * Updates whether the document should be printed in landscape. Dispatches
+ * a TICKET_CHANGE event if the setting changes.
+ * @param {boolean} isLandscape Whether the document should be printed in
+ * landscape.
+ */
+ updateOrientation: function(isLandscape) {
+ if (!this.hasOrientationCapability()) {
+ throw Error(
+ 'Updating orientation capability but destination does not have ' +
+ 'an orientation capability');
+ }
+ if (this.ticket_.isLandscapeEnabled != isLandscape) {
+ this.ticket_.isLandscapeEnabled = isLandscape;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {boolean} Whether the duplexing capability is available. */
+ hasDuplexCapability: function() {
+ return this.capabilities_.hasDuplexCapability;
+ },
+
+ /** @return {boolean} Whether the document should be printed in duplex. */
+ isDuplexEnabled: function() {
+ return this.ticket_.isDuplexEnabled;
+ },
+
+ /**
+ * Updates the duplexing setting. Dispatches a TICKET_CHANGE event if the
+ * value changes.
+ * @param {boolean} isDuplex Whether the document should be printed in
+ * duplex.
+ */
+ updateDuplex: function(isDuplex) {
+ if (!this.hasDuplexCapability()) {
+ throw Error(
+ 'Updating duplex capability but destination does not have a ' +
+ 'duplex capability');
+ }
+ if (this.ticket_.isDuplexEnabled != isDuplex) {
+ this.ticket_.isDuplexEnabled = isDuplex;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {boolean} Whether the margins capability is available. */
+ hasMarginsCapability: function() {
+ return this.documentInfo_.isModifiable;
+ },
+
+ /** @return {print_preview.Margins.Type} Type of predefined margins. */
+ getMarginsType: function() {
+ return this.ticket_.marginsType;
+ },
+
+ /**
+ * Updates the type of predefined margins. Dispatches a TICKET_CHANGE event
+ * if the margins type changes.
+ * @param {print_preview.Margins.Type} marginsType Type of predefined
+ * margins.
+ */
+ updateMarginsType: function(marginsType) {
+ if (!this.hasMarginsCapability()) {
+ throw Error(
+ 'Updating margins capability but destination does not have a ' +
+ 'margin capability');
+ }
+ if (this.ticket_.marginsType != marginsType) {
+ this.ticket_.marginsType = marginsType;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {print_preview.Margins} Custom margins of the document. */
+ getCustomMargins: function() {
+ return this.ticket_.customMargins;
+ },
+
+ // TODO Store the custom margins as a string so that validation can be done
+ // in the PrintTicketStore.
+
+ /**
+ * Updates the custom margins of the document. Dispatches a TICKET_CHANGE
+ * event if the margins have changed.
+ * @param {print_preview.Margins} margins New document page margins.
+ */
+ updateCustomMargins: function(margins) {
+ if (!this.hasMarginsCapability()) {
+ throw Error(
+ 'Updating margins capability but destination does not have a ' +
+ 'margin capability');
+ }
+ if (!margins.equals(this.ticket_.customMargins)) {
+ this.ticket_.customMargins = margins;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /** @return {boolean} Whether the page range capability is available. */
+ hasPageRangeCapability: function() {
+ // Page range can always be manipulated by Chromium.
+ return true;
+ },
+
+ /**
+ * @return {boolean} Whether the current page range string is defines a
+ * valid page number set.
+ */
+ isPageRangeValid: function() {
+ var pageRangeStr = this.ticket_.pageRangeStr;
+ return pageRangeStr == '' ||
+ isPageRangeTextValid(pageRangeStr, this.documentInfo_.pageCount);
+ },
+
+ /** @return {string} String representation of the page range. */
+ getPageRangeStr: function() {
+ return this.ticket_.pageRangeStr;
+ },
+
+ /**
+ * @return {!print_preview.PageNumberSet} Page number set specified by the
+ * string representation of the page range string.
+ */
+ getPageNumberSet: function() {
+ if (this.pageNumberSet_ == null) {
+ this.pageNumberSet_ = print_preview.PageNumberSet.parse(
+ this.ticket_.pageRangeStr, this.documentInfo_.pageCount);
+ }
+ return this.pageNumberSet_;
+ },
+
+ /**
+ * Updates the page range string. Dispatches a TICKET_CHANGE if the string
+ * changed.
+ * @param {string} pageRangeStr New page range string.
+ */
+ updatePageRange: function(pageRangeStr) {
+ if (this.ticket_.pageRangeStr != pageRangeStr) {
+ this.ticket_.pageRangeStr = pageRangeStr;
+ this.pageNumberSet_ = null;
+ cr.dispatchSimpleEvent(this, PrintTicketStore.Event.TICKET_CHANGE);
+ }
+ },
+
+ /**
+ * @return {boolean} {@code true} if the stored print ticket is valid,
+ * {@code false} otherwise.
+ */
+ isTicketValid: function() {
+ // TODO Validate custom margins
+ return this.isCopiesValid() && this.isPageRangeValid();
+ }
+ };
+
+ /**
+ * Object which contains information related to the document to print.
+ *
+ * @constructor
+ */
+ function DocumentInfo() {
+ /**
+ * Whether the document to print is modifiable (i.e. can be reflowed).
+ * @type {boolean}
+ */
+ this.isModifiable = true;
+
+ /**
+ * Number of pages in the document to print.
+ * @type {number}
+ */
+ this.pageCount = 1;
+
+ /**
+ * Size of the pages of the document.
+ * @type {!print_preview.Size}
+ */
+ this.pageSize = new print_preview.Size(612, 792);
dpapad 2012/04/24 01:24:56 Where do these values come from?
Robert Toscano 2012/04/24 22:29:56 8.5"x11" paper size. I've move the initialization
+
+ /**
+ * Printable area of the document.
+ * @type {!print_preview.PrintableArea}
+ */
+ this.printableArea = new print_preview.PrintableArea(
+ new print_preview.Coordinate2d(0, 0),
+ this.pageSize);
+ };
+
+ // Export
+ return {
+ PrintTicketStore: PrintTicketStore
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698