/** * Process text/html for message body purposes. Specifically: * * - sanitize HTML (using bleach.js): discard illegal markup entirely, render * legal but 'regulated' markup inert (ex: links to external content). * - TODO: perform normalization of quote markup from different clients into * blockquotes, like how Thunderbird conversations does it. * - snippet generation: Try and generate a usable snippet string from something * that is not a quote. * * We may eventually try and perform more detailed analysis like `quotechew.js` * does with structured markup, potentially by calling out to quotechew, but * that's a tall order to get right, so it's mightily postponed. **/ define( [ 'exports', 'bleach' ], function( exports, $bleach ) { /** * Whitelisted HTML tags list. Currently from nsTreeSanitizer.cpp which credits * Mark Pilgrim and Sam Ruby for its own initial whitelist. * * IMPORTANT THUNDERBIRD NOTE: Thunderbird only engages its sanitization logic * when processing mailto URIs, when the non-default * "view | message body as | simple html" setting is selected, or when * displaying spam messages. Accordingly, the settings are pretty strict * and not particularly thought-out. Non-CSS presentation is stripped, which * is pretty much the lingua franca of e-mail. (Thunderbird itself generates * font tags, for example.) * * Some things are just not in the list at all: * - SVG: Thunderbird nukes these itself because it forces * SanitizerCidEmbedsOnly which causes flattening of everything in the SVG * namespace. * * Tags that we are opting not to include will be commented with a reason tag: * - annoying: This thing is ruled out currently because it only allows annoying * things to happen *given our current capabilities*. * - scripty: This thing requires scripting to make anything happen, and we do * not allow scripting. * - forms: We have no UI to expose the target of a form right now, so it's * not safe. Thunderbird displays a scam warning, which isn't realy a big * help, but it's something. Because forms are largely unsupported or just * broken in many places, they are rarely used, so we are turning them off * entirely. * - non-body: previously killed as part of the parse process because we were * assigning to innerHTML rather than creating a document with the string in * it. We could change this up in a future bug now. * - dangerous: The semantics of the tag are intentionally at odds with our * goals and/or are extensible. (ex: link tag.) Our callbacks could be * used to only let through okay things. * - interactive-ui: A cross between scripty and forms, things like (HTML5) * menu and command imply some type of mutation that requires scripting. * They also are frequently very attribute-heavy. * - svg: it's SVG, we don't support it yet! */ var LEGAL_TAGS = [ 'a', 'abbr', 'acronym', 'area', 'article', 'aside', // annoying: 'audio', 'b', 'bdi', 'bdo', // (bidirectional markup stuff) 'big', 'blockquote', // implicitly-nuked: 'body' 'br', // forms: 'button', // scripty: canvas 'caption', 'center', 'cite', 'code', 'col', 'colgroup', // interactive-ui: 'command', // forms: 'datalist', 'dd', 'del', 'details', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', // forms: 'fieldset' (but allowed by nsTreeSanitizer) 'figcaption', 'figure', 'font', 'footer', // forms: 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', // non-body: 'head' 'header', 'hgroup', 'hr', // non-body: 'html' 'i', 'img', // forms: 'input', 'ins', // ("represents a range of text that has been inserted to a document") 'kbd', // ("The kbd element represents user input") 'label', 'legend', 'li', // dangerous: link (for CSS styles /* link supports many types, none of which we want, some of which are * risky: http://dev.w3.org/html5/spec/links.html#linkTypes. Specifics: * - "stylesheet": This would be okay for cid links, but there's no clear * advantage over inline styles, so we forbid it, especially as supporting * it might encourage other implementations to dangerously support link. * - "prefetch": Its whole point is de facto information leakage. */ 'listing', // (deprecated, like "pre") 'map', 'mark', // interactive-ui: 'menu', 'meta', 'meter', 'nav', 'nobr', // (deprecated "white-space:nowrap" equivalent) 'noscript', 'ol', // forms: 'optgroup', // forms: 'option', 'output', // (HTML5 draft: "result of a calculation in a form") 'p', 'pre', // interactive-ui: 'progress', 'q', /* http://www.w3.org/TR/ruby/ is a pronounciation markup that is not directly * supported by gecko at this time (although there is a Firefox extension). * All of 'rp', 'rt', and 'ruby' are ruby tags. The spec also defines 'rb' * and 'rbc' tags that nsTreeSanitizer does not whitelist, however. */ 'rp', 'rt', 'ruby', 's', 'samp', 'section', // forms: 'select', 'small', // annoying?: 'source', 'span', 'strike', 'strong', 'style', 'sub', 'summary', 'sup', // svg: 'svg', NB: this lives in its own namespace 'table', 'tbody', 'td', // forms: 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', // XXX does this mean anything outside head? 'tr', // annoying?: 'track' 'tt', 'u', 'ul', 'var', // annoying: 'video', 'wbr' // (HTML5 draft: line break opportunity) ]; /** * Tags whose children should be removed along with the tag itself, rather than * splicing the children into the position originally occupied by the parent. * * We do this for: * - forms; see `LEGAL_TAGS` for the rationale. Note that we don't bother * including children that should already be nuked by PRUNE_TAGS. For * example, 'option' and 'optgroup' only make sense under 'select' or * 'datalist', so we need not include them. This means that if the tags * are used in nonsensical positions, they will have their contents * merged into the document text, but that's not a major concern. * - non-body: don't have stuff from the header show up like it's part of the * body! For now we do want