IMP compose javascript enhancements.
authorMichael M Slusarz <slusarz@curecanti.org>
Mon, 9 Feb 2009 21:36:46 +0000 (14:36 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Mon, 9 Feb 2009 21:36:46 +0000 (14:36 -0700)
Namespace code, use proper event handling, etc.

imp/compose.php
imp/js/compose.js
imp/js/src/compose.js
imp/templates/compose/compose.html
imp/templates/compose/redirect.html

index 72881f1..0d2b70c 100644 (file)
@@ -774,15 +774,15 @@ if (!$rtemode) {
 
 /* Define some variables used in the javascript code. */
 $js_code = array(
-    'var cancel_url = \'' . $cancel_url . '\'',
-    'var compose_spellcheck = ' . intval($spellcheck && $prefs->getValue('compose_spellcheck')),
-    'var cursor_pos = ' . (is_null($cursor_pos) ? 'null' : $cursor_pos),
-    'var max_attachments = ' . (($max_attach === true) ? 'null' : $max_attach),
-    'var compose_popup = ' . intval($isPopup),
-    'var redirect = ' . intval($redirect),
-    'var rtemode = ' . intval($rtemode),
-    'var smf_check = ' . intval($smf_check),
-    'var reloaded = ' . intval($token)
+    'ImpCompose.cancel_url = \'' . $cancel_url . '\'',
+    'ImpCompose.spellcheck = ' . intval($spellcheck && $prefs->getValue('compose_spellcheck')),
+    'ImpCompose.cursor_pos = ' . (is_null($cursor_pos) ? 'null' : $cursor_pos),
+    'ImpCompose.max_attachments = ' . (($max_attach === true) ? 'null' : $max_attach),
+    'ImpCompose.popup = ' . intval($isPopup),
+    'ImpCompose.redirect = ' . intval($redirect),
+    'ImpCompose.rtemode = ' . intval($rtemode),
+    'ImpCompose.smf_check = ' . intval($smf_check),
+    'ImpCompose.reloaded = ' . intval($token)
 );
 
 /* Create javascript identities array. */
@@ -798,7 +798,7 @@ if (!$redirect) {
             Horde_Mime_Address::addrArray2String($identity->getBccAddresses($ident))
         );
     }
-    $js_code[] = 'var identities = ' . Horde_Serialize::serialize($js_ident, SERIALIZE_JSON, NLS::getCharset());
+    $js_code[] = 'ImpCompose.identities = ' . Horde_Serialize::serialize($js_ident, SERIALIZE_JSON, NLS::getCharset());
 }
 
 
