mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
More Sieve parser improvements after doing 'if not' test
This commit is contained in:
parent
2786d0d959
commit
0aafce4214
4 changed files with 153 additions and 130 deletions
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
(Sieve => {
|
(Sieve => {
|
||||||
|
|
||||||
|
const Grammar = Sieve.Grammar, Command = Grammar.Command;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-3.1
|
* https://tools.ietf.org/html/rfc5228#section-3.1
|
||||||
* Usage:
|
* Usage:
|
||||||
|
|
@ -11,23 +13,19 @@
|
||||||
* elsif <test2: test> <block2: block>
|
* elsif <test2: test> <block2: block>
|
||||||
* else <block3: block>
|
* else <block3: block>
|
||||||
*/
|
*/
|
||||||
class Conditional
|
class Conditional extends Command
|
||||||
{
|
{
|
||||||
constructor(identifier = 'if')
|
constructor(identifier = 'if')
|
||||||
{
|
{
|
||||||
this.identifier = identifier;
|
super(identifier);
|
||||||
this.test = null,
|
this.test = null;
|
||||||
this.commands = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return this.identifier
|
return this.identifier
|
||||||
+ ('else' !== this.identifier ? ' ' + this.test : '')
|
+ ('else' !== this.identifier ? ' ' + this.test : '')
|
||||||
+ (this.commands.length
|
+ ' ' + this.commands;
|
||||||
? ' {\r\n\t' + Sieve.arrayToString(this.commands, ';\r\n\t') + ';\r\n}'
|
|
||||||
: ';'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
public function pushArguments(array $args): void
|
public function pushArguments(array $args): void
|
||||||
|
|
@ -41,23 +39,24 @@ class Conditional
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-3.2
|
* https://tools.ietf.org/html/rfc5228#section-3.2
|
||||||
*/
|
*/
|
||||||
class Require /* extends Array*/
|
class Require extends Command
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
this.capabilities = new Sieve.Grammar.StringList();
|
super('require');
|
||||||
|
this.capabilities = new Grammar.StringList();
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'require ' + this.capabilities.toString();
|
return 'require ' + this.capabilities.toString() + ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
if (args[0] instanceof Sieve.Grammar.StringList) {
|
if (args[0] instanceof Grammar.StringList) {
|
||||||
this.capabilities = args[0];
|
this.capabilities = args[0];
|
||||||
} else if (args[0] instanceof Sieve.Grammar.QuotedString) {
|
} else if (args[0] instanceof Grammar.QuotedString) {
|
||||||
this.capabilities.push(args[0]);
|
this.capabilities.push(args[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -66,30 +65,36 @@ class Require /* extends Array*/
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-3.3
|
* https://tools.ietf.org/html/rfc5228#section-3.3
|
||||||
*/
|
*/
|
||||||
class Stop
|
class Stop extends Command
|
||||||
{
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super('stop');
|
||||||
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'stop';
|
return 'stop;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-4.1
|
* https://tools.ietf.org/html/rfc5228#section-4.1
|
||||||
*/
|
*/
|
||||||
class FileInto
|
class FileInto extends Command
|
||||||
{
|
{
|
||||||
// const REQUIRE = 'fileinto';
|
// const REQUIRE = 'fileinto';
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('fileinto');
|
||||||
// QuotedString / MultiLine
|
// QuotedString / MultiLine
|
||||||
this._mailbox = new Sieve.Grammar.QuotedString();
|
this._mailbox = new Grammar.QuotedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'fileinto ' + this._mailbox;
|
return 'fileinto ' + this._mailbox + ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
get mailbox()
|
get mailbox()
|
||||||
|
|
@ -104,7 +109,7 @@ class FileInto
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
if (args[0] instanceof Sieve.Grammar.StringType) {
|
if (args[0] instanceof Grammar.StringType) {
|
||||||
this._mailbox = args[0];
|
this._mailbox = args[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,17 +118,18 @@ class FileInto
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-4.2
|
* https://tools.ietf.org/html/rfc5228#section-4.2
|
||||||
*/
|
*/
|
||||||
class Redirect
|
class Redirect extends Command
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('redirect');
|
||||||
// QuotedString / MultiLine
|
// QuotedString / MultiLine
|
||||||
this._address = new Sieve.Grammar.QuotedString();
|
this._address = new Grammar.QuotedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'redirect ' + this.address;
|
return 'redirect ' + this.address + ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
get address()
|
get address()
|
||||||
|
|
@ -140,22 +146,32 @@ class Redirect
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-4.3
|
* https://tools.ietf.org/html/rfc5228#section-4.3
|
||||||
*/
|
*/
|
||||||
class Keep
|
class Keep extends Command
|
||||||
{
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super('keep');
|
||||||
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'keep';
|
return 'keep;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-4.4
|
* https://tools.ietf.org/html/rfc5228#section-4.4
|
||||||
*/
|
*/
|
||||||
class Discard
|
class Discard extends Command
|
||||||
{
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super('discard');
|
||||||
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'discard';
|
return 'discard;';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,33 +49,23 @@ class Comment extends StringType
|
||||||
*/
|
*/
|
||||||
class Command
|
class Command
|
||||||
{
|
{
|
||||||
constructor(identifier, text = null)
|
constructor(identifier)
|
||||||
{
|
{
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.arguments = [];
|
this.arguments = [];
|
||||||
if (text) {
|
this.commands = new Commands;
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
let result = this.identifier;
|
let result = this.identifier;
|
||||||
if ('anyof' === result || 'allof' === result) {
|
if (this.arguments.length) {
|
||||||
result += ' (\r\n\t' + Sieve.arrayToString(this.commands, ',\r\n\t') + '\r\n)';
|
result += Sieve.arrayToString(this.arguments, ' ');
|
||||||
|
}
|
||||||
|
if (this.commands.length) {
|
||||||
|
result += ' ' + this.commands.toString();
|
||||||
} else {
|
} else {
|
||||||
this.arguments.forEach(arg => {
|
result += ';';
|
||||||
if (Array.isArray(arg)) {
|
|
||||||
result += ' [' + arg.join(',') + ']';
|
|
||||||
} else {
|
|
||||||
result += ' ' + arg;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (this.commands) {
|
|
||||||
result += ' {\r\n\t' + Sieve.arrayToString(this.commands, ';\r\n\t') + '\r\n}';
|
|
||||||
} else {
|
|
||||||
result += ';';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -96,24 +86,22 @@ class Command
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
class Commands extends Array
|
class Commands extends Array
|
||||||
{
|
{
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return this.length
|
return this.length
|
||||||
? '{\r\n\t' + Sieve.arrayToString(this, ';\r\n\t') + ';\r\n}'
|
? '{\r\n\t' + Sieve.arrayToString(this, '\r\n\t') + '\r\n}'
|
||||||
: ';';
|
: '{}';
|
||||||
}
|
}
|
||||||
|
|
||||||
push(value)
|
push(value)
|
||||||
{
|
{
|
||||||
if (value instanceof Command) {
|
if (value instanceof Command || value instanceof Comment) {
|
||||||
super.push(value);
|
super.push(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
class BracketComment extends Comment
|
class BracketComment extends Comment
|
||||||
{
|
{
|
||||||
|
|
@ -223,7 +211,7 @@ class MultiLine extends StringType
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-2.9
|
* https://tools.ietf.org/html/rfc5228#section-5
|
||||||
*/
|
*/
|
||||||
class Test
|
class Test
|
||||||
{
|
{
|
||||||
|
|
@ -250,15 +238,15 @@ class Test
|
||||||
*/
|
*/
|
||||||
class TestList extends Array
|
class TestList extends Array
|
||||||
{
|
{
|
||||||
constructor(identifier)
|
constructor()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.identifier = identifier; // allof / anyof
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
if (1 < this.length) {
|
if (1 < this.length) {
|
||||||
|
// return '(\r\n\t' + Sieve.arrayToString(this, ',\r\n\t') + '\r\n)';
|
||||||
return '(' + this.join(', ') + ')';
|
return '(' + this.join(', ') + ')';
|
||||||
}
|
}
|
||||||
return this.length ? this[0] : '';
|
return this.length ? this[0] : '';
|
||||||
|
|
@ -266,34 +254,13 @@ class TestList extends Array
|
||||||
|
|
||||||
push(value)
|
push(value)
|
||||||
{
|
{
|
||||||
/*
|
if (!(value instanceof Test)) {
|
||||||
if (!(value instanceof Command)) {
|
throw 'Not an instanceof Test';
|
||||||
value = new Command($value);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
super.push(value);
|
super.push(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TestList.fromString = list => {
|
|
||||||
let test,
|
|
||||||
obj = new TestList,
|
|
||||||
regex = RegExp('(?:^\\s*|\\s*,\\s*)(' + RegEx.IDENTIFIER + ')((?:\\s+' + RegEx.ARGUMENT + ')*)', 'g');
|
|
||||||
list = list.replace(/^[\r\n\t(]+/, '');
|
|
||||||
while ((test = regex.exec(list))) {
|
|
||||||
let command = new Sieve.Commands.Command(test[1]);
|
|
||||||
obj.push(command);
|
|
||||||
/*
|
|
||||||
if (\preg_match_all('@\\s+(' . RegEx.ARGUMENT . ')@', $test[2], $args, PREG_SET_ORDER)) {
|
|
||||||
foreach ($args as $arg) {
|
|
||||||
$command->arguments[] = $arg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sieve.Grammar = {
|
Sieve.Grammar = {
|
||||||
Command: Command,
|
Command: Command,
|
||||||
BracketComment: BracketComment,
|
BracketComment: BracketComment,
|
||||||
|
|
|
||||||
|
|
@ -106,31 +106,32 @@ Sieve.parseScript = script => {
|
||||||
// new_command = new Sieve.Grammar.Command(value);
|
// new_command = new Sieve.Grammar.Command(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command instanceof Sieve.Commands.Conditional && !command.test) {
|
if (new_command instanceof Sieve.Grammar.Test) {
|
||||||
if (new_command instanceof Sieve.Grammar.TestList) {
|
if (command instanceof Sieve.Commands.Conditional || command instanceof Sieve.Tests.Not) {
|
||||||
levels.push(new_command);
|
// if/elsif/else new_command
|
||||||
|
// not new_command
|
||||||
|
command.test = new_command;
|
||||||
|
} else if (command.tests instanceof Sieve.Grammar.TestList) {
|
||||||
|
// allof/anyof .tests[] new_command
|
||||||
|
command.tests.push(new_command);
|
||||||
} else {
|
} else {
|
||||||
new_command = new Sieve.Grammar.Test(value);
|
error('Test not allowed here');
|
||||||
|
}
|
||||||
|
} else if (command) {
|
||||||
|
if (command.commands) {
|
||||||
|
command.commands.push(new_command);
|
||||||
|
} else {
|
||||||
|
console.dir(command);
|
||||||
|
error('commands not allowed');
|
||||||
}
|
}
|
||||||
command.test = new_command;
|
|
||||||
} else {
|
} else {
|
||||||
if (levels.length) {
|
tree.push(new_command);
|
||||||
let cmd = levels.last();
|
|
||||||
if (cmd instanceof Sieve.Grammar.TestList) {
|
|
||||||
cmd.push(new_command);
|
|
||||||
} else {
|
|
||||||
cmd.commands.push(new_command);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tree.push(new_command);
|
|
||||||
}
|
|
||||||
if (new_command instanceof Sieve.Commands.Conditional || new_command instanceof Sieve.Grammar.TestList) {
|
|
||||||
levels.push(new_command);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
levels.push(new_command);
|
||||||
command = new_command;
|
command = new_command;
|
||||||
break; }
|
break; }
|
||||||
|
|
||||||
|
// Arguments
|
||||||
case T_TAG:
|
case T_TAG:
|
||||||
command
|
command
|
||||||
? args.push(value.toLowerCase())
|
? args.push(value.toLowerCase())
|
||||||
|
|
@ -157,6 +158,7 @@ Sieve.parseScript = script => {
|
||||||
: error('Number must be command argument');
|
: error('Number must be command argument');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Comments
|
||||||
case T_BRACKET_COMMENT:
|
case T_BRACKET_COMMENT:
|
||||||
(command ? command.commands : tree).push(
|
(command ? command.commands : tree).push(
|
||||||
new Sieve.Grammar.BracketComment(value.substr(2, value.length-4))
|
new Sieve.Grammar.BracketComment(value.substr(2, value.length-4))
|
||||||
|
|
@ -174,48 +176,52 @@ Sieve.parseScript = script => {
|
||||||
command || tree.push(value.trim());
|
command || tree.push(value.trim());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Command end
|
||||||
case T_SEMICOLON:
|
case T_SEMICOLON:
|
||||||
command || error('Semicolon not at end of command');
|
command || error('Semicolon not at end of command');
|
||||||
pushArgs();
|
pushArgs();
|
||||||
// levels.pop();
|
levels.pop();
|
||||||
command = levels.last();
|
command = levels.last();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Command block
|
||||||
case T_BLOCK_START:
|
case T_BLOCK_START:
|
||||||
|
pushArgs();
|
||||||
// https://tools.ietf.org/html/rfc5228#section-2.9
|
// https://tools.ietf.org/html/rfc5228#section-2.9
|
||||||
// Action commands do not take tests or blocks
|
// Action commands do not take tests or blocks
|
||||||
levels.length || error('Block start not part of control command');
|
while (command && !(command instanceof Sieve.Commands.Conditional)) {
|
||||||
command || error('Block start not at end of command arguments');
|
levels.pop();
|
||||||
pushArgs();
|
command = levels.last();
|
||||||
command = levels.last();
|
}
|
||||||
|
command || error('Block start not part of control command');
|
||||||
break;
|
break;
|
||||||
case T_BLOCK_END:
|
case T_BLOCK_END:
|
||||||
levels.length || error('Block end has no matching block start');
|
(command instanceof Sieve.Commands.Conditional) || error('Block end has no matching block start');
|
||||||
levels.pop();
|
levels.pop();
|
||||||
command = levels.last();
|
command = levels.last();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// anyof / allof
|
// anyof / allof ( ... , ... )
|
||||||
case T_LEFT_PARENTHESIS:
|
case T_LEFT_PARENTHESIS:
|
||||||
(levels.last() instanceof Sieve.Grammar.TestList)
|
|
||||||
|| error('Test start not part of test-list');
|
|
||||||
command || error('Not inside command');
|
|
||||||
pushArgs();
|
pushArgs();
|
||||||
command = levels.last();
|
while (command && !(command.tests instanceof Sieve.Grammar.TestList)) {
|
||||||
|
levels.pop();
|
||||||
|
command = levels.last();
|
||||||
|
}
|
||||||
|
command || error('Test start not part of anyof/allof test');
|
||||||
break;
|
break;
|
||||||
case T_RIGHT_PARENTHESIS:
|
case T_RIGHT_PARENTHESIS:
|
||||||
(levels.last() instanceof Sieve.Grammar.TestList)
|
|
||||||
|| error('Test end not part of test-list');
|
|
||||||
pushArgs();
|
pushArgs();
|
||||||
levels.pop();
|
levels.pop();
|
||||||
command = levels.last();
|
command = levels.last();
|
||||||
|
(command.tests instanceof Sieve.Grammar.TestList) || error('Test end not part of test-list');
|
||||||
break;
|
break;
|
||||||
case T_COMMA:
|
case T_COMMA:
|
||||||
// Must be inside PARENTHESIS aka test-list
|
|
||||||
(levels.last() instanceof Sieve.Grammar.TestList)
|
|
||||||
|| error('Comma not part of test-list');
|
|
||||||
pushArgs();
|
pushArgs();
|
||||||
|
levels.pop();
|
||||||
command = levels.last();
|
command = levels.last();
|
||||||
|
// Must be inside PARENTHESIS aka test-list
|
||||||
|
(command.tests instanceof Sieve.Grammar.TestList) || error('Comma not part of test-list');
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_UNKNOWN:
|
case T_UNKNOWN:
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,23 @@
|
||||||
|
|
||||||
(Sieve => {
|
(Sieve => {
|
||||||
|
|
||||||
|
const Grammar = Sieve.Grammar,
|
||||||
|
Test = Grammar.Test,
|
||||||
|
StringList = Grammar.StringList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.1
|
* https://tools.ietf.org/html/rfc5228#section-5.1
|
||||||
*/
|
*/
|
||||||
class Address
|
class Address extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('address');
|
||||||
this.comparator = 'i;ascii-casemap';
|
this.comparator = 'i;ascii-casemap';
|
||||||
this.address_part = ':all'; // :localpart | :domain | :all
|
this.address_part = ':all'; // :localpart | :domain | :all
|
||||||
this.match_type = ':is';
|
this.match_type = ':is';
|
||||||
this.header_list = new Sieve.Grammar.StringList;
|
this.header_list = new StringList;
|
||||||
this.key_list = new Sieve.Grammar.StringList;
|
this.key_list = new StringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
|
|
@ -37,37 +42,50 @@ class Address
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.2
|
* https://tools.ietf.org/html/rfc5228#section-5.2
|
||||||
*/
|
*/
|
||||||
class AllOf extends Sieve.Grammar.TestList
|
class AllOf extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super('allof');
|
super('allof');
|
||||||
|
this.tests = new Grammar.TestList;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
return 'allof' + this.tests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.3
|
* https://tools.ietf.org/html/rfc5228#section-5.3
|
||||||
*/
|
*/
|
||||||
class AnyOf extends Sieve.Grammar.TestList
|
class AnyOf extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
super('anyof');
|
super('anyof');
|
||||||
|
this.tests = new Grammar.TestList;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
return 'anyof' + this.tests;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.4
|
* https://tools.ietf.org/html/rfc5228#section-5.4
|
||||||
*/
|
*/
|
||||||
class Envelope
|
class Envelope extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('envelope');
|
||||||
this.comparator = 'i;ascii-casemap';
|
this.comparator = 'i;ascii-casemap';
|
||||||
this.address_part = ':all'; // :localpart | :domain | :all
|
this.address_part = ':all'; // :localpart | :domain | :all
|
||||||
this.match_type = ':is';
|
this.match_type = ':is';
|
||||||
this.envelope_part = new Sieve.Grammar.StringList;
|
this.envelope_part = new StringList;
|
||||||
this.key_list = new Sieve.Grammar.StringList;
|
this.key_list = new StringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
|
|
@ -89,16 +107,17 @@ class Envelope
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.5
|
* https://tools.ietf.org/html/rfc5228#section-5.5
|
||||||
*/
|
*/
|
||||||
class Exists
|
class Exists extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
this.header_names = new Sieve.Grammar.StringList;
|
super('exists');
|
||||||
|
this.header_names = new StringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return "exists {this.header_names}";
|
return 'exists ' + this.header_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushArguments(/*args*/)
|
pushArguments(/*args*/)
|
||||||
|
|
@ -110,7 +129,7 @@ class Exists
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.6
|
* https://tools.ietf.org/html/rfc5228#section-5.6
|
||||||
*/
|
*/
|
||||||
class False
|
class False extends Test
|
||||||
{
|
{
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
|
|
@ -121,15 +140,16 @@ class False
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.7
|
* https://tools.ietf.org/html/rfc5228#section-5.7
|
||||||
*/
|
*/
|
||||||
class Header
|
class Header extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('header');
|
||||||
this.comparator = 'i;ascii-casemap';
|
this.comparator = 'i;ascii-casemap';
|
||||||
this.address_part = ':all'; // :localpart | :domain | :all
|
this.address_part = ':all'; // :localpart | :domain | :all
|
||||||
this.match_type = ':is';
|
this.match_type = ':is';
|
||||||
this.header_names = new Sieve.Grammar.StringList;
|
this.header_names = new StringList;
|
||||||
this.key_list = new Sieve.Grammar.StringList;
|
this.key_list = new StringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
|
|
@ -146,7 +166,7 @@ class Header
|
||||||
args.forEach((arg, i) => {
|
args.forEach((arg, i) => {
|
||||||
if (':is' === arg || ':contains' === arg || ':matches' === arg) {
|
if (':is' === arg || ':contains' === arg || ':matches' === arg) {
|
||||||
this.match_type = arg;
|
this.match_type = arg;
|
||||||
} else if (arg instanceof Sieve.Grammar.StringList || arg instanceof Sieve.Grammar.StringType) {
|
} else if (arg instanceof StringList || arg instanceof Grammar.StringType) {
|
||||||
this[args[i+1] ? 'header_names' : 'key_list'] = arg;
|
this[args[i+1] ? 'header_names' : 'key_list'] = arg;
|
||||||
// (args[i+1] ? this.header_names : this.key_list) = arg;
|
// (args[i+1] ? this.header_names : this.key_list) = arg;
|
||||||
}
|
}
|
||||||
|
|
@ -157,11 +177,12 @@ class Header
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.8
|
* https://tools.ietf.org/html/rfc5228#section-5.8
|
||||||
*/
|
*/
|
||||||
class Not
|
class Not extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
this.test = new Sieve.Grammar.Test;
|
super('not');
|
||||||
|
this.test = new Test;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
|
|
@ -178,10 +199,11 @@ class Not
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.9
|
* https://tools.ietf.org/html/rfc5228#section-5.9
|
||||||
*/
|
*/
|
||||||
class Size
|
class Size extends Test
|
||||||
{
|
{
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
|
super('size');
|
||||||
this.mode = ':over'; // :under
|
this.mode = ':over'; // :under
|
||||||
this.limit = 0;
|
this.limit = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -196,13 +218,24 @@ class Size
|
||||||
args.forEach(arg => {
|
args.forEach(arg => {
|
||||||
if (':over' === arg || ':under' === arg) {
|
if (':over' === arg || ':under' === arg) {
|
||||||
this.mode = arg;
|
this.mode = arg;
|
||||||
} else if (arg instanceof Sieve.Grammar.Number) {
|
} else if (arg instanceof Grammar.Number) {
|
||||||
this.limit = arg;
|
this.limit = arg;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://tools.ietf.org/html/rfc5228#section-5.10
|
||||||
|
*/
|
||||||
|
class True extends Test
|
||||||
|
{
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
return 'true';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Sieve.Tests = {
|
Sieve.Tests = {
|
||||||
Address: Address,
|
Address: Address,
|
||||||
AllOf: AllOf,
|
AllOf: AllOf,
|
||||||
|
|
@ -212,7 +245,8 @@ Sieve.Tests = {
|
||||||
False: False,
|
False: False,
|
||||||
Header: Header,
|
Header: Header,
|
||||||
Not: Not,
|
Not: Not,
|
||||||
Size: Size
|
Size: Size,
|
||||||
|
True: True
|
||||||
};
|
};
|
||||||
|
|
||||||
})(this.Sieve);
|
})(this.Sieve);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue