diff --git a/mercurial/hgweb/hgweb_mod.py b/mercurial/hgweb/hgweb_mod.py --- a/mercurial/hgweb/hgweb_mod.py +++ b/mercurial/hgweb/hgweb_mod.py @@ -237,14 +237,17 @@ class hgweb(object): # figure out which style to use vars = {} - style = self.config("web", "style", "paper") - if 'style' in req.form: - style = req.form['style'][0] + styles = ( + req.form.get('style', [None])[0], + self.config('web', 'style'), + 'paper', + ) + style, mapfile = templater.stylemap(styles, self.templatepath) + if style == styles[0]: vars['style'] = style start = req.url[-1] == '?' and '&' or '?' sessionvars = webutil.sessionvars(vars, start) - mapfile = templater.stylemap(style, self.templatepath) if not self.reponame: self.reponame = (self.config("web", "name") diff --git a/mercurial/hgweb/hgwebdir_mod.py b/mercurial/hgweb/hgwebdir_mod.py --- a/mercurial/hgweb/hgwebdir_mod.py +++ b/mercurial/hgweb/hgwebdir_mod.py @@ -315,18 +315,21 @@ class hgwebdir(object): url += '/' vars = {} - style = self.style - if 'style' in req.form: - vars['style'] = style = req.form['style'][0] + styles = ( + req.form.get('style', [None])[0], + config('web', 'style'), + 'paper' + ) + style, mapfile = templater.stylemap(styles) + if style == styles[0]: + vars['style'] = style + start = url[-1] == '?' and '&' or '?' sessionvars = webutil.sessionvars(vars, start) - staticurl = config('web', 'staticurl') or url + 'static/' if not staticurl.endswith('/'): staticurl += '/' - style = 'style' in req.form and req.form['style'][0] or self.style - mapfile = templater.stylemap(style) tmpl = templater.templater(mapfile, defaults={"header": header, "footer": footer, diff --git a/mercurial/templater.py b/mercurial/templater.py --- a/mercurial/templater.py +++ b/mercurial/templater.py @@ -220,7 +220,7 @@ def templatepath(name=None): return normpaths -def stylemap(style, paths=None): +def stylemap(styles, paths=None): """Return path to mapfile for a given style. Searches mapfile in the following locations: @@ -234,12 +234,20 @@ def stylemap(style, paths=None): elif isinstance(paths, str): paths = [paths] - locations = style and [os.path.join(style, "map"), "map-" + style] or [] - locations.append("map") - for path in paths: - for location in locations: - mapfile = os.path.join(path, location) - if os.path.isfile(mapfile): - return mapfile + if isinstance(styles, str): + styles = [styles] + + for style in styles: + + if not style: + continue + locations = [os.path.join(style, 'map'), 'map-' + style] + locations.append('map') + + for path in paths: + for location in locations: + mapfile = os.path.join(path, location) + if os.path.isfile(mapfile): + return style, mapfile raise RuntimeError("No hgweb templates found in %r" % paths) diff --git a/tests/test-hgweb b/tests/test-hgweb --- a/tests/test-hgweb +++ b/tests/test-hgweb @@ -7,8 +7,10 @@ mkdir da echo foo > da/foo echo foo > foo hg ci -Ambase + hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log cat hg.pid >> $DAEMON_PIDS + echo % manifest ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/?style=raw') ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/da?style=raw') @@ -30,6 +32,9 @@ echo % should give a 404 - file does not "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/bork' "$TESTDIR/get-with-headers.py" localhost:$HGPORT '/diff/tip/bork?style=raw' +echo % try bad style +("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/file/tip/?style=foobar') + echo % stop and restart "$TESTDIR/killdaemons.py" hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log diff --git a/tests/test-hgweb.out b/tests/test-hgweb.out --- a/tests/test-hgweb.out +++ b/tests/test-hgweb.out @@ -148,8 +148,96 @@ 404 Not Found error: bork@2ef0ac749a14: not found in manifest +% try bad style +200 Script output follows + + + + + + + + +test: 2ef0ac749a14 / + + + +
+ + +
+

test

+

directory / @ 0:2ef0ac749a14 tip

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
namesizepermissions
[up]drwxr-xr-x
+ +dir. da/ + + + + +drwxr-xr-x
+ +file foo + +4-rw-r--r--
+
+
+ + + + + % stop and restart -9 log lines written +10 log lines written % static file 200 Script output follows