Skip to content

/ Zope / gocept svn checkins / Archive / 2008 / 2008-09 / SVN: r6667 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript

[ << ] [ >> ]

[ SVN: r6656 - in gocept.infrastructure/testing/pupp... ] [ SVN: r6670 - in gocept.recipe.updatercd: . trunk ... ]

SVN: r6667 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript
Thomas Lotze <tl(at)gocept.com>
2008-09-22 16:02:33 [ FULL ]
Author: thomas
Date: Mon Sep 22 16:02:31 2008
New Revision: 6667

Log:
implemented splitting the HTML structure when pressing 'return' inside a block
quote


Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Mon
Sep 22 16:02:31 2008
(at)(at) -49,6 +49,18 (at)(at)
         this.editor.on('editorContentLoaded', function() {
             document.App.onAJAXFinish();
         });
+        this.editor.on('beforeNodeChange', function() {
+                var textarea = document.getElementById('textarea'); // XXX
+            textarea.value = othis.editor.getEditorHTML();
+        });
+        this.editor.on('editorKeyPress', function(event) {
+            if (event.ev.keyCode != 13) {
+                return;
+            }
+            if (othis.splitBlockQuote()) {
+                event.ev.preventDefault();
+            }
+        });
         this.editor.render();
     };
 
(at)(at) -60,14 +72,16 (at)(at)
   <div id="composeAddr-{count}">
     <span>
       <label for="composeTo-{count}">To:</label>
-      <input type="text" name="composeTo" id="composeTo-{count}">
+      <input type="text" name="composeTo" id="composeTo-{count}"/>
     </span>
     <span>
       <label for="composeSubject-{count}">Subject:</label>
-      <input type="text" name="composeSubject"
id="composeSubject-{count}">
+      <input type="text" name="composeSubject"
id="composeSubject-{count}"/>
     </span>
   </div>
-</div>]]></r>).toString();
+</div>
+<textarea id="textarea" cols="100", rows="25"></textarea>
+]]></r>).toString();
         
 
     Composer.prototype = {
(at)(at) -77,6 +91,44 (at)(at)
             var toolbar = this.editor.toolbar;
             toolbar.title
         },
+
+        splitBlockQuote: function() {
+            var dom_path = this.editor._getDomPath();
+            var found = false;
+            for (var index in dom_path) {
+                var node = dom_path[index];
+                if (node.nodeName == 'BLOCKQUOTE') {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                return false;
+            }
+            var doc = this.editor._getDoc();
+            var range = this.editor._getRange();
+            var left = range.startContainer;
+            var offset = range.startOffset;
+            var right = doc.createTextNode(left.nodeValue.substr(offset))
+            left.nodeValue = left.nodeValue.substr(0, offset)
+            left_parent = left.parentNode;
+            while (left_parent !== doc.body) {
+                var right_parent = left_parent.cloneNode(false);
+                right_parent.appendChild(right);
+                while (left.nextSibling != null) {
+                    right_parent.appendChild(left.nextSibling);
+                }
+                left = left_parent;
+                right = right_parent;
+                left_parent = left.parentNode;
+            }
+            if (left.nextSibling == null) {
+                left_parent.appendChild(right);
+            } else {
+                left_parent.insertBefore(right, left.nextSibling);
+            }
+            return true;
+        },
     }
 
 }());

SVN: r6668 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript
Christian Zagrodnick <cz(at)gocept.com>
2008-09-23 09:40:31 [ FULL ]
Author: zagy
Date: Tue Sep 23 09:40:29 2008
New Revision: 6668

Log:
korrektes positionieren des cursors


Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Tue
Sep 23 09:40:29 2008
(at)(at) -58,7 +58,7 (at)(at)
                 return;
             }
             if (othis.splitBlockQuote()) {
-                event.ev.preventDefault();
+                YAHOO.util.Event.stopEvent(event.ev);
             }
         });
         this.editor.render();
(at)(at) -80,7 +80,7 (at)(at)
     </span>
   </div>
 </div>
-<textarea id="textarea" cols="100", rows="25"></textarea>
+<textarea id="textarea" cols="100", rows="10"></textarea>
 ]]></r>).toString();
         
 
(at)(at) -127,6 +127,9 (at)(at)
             } else {
                 left_parent.insertBefore(right, left.nextSibling);
             }
+            var textnode = left_parent.insertBefore(
+                doc.createTextNode(''), right);
+            this.editor._selectNode(textnode);
             return true;
         },
     }

SVN: r6669 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript skins/cmfwebmail_styles
Christian Zagrodnick <cz(at)gocept.com>
2008-09-23 13:52:07 [ FULL ]
Author: zagy
Date: Tue Sep 23 13:52:05 2008
New Revision: 6669

Log:
test des quotings


Added:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/editor.css
Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.js
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js

Modified: CMFWebmail/trunk/products/CMFWebmail/README.js
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.js	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.js	Tue Sep 23 13:52:05 2008
(at)(at) -28,8 +28,39 (at)(at)
         content.document, null, XPathResult.ANY_TYPE, null).stringValue;
 }
 
+function get_editor_iframe(iframe_id) {
+    return content.document.getElementById(iframe_id + '_editor');
+}
+
+function get_editor_value(iframe_id) {
+    var iframe = get_editor_iframe(iframe_id);
+    return iframe.contentWindow.document.body.innerHTML
+}
+
 function set_editor_value(iframe_id, html) {
-    var iframe = content.document.getElementById(iframe_id + '_editor');
+    var iframe = get_editor_iframe(iframe_id);
     iframe.contentWindow.document.body.innerHTML = html;
 }
 
+function set_editor_cursor_position_and_press_return(iframe_id) {
+    var win = get_editor_iframe(iframe_id).contentWindow;
+    var doc = win.document;
+    var app = content.document.wrappedJSObject.App;
+    var text_node = doc.evaluate(
+        "blockquote/blockquote",
+        doc.body, null, XPathResult.ANY_TYPE, null).iterateNext().firstChild;
+    var editor = app.tabs.getTab(2).content_provider.editor;
+    var selection = editor._getSelection();
+    var range = editor._getRange();
+    selection.removeAllRanges();
+    range.setStart(text_node, 7);
+    range.setEnd(text_node, 7);
+    selection.addRange(range);
+    
+    // press return
+    var event = doc.createEvent('KeyEvents');
+    event.initKeyEvent('keypress', true, true, window, false, false, false,
+        false, 13, 0 );
+    text_node.dispatchEvent(event);
+}
+

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Tue Sep 23 13:52:05 2008
(at)(at) -149,6 +149,46 (at)(at)
 </ul>
 ...
 
+
+Replying to a message
+=====================
+
+Replying to a message works by clicking the Reply menu item. Currently the
+editor is filled with a static text:
+
+>>> browser.getLink('Reply').click()
+>>> wait_for_page_load('Schmerz')
+>>> print_html(browser.js.get_editor_value('composeBody-1'))
+<div>
+<p>Am xyz schrieb jemand:
+</p>
+<blockquote>
+   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
+   nur, weil er <blockquote>Schmerz ist</blockquote>, es sei denn,
es kommt
+   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
+</blockquote>
+</div>
+
+When the cursor is positioned in a quoted area, pressing enter results in the
+quoting being split:
+
+>>>
browser.js.set_editor_cursor_position_and_press_return('composeBody-1');
+>>> print_html(browser.js.get_editor_value('composeBody-1'))
+<div>
+<p>Am xyz schrieb jemand:
+</p>
+<blockquote>
+   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
+   nur, weil er <blockquote>Schmerz</blockquote>
+</blockquote>
+<blockquote>
+<blockquote> ist</blockquote>, es sei denn, es kommt
+   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
+</blockquote>
+</div>
+
+
+
 .. [#setup] To test the JavaScript stuff we will need a testbrowser, which has
     access to a firefox webbrowser:
 

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Tue
Sep 23 13:52:05 2008
(at)(at) -9,6 +9,11 (at)(at)
             new YAHOO.gocept.webmailer.Composer();
         });
     });
+    YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
+        document.App.menu.addMenuItem('Reply', function() {
+            new YAHOO.gocept.webmailer.Composer('url-to-mail');
+        });
+    });
 
 }());
 
(at)(at) -16,10 +21,12 (at)(at)
 
     // The composer
 
-    YAHOO.gocept.webmailer.Composer = function() {
+    YAHOO.gocept.webmailer.Composer = function(url_to_mail) {
+        this.url_to_mail = url_to_mail;
+
         document.App.onAJAXBegin();
         var othis = this;
-        this.composer_tab = document.App.addTab('Compose')
+        this.composer_tab = document.App.addTab('Compose', this)
 
         this.editor_counter = editor_id_counter;
         editor_id_counter += 1;
(at)(at) -36,14 +43,7 (at)(at)
         this.editor = new YAHOO.widget.Editor(this.textarea.id, {
             height: '300px',
             width: '522px',
-            
-            buttons: [
-                {
-                    type: 'push',
-                    label: 'My Button 3',
-                    value: 'mybutton3',
-                    disabled: false
-                }]
+            css: '(at)import url(editor.css);',
         });
         this.editor._defaultToolbar.titlebar = false; 
         this.editor.on('editorContentLoaded', function() {
(at)(at) -61,6 +61,7 (at)(at)
                 YAHOO.util.Event.stopEvent(event.ev);
             }
         });
+        this.initialize_contents();
         this.editor.render();
     };
 
(at)(at) -87,11 +88,6 (at)(at)
     Composer.prototype = {
         constructor: Composer,
 
-        configureEditor: function() {
-            var toolbar = this.editor.toolbar;
-            toolbar.title
-        },
-
         splitBlockQuote: function() {
             var dom_path = this.editor._getDomPath();
             var found = false;
(at)(at) -132,6 +128,23 (at)(at)
             this.editor._selectNode(textnode);
             return true;
         },
+
+        initialize_contents: function() {
+            if (!this.url_to_mail) {
+                // new message, do nothing for now.
+                return
+            }
+            // get quoted messsage contents
+            this.textarea.value = (<r><![CDATA[
+Am xyz schrieb jemand:
+<blockquote>
+   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
+   nur, weil er <blockquote>Schmerz ist</blockquote>, es sei denn,
es kommt
+   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
+</blockquote>
+
+]]></r>).toString();
+        },
     }
 
 }());

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Tue
Sep 23 13:52:05 2008
(at)(at) -72,13 +72,14 (at)(at)
             this.layout.render();
         },
 
