Merge lp:~jstpierre/loggerhead/css-changes into lp:loggerhead

Proposed by Jasper St. Pierre
Status: Merged
Approved by: John A Meinel
Approved revision: 450
Merged at revision: 448
Proposed branch: lp:~jstpierre/loggerhead/css-changes
Merge into: lp:loggerhead
Diff against target: 260 lines (+80/-65)
6 files modified
loggerhead/controllers/annotate_ui.py (+29/-13)
loggerhead/controllers/view_ui.py (+4/-4)
loggerhead/static/css/global.css (+1/-1)
loggerhead/static/css/view.css (+24/-20)
loggerhead/templates/inventory.pt (+6/-10)
loggerhead/templates/view.pt (+16/-17)
To merge this branch: bzr merge lp:~jstpierre/loggerhead/css-changes
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+58855@code.launchpad.net
To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

I like the idea of the changes. But I did a quick test and the annotation column on the left 'blew up' and consumed pretty much the whole screen.

I don't think it is really usable in that state. If we can find a way to prevent the annotation information from consuming so much width I think this is ready to land.

Another thing that would be nice, but certainly doesn't block this, is if the columns were split, such that selecting text would not give you the annotations. Certainly doesn't have to be done to get this landed.

But I think it would be a usability regression if we landed this as is, because many pages will push the content you want to see off to the right.

review: Needs Fixing
Revision history for this message
Jasper St. Pierre (jstpierre) wrote :

"the content you want to see"

Isn't the content you want to see the annotation?

Anyway, HTML is a mess, and I'd like to figure out how to do this properly, but after Googling and talking with people, it looks like max-width is ignored for tables, so I can't use that.

Ideally, I'd really like three columns:

=============================
 Annotation | Line | Content
=============================

 * Annotation should take up the minimum amount of space without wrapping, with a maximum width of 25%., in which case it should wrap.
 * Line should be 20px or so, like it is now.
 * Content should have all of the extra space, if there is any. Not Annotation or Line.

I don't feel this is possible with just HTML or CSS, which is extremely disappointing.

The closest I've gotten is:

td.annotation {
    max-width: 25%;
    white-space: nowrap;
}

But then Content doesn't get all of the extra space (it could be in Annotation).

Revision history for this message
Robert Collins (lifeless) wrote :

@jam are your concerned addressed? I think jasper is stalled at the moment.

Revision history for this message
John A Meinel (jameinel) wrote :

