0
|
1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
|
|
2 // Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
|
3
|
|
4 (function(mod) {
|
|
5 if (typeof exports == "object" && typeof module == "object") // CommonJS
|
|
6 mod(require("../../lib/codemirror"));
|
|
7 else if (typeof define == "function" && define.amd) // AMD
|
|
8 define(["../../lib/codemirror"], mod);
|
|
9 else // Plain browser env
|
|
10 mod(CodeMirror);
|
|
11 })(function(CodeMirror) {
|
|
12 "use strict";
|
|
13
|
|
14 var rfc2822 = [
|
|
15 "From", "Sender", "Reply-To", "To", "Cc", "Bcc", "Message-ID",
|
|
16 "In-Reply-To", "References", "Resent-From", "Resent-Sender", "Resent-To",
|
|
17 "Resent-Cc", "Resent-Bcc", "Resent-Message-ID", "Return-Path", "Received"
|
|
18 ];
|
|
19 var rfc2822NoEmail = [
|
|
20 "Date", "Subject", "Comments", "Keywords", "Resent-Date"
|
|
21 ];
|
|
22
|
|
23 CodeMirror.registerHelper("hintWords", "mbox", rfc2822.concat(rfc2822NoEmail));
|
|
24
|
|
25 var whitespace = /^[ \t]/;
|
|
26 var separator = /^From /; // See RFC 4155
|
|
27 var rfc2822Header = new RegExp("^(" + rfc2822.join("|") + "): ");
|
|
28 var rfc2822HeaderNoEmail = new RegExp("^(" + rfc2822NoEmail.join("|") + "): ");
|
|
29 var header = /^[^:]+:/; // Optional fields defined in RFC 2822
|
|
30 var email = /^[^ ]+@[^ ]+/;
|
|
31 var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/;
|
|
32 var bracketedEmail = /^<.*?>/;
|
|
33 var untilBracketedEmail = /^.*?(?=<.*>)/;
|
|
34
|
|
35 function styleForHeader(header) {
|
|
36 if (header === "Subject") return "header";
|
|
37 return "string";
|
|
38 }
|
|
39
|
|
40 function readToken(stream, state) {
|
|
41 if (stream.sol()) {
|
|
42 // From last line
|
|
43 state.inSeparator = false;
|
|
44 if (state.inHeader && stream.match(whitespace)) {
|
|
45 // Header folding
|
|
46 return null;
|
|
47 } else {
|
|
48 state.inHeader = false;
|
|
49 state.header = null;
|
|
50 }
|
|
51
|
|
52 if (stream.match(separator)) {
|
|
53 state.inHeaders = true;
|
|
54 state.inSeparator = true;
|
|
55 return "atom";
|
|
56 }
|
|
57
|
|
58 var match;
|
|
59 var emailPermitted = false;
|
|
60 if ((match = stream.match(rfc2822HeaderNoEmail)) ||
|
|
61 (emailPermitted = true) && (match = stream.match(rfc2822Header))) {
|
|
62 state.inHeaders = true;
|
|
63 state.inHeader = true;
|
|
64 state.emailPermitted = emailPermitted;
|
|
65 state.header = match[1];
|
|
66 return "atom";
|
|
67 }
|
|
68
|
|
69 // Use vim's heuristics: recognize custom headers only if the line is in a
|
|
70 // block of legitimate headers.
|
|
71 if (state.inHeaders && (match = stream.match(header))) {
|
|
72 state.inHeader = true;
|
|
73 state.emailPermitted = true;
|
|
74 state.header = match[1];
|
|
75 return "atom";
|
|
76 }
|
|
77
|
|
78 state.inHeaders = false;
|
|
79 stream.skipToEnd();
|
|
80 return null;
|
|
81 }
|
|
82
|
|
83 if (state.inSeparator) {
|
|
84 if (stream.match(email)) return "link";
|
|
85 if (stream.match(untilEmail)) return "atom";
|
|
86 stream.skipToEnd();
|
|
87 return "atom";
|
|
88 }
|
|
89
|
|
90 if (state.inHeader) {
|
|
91 var style = styleForHeader(state.header);
|
|
92
|
|
93 if (state.emailPermitted) {
|
|
94 if (stream.match(bracketedEmail)) return style + " link";
|
|
95 if (stream.match(untilBracketedEmail)) return style;
|
|
96 }
|
|
97 stream.skipToEnd();
|
|
98 return style;
|
|
99 }
|
|
100
|
|
101 stream.skipToEnd();
|
|
102 return null;
|
|
103 };
|
|
104
|
|
105 CodeMirror.defineMode("mbox", function() {
|
|
106 return {
|
|
107 startState: function() {
|
|
108 return {
|
|
109 // Is in a mbox separator
|
|
110 inSeparator: false,
|
|
111 // Is in a mail header
|
|
112 inHeader: false,
|
|
113 // If bracketed email is permitted. Only applicable when inHeader
|
|
114 emailPermitted: false,
|
|
115 // Name of current header
|
|
116 header: null,
|
|
117 // Is in a region of mail headers
|
|
118 inHeaders: false
|
|
119 };
|
|
120 },
|
|
121 token: readToken,
|
|
122 blankLine: function(state) {
|
|
123 state.inHeaders = state.inSeparator = state.inHeader = false;
|
|
124 }
|
|
125 };
|
|
126 });
|
|
127
|
|
128 CodeMirror.defineMIME("application/mbox", "mbox");
|
|
129 });
|