From e4397937b550603dff623c5bad23ae792b5ce948 Mon Sep 17 00:00:00 2001 From: "mpm@selenic.com" Date: Mon, 23 May 2005 20:57:48 -0800 Subject: [PATCH] Prettify the web interface Add header, footer templates Add null parent handling Combine files and directories Add parity flag for alternating line colors Add line numbers to filerevision --- hg | 2 +- mercurial/hgweb.py | 115 ++++++++++++++++++++++++++-------- templates/changelog.tmpl | 13 ++-- templates/changelogentry.tmpl | 25 ++++---- templates/changeset.tmpl | 33 +++++----- templates/fileannotate.tmpl | 31 +++++---- templates/filediff.tmpl | 19 +++--- templates/filelog.tmpl | 13 ++-- templates/filelogentry.tmpl | 13 ++-- templates/filerevision.tmpl | 29 ++++----- templates/footer.tmpl | 2 + templates/header.tmpl | 31 +++++++++ templates/manifest.tmpl | 19 +++--- templates/map | 15 +++-- 14 files changed, 223 insertions(+), 137 deletions(-) create mode 100644 templates/footer.tmpl create mode 100644 templates/header.tmpl diff --git a/hg b/hg index 12fb8a1a70..4fd473f293 100644 --- a/hg +++ b/hg @@ -463,7 +463,7 @@ elif cmd == "verify": except Exception, inst: ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst)) errors += 1 - + ff = [ l.split('\0') for l in delta.splitlines() ] for f, fn in ff: filenodes.setdefault(f, {})[hg.bin(fn)] = 1 diff --git a/mercurial/hgweb.py b/mercurial/hgweb.py index 54f816d44a..dac27ffa23 100644 --- a/mercurial/hgweb.py +++ b/mercurial/hgweb.py @@ -122,6 +122,10 @@ class hgweb: if len(files) > self.maxfiles: yield self.t("fileellipses") + def parent(self, t1, node, rev): + if node != hex(nullid): + yield self.t(t1, node = node, rev = rev) + def diff(self, node1, node2, files): def filterfiles(list, files): l = [ x for x in list if x in files ] @@ -169,6 +173,12 @@ class hgweb: tn = "" yield prettyprint(mdiff.unidiff(to, date1, tn, date2, f)) + def header(self): + yield self.t("header", repo = self.reponame) + + def footer(self): + yield self.t("footer", repo = self.reponame) + def changelog(self, pos=None): def changenav(): def seq(factor = 1): @@ -191,6 +201,7 @@ class hgweb: yield self.t("naventry", rev = count - 1) def changelist(): + parity = (start - end) & 1 cl = self.repo.changelog l = [] # build a list in forward order for efficiency for i in range(start, end + 1): @@ -202,9 +213,14 @@ class hgweb: l.insert(0, self.t( 'changelogentry', + parity = parity, author = obfuscate(changes[1]), shortdesc = cgi.escape(changes[4].splitlines()[0]), age = age(t), + parent1 = self.parent("changelogparent", + hex(p1), cl.rev(p1)), + parent2 = self.parent("changelogparent", + hex(p2), cl.rev(p2)), p1 = hex(p1), p2 = hex(p2), p1rev = cl.rev(p1), p2rev = cl.rev(p2), manifest = hex(changes[0]), @@ -213,6 +229,7 @@ class hgweb: files = self.listfilediffs(changes[3], n), rev = i, node = hn)) + parity = 1 - parity yield l @@ -222,8 +239,12 @@ class hgweb: start = max(0, pos - self.maxchanges) end = min(count - 1, start + self.maxchanges) - yield self.t('changelog', repo = self.reponame, changenav = changenav, - rev = pos, changesets = count, changelist = changelist) + yield self.t('changelog', + header = self.header(), + footer = self.footer(), + repo = self.reponame, + changenav = changenav, + rev = pos, changesets = count, entries = changelist) def changeset(self, nodeid): n = bin(nodeid) @@ -243,10 +264,17 @@ class hgweb: yield self.diff(p1, n, changes[3]) yield self.t('changeset', + header = self.header(), + footer = self.footer(), + repo = self.reponame, diff = diff, rev = cl.rev(n), node = nodeid, shortdesc = cgi.escape(changes[4].splitlines()[0]), + parent1 = self.parent("changesetparent", + hex(p1), cl.rev(p1)), + parent2 = self.parent("changesetparent", + hex(p2), cl.rev(p2)), p1 = hex(p1), p2 = hex(p2), p1rev = cl.rev(p1), p2rev = cl.rev(p2), manifest = hex(changes[0]), @@ -262,6 +290,8 @@ class hgweb: def entries(): l = [] + parity = (count - 1) & 1 + for i in range(count): n = fl.node(i) @@ -272,6 +302,7 @@ class hgweb: t = float(cs[2].split(' ')[0]) l.insert(0, self.t("filelogentry", + parity = parity, filenode = hex(n), filerev = i, file = f, @@ -282,10 +313,14 @@ class hgweb: shortdesc = cgi.escape(cs[4].splitlines()[0]), p1 = hex(p1), p2 = hex(p2), p1rev = fl.rev(p1), p2rev = fl.rev(p2))) + parity = 1 - parity yield l yield self.t("filelog", + header = self.header(), + footer = self.footer(), + repo = self.reponame, file = f, filenode = filenode, entries = entries) @@ -301,11 +336,21 @@ class hgweb: p1, p2 = fl.parents(n) t = float(cs[2].split(' ')[0]) mfn = cs[0] + + def lines(): + for l, t in enumerate(text.splitlines(1)): + yield self.t("fileline", + line = t, + linenumber = "% 6d" % (l + 1), + parity = l & 1) yield self.t("filerevision", file = f, + header = self.header(), + footer = self.footer(), + repo = self.reponame, filenode = node, path = up(f), - text = text, + text = lines(), rev = changerev, node = hex(cn), manifest = hex(mfn), @@ -313,6 +358,10 @@ class hgweb: age = age(t), date = time.asctime(time.gmtime(t)), shortdesc = cgi.escape(cs[4].splitlines()[0]), + parent1 = self.parent("filerevparent", + hex(p1), fl.rev(p1)), + parent2 = self.parent("filerevparent", + hex(p2), fl.rev(p2)), p1 = hex(p1), p2 = hex(p2), p1rev = fl.rev(p1), p2rev = fl.rev(p2)) @@ -332,6 +381,8 @@ class hgweb: mfn = cs[0] def annotate(): + parity = 1 + last = None for r, l in fl.annotate(n): try: cnode = ncache[r] @@ -348,7 +399,12 @@ class hgweb: name = name[:f] bcache[r] = name + if last != cnode: + parity = 1 - parity + last = cnode + yield self.t("annotateline", + parity = parity, node = hex(cnode), rev = r, author = name, @@ -356,6 +412,9 @@ class hgweb: line = cgi.escape(l)) yield self.t("fileannotate", + header = self.header(), + footer = self.footer(), + repo = self.reponame, file = f, filenode = node, annotate = annotate, @@ -367,6 +426,10 @@ class hgweb: age = age(t), date = time.asctime(time.gmtime(t)), shortdesc = cgi.escape(cs[4].splitlines()[0]), + parent1 = self.parent("filerevparent", + hex(p1), fl.rev(p1)), + parent2 = self.parent("filerevparent", + hex(p2), fl.rev(p2)), p1 = hex(p1), p2 = hex(p2), p1rev = fl.rev(p1), p2rev = fl.rev(p2)) @@ -375,10 +438,8 @@ class hgweb: rev = self.repo.manifest.rev(bin(mnode)) node = self.repo.changelog.node(rev) - dirs = {} files = {} - short = {} - + p = path[1:] l = len(p) @@ -388,37 +449,41 @@ class hgweb: remain = f[l:] if "/" in remain: short = remain[:remain.find("/") + 1] # bleah - dirs[short] = 1 + files[short] = (f, None) else: short = os.path.basename(remain) files[short] = (f, n) - def dirlist(): - dl = dirs.keys() - dl.sort() - - for d in dl: - yield self.t("manifestdirentry", - path = os.path.join(path, d), - manifest = mnode, basename = d[:-1]) - def filelist(): + parity = 0 fl = files.keys() fl.sort() for f in fl: full, fnode = files[f] - yield self.t("manifestfileentry", - file = full, manifest = mnode, filenode = hex(fnode), - basename = f) + if fnode: + yield self.t("manifestfileentry", + file = full, + manifest = mnode, + filenode = hex(fnode), + parity = parity, + basename = f) + else: + yield self.t("manifestdirentry", + parity = parity, + path = os.path.join(path, f), + manifest = mnode, basename = f[:-1]) + parity = 1 - parity yield self.t("manifest", + header = self.header(), + footer = self.footer(), + repo = self.reponame, manifest = mnode, rev = rev, node = hex(node), path = path, up = up(path), - dirs = dirlist, - files = filelist) + entries = filelist) def filediff(self, file, changeset): n = bin(changeset) @@ -431,6 +496,9 @@ class hgweb: yield self.diff(p1, n, file) yield self.t("filediff", + header = self.header(), + footer = self.footer(), + repo = self.reponame, file = file, filenode = hex(mf[file]), node = changeset, @@ -439,12 +507,7 @@ class hgweb: p1rev = self.repo.changelog.rev(p1), diff = diff) - # header and footer, css # add tags to things - # show parents - # diff between rev and parent in changeset and file - # manifest links - # browse at top # tags -> list of changesets corresponding to tags # find tag, changeset, file diff --git a/templates/changelog.tmpl b/templates/changelog.tmpl index 19abb2c761..390f13ff08 100644 --- a/templates/changelog.tmpl +++ b/templates/changelog.tmpl @@ -1,16 +1,13 @@ -Content-Type: text/html - - +#header# +#repo#: changelog +

