Initializing
Liveweave
Web
expand_more
home
Home
data_object
CSS Explorer
arrow_outward
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
outbox_alt
Generative AI
arrow_outward
frame_source
Python Playground
New
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Save
account_circle
Login
settings
Settings
expand_more
14
px
Live mode
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
<!DOCTYPE html> <html> <head> <title>Thunderbird </title> </head> <body> <!-- https://github.com/isshiki/ReFwdFormatter playground --> <div class="content-header"> <h1>Thunderbird mailbody cleaner & dequoter </h1> <input type="button" name="format" value="reFormat TEXT mail" onClick="refwdformatter.onClick(false)"> <input type="button" name="format" value="reFormat HTML mail" onClick="refwdformatter.onClick(true)"> </div> <div class="content-frame"> <hr> <div id="content-text-mail"><br><br><div class="moz-cite-prefix">Someone wrote:<br></div><span style="white-space: pre-wrap; display: block; width: 98vw;">> some text 444 <br>> whatever<br></span><br></div> <hr> <div id="content-html-mail"><p><br></p><br><div class="moz-cite-prefix">Someone wrote:<br></div><blockquote type="cite" cite="mid:abcd-efg-hijklmn@opqrstu.vwxyz">some 333 html <br> <br> </blockquote><br></div> <hr> </div> </body> </html>
h1 { font-size: x-large; margin: 0; } .content-header { text-align: center; } hr { border: 1px solid #bbb; margin: 5px 0; } p { margin: 0; } .moz-cite-prefix { border-top: 2px dashed #0a0; } blockquote { border-left: 5px solid blue; padding: 0 10px; }
var refwdformatter = { editing: false, format: function (htmlMode) { if (refwdformatter.editing) { return; } refwdformatter.editing = true; //var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("extensions.refwdformatter."); var ret = true; // prefs.getBoolPref("replytext.on"); var reh = true; // prefs.getBoolPref("replyhtml.on"); var lit = true; // prefs.getBoolPref("listtext.on"); var lih = true; // prefs.getBoolPref("listhtml.on"); var fwd = true; // prefs.getBoolPref("fwdsubject.on"); var t = 1; //gMsgCompose.type; var msgHtml = htmlMode; //gMsgCompose.composeHTML; if (fwd && (t == 3 || t == 4)) { // Foward (3: ForwardAsAttachment, 4: ForwardInline) document.getElementById("msgSubject").value = document.getElementById("msgSubject").value.replace(/^\[/, "").replace(/\]$/, ""); } else if ((ret || reh || lit || lih) && (t == 1 || t == 2 || t == 6 || t == 7 || t == 8 || t == 13)) { // Reply (1: Reply, 2: ReplyAll, 6: ReplyToSender, 7: ReplyToGroup, 8: ReplyToSenderAndGroup, 13: ReplyToList) var b = htmlMode ? document.getElementById("content-html-mail") : document.getElementById("content-text-mail"); //document.getElementById("content-frame").contentDocument.body; var h = b.innerHTML; ///// If you develop and test this add-on logic code, remove the following comment-out temporarily to get the whole html source of the current mail. /////b.innerHTML = h.replace(/[&"'<>]/g, function(m) { return { "&": "&", '"': """, "'": "'", "<": "<", ">": ">" }[m]; }); /////return; // If you would like to debug the following code, use console.log() function and open DevTools. /// [--- liveweave debug 1 - START copy here ---] if (h !== "<br>") { if ((ret || lit) && !msgHtml) { if (b.hasChildNodes()) { var children = b.childNodes; //console.log(children); var isFirstChildren = true; var brCounter = 2; // There should be two <br> tags as FirstChildren in text-mail. for (var i = 0; i < children.length; i++) { if (brCounter <= 0) isFirstChildren = false; var curChildNode = children[i]; if (curChildNode.nodeType === Node.TEXT_NODE) { //console.log(curGChildNode); refwdformatter.removeQuoteMarksInTextMessage(curChildNode); // Basically, this code-block won't be run. } else { //console.log(curChildNode.tagName); switch (curChildNode.tagName) { case "BR": if (isFirstChildren) { brCounter--; } break; case "SPAN": case "DIV": if (isFirstChildren) isFirstChildren = false; if (curChildNode.hasChildNodes()) { var grandChildren = curChildNode.childNodes; //console.log(grandChildren); for (var n = 0; n < grandChildren.length; n++) { var curGChildNode = grandChildren[n]; if (curGChildNode.nodeType === Node.TEXT_NODE) { //console.log(curGChildNode); refwdformatter.removeQuoteMarksInTextMessage(curGChildNode); } } } break; default: if (isFirstChildren) isFirstChildren = false; break; } } } refwdformatter.addLineBreakJustInCase(brCounter); } } else if ((reh || lih) && msgHtml) { if (b.hasChildNodes()) { var childNodes = b.childNodes; //console.log(childNodes); var is1stChild = true; for (var l = 0; l < childNodes.length; l++) { if (childNodes[l].tagName == "BLOCKQUOTE") { is1stChild = false; // Replace the first <blockquote> tag with new <div> tag var newdiv = document.createElement("div"); while (childNodes[l].firstChild) { newdiv.appendChild(childNodes[l].firstChild); // *Moves* the child } newdiv.setAttribute('class', 'replaced-blockquote'); for (var index = childNodes[l].attributes.length - 1; index >= 0; --index) { newdiv.attributes.setNamedItem(childNodes[l].attributes[index].cloneNode()); } childNodes[l].parentNode.replaceChild(newdiv, childNodes[l]); break; } if (!is1stChild) break; } var resethtml = b.innerHTML; b.innerHTML = resethtml; // To redraw. If there is not this code, the <div> tag width will shirink - I do not know why. refwdformatter.addLineBreakJustInCase(brCount); } } refwdformatter.initCursorPosition(); } /// [--- liveweave debug 1 - END copy here ---] } window.setTimeout(function () { refwdformatter.editing = false; }, 700); }, removeQuoteMarksInTextMessage: function (curNode) { /// [--- liveweave debug 2 - START copy here ---] //console.log(curNode.previousSibling); if ((curNode.previousSibling === null) || (curNode.previousSibling.tagName === "BR")) { //console.log(curNode.data); curNode.data = curNode.data. replace(/^> {2}/g, " "). replace(/^> /g, ""). replace(/^>((>)+) /g, "$1 "). replace(/^>((>)+)$/g, "$1 "); //console.log(curNode.data); } /// [--- liveweave debug 2 - END copy here ---] }, addLineBreakJustInCase: function (brCounter) { //if (brCounter > 0) { // var e = GetCurrentEditor(); // e.beginningOfDocument(); // while (brCounter > 0) { // brCounter--; // e.insertHTML("<br>"); // } //} }, initCursorPosition: function () { //var e = GetCurrentEditor(); //e.beginningOfDocument(); //e.insertHTML(" "); //e.undo(1); }, onClick: function (htmlMode) { window.setTimeout(function () { refwdformatter.format(htmlMode); }, 700); } };