blob: cf5358281ab1257a29e26ae7ea0950f960d5ea4a [file] [log] [blame]
// 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.
cr.define('print_preview', function() {
'use strict';
/**
* Component that renders a destination item in a destination list.
* @param {!cr.EventTarget} eventTarget Event target to dispatch selection
* events to.
* @param {!print_preview.Destination} destination Destination data object to
* render.
* @param {RegExp} query Active filter query.
* @constructor
* @extends {print_preview.Component}
*/
function DestinationListItem(eventTarget, destination, query) {
print_preview.Component.call(this);
/**
* Event target to dispatch selection events to.
* @type {!cr.EventTarget}
* @private
*/
this.eventTarget_ = eventTarget;
/**
* Destination that the list item renders.
* @type {!print_preview.Destination}
* @private
*/
this.destination_ = destination;
/**
* Active filter query text.
* @type {RegExp}
* @private
*/
this.query_ = query;
/**
* FedEx terms-of-service widget or {@code null} if this list item does not
* render the FedEx Office print destination.
* @type {print_preview.FedexTos}
* @private
*/
this.fedexTos_ = null;
};
/**
* Event types dispatched by the destination list item.
* @enum {string}
*/
DestinationListItem.EventType = {
// Dispatched when the list item is activated.
SELECT: 'print_preview.DestinationListItem.SELECT',
REGISTER_PROMO_CLICKED:
'print_preview.DestinationListItem.REGISTER_PROMO_CLICKED'
};
DestinationListItem.prototype = {
__proto__: print_preview.Component.prototype,
/** @override */
createDom: function() {
this.setElementInternal(this.cloneTemplateInternal(
'destination-list-item-template'));
this.updateUi_();
},
/** @override */
enterDocument: function() {
print_preview.Component.prototype.enterDocument.call(this);
this.tracker.add(this.getElement(), 'click', this.onActivate_.bind(this));
this.tracker.add(
this.getElement(), 'keydown', this.onKeyDown_.bind(this));
this.tracker.add(
this.getChildElement('.register-promo-button'),
'click',
this.onRegisterPromoClicked_.bind(this));
},
/** @return {!print_preiew.Destination} */
get destination() {
return this.destination_;
},
/**
* Updates the list item UI state.
* @param {RegExp} query Active filter query.
*/
update: function(query) {
this.query_ = query;
this.updateUi_();
},
/**
* Initializes the element with destination's info.
* @private
*/
updateUi_: function() {
var iconImg = this.getChildElement('.destination-list-item-icon');
iconImg.src = this.destination_.iconUrl;
var nameEl = this.getChildElement('.destination-list-item-name');
var textContent = this.destination_.displayName;
if (this.query_) {
nameEl.textContent = '';
// When search query is specified, make it obvious why this particular
// printer made it to the list. Display name is always visible, even if
// it does not match the search query.
this.addTextWithHighlight_(nameEl, textContent);
// Show the first matching property.
this.destination_.extraPropertiesToMatch.some(function(property) {
if (property.match(this.query_)) {
var hintSpan = document.createElement('span');
hintSpan.className = 'search-hint';
nameEl.appendChild(hintSpan);
this.addTextWithHighlight_(hintSpan, property);
// Add the same property to the element title.
textContent += ' (' + property + ')';
return true;
}
}, this);
} else {
// Show just the display name and nothing else to lessen visual clutter.
nameEl.textContent = textContent;
}
nameEl.title = textContent;
// Initialize the element which renders the destination's offline status.
this.getElement().classList.toggle('stale', this.destination_.isOffline);
var offlineStatusEl = this.getChildElement('.offline-status');
offlineStatusEl.textContent = this.destination_.offlineStatusText;
setIsVisible(offlineStatusEl, this.destination_.isOffline);
// Initialize registration promo element for Privet unregistered printers.
setIsVisible(
this.getChildElement('.register-promo'),
this.destination_.connectionStatus ==
print_preview.Destination.ConnectionStatus.UNREGISTERED);
},
/**
* Adds text to parent element wrapping search query matches in highlighted
* spans.
* @param {!Element} parent Element to build the text in.
* @param {string} text The text string to highlight segments in.
* @private
*/
addTextWithHighlight_: function(parent, text) {
var sections = text.split(this.query_);
for (var i = 0; i < sections.length; ++i) {
if (i % 2 == 0) {
parent.appendChild(document.createTextNode(sections[i]));
} else {
var span = document.createElement('span');
span.className = 'destination-list-item-query-highlight';
span.textContent = sections[i];
parent.appendChild(span);
}
}
},
/**
* Called when the destination item is activated. Dispatches a SELECT event
* on the given event target.
* @private
*/
onActivate_: function() {
if (this.destination_.id ==
print_preview.Destination.GooglePromotedId.FEDEX &&
!this.destination_.isTosAccepted) {
if (!this.fedexTos_) {
this.fedexTos_ = new print_preview.FedexTos();
this.fedexTos_.render(this.getElement());
this.tracker.add(
this.fedexTos_,
print_preview.FedexTos.EventType.AGREE,
this.onTosAgree_.bind(this));
}
this.fedexTos_.setIsVisible(true);
} else if (this.destination_.connectionStatus !=
print_preview.Destination.ConnectionStatus.UNREGISTERED) {
var selectEvt = new Event(DestinationListItem.EventType.SELECT);
selectEvt.destination = this.destination_;
this.eventTarget_.dispatchEvent(selectEvt);
}
},
/**
* Called when the key is pressed on the destination item. Dispatches a
* SELECT event when Enter is pressed.
* @param {KeyboardEvent} e Keyboard event to process.
* @private
*/
onKeyDown_: function(e) {
if (!e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
if (e.keyCode == 13) {
var activeElementTag = document.activeElement ?
document.activeElement.tagName.toUpperCase() : '';
if (activeElementTag == 'LI') {
e.stopPropagation();
e.preventDefault();
this.onActivate_();
}
}
}
},
/**
* Called when the user agrees to the print destination's terms-of-service.
* Selects the print destination that was agreed to.
* @private
*/
onTosAgree_: function() {
var selectEvt = new Event(DestinationListItem.EventType.SELECT);
selectEvt.destination = this.destination_;
this.eventTarget_.dispatchEvent(selectEvt);
},
/**
* Called when the registration promo is clicked.
* @private
*/
onRegisterPromoClicked_: function() {
var promoClickedEvent = new Event(
DestinationListItem.EventType.REGISTER_PROMO_CLICKED);
promoClickedEvent.destination = this.destination_;
this.eventTarget_.dispatchEvent(promoClickedEvent);
}
};
// Export
return {
DestinationListItem: DestinationListItem
};
});