changelog for #repo#

navigate: #changenav#
- -#changelist# -
+#entries# navigate: #changenav#
- - \ No newline at end of file +#footer# diff --git a/templates/changelogentry.tmpl b/templates/changelogentry.tmpl index e6051f8f32..dcdcf5f1d3 100644 --- a/templates/changelogentry.tmpl +++ b/templates/changelogentry.tmpl @@ -1,26 +1,25 @@ +
+ - + - + +#parent1# +#parent2# - - - - - - - + - + - + - + - +
#age# ago:#age# ago:  #shortdesc#
revision:revision:  #rev#:#node#
parent:#p1rev#:#p1#
parent:#p2rev#:#p2#
manifest:manifest:  #rev#:#manifest#
author:author:  #author#
date:date:  #date#
files:files:  #files#
+
diff --git a/templates/changeset.tmpl b/templates/changeset.tmpl index b29d57d45f..3d79104324 100644 --- a/templates/changeset.tmpl +++ b/templates/changeset.tmpl @@ -1,42 +1,39 @@ -Content-type: text/html - - +#header# +#repo#: changeset #node# + + +
changelog manifest +

changeset: #shortdesc#

- + +#parent1# +#parent2# - - - - - - - + - + - + - + - +
revision:revision: #rev#:#node#
parent:#p1rev#:#p1#
parent:#p2rev#:#p2#
manifest:manifest: #rev#:#manifest#
author:author: #author#
date:date: #date#
files:files: #files#
description:description: #desc#
-
- -
+
 #diff#
 