index 0a1464b..40db822 100644 (file)
@@ -1 +1 @@
-var display_unload_warning=true,textarea_ready=true;function confirmCancel(a){if(window.confirm(IMP.text.compose_cancel)){display_unload_warning=false;if(popup){if(cancel_url){self.location=cancel_url}else{self.close()}}else{window.location=cancel_url}return true}else{Event.extend(a);a.stop();return false}}function setCursorPosition(c,a){if(c.setSelectionRange){Field.focus(c);c.setSelectionRange(a,a)}else{if(c.createTextRange){var b=c.createTextRange();b.collapse(true);b.moveStart("character",a);b.moveEnd("character",0);Field.select(b);b.scrollIntoView(true)}}}function redirectSubmit(a){if($F("to")==""){alert(IMP.text.compose_recipient);$("to").focus();Event.extend(a);a.stop();return false}$("redirect").setStyle({cursor:"wait"});display_unload_warning=false;return true}function change_identity(a){var m=identities[$F("last_identity")],d=identities[a],b,e,g,l;if(rtemode){e=FCKeditorAPI.GetInstance("message");b=e.GetHTML.replace(/\r\n/g,"\n");g="<p><!--begin_signature--><!--end_signature--></p>";l="<p><!--begin_signature-->"+d[0].replace(/^ ?<br \/>\n/,"").replace(/ +/g," ")+"<!--end_signature--></p>";b=b.replace(/<p class="imp-signature">\s*<!--begin_signature-->[\s\S]*?<!--end_signature-->\s*<\/p>/,g)}else{b=$F("message").replace(/\r\n/g,"\n");g=m[0].replace(/^\n/,"");l=d[0].replace(/^\n/,"")}var k=(m[1])?b.indexOf(g):b.lastIndexOf(g);if(k!=-1){if(d[1]==m[1]){b=b.substring(0,k)+l+b.substring(k+g.length,b.length)}else{if(d[1]){b=l+b.substring(0,k)+b.substring(k+g.length,b.length)}else{b=b.substring(0,k)+b.substring(k+g.length,b.length)+l}}b=b.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");$("last_identity").setValue(a);window.status=IMP.text.compose_sigreplace}else{window.status=IMP.text.compose_signotreplace}if(rtemode){e.SetHTML(b)}else{$("message").setValue(b)}var j=$("sent_mail_folder");if(smf_check){var c=0;$A(j.options).detect(function(i){if(i.value==d[2]){j.selectedIndex=c;return true}++c})}else{if(j.firstChild){j.replaceChild(document.createTextNode(d[2]),j.firstChild)}else{j.appendChild(document.createTextNode(d[2]))}}var h=$("ssm");if(h){h.checked=d[3]}var f=$("bcc");if(f){bccval=f.value;if(m[4]){var n=new RegExp(m[4]+",? ?","gi");bccval=bccval.replace(n,"");if(bccval){bccval=bccval.replace(/, ?$/,"")}}if(d[4]){if(bccval){bccval+=", "}bccval+=d[4]}f.setValue(bccval)}}function uniqSubmit(b,a){if(a){Event.extend(a);a.stop()}if(b=="send_message"){if(($F("subject")=="")&&!window.confirm(IMP.text.compose_nosubject)){return}if(compose_spellcheck&&IMP.SpellCheckerObject&&!IMP.SpellCheckerObject.isActive()){IMP.SpellCheckerObject.spellCheck();return}}if(IMP.SpellCheckerObject){IMP.SpellCheckerObject.resume()}if(!Prototype.Browser.WebKit){$("compose").setStyle({cursor:"wait"})}display_unload_warning=false;$("actionID").setValue(b);_uniqSubmit()}function _uniqSubmit(){if(textarea_ready){$("compose").submit()}else{_uniqSubmit.defer()}}function attachmentChanged(){var a=[],e=0;$("upload_atc").select('input[type="file"]').each(function(g){a[a.length]=g});if(max_attachments!==null&&a.length==max_attachments){return}a.each(function(g){if(g.value.length>0){e++}});if(e==a.length){var d=$("attachment_row_"+e);if(d){var f=new Element("TD",{align:"left"}).insert(new Element("STRONG").insert(IMP.text.compose_file+" "+(e+1)+":")).insert("&nbsp;");var c=new Element("INPUT",{type:"file",name:"upload_"+(e+1),size:25});c.observe("change",attachmentChanged);f.insert(c);var b=new Element("TR",{id:"attachment_row_"+(e+1)}).insert(f);d.parentNode.insertBefore(b,d.nextSibling)}}}function initializeSpellChecker(){if(typeof IMP.SpellCheckerObject!="object"){initializeSpellChecker.defer();return}IMP.SpellCheckerObject.onBeforeSpellCheck=function(){IMP.SpellCheckerObject.htmlAreaParent="messageParent";IMP.SpellCheckerObject.htmlArea=$("message").adjacent("iframe[id*=message]").first();$("message").setValue(FCKeditorAPI.GetInstance("message").GetHTML());textarea_ready=false};IMP.SpellCheckerObject.onAfterSpellCheck=function(){IMP.SpellCheckerObject.htmlArea=IMP.SpellCheckerObject.htmlAreaParent=null;var a=FCKeditorAPI.GetInstance("message");a.SetHTML($("message").value);a.Events.AttachEvent("OnAfterSetHTML",function(){textarea_ready=true})}}document.observe("dom:loaded",function(){$$("INPUT").each(function(a){if(a.type!="submit"&&a.type!="button"){a.observe("keydown",function(b){if(b.keyCode==10||b.keyCode==Event.KEY_RETURN){b.stop();return false}})}});if(cursor_pos!==null&&$("message")){setCursorPosition($("message"),cursor_pos)}if(redirect){$("to").focus()}else{if(Prototype.Browser.IE){$("subject").observe("keydown",function(a){if(a.keyCode==Event.KEY_TAB&&!a.shiftKey){a.stop();$("message").focus()}})}if(rtemode){initializeSpellChecker()}if($("to")&&!$F("to")){$("to").focus()}else{if(!$F("subject")){if(rtemode){$("subject").focus()}else{$("message").focus()}}}}});Event.observe(window,"load",function(){if(compose_popup&&!reloaded){var b,a=redirect?$("redirect"):$("compose");b=Math.min(a.getHeight(),screen.height-100)-document.viewport.getHeight();if(b>0){window.resizeBy(0,b)}}});Event.observe(window,"beforeunload",function(){if(display_unload_warning){return IMP.text.compose_discard}});
\ No newline at end of file
+var ImpCompose={display_unload_warning:true,textarea_ready:true,confirmCancel:function(a){if(window.confirm(IMP.text.compose_cancel)){this.display_unload_warning=false;if(this.popup){if(this.cancel_url){self.location=this.cancel_url}else{self.close()}}else{window.location=this.cancel_url}}else{a.stop()}},setCursorPosition:function(c,a){if(c.setSelectionRange){Field.focus(c);c.setSelectionRange(a,a)}else{if(c.createTextRange){var b=c.createTextRange();b.collapse(true);b.moveStart("character",a);b.moveEnd("character",0);Field.select(b);b.scrollIntoView(true)}}},changeIdentity:function(c){var a=$F(c),n=this.identities[$F("last_identity")],e=this.identities[a],d=0,h=$("bcc"),k=$("ssm"),j=$("sent_mail_folder"),f,g,b,m,l,o;if(this.rtemode){f=FCKeditorAPI.GetInstance("message");b=f.GetHTML.replace(/\r\n/g,"\n");g="<p><!--begin_signature--><!--end_signature--></p>";m="<p><!--begin_signature-->"+e[0].replace(/^ ?<br \/>\n/,"").replace(/ +/g," ")+"<!--end_signature--></p>";b=b.replace(/<p class="imp-signature">\s*<!--begin_signature-->[\s\S]*?<!--end_signature-->\s*<\/p>/,g)}else{b=$F("message").replace(/\r\n/g,"\n");g=n[0].replace(/^\n/,"");m=e[0].replace(/^\n/,"")}l=(n[1])?b.indexOf(g):b.lastIndexOf(g);if(l!=-1){if(e[1]==n[1]){b=b.substring(0,l)+m+b.substring(l+g.length,b.length)}else{if(e[1]){b=m+b.substring(0,l)+b.substring(l+g.length,b.length)}else{b=b.substring(0,l)+b.substring(l+g.length,b.length)+m}}b=b.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n");$("last_identity").setValue(a);window.status=IMP.text.compose_sigreplace}else{window.status=IMP.text.compose_signotreplace}if(this.rtemode){f.SetHTML(b)}else{$("message").setValue(b)}if(this.smf_check){$A(j.options).detect(function(i){if(i.value==e[2]){j.selectedIndex=d;return true}++d})}else{if(j.firstChild){j.replaceChild(document.createTextNode(e[2]),j.firstChild)}else{j.appendChild(document.createTextNode(e[2]))}}if(k){k.checked=e[3]}if(h){bccval=h.value;if(n[4]){o=new RegExp(n[4]+",? ?","gi");bccval=bccval.replace(o,"");if(bccval){bccval=bccval.replace(/, ?$/,"")}}if(e[4]){if(bccval){bccval+=", "}bccval+=e[4]}h.setValue(bccval)}},uniqSubmit:function(b,a){a.stop();if(b=="redirect"){if($F("to")==""){alert(IMP.text.compose_recipient);$("to").focus()}else{if(!Prototype.Browser.WebKit){$("redirect").setStyle({cursor:"wait"})}this.display_unload_warning=false}return}if(b=="send_message"){if(($F("subject")=="")&&!window.confirm(IMP.text.compose_nosubject)){return}if(this.spellcheck&&IMP.SpellCheckerObject&&!IMP.SpellCheckerObject.isActive()){IMP.SpellCheckerObject.spellCheck();return}}if(IMP.SpellCheckerObject){IMP.SpellCheckerObject.resume()}if(!Prototype.Browser.WebKit){$("compose").setStyle({cursor:"wait"})}this.display_unload_warning=false;$("actionID").setValue(b);this._uniqSubmit()},_uniqSubmit:function(){if(this.textarea_ready){$("compose").submit()}else{this._uniqSubmit.defer()}},attachmentChanged:function(){var a=[],d=0,c,b,e;$("upload_atc").select('input[type="file"]').each(function(f){a[a.length]=f});if(this.max_attachments!==null&&a.length==this.max_attachments){return}a.each(function(f){if(f.value.length>0){d++}});if(d==a.length){c=$("attachment_row_"+d);if(c){e=new Element("TD",{align:"left"}).insert(new Element("STRONG").insert(IMP.text.compose_file+" "+(d+1)+":")).insert("&nbsp;");e.insert(new Element("INPUT",{type:"file",name:"upload_"+(d+1),size:25}));b=new Element("TR",{id:"attachment_row_"+(d+1)}).insert(e);c.parentNode.insertBefore(b,c.nextSibling)}}},initializeSpellChecker:function(){if(typeof IMP.SpellCheckerObject!="object"){this.initializeSpellChecker.defer();return}IMP.SpellCheckerObject.onBeforeSpellCheck=this._beforeSpellCheck.bind(this);IMP.SpellCheckerObject.onAfterSpellCheck=this._afterSpellCheck.bind(this)},_beforeSpellCheck:function(){IMP.SpellCheckerObject.htmlAreaParent="messageParent";IMP.SpellCheckerObject.htmlArea=$("message").adjacent("iframe[id*=message]").first();$("message").setValue(FCKeditorAPI.GetInstance("message").GetHTML());this.textarea_ready=false},_afterSpellCheck:function(){IMP.SpellCheckerObject.htmlArea=IMP.SpellCheckerObject.htmlAreaParent=null;var a=FCKeditorAPI.GetInstance("message");a.SetHTML($("message").value);a.Events.AttachEvent("OnAfterSetHTML",this._afterSetHTML.bind(this))},_afterSetHTML:function(){this.textarea_ready=true},clickHandler:function(c){var b=c.element(),a;if(b.hasClassName("button")){a=b.readAttribute("name");switch(a){case"btn_add_attachment":case"btn_redirect":case"btn_save_draft":case"btn_send_message":this.uniqSubmit(a.substring(4),c);break;case"btn_cancel_compose":this.confirmCancel(c);break}}},changeHandler:function(b){var a=b.element(),c=a.readAttribute("id");switch(c){case"identity":this.changeIdentity(a);break;case"stationery":this.uniqSubmit("change_stationery",b);break;case"sent_mail_folder":$("ssm").writeAttribute("checked","checked");break;default:if(c.substring(0,7)=="upload_"){this.attachmentChanged()}break}},onDomLoad:function(){$$("INPUT").each(function(a){if(a.type!="submit"&&a.type!="button"){a.observe("keydown",function(b){if(b.keyCode==10||b.keyCode==Event.KEY_RETURN){b.stop();return false}})}});if(this.cursor_pos!==null&&$("message")){this.setCursorPosition($("message"),this.cursor_pos)}if(this.redirect){$("to").focus()}else{if(Prototype.Browser.IE){$("subject").observe("keydown",function(a){if(a.keyCode==Event.KEY_TAB&&!a.shiftKey){a.stop();$("message").focus()}})}if(this.rtemode){this.initializeSpellChecker()}if($("to")&&!$F("to")){$("to").focus()}else{if(!$F("subject")){if(this.rtemode){$("subject").focus()}else{$("message").focus()}}}}},onLoad:function(){var b,a=this.redirect?$("redirect"):$("compose");if(this.popup&&!this.reloaded){b=Math.min(a.getHeight(),screen.height-100)-document.viewport.getHeight();if(b>0){window.resizeBy(0,b)}}document.observe("click",this.clickHandler.bindAsEventListener(this));document.observe("change",this.changeHandler.bindAsEventListener(this))},onBeforeUnload:function(){if(this.display_unload_warning){return IMP.text.compose_discard}}};document.observe("dom:loaded",ImpCompose.onDomLoad.bind(ImpCompose));Event.observe(window,"load",ImpCompose.onLoad.bind(ImpCompose));Event.observe(window,"beforeunload",ImpCompose.onBeforeUnload.bind(ImpCompose));
\ No newline at end of file
index f015ac8..38267c9 100644 (file)
 /**
- * Provides the javascript for the compose.php script.
+ * Provides the javascript for the compose.php script (standard view).
  *
  * See the enclosed file COPYING for license information (GPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
  */
 
-/*
- * Variables defined in compose.php:
- *    cancel_url, compose_spellcheck, cursor_pos, identities, max_attachments,
- *    popup, redirect, rtemode, smf_check
- */
-
-var display_unload_warning = true,
-    textarea_ready = true;
-
-function confirmCancel(event)
-{
-    if (window.confirm(IMP.text.compose_cancel)) {
-        display_unload_warning = false;
-        if (popup) {
-            if (cancel_url) {
-                self.location = cancel_url;
+var ImpCompose = {
+    /* Variables defined in compose.php:
+     *   cancel_url, spellcheck, cursor_pos, identities, max_attachments,
+     *   popup, redirect, reloaded, rtemode, smf_check */
+    display_unload_warning: true,
+    textarea_ready: true,
+
+    confirmCancel: function(e)
+    {
+        if (window.confirm(IMP.text.compose_cancel)) {
+            this.display_unload_warning = false;
+            if (this.popup) {
+                if (this.cancel_url) {
+                    self.location = this.cancel_url;
+                } else {
+                    self.close();
+                }
             } else {
-                self.close();
+                window.location = this.cancel_url;
             }
         } else {
-            window.location = cancel_url;
+            e.stop();
         }
-        return true;
-    } else {
-        Event.extend(event);
-        event.stop();
-        return false;
-    }
-}
-
-/**
- * Sets the cursor to the given position.
- */
-function setCursorPosition(input, position)
-{
-    if (input.setSelectionRange) {
-        /* This works in Mozilla */
-        Field.focus(input);
-        input.setSelectionRange(position, position);
-    } else if (input.createTextRange) {
-        /* This works in IE */
-        var range = input.createTextRange();
-        range.collapse(true);
-        range.moveStart('character', position);
-        range.moveEnd('character', 0);
-        Field.select(range);
-        range.scrollIntoView(true);
-    }
-}
-
-function redirectSubmit(event)
-{
-    if ($F('to') == '') {
-        alert(IMP.text.compose_recipient);
-        $('to').focus();
-        Event.extend(event);
-        event.stop();
-        return false;
-    }
-
-    $('redirect').setStyle({ cursor: 'wait' });
-    display_unload_warning = false;
-
-    return true;
-}
-
-function change_identity(id)
-{
-    var last = identities[$F('last_identity')],
-        next = identities[id],
-        msg, ed, lastSignature, nextSignature;
-
-    // If the rich text editor is on, we'll use a regexp to find the
-    // signature comment and replace its contents.
-    if (rtemode) {
-        ed = FCKeditorAPI.GetInstance('message');
-
-        msg = ed.GetHTML.replace(/\r\n/g, '\n');
+    },
+
+    /**
+     * Sets the cursor to the given position.
+     */
+    setCursorPosition: function(input, position)
+    {
+        if (input.setSelectionRange) {
+            /* This works in Mozilla */
+            Field.focus(input);
+            input.setSelectionRange(position, position);
+        } else if (input.createTextRange) {
+            /* This works in IE */
+            var range = input.createTextRange();
+            range.collapse(true);
+            range.moveStart('character', position);
+            range.moveEnd('character', 0);
+            Field.select(range);
+            range.scrollIntoView(true);
+        }
+    },
+
+    changeIdentity: function(elt)
+    {
+        var id = $F(elt),
+            last = this.identities[$F('last_identity')],
+            next = this.identities[id],
+            i = 0,
+            bcc = $('bcc'),
+            save = $('ssm'),
+            smf = $('sent_mail_folder'),
+            ed, lastSignature, msg, nextSignature, pos, re;
+
+        // If the rich text editor is on, we'll use a regexp to find the
+        // signature comment and replace its contents.
+        if (this.rtemode) {
+            ed = FCKeditorAPI.GetInstance('message');
+
+            msg = ed.GetHTML.replace(/\r\n/g, '\n');
+
+            lastSignature = '<p><!--begin_signature--><!--end_signature--></p>';
+            nextSignature = '<p><!--begin_signature-->' + next[0].replace(/^ ?<br \/>\n/, '').replace(/ +/g, ' ') + '<!--end_signature--></p>';
+
+            // Dot-all functionality achieved with [\s\S], see:
+            // http://simonwillison.net/2004/Sep/20/newlines/
+            msg = msg.replace(/<p class="imp-signature">\s*<!--begin_signature-->[\s\S]*?<!--end_signature-->\s*<\/p>/, lastSignature);
+        } else {
+            msg = $F('message').replace(/\r\n/g, '\n');
 
-        lastSignature = '<p><!--begin_signature--><!--end_signature--></p>';
-        nextSignature = '<p><!--begin_signature-->' + next[0].replace(/^ ?<br \/>\n/, '').replace(/ +/g, ' ') + '<!--end_signature--></p>';
+            lastSignature = last[0].replace(/^\n/, '');
+            nextSignature = next[0].replace(/^\n/, '');
+        }
 
-        // Dot-all functionality achieved with [\s\S], see:
-        // http://simonwillison.net/2004/Sep/20/newlines/
-        msg = msg.replace(/<p class="imp-signature">\s*<!--begin_signature-->[\s\S]*?<!--end_signature-->\s*<\/p>/, lastSignature);
-    } else {
-        msg = $F('message').replace(/\r\n/g, '\n');
+        pos = (last[1]) ? msg.indexOf(lastSignature) : msg.lastIndexOf(lastSignature);
+        if (pos != -1) {
+            if (next[1] == last[1]) {
+                msg = msg.substring(0, pos) + nextSignature + msg.substring(pos + lastSignature.length, msg.length);
+            } else if (next[1]) {
+                msg = nextSignature + msg.substring(0, pos) + msg.substring(pos + lastSignature.length, msg.length);
+            } else {
+                msg = msg.substring(0, pos) + msg.substring(pos + lastSignature.length, msg.length) + nextSignature;
+            }
 
-        lastSignature = last[0].replace(/^\n/, '');
-        nextSignature = next[0].replace(/^\n/, '');
-    }
+            msg = msg.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
 
-    var pos = (last[1]) ? msg.indexOf(lastSignature) : msg.lastIndexOf(lastSignature);
-    if (pos != -1) {
-        if (next[1] == last[1]) {
-            msg = msg.substring(0, pos) + nextSignature + msg.substring(pos + lastSignature.length, msg.length);
-        } else if (next[1]) {
-            msg = nextSignature + msg.substring(0, pos) + msg.substring(pos + lastSignature.length, msg.length);
+            $('last_identity').setValue(id);
+            window.status = IMP.text.compose_sigreplace;
         } else {
-            msg = msg.substring(0, pos) + msg.substring(pos + lastSignature.length, msg.length) + nextSignature;
+            window.status = IMP.text.compose_signotreplace;
         }
 
-        msg = msg.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
-
-        $('last_identity').setValue(id);
-        window.status = IMP.text.compose_sigreplace;
-    } else {
-        window.status = IMP.text.compose_signotreplace;
-    }
+        if (this.rtemode) {
+            ed.SetHTML(msg);
+        } else {
+            $('message').setValue(msg);
+        }
 
-    if (rtemode) {
-        ed.SetHTML(msg);
-    } else {
-        $('message').setValue(msg);
-    }
 
-    var smf = $('sent_mail_folder');
-    if (smf_check) {
-        var i = 0;
-        $A(smf.options).detect(function(f) {
-            if (f.value == next[2]) {
-                smf.selectedIndex = i;
-                return true;
-            }
-            ++i;
-        });
-    } else {
-        if (smf.firstChild) {
-            smf.replaceChild(document.createTextNode(next[2]), smf.firstChild);
+        if (this.smf_check) {
+            $A(smf.options).detect(function(f) {
+                if (f.value == next[2]) {
+                    smf.selectedIndex = i;
+                    return true;
+                }
+                ++i;
+            });
         } else {
-            smf.appendChild(document.createTextNode(next[2]));
+            if (smf.firstChild) {
+                smf.replaceChild(document.createTextNode(next[2]), smf.firstChild);
+            } else {
+                smf.appendChild(document.createTextNode(next[2]));
+            }
         }
-    }
 
-    var save = $('ssm');
-    if (save) {
-        save.checked = next[3];
-    }
-    var bcc = $('bcc');
-    if (bcc) {
-        bccval = bcc.value;
-
-        if (last[4]) {
-            var re = new RegExp(last[4] + ",? ?", 'gi');
-            bccval = bccval.replace(re, "");
-            if (bccval) {
-                bccval = bccval.replace(/, ?$/, "");
-            }
+        if (save) {
+            save.checked = next[3];
         }
+        if (bcc) {
+            bccval = bcc.value;
+
+            if (last[4]) {
+                re = new RegExp(last[4] + ",? ?", 'gi');
+                bccval = bccval.replace(re, "");
+                if (bccval) {
+                    bccval = bccval.replace(/, ?$/, "");
+                }
+            }
 
-        if (next[4]) {
-            if (bccval) {
-                bccval += ', ';
+            if (next[4]) {
+                if (bccval) {
+                    bccval += ', ';
+                }
+                bccval += next[4];
             }
-            bccval += next[4];
+
+            bcc.setValue(bccval);
         }
+    },
 
-        bcc.setValue(bccval);
-    }
-}
+    uniqSubmit: function(actionID, e)
+    {
+        e.stop();
 
-function uniqSubmit(actionID, event)
-{
-    if (event) {
-        Event.extend(event);
-        event.stop();
-    }
+        if (actionID == 'redirect') {
+            if ($F('to') == '') {
+                alert(IMP.text.compose_recipient);
+                $('to').focus();
+            } else {
+                // Ticket #6727; this breaks on WebKit w/FCKeditor.
+                if (!Prototype.Browser.WebKit) {
+                    $('redirect').setStyle({ cursor: 'wait' });
+                }
+                this.display_unload_warning = false;
+            }
 
-    if (actionID == 'send_message') {
-        if (($F('subject') == '') &&
-            !window.confirm(IMP.text.compose_nosubject)) {
             return;
         }
 
-        if (compose_spellcheck &&
-            IMP.SpellCheckerObject &&
-            !IMP.SpellCheckerObject.isActive()) {
-            IMP.SpellCheckerObject.spellCheck();
-            return;
+        if (actionID == 'send_message') {
+            if (($F('subject') == '') &&
+                !window.confirm(IMP.text.compose_nosubject)) {
+                return;
+            }
+
+            if (this.spellcheck &&
+                IMP.SpellCheckerObject &&
+                !IMP.SpellCheckerObject.isActive()) {
+                IMP.SpellCheckerObject.spellCheck();
+                return;
+            }
         }
-    }
 
-    if (IMP.SpellCheckerObject) {
-        IMP.SpellCheckerObject.resume();
-    }
+        if (IMP.SpellCheckerObject) {
+            IMP.SpellCheckerObject.resume();
+        }
 
-    // Ticket #6727; this breaks on WebKit w/FCKeditor.
-    if (!Prototype.Browser.WebKit) {
-        $('compose').setStyle({ cursor: 'wait' });
-    }
-    display_unload_warning = false;
-    $('actionID').setValue(actionID);
-    _uniqSubmit();
-}
-
-function _uniqSubmit()
-{
-    if (textarea_ready) {
-        $('compose').submit();
-    } else {
-        _uniqSubmit.defer();
-    }
-}
+        // Ticket #6727; this breaks on WebKit w/FCKeditor.
+        if (!Prototype.Browser.WebKit) {
+            $('compose').setStyle({ cursor: 'wait' });
+        }
 
-function attachmentChanged()
-{
-    var fields = [], usedFields = 0;
+        this.display_unload_warning = false;
+        $('actionID').setValue(actionID);
+        this._uniqSubmit();
+    },
 
-    $('upload_atc').select('input[type="file"]').each(function(i) {
-        fields[fields.length] = i;
-    });
+    _uniqSubmit: function()
+    {
+        if (this.textarea_ready) {
+            $('compose').submit();
+        } else {
+            this._uniqSubmit.defer();
+        }
+    },
 
-    if (max_attachments !== null &&
-        fields.length == max_attachments) {
-        return;
-    }
+    attachmentChanged: function()
+    {
+        var fields = [],
+            usedFields = 0,
+            lastRow, newRow, td;
 
-    fields.each(function(i) {
-        if (i.value.length > 0) {
-            usedFields++;
+        $('upload_atc').select('input[type="file"]').each(function(i) {
+            fields[fields.length] = i;
+        });
+
+        if (this.max_attachments !== null &&
+            fields.length == this.max_attachments) {
+            return;
         }
-    });
 
-    if (usedFields == fields.length) {
-        var lastRow = $('attachment_row_' + usedFields);
-        if (lastRow) {
-            var td = new Element('TD', { align: 'left' }).insert(new Element('STRONG').insert(IMP.text.compose_file + ' ' + (usedFields + 1) + ':')).insert('&nbsp;')
+        fields.each(function(i) {
+            if (i.value.length > 0) {
+                usedFields++;
+            }
+        });
 
-            var file = new Element('INPUT', { type: 'file', name: 'upload_' + (usedFields + 1), size: 25 });
-            file.observe('change', attachmentChanged);
-            td.insert(file);
+        if (usedFields == fields.length) {
+            lastRow = $('attachment_row_' + usedFields);
+            if (lastRow) {
+                td = new Element('TD', { align: 'left' }).insert(new Element('STRONG').insert(IMP.text.compose_file + ' ' + (usedFields + 1) + ':')).insert('&nbsp;')
 
-            var newRow = new Element('TR', { id: 'attachment_row_' + (usedFields + 1) }).insert(td);
+                td.insert(new Element('INPUT', { type: 'file', name: 'upload_' + (usedFields + 1), size: 25 }));
 
-            lastRow.parentNode.insertBefore(newRow, lastRow.nextSibling);
+                newRow = new Element('TR', { id: 'attachment_row_' + (usedFields + 1) }).insert(td);
+
+                lastRow.parentNode.insertBefore(newRow, lastRow.nextSibling);
+            }
         }
-    }
-}
-
-function initializeSpellChecker()
-{
-    if (typeof IMP.SpellCheckerObject != 'object') {
-        // If we fired before the onload that initializes the
-        // spellcheck, wait.
-        initializeSpellChecker.defer();
-        return;
-    }
+    },
+
+    initializeSpellChecker: function()
+    {
+        if (typeof IMP.SpellCheckerObject != 'object') {
+            // If we fired before the onload that initializes the spellcheck,
+            // wait.
+            this.initializeSpellChecker.defer();
+            return;
+        }
+
+        IMP.SpellCheckerObject.onBeforeSpellCheck = this._beforeSpellCheck.bind(this);
+        IMP.SpellCheckerObject.onAfterSpellCheck = this._afterSpellCheck.bind(this);
+    },
 
-    IMP.SpellCheckerObject.onBeforeSpellCheck = function() {
+    _beforeSpellCheck: function()
+    {
         IMP.SpellCheckerObject.htmlAreaParent = 'messageParent';
         IMP.SpellCheckerObject.htmlArea = $('message').adjacent('iframe[id*=message]').first();
         $('message').setValue(FCKeditorAPI.GetInstance('message').GetHTML());
-        textarea_ready = false;
-    }
-    IMP.SpellCheckerObject.onAfterSpellCheck = function() {
+        this.textarea_ready = false;
+    },
+
+    _afterSpellCheck: function()
+    {
         IMP.SpellCheckerObject.htmlArea = IMP.SpellCheckerObject.htmlAreaParent = null;
         var ed = FCKeditorAPI.GetInstance('message');
         ed.SetHTML($('message').value);
-        ed.Events.AttachEvent('OnAfterSetHTML', function() { textarea_ready = true; });
-    }
-}
+        ed.Events.AttachEvent('OnAfterSetHTML', this._afterSetHTML.bind(this));
+    },
+
+    _afterSetHTML: function()
+    {
+        this.textarea_ready = true;
+    },
+
+    clickHandler: function(e)
+    {
+        var elt = e.element(), name;
+
+        if (elt.hasClassName('button')) {
+            name = elt.readAttribute('name');
+            switch (name) {
+            case 'btn_add_attachment':
+            case 'btn_redirect':
+            case 'btn_save_draft':
+            case 'btn_send_message':
+                this.uniqSubmit(name.substring(4), e);
+                break;
+
+            case 'btn_cancel_compose':
+                this.confirmCancel(e);
+                break;
+            }
+        }
+    },
 
-/**
- * Code to run on window load.
- */
-document.observe('dom:loaded', function() {
-    /* Prevent Return from sending messages - it should bring us out of
-     * autocomplete, not submit the whole form. */
-    $$('INPUT').each(function(i) {
-        /* Attach to everything but button and submit elements. */
-        if (i.type != 'submit' && i.type != 'button') {
-            i.observe('keydown', function(e) {
-                if (e.keyCode == 10 || e.keyCode == Event.KEY_RETURN) {
-                    e.stop();
-                    return false;
-                }
-            });
+    changeHandler: function(e)
+    {
+        var elt = e.element(),
+            id = elt.readAttribute('id');
+
+        switch (id) {
+        case 'identity':
+            this.changeIdentity(elt);
+            break;
+
+        case 'stationery':
+            this.uniqSubmit('change_stationery', e);
+            break;
+
+        case 'sent_mail_folder':
+            $('ssm').writeAttribute('checked', 'checked');
+            break;
+
+        default:
+            if (id.substring(0, 7) == 'upload_') {
+                this.attachmentChanged();
+            }
+            break;
         }
-    });
+    },
+
+    onDomLoad: function()
+    {
+        /* Prevent Return from sending messages - it should bring us out of
+         * autocomplete, not submit the whole form. */
+        $$('INPUT').each(function(i) {
+            /* Attach to everything but button and submit elements. */
+            if (i.type != 'submit' && i.type != 'button') {
+                i.observe('keydown', function(e) {
+                    if (e.keyCode == 10 || e.keyCode == Event.KEY_RETURN) {
+                        e.stop();
+                        return false;
+                    }
+                });
+            }
+        });
 
-    if (cursor_pos !== null && $('message')) {
-        setCursorPosition($('message'), cursor_pos);
-    }
+        if (this.cursor_pos !== null && $('message')) {
+            this.setCursorPosition($('message'), this.cursor_pos);
+        }
+
+        if (this.redirect) {
+            $('to').focus();
+        } else {
+            if (Prototype.Browser.IE) {
+                $('subject').observe('keydown', function(e) {
+                    if (e.keyCode == Event.KEY_TAB && !e.shiftKey) {
+                        e.stop();
+                        $('message').focus();
+                    }
+                });
+            }
+
+            if (this.rtemode) {
+                this.initializeSpellChecker();
+            }
 
-    if (redirect) {
-        $('to').focus();
-    } else {
-        if (Prototype.Browser.IE) {
-            $('subject').observe('keydown', function(e) {
-                if (e.keyCode == Event.KEY_TAB && !e.shiftKey) {
-                    e.stop();
+            if ($('to') && !$F('to')) {
+                $('to').focus();
+            } else if (!$F('subject')) {
+                if (this.rtemode) {
+                    $('subject').focus();
+                } else {
                     $('message').focus();
                 }
-            });
+            }
         }
+    },
 
-        if (rtemode) {
-            initializeSpellChecker();
-        }
+    onLoad: function()
+    {
+        var d, e = this.redirect ? $('redirect') : $('compose');
 
-        if ($('to') && !$F('to')) {
-            $('to').focus();
-        } else if (!$F('subject')) {
-            if (rtemode) {
-                $('subject').focus();
-            } else {
-                $('message').focus();
+        if (this.popup && !this.reloaded) {
+            d = Math.min(e.getHeight(), screen.height - 100) - document.viewport.getHeight();
+            if (d > 0) {
+                window.resizeBy(0, d);
             }
         }
-    }
-});
-
-Event.observe(window, 'load', function() {
-    if (compose_popup && !reloaded) {
-        var d, e = redirect ? $('redirect') : $('compose');
-        d = Math.min(e.getHeight(), screen.height - 100) - document.viewport.getHeight();
-        if (d > 0) {
-            window.resizeBy(0, d);
+
+        document.observe('click', this.clickHandler.bindAsEventListener(this));
+        document.observe('change', this.changeHandler.bindAsEventListener(this));
+    },
+
+    onBeforeUnload: function()
+    {
+        if (this.display_unload_warning) {
+            return IMP.text.compose_discard;
         }
     }
-});
 
-/**
- * Warn before closing the window.
- */
-Event.observe(window, 'beforeunload', function() {
-    if (display_unload_warning) {
-        return IMP.text.compose_discard;
-    }
-});
+};
+
+/* Code to run on window load. */
+document.observe('dom:loaded', ImpCompose.onDomLoad.bind(ImpCompose));
+Event.observe(window, 'load', ImpCompose.onLoad.bind(ImpCompose));
+
+/* Warn before closing the window. */
+Event.observe(window, 'beforeunload', ImpCompose.onBeforeUnload.bind(ImpCompose));
index c563072..c75b53d 100644 (file)
   <td>&nbsp;</td>
   <td class="nowrap">
 <if:allow_compose>
-   <input name="btn_send_message" type="submit" <tag:send_msg_ak /> class="button" onclick="return uniqSubmit('send_message', event);" value="<gettext>Send Message</gettext>" />
+   <input name="btn_send_message" type="submit" <tag:send_msg_ak /> class="button" value="<gettext>Send Message</gettext>" />
 </if:allow_compose>
 <if:save_draft_ak>
-   <input name="btn_save_draft" type="submit" <tag:save_draft_ak /> class="button" onclick="uniqSubmit('save_draft', event);" value="<gettext>Save Draft</gettext>" />
+   <input name="btn_save_draft" type="submit" <tag:save_draft_ak /> class="button" value="<gettext>Save Draft</gettext>" />
 </if:save_draft_ak>
-   <input name="btn_cancel_compose" type="submit" title="<gettext>Cancel Message</gettext>" class="button" onclick="return confirmCancel(event);" value="<gettext>Cancel Message</gettext>" />
+   <input name="btn_cancel_compose" type="submit" title="<gettext>Cancel Message</gettext>" class="button" value="<gettext>Cancel Message</gettext>" />
   </td>
   <td class="rightAlign"><tag:help_buttons />&nbsp;</td>
  </tr>
@@ -37,7 +37,7 @@
 <else:di_locked>
    <input type="hidden" id="last_identity" name="last_identity" value="<tag:last_identity />" />
 <if:count_select_list>
-   <select id="identity" name="identity" tabindex="<tag:selectlist_tabindex />" onchange="change_identity(this.selectedIndex)">
+   <select id="identity" name="identity" tabindex="<tag:selectlist_tabindex />">
 <loop:select_list>
     <option value="<tag:select_list.value />" <if:select_list.selected>selected="selected" </if:select_list.selected>><tag:select_list.label /></option>
 </loop:select_list>
  <tr>
   <td class="light rightAlign" valign="middle"><strong><tag:stationery_label />&nbsp;</strong></td>
   <td class="item" colspan="2">
-   <select name="stationery" id="stationery" onchange="uniqSubmit('change_stationery', event);">
+   <select name="stationery" id="stationery">
     <option value=""><gettext>Select stationery:</gettext></option>
 <loop:stationeries>
     <option value="<tag:stationeries.val />" <if:stationeries.selected>selected="selected" </if:stationeries.selected>><tag:stationeries.label /></option>
    <input id="ssm" type="checkbox" class="checkbox" name="save_sent_mail" <if:ssm_selected>checked="checked" </if:ssm_selected>/>
    <tag:ssm_label />
 <if:ssm_folders>
-   <select onchange="$('ssm').checked='checked'" tabindex="<tag:ssm_tabindex />" id="sent_mail_folder" name="sent_mail_folder"><tag:ssm_folders /></select>
+   <select tabindex="<tag:ssm_tabindex />" id="sent_mail_folder" name="sent_mail_folder"><tag:ssm_folders /></select>
 <else:ssm_folders>
    <span id="sent_mail_folder"><tag:ssm_folder /></span>
 </else:ssm_folders></if:ssm_folders>
   <td>&nbsp;</td>
   <td class="nowrap">
 <if:allow_compose>
-   <input name="btn_send_message" type="submit" <tag:send_msg_ak /> class="button" onclick="return uniqSubmit('send_message', event);" value="<gettext>Send Message</gettext>" />
+   <input name="btn_send_message" type="submit" <tag:send_msg_ak /> class="button" value="<gettext>Send Message</gettext>" />
 </if:allow_compose>
 <if:save_draft_ak>
-   <input name="btn_save_draft" type="submit" <tag:save_draft_ak /> class="button" onclick="uniqSubmit('save_draft', event);" value="<gettext>Save Draft</gettext>" />
+   <input name="btn_save_draft" type="submit" <tag:save_draft_ak /> class="button" value="<gettext>Save Draft</gettext>" />
 </if:save_draft_ak>
-   <input name="btn_cancel_compose" type="submit" title="<gettext>Cancel Message</gettext>" class="button" onclick="return confirmCancel(event);" value="<gettext>Cancel Message</gettext>" />
+   <input name="btn_cancel_compose" type="submit" title="<gettext>Cancel Message</gettext>" class="button" value="<gettext>Cancel Message</gettext>" />
   </td>
   <td class="rightAlign"><tag:help_buttons />&nbsp;</td>
  </tr>
    <table>
     <tr id="attachment_row_1">
      <td>
-      <strong><label for="upload_1"><gettext>File</gettext> 1:</label></strong> <input id="upload_1" name="upload_1" tabindex="<tag:file_tabindex />" type="file" onchange="attachmentChanged()" size="25" />
+      <strong><label for="upload_1"><gettext>File</gettext> 1:</label></strong> <input id="upload_1" name="upload_1" tabindex="<tag:file_tabindex />" type="file" size="25" />
      </td>
     </tr>
     <tr>
 </else:maxattachmentnumber></if:maxattachmentnumber>
 </else:maxattachsize></if:maxattachsize>
   <td class="rightAlign">
-   <input type="submit" name="btn_add_attachment" class="button" onclick="uniqSubmit('add_attachment', event);" value="<gettext>Update</gettext>" />
+   <input type="submit" name="btn_add_attachment" class="button" value="<gettext>Update</gettext>" />
    &nbsp;<tag:help-attachments />
   </td>
  </tr>
index 2f6119c..2e3aad1 100644 (file)
@@ -81,9 +81,9 @@
   <td>&nbsp;</td>
   <td>
 <if:allow_compose>
-   <input name="submitBtn" type="submit" class="button" onclick="return redirectSubmit(event);" value="<gettext>Redirect Message</gettext>" />
+   <input name="btn_redirect" type="submit" class="button" value="<gettext>Redirect Message</gettext>" />
 </if:allow_compose>
-   <input name="cancelBtn" type="button" class="button" onclick="return confirmCancel(event);" value="<gettext>Cancel Message</gettext>" />
+   <input name="btn_cancel_compose" type="button" class="button" value="<gettext>Cancel Message</gettext>" />
   </td>
  </tr>
 </table>