From c7ad8f8df2f022f87fbabeb05dbe2c02c2c4fafa Mon Sep 17 00:00:00 2001 From: halex Date: Tue, 14 Aug 2007 07:53:13 +0000 Subject: [PATCH] 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. --- src/www/bongo/dragonfly/MailView.py | 4 +- src/www/js/Composer.js | 48 ++++++++++----- src/www/js/eArea/editableArea.js | 91 ++++++++++++++++++++++++++++- 3 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/www/bongo/dragonfly/MailView.py b/src/www/bongo/dragonfly/MailView.py index ab39d57..ad2ad8c 100644 --- a/src/www/bongo/dragonfly/MailView.py +++ b/src/www/bongo/dragonfly/MailView.py @@ -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()) diff --git a/src/www/js/Composer.js b/src/www/js/Composer.js index 017300c..2a5dc39 100644 --- a/src/www/js/Composer.js +++ b/src/www/js/Composer.js @@ -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][edit-area]"; + html.push ('
  • ', _('Attach file...'), '
  • ', - '
    ', 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]
    [edit-area]", "font-family: lucida grande,myriad,myriad pro,verdana,luxi sans,bitstream vera sans,sans-serif;font-size:0.9em;"), '', + '
    ', insertEditableArea(this.body, '99%', '250px', composerToolbar, m.defaultComposerStyle), '', '', '', '', @@ -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; diff --git a/src/www/js/eArea/editableArea.js b/src/www/js/eArea/editableArea.js index 5d985d1..0d7f08a 100644 --- a/src/www/js/eArea/editableArea.js +++ b/src/www/js/eArea/editableArea.js @@ -29,7 +29,8 @@ function insertEditableArea(editableAreaName, editableAreaWidth, editableAreaHei var redoButton = ''; var selectAllButton = ''; var insertImageButton = ''; - var insertLinkButton = ''; + var insertLinkButton = ''; + var switchModeButton = ''; var editableArea = '' 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, ''); 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(/]*>/ig,"$1"); // Linkies + d = d.replace("", "*"); // Vold (that's bold with an accent ;) + d = d.replace("", "*"); + //d = d.replace("
    " + //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);