diff --git a/templates/fileannotate.tmpl b/templates/fileannotate.tmpl index 637c9b1ca9..c460ce51a2 100644 --- a/templates/fileannotate.tmpl +++ b/templates/fileannotate.tmpl @@ -1,42 +1,39 @@ -Content-type: text/html - - +#header# +#repo#: #file# annotate + +

Annotate #file# (#filenode#)

- + +#parent1# +#parent2# - - - - - - - + - + - +
changeset:changeset: #rev#:#node#
parent:#p1rev#:#p1#
parent:#p2rev#:#p2#
manifest:manifest: #rev#:#manifest#
author:author: #author#
date:date: #date#
-
+
- +
#annotate#
- - \ No newline at end of file +#footer# diff --git a/templates/filediff.tmpl b/templates/filediff.tmpl index 3b34bb8535..aaf5188f84 100644 --- a/templates/filediff.tmpl +++ b/templates/filediff.tmpl @@ -1,30 +1,31 @@ -Content-type: text/html - - +#header# +#repo#: #file# diff + + +

#file#

- + - +
revision:revision: #rev#:#node#
parent:parent: #p1rev#:#p1#
-
-
+
 #diff#
 
- - +#header# +#repo#: #file# history + +

#file# revision history

- #entries# -
- - \ No newline at end of file +#footer# diff --git a/templates/filelogentry.tmpl b/templates/filelogentry.tmpl index 5f3c688ab2..084a5c52d6 100644 --- a/templates/filelogentry.tmpl +++ b/templates/filelogentry.tmpl @@ -1,18 +1,19 @@ + - - + - + - + - + - +
#age# ago:#shortdesc# + #age# ago: #shortdesc#
revision:revision:  #filerev#:#filenode# (diff) (annotate)
author:author:  #author#
date:date:  #date#
diff --git a/templates/filerevision.tmpl b/templates/filerevision.tmpl index c851386e5d..e8c1364979 100644 --- a/templates/filerevision.tmpl +++ b/templates/filerevision.tmpl @@ -1,42 +1,37 @@ -Content-type: text/html - - +#header# +#repo#:#file# + +