-        addTab: function(label) {
+        addTab: function(label, content_provider) {
             var tab = new YAHOO.widget.Tab({
                 label: label,
                 content: '',
                 active: true});
             this.tabs.addTab(tab);
             this.resizeAll();
+            tab.content_provider = content_provider;
             return tab;
         },
 

Added: CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/editor.css
==============================================================================
--- (empty file)
+++ CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/editor.css	Tue
Sep 23 13:52:05 2008
(at)(at) -0,0 +1,8 (at)(at)
+blockquote {
+    margin-left: 0.3em;
+    padding-left: 0.3em;
+    border-left: 2px solid blue;
+}
+blockquote > blockquote {
+    border-left: 2px solid green;
+}

SVN: r6678 - CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript
Sebastian Wehrmann <sw(at)gocept.com>
2008-09-24 13:10:33 [ FULL ]
Author: sweh
Date: Wed Sep 24 13:10:31 2008
New Revision: 6678

Log:
snapshot



Modified:
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Wed
Sep 24 13:10:31 2008
(at)(at) -6,8 +6,18 (at)(at)
 
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('New message', function() {
-            new YAHOO.gocept.webmailer.Composer();
-        });
+            // create new message for editing on the server
+            document.App.onAJAXBegin();
+
+            var new_message_created = {
+                success: function(result) {
+                    var message = YAHOO.lang.JSON.parse(result.responseText);
+                    new YAHOO.gocept.webmailer.Composer(message['url']);
+                }
+            }
+            var connectionObject = YAHOO.util.Connect.asyncRequest(
+                'GET', '(at)(at)new_draft', new_message_created);
+            });
     });
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('Reply', function() {
(at)(at) -21,8 +31,8 (at)(at)
 
     // The composer
 
-    YAHOO.gocept.webmailer.Composer = function(url_to_mail) {
-        this.url_to_mail = url_to_mail;
+    YAHOO.gocept.webmailer.Composer = function(url_to_draft) {
+        this.url_to_draft = url_to_draft;
 
         document.App.onAJAXBegin();
         var othis = this;
(at)(at) -35,12 +45,14 (at)(at)
         content.innerHTML = editor_html.replace(
             /{count}/g, this.editor_counter);
         
-        this.textarea = content.appendChild(
-            document.createElement('textarea'));
-        this.textarea.id = 'composeBody-' + this.editor_counter;
-        this.textarea.name = 'composeBody';
+        // Bind form controls to variables on the composer object.
+        this.to = document.getElementById('composeTo-' + this.editor_counter);
+        this.subject = document.getElementById(
+            'composeSubject-' + this.editor_counter);
+        this.body = document.getElementById(
+            'composeBody-' + this.editor_counter);
 
-        this.editor = new YAHOO.widget.Editor(this.textarea.id, {
+        this.editor = new YAHOO.widget.Editor(this.body.id, {
             height: '300px',
             width: '522px',
             css: '(at)import url(editor.css);',
(at)(at) -49,10 +61,6 (at)(at)
         this.editor.on('editorContentLoaded', function() {
             document.App.onAJAXFinish();
         });
-        this.editor.on('beforeNodeChange', function() {
-                var textarea = document.getElementById('textarea'); // XXX
-            textarea.value = othis.editor.getEditorHTML();
-        });
         this.editor.on('editorKeyPress', function(event) {
             if (event.ev.keyCode != 13) {
                 return;
(at)(at) -81,7 +89,8 (at)(at)
     </span>
   </div>
 </div>
-<textarea id="textarea" cols="100", rows="10"></textarea>
+<textarea id="composeBody-{count}" name="composeBody"
+          cols="100" rows="10"></textarea>
 ]]></r>).toString();
         
 
(at)(at) -130,20 +139,17 (at)(at)
         },
 
         initialize_contents: function() {
-            if (!this.url_to_mail) {
-                // new message, do nothing for now.
-                return
-            }
-            // get quoted messsage contents
-            this.textarea.value = (<r><![CDATA[
-Am xyz schrieb jemand:
-<blockquote>
-   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
-   nur, weil er <blockquote>Schmerz ist</blockquote>, es sei denn,
es kommt
-   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
-</blockquote>
-
-]]></r>).toString();
+            var editor = this;
+            var draft_content_returned = {
+                success: function(result) {
+                    var draft = YAHOO.lang.JSON.parse(result.responseText);
+                    editor.to.value = draft['to'];
+                    editor.subject.value = draft['subject'];
+                    editor.body.value = draft['body'];
+                }
+            }
+//            var connectionObject = YAHOO.util.Connect.asyncRequest(
+//                'GET', this.url_to_draft + '/(at)(at)data',
draft_content_returned);
         },
     }
 

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Wed
Sep 24 13:10:31 2008
(at)(at) -36,7 +36,7 (at)(at)
           fullpath: app_base_url + 'composer.js'});
       loader.require(['reset-fonts-grids', 'logger', 'button', 'container',
                       'tabview', 'selector', 'resize', 'layout', 'treeview',
-                      'datatable', 'menu', 'editor',
+                      'datatable', 'menu', 'editor', 'json',
                       'webmail-messages', 'webmail-composer']);
       loader.insert();

SVN: r6680 - in CMFWebmail/branches/composer_refactoring: . products/CMFWebmail/skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-24 14:51:10 [ FULL ]
Author: ctheune
Date: Wed Sep 24 14:51:08 2008
New Revision: 6680

Log:
- Refactor AJAX request tracking and calling in a more readable and manageable
  fashion.
- Load draft message content into editor.



Modified:
   CMFWebmail/branches/composer_refactoring/   (props changed)
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Wed
Sep 24 14:51:08 2008
(at)(at) -1,81 +1,47 (at)(at)
-// Compose new messages
-
-
-
+//
+// The composer for editing draft messages.
+// 
+// A composer is loaded with a draft message given as a URL and loads that
+// messages data.
+//
+// Two menu items correlate:
+// - Writing a new message creates a new draft and loads the editor with it.
+// - Replying to a message creates a draft from an existing message and loads
+//   the editor with that draft.
+
+//
+// Set up menu items
+//
 (function() {
-
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('New message', function() {
-            // create new message for editing on the server
-            document.App.onAJAXBegin();
-
-            var new_message_created = {
-                success: function(result) {
-                    var message = YAHOO.lang.JSON.parse(result.responseText);
-                    new YAHOO.gocept.webmailer.Composer(message['url']);
-                }
-            }
-            var connectionObject = YAHOO.util.Connect.asyncRequest(
-                'GET', '(at)(at)new_draft', new_message_created);
+            document.App.request('(at)(at)new_draft', function(result) {
+                var message = YAHOO.lang.JSON.parse(result.responseText);
+                new YAHOO.gocept.webmailer.Composer(message['url']);
             });
+        });
     });
+
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('Reply', function() {
             new YAHOO.gocept.webmailer.Composer('url-to-mail');
         });
     });
-
 }());
 
-(function() {
-
-    // The composer
-
-    YAHOO.gocept.webmailer.Composer = function(url_to_draft) {
-        this.url_to_draft = url_to_draft;
 
-        document.App.onAJAXBegin();
-        var othis = this;
-        this.composer_tab = document.App.addTab('Compose', this)
+//
+// The composer class
+//
+(function() {
+    // Class attributes
 
-        this.editor_counter = editor_id_counter;
-        editor_id_counter += 1;
+    // We need a running variable that counts how many composers have been
+    // instanciated.
+    var composer_counter = 0;
 
-        var content = this.composer_tab.get('contentEl')
-        content.innerHTML = editor_html.replace(
-            /{count}/g, this.editor_counter);
-        
-        // Bind form controls to variables on the composer object.
-        this.to = document.getElementById('composeTo-' + this.editor_counter);
-        this.subject = document.getElementById(
-            'composeSubject-' + this.editor_counter);
-        this.body = document.getElementById(
-            'composeBody-' + this.editor_counter);
-
-        this.editor = new YAHOO.widget.Editor(this.body.id, {
-            height: '300px',
-            width: '522px',
-            css: '(at)import url(editor.css);',
-        });
-        this.editor._defaultToolbar.titlebar = false; 
-        this.editor.on('editorContentLoaded', function() {
-            document.App.onAJAXFinish();
-        });
-        this.editor.on('editorKeyPress', function(event) {
-            if (event.ev.keyCode != 13) {
-                return;
-            }
-            if (othis.splitBlockQuote()) {
-                YAHOO.util.Event.stopEvent(event.ev);
-            }
-        });
-        this.initialize_contents();
-        this.editor.render();
-    };
-
-    var Composer = YAHOO.gocept.webmailer.Composer,
-        editor_id_counter = 0,
-        editor_html = (<r><![CDATA[
+    // An HTML "template" for the composers tab content.
+    var tab_content_template = (<r><![CDATA[
 <div id="composeBarWrap-{count}">
   <div id="composeBar-{count}"></div>
   <div id="composeAddr-{count}">
(at)(at) -89,14 +55,57 (at)(at)
     </span>
   </div>
 </div>
-<textarea id="composeBody-{count}" name="composeBody"
-          cols="100" rows="10"></textarea>
+<textarea id="composeBody-{count}" name="composeBody"></textarea>
 ]]></r>).toString();
+
+    var Composer = function(url_to_draft) {
+        var composer = this;
+    
+        composer.url_to_draft = url_to_draft;
+        // XXX We could make `addTab` store the tab property on the tabbed
+        // object directly.
+        composer.tab = document.App.addTab('Compose', composer) 
+        composer.index = composer_counter;
+        composer_counter += 1;
+
+        // Fill the tab's content area with the (raw) editor HTML and
+        // replace the composer's index.
+        tab_content = tab_content_template.replace(/{count}/g,
composer.index);
+        composer.tab.get('contentEl').innerHTML = tab_content;
         
+        // Bind form controls to variables on the composer object.
+        composer.to = document.getElementById('composeTo-'+composer.index);
+        composer.subject = document.getElementById(
+            'composeSubject-'+composer.index);
+        composer.body = document.getElementById(
+            'composeBody-'+composer.index);
+
+        // Initialize the rich text editor for the body.
+        composer.editor = new YAHOO.widget.SimpleEditor(composer.body.id);
+        composer.editor._defaultToolbar.titlebar = false; 
+        composer.editor.on('editorKeyPress', composer.handleEditorKey);
+        composer.editor.on('editorContentLoaded', function() {
+            // Load content from server.
+            composer.load_draft();
+        });
+        composer.editor.render();
+
+    };
 
     Composer.prototype = {
+        // Rebind the constructor function
         constructor: Composer,
 
+        handleEditorKey: function(event) {
+            // Handle key events relevant for the editor.
+            if (event.ev.keyCode == 13) {
+                split = this.splitBlockQuote();
+                if (split) {
+                    YAHOO.util.Event.stopEvent(event.ev);
+                };
+            };
+        },
+
         splitBlockQuote: function() {
             var dom_path = this.editor._getDomPath();
             var found = false;
(at)(at) -138,19 +147,18 (at)(at)
             return true;
         },
 
-        initialize_contents: function() {
-            var editor = this;
-            var draft_content_returned = {
-                success: function(result) {
+        load_draft: function() {
+            var composer = this;
+            document.App.request(this.url_to_draft+'/(at)(at)data',
function(result) {
                     var draft = YAHOO.lang.JSON.parse(result.responseText);
-                    editor.to.value = draft['to'];
-                    editor.subject.value = draft['subject'];
-                    editor.body.value = draft['body'];
-                }
-            }
-//            var connectionObject = YAHOO.util.Connect.asyncRequest(
-//                'GET', this.url_to_draft + '/(at)(at)data',
draft_content_returned);
+                    composer.to.value = draft['to'];
+                    composer.subject.value = draft['subject'];
+                    composer.body.value = draft['body'];
+                    composer.editor.setEditorHTML(composer.body.value);
+            });
         },
     }
 
+    // Insert the class into our namespace
+    YAHOO.gocept.webmailer.Composer = Composer;
 }());

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Wed
Sep 24 14:51:08 2008
(at)(at) -125,7 +125,23 (at)(at)
 
         onAJAXFinish: function() {
             this.ajaxInProgress -= 1;
-        }
+        },
+
+        request: function(url, on_success) {
+            var app = this;
+            app.ajaxInProgress += 1;
+
+            // Define the callback handler structure
+            var callbacks = {
+                success: function(result) {
+                    on_success(result);              
+                    app.ajaxInProgress -= 1;
+                },
+            };
+    
+            YAHOO.util.Connect.asyncRequest('GET', url, callbacks);
+        },
+
     }
 }());

SVN: r6683 - in CMFWebmail/branches/composer_refactoring: . products/CMFWebmail/skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-24 15:32:48 [ FULL ]
Author: ctheune
Date: Wed Sep 24 15:32:46 2008
New Revision: 6683

Log:
- Make text area larger again
- Wire up reply draft editing.



Modified:
   CMFWebmail/branches/composer_refactoring/   (props changed)
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
  
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/message.js

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Wed
Sep 24 15:32:46 2008
(at)(at) -24,7 +24,10 (at)(at)
 
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('Reply', function() {
-            new YAHOO.gocept.webmailer.Composer('url-to-mail');
+            document.App.request(document.App.current_mail+'/(at)(at)reply',
function(result) {
+                var message = YAHOO.lang.JSON.parse(result.responseText);
+                new YAHOO.gocept.webmailer.Composer(message['url']);
+            });
         });
     });
 }());
(at)(at) -55,7 +58,7 (at)(at)
     </span>
   </div>
 </div>
