2010-03-02 20:57:30 +01:00
|
|
|
/* -*- Mode: java; tab-width: 2; c-label-minimum-indentation: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
|
|
|
|
/* Cyrus: comparator-i;ascii-numeric fileinto reject vacation imapflags
|
|
|
|
notify envelope relational regex subaddress copy */
|
|
|
|
var sieveCapabilities = [];
|
|
|
|
|
|
|
|
var filter;
|
|
|
|
|
|
|
|
var selectedRuleDiv = null;
|
|
|
|
var selectedActionDiv = null;
|
|
|
|
|
|
|
|
var fieldLabels;
|
|
|
|
var methodLabels;
|
|
|
|
var operatorLabels;
|
|
|
|
var operatorRequirements;
|
|
|
|
var methodRequirements;
|
|
|
|
var flagLabels;
|
|
|
|
|
|
|
|
var mailboxes = [];
|
|
|
|
|
|
|
|
function onLoadHandler() {
|
|
|
|
setupConstants();
|
|
|
|
setupEventHandlers();
|
|
|
|
|
|
|
|
if (window.opener)
|
|
|
|
sieveCapabilities = window.opener.getSieveCapabilitiesFromEditor();
|
|
|
|
if (!window.opener || filterId == "new") {
|
|
|
|
setupNewFilterData();
|
|
|
|
} else {
|
2012-01-02 20:42:46 +01:00
|
|
|
filter = window.opener.getFilterFromEditor(filterId).evalJSON();
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!window.opener || window.opener.userMailboxes) {
|
|
|
|
setupFilterViews();
|
|
|
|
} else {
|
|
|
|
loadMailboxes();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadMailboxes() {
|
2014-03-04 19:23:55 +01:00
|
|
|
var url = ApplicationBaseURL + "/Mail/0/mailboxes";
|
2010-03-02 20:57:30 +01:00
|
|
|
triggerAjaxRequest(url, onLoadMailboxesCallback);
|
|
|
|
}
|
|
|
|
|
|
|
|
function onLoadMailboxesCallback(http) {
|
|
|
|
if (http.readyState == 4) {
|
2010-04-06 17:41:08 +02:00
|
|
|
// log("http.status: " + http.status);
|
2010-03-02 20:57:30 +01:00
|
|
|
if (http.status == 200) {
|
|
|
|
checkAjaxRequestsState();
|
|
|
|
if (http.responseText.length > 0) {
|
|
|
|
var jsonResponse = http.responseText.evalJSON(true);
|
2010-08-27 16:56:57 +02:00
|
|
|
window.opener.setupMailboxesFromJSON(jsonResponse);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
setupFilterViews();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setupConstants() {
|
|
|
|
fieldLabels = { "subject": _("Subject"),
|
|
|
|
"from": _("From"),
|
|
|
|
"to": _("To"),
|
|
|
|
"cc": _("Cc"),
|
|
|
|
"to_or_cc": _("To or Cc"),
|
|
|
|
"size": _("Size (Kb)"),
|
2014-01-27 21:09:22 +01:00
|
|
|
"header": _("Header"),
|
|
|
|
"body": _("Body") };
|
2015-12-03 21:02:01 +01:00
|
|
|
methodLabels = { "addflag": _("Flag the message with"),
|
2010-03-02 20:57:30 +01:00
|
|
|
"discard": _("Discard the message"),
|
2015-12-03 21:02:01 +01:00
|
|
|
"fileinto": _("File the message in"),
|
2010-03-02 20:57:30 +01:00
|
|
|
"keep": _("Keep the message"),
|
2015-12-03 21:02:01 +01:00
|
|
|
"redirect": _("Forward the message to"),
|
|
|
|
"reject": _("Send a reject message"),
|
2010-03-02 20:57:30 +01:00
|
|
|
"vacation": _("Send a vacation message"),
|
|
|
|
"stop": _("Stop processing filter rules") };
|
|
|
|
|
|
|
|
operatorLabels = { "under": _("is under"),
|
|
|
|
"over": _("is over"),
|
|
|
|
"is": _("is"),
|
|
|
|
"is_not": _("is not"),
|
|
|
|
"contains": _("contains"),
|
|
|
|
"contains_not": _("does not contain"),
|
|
|
|
"matches": _("matches"),
|
|
|
|
"matches_not": _("does not match"),
|
|
|
|
"regex": _("matches regex"),
|
|
|
|
"regex_not": _("does not match regex") };
|
|
|
|
|
|
|
|
flagLabels = { "seen": _("Seen"),
|
|
|
|
"deleted": _("Deleted"),
|
|
|
|
"answered": _("Answered"),
|
|
|
|
"flagged": _("Flagged"),
|
|
|
|
"junk": _("Junk"),
|
|
|
|
"not_junk": _("Not Junk") };
|
2013-11-11 16:49:58 +01:00
|
|
|
|
2013-11-21 14:50:24 +01:00
|
|
|
for (var name in mailTags) {
|
|
|
|
flagLabels[name] = _( mailTags[name][0] );
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setupEventHandlers() {
|
2010-03-02 22:35:42 +01:00
|
|
|
var filterName = $($("mainForm").filterName);
|
2010-03-02 20:57:30 +01:00
|
|
|
if (filterName) {
|
2014-02-15 03:31:32 +01:00
|
|
|
filterName.on('change', onFilterNameChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
var matchTypeSelect = $("matchType");
|
|
|
|
if (matchTypeSelect) {
|
2014-02-15 03:31:32 +01:00
|
|
|
matchTypeSelect.on('change', onMatchTypeChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
2014-02-15 03:31:32 +01:00
|
|
|
// Filter rules
|
|
|
|
$("filterRules").on('click', onFilterRulesDivClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
var ruleAdd = $("ruleAdd");
|
|
|
|
if (ruleAdd) {
|
2014-02-15 03:31:32 +01:00
|
|
|
ruleAdd.on('click', onRuleAddClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
var ruleDelete = $("ruleDelete");
|
|
|
|
if (ruleDelete) {
|
2014-02-15 03:31:32 +01:00
|
|
|
ruleDelete.on('click', onRuleDeleteClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
2014-02-15 03:31:32 +01:00
|
|
|
// Filter actions
|
|
|
|
$('filterActions').on('click', onFilterActionsDivClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
var actionAdd = $("actionAdd");
|
|
|
|
if (actionAdd) {
|
2014-02-15 03:31:32 +01:00
|
|
|
actionAdd.on('click', onActionAddClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
var actionDelete = $("actionDelete");
|
|
|
|
if (actionDelete) {
|
2014-02-15 03:31:32 +01:00
|
|
|
actionDelete.on('click', onActionDeleteClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFilterNameChange(event) {
|
|
|
|
filter.name = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onMatchTypeChange() {
|
|
|
|
var matchType = this.value;
|
|
|
|
filter.match = matchType;
|
|
|
|
var container = $("filterRulesContainer");
|
|
|
|
var otherContainer = $("filterActionsContainer");
|
|
|
|
var otherContainerTop;
|
|
|
|
if (matchType == "allmessages") {
|
|
|
|
container.hide();
|
|
|
|
otherContainerTop = 130;
|
|
|
|
} else {
|
|
|
|
container.show();
|
|
|
|
otherContainerTop = 240;
|
|
|
|
}
|
|
|
|
otherContainer.setStyle({ top: otherContainerTop + "px" });
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFilterRulesDivClick(event) {
|
|
|
|
setSelectedRuleDiv(null);
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onFilterActionsDivClick(event) {
|
|
|
|
setSelectedActionDiv(null);
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function createFilterRule() {
|
|
|
|
return { field: "subject", operator: "contains", value: "" };
|
|
|
|
}
|
|
|
|
|
|
|
|
function createFilterAction() {
|
|
|
|
return { method: "fileinto", argument: "INBOX" };
|
|
|
|
}
|
|
|
|
|
|
|
|
function setupNewFilterData() {
|
|
|
|
var newFilterTemplate = $({ name: _("Untitled Filter"),
|
2012-01-17 20:52:51 +01:00
|
|
|
match: "any",
|
|
|
|
active: true });
|
2010-03-02 20:57:30 +01:00
|
|
|
newFilterTemplate.rules = $([ createFilterRule() ]);
|
|
|
|
newFilterTemplate.actions = $([ createFilterAction() ]);
|
|
|
|
|
|
|
|
filter = newFilterTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
function setupFilterViews() {
|
|
|
|
var filterName = $("mainForm").filterName;
|
|
|
|
if (filterName) {
|
|
|
|
filterName.value = filter.name;
|
|
|
|
if (filterId == "new") {
|
|
|
|
filterName.focus();
|
|
|
|
$(filterName).selectText(0, filterName.value.length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var matchTypeSelect = $("matchType");
|
|
|
|
if (matchTypeSelect) {
|
|
|
|
matchTypeSelect.value = filter.match;
|
|
|
|
}
|
|
|
|
if (filter.match != "allmessages") {
|
|
|
|
var filterRules = $("filterRules");
|
|
|
|
if (filterRules && filter.rules) {
|
|
|
|
for (var i = 0; i < filter.rules.length; i++) {
|
|
|
|
appendRule(filterRules, filter.rules[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-04-06 17:41:08 +02:00
|
|
|
onMatchTypeChange.apply(matchTypeSelect);
|
|
|
|
|
2010-03-02 20:57:30 +01:00
|
|
|
var filterActions = $("filterActions");
|
|
|
|
if (filterActions && filter.actions) {
|
|
|
|
for (var i = 0; i < filter.actions.length; i++) {
|
|
|
|
appendAction(filterActions, filter.actions[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function appendRule(container, rule) {
|
|
|
|
var ruleDiv = createElement("div", null, "rule",
|
|
|
|
{ rule: rule }, null,
|
|
|
|
container);
|
2014-02-15 03:31:32 +01:00
|
|
|
ruleDiv.on('click', onRuleDivClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
ensureRuleRepresentation(ruleDiv);
|
|
|
|
|
|
|
|
return ruleDiv;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onRuleDivClick(event) {
|
|
|
|
setSelectedRuleDiv(this);
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function setSelectedRuleDiv(newDiv) {
|
|
|
|
if (selectedRuleDiv) {
|
|
|
|
selectedRuleDiv.removeClassName("_selected");
|
|
|
|
}
|
|
|
|
selectedRuleDiv = newDiv;
|
|
|
|
if (selectedRuleDiv) {
|
|
|
|
selectedRuleDiv.addClassName("_selected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureRuleRepresentation(container) {
|
|
|
|
ensureFieldRepresentation(container);
|
|
|
|
ensureOperatorRepresentation(container);
|
|
|
|
ensureValueRepresentation(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFieldRepresentation(container) {
|
|
|
|
var fieldSpans = container.select("SPAN.fieldContainer");
|
|
|
|
var fieldSpan;
|
|
|
|
if (fieldSpans.length)
|
|
|
|
fieldSpan = fieldSpans[0];
|
|
|
|
else {
|
|
|
|
while (container.firstChild) {
|
|
|
|
container.removeChild(container.firstChild);
|
|
|
|
}
|
|
|
|
fieldSpan = createElement("span", null, "fieldContainer",
|
|
|
|
null, null, container);
|
|
|
|
}
|
|
|
|
ensureFieldSelectRepresentation(container, fieldSpan);
|
|
|
|
ensureFieldCustomHeaderRepresentation(container, fieldSpan);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFieldSelectRepresentation(container, fieldSpan) {
|
2014-01-27 21:09:22 +01:00
|
|
|
var fields = [ "subject", "from", "to", "cc", "to_or_cc", "size", "header" ];
|
|
|
|
if (sieveCapabilities.indexOf("body") > -1) {
|
|
|
|
fields.push("body");
|
|
|
|
}
|
2010-03-02 20:57:30 +01:00
|
|
|
var selects = fieldSpan.select("SELECT");
|
|
|
|
var select;
|
|
|
|
if (selects.length)
|
|
|
|
select = selects[0];
|
|
|
|
else {
|
|
|
|
select = createElement("select");
|
|
|
|
select.rule = container.rule;
|
2014-02-15 03:31:32 +01:00
|
|
|
select.on('change', onFieldSelectChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
for (var i = 0; i < fields.length; i++) {
|
|
|
|
var field = fields[i];
|
|
|
|
var fieldOption = createElement("option", null, null,
|
|
|
|
{ value: field }, null, select);
|
2014-02-15 03:31:32 +01:00
|
|
|
fieldOption.appendChild(document.createTextNode(fieldLabels[field]));
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
fieldSpan.appendChild(select);
|
|
|
|
}
|
|
|
|
select.value = container.rule.field;
|
|
|
|
container.rule.field = select.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFieldSelectChange(event) {
|
|
|
|
this.rule.field = this.value;
|
|
|
|
var fieldSpan = this.parentNode;
|
|
|
|
var container = fieldSpan.parentNode;
|
|
|
|
ensureFieldCustomHeaderRepresentation(container, fieldSpan);
|
|
|
|
ensureOperatorRepresentation(container);
|
|
|
|
ensureValueRepresentation(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFieldCustomHeaderRepresentation(container, fieldSpan) {
|
|
|
|
var headerInputs = fieldSpan.select("INPUT");
|
|
|
|
var headerInput = null;
|
|
|
|
if (headerInputs.length) {
|
|
|
|
headerInput = headerInputs[0];
|
|
|
|
}
|
|
|
|
if (container.rule.field == "header") {
|
|
|
|
if (!headerInput) {
|
2012-09-18 17:27:11 +02:00
|
|
|
headerInput = createElement("input", null, null,
|
2010-03-02 20:57:30 +01:00
|
|
|
{ type: "text" }, null, fieldSpan);
|
|
|
|
headerInput.rule = container.rule;
|
|
|
|
if (!container.rule.custom_header)
|
|
|
|
container.rule.custom_header = "";
|
|
|
|
headerInput.value = container.rule.custom_header;
|
2014-02-15 03:31:32 +01:00
|
|
|
headerInput.on('change', onFieldCustomHeaderChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
headerInput.focus();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (headerInput) {
|
|
|
|
if (container.rule.custom_header)
|
|
|
|
container.rule.custom_header = null;
|
|
|
|
fieldSpan.removeChild(headerInput);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFieldCustomHeaderChange(event) {
|
|
|
|
this.rule.custom_header = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureOperatorRepresentation(container) {
|
|
|
|
var operatorSpans = container.select("SPAN.operatorContainer");
|
|
|
|
var operatorSpan;
|
|
|
|
if (operatorSpans.length)
|
|
|
|
operatorSpan = operatorSpans[0];
|
|
|
|
else
|
|
|
|
operatorSpan = createElement("span", null, "operatorContainer",
|
|
|
|
null, null, container);
|
|
|
|
ensureOperatorSelectRepresentation(container, operatorSpan);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureOperatorSelectRepresentation(container, operatorSpan) {
|
|
|
|
var operators = determineOperators(container.rule.field);
|
|
|
|
|
|
|
|
var ruleField = container.rule.field;
|
|
|
|
var selects = operatorSpan.select("SELECT");
|
|
|
|
var select = null;
|
|
|
|
if (selects.length) {
|
|
|
|
select = selects[0];
|
|
|
|
if ((ruleField == "size" && !select.sizeOperator)
|
|
|
|
|| (ruleField != "size" && select.sizeOperator)) {
|
|
|
|
operatorSpan.removeChild(select);
|
|
|
|
select = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!select) {
|
|
|
|
select = createElement("select");
|
|
|
|
select.rule = container.rule;
|
|
|
|
select.sizeOperator = (ruleField == "size");
|
2014-02-15 03:31:32 +01:00
|
|
|
select.on('change', onOperatorSelectChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
for (var i = 0; i < operators.length; i++) {
|
|
|
|
var operator = operators[i];
|
|
|
|
var operatorOption = createElement("option", null, null,
|
|
|
|
{ value: operator }, null,
|
|
|
|
select);
|
2014-01-27 21:09:22 +01:00
|
|
|
operatorOption.appendChild(document.createTextNode(operatorLabels[operator]));
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
operatorSpan.appendChild(select);
|
|
|
|
}
|
|
|
|
if (container.rule.operator
|
|
|
|
&& operators.indexOf(container.rule.operator) == -1) {
|
|
|
|
container.rule.operator = operators[0];
|
|
|
|
}
|
|
|
|
select.value = container.rule.operator;
|
|
|
|
container.rule.operator = select.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onOperatorSelectChange(event) {
|
|
|
|
this.rule.operator = this.value;
|
|
|
|
var valueSpans = this.parentNode.parentNode.select("SPAN.valueContainer");
|
|
|
|
if (valueSpans.length) {
|
|
|
|
var valueInputs = valueSpans[0].select("INPUT");
|
|
|
|
if (valueInputs.length) {
|
|
|
|
valueInputs[0].focus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function determineOperators(field) {
|
|
|
|
var operators;
|
|
|
|
if (field == "size") {
|
|
|
|
operators = [ "under", "over" ];
|
|
|
|
} else {
|
|
|
|
var baseOperators = [ "is", "contains", "matches" ];
|
|
|
|
if (sieveCapabilities.indexOf("regex") > -1) {
|
|
|
|
baseOperators.push("regex");
|
|
|
|
}
|
|
|
|
operators = [];
|
|
|
|
for (var i = 0; i < baseOperators.length; i++) {
|
|
|
|
operators.push(baseOperators[i]);
|
|
|
|
operators.push(baseOperators[i] + "_not");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return operators;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureValueRepresentation(container) {
|
|
|
|
var valueSpans = container.select("SPAN.valueContainer");
|
|
|
|
var valueSpan;
|
|
|
|
if (valueSpans.length)
|
|
|
|
valueSpan = valueSpans[0];
|
|
|
|
else
|
|
|
|
valueSpan = createElement("span", null, "valueContainer",
|
|
|
|
null, null, container);
|
|
|
|
ensureValueInputRepresentation(container, valueSpan);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureValueInputRepresentation(container, valueSpan) {
|
|
|
|
var inputs = valueSpan.select("INPUT");
|
|
|
|
var input;
|
|
|
|
if (inputs.length) {
|
|
|
|
input = inputs[0];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
input = createElement("input", null, "textField");
|
|
|
|
input.rule = container.rule;
|
2014-02-15 03:31:32 +01:00
|
|
|
input.on('change', onValueInputChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
valueSpan.appendChild(input);
|
|
|
|
}
|
|
|
|
input.value = container.rule.value;
|
|
|
|
ensureFieldValidity(input);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFieldValidity(input) {
|
2012-01-02 20:02:43 +01:00
|
|
|
var valid = ensureFieldIsNotEmpty(input);
|
|
|
|
if (valid && input.rule.field == "size") {
|
2010-03-02 20:57:30 +01:00
|
|
|
valid = ensureFieldIsNumerical(input);
|
2012-01-02 20:02:43 +01:00
|
|
|
}
|
2010-03-02 20:57:30 +01:00
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onValueInputChange(event) {
|
|
|
|
if (ensureFieldValidity(this))
|
|
|
|
this.rule.value = this.value;
|
|
|
|
else
|
2012-01-02 20:02:43 +01:00
|
|
|
this.rule.value = "";
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFieldIsNumerical(input) {
|
|
|
|
var valid = !isNaN(input.value);
|
|
|
|
if (valid) {
|
|
|
|
input.removeClassName("_invalid");
|
|
|
|
} else {
|
|
|
|
input.addClassName("_invalid");
|
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
2012-01-02 20:02:43 +01:00
|
|
|
function ensureFieldIsNotEmpty(input) {
|
|
|
|
var valid = !input.value.blank();
|
|
|
|
if (valid) {
|
|
|
|
input.removeClassName("_invalid");
|
|
|
|
} else {
|
|
|
|
input.addClassName("_invalid");
|
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
2010-03-02 20:57:30 +01:00
|
|
|
function appendAction(container, action) {
|
|
|
|
var actionDiv = createElement("div", null, "action",
|
|
|
|
{ action: action }, null,
|
|
|
|
container);
|
2014-02-15 03:31:32 +01:00
|
|
|
actionDiv.on('click', onActionDivClick);
|
2010-03-02 20:57:30 +01:00
|
|
|
ensureActionRepresentation(actionDiv);
|
|
|
|
|
|
|
|
return actionDiv;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onActionDivClick(event) {
|
|
|
|
setSelectedActionDiv(this);
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function setSelectedActionDiv(newSpan) {
|
|
|
|
if (selectedActionDiv) {
|
|
|
|
selectedActionDiv.removeClassName("_selected");
|
|
|
|
}
|
|
|
|
selectedActionDiv = newSpan;
|
|
|
|
if (selectedActionDiv) {
|
|
|
|
selectedActionDiv.addClassName("_selected");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureActionRepresentation(container) {
|
|
|
|
ensureMethodRepresentation(container);
|
|
|
|
ensureArgumentRepresentation(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureMethodRepresentation(container) {
|
|
|
|
var methodSpans = container.select("SPAN.methodContainer");
|
|
|
|
var methodSpan;
|
|
|
|
if (methodSpans.length)
|
|
|
|
methodSpan = methodSpans[0];
|
|
|
|
else {
|
|
|
|
while (container.firstChild) {
|
|
|
|
container.removeChild(container.firstChild);
|
|
|
|
}
|
|
|
|
methodSpan = createElement("span", null, "methodContainer",
|
|
|
|
null, null, container);
|
|
|
|
}
|
|
|
|
ensureMethodSelectRepresentation(container, methodSpan);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureMethodSelectRepresentation(container, methodSpan) {
|
|
|
|
var methods = [ "redirect", "discard", "keep" ];
|
|
|
|
if (sieveCapabilities.indexOf("reject") > -1) {
|
|
|
|
methods.push("reject");
|
|
|
|
}
|
|
|
|
if (sieveCapabilities.indexOf("fileinto") > -1) {
|
|
|
|
methods.push("fileinto");
|
|
|
|
}
|
2014-03-27 17:06:24 +01:00
|
|
|
if (sieveCapabilities.indexOf("imapflags") > -1 || sieveCapabilities.indexOf("imap4flags") > -1) {
|
2010-03-02 20:57:30 +01:00
|
|
|
methods.push("addflag");
|
|
|
|
}
|
|
|
|
methods.push("stop");
|
|
|
|
/* TODO: those are currently unimplemented */
|
|
|
|
// if (sieveCapabilities.indexOf("notify") > -1) {
|
|
|
|
// methods.push("notify");
|
|
|
|
// }
|
|
|
|
// if (sieveCapabilities.indexOf("vacation") > -1) {
|
|
|
|
// methods.push("vacation");
|
|
|
|
// }
|
|
|
|
|
|
|
|
var selects = methodSpan.select("SELECT");
|
|
|
|
var select;
|
|
|
|
if (selects.length)
|
|
|
|
select = selects[0];
|
|
|
|
else {
|
|
|
|
select = createElement("select");
|
|
|
|
select.action = container.action;
|
2014-02-15 03:31:32 +01:00
|
|
|
select.on('change', onMethodSelectChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
for (var i = 0; i < methods.length; i++) {
|
|
|
|
var method = methods[i];
|
|
|
|
var methodOption = createElement("option", null, null,
|
|
|
|
{ value: method }, null, select);
|
2014-02-15 03:31:32 +01:00
|
|
|
methodOption.appendChild(document.createTextNode(methodLabels[method]));
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
methodSpan.appendChild(select);
|
|
|
|
}
|
|
|
|
select.value = container.action.method;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onMethodSelectChange(event) {
|
|
|
|
this.action.method = this.value;
|
|
|
|
var methodSpan = this.parentNode;
|
|
|
|
var container = methodSpan.parentNode;
|
|
|
|
ensureArgumentRepresentation(container);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureArgumentRepresentation(container) {
|
|
|
|
var argumentWidgetMethods
|
|
|
|
= { "addflag": ensureFlagArgRepresentation,
|
|
|
|
"fileinto": ensureMailboxArgRepresentation,
|
|
|
|
"redirect": ensureRedirectArgRepresentation,
|
|
|
|
"reject": ensureRejectArgRepresentation,
|
|
|
|
"vacation": ensureVacationArgRepresentation };
|
|
|
|
|
|
|
|
var widgetMethod = argumentWidgetMethods[container.action.method];
|
|
|
|
var spanClass = container.action.method + "Argument";
|
|
|
|
|
|
|
|
var argumentSpans = container.select("SPAN.argumentContainer");
|
|
|
|
var argumentSpan;
|
|
|
|
if (argumentSpans.length) {
|
|
|
|
argumentSpan = argumentSpans[0];
|
|
|
|
if (argumentSpan
|
|
|
|
&& (!widgetMethod || !argumentSpan.hasClassName(spanClass))) {
|
|
|
|
container.removeChild(argumentSpan);
|
|
|
|
container.action.argument = null;
|
|
|
|
argumentSpan = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
argumentSpan = null;
|
|
|
|
|
|
|
|
if (!argumentSpan && widgetMethod) {
|
|
|
|
argumentSpan = createElement("span", null,
|
|
|
|
["argumentContainer", spanClass],
|
|
|
|
null, null, container);
|
|
|
|
widgetMethod(container, argumentSpan);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureFlagArgRepresentation(container, argumentSpan) {
|
|
|
|
var selects = argumentSpan.select("SELECT");
|
|
|
|
var select;
|
|
|
|
if (selects.length)
|
|
|
|
select = selects[0];
|
|
|
|
else {
|
|
|
|
select = createElement("select");
|
|
|
|
select.action = container.action;
|
2014-02-15 03:31:32 +01:00
|
|
|
select.on('change', onFlagArgumentSelectChange);
|
|
|
|
for (var flag in flagLabels) {
|
|
|
|
if (typeof flag != 'undefined') {
|
|
|
|
var flagOption = createElement("option", null, null,
|
|
|
|
{ value: flag }, null, select);
|
|
|
|
var label = flagLabels[flag];
|
|
|
|
flagOption.appendChild(document.createTextNode(label));
|
|
|
|
}
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
argumentSpan.appendChild(select);
|
|
|
|
}
|
|
|
|
/* 1) initialize the value if null
|
|
|
|
2) set the SELECT to the corresponding value
|
|
|
|
3) if value was not null in 1, we must ensure the SELECT contains it */
|
|
|
|
if (!container.action.argument)
|
|
|
|
container.action.argument = "seen";
|
|
|
|
select.value = container.action.argument;
|
|
|
|
container.action.argument = select.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onFlagArgumentSelectChange(event) {
|
|
|
|
this.action.argument = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureMailboxArgRepresentation(container, argumentSpan) {
|
|
|
|
var selects = argumentSpan.select("SELECT");
|
|
|
|
var select;
|
|
|
|
if (selects.length)
|
|
|
|
select = selects[0];
|
|
|
|
else {
|
|
|
|
select = createElement("select");
|
|
|
|
select.action = container.action;
|
|
|
|
if (!container.action.argument)
|
|
|
|
container.action.argument = "INBOX";
|
2014-02-15 03:31:32 +01:00
|
|
|
select.on('change', onMailboxArgumentSelectChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
var mailboxes = (window.opener
|
|
|
|
? window.opener.userMailboxes
|
2014-01-27 21:43:48 +01:00
|
|
|
: {'displayName': 'INBOX', 'path': 'INBOX' });
|
2010-03-02 20:57:30 +01:00
|
|
|
for (var i = 0; i < mailboxes.length; i++) {
|
|
|
|
var mailbox = mailboxes[i];
|
2014-03-05 18:31:27 +01:00
|
|
|
var folderValue;
|
2014-04-04 20:56:14 +02:00
|
|
|
((sieveFolderEncoding == "UTF-8") ? folderValue = mailbox.displayName
|
|
|
|
: folderValue = mailbox.path);
|
2014-03-05 18:31:27 +01:00
|
|
|
|
2010-03-02 20:57:30 +01:00
|
|
|
var mboxOption = createElement("option", null, null,
|
2014-03-05 18:31:27 +01:00
|
|
|
{ value: folderValue }, null, select);
|
2014-01-27 21:43:48 +01:00
|
|
|
mboxOption.appendChild(document.createTextNode(mailbox.displayName));
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
argumentSpan.appendChild(select);
|
|
|
|
}
|
|
|
|
select.value = container.action.argument;
|
|
|
|
container.action.argument = select.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onMailboxArgumentSelectChange(event) {
|
|
|
|
this.action.argument = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureRedirectArgRepresentation(container, argumentSpan) {
|
|
|
|
var emailInputs = argumentSpan.select("INPUT");
|
|
|
|
var emailInput = null;
|
|
|
|
if (emailInputs.length) {
|
|
|
|
emailInput = emailInputs[0];
|
|
|
|
}
|
|
|
|
if (!emailInput) {
|
|
|
|
emailInput = createElement("input", null, "textField",
|
|
|
|
{ type: "text" }, null, argumentSpan);
|
|
|
|
emailInput.action = container.action;
|
|
|
|
if (!container.action.argument)
|
|
|
|
container.action.argument = "";
|
2014-02-15 03:31:32 +01:00
|
|
|
emailInput.on('change', onEmailArgumentChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
emailInput.focus();
|
|
|
|
}
|
|
|
|
emailInput.value = container.action.argument;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onEmailArgumentChange(event) {
|
|
|
|
this.action.argument = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureRejectArgRepresentation(container, argumentSpan) {
|
|
|
|
var msgAreas = argumentSpan.select("TEXTAREA");
|
|
|
|
var msgArea = null;
|
|
|
|
if (msgAreas.length) {
|
|
|
|
msgArea = msgAreas[0];
|
|
|
|
}
|
|
|
|
if (!msgArea) {
|
|
|
|
msgArea = createElement("textarea", null, null,
|
|
|
|
{ action: container.action }, null,
|
|
|
|
argumentSpan);
|
|
|
|
if (!container.action.argument)
|
|
|
|
container.action.argument = "";
|
2014-02-15 03:31:32 +01:00
|
|
|
msgArea.on('change', onMsgArgumentChange);
|
2010-03-02 20:57:30 +01:00
|
|
|
msgArea.focus();
|
|
|
|
}
|
|
|
|
msgArea.value = container.action.argument;
|
|
|
|
}
|
|
|
|
|
|
|
|
function onMsgArgumentChange(event) {
|
|
|
|
this.action.argument = this.value;
|
|
|
|
}
|
|
|
|
|
|
|
|
function ensureVacationArgRepresentation(container, argumentSpan) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function onRuleAddClick(event) {
|
|
|
|
var filterRules = $("filterRules");
|
|
|
|
if (filterRules) {
|
|
|
|
var newRule = createFilterRule();
|
2010-04-06 17:41:08 +02:00
|
|
|
if (!filter.rules)
|
|
|
|
filter.rules = [];
|
2010-03-02 20:57:30 +01:00
|
|
|
filter.rules.push(newRule);
|
|
|
|
var newRuleDiv = appendRule(filterRules, newRule);
|
|
|
|
setSelectedRuleDiv(newRuleDiv);
|
|
|
|
filterRules.scrollTop = newRuleDiv.offsetTop;
|
|
|
|
}
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onRuleDeleteClick(event) {
|
|
|
|
if (selectedRuleDiv) {
|
|
|
|
var ruleIndex = filter.rules.indexOf(selectedRuleDiv.rule);
|
|
|
|
filter.rules.splice(ruleIndex, 1);
|
|
|
|
var nextSelected = selectedRuleDiv.next();
|
|
|
|
if (!nextSelected)
|
|
|
|
nextSelected = selectedRuleDiv.previous();
|
|
|
|
selectedRuleDiv.parentNode.removeChild(selectedRuleDiv);
|
|
|
|
setSelectedRuleDiv(nextSelected);
|
|
|
|
}
|
|
|
|
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onActionAddClick(event) {
|
|
|
|
var filterActions = $("filterActions");
|
|
|
|
if (filterActions) {
|
|
|
|
var newAction = createFilterAction();
|
|
|
|
filter.actions.push(newAction);
|
|
|
|
var newActionDiv = appendAction(filterActions, newAction);
|
|
|
|
setSelectedActionDiv(newActionDiv);
|
|
|
|
filterActions.scrollTop = newActionDiv.offsetTop;
|
|
|
|
}
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function onActionDeleteClick(event) {
|
|
|
|
if (selectedActionDiv) {
|
|
|
|
var actionIndex = filter.actions.indexOf(selectedActionDiv.action);
|
|
|
|
filter.actions.splice(actionIndex, 1);
|
|
|
|
var nextSelected = selectedActionDiv.next();
|
|
|
|
if (!nextSelected)
|
|
|
|
nextSelected = selectedActionDiv.previous();
|
|
|
|
selectedActionDiv.parentNode.removeChild(selectedActionDiv);
|
|
|
|
setSelectedActionDiv(nextSelected);
|
|
|
|
}
|
|
|
|
|
2012-03-14 01:48:26 +01:00
|
|
|
Event.stop(event);
|
2010-03-02 20:57:30 +01:00
|
|
|
}
|
|
|
|
|
2012-03-13 22:13:31 +01:00
|
|
|
function savePreferences(event) {
|
2012-01-02 20:02:43 +01:00
|
|
|
var valid = true;
|
2012-03-13 22:13:31 +01:00
|
|
|
|
2012-06-04 21:47:36 +02:00
|
|
|
var container = $('filterRulesContainer');
|
|
|
|
if (container.visible()) {
|
|
|
|
var rules = container.select("DIV#filterRules DIV.rule");
|
|
|
|
if (rules.length == 0) {
|
|
|
|
onRuleAddClick(event);
|
|
|
|
valid = false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
var inputs = $$("DIV#filterRules input");
|
|
|
|
inputs.each(function(input) {
|
|
|
|
if (input.hasClassName("_invalid"))
|
|
|
|
valid = false;
|
|
|
|
});
|
|
|
|
}
|
2012-03-13 22:13:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var actions = $$("DIV#filterActions DIV.action");
|
|
|
|
if (actions.length == 0) {
|
|
|
|
onActionAddClick(event);
|
|
|
|
valid = false;
|
|
|
|
}
|
|
|
|
|
2012-01-02 20:02:43 +01:00
|
|
|
if (valid) {
|
|
|
|
if (window.opener) {
|
|
|
|
window.opener.updateFilterFromEditor(filterId, Object.toJSON(filter));
|
|
|
|
}
|
|
|
|
window.close();
|
|
|
|
}
|
|
|
|
|
2010-03-02 20:57:30 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// function configureDragHandles() {
|
|
|
|
// var handle = $("splitter");
|
|
|
|
// if (handle) {
|
|
|
|
// handle.addInterface(SOGoDragHandlesInterface);
|
|
|
|
// handle.upperBlock = $("filterRulesContainer");
|
|
|
|
// handle.lowerBlock = $("filterActionsContainer");
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
document.observe("dom:loaded", onLoadHandler);
|