#file# (revision #filenode#)

- + +#parent1# +#parent2# - - - - - - - + - + - +
changeset:changeset: #rev#:#node#
parent:#p1rev#:#p1#
parent:#p2rev#:#p2#
manifest:manifest: #rev#:#manifest#
author:author: #author#
date:date: #date#
-
-
 #text#
 
- - \ No newline at end of file +#footer# diff --git a/templates/footer.tmpl b/templates/footer.tmpl new file mode 100644 index 0000000000..308b1d01b6 --- /dev/null +++ b/templates/footer.tmpl @@ -0,0 +1,2 @@ + + diff --git a/templates/header.tmpl b/templates/header.tmpl new file mode 100644 index 0000000000..2f499acc06 --- /dev/null +++ b/templates/header.tmpl @@ -0,0 +1,31 @@ +Content-type: text/html + + + + + + + + diff --git a/templates/manifest.tmpl b/templates/manifest.tmpl index 3c397ab1f4..91b4d5bc34 100644 --- a/templates/manifest.tmpl +++ b/templates/manifest.tmpl @@ -1,19 +1,16 @@ -Content-Type: text/html - - +#header# +#repo#: manifest #manifest# + +

manifest: #path#

-

(#rev#:#manifest#)

-

-[up]
-#dirs#

+ +#entries# -

#files#

- - - \ No newline at end of file +#footer# \ No newline at end of file diff --git a/templates/map b/templates/map index 839bd8ee76..33f03fa040 100644 --- a/templates/map +++ b/templates/map @@ -1,3 +1,5 @@ +header = header.tmpl +footer = footer.tmpl changelog = changelog.tmpl naventry = "#rev# " filedifflink = "#file# " @@ -6,15 +8,20 @@ fileellipses = "..." changelogentry = changelogentry.tmpl changeset = changeset.tmpl manifest = manifest.tmpl -manifestdirentry = "#basename#/
" -manifestfileentry = "#basename#
" +manifestdirentry = "" +manifestfileentry = "" filerevision = filerevision.tmpl fileannotate = fileannotate.tmpl filediff = filediff.tmpl filelog = filelog.tmpl +fileline = "
#linenumber# #line#
" filelogentry = filelogentry.tmpl -annotateline = "#author#@#rev#:
#line#
" +annotateline = "#author#@#rev#
#line#
" difflineplus = "#line#" difflineminus = "#line#" difflineat = "#line#" -diffline = "#line#" \ No newline at end of file +diffline = "#line#" +changelogparent = "parent: #rev#:#node#" +changesetparent = "parent:#rev#:#node#" +filerevparent = "parent:#rev#:#node#" +fileannotateparent = "parent:#rev#:#node#"