changeset 1789:17caf4efe15c beta

implements #308 rewrote diffs to enable displaying full diff on each file - fixed escaping of html special chars in file editor
author Marcin Kuzminski <marcin@python-works.com>
date Mon, 19 Dec 2011 00:11:20 +0200
parents ef0613584ced
children f551007ce085
files rhodecode/controllers/changeset.py rhodecode/controllers/files.py rhodecode/lib/diffs.py rhodecode/lib/helpers.py rhodecode/model/comment.py rhodecode/templates/changeset/diff_block.html rhodecode/templates/files/file_diff.html rhodecode/templates/files/files_edit.html rhodecode/templates/files/files_source.html
diffstat 9 files changed, 221 insertions(+), 228 deletions(-) [+]
line wrap: on
line diff
--- a/rhodecode/controllers/changeset.py	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/controllers/changeset.py	Mon Dec 19 00:11:20 2011 +0200
@@ -46,6 +46,7 @@
 from rhodecode.model.db import ChangesetComment
 from rhodecode.model.comment import ChangesetCommentsModel
 from rhodecode.model.meta import Session
+from rhodecode.lib.diffs import wrapped_diff
 
 log = logging.getLogger(__name__)
 
@@ -145,15 +146,6 @@
     return h.link_to(lbl, h.url.current(**params))
 
 
-def wrap_to_table(str_):
-    return '''<table class="code-difftable">
-                <tr class="line no-comment">
-                <td class="lineno new"></td>
-                <td class="code no-comment"><pre>%s</pre></td>
-                </tr>
-              </table>''' % str_
-
-
 class ChangesetController(BaseRepoController):
 
     @LoginRequired()
@@ -192,10 +184,11 @@
             return redirect(url('home'))
 
         c.changes = OrderedDict()
-        c.sum_added = 0
-        c.sum_removed = 0
-        c.lines_added = 0
-        c.lines_deleted = 0
+
+        c.lines_added = 0  # count of lines added
+        c.lines_deleted = 0  # count of lines removes
+
+        cumulative_diff = 0
         c.cut_off = False  # defines if cut off limit is reached
 
         c.comments = []
@@ -220,37 +213,19 @@
             # ADDED FILES
             #==================================================================
             for node in changeset.added:
-
-                filenode_old = FileNode(node.path, '', EmptyChangeset())
-                if filenode_old.is_binary or node.is_binary:
-                    diff = wrap_to_table(_('binary file'))
-                    st = (0, 0)
-                else:
-                    # in this case node.size is good parameter since those are
-                    # added nodes and their size defines how many changes were
-                    # made
-                    c.sum_added += node.size
-                    fid = h.FID(revision, node.path)
-                    line_context_lcl = get_line_ctx(fid, request.GET)
-                    ignore_whitespace_lcl = get_ignore_ws(fid, request.GET)
-                    if c.sum_added < self.cut_off_limit:
-                        f_gitdiff = diffs.get_gitdiff(filenode_old, node,
-                                        ignore_whitespace=ignore_whitespace_lcl,
-                                        context=line_context_lcl)
-                        d = diffs.DiffProcessor(f_gitdiff, format='gitdiff')
-
-                        st = d.stat()
-                        diff = d.as_html(enable_comments=enable_comments)
-
-                    else:
-                        diff = wrap_to_table(_('Changeset is to big and '
-                                               'was cut off, see raw '
-                                               'changeset instead'))
-                        c.cut_off = True
-                        break
-
-                cs1 = None
-                cs2 = node.last_changeset.raw_id
+                fid = h.FID(revision, node.path)
+                line_context_lcl = get_line_ctx(fid, request.GET)
+                ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
+                lim = self.cut_off_limit
+                if cumulative_diff > self.cut_off_limit:
+                    lim = -1
+                size, cs1, cs2, diff, st = wrapped_diff(filenode_old=None,
+                                         filenode_new=node,
+                                         cut_off_limit=lim,
+                                         ignore_whitespace=ign_whitespace_lcl,
+                                         line_context=line_context_lcl,
+                                         enable_comments=enable_comments)
+                cumulative_diff += size
                 c.lines_added += st[0]
                 c.lines_deleted += st[1]
                 c.changes[changeset.raw_id].append(('added', node, diff,
@@ -259,60 +234,37 @@
             #==================================================================
             # CHANGED FILES
             #==================================================================
-            if not c.cut_off:
-                for node in changeset.changed:
-                    try:
-                        filenode_old = changeset_parent.get_node(node.path)
-                    except ChangesetError:
-                        log.warning('Unable to fetch parent node for diff')
-                        filenode_old = FileNode(node.path, '',
-                                                EmptyChangeset())
-
-                    if filenode_old.is_binary or node.is_binary:
-                        diff = wrap_to_table(_('binary file'))
-                        st = (0, 0)
-                    else:
+            for node in changeset.changed:
+                try:
+                    filenode_old = changeset_parent.get_node(node.path)
+                except ChangesetError:
+                    log.warning('Unable to fetch parent node for diff')
+                    filenode_old = FileNode(node.path, '', EmptyChangeset())
 
-                        if c.sum_removed < self.cut_off_limit:
-                            fid = h.FID(revision, node.path)
-                            line_context_lcl = get_line_ctx(fid, request.GET)
-                            ignore_whitespace_lcl = get_ignore_ws(fid, request.GET,)
-                            f_gitdiff = diffs.get_gitdiff(filenode_old, node,
-                                    ignore_whitespace=ignore_whitespace_lcl,
-                                    context=line_context_lcl)
-                            d = diffs.DiffProcessor(f_gitdiff,
-                                                     format='gitdiff')
-                            st = d.stat()
-                            if (st[0] + st[1]) * 256 > self.cut_off_limit:
-                                diff = wrap_to_table(_('Diff is to big '
-                                                       'and was cut off, see '
-                                                       'raw diff instead'))
-                            else:
-                                diff = d.as_html(enable_comments=enable_comments)
-
-                            if diff:
-                                c.sum_removed += len(diff)
-                        else:
-                            diff = wrap_to_table(_('Changeset is to big and '
-                                                   'was cut off, see raw '
-                                                   'changeset instead'))
-                            c.cut_off = True
-                            break
-
-                    cs1 = filenode_old.last_changeset.raw_id
-                    cs2 = node.last_changeset.raw_id
-                    c.lines_added += st[0]
-                    c.lines_deleted += st[1]
-                    c.changes[changeset.raw_id].append(('changed', node, diff,
-                                                        cs1, cs2, st))
+                fid = h.FID(revision, node.path)
+                line_context_lcl = get_line_ctx(fid, request.GET)
+                ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
+                lim = self.cut_off_limit
+                if cumulative_diff > self.cut_off_limit:
+                    lim = -1
+                size, cs1, cs2, diff, st = wrapped_diff(filenode_old=filenode_old,
+                                         filenode_new=node,
+                                         cut_off_limit=lim,
+                                         ignore_whitespace=ign_whitespace_lcl,
+                                         line_context=line_context_lcl,
+                                         enable_comments=enable_comments)
+                cumulative_diff += size
+                c.lines_added += st[0]
+                c.lines_deleted += st[1]
+                c.changes[changeset.raw_id].append(('changed', node, diff,
+                                                    cs1, cs2, st))
 
             #==================================================================
             # REMOVED FILES
             #==================================================================
-            if not c.cut_off:
-                for node in changeset.removed:
-                    c.changes[changeset.raw_id].append(('removed', node, None,
-                                                        None, None, (0, 0)))
+            for node in changeset.removed:
+                c.changes[changeset.raw_id].append(('removed', node, None,
+                                                    None, None, (0, 0)))
 
         # count inline comments
         for path, lines in c.inline_comments:
--- a/rhodecode/controllers/files.py	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/controllers/files.py	Mon Dec 19 00:11:20 2011 +0200
@@ -27,19 +27,18 @@
 import logging
 import traceback
 
-from os.path import join as jn
-
-from pylons import request, response, session, tmpl_context as c, url
+from pylons import request, response, tmpl_context as c, url
 from pylons.i18n.translation import _
 from pylons.controllers.util import redirect
 from pylons.decorators import jsonify
 
 from vcs.conf import settings
 from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
-    EmptyRepositoryError, ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError
-from vcs.nodes import FileNode, NodeKind
+    EmptyRepositoryError, ImproperArchiveTypeError, VCSError, \
+    NodeAlreadyExistsError
+from vcs.nodes import FileNode
 
-
+from rhodecode.lib.compat import OrderedDict
 from rhodecode.lib import convert_line_endings, detect_mode, safe_str
 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 from rhodecode.lib.base import BaseRepoController, render
@@ -47,6 +46,9 @@
 from rhodecode.lib import diffs
 import rhodecode.lib.helpers as h
 from rhodecode.model.repo import RepoModel
+from rhodecode.controllers.changeset import anchor_url, _ignorews_url,\
+    _context_url, get_line_ctx, get_ignore_ws
+from rhodecode.lib.diffs import wrapped_diff
 
 log = logging.getLogger(__name__)
 
@@ -105,7 +107,6 @@
 
         return file_node
 
-
     def __get_paths(self, changeset, starting_path):
         """recursive walk in root dir and return a set of all path in that dir
         based on repository walk function
@@ -128,7 +129,7 @@
     @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
                                    'repository.admin')
     def index(self, repo_name, revision, f_path):
-        #reditect to given revision from form if given
+        # redirect to given revision from form if given
         post_revision = request.POST.get('at_rev', None)
         if post_revision:
             cs = self.__get_cs_or_redirect(post_revision, repo_name)
@@ -141,7 +142,7 @@
 
         cur_rev = c.changeset.revision
 
-        #prev link
+        # prev link
         try:
             prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
             c.url_prev = url('files_home', repo_name=c.repo_name,
@@ -151,7 +152,7 @@
         except (ChangesetDoesNotExistError, VCSError):
             c.url_prev = '#'
 
-        #next link
+        # next link
         try:
             next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
             c.url_next = url('files_home', repo_name=c.repo_name,
@@ -161,7 +162,7 @@
         except (ChangesetDoesNotExistError, VCSError):
             c.url_next = '#'
 
-        #files or dirs
+        # files or dirs
         try:
             c.file = c.changeset.get_node(f_path)
 
@@ -407,13 +408,17 @@
     def diff(self, repo_name, f_path):
         ignore_whitespace = request.GET.get('ignorews') == '1'
         line_context = request.GET.get('context', 3)
-        diff1 = request.GET.get('diff1')
-        diff2 = request.GET.get('diff2')
+        diff1 = request.GET.get('diff1', '')
+        diff2 = request.GET.get('diff2', '')
         c.action = request.GET.get('diff')
         c.no_changes = diff1 == diff2
         c.f_path = f_path
         c.big_diff = False
-
+        c.anchor_url = anchor_url
+        c.ignorews_url = _ignorews_url
+        c.context_url = _context_url
+        c.changes = OrderedDict()
+        c.changes[diff2] = []
         try:
             if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
                 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
@@ -429,14 +434,14 @@
                 c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo)
                 node2 = FileNode('.', '', changeset=c.changeset_2)
         except RepositoryError:
-            return redirect(url('files_home',
-                                repo_name=c.repo_name, f_path=f_path))
+            return redirect(url('files_home', repo_name=c.repo_name, 
+                                f_path=f_path))
 
         if c.action == 'download':
             _diff = diffs.get_gitdiff(node1, node2,
                                       ignore_whitespace=ignore_whitespace,
                                       context=line_context)
-            diff = diffs.DiffProcessor(_diff,format='gitdiff')
+            diff = diffs.DiffProcessor(_diff, format='gitdiff')
 
             diff_name = '%s_vs_%s.diff' % (diff1, diff2)
             response.content_type = 'text/plain'
@@ -448,42 +453,25 @@
             _diff = diffs.get_gitdiff(node1, node2,
                                       ignore_whitespace=ignore_whitespace,
                                       context=line_context)
-            diff = diffs.DiffProcessor(_diff,format='gitdiff')
+            diff = diffs.DiffProcessor(_diff, format='gitdiff')
             response.content_type = 'text/plain'
             return diff.raw_diff()
 
-        elif c.action == 'diff':
-            if node1.is_binary or node2.is_binary:
-                c.cur_diff = _('Binary file')
-            elif node1.size > self.cut_off_limit or \
-                    node2.size > self.cut_off_limit:
-                c.cur_diff = ''
-                c.big_diff = True
-            else:
-                _diff = diffs.get_gitdiff(node1, node2,
-                                           ignore_whitespace=ignore_whitespace,
-                                           context=line_context)
-                diff = diffs.DiffProcessor(_diff,format='gitdiff')
-                c.cur_diff = diff.as_html()
         else:
+            fid = h.FID(diff2, node2.path)
+            line_context_lcl = get_line_ctx(fid, request.GET)
+            ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
 
-            #default option
-            if node1.is_binary or node2.is_binary:
-                c.cur_diff = _('Binary file')
-            elif node1.size > self.cut_off_limit or \
-                    node2.size > self.cut_off_limit:
-                c.cur_diff = ''
-                c.big_diff = True
+            lim = request.GET.get('fulldiff') or self.cut_off_limit
+            _, cs1, cs2, diff, st = wrapped_diff(filenode_old=node1,
+                                         filenode_new=node2,
+                                         cut_off_limit=lim,
+                                         ignore_whitespace=ign_whitespace_lcl,
+                                         line_context=line_context_lcl,
+                                         enable_comments=False)
 
-            else:
-                _diff = diffs.get_gitdiff(node1, node2,
-                                          ignore_whitespace=ignore_whitespace,
-                                          context=line_context)
-                diff = diffs.DiffProcessor(_diff,format='gitdiff')
-                c.cur_diff = diff.as_html()
+            c.changes = [('', node2, diff, cs1, cs2, st,)]
 
-        if not c.cur_diff and not c.big_diff:
-            c.no_changes = True
         return render('files/file_diff.html')
 
     def _get_node_history(self, cs, f_path):
@@ -501,12 +489,10 @@
         hist_l.append(changesets_group)
 
         for name, chs in c.rhodecode_repo.branches.items():
-            #chs = chs.split(':')[-1]
             branches_group[0].append((chs, name),)
         hist_l.append(branches_group)
 
         for name, chs in c.rhodecode_repo.tags.items():
-            #chs = chs.split(':')[-1]
             tags_group[0].append((chs, name),)
         hist_l.append(tags_group)
 
--- a/rhodecode/lib/diffs.py	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/lib/diffs.py	Mon Dec 19 00:11:20 2011 +0200
@@ -27,12 +27,66 @@
 
 import re
 import difflib
+import markupsafe
+from itertools import tee, imap
 
-from itertools import tee, imap
+from pylons.i18n.translation import _
 
 from vcs.exceptions import VCSError
 from vcs.nodes import FileNode
-import markupsafe
+
+from rhodecode.lib.utils import EmptyChangeset
+
+
+def wrap_to_table(str_):
+    return '''<table class="code-difftable">
+                <tr class="line no-comment">
+                <td class="lineno new"></td>
+                <td class="code no-comment"><pre>%s</pre></td>
+                </tr>
+              </table>''' % str_
+
+
+def wrapped_diff(filenode_old, filenode_new, cut_off_limit=None,
+                ignore_whitespace=True, line_context=3,
+                enable_comments=False):
+    """
+    returns a wrapped diff into a table, checks for cut_off_limit and presents
+    proper message
+    """
+
+    if filenode_old is None:
+        filenode_old = FileNode(filenode_new.path, '', EmptyChangeset())
+
+    if filenode_old.is_binary or filenode_new.is_binary:
+        diff = wrap_to_table(_('binary file'))
+        stats = (0, 0)
+        size = 0
+
+    elif cut_off_limit != -1 and (cut_off_limit is None or
+    (filenode_old.size < cut_off_limit and filenode_new.size < cut_off_limit)):
+
+        f_gitdiff = get_gitdiff(filenode_old, filenode_new,
+                                ignore_whitespace=ignore_whitespace,
+                                context=line_context)
+        diff_processor = DiffProcessor(f_gitdiff, format='gitdiff')
+
+        diff = diff_processor.as_html(enable_comments=enable_comments)
+        stats = diff_processor.stat()
+        size = len(diff or '')
+    else:
+        diff = wrap_to_table(_('Changeset was to big and was cut off, use '
+                               'diff menu to display this diff'))
+        stats = (0, 0)
+        size = 0
+
+    if not diff:
+        diff = wrap_to_table(_('No changes detected'))
+
+    cs1 = filenode_old.last_changeset.raw_id
+    cs2 = filenode_new.last_changeset.raw_id
+
+    return size, cs1, cs2, diff, stats
 
 
 def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3):
@@ -263,8 +317,8 @@
                             lines.append({
                                 'old_lineno': '...',
                                 'new_lineno': '...',
-                                'action': 'context',
-                                'line': line,
+                                'action':     'context',
+                                'line':       line,
                             })
                         else:
                             skipfirst = False
@@ -371,34 +425,40 @@
             """
 
             if condition:
-                return '''<a href="%(url)s">%(label)s</a>''' % {'url': url,
-                                                                'label': label}
+                return '''<a href="%(url)s">%(label)s</a>''' % {
+                    'url': url,
+                    'label': label
+                }
             else:
                 return label
         diff_lines = self.prepare()
         _html_empty = True
         _html = []
-        _html.append('''<table class="%(table_class)s">\n''' \
-                                            % {'table_class': table_class})
+        _html.append('''<table class="%(table_class)s">\n''' % {
+            'table_class': table_class
+        })
         for diff in diff_lines:
             for line in diff['chunks']:
                 _html_empty = False
                 for change in line:
-                    _html.append('''<tr class="%(line_class)s %(action)s">\n''' \
-                        % {'line_class': line_class,
-                           'action': change['action']})
+                    _html.append('''<tr class="%(lc)s %(action)s">\n''' % {
+                        'lc': line_class,
+                        'action': change['action']
+                    })
                     anchor_old_id = ''
                     anchor_new_id = ''
-                    anchor_old = "%(filename)s_o%(oldline_no)s" % \
-                                {'filename': self._safe_id(diff['filename']),
-                                 'oldline_no': change['old_lineno']}
-                    anchor_new = "%(filename)s_n%(oldline_no)s" % \
-                                {'filename': self._safe_id(diff['filename']),
-                                 'oldline_no': change['new_lineno']}
-                    cond_old = change['old_lineno'] != '...' and \
-                                                        change['old_lineno']
-                    cond_new = change['new_lineno'] != '...' and \
-                                                        change['new_lineno']
+                    anchor_old = "%(filename)s_o%(oldline_no)s" % {
+                        'filename': self._safe_id(diff['filename']),
+                        'oldline_no': change['old_lineno']
+                    }
+                    anchor_new = "%(filename)s_n%(oldline_no)s" % {
+                        'filename': self._safe_id(diff['filename']),
+                        'oldline_no': change['new_lineno']
+                    }
+                    cond_old = (change['old_lineno'] != '...' and
+                                change['old_lineno'])
+                    cond_new = (change['new_lineno'] != '...' and
+                                change['new_lineno'])
                     if cond_old:
                         anchor_old_id = 'id="%s"' % anchor_old
                     if cond_new:
@@ -406,37 +466,41 @@
                     ###########################################################
                     # OLD LINE NUMBER
                     ###########################################################
-                    _html.append('''\t<td %(a_id)s class="%(old_lineno_cls)s">''' \
-                                    % {'a_id': anchor_old_id,
-                                       'old_lineno_cls': old_lineno_class})
+                    _html.append('''\t<td %(a_id)s class="%(olc)s">''' % {
+                        'a_id': anchor_old_id,
+                        'olc': old_lineno_class
+                    })
 
-                    _html.append('''%(link)s''' \
-                        % {'link':
-                        _link_to_if(cond_old, change['old_lineno'], '#%s' \
-                                                                % anchor_old)})
+                    _html.append('''%(link)s''' % {
+                        'link': _link_to_if(True, change['old_lineno'],
+                                            '#%s' % anchor_old)
+                    })
                     _html.append('''</td>\n''')
                     ###########################################################
                     # NEW LINE NUMBER
                     ###########################################################
 
-                    _html.append('''\t<td %(a_id)s class="%(new_lineno_cls)s">''' \
-                                    % {'a_id': anchor_new_id,
-                                       'new_lineno_cls': new_lineno_class})
+                    _html.append('''\t<td %(a_id)s class="%(nlc)s">''' % {
+                        'a_id': anchor_new_id,
+                        'nlc': new_lineno_class
+                    })
 
-                    _html.append('''%(link)s''' \
-                        % {'link':
-                        _link_to_if(cond_new, change['new_lineno'], '#%s' \
-                                                                % anchor_new)})
+                    _html.append('''%(link)s''' % {
+                        'link': _link_to_if(True, change['new_lineno'],
+                                            '#%s' % anchor_new)
+                    })
                     _html.append('''</td>\n''')
                     ###########################################################
                     # CODE
                     ###########################################################
                     comments = '' if enable_comments else 'no-comment'
-                    _html.append('''\t<td class="%(code_class)s %(in-comments)s">''' \
-                                                % {'code_class': code_class,
-                                                   'in-comments': comments})
-                    _html.append('''\n\t\t<pre>%(code)s</pre>\n''' \
-                                                % {'code': change['line']})
+                    _html.append('''\t<td class="%(cc)s %(inc)s">''' % {
+                        'cc': code_class,
+                        'inc': comments
+                    })
+                    _html.append('''\n\t\t<pre>%(code)s</pre>\n''' % {
+                        'code': change['line']
+                    })
                     _html.append('''\t</td>''')
                     _html.append('''\n</tr>\n''')
         _html.append('''</table>''')
--- a/rhodecode/lib/helpers.py	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/lib/helpers.py	Mon Dec 19 00:11:20 2011 +0200
@@ -40,6 +40,7 @@
 from rhodecode.lib import str2bool, safe_unicode, safe_str, get_changeset_safe
 from rhodecode.lib.markup_renderer import MarkupRenderer
 
+
 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
     """
     Reset button
@@ -52,11 +53,11 @@
 reset = _reset
 safeid = _make_safe_id_component
 
-        
-def FID(raw_id,path):
+
+def FID(raw_id, path):
     """
     Creates a uniqe ID for filenode based on it's path and revision
-    
+
     :param raw_id:
     :param path:
     """
@@ -116,7 +117,7 @@
         paths_l = paths.split('/')
         for cnt, p in enumerate(paths_l):
             if p != '':
-                url_l.append(link_to(p, 
+                url_l.append(link_to(p,
                                      url('files_home',
                                          repo_name=repo_name,
                                          revision=rev,
@@ -738,14 +739,14 @@
 
 
 def rst(source):
-    return literal('<div class="rst-block">%s</div>' % 
+    return literal('<div class="rst-block">%s</div>' %
                    MarkupRenderer.rst(source))
-    
+
 def rst_w_mentions(source):
     """
     Wrapped rst renderer with @mention highlighting
     
     :param source:
     """
-    return literal('<div class="rst-block">%s</div>' % 
-                   MarkupRenderer.rst_with_mentions(source))    
+    return literal('<div class="rst-block">%s</div>' %
+                   MarkupRenderer.rst_with_mentions(source))
--- a/rhodecode/model/comment.py	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/model/comment.py	Mon Dec 19 00:11:20 2011 +0200
@@ -4,7 +4,7 @@
     ~~~~~~~~~~~~~~~~~~~~~~~
 
     comments model for RhodeCode
-    
+
     :created_on: Nov 11, 2011
     :author: marcink
     :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
@@ -55,7 +55,7 @@
                line_no=None):
         """
         Creates new comment for changeset
-        
+
         :param text:
         :param repo_id:
         :param user_id:
@@ -84,7 +84,7 @@
             if line_no:
                 line = _('on line %s') % line_no
             subj = h.link_to('Re commit: %(commit_desc)s %(line)s' % \
-                                    {'commit_desc':desc, 'line':line},
+                                    {'commit_desc': desc, 'line': line},
                              h.url('changeset_home', repo_name=repo.repo_name,
                                    revision=revision,
                                    anchor='comment-%s' % comment.comment_id,
@@ -114,7 +114,7 @@
     def delete(self, comment):
         """
         Deletes given comment
-        
+
         :param comment_id:
         """
         comment = self.__get_changeset_comment(comment)
@@ -122,7 +122,6 @@
 
         return comment
 
-
     def get_comments(self, repo_id, revision):
         return ChangesetComment.query()\
                 .filter(ChangesetComment.repo_id == repo_id)\
@@ -137,7 +136,7 @@
             .filter(ChangesetComment.line_no != None)\
             .filter(ChangesetComment.f_path != None).all()
 
-        paths = defaultdict(lambda:defaultdict(list))
+        paths = defaultdict(lambda: defaultdict(list))
 
         for co in comments:
             paths[co.f_path][co.line_no].append(co)
--- a/rhodecode/templates/changeset/diff_block.html	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/templates/changeset/diff_block.html	Mon Dec 19 00:11:20 2011 +0200
@@ -19,7 +19,7 @@
                     <img class="diff-menu-activate" style="margin-bottom:-6px;cursor: pointer" alt="diff-menu" src="${h.url('/images/icons/script_gear.png')}" />
                     <div class="diff-menu" style="display:none">
                         <ul>
-                          <li>${h.link_to(_('diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff'))}</li>
+                          <li>${h.link_to(_('diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff',fulldiff=1))}</li>
                           <li>${h.link_to(_('raw diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='raw'))}</li>
                           <li>${h.link_to(_('download diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='download'))}</li>
                           <li>${c.ignorews_url(h.FID(filenode.changeset.raw_id,filenode.path))}</li>
@@ -37,11 +37,7 @@
         </div>
         <div class="code-body">
             <div class="full_f_path" path="${h.safe_unicode(filenode.path)}"></div>        
-            %if diff:
-                ${diff|n}
-            %else:
-                ${_('No changes in this file')}
-            %endif
+            ${diff|n}
         </div>
     </div>
     %endif
--- a/rhodecode/templates/files/file_diff.html	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/templates/files/file_diff.html	Mon Dec 19 00:11:20 2011 +0200
@@ -21,33 +21,29 @@
     <div class="title">
         ${self.breadcrumbs()}
     </div>
-    <div class="table">
-		<div id="body" class="diffblock">
-			<div class="code-header">
-                <div class="changeset_header">
-                <span class="changeset_file">${h.link_to(c.f_path,h.url('files_home',repo_name=c.repo_name,
-				revision=c.changeset_2.raw_id,f_path=c.f_path))}</span>
-				 &raquo; <span>${h.link_to(_('diff'),
-				h.url.current(diff2=c.changeset_2.raw_id,diff1=c.changeset_1.raw_id,diff='diff'))}</span>
-				 &raquo; <span>${h.link_to(_('raw diff'),
-				h.url.current(diff2=c.changeset_2.raw_id,diff1=c.changeset_1.raw_id,diff='raw'))}</span>
-				 &raquo; <span>${h.link_to(_('download diff'),
-				h.url.current(diff2=c.changeset_2.raw_id,diff1=c.changeset_1.raw_id,diff='download'))}</span>
-				</div>
-			</div>
-			<div class="code-body">
-		 			%if c.no_changes:
-		            	${_('No changes')}
-		            %elif c.big_diff:
-		                ${_('Diff is to big to display')} ${h.link_to(_('raw diff'),
-                           h.url.current(diff2=c.changeset_2.raw_id,diff1=c.changeset_1.raw_id,diff='raw'))}
-		            %else:        
-						${c.cur_diff|n}
-		            %endif
-			</div>
-		</div>   
+    <div>
+    ## diff block       
+    <%namespace name="diff_block" file="/changeset/diff_block.html"/>
+    ${diff_block.diff_block(c.changes)}  
     </div>
 </div>    
+<script>
+YUE.onDOMReady(function(){
+    
+    YUE.on(YUQ('.diff-menu-activate'),'click',function(e){
+        var act = e.currentTarget.nextElementSibling;
+        
+        if(YUD.hasClass(act,'active')){
+            YUD.removeClass(act,'active');
+            YUD.setStyle(act,'display','none');
+        }else{
+            YUD.addClass(act,'active');
+            YUD.setStyle(act,'display','');
+        }
+    });
+
+})
+</script>
 </%def>  
 
    
\ No newline at end of file
--- a/rhodecode/templates/files/files_edit.html	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/templates/files/files_edit.html	Mon Dec 19 00:11:20 2011 +0200
@@ -59,7 +59,7 @@
                 <div class="commit">${_('Editing file')}: ${c.file.path}</div>
             </div>      
 			    <pre id="editor_pre"></pre>
-				<textarea id="editor" name="content" style="display:none">${c.file.content|n}</textarea>
+				<textarea id="editor" name="content" style="display:none">${h.escape(c.file.content)|n}</textarea>
 				<div style="padding: 10px;color:#666666">${_('commit message')}</div>
 				<textarea id="commit" name="message" style="height: 60px;width: 99%;margin-left:4px"></textarea>
 			</div>
--- a/rhodecode/templates/files/files_source.html	Sun Dec 18 04:41:52 2011 +0200
+++ b/rhodecode/templates/files/files_source.html	Mon Dec 19 00:11:20 2011 +0200
@@ -11,7 +11,6 @@
 		</div>
 	</dd>
 </dl>
-
 	
 <div id="body" class="codeblock">
 	<div class="code-header">