-<textarea id="composeBody-{count}" name="composeBody"></textarea>
+<textarea id="composeBody-{count}" name="composeBody" cols="100"
rows="20"></textarea>
 ]]></r>).toString();
 
     var Composer = function(url_to_draft) {

Modified:
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/message.js
==============================================================================
---
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/message.js	(original)
+++
CMFWebmail/branches/composer_refactoring/products/CMFWebmail/skins/cmfwebmail_javascript/message.js	Wed
Sep 24 15:32:46 2008
(at)(at) -1,5 +1,5 (at)(at)
 // code for message display and list
-
+//
 (function() {
 
     // Container for message list and display
(at)(at) -73,7 +73,8 (at)(at)
             dataTable.set("selectionMode","standard");
             dataTable.subscribe("rowClickEvent", dataTable.onEventSelectRow);
             dataTable.subscribe("rowSelectEvent", function(event) {
-                return othis.message_display.load(event.record.getData().url);
+                url = event.record.getData().url;
+                return othis.message_display.load(url);
                 });
             dataTable.subscribe("initEvent", document.App.onAJAXFinish,
                 document.App, true);
(at)(at) -110,6 +111,7 (at)(at)
                 this.layout_unit.body.innerHTML = (
                     oResponse.results[0]['header'] +
                     oResponse.results[0]['body']);
+                document.App.current_mail = url;
                 document.App.onAJAXFinish();
               },
               failure: function(oRequest, oResponse, oPayload) {

SVN: r6684 - in CMFWebmail/trunk: . products/CMFWebmail/skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-24 15:35:26 [ FULL ]
Author: ctheune
Date: Wed Sep 24 15:35:23 2008
New Revision: 6684

Log:
Merge the composer refactoring branch.



Modified:
   CMFWebmail/trunk/   (props changed)
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/message.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Wed
Sep 24 15:35:23 2008
(at)(at) -1,73 +1,50 (at)(at)
-// Compose new messages
-
-
-
+//
+// The composer for editing draft messages.
+// 
+// A composer is loaded with a draft message given as a URL and loads that
+// messages data.
+//
+// Two menu items correlate:
+// - Writing a new message creates a new draft and loads the editor with it.
+// - Replying to a message creates a draft from an existing message and loads
+//   the editor with that draft.
+
+//
+// Set up menu items
+//
 (function() {
-
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('New message', function() {
-            new YAHOO.gocept.webmailer.Composer();
+            document.App.request('(at)(at)new_draft', function(result) {
+                var message = YAHOO.lang.JSON.parse(result.responseText);
+                new YAHOO.gocept.webmailer.Composer(message['url']);
+            });
         });
     });
+
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('Reply', function() {
-            new YAHOO.gocept.webmailer.Composer('url-to-mail');
+            document.App.request(document.App.current_mail+'/(at)(at)reply',
function(result) {
+                var message = YAHOO.lang.JSON.parse(result.responseText);
+                new YAHOO.gocept.webmailer.Composer(message['url']);
+            });
         });
     });
-
 }());
 
-(function() {
-
-    // The composer
-
-    YAHOO.gocept.webmailer.Composer = function(url_to_mail) {
-        this.url_to_mail = url_to_mail;
 
-        document.App.onAJAXBegin();
-        var othis = this;
-        this.composer_tab = document.App.addTab('Compose', this)
-
-        this.editor_counter = editor_id_counter;
-        editor_id_counter += 1;
+//
+// The composer class
+//
+(function() {
+    // Class attributes
 
-        var content = this.composer_tab.get('contentEl')
-        content.innerHTML = editor_html.replace(
-            /{count}/g, this.editor_counter);
-        
-        this.textarea = content.appendChild(
-            document.createElement('textarea'));
-        this.textarea.id = 'composeBody-' + this.editor_counter;
-        this.textarea.name = 'composeBody';
-
-        this.editor = new YAHOO.widget.Editor(this.textarea.id, {
-            height: '300px',
-            width: '522px',
-            css: '(at)import url(editor.css);',
-        });
-        this.editor._defaultToolbar.titlebar = false; 
-        this.editor.on('editorContentLoaded', function() {
-            document.App.onAJAXFinish();
-        });
-        this.editor.on('beforeNodeChange', function() {
-                var textarea = document.getElementById('textarea'); // XXX
-            textarea.value = othis.editor.getEditorHTML();
-        });
-        this.editor.on('editorKeyPress', function(event) {
-            if (event.ev.keyCode != 13) {
-                return;
-            }
-            if (othis.splitBlockQuote()) {
-                YAHOO.util.Event.stopEvent(event.ev);
-            }
-        });
-        this.initialize_contents();
-        this.editor.render();
-    };
+    // We need a running variable that counts how many composers have been
+    // instanciated.
+    var composer_counter = 0;
 
-    var Composer = YAHOO.gocept.webmailer.Composer,
-        editor_id_counter = 0,
-        editor_html = (<r><![CDATA[
+    // An HTML "template" for the composers tab content.
+    var tab_content_template = (<r><![CDATA[
 <div id="composeBarWrap-{count}">
   <div id="composeBar-{count}"></div>
   <div id="composeAddr-{count}">
(at)(at) -81,13 +58,57 (at)(at)
     </span>
   </div>
 </div>
-<textarea id="textarea" cols="100", rows="10"></textarea>
+<textarea id="composeBody-{count}" name="composeBody" cols="100"
rows="20"></textarea>
 ]]></r>).toString();
+
+    var Composer = function(url_to_draft) {
+        var composer = this;
+    
+        composer.url_to_draft = url_to_draft;
+        // XXX We could make `addTab` store the tab property on the tabbed
+        // object directly.
+        composer.tab = document.App.addTab('Compose', composer) 
+        composer.index = composer_counter;
+        composer_counter += 1;
+
+        // Fill the tab's content area with the (raw) editor HTML and
+        // replace the composer's index.
+        tab_content = tab_content_template.replace(/{count}/g,
composer.index);
+        composer.tab.get('contentEl').innerHTML = tab_content;
         
+        // Bind form controls to variables on the composer object.
+        composer.to = document.getElementById('composeTo-'+composer.index);
+        composer.subject = document.getElementById(
+            'composeSubject-'+composer.index);
+        composer.body = document.getElementById(
+            'composeBody-'+composer.index);
+
+        // Initialize the rich text editor for the body.
+        composer.editor = new YAHOO.widget.SimpleEditor(composer.body.id);
+        composer.editor._defaultToolbar.titlebar = false; 
+        composer.editor.on('editorKeyPress', composer.handleEditorKey);
+        composer.editor.on('editorContentLoaded', function() {
+            // Load content from server.
+            composer.load_draft();
+        });
+        composer.editor.render();
+
+    };
 
     Composer.prototype = {
+        // Rebind the constructor function
         constructor: Composer,
 
+        handleEditorKey: function(event) {
+            // Handle key events relevant for the editor.
+            if (event.ev.keyCode == 13) {
+                split = this.splitBlockQuote();
+                if (split) {
+                    YAHOO.util.Event.stopEvent(event.ev);
+                };
+            };
+        },
+
         splitBlockQuote: function() {
             var dom_path = this.editor._getDomPath();
             var found = false;
(at)(at) -129,22 +150,18 (at)(at)
             return true;
         },
 
-        initialize_contents: function() {
-            if (!this.url_to_mail) {
-                // new message, do nothing for now.
-                return
-            }
-            // get quoted messsage contents
-            this.textarea.value = (<r><![CDATA[
-Am xyz schrieb jemand:
-<blockquote>
-   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
-   nur, weil er <blockquote>Schmerz ist</blockquote>, es sei denn,
es kommt
-   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
-</blockquote>
-
-]]></r>).toString();
+        load_draft: function() {
+            var composer = this;
+            document.App.request(this.url_to_draft+'/(at)(at)data',
function(result) {
+                    var draft = YAHOO.lang.JSON.parse(result.responseText);
+                    composer.to.value = draft['to'];
+                    composer.subject.value = draft['subject'];
+                    composer.body.value = draft['body'];
+                    composer.editor.setEditorHTML(composer.body.value);
+            });
         },
     }
 
+    // Insert the class into our namespace
+    YAHOO.gocept.webmailer.Composer = Composer;
 }());

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/message.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/message.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/message.js	Wed
Sep 24 15:35:23 2008
(at)(at) -1,5 +1,5 (at)(at)
 // code for message display and list
-
+//
 (function() {
 
     // Container for message list and display
(at)(at) -73,7 +73,8 (at)(at)
             dataTable.set("selectionMode","standard");
             dataTable.subscribe("rowClickEvent", dataTable.onEventSelectRow);
             dataTable.subscribe("rowSelectEvent", function(event) {
-                return othis.message_display.load(event.record.getData().url);
+                url = event.record.getData().url;
+                return othis.message_display.load(url);
                 });
             dataTable.subscribe("initEvent", document.App.onAJAXFinish,
                 document.App, true);
(at)(at) -110,6 +111,7 (at)(at)
                 this.layout_unit.body.innerHTML = (
                     oResponse.results[0]['header'] +
                     oResponse.results[0]['body']);
+                document.App.current_mail = url;
                 document.App.onAJAXFinish();
               },
               failure: function(oRequest, oResponse, oPayload) {

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Wed
Sep 24 15:35:23 2008
(at)(at) -36,7 +36,7 (at)(at)
           fullpath: app_base_url + 'composer.js'});
       loader.require(['reset-fonts-grids', 'logger', 'button', 'container',
                       'tabview', 'selector', 'resize', 'layout', 'treeview',
-                      'datatable', 'menu', 'editor',
+                      'datatable', 'menu', 'editor', 'json',
                       'webmail-messages', 'webmail-composer']);
       loader.insert();
 
(at)(at) -125,7 +125,23 (at)(at)
 
         onAJAXFinish: function() {
             this.ajaxInProgress -= 1;
-        }
+        },
+
+        request: function(url, on_success) {
+            var app = this;
+            app.ajaxInProgress += 1;
+
+            // Define the callback handler structure
+            var callbacks = {
+                success: function(result) {
+                    on_success(result);              
+                    app.ajaxInProgress -= 1;
+                },
+            };
+    
+            YAHOO.util.Connect.asyncRequest('GET', url, callbacks);
+        },
+
     }
 }());

SVN: r6686 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-24 17:50:17 [ FULL ]
Author: ctheune
Date: Wed Sep 24 17:50:14 2008
New Revision: 6686

Log:
- AJAX convenience function for get/post requests
- Menu item for `Reply`
- Implement saving message drafts
- Test refactorings



Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.js
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js

Modified: CMFWebmail/trunk/products/CMFWebmail/README.js
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.js	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.js	Wed Sep 24 17:50:14 2008
(at)(at) -3,8 +3,6 (at)(at)
 // See also LICENSE.txt
 // $Id$
 
-//var YAHOO = content.window.wrappedJSObject.YAHOO;
-
 function isAJAXInProgress() {
     var app = content.document.wrappedJSObject.App;
     if (typeof(app) == 'undefined')
(at)(at) -47,7 +45,7 (at)(at)
     var doc = win.document;
     var app = content.document.wrappedJSObject.App;
     var text_node = doc.evaluate(
-        "blockquote/blockquote",
+        "//blockquote/blockquote",
         doc.body, null, XPathResult.ANY_TYPE, null).iterateNext().firstChild;
     var editor = app.tabs.getTab(2).content_provider.editor;
     var selection = editor._getSelection();
(at)(at) -64,3 +62,27 (at)(at)
     text_node.dispatchEvent(event);
 }
 
+var monitors = new Array();
+
+// Helper to listen for events
+function monitor(node, event) {
+    var YAHOO = content.window.wrappedJSObject.YAHOO;
+
+    var Monitor = function() {
+        this.ready = false;
+        YAHOO.util.Event.addListener(node, event, function(ev) {
+            this.ready = true;
+        }, this, true);
+    };
+    var monitor = new Monitor();
+    monitors['foo'] = monitor;
+};
+
+function monitor_ready(id) {
+    return monitors['foo'].ready;
+};
+
+function set_control_value(node, value) {
+    var node = content.document.getElementById(node);
+    node.value = value;
+};

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Wed Sep 24 17:50:14 2008
(at)(at) -113,19 +113,47 (at)(at)
 
 We can compose a new message via the "new message" menu entry:
 
+>>> browser.js.monitor('body', 'click')
 >>> browser.getLink('New message').click()
->>> wait_for_page_load('New message')
+>>> time.sleep(1)
 
 Fill in the recipient and subject:
 
->>> browser.getControl('To').value = 'mailtest(at)test.gocept.com'
->>> browser.getControl('Subject').value = (
+>>> browser.js.set_control_value('composeTo-0', 'foo')
+>>> browser.js.set_control_value('composeSubject-0',
 ...    'The quick brown fox jumped over the lazy dog.')
 >>> browser.js.set_editor_value('composeBody-0',
'<p><b>blub</b></p>')
 
+We can save the draft message, while we're editing it:
 
-XXX missing: send, verify contents
+>>> browser.getControl(name='composeSave-0').click()
+>>> wait_for_page_load('Saving')
 
+Now, there is a message in the draft folder which contains the current state
+as in the composer:
+
+>>> root = getRootFolder()
+>>> draft = root['webmail']['account']['drafts'].objectValues()[0]
+>>> draft
+<DraftMessage at /webmail/account/drafts/...>
+>>> draft.to
+'foo'
+>>> draft.subject
+'The quick brown fox jumped over the lazy dog.'
+>>> draft.body
+'<p><strong>blub</strong></p>'
+
+We can keep modifying the message in the browser, subsequent `Saves` will
+update again:
+
+>>> browser.js.set_control_value('composeTo-0',
'mailothertest(at)test.gocept.com')
+>>> draft.to
+'foo'
+>>> browser.getControl(name='composeSave-0').click()
+>>> draft.to
+'mailothertest(at)test.gocept.com'
+
+XXX missing: send
 
 Let's go back to the inbox via the tab:
 
(at)(at) -153,21 +181,25 (at)(at)
 Replying to a message
 =====================
 
-Replying to a message works by clicking the Reply menu item. Currently the
-editor is filled with a static text:
+Replying to a message works by clicking the Reply menu item. 
 
 >>> browser.getLink('Reply').click()
->>> wait_for_page_load('Schmerz')
->>> print_html(browser.js.get_editor_value('composeBody-1'))
-<div>
-<p>Am xyz schrieb jemand:
-</p>
-<blockquote>
-   Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
-   nur, weil er <blockquote>Schmerz ist</blockquote>, es sei denn,
es kommt
-   zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
-</blockquote>
-</div>
+>>> time.sleep(1)
+
+Quote splitting
+---------------
+
+To demonstrate quote splitting, we fill a known text into the editor:
+
+>>> browser.js.set_editor_value('composeBody-1', """
+... <p>Am xyz schrieb jemand:
+... </p>
+... <blockquote>
+...    Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder
wuenscht,
+...    nur, weil er <blockquote>Schmerz ist</blockquote>, es sei
denn, es kommt
+...    zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
+... </blockquote>
+... """)
 
 When the cursor is positioned in a quoted area, pressing enter results in the
 quoting being split:
(at)(at) -188,7 +220,6 (at)(at)
 </div>
 
 
-
 .. [#setup] To test the JavaScript stuff we will need a testbrowser, which has
     access to a firefox webbrowser:
 
(at)(at) -213,6 +244,10 (at)(at)
     ...         time.sleep(0.001)
     ...     #print >> sys.stderr, 'end:', message
 
+    >>> def wait_for_monitor():
+    ...     while not browser.js.monitor_ready():
+    ...         print "sleeping"
+    ...         time.sleep(0.001)
 
     Define a helper function to expand/collapse entries in the mail folder
     tree:

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Wed
Sep 24 17:50:14 2008
(at)(at) -15,7 +15,7 (at)(at)
 (function() {
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('New message', function() {
-            document.App.request('(at)(at)new_draft', function(result) {
+            document.App.get('(at)(at)new_draft', function(result) {
                 var message = YAHOO.lang.JSON.parse(result.responseText);
                 new YAHOO.gocept.webmailer.Composer(message['url']);
             });
(at)(at) -24,7 +24,7 (at)(at)
 
     YAHOO.util.Event.onContentReady("webmailer-main-menu", function () { 
         document.App.menu.addMenuItem('Reply', function() {
-            document.App.request(document.App.current_mail+'/(at)(at)reply',
function(result) {
+            document.App.get(document.App.current_mail+'/(at)(at)reply',
function(result) {
                 var message = YAHOO.lang.JSON.parse(result.responseText);
                 new YAHOO.gocept.webmailer.Composer(message['url']);
             });
(at)(at) -50,15 +50,16 (at)(at)
   <div id="composeAddr-{count}">
     <span>
       <label for="composeTo-{count}">To:</label>
-      <input type="text" name="composeTo" id="composeTo-{count}"/>
+      <input type="text" name="composeTo-{count}"
id="composeTo-{count}"/>
     </span>
     <span>
       <label for="composeSubject-{count}">Subject:</label>
-      <input type="text" name="composeSubject"
id="composeSubject-{count}"/>
+      <input type="text" name="composeSubject-{count}"
id="composeSubject-{count}"/>
     </span>
   </div>
 </div>
-<textarea id="composeBody-{count}" name="composeBody" cols="100"
rows="20"></textarea>
+<textarea id="composeBody-{count}" name="composeBody-{count}" cols="100"
rows="20"></textarea>
+<input type="button" id="composeSave-{count}" name="composeSave-{count}"
value="Save"/>
 ]]></r>).toString();
 
     var Composer = function(url_to_draft) {
(at)(at) -76,23 +77,21 (at)(at)
         tab_content = tab_content_template.replace(/{count}/g,
composer.index);
         composer.tab.get('contentEl').innerHTML = tab_content;
         
-        // Bind form controls to variables on the composer object.
-        composer.to = document.getElementById('composeTo-'+composer.index);
-        composer.subject = document.getElementById(
-            'composeSubject-'+composer.index);
-        composer.body = document.getElementById(
-            'composeBody-'+composer.index);
 
         // Initialize the rich text editor for the body.
-        composer.editor = new YAHOO.widget.SimpleEditor(composer.body.id);
+        composer.editor = new
YAHOO.widget.SimpleEditor(composer.getControl('Body').id);
         composer.editor._defaultToolbar.titlebar = false; 
-        composer.editor.on('editorKeyPress', composer.handleEditorKey);
+        composer.editor.on('editorKeyPress', composer.handleEditorKey,
composer, true);
         composer.editor.on('editorContentLoaded', function() {
             // Load content from server.
             composer.load_draft();
         });
         composer.editor.render();
 
+        // Wire up save button and make sure the context correction makes
+        // `this` the composer
+        YAHOO.util.Event.addListener(
+            composer.getControl('Save'), 'click', composer.save_draft,
composer, true);
     };
 
     Composer.prototype = {
(at)(at) -152,14 +151,31 (at)(at)
 
         load_draft: function() {
             var composer = this;
-            document.App.request(this.url_to_draft+'/(at)(at)data',
function(result) {
+            document.App.get(composer.url_to_draft+'/(at)(at)data',
function(result) {
                     var draft = YAHOO.lang.JSON.parse(result.responseText);
-                    composer.to.value = draft['to'];
-                    composer.subject.value = draft['subject'];
-                    composer.body.value = draft['body'];
-                    composer.editor.setEditorHTML(composer.body.value);
+                    composer.getControl('To').value = draft['to'];
+                    composer.getControl('Subject').value = draft['subject'];
+                    composer.getControl('Body').value = draft['body'];
+                    composer.editor.setEditorHTML(draft['body']);
             });
         },
+
+        save_draft: function(ev) {
+            var composer = this;
+            // Make the editor save back to the text area.
+            composer.editor.saveHTML()
+            // Submit form
+            data =
('to='+encodeURIComponent(composer.getControl('To').value)+'&'+
+                   
'subject='+encodeURIComponent(composer.getControl('Subject').value)+'&'+
+                   
'body='+encodeURIComponent(composer.getControl('Body').value))
+            document.App.post(composer.url_to_draft+'/(at)(at)save',
+                              data)
+        },
+
+        getControl: function(name) {
+            var composer = this;
+            return document.getElementById('compose'+name+'-'+composer.index);
+        },
     }
 
     // Insert the class into our namespace

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Wed
Sep 24 17:50:14 2008
(at)(at) -127,19 +127,29 (at)(at)
             this.ajaxInProgress -= 1;
         },
 
-        request: function(url, on_success) {
+        request: function(method, url, on_success, data) {
             var app = this;
             app.ajaxInProgress += 1;
 
             // Define the callback handler structure
             var callbacks = {
                 success: function(result) {
-                    on_success(result);              
+                    if (on_success) {
+                        on_success(result);
+                    };
                     app.ajaxInProgress -= 1;
                 },
             };
     
-            YAHOO.util.Connect.asyncRequest('GET', url, callbacks);
+            YAHOO.util.Connect.asyncRequest(method, url, callbacks, data);
+        },
+
+        get: function(url, on_success) {
+            this.request('GET', url, on_success, null);
+        },
+
+        post: function(url, data, on_success) {
+            this.request('POST', url, on_success, data);
         },
 
     }

SVN: r6696 - in CMFWebmail/trunk/products/CMFWebmail/skins: cmfwebmail_javascript cmfwebmail_styles cmfwebmail_templates
Christian Theune <ct(at)gocept.com>
2008-09-25 09:35:14 [ FULL ]
Author: ctheune
Date: Thu Sep 25 09:35:13 2008
New Revision: 6696

Log:
Refactor main template a bit:
- <script> doesn't belong into the body
- our customer wants to insert their own banner at top, so switch to
  element-based layout  



Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Thu
Sep 25 09:35:13 2008
(at)(at) -57,12 +57,15 (at)(at)
 
         init: function() {
             var othis = this;
-            this.layout = new YAHOO.widget.Layout({
+            this.layout = new YAHOO.widget.Layout('webmailer',
+              {
                 units: [
-                    { position: 'top', height: 50, body: '',
-                      gutter: '10 4' },
-                    { position: 'left', width: 200, resize: true, body:
'tree'},
-                    { position: 'center', body: '' },
+                    { position: 'top',
+                          height: 50, body: '', gutter: '10 4' },
+                    { position: 'left',
+                          width: 200, resize: true, body: 'tree'},
+                    { position: 'center',
+                          body: '' },
                 ]
             });
             this.layout.on('render', function() {

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css	Thu
Sep 25 09:35:13 2008
(at)(at) -7,6 +7,11 (at)(at)
   color: #265b72;
 }
 
+#webmailer {
+  position:absolute;
+  height:80%;
+  width:80%;
+}
 
 #maillisting li {
   cursor: pointer;

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt	Thu
Sep 25 09:35:13 2008
(at)(at) -2,11 +2,10 (at)(at)
   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html>
-  <head>
-    <title>Portal</title>
-  </head>
-  <body class="yui-skin-sam" id="body"
+  <head 
     tal:define="yui_base_url context/yui/build/absolute_url">
+    <title>Portal</title>
+    
     <script type="text/javascript" tal:content="string:
       var yui_base_url = '$yui_base_url/';
       var app_base_url = '${context/portal_url}/'">
(at)(at) -17,8 +16,18 (at)(at)
     </script>
     <script type="text/javascript" src="webmail.js"
       tal:attributes="src context/webmail.js/absolute_url">
-
     </script> 
 
+    <link rel="stylesheet" type="text/css"
+        tal:attributes="href context/webmail.css/absolute_url"/>
+
+  </head>
+
+  <body class="yui-skin-sam">
+    <h2>Der TUM Webmailer</h2>
+
+    <div id="webmailer">
+    </div>
+
   </body>
 </html>

SVN: r6699 - CMFWebmail/trunk/products/CMFWebmail
Thomas Lotze <tl(at)gocept.com>
2008-09-25 10:04:28 [ FULL ]
Author: thomas
Date: Thu Sep 25 10:04:27 2008
New Revision: 6699

Log:
fixed a timing problem


Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.txt

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Thu Sep 25 10:04:27 2008
(at)(at) -200,6 +200,7 (at)(at)
 ...    zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
 ... </blockquote>
 ... """)
+>>> time.sleep(1)
 
 When the cursor is positioned in a quoted area, pressing enter results in the
 quoting being split:

SVN: r6701 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript
Thomas Lotze <tl(at)gocept.com>
2008-09-25 10:18:04 [ FULL ]
Author: thomas
Date: Thu Sep 25 10:18:03 2008
New Revision: 6701

Log:
added back editor CSS, unquote hacky HTML quoting needed for parsing JSON with
HTML strings


Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Thu
Sep 25 10:18:03 2008
(at)(at) -79,7 +79,8 (at)(at)
         
 
         // Initialize the rich text editor for the body.
-        composer.editor = new
YAHOO.widget.SimpleEditor(composer.getControl('Body').id);
+        composer.editor = new YAHOO.widget.SimpleEditor(
+            composer.getControl('Body').id, {css: '(at)import
url(editor.css);'});
         composer.editor._defaultToolbar.titlebar = false; 
         composer.editor.on('editorKeyPress', composer.handleEditorKey,
composer, true);
         composer.editor.on('editorContentLoaded', function() {
(at)(at) -155,8 +156,11 (at)(at)
                     var draft = YAHOO.lang.JSON.parse(result.responseText);
                     composer.getControl('To').value = draft['to'];
                     composer.getControl('Subject').value = draft['subject'];
-                    composer.getControl('Body').value = draft['body'];
-                    composer.editor.setEditorHTML(draft['body']);
+                    body = draft['body'];
+                    body = body.replace('%l', '<', 'g');
+                    body = body.replace('%p', '%', 'g');
+                    composer.getControl('Body').value = body;
+                    composer.editor.setEditorHTML(body);
             });
         },

SVN: r6703 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-25 10:48:52 [ FULL ]
Author: ctheune
Date: Thu Sep 25 10:48:50 2008
New Revision: 6703

Log:
Implement sending messages.



Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.js
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified: CMFWebmail/trunk/products/CMFWebmail/README.js
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.js	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.js	Thu Sep 25 10:48:50 2008
(at)(at) -47,7 +47,7 (at)(at)
     var text_node = doc.evaluate(
         "//blockquote/blockquote",
         doc.body, null, XPathResult.ANY_TYPE, null).iterateNext().firstChild;
-    var editor = app.tabs.getTab(2).content_provider.editor;
+    var editor = app.tabs.getTab(1).content_provider.editor;
     var selection = editor._getSelection();
     var range = editor._getRange();
     selection.removeAllRanges();

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Thu Sep 25 10:48:50 2008
(at)(at) -153,30 +153,31 (at)(at)
 >>> draft.to
 'mailothertest(at)test.gocept.com'
 
-XXX missing: send
+Sending the message
+-------------------
 
-Let's go back to the inbox via the tab:
-
->>> print_html(browser.contents)
-<html>
-...
-<ul class="yui-nav">
-<li title="" class=""><a
href="#"><em>Inbox</em></a></li>
-<li title="active" class="selected"><a
href="#"><em>Compose</em></a></li>
-</ul>
-...
-
->>> browser.getLink('Inbox').click()
->>> wait_for_page_load('Back to inbox')
->>> print_html(browser.contents)
-<html>
-...
-<ul class="yui-nav">
-<li title="active" class="selected"><a
href="#"><em>Inbox</em></a></li>
-<li title="" class=""><a
href="#"><em>Compose</em></a></li>
-</ul>
-...
+The message will be send, when the user presses the `Send` button. It also
+saves the message right before sending it:
 
+>>> browser.js.set_control_value('composeTo-0',
'anotherchange(at)test.gocept.com')
+>>> browser.getControl(name='composeSend-0').click()
+Content-Type: text/html; charset="us-ascii"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+From: ct(at)gocept.com
+To: anotherchange(at)test.gocept.com
+Subject: The quick brown fox jumped over the lazy dog.
+<BLANKLINE>
+<p><strong>blub</strong></p>
+
+After sending the message, the tab and the editor is gone:
+
+>>> browser.getControl(name='composeSend-0')
+Traceback (most recent call last):
+LookupError: name 'composeSend-0'
+>>> browser.getLink('Compose')
+Traceback (most recent call last):
+LinkNotFoundError
 
 Replying to a message
 =====================

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Thu
Sep 25 10:48:50 2008
(at)(at) -60,6 +60,7 (at)(at)
 </div>
 <textarea id="composeBody-{count}" name="composeBody-{count}" cols="100"
rows="20"></textarea>
 <input type="button" id="composeSave-{count}" name="composeSave-{count}"
value="Save"/>
+<input type="button" id="composeSend-{count}" name="composeSend-{count}"
value="Send"/>
 ]]></r>).toString();
 
     var Composer = function(url_to_draft) {
(at)(at) -89,10 +90,12 (at)(at)
         });
         composer.editor.render();
 
-        // Wire up save button and make sure the context correction makes
+        // Wire up the buttons and make sure the context correction makes
         // `this` the composer
         YAHOO.util.Event.addListener(
             composer.getControl('Save'), 'click', composer.save_draft,
composer, true);
+        YAHOO.util.Event.addListener(
+            composer.getControl('Send'), 'click', composer.send_message,
composer, true);
     };
 
     Composer.prototype = {
(at)(at) -164,16 +167,25 (at)(at)
             });
         },
 
-        save_draft: function(ev) {
+        _prepare_data: function() {
             var composer = this;
-            // Make the editor save back to the text area.
             composer.editor.saveHTML()
-            // Submit form
             data =
('to='+encodeURIComponent(composer.getControl('To').value)+'&'+
                    
'subject='+encodeURIComponent(composer.getControl('Subject').value)+'&'+
                    
'body='+encodeURIComponent(composer.getControl('Body').value))
-            document.App.post(composer.url_to_draft+'/(at)(at)save',
-                              data)
+            return data;
+        },
+
+        save_draft: function(ev) {
+            var composer = this;
+            document.App.post(composer.url_to_draft+'/(at)(at)save',
composer._prepare_data())
+        },
+
+        send_message: function(ev) {
+            var composer = this;
+            document.App.post(composer.url_to_draft+'/(at)(at)send',
composer._prepare_data(), function(result) {
+                document.App.tabs.removeTab(composer.tab);
+            })
         },
 
         getControl: function(name) {

SVN: r6707 - CMFWebmail/trunk/products/CMFWebmail
Thomas Lotze <tl(at)gocept.com>
2008-09-25 14:09:41 [ FULL ]
Author: thomas
Date: Thu Sep 25 14:09:40 2008
New Revision: 6707

Log:
some more sleeping to wait for asynchronous stuff


Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.txt

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Thu Sep 25 14:09:40 2008
(at)(at) -150,17 +150,18 (at)(at)
 >>> draft.to
 'foo'
 >>> browser.getControl(name='composeSave-0').click()
+>>> time.sleep(1)
 >>> draft.to
 'mailothertest(at)test.gocept.com'
 
 Sending the message
 -------------------
 
-The message will be send, when the user presses the `Send` button. It also
+The message will be sent, when the user presses the `Send` button. It also
 saves the message right before sending it:
 
 >>> browser.js.set_control_value('composeTo-0',
'anotherchange(at)test.gocept.com')
->>> browser.getControl(name='composeSend-0').click()
+>>> browser.getControl(name='composeSend-0').click();
wait_for_page_load('Sending message')
 Content-Type: text/html; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit
(at)(at) -169,7 +170,6 (at)(at)
 Subject: The quick brown fox jumped over the lazy dog.
 <BLANKLINE>
 <p><strong>blub</strong></p>
->>> wait_for_page_load('Sending message')
 
 After sending the message, the tab and the editor is gone:
 
(at)(at) -186,7 +186,7 (at)(at)
 Replying to a message works by clicking the Reply menu item. 
 
 >>> browser.getLink('Reply').click()
->>> time.sleep(1)
+>>> time.sleep(2)
 
 Quote splitting
 ---------------
(at)(at) -236,10 +236,12 (at)(at)
     >>> import os.path
     >>> browser.load_file(
     ...     os.path.join(os.path.dirname(__file__), 'README.js'))
+    >>> import time
+    >>> time.sleep(1)
 
-    We'll need a function which Waits until everything is loaded:
+    We'll need a function which waits until everything is loaded:
 
-    >>> import time, sys
+    >>> import sys
     >>> def wait_for_page_load(message):
     ...     #print >> sys.stderr, 'start:', message
     ...     while browser.js.isAJAXInProgress():

SVN: r6712 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Christian Theune <ct(at)gocept.com>
2008-09-25 16:22:25 [ FULL ]
Author: ctheune
Date: Thu Sep 25 16:22:21 2008
New Revision: 6712

Log:
Integrate identity functions and the profile feature from gocept.restmail.



Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
   CMFWebmail/trunk/products/CMFWebmail/tests.py

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Thu Sep 25 16:22:21 2008
(at)(at) -8,23 +8,33 (at)(at)
 Lets make sure that the browser can access the standard IMAP folder listing.
 Be sure that firefox with mozrepl is running[#setup]_:
 
->>> browser.open('/webmail/account/webmailer')
+>>> browser.open('/webmail/profile/webmailer')
 >>> wait_for_page_load('page load')
 >>> print browser.contents
 <!DOCTYPE ...
 
 
-Folder Navigation
+Folder navigation
 =================
 
-After the initial load of the page there should be two Folders on the page,
-the Bar and INBOX folders:
+After the initial load of the page the accounts are listed. Currently there is
+only a single account:
 
 >>> print_html(browser.contents)
 <html>
 ...
  <title>Portal</title>
- ...
+...
+...<a ...>account</a>...
+
+Expanding the account, reveals its top-level folders:
+
+>>> click_tree('account')
+>>> print_html(browser.contents)
+<html>
+...
+ <title>Portal</title>
+...
 ...<a ...>Bar</a>...
 ...<a ...>INBOX</a>...
 
(at)(at) -39,7 +49,7 (at)(at)
 >>> click_tree('INBOX')
 
 
-Now there are three Folders available:
+Now there are three folders available:
 
 >>> print browser.contents
 <!DOCTYPE html...
(at)(at) -58,7 +68,7 (at)(at)
 True
 
 
-If you click on an Folder item, you get a list auf Mails from that mailbox:
+If you click on an folder item, you get a list auf Mails from that mailbox:
 
 >>> browser.getLink('INBOX').click()
 >>> wait_for_page_load('mail list')
(at)(at) -133,9 +143,9 (at)(at)
 as in the composer:
 
 >>> root = getRootFolder()
->>> draft = root['webmail']['account']['drafts'].objectValues()[0]
+>>> draft = root['webmail']['profile']['drafts'].objectValues()[0]
 >>> draft
-<DraftMessage at /webmail/account/drafts/...>
+<DraftMessage at /webmail/profile/drafts/...>
 >>> draft.to
 'foo'
 >>> draft.subject
(at)(at) -165,7 +175,7 (at)(at)
 Content-Type: text/html; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit
-From: ct(at)gocept.com
+From: Ben Utzer <ben(at)example.com>
 To: anotherchange(at)test.gocept.com
 Subject: The quick brown fox jumped over the lazy dog.
 <BLANKLINE>

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Thu
Sep 25 16:22:21 2008
(at)(at) -47,15 +47,18 (at)(at)
     var tab_content_template = (<r><![CDATA[
 <div id="composeBarWrap-{count}">
   <div id="composeBar-{count}"></div>
+  <div id="composeIdentity-{count}">
+      From: <input type="text" id="composeFrom-{count}"
name="composeFrom-{count}" disabled value=""/>
+  </div>
   <div id="composeAddr-{count}">
-    <span>
+    <div>
       <label for="composeTo-{count}">To:</label>
       <input type="text" name="composeTo-{count}"
id="composeTo-{count}"/>
-    </span>
-    <span>
+    </div>
+    <div>
       <label for="composeSubject-{count}">Subject:</label>
       <input type="text" name="composeSubject-{count}"
id="composeSubject-{count}"/>
-    </span>
+    </div>
   </div>
 </div>
 <textarea id="composeBody-{count}" name="composeBody-{count}" cols="100"
rows="20"></textarea>
(at)(at) -77,6 +80,12 (at)(at)
         // replace the composer's index.
         tab_content = tab_content_template.replace(/{count}/g,
composer.index);
         composer.tab.get('contentEl').innerHTML = tab_content;
+
+        // Query the default identity to compose with
+        document.App.get('(at)(at)default_identity', function(result) {
+            var identity = YAHOO.lang.JSON.parse(result.responseText);
+            composer.getControl('From').value = identity['name'] + ' <' +
identity['address'] + '>';
+        });
         
 
         // Initialize the rich text editor for the body.

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Thu
Sep 25 16:22:21 2008
(at)(at) -186,10 +186,9 (at)(at)
 
 }());
 
+// The account and folder tree
 (function() {
 
-    // The tree of folders
-
     YAHOO.gocept.webmailer.Tree = function(tree_container) {
         var othis = this;
         this.tree = new YAHOO.widget.TreeView(tree_container),
(at)(at) -238,7 +237,13 (at)(at)
                 scope: this,
                 argument: encodeURI(node.label)
             }
-            var url = node.foldersUrl + "(at)(at)folders?";
+            if (node == this.tree.getRoot()) {
+                // The root node loads the list of accounts, not folders.
+                var url = "(at)(at)accounts";
+            } else {
+                var url = node.foldersUrl + "(at)(at)folders";
+            };
+
             document.App.onAJAXBegin();
             document.App.getDataSource(url, responseSchema).sendRequest(
                 '', callback);

Modified: CMFWebmail/trunk/products/CMFWebmail/tests.py
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/tests.py	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/tests.py	Thu Sep 25 16:22:21 2008
(at)(at) -35,9 +35,21 (at)(at)
     addConfiguredSite(app, 'webmail', 'CMFDefault:default',
                       extension_ids=('CMFWebmail:default', ))
     cmfsite = test.app['webmail']
-
-    # add the imap account to this site
+    
+    # Add a webmail profile to the site
     cmfsite._setObject(
+        'profile',
+        gocept.restmail.profile.Profile('profile'))
+    profile = cmfsite['profile']
+    profile.name = 'Ben Utzer'
+    profile.address = 'ben(at)example.com'
+    profile.smtp_server = 'default'
+
+    # Add mail host
+    profile.manage_addProduct['MailHost'].manage_addMailHost('default')
+
+    # And an IMAP account to the profile
+    profile._setObject(
         'account',
         gocept.restmail.imapaccount.IMAPAccount(
             'account', 'localhost', 10143, 'test', 'bsdf'))

SVN: r6714 - CMFWebmail/trunk/products/CMFWebmail
Christian Theune <ct(at)gocept.com>
2008-09-25 17:00:57 [ FULL ]
Author: ctheune
Date: Thu Sep 25 17:00:52 2008
New Revision: 6714

Log:
Change test setup to accomodate new identity structure



Modified:
   CMFWebmail/trunk/products/CMFWebmail/tests.py

Modified: CMFWebmail/trunk/products/CMFWebmail/tests.py
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/tests.py	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/tests.py	Thu Sep 25 17:00:52 2008
(at)(at) -41,12 +41,13 (at)(at)
         'profile',
         gocept.restmail.profile.Profile('profile'))
     profile = cmfsite['profile']
-    profile.name = 'Ben Utzer'
-    profile.address = 'ben(at)example.com'
-    profile.smtp_server = 'default'
+    profile['default-identity'].name = 'Ben Utzer'
+    profile['default-identity'].address = 'ben(at)example.com'
+    profile['default-identity'].smtp_server = 'default-smtp'
+    profile['default-identity'].sent_folder = 'account/+INBOX'
 
     # Add mail host
-    profile.manage_addProduct['MailHost'].manage_addMailHost('default')
+    profile.manage_addProduct['MailHost'].manage_addMailHost('default-smtp')
 
     # And an IMAP account to the profile
     profile._setObject(

SVN: r6724 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Sebastian Wehrmann <sw(at)gocept.com>
2008-09-26 15:36:53 [ FULL ]
Author: sweh
Date: Fri Sep 26 15:36:51 2008
New Revision: 6724

Log:
ability to chooes between multiple identities when composing messages
drafts message listing and re-opening of drafts
ability to close drafts




Added:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js
Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.js
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
   CMFWebmail/trunk/products/CMFWebmail/tests.py

Modified: CMFWebmail/trunk/products/CMFWebmail/README.js
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.js	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.js	Fri Sep 26 15:36:51 2008
(at)(at) -47,7 +47,7 (at)(at)
     var text_node = doc.evaluate(
         "//blockquote/blockquote",
         doc.body, null, XPathResult.ANY_TYPE, null).iterateNext().firstChild;
-    var editor = app.tabs.getTab(1).content_provider.editor;
+    var editor = app.tabs.getTab(2).content_provider.editor;
     var selection = editor._getSelection();
     var range = editor._getRange();
     selection.removeAllRanges();
(at)(at) -86,3 +86,8 (at)(at)
     var node = content.document.getElementById(node);
     node.value = value;
 };
+
+function get_control_value(node) {
+    var node = content.document.getElementById(node);
+    return node.value;
+};

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Fri Sep 26 15:36:51 2008
(at)(at) -43,7 +43,6 (at)(at)
 >>> 'Baz' in browser.contents
 False
 
-
 Expand the INBOX folder:
 
 >>> click_tree('INBOX')
(at)(at) -51,16 +50,12 (at)(at)
 
 Now there are three folders available:
 
->>> print browser.contents
-<!DOCTYPE html...
-...
-...<a ...>Bar</a>...
-...<a ...>INBOX</a>...
-...<a ...>Baz</a>...
+>>> 'Baz' in browser.contents
+True
 
 
-Displaying a Maillist
-=====================
+Displaying a list of messages
+=============================
 
 The initial page displays no mails:
 
(at)(at) -96,10 +91,8 (at)(at)
 </tr>...
 
 
-
-Displaying an email
-===================
-
+Displaying a message
+====================
 
 >>> click_listing('Mail 1')
 >>> wait_for_page_load('Show Mail 1')
(at)(at) -117,7 +110,6 (at)(at)
   ...
 
 
-
 Composing a new message
 =======================
 
(at)(at) -127,6 +119,11 (at)(at)
 >>> browser.getLink('New message').click()
 >>> time.sleep(1)
 
+The sender is pre-filled with the default identity:
+
+>>> browser.js.get_control_value('composeFrom-0')
+u'default-identity'
+
 Fill in the recipient and subject:
 
 >>> browser.js.set_control_value('composeTo-0', 'foo')
(at)(at) -138,31 +135,43 (at)(at)
 
 >>> browser.getControl(name='composeSave-0').click()
 >>> wait_for_page_load('Saving')
+>>> browser.getControl(name='composeClose-0').click()
 
 Now, there is a message in the draft folder which contains the current state
 as in the composer:
 
->>> root = getRootFolder()
->>> draft = root['webmail']['profile']['drafts'].objectValues()[0]
->>> draft
-<DraftMessage at /webmail/profile/drafts/...>
->>> draft.to
-'foo'
->>> draft.subject
-'The quick brown fox jumped over the lazy dog.'
->>> draft.body
-'<p><strong>blub</strong></p>'
+>>> print_html(browser.contents)
+<html>...
+<thead><tr ...>
+<th ...><a ...>Empf&#228;nger</a>...</th>
+<th ...><a ...>Betreff</a>...</th>
+</tr></thead>
+<tbody ...><tr ...>
+<td ...>foo</div></td>
+<td ...>The quick brown fox jumped over the lazy
dog.</div></td>
+...
 
 We can keep modifying the message in the browser, subsequent `Saves` will
 update again:
 
->>> browser.js.set_control_value('composeTo-0',
'mailothertest(at)test.gocept.com')
->>> draft.to
-'foo'
->>> browser.getControl(name='composeSave-0').click()
+>>> click_listing('The quick brown fox jumped over the lazy dog')
+>>> time.sleep(2)
+
+We change the senders identity and the recipients address and save the message
+again:
+
+>>> browser.js.set_control_value('composeFrom-1', 'basti')
+>>> browser.js.set_control_value('composeTo-1',
'mailothertest(at)test.gocept.com')
+>>> browser.getControl(name='composeSave-1').click()
+
 >>> time.sleep(1)
->>> draft.to
-'mailothertest(at)test.gocept.com'
+>>> browser.getLink('Drafts').click()
+>>> print_html(browser.contents)
+<html>...
+<tbody ...><tr ...>
+<td ...>mailothertest(at)test.gocept.com</div></td>
+<td ...>The quick brown fox jumped over the lazy
dog.</div></td>
+...
 
 Sending the message
 -------------------
(at)(at) -170,12 +179,12 (at)(at)
 The message will be sent, when the user presses the `Send` button. It also
 saves the message right before sending it:
 
->>> browser.js.set_control_value('composeTo-0',
'anotherchange(at)test.gocept.com')
->>> browser.getControl(name='composeSend-0').click();
wait_for_page_load('Sending message')
+>>> browser.js.set_control_value('composeTo-1',
'anotherchange(at)test.gocept.com')
+>>> browser.getControl(name='composeSend-1').click();
wait_for_page_load('Sending message')
 Content-Type: text/html; charset="us-ascii"
 MIME-Version: 1.0
 Content-Transfer-Encoding: 7bit
-From: Ben Utzer <ben(at)example.com>
+From: Basti <basti(at)example.com>
 To: anotherchange(at)test.gocept.com
 Subject: The quick brown fox jumped over the lazy dog.
 <BLANKLINE>
(at)(at) -183,17 +192,34 (at)(at)
 
 After sending the message, the tab and the editor is gone:
 
->>> browser.getControl(name='composeSend-0')
+>>> browser.getControl(name='composeSend-1')
 Traceback (most recent call last):
-LookupError: name 'composeSend-0'
+LookupError: name 'composeSend-1'
 >>> browser.getLink('Compose')
 Traceback (most recent call last):
 LinkNotFoundError
 
+Changing the default identity
+-----------------------------
+
+Changing the default identity changes the default sender of a new message,
too:
+
+>>> root = getRootFolder()
+>>> root['webmail']['profile'].default_identity = 'basti'
+
+The sender is pre-filled with the default identity:
+
+>>> browser.getLink('New message').click()
+>>> time.sleep(1)
+>>> browser.js.get_control_value('composeFrom-2')
+u'basti'
+>>> browser.getControl(name='composeClose-2').click()
+
+
 Replying to a message
 =====================
 
-Replying to a message works by clicking the Reply menu item. 
+Replying to a message works by clicking the Reply menu item.
 
 >>> browser.getLink('Reply').click()
 >>> time.sleep(2)
(at)(at) -203,7 +229,7 (at)(at)
 
 To demonstrate quote splitting, we fill a known text into the editor:
 
->>> browser.js.set_editor_value('composeBody-1', """
+>>> browser.js.set_editor_value('composeBody-3', """
 ... <p>Am xyz schrieb jemand:
 ... </p>
 ... <blockquote>
(at)(at) -217,8 +243,8 (at)(at)
 When the cursor is positioned in a quoted area, pressing enter results in the
 quoting being split:
 
->>>
browser.js.set_editor_cursor_position_and_press_return('composeBody-1');
->>> print_html(browser.js.get_editor_value('composeBody-1'))
+>>>
browser.js.set_editor_cursor_position_and_press_return('composeBody-3');
+>>> print_html(browser.js.get_editor_value('composeBody-3'))
 <div>
 <p>Am xyz schrieb jemand:
 </p>
(at)(at) -257,6 +283,7 (at)(at)
     ...     while browser.js.isAJAXInProgress():
     ...         #print >> sys.stderr, browser.js.isAJAXInProgress()
     ...         time.sleep(0.001)
+    ...     time.sleep(1)
     ...     #print >> sys.stderr, 'end:', message
 
     >>> def wait_for_monitor():

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Fri
Sep 26 15:36:51 2008
(at)(at) -48,7 +48,9 (at)(at)
 <div id="composeBarWrap-{count}">
   <div id="composeBar-{count}"></div>
   <div id="composeIdentity-{count}">
-      From: <input type="text" id="composeFrom-{count}"
name="composeFrom-{count}" disabled value=""/>
+      <label for="composeFrom-{count}">From:</label>
+      <select id="composeFrom-{count}" name="composeFrom-{count}">
+      </select>
   </div>
   <div id="composeAddr-{count}">
     <div>
(at)(at) -64,6 +66,7 (at)(at)
 <textarea id="composeBody-{count}" name="composeBody-{count}" cols="100"
rows="20"></textarea>
 <input type="button" id="composeSave-{count}" name="composeSave-{count}"
value="Save"/>
 <input type="button" id="composeSend-{count}" name="composeSend-{count}"
value="Send"/>
+<input type="button" id="composeClose-{count}" name="composeClose-{count}"
value="Close"/>
 ]]></r>).toString();
 
     var Composer = function(url_to_draft) {
(at)(at) -81,13 +84,20 (at)(at)
         tab_content = tab_content_template.replace(/{count}/g,
composer.index);
         composer.tab.get('contentEl').innerHTML = tab_content;
 
-        // Query the default identity to compose with
-        document.App.get('(at)(at)default_identity', function(result) {
-            var identity = YAHOO.lang.JSON.parse(result.responseText);
-            composer.getControl('From').value = identity['name'] + ' <' +
identity['address'] + '>';
+        // Query the identities to compose with
+        document.App.get('(at)(at)identities', function(result) {
+            var identities = YAHOO.lang.JSON.parse(result.responseText);
+            for (i=0;i<identities.length;i++) {
+                identity = document.createElement('option');
+                identity.value = identities[i]['id'];
+                identity.innerHTML = identities[i]['title'];
+                if (identities[i]['default']) {
+                    identity.selected = 'selected';
+                };
+                composer.getControl('From').appendChild(identity);
+            };
         });
         
-
         // Initialize the rich text editor for the body.
         composer.editor = new YAHOO.widget.SimpleEditor(
             composer.getControl('Body').id, {css: '(at)import
url(editor.css);'});
(at)(at) -105,6 +115,8 (at)(at)
             composer.getControl('Save'), 'click', composer.save_draft,
composer, true);
         YAHOO.util.Event.addListener(
             composer.getControl('Send'), 'click', composer.send_message,
composer, true);
+        YAHOO.util.Event.addListener(
+            composer.getControl('Close'), 'click', composer.close_draft,
composer, true);
     };
 
     Composer.prototype = {
(at)(at) -168,6 +180,14 (at)(at)
                     var draft = YAHOO.lang.JSON.parse(result.responseText);
                     composer.getControl('To').value = draft['to'];
                     composer.getControl('Subject').value = draft['subject'];
+                    if (draft['identity']) {
+                        identities = YAHOO.util.Dom.getChildren(
+                            composer.getControl('From'));
+                        for (i=0;i<identities.length;i++) {
+                            identities[i].selected = (
+                                identities[i].value == draft['identity']);
+                        };
+                    };
                     body = draft['body'];
                     body = body.replace('%l', '<', 'g');
                     body = body.replace('%p', '%', 'g');
(at)(at) -179,7 +199,8 (at)(at)
         _prepare_data: function() {
             var composer = this;
             composer.editor.saveHTML()
-            data =
('to='+encodeURIComponent(composer.getControl('To').value)+'&'+
+            data =
('identity='+encodeURIComponent(composer.getControl('From').value)+'&'+
+                   
'to='+encodeURIComponent(composer.getControl('To').value)+'&'+
                    
'subject='+encodeURIComponent(composer.getControl('Subject').value)+'&'+
                    
'body='+encodeURIComponent(composer.getControl('Body').value))
             return data;
(at)(at) -187,16 +208,23 (at)(at)
 
         save_draft: function(ev) {
             var composer = this;
-            document.App.post(composer.url_to_draft+'/(at)(at)save',
composer._prepare_data())
+            document.App.post(composer.url_to_draft+'/(at)(at)save',
composer._prepare_data(),
+            function (result) {
+                document.App.drafts.refresh();
+            });
         },
 
         send_message: function(ev) {
             var composer = this;
             document.App.post(composer.url_to_draft+'/(at)(at)send',
composer._prepare_data(), function(result) {
-                document.App.tabs.removeTab(composer.tab);
+                composer.close_draft();
             })
         },
 
+        close_draft: function(ev) {
+            document.App.tabs.removeTab(this.tab);
+        },
+
         getControl: function(name) {
             var composer = this;
             return document.getElementById('compose'+name+'-'+composer.index);

Added:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js
==============================================================================
--- (empty file)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js	Fri
Sep 26 15:36:51 2008
(at)(at) -0,0 +1,69 (at)(at)
+// Display and load drafts for editing.
+//
+
+// GUI container for drafts list
+
+(function() {
+
+    YAHOO.gocept.webmailer.Drafts = function(layout_unit) {
+        var drafts = this;
+        this.layout_unit = layout_unit;
+        this.layout = new YAHOO.widget.Layout(layout_unit, {
+            units: [
+                { position: 'center', scroll: true, height: '200', 
+                  body: ''}],
+        });
+        this.layout.on("render", function() {
+            var element = drafts.layout.getUnitByPosition('center');
+            drafts.drafts_list = new YAHOO.gocept.webmailer.DraftsList(
+                element.get('id'));
+        });
+        this.layout.render();
+    };
+
+    var Drafts = YAHOO.gocept.webmailer.Drafts;
+
+    Drafts.prototype = {
+        constructor: Drafts,
+
+        refresh: function() {
+            table = this.drafts_list.table;
+            table.getDataSource().sendRequest(
+                '', table.onDataReturnInitializeTable, table);
+        },
+    };
+
+}());
+
+// List of drafts
+    
+(function() {
+
+    var columnDefs = [{key:"to", label:"Empfänger", sortable:true},
+                      {key:"subject", label:"Betreff", sortable:true}];
+    var responseSchema = {
+        resultsList: "",
+        fields: ["url", "to", "subject"],
+    };
+
+    YAHOO.gocept.webmailer.DraftsList = function(container) {
+        var drafts_list = this;
+        drafts_list.container = container;
+        var dataSource = document.App.getDataSource('(at)(at)drafts?',
responseSchema);
+        this.table = new YAHOO.widget.DataTable(
+            this.container, columnDefs, dataSource);
+        this.table.set("selectionMode", "standard");
+        this.table.subscribe("rowClickEvent", this.table.onEventSelectRow);
+        this.table.subscribe("rowSelectEvent", function(event) {
+            new YAHOO.gocept.webmailer.Composer(
+                event.record.getData().url);
+            });
+    };
+
+    var DraftsList = YAHOO.gocept.webmailer.DraftsList;
+
+    DraftsList.prototype = {
+        constructor: DraftsList,
+    };
+
+}());

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Fri
Sep 26 15:36:51 2008
(at)(at) -32,12 +32,15 (at)(at)
 
       loader.addModule({name: 'webmail-messages', type: 'js',
           fullpath: app_base_url + 'message.js'});
+      loader.addModule({name: 'webmail-draft', type: 'js',
+          fullpath: app_base_url + 'draft.js'});
       loader.addModule({name: 'webmail-composer', type: 'js',
           fullpath: app_base_url + 'composer.js'});
       loader.require(['reset-fonts-grids', 'logger', 'button', 'container',
                       'tabview', 'selector', 'resize', 'layout', 'treeview',
                       'datatable', 'menu', 'editor', 'json',
-                      'webmail-messages', 'webmail-composer']);
+                      'webmail-messages', 'webmail-draft',
+                      'webmail-composer']);
       loader.insert();
 
 }());
(at)(at) -48,10 +51,12 (at)(at)
 
     YAHOO.gocept.webmailer.App = function() {
         this.ajaxInProgress = 0;
+        this.tx_queue = new Array();
     };
 
     var App = YAHOO.gocept.webmailer.App;
 
+
     App.prototype = {
         contructor: App,
 
(at)(at) -99,10 +104,14 (at)(at)
             this.tabs.on('activeTabChange', function () {
                     othis.resizeAll();});
 
-            var inboxTab = this.addTab('Inbox');
+            var inboxTab = this.addTab('Messages');
             inboxTab.get('contentEl').id = 'inboxContent';
             var messages = new
YAHOO.gocept.webmailer.Messages('inboxContent');
 
+            var draftsTab = this.addTab('Drafts');
+            draftsTab.get('contentEl').id = 'draftsContent';
+            this.drafts = new YAHOO.gocept.webmailer.Drafts('draftsContent');
+
             this.menu = new YAHOO.gocept.webmailer.Menu(menu_unit);
 
             this.resizeAll();
(at)(at) -130,6 +139,30 (at)(at)
             this.ajaxInProgress -= 1;
         },
 
+        // XXX test serialization
+        _schedule_request: function(request) {
+            this.tx_queue.push(request);
+            if (!this.tx_working) {
+                this.tx_working = true;
+                window.setTimeout(this._handle_queue, 10);
+            };
+        },
+
+        _handle_queue: function(p) {
+            app = document.App;
+            if (!YAHOO.util.Connect.isCallInProgress(app.tx_current)) {
+                request = app.tx_queue.shift();
+                if (request == null) {
+                    app.tx_working = false;
+                    return
+                };
+                app.tx_current = YAHOO.util.Connect.asyncRequest(
+                    request.method, request.url, request.callbacks,
+                    request.data);
+            };
+            window.setTimeout(app._handle_queue, 10);
+        },
+    
         request: function(method, url, on_success, data) {
             var app = this;
             app.ajaxInProgress += 1;
(at)(at) -143,8 +176,12 (at)(at)
                     app.ajaxInProgress -= 1;
                 },
             };
-    
-            YAHOO.util.Connect.asyncRequest(method, url, callbacks, data);
+            var request = new Object();
+            request.method = method;
+            request.url = url;
+            request.callbacks = callbacks;
+            request.data = data;
+            this._schedule_request(request);
         },
 
         get: function(url, on_success) {

Modified: CMFWebmail/trunk/products/CMFWebmail/tests.py
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/tests.py	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/tests.py	Fri Sep 26 15:36:51 2008
(at)(at) -46,6 +46,13 (at)(at)
     profile['default-identity'].smtp_server = 'default-smtp'
     profile['default-identity'].sent_folder = 'account/+INBOX'
 
+    # Add a second identity beside the default one
+    profile.manage_addProduct['gocept.restmail'].manage_addIdentity('basti')
+    profile['basti'].name = 'Basti'
+    profile['basti'].address = 'basti(at)example.com'
+    profile['basti'].smtp_server = 'default-smtp'
+    profile['basti'].sent_folder = 'account/+INBOX'
+
     # Add mail host
     profile.manage_addProduct['MailHost'].manage_addMailHost('default-smtp')

SVN: r6728 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Sebastian Wehrmann <sw(at)gocept.com>
2008-09-29 13:39:40 [ FULL ]
Author: sweh
Date: Mon Sep 29 13:39:39 2008
New Revision: 6728

Log:
added date to draft messages
import renormalize checkers from gocept.restmail for the date compares



Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js
   CMFWebmail/trunk/products/CMFWebmail/tests.py

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Mon Sep 29 13:39:39 2008
(at)(at) -145,10 +145,12 (at)(at)
 <thead><tr ...>
 <th ...><a ...>Empf&#228;nger</a>...</th>
 <th ...><a ...>Betreff</a>...</th>
+<th ...><a ...>Datum</a>...</th>
 </tr></thead>
 <tbody ...><tr ...>
 <td ...>foo</div></td>
 <td ...>The quick brown fox jumped over the lazy
dog.</div></td>
+<td ...><ISO DATE></div></td>
 ...
 
 We can keep modifying the message in the browser, subsequent `Saves` will

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/draft.js	Mon
Sep 29 13:39:39 2008
(at)(at) -40,10 +40,11 (at)(at)
 (function() {
 
     var columnDefs = [{key:"to", label:"Empfänger", sortable:true},
-                      {key:"subject", label:"Betreff", sortable:true}];
+                      {key:"subject", label:"Betreff", sortable:true},
+                      {key:"date", label:"Datum", sortable:true}];
     var responseSchema = {
         resultsList: "",
-        fields: ["url", "to", "subject"],
+        fields: ["url", "to", "subject", "date"],
     };
 
     YAHOO.gocept.webmailer.DraftsList = function(container) {

Modified: CMFWebmail/trunk/products/CMFWebmail/tests.py
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/tests.py	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/tests.py	Mon Sep 29 13:39:39 2008
(at)(at) -19,7 +19,7 (at)(at)
 
 checker = renormalizing.RENormalizing([
     (re.compile(r'http://127.0.0.1:[0-9]+/'),
'http://localhost/'),
-    ])
+    ] + gocept.restmail.tests.checker.patterns)
 
 
 def setUp(test):

SVN: r6740 - in CMFWebmail/trunk/products/CMFWebmail/skins: cmfwebmail_javascript cmfwebmail_styles cmfwebmail_templates
Sebastian Wehrmann <sw(at)gocept.com>
2008-09-30 08:25:35 [ FULL ]
Author: sweh
Date: Tue Sep 30 08:25:33 2008
New Revision: 6740

Log:
refactor UI



Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/webmail.js	Tue
Sep 30 08:25:33 2008
(at)(at) -6,9 +6,8 (at)(at)
     
     function initialize_webmailer() {
         YAHOO.util.Get.css(app_base_url + 'webmail.css');
-    
+
         document.App = new YAHOO.gocept.webmailer.App()
-        document.App.init()
     }
 
       var loader = new YAHOO.util.YUILoader({
(at)(at) -50,8 +49,35 (at)(at)
     // The main App object.
 
     YAHOO.gocept.webmailer.App = function() {
-        this.ajaxInProgress = 0;
+        var app = this;
+        this.module = new YAHOO.widget.Module("webmailer");
+        this.module.setBody('<div id="layout"></div>');
+        this.module.renderEvent.subscribe(function () {
+            YAHOO.util.Event.onAvailable("layout", function () {
+                app.layout = new YAHOO.widget.Layout('layout',
+                  {
+                    units: [
+                        { position: 'top',
+                              height: 45, body: '', gutter: '10' },
+                        { position: 'left',
+                              width: 200, resize: true, body: 'tree',
+                              gutter: '10px'},
+                        { position: 'center',
+                              body: '', gutter: '10'},
+                    ]
+                });
+                app.layout.on('render', function() {
+                    app._setupWidgets();
+                });
+                app.layout.render();
+            });
+        });
+        this.module.render();
+        
+
         this.tx_queue = new Array();
+        this.ajaxInProgress = 0;
+
     };
 
     var App = YAHOO.gocept.webmailer.App;
(at)(at) -60,33 +86,12 (at)(at)
     App.prototype = {
         contructor: App,
 
-        init: function() {
-            var othis = this;
-            this.layout = new YAHOO.widget.Layout('webmailer',
-              {
-                units: [
-                    { position: 'top',
-                          height: 50, body: '', gutter: '10 4' },
-                    { position: 'left',
-                          width: 200, resize: true, body: 'tree'},
-                    { position: 'center',
-                          body: '' },
-                ]
-            });
-            this.layout.on('render', function() {
-                othis._setupWidgets();
-            });
-
-            this.layout.render();
-        },
-
         addTab: function(label, content_provider) {
             var tab = new YAHOO.widget.Tab({
                 label: label,
                 content: '',
                 active: true});
             this.tabs.addTab(tab);
-            this.resizeAll();
             tab.content_provider = content_provider;
             return tab;
         },
(at)(at) -102,7 +107,7 (at)(at)
 
             this.tabs = new YAHOO.widget.TabView(center.body);
             this.tabs.on('activeTabChange', function () {
-                    othis.resizeAll();});
+                    othis.setCenterHeight();});
 
             var inboxTab = this.addTab('Messages');
             inboxTab.get('contentEl').id = 'inboxContent';
(at)(at) -113,16 +118,21 (at)(at)
             this.drafts = new YAHOO.gocept.webmailer.Drafts('draftsContent');
 
             this.menu = new YAHOO.gocept.webmailer.Menu(menu_unit);
-
-            this.resizeAll();
+            this.setCenterHeight();
         },
 
-        resizeAll: function() { 
+        setCenterHeight: function() { 
             this.layout.resize();
             var center = this.layout.getUnitByPosition('center');
-            YAHOO.util.Dom.setStyle(this.tabs._contentParent, 'height',
-                YAHOO.util.Dom.getStyle(center.body, 'height'));
-            },
+            var left = this.layout.getUnitByPosition('left');
+//            var height = YAHOO.util.Dom.getStyle(center.body, 'height');
+//            var height = '500px';
+            var height = window.innerHeight - 60;
+            height = height + 'px'
+            YAHOO.util.Dom.setStyle(center.body.parentNode.parentNode,
'height', height);
+            YAHOO.util.Dom.setStyle(left.body.parentNode.parentNode, 'height',
height);
+            YAHOO.util.Dom.setStyle(this.tabs._contentParent, 'height',
height);
+        },
 
         getDataSource: function(url, schema) {
             var dataSource = new YAHOO.util.DataSource(url);

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_styles/webmail.css	Tue
Sep 30 08:25:33 2008
(at)(at) -2,57 +2,25 (at)(at)
   background-color: #ffffff;
   font-family: Verdana, "Bitstream Vera Sans", sans-serif;
   font-size: 11px;
-  margin:0;
-  min-width: 900px;
   color: #265b72;
 }
 
 #webmailer {
   position:absolute;
-  height:80%;
-  width:80%;
+  width:100%;
 }
 
 #maillisting li {
   cursor: pointer;
 }
 
-.boxed {
-  border: 1px solid black;
-  overflow: auto;
-  float: left;
-  margin: 3px;
+.yui-skin-sam .yui-dt-hd table,
+.yui-skin-sam .yui-dt-bd table {
+    width: 100%;
 }
 
-.yui-dt-col-1 {
-  width: 150px !important;
-}
-
-.yui-dt-col-2 {
-  width: 415px !important;
-}
-
-.yui-dt-col-3 {
-  width: 200px !important;
-}
-
-
-.yui-dt-sortable {
-    text-decoration: None;
-    color: black;
-}
-
-.yui-dt-sortable:hover {
-    text-decoration: None;
-    color: blue;
-}
-
-
-.yui-dt-odd {
-    cursor: pointer;
-    background-color: #EFEFEF;
-}
-
-.yui-dt-even {
-    cursor: pointer;
+.yui-skin-sam #webmailer .yui-layout-unit-center .yui-layout-bd,
+.yui-skin-sam #webmailer .yui-layout-unit-top .yui-layout-bd {
+    border: none;
+    background-color: inherit;
 }

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_templates/webmailer.pt	Tue
Sep 30 08:25:33 2008
(at)(at) -26,8 +26,8 (at)(at)
   <body class="yui-skin-sam">
     <h2>Der TUM Webmailer</h2>
 
-    <div id="webmailer">
-    </div>
+    <div id="webmailer"></div>
+
 
   </body>
 </html>

SVN: r6743 - in CMFWebmail/trunk/products/CMFWebmail: . skins/cmfwebmail_javascript
Christian Zagrodnick <cz(at)gocept.com>
2008-09-30 09:47:15 [ FULL ]
Author: zagy
Date: Tue Sep 30 09:47:15 2008
New Revision: 6743

Log:
verhalten beim returndrücken im blockquote verbessert (kein springen mehr
bei texteingabe)


Modified:
   CMFWebmail/trunk/products/CMFWebmail/README.txt
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified: CMFWebmail/trunk/products/CMFWebmail/README.txt
==============================================================================
--- CMFWebmail/trunk/products/CMFWebmail/README.txt	(original)
+++ CMFWebmail/trunk/products/CMFWebmail/README.txt	Tue Sep 30 09:47:15 2008
(at)(at) -254,7 +254,7 (at)(at)
    Auch gibt es niemanden, der den Schmerz an sich liebt, sucht oder wuenscht,
    nur, weil er <blockquote>Schmerz</blockquote>
 </blockquote>
-<blockquote>
+<br><blockquote>
 <blockquote> ist</blockquote>, es sei denn, es kommt
    zu zufaelligen Umstaenden, in denen Muehen und Schmerz ihm grosse
 </blockquote>

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Tue
Sep 30 09:47:15 2008
(at)(at) -170,6 +170,8 (at)(at)
             }
             var textnode = left_parent.insertBefore(
                 doc.createTextNode(''), right);
+            left_parent.insertBefore(
+                doc.createElement('br'), right);
             this.editor._selectNode(textnode);
             return true;
         },

SVN: r6744 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript
Christian Zagrodnick <cz(at)gocept.com>
2008-09-30 11:08:55 [ FULL ]
Author: zagy
Date: Tue Sep 30 11:08:53 2008
New Revision: 6744

Log:
refactored quote breaking code to be symmetric


Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Tue
Sep 30 11:08:53 2008
(at)(at) -148,30 +148,42 (at)(at)
             }
             var doc = this.editor._getDoc();
             var range = this.editor._getRange();
-            var left = range.startContainer;
             var offset = range.startOffset;
-            var right = doc.createTextNode(left.nodeValue.substr(offset))
-            left.nodeValue = left.nodeValue.substr(0, offset)
-            left_parent = left.parentNode;
-            while (left_parent !== doc.body) {
-                var right_parent = left_parent.cloneNode(false);
+
+            var current = range.startContainer;
+
+            var left = doc.createTextNode(current.nodeValue.substr(0,
offset));
+            var right = doc.createTextNode(current.nodeValue.substr(offset));
+            var parent = current.parentNode;
+
+            while (parent !== doc.body) {
+                var left_parent = parent.cloneNode(false);
+                var right_parent = parent.cloneNode(false);
+                left_parent.appendChild(left);
                 right_parent.appendChild(right);
-                while (left.nextSibling != null) {
-                    right_parent.appendChild(left.nextSibling);
+                while (current.previousSibling != null) {
+                    left_parent.insertBefore(current.previousSibling,
+                                             left_parent.firstChild);
+                }
+                while (current.nextSibling != null) {
+                    right_parent.appendChild(current.nextSibling);
                 }
+                
+                current = parent;
+                parent = current.parentNode;
                 left = left_parent;
                 right = right_parent;
-                left_parent = left.parentNode;
             }
-            if (left.nextSibling == null) {
-                left_parent.appendChild(right);
+            parent.insertBefore(left, current);
+            if (current.nextSibling == null) {
+                parent.appendChild(right);
             } else {
-                left_parent.insertBefore(right, left.nextSibling);
+                parent.insertBefore(right, current.nextSibling);
             }
-            var textnode = left_parent.insertBefore(
-                doc.createTextNode(''), right);
-            left_parent.insertBefore(
-                doc.createElement('br'), right);
+            var textnode = parent.insertBefore(
+                doc.createTextNode(''), current);
+            parent.replaceChild(
+                doc.createElement('br'), current);
             this.editor._selectNode(textnode);
             return true;
         },

SVN: r6745 - CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript
Christian Zagrodnick <cz(at)gocept.com>
2008-09-30 11:41:17 [ FULL ]
Author: zagy
Date: Tue Sep 30 11:41:15 2008
New Revision: 6745

Log:
implemented new line at begin/end of quoted block XXX needs tests!


Modified:
   CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js

Modified:
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js
==============================================================================
---
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	(original)
+++
CMFWebmail/trunk/products/CMFWebmail/skins/cmfwebmail_javascript/composer.js	Tue
Sep 30 11:41:15 2008
(at)(at) -119,6 +119,16 (at)(at)
             composer.getControl('Close'), 'click', composer.close_draft,
composer, true);
     };
 
+    var has_content = function(element) {
+        if (element.nodeType == element.TEXT_NODE) {
+            return element.nodeValue != "";
+        } else if (element.nodeType == element.ELEMENT_NODE) {
+            return element.firstChild != null;
+        } else {
+            return true; // guess
+        }
+    }
+
     Composer.prototype = {
         // Rebind the constructor function
         constructor: Composer,
(at)(at) -159,8 +169,12 (at)(at)
             while (parent !== doc.body) {
                 var left_parent = parent.cloneNode(false);
                 var right_parent = parent.cloneNode(false);
-                left_parent.appendChild(left);
-                right_parent.appendChild(right);
+                if (has_content(left)) {
+                    left_parent.appendChild(left);
+                }
+                if (has_content(right)) {
+                    right_parent.appendChild(right);
+                }
                 while (current.previousSibling != null) {
                     left_parent.insertBefore(current.previousSibling,
                                              left_parent.firstChild);
(at)(at) -174,12 +188,13 (at)(at)
                 left = left_parent;
                 right = right_parent;
             }
-            parent.insertBefore(left, current);
-            if (current.nextSibling == null) {
-                parent.appendChild(right);
-            } else {
+            if (has_content(left)) {
+                parent.insertBefore(left, current);
+            }
+            if (has_content(right)) {
                 parent.insertBefore(right, current.nextSibling);
             }
+
             var textnode = parent.insertBefore(
                 doc.createTextNode(''), current);
             parent.replaceChild(

MailBoxer