Adds the ability to switch between HTML and text-based composition.

Three notes: all the HTML buttons are still available when you're in plain-text mode; we don't check your prefs as to what default composer mode you'd like; and line breaks are a bit whacky when you switch modes (I think :).
Please expect and report breakage.
This commit is contained in:
halex
2007-08-14 07:53:13 +00:00
parent 6ce6bd184f
commit c7ad8f8df2
3 changed files with 123 additions and 20 deletions
+2 -2
View File
@@ -35,8 +35,8 @@ class ConversationsHandler(ResourceHandler):
if jsob.has_key("body") :
composer.SetBody(jsob.get("body"))
if jsob.has_key("bodyHtml") :
composer.SetBody(jsob.get("bodyHtml"), "text/html")
if jsob.has_key("isHtml") and (jsob.get("isHtml") == True or jsob.get("isHtml") == 'true') :
composer.SetBody(jsob.get("body"), "text/html")
composer.SetDate(time.time())
+32 -16
View File
@@ -53,7 +53,7 @@ Dragonfly.Mail.Composer.parseMailto = function (mailto)
to: '',
cc: '',
bcc: p.getAutoBcc() || '',
bodyHtml: defaultbodyHtml
body: defaultbodyHtml
};
if (mailto.substr (0, 7) != 'mailto:') {
return null;
@@ -75,7 +75,7 @@ Dragonfly.Mail.Composer.parseMailto = function (mailto)
case 'subject':
case 'inreplyto':
case 'forward':
case 'bodyHtml':
case 'body':
case 'conversation':
msg[field] = decodeURIComponent (arg[1]);
break;
@@ -104,9 +104,9 @@ Dragonfly.Mail.Composer.prototype.buildHtml = function (html)
this.addAttachment = d.nextId ('add-attachment');
this.subject = d.nextId ('subject');
this.bodyHtml = d.nextId ('bodyHtml');
this.toolbar = d.nextId ('toolbar');
this.body = d.nextId ('body');
this.toolbar = $('toolbar');
this.discard = d.nextId ('discard');
this.save = d.nextId ('save');
this.send = d.nextId ('send');
@@ -137,9 +137,9 @@ Dragonfly.Mail.Composer.prototype.buildHtml = function (html)
if (this.msg.contents) {
switch (this.msg.contents.contenttype) {
case 'multipart/mixed':
var bodyHtml = this.msg.contents.children[0];
if (bodyHtml.contenttype == 'text/plain') {
this.msg.bodyHtml = bodyHtml.content;
var body = this.msg.contents.children[0];
if (body.contenttype == 'text/plain') {
this.msg.body = body.content;
}
for (var i = 1; i < this.msg.contents.children.length; i++) {
var attachment = this.msg.contents.children[i];
@@ -149,13 +149,18 @@ Dragonfly.Mail.Composer.prototype.buildHtml = function (html)
}
break;
case 'text/plain':
this.msg.bodyHtml = this.msg.contents.content;
this.msg.body = this.msg.contents.content;
break;
}
}
m.defaultComposerStyle = "font-family: lucida grande,myriad,myriad pro,verdana,luxi sans,bitstream vera sans,sans-serif;font-size:0.9em;"
m.isHtml = true;
var composerToolbar = "[bold][italic][underlined] sep [align-left][justify][align-center][align-right] sep [undo][redo][select-all] sep [insert-image][insert-link] sep [switch-mode]</div>[edit-area]";
html.push ('<li><a id="', this.addAttachment, '">', _('Attach file...'), '</a></li></ul>',
'<tr><td colspan="2"><div class="toolbar">', insertEditableArea(this.bodyHtml, '99%', '250px', "[bold][italic][underlined] sep [align-left][justify][align-center][align-right] sep [undo][redo][select-all] sep [insert-image][insert-link]</div>[edit-area]", "font-family: lucida grande,myriad,myriad pro,verdana,luxi sans,bitstream vera sans,sans-serif;font-size:0.9em;"), '</td></tr>',
'<tr><td colspan="2"><div class="toolbar">', insertEditableArea(this.body, '99%', '250px', composerToolbar, m.defaultComposerStyle), '</td></tr>',
'<tr class="action"><td id="', this.toolbar, '" colspan="2">',
'<input id="', this.discard, '" class="discard" type="button" value="', _('Discard'), '">',
'<input id="', this.save, '" class="save" type="button" value="', _('Save Draft'), '">',
@@ -184,8 +189,8 @@ Dragonfly.Mail.Composer.prototype.connectHtml = function (elem)
this.bcc = $(this.bcc);
this.from = $(this.from);
this.subject = $(this.subject);
//d.bodyHtmlname = this.bodyHtml;
//this.bodyHtml = $(this.bodyHtml);
//d.bodyname = this.body;
//this.body = $(this.body);
this.addAttachment = $(this.addAttachment);
this.discard = $(this.discard);
this.send = $(this.send);
@@ -244,7 +249,8 @@ Dragonfly.Mail.Composer.prototype.getCurrentMessage = function ()
cc: this.cc.value,
bcc: this.bcc.value,
subject: this.subject.value,
bodyHtml: editableAreaContents(this.bodyHtml)
body: editableAreaContents(this.body),
isHtml: Dragonfly.Mail.isHtml
};
};
@@ -425,12 +431,22 @@ Dragonfly.Mail.Composer.prototype.sendMessage = function (evt)
{
this.saveDraft(this);
this.draftSaveCalled = true;
this.callCount = 1;
callLater(1, bind('sendMessage', this));
}
else if (this.callCount > 10)
{
logDebug('Save took more than 10sec, giving up.');
d.notifyError (_('Error sending message: Gave up while trying to send. Check logs.'));
this.callCount = 0; // Reset counter.
this.draftSaveCalled = false;
return false;
}
else
{
// Still waiting for draft to save...
logDebug('Save not finished yet - checking again in 1sec.');
this.callCount++;
callLater(1, bind('sendMessage', this));
}
@@ -610,8 +626,8 @@ Dragonfly.Mail.Composer.composeNew = function (msg)
html.set ('conv-msg-list');
setEditableAreaContents(composer.bodyHtml, d.escapeHTML (msg.bodyHtml));
ititButtons(composer.bodyHtml);
setEditableAreaContents(composer.body, d.escapeHTML (msg.body));
ititButtons(composer.body);
d.resizeScrolledView();
@@ -880,7 +896,7 @@ Dragonfly.Mail.AttachmentForm.prototype.frameLoad = function (evt)
var doc = d.getIFrameDocument (this.iframeId);
var jsob;
try {
jsob = d.eval (Element.getText (doc.bodyHtml));
jsob = d.eval (Element.getText (doc.body));
} catch (e) {
showError.call (this, 'server response was not understood');
return;
+89 -2
View File
@@ -29,7 +29,8 @@ function insertEditableArea(editableAreaName, editableAreaWidth, editableAreaHei
var redoButton = '<input type="image" src="/js/eArea/icons/edit-redo.png" value="Redo" alt="Redo" name="' + editableAreaName + '" id="redo" class="icon" style="width:24px;height:24px;">';
var selectAllButton = '<input type="image" src="/js/eArea/icons/edit-select-all.png" value="Select all" alt="Select all" name="' + editableAreaName + '" id="selectall" class="icon" style="width:24px;height:24px;">';
var insertImageButton = '<input type="image" src="/js/eArea/icons/insert-image.png" value="Insert image" alt="Insert image" name="' + editableAreaName + '" id="insertimage" class="icon" style="width:24px;height:24px;">';
var insertLinkButton = '<input type="image" src="/js/eArea/icons/insert-link.png" value="Insert link" alt="Insert link" name="' + editableAreaName + '" id="insertlink" class="icon" style="width:24px;height:24px;">';
var insertLinkButton = '<input type="image" src="/js/eArea/icons/insert-link.png" value="Insert link" alt="Insert link" name="' + editableAreaName + '" id="insertlink" class="icon" style="width:24px;height:24px;">';
var switchModeButton = '<input type="image" src="/js/eArea/icons/switch-mode.png" value="Switch mode" alt="Switch mode" name="' + editableAreaName + '" id="switchmode" class="icon" style="width:24px;height:24px;">';
var editableArea = '<iframe src="/js/eArea/blank.html?style=' + editableAreaStyle + '" id="' + editableAreaName + '" \n style="width:' + editableAreaWidth + '; min-height:' + editableAreaHeight + '; border-style:solid; border: 1px solid #DDDDDD;" frameborder="0px"></iframe>'
var editableAreaHTML = editableAreaLayout;
@@ -48,6 +49,7 @@ function insertEditableArea(editableAreaName, editableAreaWidth, editableAreaHei
editableAreaHTML = editableAreaHTML.replace("[select-all]", selectAllButton);
editableAreaHTML = editableAreaHTML.replace("[insert-image]", insertImageButton);
editableAreaHTML = editableAreaHTML.replace("[insert-link]", insertLinkButton);
editableAreaHTML = editableAreaHTML.replace("[switch-mode]", switchModeButton);
editableAreaHTML = editableAreaHTML.replace(/sep/g, '<span class="split"></span>');
editableAreaHTML = editableAreaHTML.replace("[edit-area]", editableArea);
@@ -65,9 +67,24 @@ function insertEditableArea(editableAreaName, editableAreaWidth, editableAreaHei
return retHTML;
}
// TODO!
function stripHTML(d)
{
d = d.replace(/(<([^>]+)>)/ig, ""); // Remove the other tags we can't handle.
/*
foreach ($tags as $tag){
while(preg_match('/<'.$tag.'(|\W[^>]*)>(.*)<\/'. $tag .'>/iusU', $text, $found)){
$text = str_replace($found[0],$found[2],$text);
}
}
return preg_replace('/(<('.join('|',$tags).')(|\W.*)\/>)/iusU', '', $text);
*/
d = d.replace(/<a[^href]+href=\"([^\"]*)\"[^>]*>/ig,"$1"); // Linkies
d = d.replace("<b>", "*"); // Vold (that's bold with an accent ;)
d = d.replace("<strong>", "*");
//d = d.replace("<br />"
//d = d.replace(/(<([^>]+)>)/ig, ""); // Remove the other tags we can't handle.
return d;
}
@@ -84,6 +101,21 @@ function editableAreaContents(editableAreaName) {
}
}
// Enable/disable HTML buttons
// TODO!!!
function setHTMLbuttons(value)
{
var obj = $('toolbar').childNodes;
for (var i=0; i < obj.length; i++)
{
var btn = obj[i];
if (btn.attributes.getNamedItem('isHtml').value == "true")
{
btn.style.class = "icon selected";
}
}
}
function setEditableAreaContents(editableAreaName, value)
{
if (document.designMode) {
@@ -260,6 +292,61 @@ function buttonOnClick() {
//runCmd(this.name, this.id, null, path);
}
}
else if (this.id == "switchmode")
{
// Dragonfly must be included here; otherwise you'll get script errors!
if (Dragonfly)
{
var m = Dragonfly.Mail;
if (m.isHtml)
{
// Grab the contents to put in the normal textarea.
var style = "'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Monaco', 'Courier', monospace";
// Disable HTML-styling buttons / change onclick events.
// Set the style for the inner iframe thing (only on browsers that support designMode, since textarea is already ok)
if (window[this.name])
{
window[this.name].document.body.style.fontFamily = style;
window[this.name].document.body.style.width = "47em";
}
else
{
document.getElementById(this.name).contentWindow.document.body.style.fontFamily = style;
document.getElementById(this.name).contentWindow.document.body.style.width = "47em";
}
setEditableAreaContents(this.name, stripHTML(editableAreaContents(this.name)));
m.isHtml = false;
}
else
{
var style = m.defaultComposerStyle;
// Re-enable HTML-styling buttons / change onclick events.
// Set the style for the inner iframe thing (only on browsers that support designMode, since textarea is already ok)
if (window[this.name])
{
window[this.name].document.body.setAttribute('style', style);
}
else
{
document.getElementById(this.name).contentWindow.document.body.setAttribute('style', style);
}
m.isHtml = true;
}
//alert('isHtml? ' + m.isHtml);
}
else
{
alert('Dragonfly not loaded - can\'t switch composition modes.');
}
}
else
{
runCmd(this.name, this.id, false, null);