1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
{{/*
Rendering of one correspondent's name, shared by every HTML view.
The distinction it draws is the same one the text renderings draw with ~ and
quotes: a petname was assigned here and is vouched for, a display name came
out of a From: header and is a claim by whoever sent the mail. This archive
contains "Deutsche-Baпk AG" with a Cyrillic п, and "Ζaκaria" in Greek letters
arriving through GitHub, both of which used to render exactly like a name the
reader had chosen.
It is one defined template rather than markup repeated in each view because
the marking is a security property: four copies are four chances for one of
them to quietly print a bare .Claimed, which is the state this replaced.
"name" renders the name alone; "nameAddr" adds the address beneath it, for
the places with room for two lines. "penLink" is the way to the settings
page, where a name is assigned; it lives here beside the marking because the
two are the same subject — what this contact is called, and by whom.
*/}}
{{define "name"}}
{{- if .Petname -}}
<span class="pet" title="A name you assigned to {{.Address}}. Local to mailweb and never sent.">{{.Petname}}</span>
{{- else if .Claimed -}}
<span class="claimed" title="Written by the sender and not verified by anything.">“{{.Claimed}}”</span>
{{- if .Mixed}} <span class="mixed" title="This name mixes alphabets inside a single word — Latin with Cyrillic or Greek — which is how a lookalike name is built. It is not proof of anything, but it is worth a second look at the address.">mixed alphabets</span>{{end -}}
{{- else -}}
<span class="claimed">{{.Address}}</span>
{{- end -}}
{{end}}
{{define "nameAddr"}}
{{- template "name" . -}}
{{- if or .Petname .Claimed}}<br><span class="addr-line">{{.Address}}</span>{{end -}}
{{end}}
{{/*
A list of correspondents, each marked. Takes a []mailtext.Name.
The address is appended only where a name was printed in front of it. With no
petname and no claimed name "name" renders the address itself, and following
that with the same address in angle brackets says it twice — which is what a
recipient list mostly is, since a To: header usually carries bare addresses.
*/}}
{{define "nameList"}}
{{- range $i, $n := . }}{{if $i}}, {{end}}{{template "name" $n}}
{{- if or $n.Petname $n.Claimed}} <{{$n.Address}}>{{end}}{{end -}}
{{end}}
{{/*
Who a message was between: one line saying either who wrote it or who it went
to, and who else was copied.
Takes a msgRow. It is one partial rather than markup in each view for the same
reason "name" is: the index, the conversation page and a message's own page
all answer this question, and three copies are three chances for one to print
a recipient list the reader cannot tell from a name they chose themselves.
That is not hypothetical — it is what the conversation page did, printing a
preformatted "Name <addr>" string straight out of somebody else's header.
Which side is shown is isOutgoing's answer, carried here as .Direction: for
mail this account wrote, "From: you" is the one fact the reader already has,
and who it went to is the thing worth the line.
Cc is shown whenever there is one, in both directions. On incoming mail it is
what distinguishes a letter written to you from one you were copied on, and
20578 messages in this archive carry one. Bcc is shown if it is ever present;
no received message carries one, and mailweb's own sender writes none, so in
practice this renders nothing — it is here so that the day something does
write one, it is not silently dropped.
*/}}
{{define "correspondents"}}
{{- if eq .Direction "sent" -}}
<span class="dir dir-sent">→</span>To:
{{- if .To}} {{template "nameList" .To}}{{else}} —{{end}}
{{- else -}}
<span class="dir dir-recv">←</span>From: {{template "name" .From}} <{{.From.Address}}>
{{- end}}
{{- with .Cc}}<br><span class="cc-line">Cc: {{template "nameList" .}}</span>{{end}}
{{- with .Bcc}}<br><span class="cc-line">Bcc: {{template "nameList" .}}</span>{{end}}
{{- /* Nobody visible was addressed, yet it arrived: the reader was blind
copied, and Delivered-To is the only header naming them. Saying so is
the difference between that and a letter written to them directly,
which is otherwise exactly what it looks like. */ -}}
{{- with .DeliveredTo}}<br><span class="cc-line" title="No recipient header on this message names you; it reached this account as a blind copy. This address comes from the Delivered-To header added on delivery.">To: undisclosed recipients — delivered to {{.}}</span>{{end}}
{{end}}
{{/*
The way to name a contact. Takes a contactPen: the path-escaped address and
the URL to come back to.
It replaced an inline petname field in the listing and another in the contact
header. Two forms meant two places that had to agree about what naming is,
and neither had room to say anything about it — a bare text input beside a
stranger's address, with no mention that the name is local, never sent, and
not a way to identify anybody. That is now on one page which has room for it.
The cost is honest: naming a stranger while scanning the listing is a page
away rather than in the row. Hence Return, so the way back is one click and
lands where the reader was, ?show=hidden and all.
*/}}
{{define "penLink"}}
<a class="pen-link" href="/contact/{{.AddrEscaped}}/settings?return={{.Return}}"
title="Name this contact, and everything else about it">✎</a>
{{end}}
{{define "nameStyle"}}
.pet { font-weight: 600; }
.claimed { font-weight: normal; color: var(--text-meta); font-style: italic; }
.addr-line { color: var(--text-meta); font-size: 0.85em; }
{{/* The direction arrow and the copied-to lines belong to the
"correspondents" partial above, so they live here rather than in each
page that mounts it — a view that has the markup and not the style
renders an unstyled arrow. */}}
.dir { font-size: 0.8rem; font-weight: bold; margin-right: 0.4rem; }
.dir-recv { color: var(--text-meta); }
.dir-sent { color: var(--link); }
.cc-line { color: var(--text-meta); }
.mixed {
font-size: 0.75em; color: var(--danger, #c0392b);
border: 1px solid currentColor; border-radius: 3px;
padding: 0 0.25em; white-space: nowrap; font-style: normal;
}
a.pen-link {
color: var(--text-meta); text-decoration: none; font-size: 0.9em;
padding: 0 0.25em; border-radius: 3px; vertical-align: middle;
}
a.pen-link:hover { color: var(--text); background: var(--border); }
{{end}}
|