mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-05 23:47:03 +03:00
Added Sieve extension rfc5703
This commit is contained in:
parent
7468268e1a
commit
63de537f8f
5 changed files with 341 additions and 80 deletions
|
|
@ -33,6 +33,11 @@ export class ConditionalCommand extends GrammarCommand
|
||||||
/*
|
/*
|
||||||
public function pushArguments(array $args): void
|
public function pushArguments(array $args): void
|
||||||
{
|
{
|
||||||
|
args.forEach((arg, i) => {
|
||||||
|
if (':' === args[i-1][0]) {
|
||||||
|
this[args[i-1].replace(':','_')].value = arg.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
print_r($args);
|
print_r($args);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,8 @@ export class VacationCommand extends GrammarCommand
|
||||||
result += ' :subject ' + this._subject;
|
result += ' :subject ' + this._subject;
|
||||||
}
|
}
|
||||||
if (this._from.length) {
|
if (this._from.length) {
|
||||||
result += ' :from ' + this.arguments[':from'];
|
result += ' :from ' + this._from;
|
||||||
|
// result += ' :from ' + this.arguments[':from'];
|
||||||
}
|
}
|
||||||
if (this.addresses.length) {
|
if (this.addresses.length) {
|
||||||
result += ' :addresses ' + this.addresses.toString();
|
result += ' :addresses ' + this.addresses.toString();
|
||||||
|
|
|
||||||
178
dev/Sieve/Extensions/rfc5703.js
Normal file
178
dev/Sieve/Extensions/rfc5703.js
Normal file
|
|
@ -0,0 +1,178 @@
|
||||||
|
/**
|
||||||
|
* https://tools.ietf.org/html/rfc5703
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
GrammarCommand,
|
||||||
|
GrammarNumber,
|
||||||
|
GrammarQuotedString,
|
||||||
|
GrammarString,
|
||||||
|
GrammarStringList
|
||||||
|
} from 'Sieve/Grammar';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc5703#section-3
|
||||||
|
*/
|
||||||
|
export class ForEveryPartCommand extends GrammarCommand
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this._name = new GrammarString;
|
||||||
|
}
|
||||||
|
|
||||||
|
get require() { return 'foreverypart'; }
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
let result = 'foreverypart';
|
||||||
|
if (this._subject.length) {
|
||||||
|
result += ' :name ' + this._name;
|
||||||
|
}
|
||||||
|
return result + ' ' + this.commands;
|
||||||
|
}
|
||||||
|
|
||||||
|
pushArguments(args)
|
||||||
|
{
|
||||||
|
args.forEach((arg, i) => {
|
||||||
|
if (':name' === arg) {
|
||||||
|
this._name.value = args[i+1].value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BreakCommand extends ForEveryPartCommand
|
||||||
|
{
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
let result = 'break';
|
||||||
|
if (this._subject.length) {
|
||||||
|
result += ' :name ' + this._name;
|
||||||
|
}
|
||||||
|
return result + ';';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc5703#section-5
|
||||||
|
*/
|
||||||
|
export class ReplaceCommand extends GrammarCommand
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.mime = false;
|
||||||
|
this._subject = new GrammarQuotedString;
|
||||||
|
this._from = new GrammarQuotedString;
|
||||||
|
this.replacement = new GrammarQuotedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
get require() { return 'replace'; }
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
let result = 'replace';
|
||||||
|
if (this.mime) {
|
||||||
|
result += ' :mime';
|
||||||
|
}
|
||||||
|
if (this._subject.length) {
|
||||||
|
result += ' :subject ' + this._subject;
|
||||||
|
}
|
||||||
|
if (this._from.length) {
|
||||||
|
result += ' :from ' + this._from;
|
||||||
|
// result += ' :from ' + this.arguments[':from'];
|
||||||
|
}
|
||||||
|
return result + this.replacement + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
pushArguments(args)
|
||||||
|
{
|
||||||
|
this.replacement = args.pop();
|
||||||
|
args.forEach((arg, i) => {
|
||||||
|
if (':mime' === arg) {
|
||||||
|
this.mime = true;
|
||||||
|
} else if (':' === args[i-1][0]) {
|
||||||
|
// :subject, :from
|
||||||
|
this[args[i-1].replace(':','_')].value = arg.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc5703#section-6
|
||||||
|
*/
|
||||||
|
export class EncloseCommand extends GrammarCommand
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this._subject = new GrammarQuotedString;
|
||||||
|
this.headers = new GrammarStringList;
|
||||||
|
}
|
||||||
|
|
||||||
|
get require() { return 'enclose'; }
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
let result = 'enclose';
|
||||||
|
if (this._subject.length) {
|
||||||
|
result += ' :subject ' + this._subject;
|
||||||
|
}
|
||||||
|
if (this.headers.length) {
|
||||||
|
result += ' :headers ' + this.headers;
|
||||||
|
}
|
||||||
|
return result + ' :text;';
|
||||||
|
}
|
||||||
|
|
||||||
|
pushArguments(args)
|
||||||
|
{
|
||||||
|
args.forEach((arg, i) => {
|
||||||
|
if (':' === args[i-1][0]) {
|
||||||
|
// :subject, :headers
|
||||||
|
this[args[i-1].replace(':','_')].value = arg.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc5703#section-7
|
||||||
|
*/
|
||||||
|
export class ExtractTextCommand extends GrammarCommand
|
||||||
|
{
|
||||||
|
constructor()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.modifiers = [];
|
||||||
|
this._first = new GrammarNumber;
|
||||||
|
this.varname = new GrammarQuotedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
get require() { return 'extracttext'; }
|
||||||
|
|
||||||
|
toString()
|
||||||
|
{
|
||||||
|
let result = 'extracttext '
|
||||||
|
+ this.modifiers.join(' ');
|
||||||
|
if (0 < this._first.value) {
|
||||||
|
result += ' :first ' + this._first;
|
||||||
|
}
|
||||||
|
return result + ' ' + this.varname + ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
pushArguments(args)
|
||||||
|
{
|
||||||
|
this.varname = args.pop();
|
||||||
|
[':lower', ':upper', ':lowerfirst', ':upperfirst', ':quotewildcard', ':length'].forEach(modifier => {
|
||||||
|
args.includes(modifier) && this.modifiers.push(modifier);
|
||||||
|
});
|
||||||
|
args.forEach((arg, i) => {
|
||||||
|
if (':' === args[i-1][0]) {
|
||||||
|
// :first
|
||||||
|
this[args[i-1].replace(':','_')].value = arg.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
* https://tools.ietf.org/html/rfc5228#section-8
|
* https://tools.ietf.org/html/rfc5228#section-8
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { capa, forEachObjectEntry } from 'Sieve/Utils';
|
import { capa } from 'Sieve/Utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BRACKET_COMMENT,
|
BRACKET_COMMENT,
|
||||||
|
|
@ -57,14 +57,7 @@ import { BodyTest } from 'Sieve/Extensions/rfc5173';
|
||||||
import { EnvironmentTest } from 'Sieve/Extensions/rfc5183';
|
import { EnvironmentTest } from 'Sieve/Extensions/rfc5183';
|
||||||
import { SetCommand, StringTest } from 'Sieve/Extensions/rfc5229';
|
import { SetCommand, StringTest } from 'Sieve/Extensions/rfc5229';
|
||||||
import { VacationCommand } from 'Sieve/Extensions/rfc5230';
|
import { VacationCommand } from 'Sieve/Extensions/rfc5230';
|
||||||
|
import { SetFlagCommand, AddFlagCommand, RemoveFlagCommand, HasFlagTest } from 'Sieve/Extensions/rfc5232';
|
||||||
import {
|
|
||||||
SetFlagCommand,
|
|
||||||
AddFlagCommand,
|
|
||||||
RemoveFlagCommand,
|
|
||||||
HasFlagTest
|
|
||||||
} from 'Sieve/Extensions/rfc5232';
|
|
||||||
|
|
||||||
import { SpamTestTest, VirusTestTest } from 'Sieve/Extensions/rfc5235';
|
import { SpamTestTest, VirusTestTest } from 'Sieve/Extensions/rfc5235';
|
||||||
import { DateTest, CurrentDateTest } from 'Sieve/Extensions/rfc5260';
|
import { DateTest, CurrentDateTest } from 'Sieve/Extensions/rfc5260';
|
||||||
import { AddHeaderCommand, DeleteHeaderCommand } from 'Sieve/Extensions/rfc5293';
|
import { AddHeaderCommand, DeleteHeaderCommand } from 'Sieve/Extensions/rfc5293';
|
||||||
|
|
@ -72,74 +65,81 @@ import { ErejectCommand, RejectCommand } from 'Sieve/Extensions/rfc5429';
|
||||||
import { NotifyCommand, ValidNotifyMethodTest, NotifyMethodCapabilityTest } from 'Sieve/Extensions/rfc5435';
|
import { NotifyCommand, ValidNotifyMethodTest, NotifyMethodCapabilityTest } from 'Sieve/Extensions/rfc5435';
|
||||||
import { IHaveTest, ErrorCommand } from 'Sieve/Extensions/rfc5463';
|
import { IHaveTest, ErrorCommand } from 'Sieve/Extensions/rfc5463';
|
||||||
import { MailboxExistsTest, MetadataTest, MetadataExistsTest } from 'Sieve/Extensions/rfc5490';
|
import { MailboxExistsTest, MetadataTest, MetadataExistsTest } from 'Sieve/Extensions/rfc5490';
|
||||||
|
import { ForEveryPartCommand, BreakCommand, ReplaceCommand, EncloseCommand, ExtractTextCommand } from 'Sieve/Extensions/rfc5703';
|
||||||
import { IncludeCommand, ReturnCommand } from 'Sieve/Extensions/rfc6609';
|
import { IncludeCommand, ReturnCommand } from 'Sieve/Extensions/rfc6609';
|
||||||
|
|
||||||
const
|
const
|
||||||
AllCommands = {
|
AllCommands = [
|
||||||
// Control commands
|
// Control commands
|
||||||
if: IfCommand,
|
IfCommand,
|
||||||
elsif: ElsIfCommand,
|
ElsIfCommand,
|
||||||
else: ElseCommand,
|
ElseCommand,
|
||||||
conditional: ConditionalCommand,
|
ConditionalCommand,
|
||||||
require: RequireCommand,
|
RequireCommand,
|
||||||
stop: StopCommand,
|
StopCommand,
|
||||||
// Action commands
|
// Action commands
|
||||||
discard: DiscardCommand,
|
DiscardCommand,
|
||||||
fileinto: FileIntoCommand,
|
FileIntoCommand,
|
||||||
keep: KeepCommand,
|
KeepCommand,
|
||||||
redirect: RedirectCommand,
|
RedirectCommand,
|
||||||
// Test commands
|
// Test commands
|
||||||
address: AddressTest,
|
AddressTest,
|
||||||
allof: AllOfTest,
|
AllOfTest,
|
||||||
anyof: AnyOfTest,
|
AnyOfTest,
|
||||||
envelope: EnvelopeTest,
|
EnvelopeTest,
|
||||||
exists: ExistsTest,
|
ExistsTest,
|
||||||
false: FalseTest,
|
FalseTest,
|
||||||
header: HeaderTest,
|
HeaderTest,
|
||||||
not: NotTest,
|
NotTest,
|
||||||
size: SizeTest,
|
SizeTest,
|
||||||
true: TrueTest,
|
TrueTest,
|
||||||
// rfc5173
|
// rfc5173
|
||||||
body: BodyTest,
|
BodyTest,
|
||||||
// rfc5183
|
// rfc5183
|
||||||
environment: EnvironmentTest,
|
EnvironmentTest,
|
||||||
// rfc5229
|
// rfc5229
|
||||||
set: SetCommand,
|
SetCommand,
|
||||||
string: StringTest,
|
StringTest,
|
||||||
// rfc5230
|
// rfc5230
|
||||||
vacation: VacationCommand,
|
VacationCommand,
|
||||||
// rfc5232
|
// rfc5232
|
||||||
setflag: SetFlagCommand,
|
SetFlagCommand,
|
||||||
addflag: AddFlagCommand,
|
AddFlagCommand,
|
||||||
removeflag: RemoveFlagCommand,
|
RemoveFlagCommand,
|
||||||
hasflag: HasFlagTest,
|
HasFlagTest,
|
||||||
// rfc5235
|
// rfc5235
|
||||||
spamtest: SpamTestTest,
|
SpamTestTest,
|
||||||
virustest: VirusTestTest,
|
VirusTestTest,
|
||||||
// rfc5260
|
// rfc5260
|
||||||
date: DateTest,
|
DateTest,
|
||||||
currentdate: CurrentDateTest,
|
CurrentDateTest,
|
||||||
// rfc5293
|
// rfc5293
|
||||||
AddHeaderCommand,
|
AddHeaderCommand,
|
||||||
DeleteHeaderCommand,
|
DeleteHeaderCommand,
|
||||||
// rfc5429
|
// rfc5429
|
||||||
ereject: ErejectCommand,
|
ErejectCommand,
|
||||||
reject: RejectCommand,
|
RejectCommand,
|
||||||
// rfc5435
|
// rfc5435
|
||||||
notify: NotifyCommand,
|
NotifyCommand,
|
||||||
valid_notify_method: ValidNotifyMethodTest,
|
ValidNotifyMethodTest,
|
||||||
notify_method_capability: NotifyMethodCapabilityTest,
|
NotifyMethodCapabilityTest,
|
||||||
// rfc5463
|
// rfc5463
|
||||||
ihave: IHaveTest,
|
IHaveTest,
|
||||||
error: ErrorCommand,
|
ErrorCommand,
|
||||||
// rfc5490
|
// rfc5490
|
||||||
mailboxexists: MailboxExistsTest,
|
MailboxExistsTest,
|
||||||
metadata: MetadataTest,
|
MetadataTest,
|
||||||
metadataexists: MetadataExistsTest,
|
MetadataExistsTest,
|
||||||
|
// rfc5703
|
||||||
|
ForEveryPartCommand,
|
||||||
|
BreakCommand,
|
||||||
|
ReplaceCommand,
|
||||||
|
EncloseCommand,
|
||||||
|
ExtractTextCommand,
|
||||||
// rfc6609
|
// rfc6609
|
||||||
include: IncludeCommand,
|
IncludeCommand,
|
||||||
return: ReturnCommand
|
ReturnCommand
|
||||||
},
|
],
|
||||||
|
|
||||||
T_UNKNOWN = 0,
|
T_UNKNOWN = 0,
|
||||||
T_STRING_LIST = 1,
|
T_STRING_LIST = 1,
|
||||||
|
|
@ -182,12 +182,12 @@ export const parseScript = (script, name = 'script.sieve') => {
|
||||||
|
|
||||||
// Only activate available commands
|
// Only activate available commands
|
||||||
const Commands = {};
|
const Commands = {};
|
||||||
forEachObjectEntry(AllCommands, (key, cmd) => {
|
AllCommands.forEach(cmd => {
|
||||||
const requires = (new cmd).require;
|
const obj = new cmd, requires = obj.require;
|
||||||
if (!requires
|
if (!requires
|
||||||
|| (Array.isArray(requires) ? requires : [requires]).every(string => capa.includes(string))
|
|| (Array.isArray(requires) ? requires : [requires]).every(string => capa.includes(string))
|
||||||
) {
|
) {
|
||||||
Commands[key] = cmd;
|
Commands[obj.identifier] = cmd;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -260,13 +260,14 @@ export const parseScript = (script, name = 'script.sieve') => {
|
||||||
}
|
}
|
||||||
new_command = new Commands[value]();
|
new_command = new Commands[value]();
|
||||||
} else {
|
} else {
|
||||||
console.error('Unknown command: ' + value);
|
|
||||||
if (command && (
|
if (command && (
|
||||||
command instanceof ConditionalCommand
|
command instanceof ConditionalCommand
|
||||||
|| command instanceof NotTest
|
|| command instanceof NotTest
|
||||||
|| command.tests instanceof GrammarTestList)) {
|
|| command.tests instanceof GrammarTestList)) {
|
||||||
|
console.error('Unknown test: ' + value);
|
||||||
new_command = new GrammarTest(value);
|
new_command = new GrammarTest(value);
|
||||||
} else {
|
} else {
|
||||||
|
console.error('Unknown command: ' + value);
|
||||||
new_command = new GrammarCommand(value);
|
new_command = new GrammarCommand(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5
|
* https://tools.ietf.org/html/rfc5228#section-5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { capa } from 'Sieve/Utils';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
GrammarNumber,
|
GrammarNumber,
|
||||||
GrammarString,
|
GrammarString,
|
||||||
|
|
@ -13,7 +15,18 @@ import {
|
||||||
const
|
const
|
||||||
isAddressPart = tag => ':localpart' === tag || ':domain' === tag || ':all' === tag || isSubAddressPart(tag),
|
isAddressPart = tag => ':localpart' === tag || ':domain' === tag || ':all' === tag || isSubAddressPart(tag),
|
||||||
// https://tools.ietf.org/html/rfc5233
|
// https://tools.ietf.org/html/rfc5233
|
||||||
isSubAddressPart = tag => ':user' === tag || ':detail' === tag;
|
isSubAddressPart = tag => ':user' === tag || ':detail' === tag,
|
||||||
|
|
||||||
|
asStringList = arg => {
|
||||||
|
if (arg instanceof GrammarStringList) {
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
let args = new GrammarStringList();
|
||||||
|
if (arg instanceof GrammarString) {
|
||||||
|
args.push(arg.value);
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://tools.ietf.org/html/rfc5228#section-5.1
|
* https://tools.ietf.org/html/rfc5228#section-5.1
|
||||||
|
|
@ -29,18 +42,31 @@ export class AddressTest extends GrammarTest
|
||||||
// rfc5260#section-6
|
// rfc5260#section-6
|
||||||
// this.index = new GrammarNumber;
|
// this.index = new GrammarNumber;
|
||||||
// this.last = false;
|
// this.last = false;
|
||||||
|
// rfc5703#section-6
|
||||||
|
// this.mime
|
||||||
|
// this.anychild
|
||||||
}
|
}
|
||||||
|
|
||||||
get require() {
|
get require() {
|
||||||
let requires = [];
|
let requires = [];
|
||||||
isSubAddressPart(this.address_part) && requires.push('subaddress');
|
isSubAddressPart(this.address_part) && requires.push('subaddress');
|
||||||
(this.last || (this.index && this.index.value)) && requires.push('index');
|
(this.last || (this.index && this.index.value)) && requires.push('index');
|
||||||
|
(this.mime || this.anychild) && requires.push('mime');
|
||||||
return requires;
|
return requires;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'address'
|
let result = 'address';
|
||||||
|
if (capa.includes('mime')) {
|
||||||
|
if (this.mime) {
|
||||||
|
result += ' :mime';
|
||||||
|
}
|
||||||
|
if (this.anychild) {
|
||||||
|
result += ' :anychild';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
// + (this.last ? ' :last' : (this.index.value ? ' :index ' + this.index : ''))
|
// + (this.last ? ' :last' : (this.index.value ? ' :index ' + this.index : ''))
|
||||||
+ (this.comparator ? ' :comparator ' + this.comparator : '')
|
+ (this.comparator ? ' :comparator ' + this.comparator : '')
|
||||||
+ ' ' + this.address_part
|
+ ' ' + this.address_part
|
||||||
|
|
@ -51,16 +77,19 @@ export class AddressTest extends GrammarTest
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
|
this.key_list = asStringList(args.pop());
|
||||||
|
this.header_list = asStringList(args.pop());
|
||||||
args.forEach((arg, i) => {
|
args.forEach((arg, i) => {
|
||||||
if (isAddressPart(arg)) {
|
if (isAddressPart(arg)) {
|
||||||
this.address_part = arg;
|
this.address_part = arg;
|
||||||
} else if (':last' === arg) {
|
} else if (':last' === arg) {
|
||||||
this.last = true;
|
this.last = true;
|
||||||
|
} else if (':mime' === arg) {
|
||||||
|
this.mime = true;
|
||||||
|
} else if (':anychild' === arg) {
|
||||||
|
this.anychild = true;
|
||||||
} else if (':index' === args[i-1]) {
|
} else if (':index' === args[i-1]) {
|
||||||
this.index.value = arg.value;
|
this.index.value = arg.value;
|
||||||
} else if (arg instanceof GrammarStringList || arg instanceof GrammarString) {
|
|
||||||
this[args[i+1] ? 'header_list' : 'key_list'] = arg;
|
|
||||||
// (args[i+1] ? this.header_list : this.key_list) = arg;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -127,12 +156,11 @@ export class EnvelopeTest extends GrammarTest
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
args.forEach((arg, i) => {
|
this.key_list = asStringList(args.pop());
|
||||||
|
this.envelope_part = asStringList(args.pop());
|
||||||
|
args.forEach(arg => {
|
||||||
if (isAddressPart(arg)) {
|
if (isAddressPart(arg)) {
|
||||||
this.address_part = arg;
|
this.address_part = arg;
|
||||||
} else if (arg instanceof GrammarStringList || arg instanceof GrammarString) {
|
|
||||||
this[args[i+1] ? 'envelope_part' : 'key_list'] = arg;
|
|
||||||
// (args[i+1] ? this.envelope_part : this.key_list) = arg;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -147,20 +175,39 @@ export class ExistsTest extends GrammarTest
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
this.header_names = new GrammarStringList;
|
this.header_names = new GrammarStringList;
|
||||||
|
// rfc5703#section-6
|
||||||
|
// this.mime
|
||||||
|
// this.anychild
|
||||||
|
}
|
||||||
|
|
||||||
|
get require() {
|
||||||
|
return (this.mime || this.anychild) ? ['mime'] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'exists ' + this.header_names.toString();
|
let result = 'exists';
|
||||||
|
if (capa.includes('mime')) {
|
||||||
|
if (this.mime) {
|
||||||
|
result += ' :mime';
|
||||||
|
}
|
||||||
|
if (this.anychild) {
|
||||||
|
result += ' :anychild';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result + ' ' + this.header_names.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
if (args[0] instanceof GrammarStringList) {
|
this.header_names = asStringList(args.pop());
|
||||||
this.header_names = args;
|
args.forEach(arg => {
|
||||||
} else if (args[0] instanceof GrammarString) {
|
if (':mime' === arg) {
|
||||||
this.header_names.push(args[0].value);
|
this.mime = true;
|
||||||
}
|
} else if (':anychild' === arg) {
|
||||||
|
this.mime = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,18 +236,48 @@ export class HeaderTest extends GrammarTest
|
||||||
// rfc5260#section-6
|
// rfc5260#section-6
|
||||||
// this.index = new GrammarNumber;
|
// this.index = new GrammarNumber;
|
||||||
// this.last = false;
|
// this.last = false;
|
||||||
|
// rfc5703#section-6
|
||||||
|
this.mime = false;
|
||||||
|
this.anychild = false;
|
||||||
|
// when ":mime" is used:
|
||||||
|
this.type = false;
|
||||||
|
this.subtype = false;
|
||||||
|
this.contenttype = false;
|
||||||
|
this.param = new GrammarStringList;
|
||||||
}
|
}
|
||||||
|
|
||||||
get require() {
|
get require() {
|
||||||
let requires = [];
|
let requires = [];
|
||||||
isSubAddressPart(this.address_part) && requires.push('subaddress');
|
isSubAddressPart(this.address_part) && requires.push('subaddress');
|
||||||
(this.last || (this.index && this.index.value)) && requires.push('index');
|
(this.last || (this.index && this.index.value)) && requires.push('index');
|
||||||
|
(this.mime || this.anychild) && requires.push('mime');
|
||||||
return requires;
|
return requires;
|
||||||
}
|
}
|
||||||
|
|
||||||
toString()
|
toString()
|
||||||
{
|
{
|
||||||
return 'header'
|
let result = 'header';
|
||||||
|
if (capa.includes('mime')) {
|
||||||
|
if (this.mime) {
|
||||||
|
result += ' :mime';
|
||||||
|
if (this.type) {
|
||||||
|
result += ' :type';
|
||||||
|
}
|
||||||
|
if (this.subtype) {
|
||||||
|
result += ' :subtype';
|
||||||
|
}
|
||||||
|
if (this.contenttype) {
|
||||||
|
result += ' :contenttype';
|
||||||
|
}
|
||||||
|
if (this.param.length) {
|
||||||
|
result += ' :param ' + this.param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.anychild) {
|
||||||
|
result += ' :anychild';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
// + (this.last ? ' :last' : (this.index.value ? ' :index ' + this.index : ''))
|
// + (this.last ? ' :last' : (this.index.value ? ' :index ' + this.index : ''))
|
||||||
+ (this.comparator ? ' :comparator ' + this.comparator : '')
|
+ (this.comparator ? ' :comparator ' + this.comparator : '')
|
||||||
+ ' ' + this.match_type
|
+ ' ' + this.match_type
|
||||||
|
|
@ -210,6 +287,8 @@ export class HeaderTest extends GrammarTest
|
||||||
|
|
||||||
pushArguments(args)
|
pushArguments(args)
|
||||||
{
|
{
|
||||||
|
this.key_list = asStringList(args.pop());
|
||||||
|
this.header_names = asStringList(args.pop());
|
||||||
args.forEach((arg, i) => {
|
args.forEach((arg, i) => {
|
||||||
if (isAddressPart(arg)) {
|
if (isAddressPart(arg)) {
|
||||||
this.address_part = arg;
|
this.address_part = arg;
|
||||||
|
|
@ -217,9 +296,6 @@ export class HeaderTest extends GrammarTest
|
||||||
this.last = true;
|
this.last = true;
|
||||||
} else if (':index' === args[i-1]) {
|
} else if (':index' === args[i-1]) {
|
||||||
this.index.value = arg.value;
|
this.index.value = arg.value;
|
||||||
} else if (arg instanceof GrammarStringList || arg instanceof GrammarString) {
|
|
||||||
this[args[i+1] ? 'header_names' : 'key_list'] = arg;
|
|
||||||
// (args[i+1] ? this.header_names : this.key_list) = arg;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue