editor: comments in a gutter - first approach
authorAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 28 May 2014 08:25:37 +0000 (10:25 +0200)
committerAleksander Łukasz <aleksander.lukasz@nowoczesnapolska.org.pl>
Wed, 28 May 2014 12:45:58 +0000 (14:45 +0200)
src/editor/modules/documentCanvas/canvas/comments/comment.html [new file with mode: 0644]
src/editor/modules/documentCanvas/canvas/comments/comments.html [new file with mode: 0644]
src/editor/modules/documentCanvas/canvas/comments/comments.js [new file with mode: 0644]
src/editor/modules/documentCanvas/canvas/comments/comments.less [new file with mode: 0644]
src/editor/modules/documentCanvas/canvas/genericElement.js
src/editor/modules/documentCanvas/documentCanvas.less

diff --git a/src/editor/modules/documentCanvas/canvas/comments/comment.html b/src/editor/modules/documentCanvas/canvas/comments/comment.html
new file mode 100644 (file)
index 0000000..3ba1cec
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="comment">
+    <div class="header">
+        <span class="author"><%= author %></span>
+        <span class="date"><%= date %></span>
+    </div>
+    <div style="clear: both"></div>
+    <div class="content">
+        <%= content %>
+        <div class="toolbox"><a href="#" class="remove-btn"><%= gettext('remove') %></a></div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/editor/modules/documentCanvas/canvas/comments/comments.html b/src/editor/modules/documentCanvas/canvas/comments/comments.html
new file mode 100644 (file)
index 0000000..7ca0760
--- /dev/null
@@ -0,0 +1,9 @@
+<div class="comments">
+    <div class="list"></div>
+    <div class="newComment">
+        <textarea rows="1"></textarea>
+        <button class="btn btn-info btn-mini btnAdd" disabled><%= gettext('Comment') %></button>
+        <button class="btn btn-mini btnCancel"><%= gettext('Cancel') %></button>
+        <div style="clear:both;"></div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/src/editor/modules/documentCanvas/canvas/comments/comments.js b/src/editor/modules/documentCanvas/canvas/comments/comments.js
new file mode 100644 (file)
index 0000000..790731f
--- /dev/null
@@ -0,0 +1,164 @@
+define(function(require) {
+    
+'use strict';
+/* globals Node, gettext */
+
+
+var $ = require('libs/jquery'),
+    _ = require('libs/underscore'),
+    datetime = require('fnpjs/datetime'),
+    commentsTemplate = require('libs/text!./comments.html'),
+    commentTemplate = require('libs/text!./comment.html');
+
+
+var View = function(node, user) {
+    this.node = node;
+    this.user = user;
+    this.dom = $(_.template(commentsTemplate)());
+    this.list = this.dom.find('.list');
+    this.textarea = this.dom.find('textarea');
+    this.addButton = this.dom.find('button.btnAdd');
+    this.cancelButton = this.dom.find('button.btnCancel');
+
+    this.textarea.on('input', function() {
+        this.addButton.attr('disabled', this.textarea.val() === '');
+
+        if (this.textarea.prop('scrollHeight') > this.textarea.prop('clientHeight')) {
+            this.textarea.height(this.textarea.prop('scrollHeight'));
+        }
+
+
+    }.bind(this));
+    this.addButton.hide();
+    this.cancelButton.hide();
+    this.textarea.on('focus', function() {
+        this.addButton.show();
+        this.cancelButton.show();
+    }.bind(this));
+
+    this.addButton.on('click', function() {
+        if(!this.node) {
+            return;
+        }
+
+        this.node.document.transaction(function() {
+            var commentNode = this.node.document.createDocumentNode({tagName: 'aside', attrs: {'class': 'comment'}}),
+                metadata = commentNode.getMetadata(),
+                creator;
+
+            if(this.user) {
+                creator = this.user.name;
+                if(this.user.email) {
+                    creator += ' (' + this.user.email + ')';
+                }
+            } else {
+                creator = 'anonymous';
+            }
+
+            metadata.add({key: 'creator', value: creator});
+            metadata.add({key: 'date', value: datetime.currentStrfmt()});
+            commentNode.append({text: this.textarea.val()});
+
+            this.node.append(commentNode);
+        }.bind(this), {
+            metadata: {
+                description: gettext('Add comment')
+            },
+            success: function() {
+                this.textarea.val('');
+            }.bind(this)
+        });
+
+    }.bind(this));
+
+    this.cancelButton.on('click', function() {
+        this.addButton.hide();
+        this.cancelButton.hide();
+        this.textarea.val('');
+    }.bind(this));
+
+    this.render();
+    this.onDeactivated();
+
+};
+
+_.extend(View.prototype, {
+    render: function() {
+        this.list.empty();
+
+        // while(this.node.getTagName() === 'span' && this.node.parent()) {
+        //     this.node = this.node.parent();
+        // }
+        this.textarea.attr('placeholder', gettext('Comment'));
+
+        this.node.contents()
+            .filter(function(child) {
+                return child.nodeType === Node.ELEMENT_NODE && child.getTagName() === 'aside' && child.getClass() === 'comment';
+                //return child.is({tag: 'aside', klass: 'comment'});
+
+            })
+            .forEach(function(commentNode) {
+                var metaData = commentNode.getMetadata(),
+                    author, date, content;
+
+                metaData.some(function(row) {
+                    author = row.getValue();
+                    if(author) {
+                        author = author.split(' ')[0];
+                    }
+                    return true;
+                }, 'creator');
+                
+                metaData.some(function(row) {
+                    date = row.getValue();
+                    return true;
+                }, 'date');
+
+                content = commentNode.object.getText();
+
+                var commentView = $(_.template(commentTemplate)({
+                    author: author ||'?',
+                    date: date || '?',
+                    content: content || '?'
+                }));
+
+                commentView.find('.remove-btn').on('click', function() {
+                    commentNode.document.transaction(function() {
+                        commentNode.detach();
+                    }, {
+                        metadata: {
+                            description: gettext('Remove comment')
+                        }
+                    });
+                });
+
+                this.list.append(commentView);
+                this.textarea.attr('placeholder', gettext('Respond') + '...');
+            }.bind(this));
+        
+    },
+    onActivated: function() {
+        //if(this.list.find('.comment').length === 0) {
+            this.dom.find('.newComment').toggle(true);
+        //}
+       //this.dom.show();
+
+    },
+    onDeactivated: function() {
+      this.dom.find('.newComment').toggle(false);
+      this.addButton.hide();
+      this.cancelButton.hide();
+      //this.dom.hide();
+
+    },
+
+    getHeight: function() {
+        return this.dom.outerHeight();
+    }
+
+});
+
+
+return View;
+
+});
\ No newline at end of file
diff --git a/src/editor/modules/documentCanvas/canvas/comments/comments.less b/src/editor/modules/documentCanvas/canvas/comments/comments.less
new file mode 100644 (file)
index 0000000..11b776b
--- /dev/null
@@ -0,0 +1,48 @@
+.comments {
+    @borderColor: darken(#FFFCB7, 15%);
+
+    font-size: 12px;
+
+    .comment {
+        
+        border-color: @borderColor;
+        border-style: solid;
+        border-width: 1px;
+        margin-top: 10px;
+
+        .header {
+            border-bottom: 1px solid @borderColor;
+            padding: 0 3px;
+            font-size: 10px;
+            
+            .author {
+                
+            }
+            .date {
+                float: right;
+            }
+        }
+
+        .content {
+            padding: 5px;
+        }
+    }
+
+    .newComment {
+        margin-top: 10px;
+
+        textarea {
+            display: block;
+            width: 95%;
+            padding: 2px 2px;
+            margin: 0 0 10px 0;
+            font-size: 12px;
+            resize: vertical;
+            outline: none !important;
+            box-shadow: none;
+
+        }
+    }
+
+
+}
\ No newline at end of file
index 4f4da9b..e0fc84b 100644 (file)
@@ -6,7 +6,8 @@ var $ = require('libs/jquery'),
     _ = require('libs/underscore'),
     documentElement = require('./documentElement'),
     utils = require('./utils'),
-    wlxmlUtils = require('utils/wlxml');
+    wlxmlUtils = require('utils/wlxml'),
+    CommentsView = require('./comments/comments');
 
 var labelWidget = function(tag, klass) {
     return $('<span>')
@@ -32,6 +33,8 @@ $.extend(generic, {
             }
         }.bind(this));
 
+        this.commentsView = new CommentsView(this.wlxmlNode, {});
+        this.addToGutter(this.commentsView);
         this.commentTip = $('<div class="comment-tip"><i class="icon-comment"></i></div>');
         this.addWidget(this.commentTip);
 
@@ -130,6 +133,7 @@ $.extend(generic, {
 
         if(event.meta.node.is('comment')) {
             this.commentTip.show();
+            this.commentsView.render();
         }
     },
     onNodeDetached: function(event) {
@@ -146,6 +150,7 @@ $.extend(generic, {
             if(isComment && !this.wlxmlNode.hasChild({klass: 'comment'})) {
                 this.commentTip.hide();
             }
+            this.commentsView.render();
         }
     },
     onNodeTextChange: function(event) {
index b2fbd5d..f2e714f 100644 (file)
@@ -2,6 +2,7 @@
 @import 'canvas/documentElement.less';
 @import 'canvas/genericElement.less';
 @import 'canvas/gutter.less';
+@import 'canvas/comments/comments.less';
 
 #rng-module-documentCanvas {
    height: 100%;