define('tmpl!cards/msg/contact_menu.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('
\n');
});
define('tmpl!cards/msg/reply_menu.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('\n');
});
define('tmpl!cards/msg/browse_confirm.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('');
});
define('tmpl!cards/msg/peep_bubble.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('\n \n
\n');
});
define('tmpl!cards/msg/attachment_item.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('\n \n \n \n \n \n \n \n \n \n \n \n\n');
});
define('tmpl!cards/msg/attachment_disabled_confirm.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('\n');
});
define('tmpl!cards/msg/attachment_did_not_open_alert.html', ['tmpl'], function (tmpl) {
return tmpl.toDom('\n');
});
define('marquee', [], function () {
var Marquee = {
timingFunction: [
'linear',
'ease'
],
setup: function marquee_setup(text, headerNode) {
this._headerNode = headerNode;
this._headerWrapper = document.getElementById('marquee-h-wrapper');
if (!this._headerWrapper) {
this._headerWrapper = document.createElement('div');
this._headerWrapper.id = 'marquee-h-wrapper';
this._headerNode.appendChild(this._headerWrapper);
}
var headerText = document.getElementById('marquee-h-text');
if (!headerText) {
headerText = document.createElement('div');
headerText.id = 'marquee-h-text';
this._headerWrapper.dir = 'auto';
this._headerWrapper.appendChild(headerText);
}
headerText.textContent = text;
},
activate: function marquee_activate(behavior, timingFun) {
if (!this._headerNode || !this._headerWrapper) {
return;
}
var mode = behavior || 'scroll';
var tf = timingFun || null;
var timing = Marquee.timingFunction.indexOf(tf) >= 0 ? tf : 'linear';
var marqueeCssClass = 'marquee';
var titleText = document.getElementById('marquee-h-text');
var cssClass, width;
if (this._headerWrapper.clientWidth < this._headerWrapper.scrollWidth) {
this._marqueeCssClassList = [];
switch (mode) {
case 'scroll':
cssClass = marqueeCssClass + '-rtl';
width = this._headerWrapper.scrollWidth;
titleText.style.width = width + 'px';
titleText.classList.add(cssClass + '-start-' + timing);
this._marqueeCssClassList.push(cssClass + '-start-' + timing);
var self = this;
titleText.addEventListener('animationend', function () {
titleText.classList.remove(cssClass + '-start-' + timing);
this._marqueeCssClassList.pop();
var visibleWidth = self._headerWrapper.clientWidth + 'px';
titleText.style.transform = 'translateX(' + visibleWidth + ')';
titleText.classList.add(cssClass);
this._marqueeCssClassList.push(cssClass);
});
break;
case 'alternate':
var dirSuffix = '';
if (window.getComputedStyle(titleText).direction === 'rtl') {
dirSuffix = '-rtl';
}
timing += dirSuffix;
cssClass = marqueeCssClass + '-alt-';
width = this._headerWrapper.scrollWidth - this._headerWrapper.clientWidth;
titleText.style.width = width + 'px';
titleText.classList.add(cssClass + timing);
break;
}
} else {
if (!this._marqueeCssClassList) {
return;
}
for (var titleCssClass in this._marqueeCssClassList) {
titleText.classList.remove(titleCssClass);
}
titleText.style.transform = '';
}
}
};
return Marquee;
});
define('mime_to_class', [], function () {
return function mimeToClass(mimeType) {
mimeType = mimeType || '';
return 'mime-' + (mimeType.split('/')[0] || '');
};
});
define('file_display', [
'require',
'l10n!'
], function (require) {
var mozL10n = require('l10n!');
return {
fileSize: function (node, sizeInBytes) {
var kilos = Math.ceil(sizeInBytes / 1024);
mozL10n.setAttributes(node, 'attachment-size-kib', { kilobytes: kilos });
}
};
});
define('template!cards/message_reader.html', ['template'], function (template) {
return {
createdCallback: template.templateCreatedCallback,
template: template.objToFn({
'id': 'cards/message_reader.html',
'deps': [],
'text': '\n\n\n\n'
})
};
});
define('cards/message_reader', [
'require',
'tmpl!./msg/delete_confirm.html',
'tmpl!./msg/contact_menu.html',
'tmpl!./msg/reply_menu.html',
'tmpl!./msg/browse_confirm.html',
'tmpl!./msg/peep_bubble.html',
'tmpl!./msg/attachment_item.html',
'tmpl!./msg/attachment_disabled_confirm.html',
'tmpl!./msg/attachment_did_not_open_alert.html',
'cards',
'confirm_dialog',
'date',
'toaster',
'header_cursor',
'evt',
'iframe_shims',
'marquee',
'l10n!',
'query_uri',
'mime_to_class',
'file_display',
'message_display',
'./base_card',
'template!./message_reader.html'
], function (require) {
var MimeMapper, msgDeleteConfirmNode = require('tmpl!./msg/delete_confirm.html'), msgContactMenuNode = require('tmpl!./msg/contact_menu.html'), msgReplyMenuNode = require('tmpl!./msg/reply_menu.html'), msgBrowseConfirmNode = require('tmpl!./msg/browse_confirm.html'), msgPeepBubbleNode = require('tmpl!./msg/peep_bubble.html'), msgAttachmentItemNode = require('tmpl!./msg/attachment_item.html'), msgAttachmentDisabledConfirmNode = require('tmpl!./msg/attachment_disabled_confirm.html'), msgAttachmentDidNotOpenAlertNode = require('tmpl!./msg/attachment_did_not_open_alert.html'), cards = require('cards'), ConfirmDialog = require('confirm_dialog'), date = require('date'), toaster = require('toaster'), HeaderCursor = require('header_cursor'), evt = require('evt'), iframeShims = require('iframe_shims'), Marquee = require('marquee'), mozL10n = require('l10n!'), queryURI = require('query_uri'), mimeToClass = require('mime_to_class'), fileDisplay = require('file_display'), messageDisplay = require('message_display');
var CONTENT_TYPES_TO_CLASS_NAMES = [
null,
'msg-body-content',
'msg-body-signature',
'msg-body-leadin',
null,
'msg-body-disclaimer',
'msg-body-list',
'msg-body-product',
'msg-body-ads'
];
var CONTENT_QUOTE_CLASS_NAMES = [
'msg-body-q1',
'msg-body-q2',
'msg-body-q3',
'msg-body-q4',
'msg-body-q5',
'msg-body-q6',
'msg-body-q7',
'msg-body-q8',
'msg-body-q9'
];
var MAX_QUOTE_CLASS_NAME = 'msg-body-qmax';
var OCTET_STREAM_TYPE = 'application/octet-stream';
function sendActivity(obj) {
return new MozActivity(obj);
}
return [
require('./base_card')(require('template!./message_reader.html')),
{
createdCallback: function () {
this.htmlBodyNodes = [];
this._on('msg-up-btn', 'click', 'onPrevious');
this._on('msg-down-btn', 'click', 'onNext');
this._on('msg-reply-btn', 'click', 'onReplyMenu');
this._on('msg-delete-btn', 'click', 'onDelete');
this._on('msg-star-btn', 'click', 'onToggleStar');
this._on('msg-move-btn', 'click', 'onMove');
this._on('msg-mark-read-btn', 'click', 'onMarkRead');
this._on('msg-envelope-bar', 'click', 'onEnvelopeClick');
this._on('msg-reader-load-infobar', 'click', 'onLoadBarClick');
this._emittedContentEvents = false;
this.disableReply();
this._builtBodyDom = false;
this.handleBodyChange = this.handleBodyChange.bind(this);
this.onMessageSuidNotFound = this.onMessageSuidNotFound.bind(this);
this.onCurrentMessage = this.onCurrentMessage.bind(this);
},
onArgs: function (args) {
this.model = args.model;
this.messageSuid = args.messageSuid;
var headerCursor = this.headerCursor = args.headerCursor || new HeaderCursor(this.model);
headerCursor.on('messageSuidNotFound', this.onMessageSuidNotFound);
headerCursor.latest('currentMessage', this.onCurrentMessage);
headerCursor.setCurrentMessage(this.header);
},
_contextMenuType: {
VIEW_CONTACT: 1,
CREATE_CONTACT: 2,
ADD_TO_CONTACT: 4,
REPLY: 8,
NEW_MESSAGE: 16
},
skipEmitContentEvents: true,
_on: function (className, eventName, method, skipProtection) {
this.getElementsByClassName(className)[0].addEventListener(eventName, function (evt) {
if (this.header || skipProtection) {
return this[method](evt);
}
}.bind(this), false);
},
_setHeader: function (header) {
this.header = header.makeCopy();
this.hackMutationHeader = header;
if (!this.header.isRead) {
this.header.setRead(true);
} else {
this.readBtn.classList.remove('unread');
mozL10n.setAttributes(this.readBtn, 'message-mark-read-button');
}
this.starBtn.classList.toggle('msg-star-btn-on', this.hackMutationHeader.isStarred);
this.starBtn.setAttribute('aria-pressed', this.hackMutationHeader.isStarred);
this.emit('header');
},
postInsert: function () {
this._inDom = true;
if (this._afterInDomMessage) {
this.onCurrentMessage(this._afterInDomMessage);
this._afterInDomMessage = null;
}
},
told: function (args) {
if (args.messageSuid) {
this.messageSuid = args.messageSuid;
}
},
handleBodyChange: function (evt) {
this.buildBodyDom(evt.changeDetails);
},
onBack: function (event) {
cards.removeCardAndSuccessors(this, 'animate');
},
onPrevious: function (event) {
this.headerCursor.advance('previous');
},
onNext: function (event) {
this.headerCursor.advance('next');
},
onMessageSuidNotFound: function (messageSuid) {
if (this.messageSuid === messageSuid) {
this.onBack();
}
},
onCurrentMessage: function (currentMessage) {
if (!this._inDom) {
this._afterInDomMessage = currentMessage;
return;
}
if (this.header && this.header.id === currentMessage.header.id) {
return;
}
this.messageSuid = null;
this._setHeader(currentMessage.header);
this.clearDom();
this.latestOnce('header', function () {
this.buildHeaderDom(this);
this.header.getBody({ downloadBodyReps: true }, function (body) {
if (this.header.id !== body.id) {
return;
}
this.body = body;
body.onchange = this.handleBodyChange;
if (body.bodyRepsDownloaded) {
this.buildBodyDom();
}
}.bind(this));
}.bind(this));
var hasPrevious = currentMessage.siblings.hasPrevious;
this.previousBtn.disabled = !hasPrevious;
this.previousIcon.classList[hasPrevious ? 'remove' : 'add']('icon-disabled');
var hasNext = currentMessage.siblings.hasNext;
this.nextBtn.disabled = !hasNext;
this.nextIcon.classList[hasNext ? 'remove' : 'add']('icon-disabled');
},
reply: function () {
cards.eatEventsUntilNextCard();
var composer = this.header.replyToMessage(null, () => {
cards.pushCard('compose', 'animate', {
model: this.model,
composer: composer
});
});
},
replyAll: function () {
cards.eatEventsUntilNextCard();
var composer = this.header.replyToMessage('all', () => {
cards.pushCard('compose', 'animate', {
model: this.model,
composer: composer
});
});
},
forward: function () {
var needToPrompt = this.header.hasAttachments || this.body.embeddedImageCount > 0;
var forwardMessage = function () {
cards.eatEventsUntilNextCard();
var composer = this.header.forwardMessage('inline', () => {
cards.pushCard('compose', 'animate', {
model: this.model,
composer: composer
});
});
}.bind(this);
if (needToPrompt) {
var dialog = msgAttachmentDisabledConfirmNode.cloneNode(true);
ConfirmDialog.show(dialog, {
id: 'msg-attachment-disabled-ok',
handler: function () {
forwardMessage();
}
}, {
id: 'msg-attachment-disabled-cancel',
handler: null
});
} else {
forwardMessage();
}
},
canReplyAll: function () {
var myAddresses = this.model.account.identities.map(function (ident) {
return ident.address;
});
var otherAddresses = (this.header.to || []).concat(this.header.cc || []);
if (this.header.replyTo && this.header.replyTo.author) {
otherAddresses.push(this.header.replyTo.author);
}
for (var i = 0; i < otherAddresses.length; i++) {
var otherAddress = otherAddresses[i];
if (otherAddress.address && myAddresses.indexOf(otherAddress.address) == -1) {
return true;
}
}
return false;
},
onReplyMenu: function (event) {
var contents = msgReplyMenuNode.cloneNode(true);
cards.setStatusColor(contents);
document.body.appendChild(contents);
var formSubmit = function (evt) {
cards.setStatusColor();
document.body.removeChild(contents);
switch (evt.explicitOriginalTarget.className) {
case 'msg-reply-menu-reply':
this.reply();
break;
case 'msg-reply-menu-reply-all':
this.replyAll();
break;
case 'msg-reply-menu-forward':
this.forward();
break;
case 'msg-reply-menu-cancel':
break;
}
return false;
}.bind(this);
contents.addEventListener('submit', formSubmit);
if (!this.canReplyAll()) {
contents.querySelector('.msg-reply-menu-reply-all').classList.add('collapsed');
}
},
onDelete: function () {
var dialog = msgDeleteConfirmNode.cloneNode(true);
var content = dialog.getElementsByTagName('p')[0];
mozL10n.setAttributes(content, 'message-edit-delete-confirm');
ConfirmDialog.show(dialog, {
id: 'msg-delete-ok',
handler: function () {
var op = this.header.deleteMessage();
cards.removeCardAndSuccessors(this, 'animate');
toaster.toastOperation(op);
}.bind(this)
}, {
id: 'msg-delete-cancel',
handler: null
});
},
onToggleStar: function () {
this.starBtn.classList.toggle('msg-star-btn-on', !this.hackMutationHeader.isStarred);
this.hackMutationHeader.isStarred = !this.hackMutationHeader.isStarred;
this.starBtn.setAttribute('aria-pressed', this.hackMutationHeader.isStarred);
this.header.setStarred(this.hackMutationHeader.isStarred);
},
onMove: function () {
cards.folderSelector(this.model, function (folder) {
var op = this.header.moveMessage(folder);
cards.removeCardAndSuccessors(this, 'animate');
toaster.toastOperation(op);
}.bind(this), function (folder) {
return folder.isValidMoveTarget;
});
},
setRead: function (isRead) {
this.hackMutationHeader.isRead = isRead;
this.header.setRead(isRead);
this.readBtn.classList.toggle('unread', !isRead);
mozL10n.setAttributes(this.readBtn, isRead ? 'message-mark-read-button' : 'message-mark-unread-button');
},
onMarkRead: function () {
this.setRead(!this.hackMutationHeader.isRead);
},
onEnvelopeClick: function (event) {
var target = event.target;
if (!target.classList.contains('msg-peep-bubble')) {
return;
}
this.onPeepClick(target);
},
onPeepClick: function (target) {
var contents = msgContactMenuNode.cloneNode(true);
var peep = target.peep;
var headerNode = contents.getElementsByTagName('header')[0];
Marquee.setup(peep.address, headerNode);
document.body.appendChild(contents);
Marquee.activate('alternate', 'ease');
var formSubmit = function (evt) {
document.body.removeChild(contents);
switch (evt.explicitOriginalTarget.className) {
case 'msg-contact-menu-new':
cards.pushCard('compose', 'animate', {
model: this.model,
composerData: {
message: this.header,
onComposer: function (composer) {
composer.to = [{
address: peep.address,
name: peep.name
}];
}
}
});
break;
case 'msg-contact-menu-view':
sendActivity({
name: 'open',
data: {
type: 'webcontacts/contact',
params: { 'id': peep.contactId }
}
});
break;
case 'msg-contact-menu-create-contact':
var params = { 'email': peep.address };
if (peep.name) {
params.givenName = peep.name;
}
sendActivity({
name: 'new',
data: {
type: 'webcontacts/contact',
params: params
}
});
break;
case 'msg-contact-menu-add-to-existing-contact':
sendActivity({
name: 'update',
data: {
type: 'webcontacts/contact',
params: { 'email': peep.address }
}
});
break;
case 'msg-contact-menu-reply':
var composer = this.header.replyToMessage(null, () => {
cards.pushCard('compose', 'animate', {
model: this.model,
composer: composer
});
});
break;
}
return false;
}.bind(this);
contents.addEventListener('submit', formSubmit);
var contextMenuOptions = this._contextMenuType.NEW_MESSAGE;
var messageType = peep.type;
if (messageType === 'from') {
contextMenuOptions |= this._contextMenuType.REPLY;
}
if (peep.isContact) {
contextMenuOptions |= this._contextMenuType.VIEW_CONTACT;
} else {
contextMenuOptions |= this._contextMenuType.CREATE_CONTACT;
contextMenuOptions |= this._contextMenuType.ADD_TO_CONTACT;
}
if (contextMenuOptions & this._contextMenuType.VIEW_CONTACT) {
contents.querySelector('.msg-contact-menu-view').classList.remove('collapsed');
}
if (contextMenuOptions & this._contextMenuType.CREATE_CONTACT) {
contents.querySelector('.msg-contact-menu-create-contact').classList.remove('collapsed');
}
if (contextMenuOptions & this._contextMenuType.ADD_TO_CONTACT) {
contents.querySelector('.msg-contact-menu-add-to-existing-contact').classList.remove('collapsed');
}
if (contextMenuOptions & this._contextMenuType.REPLY) {
contents.querySelector('.msg-contact-menu-reply').classList.remove('collapsed');
}
if (contextMenuOptions & this._contextMenuType.NEW_MESSAGE) {
contents.querySelector('.msg-contact-menu-new').classList.remove('collapsed');
}
},
onLoadBarClick: function (event) {
var self = this;
var loadBar = this.loadBar;
if (!this.body.embeddedImagesDownloaded) {
this.body.downloadEmbeddedImages(function () {
if (!self.body) {
return;
}
for (var i = 0; i < self.htmlBodyNodes.length; i++) {
self.body.showEmbeddedImages(self.htmlBodyNodes[i], self.iframeResizeHandler);
}
});
loadBar.classList.add('collapsed');
} else {
for (var i = 0; i < this.htmlBodyNodes.length; i++) {
this.body.showExternalImages(this.htmlBodyNodes[i], this.iframeResizeHandler);
}
loadBar.classList.add('collapsed');
}
},
getAttachmentBlob: function (attachment, callback) {
try {
var storageType = attachment._file[0];
var filename = attachment._file[1];
var storage = navigator.getDeviceStorage(storageType);
var getreq = storage.get(filename);
getreq.onerror = function () {
console.warn('Could not open attachment file: ', filename, getreq.error.name);
};
getreq.onsuccess = function () {
var blob = getreq.result;
callback(blob);
};
} catch (ex) {
console.warn('Exception getting attachment from device storage:', attachment._file, '\n', ex, '\n', ex.stack);
}
},
onDownloadAttachmentClick: function (node, attachment) {
node.setAttribute('state', 'downloading');
var registerWithDownloadManager = true;
attachment.download(function downloaded() {
if (!attachment._file) {
return;
}
node.setAttribute('state', 'downloaded');
}, null, registerWithDownloadManager);
},
onViewAttachmentClick: function (node, attachment) {
console.log('trying to open', attachment._file, 'known type:', attachment.mimetype);
if (!attachment._file) {
return;
}
if (attachment.isDownloaded) {
this.getAttachmentBlob(attachment, function (blob) {
try {
if (!blob) {
throw new Error('Blob does not exist');
}
var useType = attachment.mimetype;
if (!useType || useType === OCTET_STREAM_TYPE) {
useType = blob.type;
}
if (!useType || useType === OCTET_STREAM_TYPE) {
useType = MimeMapper.guessTypeFromFileProperties(attachment.filename, OCTET_STREAM_TYPE);
}
if (!useType) {
useType = OCTET_STREAM_TYPE;
}
console.log('triggering open activity with MIME type:', useType);
var activity = new MozActivity({
name: 'open',
data: {
type: useType,
filename: attachment.filename,
blob: blob,
url: attachment.filename
}
});
activity.onerror = function () {
console.warn('Problem with "open" activity', activity.error.name);
if (activity.error.name === 'NO_PROVIDER') {
var dialog = msgAttachmentDidNotOpenAlertNode.cloneNode(true);
ConfirmDialog.show(dialog, {
id: 'msg-attachment-did-not-open-ok',
handler: null
}, { handler: null });
}
};
activity.onsuccess = function () {
console.log('"open" activity allegedly succeeded');
};
} catch (ex) {
console.warn('Problem creating "open" activity:', ex, '\n', ex.stack);
}
});
}
},
onHyperlinkClick: function (event, linkNode, linkUrl, linkText) {
if (/^mailto:/i.test(linkUrl)) {
var data = queryURI(linkUrl);
cards.pushCard('compose', 'animate', {
model: this.model,
composerData: {
onComposer: (composer, composeCard) => {
Object.keys(data).forEach(key => {
if (key === 'to' || key === 'cc' || key === 'bcc') {
composer[key] = data[key].map(addr => {
return this.model.api.parseMailbox(addr).address;
}).filter(value => {
return value;
});
} else {
composer[key] = data[key];
}
});
}
}
});
} else {
var dialog = msgBrowseConfirmNode.cloneNode(true);
var content = dialog.getElementsByTagName('p')[0];
mozL10n.setAttributes(content, 'browse-to-url-prompt', { url: linkUrl });
ConfirmDialog.show(dialog, {
id: 'msg-browse-ok',
handler: function () {
sendActivity({
name: 'view',
data: {
type: 'url',
url: linkUrl
}
});
}.bind(this)
}, {
id: 'msg-browse-cancel',
handler: null
});
}
},
_populatePlaintextBodyNode: function (bodyNode, rep) {
for (var i = 0; i < rep.length; i += 2) {
var node = document.createElement('div'), cname;
var etype = rep[i] & 15;
if (etype === 4) {
var qdepth = (rep[i] >> 8 & 255) + 1;
if (qdepth > 8) {
cname = MAX_QUOTE_CLASS_NAME;
} else {
cname = CONTENT_QUOTE_CLASS_NAMES[qdepth];
}
} else {
cname = CONTENT_TYPES_TO_CLASS_NAMES[etype];
}
if (cname) {
node.setAttribute('class', cname);
}
var subnodes = this.model.api.utils.linkifyPlain(rep[i + 1], document);
for (var iNode = 0; iNode < subnodes.length; iNode++) {
node.appendChild(subnodes[iNode]);
}
bodyNode.appendChild(node);
}
},
buildHeaderDom: function (domNode) {
var header = this.header;
function updatePeep(peep) {
var nameNode = peep.element.querySelector('.msg-peep-content');
if (peep.type === 'from') {
domNode.querySelector('.msg-reader-header-label').textContent = peep.name || peep.address;
nameNode.textContent = peep.address;
nameNode.classList.add('msg-peep-address');
} else {
nameNode.textContent = peep.name || peep.address;
if (!peep.name && peep.address) {
nameNode.classList.add('msg-peep-address');
} else {
nameNode.classList.remove('msg-peep-address');
}
}
}
function addHeaderEmails(type, peeps) {
var lineClass = 'msg-envelope-' + type + '-line';
var lineNode = domNode.getElementsByClassName(lineClass)[0];
if (!peeps || !peeps.length) {
lineNode.classList.add('collapsed');
return;
}
lineNode.classList.remove('collapsed');
var peepTemplate = msgPeepBubbleNode;
for (var i = 0; i < peeps.length; i++) {
var peep = peeps[i];
peep.type = type;
peep.element = peepTemplate.cloneNode(true);
peep.element.peep = peep;
peep.onchange = updatePeep;
updatePeep(peep);
lineNode.appendChild(peep.element);
}
}
addHeaderEmails('from', [header.author]);
addHeaderEmails('to', header.to);
addHeaderEmails('cc', header.cc);
addHeaderEmails('bcc', header.bcc);
var dateNode = domNode.querySelector('.msg-envelope-date');
var dateTime = dateNode.dataset.time = header.date.valueOf();
date.relativeDateElement(dateNode, dateTime);
messageDisplay.subject(domNode.querySelector('.msg-envelope-subject'), header);
},
clearDom: function () {
Array.slice(this.querySelectorAll('.msg-peep-bubble')).forEach(function (node) {
node.parentNode.removeChild(node);
});
var attachmentsContainer = this.querySelector('.msg-attachments-container');
attachmentsContainer.innerHTML = '';
this.rootBodyNode.innerHTML = '';
this.loadBar.classList.add('collapsed');
},
buildBodyDom: function (changeDetails) {
var body = this.body;
if (!body || this.header.id !== body.id) {
return;
}
var domNode = this, rootBodyNode = this.rootBodyNode, reps = body.bodyReps, hasExternalImages = false, showEmbeddedImages = body.embeddedImageCount && body.embeddedImagesDownloaded;
if (!this._builtBodyDom) {
iframeShims.bindSanitizedClickHandler(rootBodyNode, this.onHyperlinkClick.bind(this), rootBodyNode, null);
this._builtBodyDom = true;
}
if (reps.length && reps[0].isDownloaded) {
var progressNode = rootBodyNode.querySelector('progress');
if (progressNode) {
progressNode.parentNode.removeChild(progressNode);
}
}
for (var iRep = 0; iRep < reps.length; iRep++) {
var rep = reps[iRep];
var repNode = rootBodyNode.childNodes[iRep];
if (!repNode) {
repNode = rootBodyNode.appendChild(document.createElement('div'));
}
if (changeDetails && changeDetails.bodyReps && changeDetails.bodyReps.indexOf(iRep) === -1) {
continue;
}
repNode.innerHTML = '';
if (rep.type === 'plain') {
this._populatePlaintextBodyNode(repNode, rep.content);
} else if (rep.type === 'html') {
var iframeShim = iframeShims.createAndInsertIframeForContent(rep.content, this.scrollContainer, repNode, null, 'interactive', this.onHyperlinkClick.bind(this));
var iframe = iframeShim.iframe;
var bodyNode = iframe.contentDocument.body;
this.iframeResizeHandler = iframeShim.resizeHandler;
this.model.api.utils.linkifyHTML(iframe.contentDocument);
this.htmlBodyNodes.push(bodyNode);
if (body.checkForExternalImages(bodyNode)) {
hasExternalImages = true;
}
if (showEmbeddedImages) {
body.showEmbeddedImages(bodyNode, this.iframeResizeHandler);
}
}
}
var loadBar = this.loadBar;
if (body.embeddedImageCount && !body.embeddedImagesDownloaded) {
loadBar.classList.remove('collapsed');
mozL10n.setAttributes(this.loadBarText, 'message-download-images-tap', { n: body.embeddedImageCount });
} else if (hasExternalImages) {
loadBar.classList.remove('collapsed');
mozL10n.setAttributes(this.loadBarText, 'message-show-external-images');
} else {
loadBar.classList.add('collapsed');
}
var attachmentsContainer = domNode.querySelector('.msg-attachments-container');
if (body.attachments && body.attachments.length) {
attachmentsContainer.classList.remove('collapsed');
require(['shared/js/mime_mapper'], function (mapper) {
if (!MimeMapper) {
MimeMapper = mapper;
}
var attTemplate = msgAttachmentItemNode, filenameTemplate = attTemplate.querySelector('.msg-attachment-filename'), filesizeTemplate = attTemplate.querySelector('.msg-attachment-filesize');
for (var iAttach = 0; iAttach < body.attachments.length; iAttach++) {
var attNode = attachmentsContainer.childNodes[iAttach];
if (!attNode) {
attNode = attachmentsContainer.appendChild(document.createElement('li'));
}
if (changeDetails && changeDetails.attachments && changeDetails.attachments.indexOf(iAttach) === -1) {
continue;
}
var attachment = body.attachments[iAttach], state;
var extension = attachment.filename.split('.').pop();
var MAX_ATTACHMENT_SIZE = 25 * 1024 * 1024;
var attachmentDownloadable = true;
var mimeClass = mimeToClass(attachment.mimetype || MimeMapper.guessTypeFromExtension(extension));
if (attachment.isDownloaded) {
state = 'downloaded';
} else if (!attachment.isDownloadable) {
state = 'nodownload';
attachmentDownloadable = false;
} else if (attachment.sizeEstimateInBytes > MAX_ATTACHMENT_SIZE) {
state = 'toolarge';
attachmentDownloadable = false;
} else {
state = 'downloadable';
}
attTemplate.setAttribute('state', state);
filenameTemplate.textContent = attachment.filename;
fileDisplay.fileSize(filesizeTemplate, attachment.sizeEstimateInBytes);
var attachmentNode = attTemplate.cloneNode(true);
attachmentNode.classList.add(mimeClass);
attachmentsContainer.replaceChild(attachmentNode, attNode);
var downloadButton = attachmentNode.querySelector('.msg-attachment-download');
downloadButton.disabled = !attachmentDownloadable;
if (attachmentDownloadable) {
downloadButton.addEventListener('click', this.onDownloadAttachmentClick.bind(this, attachmentNode, attachment));
}
attachmentNode.setAttribute('aria-disabled', !attachmentDownloadable);
attachmentNode.querySelector('.msg-attachment-view').addEventListener('click', this.onViewAttachmentClick.bind(this, attachmentNode, attachment));
this.enableReply();
}
}.bind(this));
} else {
attachmentsContainer.classList.add('collapsed');
this.enableReply();
}
},
disableReply: function () {
var btn = this.querySelector('.msg-reply-btn');
btn.setAttribute('aria-disabled', true);
},
enableReply: function () {
var btn = this.querySelector('.msg-reply-btn');
btn.removeAttribute('aria-disabled');
if (!this._emittedContentEvents) {
evt.emit('metrics:contentDone');
this._emittedContentEvents = true;
}
},
die: function () {
var headerCursor = this.headerCursor;
headerCursor.removeListener('messageSuidNotFound', this.onMessageSuidNotFound);
headerCursor.removeListener('currentMessage', this.onCurrentMessage);
if (this.header) {
this.header.__die();
this.header = null;
}
if (this.body) {
this.body.die();
this.body = null;
}
}
}
];
});