// CodeMirror, copyright (c) by Marijn Haverbeke and others // Distributed under an MIT license: https://codemirror.net/LICENSE ;(function (mod) { if (typeof exports == 'object' && typeof module == 'object') // CommonJS mod(require('../../lib/codemirror')) else if (typeof define == 'function' && define.amd) // AMD define(['../../lib/codemirror'], mod) // Plain browser env else mod(CodeMirror) })(function (CodeMirror) { 'use strict' var rfc2822 = [ 'From', 'Sender', 'Reply-To', 'To', 'Cc', 'Bcc', 'Message-ID', 'In-Reply-To', 'References', 'Resent-From', 'Resent-Sender', 'Resent-To', 'Resent-Cc', 'Resent-Bcc', 'Resent-Message-ID', 'Return-Path', 'Received', ] var rfc2822NoEmail = ['Date', 'Subject', 'Comments', 'Keywords', 'Resent-Date'] CodeMirror.registerHelper('hintWords', 'mbox', rfc2822.concat(rfc2822NoEmail)) var whitespace = /^[ \t]/ var separator = /^From / // See RFC 4155 var rfc2822Header = new RegExp('^(' + rfc2822.join('|') + '): ') var rfc2822HeaderNoEmail = new RegExp('^(' + rfc2822NoEmail.join('|') + '): ') var header = /^[^:]+:/ // Optional fields defined in RFC 2822 var email = /^[^ ]+@[^ ]+/ var untilEmail = /^.*?(?=[^ ]+?@[^ ]+)/ var bracketedEmail = /^<.*?>/ var untilBracketedEmail = /^.*?(?=<.*>)/ function styleForHeader(header) { if (header === 'Subject') return 'header' return 'string' } function readToken(stream, state) { if (stream.sol()) { // From last line state.inSeparator = false if (state.inHeader && stream.match(whitespace)) { // Header folding return null } else { state.inHeader = false state.header = null } if (stream.match(separator)) { state.inHeaders = true state.inSeparator = true return 'atom' } var match var emailPermitted = false if ((match = stream.match(rfc2822HeaderNoEmail)) || ((emailPermitted = true) && (match = stream.match(rfc2822Header)))) { state.inHeaders = true state.inHeader = true state.emailPermitted = emailPermitted state.header = match[1] return 'atom' } // Use vim's heuristics: recognize custom headers only if the line is in a // block of legitimate headers. if (state.inHeaders && (match = stream.match(header))) { state.inHeader = true state.emailPermitted = true state.header = match[1] return 'atom' } state.inHeaders = false stream.skipToEnd() return null } if (state.inSeparator) { if (stream.match(email)) return 'link' if (stream.match(untilEmail)) return 'atom' stream.skipToEnd() return 'atom' } if (state.inHeader) { var style = styleForHeader(state.header) if (state.emailPermitted) { if (stream.match(bracketedEmail)) return style + ' link' if (stream.match(untilBracketedEmail)) return style } stream.skipToEnd() return style } stream.skipToEnd() return null } CodeMirror.defineMode('mbox', function () { return { startState: function () { return { // Is in a mbox separator inSeparator: false, // Is in a mail header inHeader: false, // If bracketed email is permitted. Only applicable when inHeader emailPermitted: false, // Name of current header header: null, // Is in a region of mail headers inHeaders: false, } }, token: readToken, blankLine: function (state) { state.inHeaders = state.inSeparator = state.inHeader = false }, } }) CodeMirror.defineMIME('application/mbox', 'mbox') })