I don't think this is perfect, but my CSS is far worse than Jasper's. So I don't have anything better to put here, and I think on the whole it is better than the current layout.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'loggerhead/controllers/annotate_ui.py'
2--- loggerhead/controllers/annotate_ui.py 2010-12-01 08:30:02 +0000
3+++ loggerhead/controllers/annotate_ui.py 2011-04-22 21:35:57 +0000
4@@ -16,6 +16,8 @@
5 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 #
7
8+import itertools
9+
10 from loggerhead.controllers.view_ui import ViewUI
11 from loggerhead import util
12
13@@ -29,23 +31,37 @@
14
15 change_cache = {}
16 last_line_revid = None
17- parity = 1
18- for line_revid, text in tree.annotate_iter(file_id):
19- if line_revid == last_line_revid:
20- # remember which lines have a new revno and which don't
21- new_rev = False
22- else:
23- new_rev = True
24- parity ^= 1
25+ last_lineno = None
26+ message = ""
27+
28+ revisions = {}
29+
30+ lineno = 0
31+ for (line_revid, text), lineno in zip(tree.annotate_iter(file_id), itertools.count(1)):
32+ if line_revid != last_line_revid:
33 last_line_revid = line_revid
34- if line_revid in change_cache:
35- change = change_cache[line_revid]
36- else:
37+
38+ change = change_cache.get(line_revid, None)
39+ if change is None:
40 change = self._history.get_changes([line_revid])[0]
41 change_cache[line_revid] = change
42
43- yield util.Container(
44- parity=parity, new_rev=new_rev, change=change)
45+ message = change.comment.splitlines()[0]
46+
47+ if last_lineno:
48+ # The revspan is of lines between the last revision and this one.
49+ # We set the one for the previous revision when we're creating the current revision.
50+ revisions[last_lineno].revspan = lineno - last_lineno
51+
52+ revisions[lineno] = util.Container(change=change, message=message)
53+
54+ last_lineno = lineno
55+ last_line_revid = line_revid
56+
57+ # We never set a revspan for the last revision during the loop above, so set it here.
58+ revisions[last_lineno].revspan = lineno - last_lineno + 1
59+
60+ return revisions
61
62 def get_values(self, path, kwargs, headers):
63 values = super(AnnotateUI, self).get_values(path, kwargs, headers)
64
65=== modified file 'loggerhead/controllers/view_ui.py'
66--- loggerhead/controllers/view_ui.py 2011-03-23 02:37:07 +0000
67+++ loggerhead/controllers/view_ui.py 2011-04-22 21:35:57 +0000
68@@ -123,10 +123,10 @@
69 raise HTTPMovedPermanently(self._branch.context_url(['/files', revno_url, path]))
70
71 return {
72- # In AnnotateUI, "annotated" is a generator giving revision
73- # numbers per lines, but the template checks if "annotated" is
74- # true or not before using it, so we have to define it here also.
75- 'annotated': False,
76+ # In AnnotateUI, "annotated" is a dictionary mapping lines to changes.
77+ # We exploit the fact that bool({}) is False when checking whether
78+ # we're in "annotated" mode.
79+ 'annotated': {},
80 'revno_url': revno_url,
81 'file_id': file_id,
82 'file_path': path,
83
84=== modified file 'loggerhead/static/css/global.css'
85--- loggerhead/static/css/global.css 2011-02-24 00:44:09 +0000
86+++ loggerhead/static/css/global.css 2011-04-22 21:35:57 +0000
87@@ -152,6 +152,7 @@
88 float: left;
89 display: inline;
90 height: 22px;
91+ line-height: 22px;
92 padding: 0 0 0 18px;
93 background: transparent url(../images/ico_description.gif) no-repeat center left;
94 }
95@@ -163,7 +164,6 @@
96 }
97
98 #branch-info {
99- width: 900px;
100 padding: 10px;
101 margin: 0 0 10px 0;
102 color: #666;
103
104=== modified file 'loggerhead/static/css/view.css'
105--- loggerhead/static/css/view.css 2011-02-18 05:41:17 +0000
106+++ loggerhead/static/css/view.css 2011-04-22 21:35:57 +0000
107@@ -1,31 +1,30 @@
108 /*table*/
109-.viewLineTit,
110-.viewRevTit,
111-.viewContTit {
112+#logentries,
113+.viewRev,
114+.viewLine {
115 border: 1px solid #d2d2d2;
116- }
117-.viewLine,
118-.viewRev,
119+}
120+.viewRev {
121+ border-right: none;
122+ white-space: nowrap;
123+ width: 1px;
124+ padding: .3em .6em;
125+}
126 .viewComm,
127 .viewCont {
128 border: none;
129 }
130-.viewLine,
131-.viewLineTit {
132+.viewLine {
133+ border-style: none solid none none;
134+ width: 20px;
135+ padding-left: .6em;
136 padding-right: .2em;
137 }
138-.viewLine {
139- width: 37px;
140- }
141-.viewContTit,
142+.viewLine.first {
143+ border-style: solid solid none none;
144+}
145 .viewCont {
146- width: auto;
147- padding-left: .3em;
148- }
149-.viewRevTit,
150-.viewRev {
151- width: 70px;
152- text-align: center;
153+ padding-left: .4em;
154 }
155 .viewLine,
156 .viewCont {
157@@ -38,6 +37,11 @@
158 margin: 0;
159 }
160 .viewLine {
161- text-align: right;
162+ text-align: center;
163+ }
164+.viewLine {
165 font-size: 93%;
166 }
167+.viewAuthors {
168+ color: #999999;
169+}
170
171=== modified file 'loggerhead/templates/inventory.pt'
172--- loggerhead/templates/inventory.pt 2011-02-23 03:01:15 +0000
173+++ loggerhead/templates/inventory.pt 2011-04-22 21:35:57 +0000
174@@ -19,22 +19,18 @@
175 </tal:has-link>
176 </tal:block>
177 <tal:block metal:fill-slot="branchname" tal:content="string:${branch/friendly_name}" />
178- <tal:block metal:fill-slot="heading">
179- <div id="breadcrumbs">
180+ <tal:block metal:fill-slot="heading">
181+ <div id="breadcrumbs">
182 <tal:has-link condition="branch/branch_link">
183 <a tal:attributes="href branch/branch_link"
184 tal:content="branch/friendly_name">
185 nice/branch/name
186 </a>
187 </tal:has-link>
188- <span tal:condition="not: branch/branch_link">
189- <span metal:use-macro="breadcrumbs/directory" />
190- </span>
191- <tal:block condition="python:change">
192- &#187; Viewing
193- <span metal:use-macro="breadcrumbs/branch" />
194- for revision <span tal:content="change/revno"/>
195- </tal:block>
196+ <tal:no-link condition="not: branch/branch_link">
197+ <span metal:use-macro="breadcrumbs/directory"></span>
198+ </tal:no-link>
199+ <span>: <span metal:use-macro="breadcrumbs/branch" /> (revision <tal:revno content="change/revno"></tal:revno>)</span>
200 </div>
201 </tal:block>
202
203
204=== modified file 'loggerhead/templates/view.pt'
205--- loggerhead/templates/view.pt 2011-02-23 03:01:15 +0000
206+++ loggerhead/templates/view.pt 2011-04-22 21:35:57 +0000
207@@ -49,11 +49,11 @@
208 </li>
209 <li tal:condition="not:annotated">
210 <a tal:attributes="href python:url(['/annotate', revno_url, file_path], clear=1)"
211- >view revision numbers per line</a>
212+ >view with revision information</a>
213 </li>
214 <li tal:condition="annotated">
215 <a tal:attributes="href python:url(['/view', revno_url, file_path], clear=1)"
216- >view without revision numbers</a>
217+ >view without revision information</a>
218 </li>
219 <li>
220 <a tal:attributes="href python:url(['/revision', change.revno], clear=1)">view revision</a>
221@@ -71,25 +71,24 @@
222
223 <div class="view">
224 <table id="logentries">
225- <tr class="logheader">
226- <th class="viewLineTit">Line</th>
227- <th class="viewRevTit" tal:condition="annotated">Revision</th>
228- <th class="viewContTit">Contents</th>
229- </tr>
230-
231 <tal:rep tal:repeat="line contents">
232- <tr tal:define="anno python:annotated and annotated.next()"
233- tal:attributes="class python:anno and 'blueRow' + str(anno.parity) or None">
234- <td class="viewLine">
235+ <tr>
236+ <td tal:condition="python:path('repeat/line/number') in annotated"
237+ tal:define="anno python:annotated.get(path('repeat/line/number'), None)"
238+ tal:attributes="rowspan python:anno.revspan"
239+ class="viewRev">
240+ <a tal:content="python:'%s' % (anno.change.revno,)"
241+ tal:attributes="href python:url(['/revision', anno.change.revno], clear=1);
242+ title python:'%s by %s, on %s (%s)' % (anno.change.revno, ', '.join(util.hide_emails(anno.change.authors)), anno.change.date.strftime('%d %b %Y %H:%M'), util.date_time(anno.change.date))"></a>
243+ <span class="viewAuthors" tal:content="python:'by ' + ', '.join(util.hide_emails(anno.change.authors))" />
244+ <br />
245+
246+ <span tal:content="python:anno.message"></span>
247+ </td>
248+ <td tal:attributes="class python:path('repeat/line/number') in annotated and 'viewLine first' or 'viewLine'">
249 <a tal:attributes="id string:L${repeat/line/number}; href string:#L${repeat/line/number}"
250 tal:content="repeat/line/number">1</a>
251 </td>
252- <td class="viewRev" tal:condition="annotated">
253- <a tal:condition="python:anno.new_rev"
254- tal:content="python:util.trunc(anno.change.revno)"
255- tal:attributes="href python:url(['/revision', anno.change.revno], clear=1);
256- title python:'%s by %s, on %s (%s)' % (anno.change.revno, ', '.join(util.hide_emails(anno.change.authors)), anno.change.date.strftime('%d %b %Y %H:%M'), util.date_time(anno.change.date))"></a>
257- </td>
258 <td class="viewCont"><pre tal:content="structure line"></pre></td>
259 </tr>
260 </tal:rep>

Subscribers

People subscribed via source and target branches