Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
190 lines
6 KiB
JavaScript
Executable file
190 lines
6 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
define(function(require, exports) {
|
|
var cards = require('cards'),
|
|
ConfirmDialog = require('confirm_dialog'),
|
|
deleteConfirmMsgNode = require('tmpl!../msg/delete_confirm.html'),
|
|
mozL10n = require('l10n!'),
|
|
toaster = require('toaster');
|
|
|
|
return {
|
|
createdCallback: function() {
|
|
this.editMode = false;
|
|
this.selectedMessages = null;
|
|
this.editModeEnabled = false;
|
|
},
|
|
|
|
setEditMode: function(editMode) {
|
|
// Do not bother if edit mode is not enabled yet.
|
|
if (!this.editModeEnabled) {
|
|
return;
|
|
}
|
|
|
|
this._setEditMode(editMode);
|
|
},
|
|
|
|
// This function is called from setEditMode() after ensuring that
|
|
// the backend is in a state where we can safely use edit mode.
|
|
_setEditMode: function(editMode) {
|
|
var i;
|
|
|
|
this.editMode = editMode;
|
|
|
|
if (editMode) {
|
|
this.classList.add('show-edit');
|
|
|
|
this.selectedMessages = [];
|
|
this.updateDomEditControls();
|
|
}
|
|
else {
|
|
this.classList.remove('show-edit');
|
|
|
|
this.selectedMessages = null;
|
|
}
|
|
|
|
// Reset checked mode for all message items.
|
|
var msgNodes = this.msgVScroll.querySelectorAll('.msg-header-item');
|
|
for (i = 0; i < msgNodes.length; i++) {
|
|
this.updateDomMessageChecked(msgNodes[i], false);
|
|
}
|
|
|
|
if (this.editModeChanged) {
|
|
this.editModeChanged(editMode);
|
|
}
|
|
},
|
|
|
|
// Event handler wired up in HTML template
|
|
setEditModeStart: function() {
|
|
this.setEditMode(true);
|
|
},
|
|
|
|
// Event handler wired up in HTML template
|
|
editHeaderClose: function() {
|
|
this.setEditMode(false);
|
|
},
|
|
|
|
/**
|
|
* Toggles the selection state of the node and therefore the stored
|
|
* `selectedMessages` state based on the previous state of the selection.
|
|
* The change in the total number of selections is then reflected in DOM
|
|
* updates.
|
|
* @param {Element} msgNode
|
|
*/
|
|
toggleSelection: function(msgNode) {
|
|
var header = msgNode.message;
|
|
var idx = this.selectedMessages.indexOf(header);
|
|
if (idx !== -1) {
|
|
this.selectedMessages.splice(idx, 1);
|
|
} else {
|
|
this.selectedMessages.push(header);
|
|
}
|
|
this.updateDomMessageChecked(msgNode, idx === -1);
|
|
this.updateDomEditControls();
|
|
},
|
|
|
|
/**
|
|
* Set or unset the select state on a node based on the edit mode.
|
|
*/
|
|
updateDomSelectState: function(msgNode, message) {
|
|
if (this.editMode) {
|
|
this.updateDomMessageChecked(msgNode,
|
|
this.selectedMessages.indexOf(message) !== -1);
|
|
} else {
|
|
msgNode.removeAttribute('aria-selected');
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set the checked state for the message item in the list. It sets both
|
|
* checkbox checked and aria-selected states.
|
|
*/
|
|
updateDomMessageChecked: function(msgNode, checked) {
|
|
var checkbox = msgNode.querySelector('input[type=checkbox]');
|
|
checkbox.checked = checked;
|
|
msgNode.setAttribute('aria-selected', checked);
|
|
},
|
|
|
|
/**
|
|
* Update the edit mode UI bits sensitive to a change in the set of selected
|
|
* messages. This means the label that says how many messages are selected,
|
|
* whether the buttons are enabled, which of the toggle-pairs are visible.
|
|
*/
|
|
updateDomEditControls: function() {
|
|
this.editHeader.updateDomHeaderCount(this.selectedMessages.length);
|
|
this.editToolbar.updateDomEditButtons(this.selectedMessages.length > 0);
|
|
|
|
// Enabling/disabling rules (not UX-signed-off): Our bias is that people
|
|
// want to star messages and mark messages unread (since it they naturally
|
|
// end up unread), so unless messages are all in this state, we assume
|
|
// that is the desired action.
|
|
var numStarred = 0, numRead = 0;
|
|
for (var i = 0; i < this.selectedMessages.length; i++) {
|
|
var msg = this.selectedMessages[i];
|
|
if (msg.isStarred) {
|
|
numStarred++;
|
|
}
|
|
if (msg.isRead) {
|
|
numRead++;
|
|
}
|
|
}
|
|
|
|
// Unstar if everything is starred, otherwise star
|
|
this.setAsStarred = !(numStarred && numStarred ===
|
|
this.selectedMessages.length);
|
|
this.editToolbar.updateDomStartButton(this.setAsStarred);
|
|
|
|
// Mark read if everything is unread, otherwise unread
|
|
this.setAsRead = (!!this.selectedMessages.length && numRead === 0);
|
|
this.editToolbar.updateDomReadButton(numRead > 0);
|
|
},
|
|
|
|
onDeleteMessages: function() {
|
|
if (this.selectedMessages.length === 0) {
|
|
return this.setEditMode(false);
|
|
}
|
|
|
|
var dialog = deleteConfirmMsgNode.cloneNode(true);
|
|
var content = dialog.getElementsByTagName('p')[0];
|
|
mozL10n.setAttributes(content, 'message-multiedit-delete-confirm',
|
|
{ n: this.selectedMessages.length });
|
|
ConfirmDialog.show(dialog,
|
|
{ // Confirm
|
|
id: 'msg-delete-ok',
|
|
handler: function() {
|
|
var op = this.model.api.deleteMessages(this.selectedMessages);
|
|
toaster.toastOperation(op);
|
|
this.setEditMode(false);
|
|
}.bind(this)
|
|
},
|
|
{ // Cancel
|
|
id: 'msg-delete-cancel',
|
|
handler: null
|
|
}
|
|
);
|
|
},
|
|
|
|
onStarMessages: function() {
|
|
var op = this.model.api.markMessagesStarred(this.selectedMessages,
|
|
this.setAsStarred);
|
|
this.setEditMode(false);
|
|
toaster.toastOperation(op);
|
|
},
|
|
|
|
onMarkMessagesRead: function() {
|
|
var op = this.model.api.markMessagesRead(this.selectedMessages,
|
|
this.setAsRead);
|
|
this.setEditMode(false);
|
|
toaster.toastOperation(op);
|
|
},
|
|
|
|
onMoveMessages: function() {
|
|
cards.folderSelector(this.model, function(folder) {
|
|
var op = this.model.api.moveMessages(this.selectedMessages, folder);
|
|
toaster.toastOperation(op);
|
|
this.setEditMode(false);
|
|
}.bind(this), function(folder) {
|
|
return folder.isValidMoveTarget;
|
|
});
|
|
}
|
|
};
|
|
});
|