openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

mbox.js (3649B)


      1 // CodeMirror, copyright (c) by Marijn Haverbeke and others
      2 // Distributed under an MIT license: http://codemirror.net/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 });