##// END OF EJS Templates
hgweb: re-implement followlines UI selection using buttons...
Denis Laxalde -
r33390:32331f54 default
parent child Browse files
Show More
@@ -1,336 +1,336 b''
1 default = 'summary'
1 default = 'summary'
2 mimetype = 'text/html; charset={encoding}'
2 mimetype = 'text/html; charset={encoding}'
3 header = header.tmpl
3 header = header.tmpl
4 footer = footer.tmpl
4 footer = footer.tmpl
5 search = search.tmpl
5 search = search.tmpl
6 changelog = changelog.tmpl
6 changelog = changelog.tmpl
7 summary = summary.tmpl
7 summary = summary.tmpl
8 error = error.tmpl
8 error = error.tmpl
9 notfound = notfound.tmpl
9 notfound = notfound.tmpl
10
10
11 help = help.tmpl
11 help = help.tmpl
12 helptopics = helptopics.tmpl
12 helptopics = helptopics.tmpl
13
13
14 helpentry = '
14 helpentry = '
15 <tr><td>
15 <tr><td>
16 <a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
16 <a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
17 {if(basename, '{basename|escape}', '{topic|escape}')}
17 {if(basename, '{basename|escape}', '{topic|escape}')}
18 </a>
18 </a>
19 </td><td>
19 </td><td>
20 {summary|escape}
20 {summary|escape}
21 </td></tr>'
21 </td></tr>'
22
22
23 naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
23 naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
24 navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
24 navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
25 navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
25 navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
26 filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
26 filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
27 filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
27 filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
28 filenodelink = '
28 filenodelink = '
29 <tr class="parity{parity}">
29 <tr class="parity{parity}">
30 <td><a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
30 <td><a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
31 <td></td>
31 <td></td>
32 <td class="link">
32 <td class="link">
33 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
33 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
34 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
34 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
35 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
35 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
36 <a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
36 <a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
37 <a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
37 <a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
38 </td>
38 </td>
39 </tr>'
39 </tr>'
40 filenolink = '
40 filenolink = '
41 <tr class="parity{parity}">
41 <tr class="parity{parity}">
42 <td><a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
42 <td><a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a></td>
43 <td></td>
43 <td></td>
44 <td class="link">
44 <td class="link">
45 file |
45 file |
46 annotate |
46 annotate |
47 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
47 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
48 <a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
48 <a href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">comparison</a> |
49 <a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
49 <a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">revisions</a>
50 </td>
50 </td>
51 </tr>'
51 </tr>'
52
52
53 nav = '{before%naventry} {after%naventry}'
53 nav = '{before%naventry} {after%naventry}'
54 navshort = '{before%navshortentry}{after%navshortentry}'
54 navshort = '{before%navshortentry}{after%navshortentry}'
55 navgraph = '{before%navgraphentry}{after%navgraphentry}'
55 navgraph = '{before%navgraphentry}{after%navgraphentry}'
56 filenav = '{before%filenaventry}{after%filenaventry}'
56 filenav = '{before%filenaventry}{after%filenaventry}'
57
57
58 fileellipses = '...'
58 fileellipses = '...'
59 changelogentry = changelogentry.tmpl
59 changelogentry = changelogentry.tmpl
60 searchentry = changelogentry.tmpl
60 searchentry = changelogentry.tmpl
61 changeset = changeset.tmpl
61 changeset = changeset.tmpl
62 manifest = manifest.tmpl
62 manifest = manifest.tmpl
63 direntry = '
63 direntry = '
64 <tr class="parity{parity}">
64 <tr class="parity{parity}">
65 <td style="font-family:monospace">drwxr-xr-x</td>
65 <td style="font-family:monospace">drwxr-xr-x</td>
66 <td style="font-family:monospace"></td>
66 <td style="font-family:monospace"></td>
67 <td style="font-family:monospace"></td>
67 <td style="font-family:monospace"></td>
68 <td>
68 <td>
69 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
69 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
70 <a href="{url|urlescape}file/{symrev}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
70 <a href="{url|urlescape}file/{symrev}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">{emptydirs|escape}</a>
71 </td>
71 </td>
72 <td class="link">
72 <td class="link">
73 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">files</a>
73 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">files</a>
74 </td>
74 </td>
75 </tr>'
75 </tr>'
76 fileentry = '
76 fileentry = '
77 <tr class="parity{parity}">
77 <tr class="parity{parity}">
78 <td style="font-family:monospace">{permissions|permissions}</td>
78 <td style="font-family:monospace">{permissions|permissions}</td>
79 <td style="font-family:monospace" align=right>{date|isodate}</td>
79 <td style="font-family:monospace" align=right>{date|isodate}</td>
80 <td style="font-family:monospace" align=right>{size}</td>
80 <td style="font-family:monospace" align=right>{size}</td>
81 <td class="list">
81 <td class="list">
82 <a class="list" href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
82 <a class="list" href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">{basename|escape}</a>
83 </td>
83 </td>
84 <td class="link">
84 <td class="link">
85 <a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
85 <a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
86 <a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
86 <a href="{url|urlescape}log/{symrev}/{file|urlescape}{sessionvars%urlparameter}">revisions</a> |
87 <a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
87 <a href="{url|urlescape}annotate/{symrev}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
88 </td>
88 </td>
89 </tr>'
89 </tr>'
90 filerevision = filerevision.tmpl
90 filerevision = filerevision.tmpl
91 fileannotate = fileannotate.tmpl
91 fileannotate = fileannotate.tmpl
92 filediff = filediff.tmpl
92 filediff = filediff.tmpl
93 filecomparison = filecomparison.tmpl
93 filecomparison = filecomparison.tmpl
94 filelog = filelog.tmpl
94 filelog = filelog.tmpl
95 fileline = '
95 fileline = '
96 <a href="#{lineid}"></a><span id="{lineid}">{strip(line|escape, '\r\n')}</span>'
96 <a href="#{lineid}"></a><span id="{lineid}">{strip(line|escape, '\r\n')}</span>'
97 annotateline = '
97 annotateline = '
98 <tr id="{lineid}" style="font-family:monospace" class="parity{parity}{ifeq(node, originalnode, ' thisrev')}">
98 <tr id="{lineid}" style="font-family:monospace" class="parity{parity}{ifeq(node, originalnode, ' thisrev')}">
99 <td class="annotate linenr parity{blockparity}" style="text-align: right;">
99 <td class="annotate linenr parity{blockparity}" style="text-align: right;">
100 {if(blockhead,
100 {if(blockhead,
101 '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
101 '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
102 {rev}
102 {rev}
103 </a>')}
103 </a>')}
104 <div class="annotate-info">
104 <div class="annotate-info">
105 <div>
105 <div>
106 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
106 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
107 {node|short}</a>
107 {node|short}</a>
108 {desc|escape|firstline}
108 {desc|escape|firstline}
109 </div>
109 </div>
110 <div><em>{author|obfuscate}</em></div>
110 <div><em>{author|obfuscate}</em></div>
111 <div>parents: {parents%annotateparent}</div>
111 <div>parents: {parents%annotateparent}</div>
112 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>
112 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>
113 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
113 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
114 </div>
114 </div>
115 </td>
115 </td>
116 <td><pre><a class="linenr" href="#{lineid}">{linenumber}</a></pre></td>
116 <td class="followlines-btn-parent"><pre><a class="linenr" href="#{lineid}">{linenumber}</a></pre></td>
117 <td><pre>{line|escape}</pre></td>
117 <td><pre>{line|escape}</pre></td>
118 </tr>'
118 </tr>'
119 annotateparent = '
119 annotateparent = '
120 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rev}</a>'
120 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rev}</a>'
121 difflineplus = '
121 difflineplus = '
122 <a href="#{lineid}"></a><span id="{lineid}" class="difflineplus">{strip(line|escape, '\r\n')}</span>'
122 <a href="#{lineid}"></a><span id="{lineid}" class="difflineplus">{strip(line|escape, '\r\n')}</span>'
123 difflineminus = '
123 difflineminus = '
124 <a href="#{lineid}"></a><span id="{lineid}" class="difflineminus">{strip(line|escape, '\r\n')}</span>'
124 <a href="#{lineid}"></a><span id="{lineid}" class="difflineminus">{strip(line|escape, '\r\n')}</span>'
125 difflineat = '
125 difflineat = '
126 <a href="#{lineid}"></a><span id="{lineid}" class="difflineat">{strip(line|escape, '\r\n')}</span>'
126 <a href="#{lineid}"></a><span id="{lineid}" class="difflineat">{strip(line|escape, '\r\n')}</span>'
127 diffline = '
127 diffline = '
128 <a href="#{lineid}"></a><span id="{lineid}">{strip(line|escape, '\r\n')}</span>'
128 <a href="#{lineid}"></a><span id="{lineid}">{strip(line|escape, '\r\n')}</span>'
129
129
130 comparisonblock ='
130 comparisonblock ='
131 <tbody class="block">
131 <tbody class="block">
132 {lines}
132 {lines}
133 </tbody>'
133 </tbody>'
134 comparisonline = '
134 comparisonline = '
135 <tr id="{lineid}" style="font-family:monospace">
135 <tr id="{lineid}" style="font-family:monospace">
136 <td class="{type}"><pre><a class="linenr" href="#{lineid}">{leftlinenumber}</a> {leftline|escape}</pre></td>
136 <td class="{type}"><pre><a class="linenr" href="#{lineid}">{leftlinenumber}</a> {leftline|escape}</pre></td>
137 <td class="{type}"><pre><a class="linenr" href="#{lineid}">{rightlinenumber}</a> {rightline|escape}</pre></td>
137 <td class="{type}"><pre><a class="linenr" href="#{lineid}">{rightlinenumber}</a> {rightline|escape}</pre></td>
138 </tr>'
138 </tr>'
139
139
140 changesetlink = '<a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
140 changesetlink = '<a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
141 changesetbranch = '<tr><td>branch</td><td>{name|escape}</td></tr>'
141 changesetbranch = '<tr><td>branch</td><td>{name|escape}</td></tr>'
142 changesetparent = '
142 changesetparent = '
143 <tr>
143 <tr>
144 <td>parent {rev}</td>
144 <td>parent {rev}</td>
145 <td style="font-family:monospace">
145 <td style="font-family:monospace">
146 {changesetlink}
146 {changesetlink}
147 </td>
147 </td>
148 </tr>'
148 </tr>'
149 changesetparentdiff = '
149 changesetparentdiff = '
150 <tr>
150 <tr>
151 <td>parent {rev}</td>
151 <td>parent {rev}</td>
152 <td style="font-family:monospace">
152 <td style="font-family:monospace">
153 {changesetlink} {ifeq(node, basenode, '(current diff)', '({difffrom})')}
153 {changesetlink} {ifeq(node, basenode, '(current diff)', '({difffrom})')}
154 </td>
154 </td>
155 </tr>'
155 </tr>'
156 difffrom = '<a href="{url|urlescape}rev/{node|short}:{originalnode|short}{sessionvars%urlparameter}">diff</a>'
156 difffrom = '<a href="{url|urlescape}rev/{node|short}:{originalnode|short}{sessionvars%urlparameter}">diff</a>'
157 filerevbranch = '<tr><td>branch</td><td>{name|escape}</td></tr>'
157 filerevbranch = '<tr><td>branch</td><td>{name|escape}</td></tr>'
158 filerevparent = '
158 filerevparent = '
159 <tr>
159 <tr>
160 <td>parent {rev}</td>
160 <td>parent {rev}</td>
161 <td style="font-family:monospace">
161 <td style="font-family:monospace">
162 <a class="list" href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
162 <a class="list" href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
163 {rename%filerename}{node|short}
163 {rename%filerename}{node|short}
164 </a>
164 </a>
165 </td>
165 </td>
166 </tr>'
166 </tr>'
167 filerename = '{file|escape}@'
167 filerename = '{file|escape}@'
168 filelogrename = '| <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
168 filelogrename = '| <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">base</a>'
169 fileannotateparent = '
169 fileannotateparent = '
170 <tr>
170 <tr>
171 <td>parent {rev}</td>
171 <td>parent {rev}</td>
172 <td style="font-family:monospace">
172 <td style="font-family:monospace">
173 <a class="list" href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
173 <a class="list" href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
174 {rename%filerename}{node|short}
174 {rename%filerename}{node|short}
175 </a>
175 </a>
176 </td>
176 </td>
177 </tr>'
177 </tr>'
178 changesetchild = '
178 changesetchild = '
179 <tr>
179 <tr>
180 <td>child {rev}</td>
180 <td>child {rev}</td>
181 <td style="font-family:monospace">
181 <td style="font-family:monospace">
182 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
182 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
183 </td>
183 </td>
184 </tr>'
184 </tr>'
185 filerevchild = '
185 filerevchild = '
186 <tr>
186 <tr>
187 <td>child {rev}</td>
187 <td>child {rev}</td>
188 <td style="font-family:monospace">
188 <td style="font-family:monospace">
189 <a class="list" href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
189 <a class="list" href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
190 </tr>'
190 </tr>'
191 fileannotatechild = '
191 fileannotatechild = '
192 <tr>
192 <tr>
193 <td>child {rev}</td>
193 <td>child {rev}</td>
194 <td style="font-family:monospace">
194 <td style="font-family:monospace">
195 <a class="list" href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
195 <a class="list" href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a></td>
196 </tr>'
196 </tr>'
197 tags = tags.tmpl
197 tags = tags.tmpl
198 tagentry = '
198 tagentry = '
199 <tr class="parity{parity}">
199 <tr class="parity{parity}">
200 <td class="age"><i class="age">{date|rfc822date}</i></td>
200 <td class="age"><i class="age">{date|rfc822date}</i></td>
201 <td><a class="list" href="{url|urlescape}rev/{tag|revescape}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
201 <td><a class="list" href="{url|urlescape}rev/{tag|revescape}{sessionvars%urlparameter}"><b>{tag|escape}</b></a></td>
202 <td class="link">
202 <td class="link">
203 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
203 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
204 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
204 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
205 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
205 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
206 </td>
206 </td>
207 </tr>'
207 </tr>'
208 bookmarks = bookmarks.tmpl
208 bookmarks = bookmarks.tmpl
209 bookmarkentry = '
209 bookmarkentry = '
210 <tr class="parity{parity}">
210 <tr class="parity{parity}">
211 <td class="age"><i class="age">{date|rfc822date}</i></td>
211 <td class="age"><i class="age">{date|rfc822date}</i></td>
212 <td><a class="list" href="{url|urlescape}rev/{bookmark|revescape}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
212 <td><a class="list" href="{url|urlescape}rev/{bookmark|revescape}{sessionvars%urlparameter}"><b>{bookmark|escape}</b></a></td>
213 <td class="link">
213 <td class="link">
214 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
214 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
215 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
215 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
216 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
216 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
217 </td>
217 </td>
218 </tr>'
218 </tr>'
219 branches = branches.tmpl
219 branches = branches.tmpl
220 branchentry = '
220 branchentry = '
221 <tr class="parity{parity}">
221 <tr class="parity{parity}">
222 <td class="age"><i class="age">{date|rfc822date}</i></td>
222 <td class="age"><i class="age">{date|rfc822date}</i></td>
223 <td class="{status}"><a class="list" href="{url|urlescape}shortlog/{branch|revescape}{sessionvars%urlparameter}"><b>{branch|escape}</b></a></td>
223 <td class="{status}"><a class="list" href="{url|urlescape}shortlog/{branch|revescape}{sessionvars%urlparameter}"><b>{branch|escape}</b></a></td>
224 <td class="link">
224 <td class="link">
225 <a href="{url|urlescape}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
225 <a href="{url|urlescape}changeset/{node|short}{sessionvars%urlparameter}">changeset</a> |
226 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
226 <a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">changelog</a> |
227 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
227 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
228 </td>
228 </td>
229 </tr>'
229 </tr>'
230 diffblock = '<div class="diffblock"><pre class="sourcelines">{lines}</pre></div>'
230 diffblock = '<div class="diffblock"><pre class="sourcelines">{lines}</pre></div>'
231 filediffparent = '
231 filediffparent = '
232 <tr>
232 <tr>
233 <td>parent {rev}</td>
233 <td>parent {rev}</td>
234 <td style="font-family:monospace">
234 <td style="font-family:monospace">
235 <a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
235 <a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
236 {node|short}
236 {node|short}
237 </a>
237 </a>
238 </td>
238 </td>
239 </tr>'
239 </tr>'
240 filecompparent = '
240 filecompparent = '
241 <tr>
241 <tr>
242 <td>parent {rev}</td>
242 <td>parent {rev}</td>
243 <td style="font-family:monospace">
243 <td style="font-family:monospace">
244 <a class="list" href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
244 <a class="list" href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
245 {node|short}
245 {node|short}
246 </a>
246 </a>
247 </td>
247 </td>
248 </tr>'
248 </tr>'
249 filediffchild = '
249 filediffchild = '
250 <tr>
250 <tr>
251 <td>child {rev}</td>
251 <td>child {rev}</td>
252 <td style="font-family:monospace">
252 <td style="font-family:monospace">
253 <a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
253 <a class="list" href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
254 </td>
254 </td>
255 </tr>'
255 </tr>'
256 filecompchild = '
256 filecompchild = '
257 <tr>
257 <tr>
258 <td>child {rev}</td>
258 <td>child {rev}</td>
259 <td style="font-family:monospace">
259 <td style="font-family:monospace">
260 <a class="list" href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
260 <a class="list" href="{url|urlescape}comparison/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a>
261 </td>
261 </td>
262 </tr>'
262 </tr>'
263 shortlog = shortlog.tmpl
263 shortlog = shortlog.tmpl
264 graph = graph.tmpl
264 graph = graph.tmpl
265 tagtag = '<span class="tagtag" title="{name|escape}">{name|escape}</span> '
265 tagtag = '<span class="tagtag" title="{name|escape}">{name|escape}</span> '
266 branchtag = '<span class="branchtag" title="{name|escape}">{name|escape}</span> '
266 branchtag = '<span class="branchtag" title="{name|escape}">{name|escape}</span> '
267 inbranchtag = '<span class="inbranchtag" title="{name|escape}">{name|escape}</span> '
267 inbranchtag = '<span class="inbranchtag" title="{name|escape}">{name|escape}</span> '
268 bookmarktag = '<span class="bookmarktag" title="{name|escape}">{name|escape}</span> '
268 bookmarktag = '<span class="bookmarktag" title="{name|escape}">{name|escape}</span> '
269 shortlogentry = '
269 shortlogentry = '
270 <tr class="parity{parity}">
270 <tr class="parity{parity}">
271 <td class="age"><i class="age">{date|rfc822date}</i></td>
271 <td class="age"><i class="age">{date|rfc822date}</i></td>
272 <td><i>{author|person}</i></td>
272 <td><i>{author|person}</i></td>
273 <td>
273 <td>
274 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
274 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
275 <b>{desc|strip|firstline|escape|nonempty}</b>
275 <b>{desc|strip|firstline|escape|nonempty}</b>
276 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
276 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
277 </a>
277 </a>
278 </td>
278 </td>
279 <td class="link" nowrap>
279 <td class="link" nowrap>
280 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
280 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a> |
281 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
281 <a href="{url|urlescape}file/{node|short}{sessionvars%urlparameter}">files</a>
282 </td>
282 </td>
283 </tr>'
283 </tr>'
284 filelogentry = '
284 filelogentry = '
285 <tr class="parity{if(patch, '1', '{parity}')}">
285 <tr class="parity{if(patch, '1', '{parity}')}">
286 <td class="age"><i class="age">{date|rfc822date}</i></td>
286 <td class="age"><i class="age">{date|rfc822date}</i></td>
287 <td><i>{author|person}</i></td>
287 <td><i>{author|person}</i></td>
288 <td>
288 <td>
289 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
289 <a class="list" href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
290 <b>{desc|strip|firstline|escape|nonempty}</b>
290 <b>{desc|strip|firstline|escape|nonempty}</b>
291 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
291 <span class="logtags">{inbranch%inbranchtag}{branches%branchtag}{tags%tagtag}{bookmarks%bookmarktag}</span>
292 </a>
292 </a>
293 </td>
293 </td>
294 <td class="link">
294 <td class="link">
295 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
295 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">file</a> |
296 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
296 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
297 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
297 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a>
298 {rename%filelogrename}
298 {rename%filelogrename}
299 </td>
299 </td>
300 </tr>
300 </tr>
301 {if(patch, '<tr><td colspan="4">{diff}</td></tr>')}'
301 {if(patch, '<tr><td colspan="4">{diff}</td></tr>')}'
302 archiveentry = ' | <a href="{url|urlescape}archive/{symrev}{extension}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a> '
302 archiveentry = ' | <a href="{url|urlescape}archive/{symrev}{extension}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a> '
303 indexentry = '
303 indexentry = '
304 <tr class="parity{parity}">
304 <tr class="parity{parity}">
305 <td>
305 <td>
306 <a class="list" href="{url|urlescape}{sessionvars%urlparameter}">
306 <a class="list" href="{url|urlescape}{sessionvars%urlparameter}">
307 <b>{name|escape}</b>
307 <b>{name|escape}</b>
308 </a>
308 </a>
309 </td>
309 </td>
310 <td>{description}</td>
310 <td>{description}</td>
311 <td>{contact|obfuscate}</td>
311 <td>{contact|obfuscate}</td>
312 <td class="age">{lastchange|rfc822date}</td>
312 <td class="age">{lastchange|rfc822date}</td>
313 <td class="indexlinks">{archives%indexarchiveentry}</td>
313 <td class="indexlinks">{archives%indexarchiveentry}</td>
314 <td>{if(isdirectory, '',
314 <td>{if(isdirectory, '',
315 '<div class="rss_logo">
315 '<div class="rss_logo">
316 <a href="{url|urlescape}rss-log">RSS</a> <a href="{url|urlescape}atom-log">Atom</a>
316 <a href="{url|urlescape}rss-log">RSS</a> <a href="{url|urlescape}atom-log">Atom</a>
317 </div>'
317 </div>'
318 )}
318 )}
319 </td>
319 </td>
320 </tr>\n'
320 </tr>\n'
321 indexarchiveentry = ' <a href="{url|urlescape}archive/{node|short}{extension}">{type|escape}</a> '
321 indexarchiveentry = ' <a href="{url|urlescape}archive/{node|short}{extension}">{type|escape}</a> '
322 index = index.tmpl
322 index = index.tmpl
323 urlparameter = '{separator}{name}={value|urlescape}'
323 urlparameter = '{separator}{name}={value|urlescape}'
324 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
324 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
325 breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '
325 breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '
326
326
327 searchform = '
327 searchform = '
328 <div class="search">
328 <div class="search">
329 <form id="searchform" action="{url|urlescape}log">
329 <form id="searchform" action="{url|urlescape}log">
330 {sessionvars%hiddenformentry}
330 {sessionvars%hiddenformentry}
331 <input name="rev" type="text" value="{query|escape}" size="40" />
331 <input name="rev" type="text" value="{query|escape}" size="40" />
332 <div id="hint">{searchhint}</div>
332 <div id="hint">{searchhint}</div>
333 </form>
333 </form>
334 </div>'
334 </div>'
335 searchhint = 'Find changesets by keywords (author, files, the commit message), revision
335 searchhint = 'Find changesets by keywords (author, files, the commit message), revision
336 number or hash, or <a href="{url|urlescape}help/revsets">revset expression</a>.'
336 number or hash, or <a href="{url|urlescape}help/revsets">revset expression</a>.'
@@ -1,253 +1,253 b''
1 default = 'shortlog'
1 default = 'shortlog'
2
2
3 mimetype = 'text/html; charset={encoding}'
3 mimetype = 'text/html; charset={encoding}'
4 header = header.tmpl
4 header = header.tmpl
5 footer = footer.tmpl
5 footer = footer.tmpl
6 search = search.tmpl
6 search = search.tmpl
7
7
8 changelog = shortlog.tmpl
8 changelog = shortlog.tmpl
9 shortlog = shortlog.tmpl
9 shortlog = shortlog.tmpl
10 shortlogentry = shortlogentry.tmpl
10 shortlogentry = shortlogentry.tmpl
11 graph = graph.tmpl
11 graph = graph.tmpl
12 help = help.tmpl
12 help = help.tmpl
13 helptopics = helptopics.tmpl
13 helptopics = helptopics.tmpl
14
14
15 helpentry = '
15 helpentry = '
16 <tr><td>
16 <tr><td>
17 <a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
17 <a href="{url|urlescape}help/{topic|escape}{sessionvars%urlparameter}">
18 {if(basename, '{basename|escape}', '{topic|escape}')}
18 {if(basename, '{basename|escape}', '{topic|escape}')}
19 </a>
19 </a>
20 </td><td>
20 </td><td>
21 {summary|escape}
21 {summary|escape}
22 </td></tr>'
22 </td></tr>'
23
23
24 naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
24 naventry = '<a href="{url|urlescape}log/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
25 navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
25 navshortentry = '<a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
26 navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
26 navgraphentry = '<a href="{url|urlescape}graph/{node|short}{sessionvars%urlparameter}">{label|escape}</a> '
27 filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
27 filenaventry = '<a href="{url|urlescape}log/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{label|escape}</a> '
28 filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
28 filedifflink = '<a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
29 filenodelink = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
29 filenodelink = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{file|escape}</a> '
30 filenolink = '{file|escape} '
30 filenolink = '{file|escape} '
31 fileellipses = '...'
31 fileellipses = '...'
32 diffstatlink = diffstat.tmpl
32 diffstatlink = diffstat.tmpl
33 diffstatnolink = diffstat.tmpl
33 diffstatnolink = diffstat.tmpl
34 changelogentry = shortlogentry.tmpl
34 changelogentry = shortlogentry.tmpl
35 searchentry = shortlogentry.tmpl
35 searchentry = shortlogentry.tmpl
36 changeset = changeset.tmpl
36 changeset = changeset.tmpl
37 manifest = manifest.tmpl
37 manifest = manifest.tmpl
38
38
39 nav = '{before%naventry} {after%naventry}'
39 nav = '{before%naventry} {after%naventry}'
40 navshort = '{before%navshortentry}{after%navshortentry}'
40 navshort = '{before%navshortentry}{after%navshortentry}'
41 navgraph = '{before%navgraphentry}{after%navgraphentry}'
41 navgraph = '{before%navgraphentry}{after%navgraphentry}'
42 filenav = '{before%filenaventry}{after%filenaventry}'
42 filenav = '{before%filenaventry}{after%filenaventry}'
43
43
44 direntry = '
44 direntry = '
45 <tr class="fileline">
45 <tr class="fileline">
46 <td class="name">
46 <td class="name">
47 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">
47 <a href="{url|urlescape}file/{symrev}{path|urlescape}{sessionvars%urlparameter}">
48 <img src="{staticurl|urlescape}coal-folder.png" alt="dir."/> {basename|escape}/
48 <img src="{staticurl|urlescape}coal-folder.png" alt="dir."/> {basename|escape}/
49 </a>
49 </a>
50 <a href="{url|urlescape}file/{symrev}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
50 <a href="{url|urlescape}file/{symrev}{path|urlescape}/{emptydirs|urlescape}{sessionvars%urlparameter}">
51 {emptydirs|escape}
51 {emptydirs|escape}
52 </a>
52 </a>
53 </td>
53 </td>
54 <td class="size"></td>
54 <td class="size"></td>
55 <td class="permissions">drwxr-xr-x</td>
55 <td class="permissions">drwxr-xr-x</td>
56 </tr>'
56 </tr>'
57
57
58 fileentry = '
58 fileentry = '
59 <tr class="fileline">
59 <tr class="fileline">
60 <td class="filename">
60 <td class="filename">
61 <a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">
61 <a href="{url|urlescape}file/{symrev}/{file|urlescape}{sessionvars%urlparameter}">
62 <img src="{staticurl|urlescape}coal-file.png" alt="file"/> {basename|escape}
62 <img src="{staticurl|urlescape}coal-file.png" alt="file"/> {basename|escape}
63 </a>
63 </a>
64 </td>
64 </td>
65 <td class="size">{size}</td>
65 <td class="size">{size}</td>
66 <td class="permissions">{permissions|permissions}</td>
66 <td class="permissions">{permissions|permissions}</td>
67 </tr>'
67 </tr>'
68
68
69 filerevision = filerevision.tmpl
69 filerevision = filerevision.tmpl
70 fileannotate = fileannotate.tmpl
70 fileannotate = fileannotate.tmpl
71 filediff = filediff.tmpl
71 filediff = filediff.tmpl
72 filecomparison = filecomparison.tmpl
72 filecomparison = filecomparison.tmpl
73 filelog = filelog.tmpl
73 filelog = filelog.tmpl
74 fileline = '
74 fileline = '
75 <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
75 <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
76 filelogentry = filelogentry.tmpl
76 filelogentry = filelogentry.tmpl
77
77
78 annotateline = '
78 annotateline = '
79 <tr id="{lineid}"{ifeq(node, originalnode, ' class="thisrev"')}>
79 <tr id="{lineid}"{ifeq(node, originalnode, ' class="thisrev"')}>
80 <td class="annotate parity{blockparity}">
80 <td class="annotate parity{blockparity}">
81 {if(blockhead,
81 {if(blockhead,
82 '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
82 '<a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
83 {rev}
83 {rev}
84 </a>')}
84 </a>')}
85 <div class="annotate-info">
85 <div class="annotate-info">
86 <div>
86 <div>
87 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
87 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}#l{targetline}">
88 {node|short}</a>
88 {node|short}</a>
89 {desc|escape|firstline}
89 {desc|escape|firstline}
90 </div>
90 </div>
91 <div><em>{author|obfuscate}</em></div>
91 <div><em>{author|obfuscate}</em></div>
92 <div>parents: {parents%annotateparent}</div>
92 <div>parents: {parents%annotateparent}</div>
93 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>
93 <a href="{url|urlescape}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a>
94 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
94 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">changeset</a>
95 </div>
95 </div>
96 </td>
96 </td>
97 <td class="source"><a href="#{lineid}">{linenumber}</a> {line|escape}</td>
97 <td class="source followlines-btn-parent"><a href="#{lineid}">{linenumber}</a> {line|escape}</td>
98 </tr>'
98 </tr>'
99 annotateparent = '
99 annotateparent = '
100 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rev}</a>'
100 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rev}</a>'
101 diffblock = '<div class="bottomline inc-lineno"><pre class="sourcelines wrap">{lines}</pre></div>'
101 diffblock = '<div class="bottomline inc-lineno"><pre class="sourcelines wrap">{lines}</pre></div>'
102 difflineplus = '
102 difflineplus = '
103 <span id="{lineid}" class="plusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
103 <span id="{lineid}" class="plusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
104 difflineminus = '
104 difflineminus = '
105 <span id="{lineid}" class="minusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
105 <span id="{lineid}" class="minusline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
106 difflineat = '
106 difflineat = '
107 <span id="{lineid}" class="atline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
107 <span id="{lineid}" class="atline">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
108 diffline = '
108 diffline = '
109 <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
109 <span id="{lineid}">{strip(line|escape, '\r\n')}</span><a href="#{lineid}"></a>'
110
110
111 comparisonblock ='
111 comparisonblock ='
112 <tbody class="block">
112 <tbody class="block">
113 {lines}
113 {lines}
114 </tbody>'
114 </tbody>'
115 comparisonline = '
115 comparisonline = '
116 <tr id="{lineid}">
116 <tr id="{lineid}">
117 <td class="source {type}"><a href="#{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
117 <td class="source {type}"><a href="#{lineid}">{leftlinenumber}</a> {leftline|escape}</td>
118 <td class="source {type}"><a href="#{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
118 <td class="source {type}"><a href="#{lineid}">{rightlinenumber}</a> {rightline|escape}</td>
119 </tr>'
119 </tr>'
120
120
121 changesetparent = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
121 changesetparent = '<a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a> '
122
122
123 changesetparentdiff = '
123 changesetparentdiff = '
124 {changesetparent}
124 {changesetparent}
125 {ifeq(node, basenode, '(current diff)', '({difffrom})')}'
125 {ifeq(node, basenode, '(current diff)', '({difffrom})')}'
126
126
127 difffrom = '<a href="{url|urlescape}rev/{node|short}:{originalnode|short}{sessionvars%urlparameter}">diff</a>'
127 difffrom = '<a href="{url|urlescape}rev/{node|short}:{originalnode|short}{sessionvars%urlparameter}">diff</a>'
128
128
129 filerevparent = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
129 filerevparent = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{rename%filerename}{node|short}</a> '
130 filerevchild = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
130 filerevchild = '<a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">{node|short}</a> '
131
131
132 filerename = '{file|escape}@'
132 filerename = '{file|escape}@'
133 filelogrename = '
133 filelogrename = '
134 <span class="base">
134 <span class="base">
135 base
135 base
136 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
136 <a href="{url|urlescape}file/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
137 {file|escape}@{node|short}
137 {file|escape}@{node|short}
138 </a>
138 </a>
139 </span>'
139 </span>'
140 fileannotateparent = '
140 fileannotateparent = '
141 <tr>
141 <tr>
142 <td class="metatag">parent:</td>
142 <td class="metatag">parent:</td>
143 <td>
143 <td>
144 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
144 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
145 {rename%filerename}{node|short}
145 {rename%filerename}{node|short}
146 </a>
146 </a>
147 </td>
147 </td>
148 </tr>'
148 </tr>'
149 changesetchild = ' <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
149 changesetchild = ' <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>'
150 fileannotatechild = '
150 fileannotatechild = '
151 <tr>
151 <tr>
152 <td class="metatag">child:</td>
152 <td class="metatag">child:</td>
153 <td>
153 <td>
154 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
154 <a href="{url|urlescape}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">
155 {node|short}
155 {node|short}
156 </a>
156 </a>
157 </td>
157 </td>
158 </tr>'
158 </tr>'
159 tags = tags.tmpl
159 tags = tags.tmpl
160 tagentry = '
160 tagentry = '
161 <tr class="tagEntry">
161 <tr class="tagEntry">
162 <td>
162 <td>
163 <a href="{url|urlescape}rev/{tag|revescape}{sessionvars%urlparameter}">
163 <a href="{url|urlescape}rev/{tag|revescape}{sessionvars%urlparameter}">
164 {tag|escape}
164 {tag|escape}
165 </a>
165 </a>
166 </td>
166 </td>
167 <td class="node">
167 <td class="node">
168 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
168 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
169 {node|short}
169 {node|short}
170 </a>
170 </a>
171 </td>
171 </td>
172 </tr>'
172 </tr>'
173 bookmarks = bookmarks.tmpl
173 bookmarks = bookmarks.tmpl
174 bookmarkentry = '
174 bookmarkentry = '
175 <tr class="tagEntry">
175 <tr class="tagEntry">
176 <td>
176 <td>
177 <a href="{url|urlescape}rev/{bookmark|revescape}{sessionvars%urlparameter}">
177 <a href="{url|urlescape}rev/{bookmark|revescape}{sessionvars%urlparameter}">
178 {bookmark|escape}
178 {bookmark|escape}
179 </a>
179 </a>
180 </td>
180 </td>
181 <td class="node">
181 <td class="node">
182 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
182 <a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">
183 {node|short}
183 {node|short}
184 </a>
184 </a>
185 </td>
185 </td>
186 </tr>'
186 </tr>'
187 branches = branches.tmpl
187 branches = branches.tmpl
188 branchentry = '
188 branchentry = '
189 <tr class="tagEntry">
189 <tr class="tagEntry">
190 <td>
190 <td>
191 <a href="{url|urlescape}shortlog/{branch|revescape}{sessionvars%urlparameter}" class="{status}">
191 <a href="{url|urlescape}shortlog/{branch|revescape}{sessionvars%urlparameter}" class="{status}">
192 {branch|escape}
192 {branch|escape}
193 </a>
193 </a>
194 </td>
194 </td>
195 <td class="node">
195 <td class="node">
196 <a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
196 <a href="{url|urlescape}shortlog/{node|short}{sessionvars%urlparameter}" class="{status}">
197 {node|short}
197 {node|short}
198 </a>
198 </a>
199 </td>
199 </td>
200 </tr>'
200 </tr>'
201 changelogtag = '<span class="tag">{name|escape}</span> '
201 changelogtag = '<span class="tag">{name|escape}</span> '
202 changesettag = '<span class="tag">{tag|escape}</span> '
202 changesettag = '<span class="tag">{tag|escape}</span> '
203 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
203 changesetbookmark = '<span class="tag">{bookmark|escape}</span> '
204 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
204 changelogbranchhead = '<span class="branchhead">{name|escape}</span> '
205 changelogbranchname = '<span class="branchname">{name|escape}</span> '
205 changelogbranchname = '<span class="branchname">{name|escape}</span> '
206
206
207 filediffparent = '
207 filediffparent = '
208 <tr>
208 <tr>
209 <th class="parent">parent {rev}:</th>
209 <th class="parent">parent {rev}:</th>
210 <td class="parent"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
210 <td class="parent"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a></td>
211 </tr>'
211 </tr>'
212 filediffchild = '
212 filediffchild = '
213 <tr>
213 <tr>
214 <th class="child">child {rev}:</th>
214 <th class="child">child {rev}:</th>
215 <td class="child"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
215 <td class="child"><a href="{url|urlescape}rev/{node|short}{sessionvars%urlparameter}">{node|short}</a>
216 </td>
216 </td>
217 </tr>'
217 </tr>'
218
218
219 indexentry = '
219 indexentry = '
220 <tr>
220 <tr>
221 <td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td>
221 <td><a href="{url|urlescape}{sessionvars%urlparameter}">{name|escape}</a></td>
222 <td>{description}</td>
222 <td>{description}</td>
223 <td>{contact|obfuscate}</td>
223 <td>{contact|obfuscate}</td>
224 <td class="age">{lastchange|rfc822date}</td>
224 <td class="age">{lastchange|rfc822date}</td>
225 <td class="indexlinks">{archives%indexarchiveentry}</td>
225 <td class="indexlinks">{archives%indexarchiveentry}</td>
226 <td>
226 <td>
227 {if(isdirectory, '',
227 {if(isdirectory, '',
228 '<a href="{url|urlescape}atom-log" title="subscribe to repository atom feed">
228 '<a href="{url|urlescape}atom-log" title="subscribe to repository atom feed">
229 <img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="subscribe to repository atom feed">
229 <img class="atom-logo" src="{staticurl|urlescape}feed-icon-14x14.png" alt="subscribe to repository atom feed">
230 </a>'
230 </a>'
231 )}
231 )}
232 </td>
232 </td>
233 </tr>\n'
233 </tr>\n'
234 indexarchiveentry = '<a href="{url|urlescape}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
234 indexarchiveentry = '<a href="{url|urlescape}archive/{node|short}{extension|urlescape}">&nbsp;&darr;{type|escape}</a>'
235 index = index.tmpl
235 index = index.tmpl
236 archiveentry = '
236 archiveentry = '
237 <li>
237 <li>
238 <a href="{url|urlescape}archive/{symrev}{extension|urlescape}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a>
238 <a href="{url|urlescape}archive/{symrev}{extension|urlescape}{ifeq(path,'/','',path|urlescape)}">{type|escape}</a>
239 </li>'
239 </li>'
240 notfound = notfound.tmpl
240 notfound = notfound.tmpl
241 error = error.tmpl
241 error = error.tmpl
242 urlparameter = '{separator}{name}={value|urlescape}'
242 urlparameter = '{separator}{name}={value|urlescape}'
243 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
243 hiddenformentry = '<input type="hidden" name="{name}" value="{value|escape}" />'
244 breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '
244 breadcrumb = '&gt; <a href="{url|urlescape}">{name|escape}</a> '
245
245
246 searchform = '
246 searchform = '
247 <form class="search" action="{url|urlescape}log">
247 <form class="search" action="{url|urlescape}log">
248 {sessionvars%hiddenformentry}
248 {sessionvars%hiddenformentry}
249 <p><input name="rev" id="search1" type="text" size="30" value="{query|escape}" /></p>
249 <p><input name="rev" id="search1" type="text" size="30" value="{query|escape}" /></p>
250 <div id="hint">{searchhint}</div>
250 <div id="hint">{searchhint}</div>
251 </form>'
251 </form>'
252 searchhint = 'Find changesets by keywords (author, files, the commit message), revision
252 searchhint = 'Find changesets by keywords (author, files, the commit message), revision
253 number or hash, or <a href="{url|urlescape}help/revsets">revset expression</a>.'
253 number or hash, or <a href="{url|urlescape}help/revsets">revset expression</a>.'
@@ -1,242 +1,286 b''
1 // followlines.js - JavaScript utilities for followlines UI
1 // followlines.js - JavaScript utilities for followlines UI
2 //
2 //
3 // Copyright 2017 Logilab SA <contact@logilab.fr>
3 // Copyright 2017 Logilab SA <contact@logilab.fr>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 //** Install event listeners for line block selection and followlines action */
8 //** Install event listeners for line block selection and followlines action */
9 document.addEventListener('DOMContentLoaded', function() {
9 document.addEventListener('DOMContentLoaded', function() {
10 var sourcelines = document.getElementsByClassName('sourcelines')[0];
10 var sourcelines = document.getElementsByClassName('sourcelines')[0];
11 if (typeof sourcelines === 'undefined') {
11 if (typeof sourcelines === 'undefined') {
12 return;
12 return;
13 }
13 }
14 // URL to complement with "linerange" query parameter
14 // URL to complement with "linerange" query parameter
15 var targetUri = sourcelines.dataset.logurl;
15 var targetUri = sourcelines.dataset.logurl;
16 if (typeof targetUri === 'undefined')Β {
16 if (typeof targetUri === 'undefined')Β {
17 return;
17 return;
18 }
18 }
19
19
20 // Tag of children of "sourcelines" element on which to add "line
20 // Tag of children of "sourcelines" element on which to add "line
21 // selection" style.
21 // selection" style.
22 var selectableTag = sourcelines.dataset.selectabletag;
22 var selectableTag = sourcelines.dataset.selectabletag;
23 if (typeof selectableTag === 'undefined') {
23 if (typeof selectableTag === 'undefined') {
24 return;
24 return;
25 }
25 }
26
26
27 var isHead = parseInt(sourcelines.dataset.ishead || "0");
27 var isHead = parseInt(sourcelines.dataset.ishead || "0");
28
28
29 // tooltip to invite on lines selection
30 var tooltip = document.createElement('div');
31 tooltip.id = 'followlines-tooltip';
32 tooltip.classList.add('hidden');
33 var initTooltipText = 'click to start following lines history from here';
34 tooltip.textContent = initTooltipText;
35 sourcelines.appendChild(tooltip);
36
37 //* position "element" on top-right of cursor */
29 //* position "element" on top-right of cursor */
38 function positionTopRight(element, event) {
30 function positionTopRight(element, event) {
39 var x = (event.clientX + 10) + 'px',
31 var x = (event.clientX + 10) + 'px',
40 y = (event.clientY - 20) + 'px';
32 y = (event.clientY - 20) + 'px';
41 element.style.top = y;
33 element.style.top = y;
42 element.style.left = x;
34 element.style.left = x;
43 }
35 }
44
36
45 var tooltipTimeoutID;
46 //* move the "tooltip" with cursor (top-right) and show it after 1s */
47 function moveAndShowTooltip(e) {
48 if (typeof tooltipTimeoutID !== 'undefined') {
49 // avoid accumulation of timeout callbacks (blinking)
50 window.clearTimeout(tooltipTimeoutID);
51 }
52 tooltip.classList.add('hidden');
53 positionTopRight(tooltip, e);
54 tooltipTimeoutID = window.setTimeout(function() {
55 tooltip.classList.remove('hidden');
56 }, 1000);
57 }
58
59 // on mousemove, show tooltip close to cursor position
60 sourcelines.addEventListener('mousemove', moveAndShowTooltip);
61
62 // retrieve all direct *selectable* children of class="sourcelines"
37 // retrieve all direct *selectable* children of class="sourcelines"
63 // element
38 // element
64 var selectableElements = Array.prototype.filter.call(
39 var selectableElements = Array.prototype.filter.call(
65 sourcelines.children,
40 sourcelines.children,
66 function(x) { return x.tagName === selectableTag });
41 function(x) { return x.tagName === selectableTag });
67
42
68 // add a "followlines-select" class to change cursor type in CSS
43 var btnTitleStart = 'start following lines history from here';
44 var btnTitleEnd = 'terminate line block selection here';
45
46 //** return a <button> element with +/- spans */
47 function createButton() {
48 var btn = document.createElement('button');
49 btn.title = btnTitleStart;
50 btn.classList.add('btn-followlines');
51 var plusSpan = document.createElement('span');
52 plusSpan.classList.add('followlines-plus');
53 plusSpan.textContent = '+';
54 btn.appendChild(plusSpan);
55 var br = document.createElement('br');
56 btn.appendChild(br);
57 var minusSpan = document.createElement('span');
58 minusSpan.classList.add('followlines-minus');
59 minusSpan.textContent = 'βˆ’';
60 btn.appendChild(minusSpan);
61 return btn;
62 }
63
64 // extend DOM with CSS class for selection highlight and action buttons
65 var followlinesButtons = []
69 for (var i = 0; i < selectableElements.length; i++) {
66 for (var i = 0; i < selectableElements.length; i++) {
70 selectableElements[i].classList.add('followlines-select');
67 selectableElements[i].classList.add('followlines-select');
68 var btn = createButton();
69 followlinesButtons.push(btn);
70 // insert the <button> as child of `selectableElements[i]` unless the
71 // latter has itself a child with a "followlines-btn-parent" class
72 // (annotate view)
73 var btnSupportElm = selectableElements[i];
74 var childSupportElms = btnSupportElm.getElementsByClassName(
75 'followlines-btn-parent');
76 if ( childSupportElms.length > 0 ) {
77 btnSupportElm = childSupportElms[0];
78 }
79 var refNode = btnSupportElm.children[0]; // node to insert <button> before
80 btnSupportElm.insertBefore(btn, refNode);
81 }
82
83 // ** re-initialize followlines buttons */
84 function resetButtons() {
85 for (var i = 0; i < followlinesButtons.length; i++) {
86 var btn = followlinesButtons[i];
87 btn.title = btnTitleStart;
88 btn.classList.remove('btn-followlines-end');
89 btn.classList.remove('btn-followlines-hidden');
90 }
71 }
91 }
72
92
73 var lineSelectedCSSClass = 'followlines-selected';
93 var lineSelectedCSSClass = 'followlines-selected';
74
94
75 //** add CSS class on selectable elements in `from`-`to` line range */
95 //** add CSS class on selectable elements in `from`-`to` line range */
76 function addSelectedCSSClass(from, to) {
96 function addSelectedCSSClass(from, to) {
77 for (var i = from; i <= to; i++) {
97 for (var i = from; i <= to; i++) {
78 selectableElements[i].classList.add(lineSelectedCSSClass);
98 selectableElements[i].classList.add(lineSelectedCSSClass);
79 }
99 }
80 }
100 }
81
101
82 //** remove CSS class from previously selected lines */
102 //** remove CSS class from previously selected lines */
83 function removeSelectedCSSClass() {
103 function removeSelectedCSSClass() {
84 var elements = sourcelines.getElementsByClassName(
104 var elements = sourcelines.getElementsByClassName(
85 lineSelectedCSSClass);
105 lineSelectedCSSClass);
86 while (elements.length) {
106 while (elements.length) {
87 elements[0].classList.remove(lineSelectedCSSClass);
107 elements[0].classList.remove(lineSelectedCSSClass);
88 }
108 }
89 }
109 }
90
110
91 // ** return the element of type "selectableTag" parent of `element` */
111 // ** return the element of type "selectableTag" parent of `element` */
92 function selectableParent(element) {
112 function selectableParent(element) {
93 var parent = element.parentElement;
113 var parent = element.parentElement;
94 if (parent === null) {
114 if (parent === null) {
95 return null;
115 return null;
96 }
116 }
97 if (element.tagName == selectableTag && parent.isSameNode(sourcelines)) {
117 if (element.tagName == selectableTag && parent.isSameNode(sourcelines)) {
98 return element;
118 return element;
99 }
119 }
100 return selectableParent(parent);
120 return selectableParent(parent);
101 }
121 }
102
122
123 // ** update buttons title and style upon first click */
124 function updateButtons(selectable) {
125 for (var i = 0; i < followlinesButtons.length; i++) {
126 var btn = followlinesButtons[i];
127 btn.title = btnTitleEnd;
128 btn.classList.add('btn-followlines-end');
129 }
130 // on clicked button, change title to "cancel"
131 var clicked = selectable.getElementsByClassName('btn-followlines')[0];
132 clicked.title = 'cancel';
133 clicked.classList.remove('btn-followlines-end');
134 }
135
136 //** add `listener` on "click" event for all `followlinesButtons` */
137 function buttonsAddEventListener(listener) {
138 for (var i = 0; i < followlinesButtons.length; i++) {
139 followlinesButtons[i].addEventListener('click', listener);
140 }
141 }
142
143 //** remove `listener` on "click" event for all `followlinesButtons` */
144 function buttonsRemoveEventListener(listener) {
145 for (var i = 0; i < followlinesButtons.length; i++) {
146 followlinesButtons[i].removeEventListener('click', listener);
147 }
148 }
149
103 //** event handler for "click" on the first line of a block */
150 //** event handler for "click" on the first line of a block */
104 function lineSelectStart(e) {
151 function lineSelectStart(e) {
105 var startElement = selectableParent(e.target);
152 var startElement = selectableParent(e.target.parentElement);
106 if (startElement === null) {
153 if (startElement === null) {
107 // not a "selectable" element (maybe <a>): abort, keeping event
154 // not a "selectable" element (maybe <a>): abort, keeping event
108 // listener registered for other click with a "selectable" target
155 // listener registered for other click with a "selectable" target
109 return;
156 return;
110 }
157 }
111
158
112 // update tooltip text
159 // update button tooltip text and CSS
113 tooltip.textContent = 'click again to terminate line block selection here';
160 updateButtons(startElement);
114
161
115 var startId = parseInt(startElement.id.slice(1));
162 var startId = parseInt(startElement.id.slice(1));
116 startElement.classList.add(lineSelectedCSSClass); // CSS
163 startElement.classList.add(lineSelectedCSSClass); // CSS
117
164
118 // remove this event listener
165 // remove this event listener
119 sourcelines.removeEventListener('click', lineSelectStart);
166 buttonsRemoveEventListener(lineSelectStart);
120
167
121 //** event handler for "click" on the last line of the block */
168 //** event handler for "click" on the last line of the block */
122 function lineSelectEnd(e) {
169 function lineSelectEnd(e) {
123 var endElement = selectableParent(e.target);
170 var endElement = selectableParent(e.target.parentElement);
124 if (endElement === null) {
171 if (endElement === null) {
125 // not a <span> (maybe <a>): abort, keeping event listener
172 // not a <span> (maybe <a>): abort, keeping event listener
126 // registered for other click with <span> target
173 // registered for other click with <span> target
127 return;
174 return;
128 }
175 }
129
176
130 // remove this event listener
177 // remove this event listener
131 sourcelines.removeEventListener('click', lineSelectEnd);
178 buttonsRemoveEventListener(lineSelectEnd);
132
179
133 // hide tooltip and disable motion tracking
180 // reset button tooltip text
134 tooltip.classList.add('hidden');
181 resetButtons();
135 sourcelines.removeEventListener('mousemove', moveAndShowTooltip);
136 window.clearTimeout(tooltipTimeoutID);
137
138 //* restore initial "tooltip" state */
139 function restoreTooltip() {
140 tooltip.textContent = initTooltipText;
141 sourcelines.addEventListener('mousemove', moveAndShowTooltip);
142 }
143
182
144 // compute line range (startId, endId)
183 // compute line range (startId, endId)
145 var endId = parseInt(endElement.id.slice(1));
184 var endId = parseInt(endElement.id.slice(1));
146 if (endId == startId) {
185 if (endId == startId) {
147 // clicked twice the same line, cancel and reset initial state
186 // clicked twice the same line, cancel and reset initial state
148 // (CSS, event listener for selection start, tooltip)
187 // (CSS, event listener for selection start)
149 removeSelectedCSSClass();
188 removeSelectedCSSClass();
150 sourcelines.addEventListener('click', lineSelectStart);
189 buttonsAddEventListener(lineSelectStart);
151 restoreTooltip();
152 return;
190 return;
153 }
191 }
154 var inviteElement = endElement;
192 var inviteElement = endElement;
155 if (endId < startId) {
193 if (endId < startId) {
156 var tmp = endId;
194 var tmp = endId;
157 endId = startId;
195 endId = startId;
158 startId = tmp;
196 startId = tmp;
159 inviteElement = startElement;
197 inviteElement = startElement;
160 }
198 }
161
199
162 addSelectedCSSClass(startId - 1, endId -1); // CSS
200 addSelectedCSSClass(startId - 1, endId -1); // CSS
163
201
164 // append the <div id="followlines"> element to last line of the
202 // append the <div id="followlines"> element to last line of the
165 // selection block
203 // selection block
166 var divAndButton = followlinesBox(targetUri, startId, endId, isHead);
204 var divAndButton = followlinesBox(targetUri, startId, endId, isHead);
167 var div = divAndButton[0],
205 var div = divAndButton[0],
168 button = divAndButton[1];
206 button = divAndButton[1];
169 inviteElement.appendChild(div);
207 inviteElement.appendChild(div);
170 // set position close to cursor (top-right)
208 // set position close to cursor (top-right)
171 positionTopRight(div, e);
209 positionTopRight(div, e);
210 // hide all buttons
211 for (var i = 0; i < followlinesButtons.length; i++) {
212 followlinesButtons[i].classList.add('btn-followlines-hidden');
213 }
172
214
173 //** event handler for cancelling selection */
215 //** event handler for cancelling selection */
174 function cancel() {
216 function cancel() {
175 // remove invite box
217 // remove invite box
176 div.parentNode.removeChild(div);
218 div.parentNode.removeChild(div);
177 // restore initial event listeners
219 // restore initial event listeners
178 sourcelines.addEventListener('click', lineSelectStart);
220 buttonsAddEventListener(lineSelectStart);
179 sourcelines.removeEventListener('click', cancel);
221 buttonsRemoveEventListener(cancel);
222 for (var i = 0; i < followlinesButtons.length; i++) {
223 followlinesButtons[i].classList.remove('btn-followlines-hidden');
224 }
180 // remove styles on selected lines
225 // remove styles on selected lines
181 removeSelectedCSSClass();
226 removeSelectedCSSClass();
182 // restore tooltip element
227 resetButtons();
183 restoreTooltip();
184 }
228 }
185
229
186 // bind cancel event to click on <button>
230 // bind cancel event to click on <button>
187 button.addEventListener('click', cancel);
231 button.addEventListener('click', cancel);
188 // as well as on an click on any source line
232 // as well as on an click on any source line
189 sourcelines.addEventListener('click', cancel);
233 buttonsAddEventListener(cancel);
190 }
234 }
191
235
192 sourcelines.addEventListener('click', lineSelectEnd);
236 buttonsAddEventListener(lineSelectEnd);
193
237
194 }
238 }
195
239
196 sourcelines.addEventListener('click', lineSelectStart);
240 buttonsAddEventListener(lineSelectStart);
197
241
198 //** return a <div id="followlines"> and inner cancel <button> elements */
242 //** return a <div id="followlines"> and inner cancel <button> elements */
199 function followlinesBox(targetUri, fromline, toline, isHead) {
243 function followlinesBox(targetUri, fromline, toline, isHead) {
200 // <div id="followlines">
244 // <div id="followlines">
201 var div = document.createElement('div');
245 var div = document.createElement('div');
202 div.id = 'followlines';
246 div.id = 'followlines';
203
247
204 // <div class="followlines-cancel">
248 // <div class="followlines-cancel">
205 var buttonDiv = document.createElement('div');
249 var buttonDiv = document.createElement('div');
206 buttonDiv.classList.add('followlines-cancel');
250 buttonDiv.classList.add('followlines-cancel');
207
251
208 // <button>x</button>
252 // <button>x</button>
209 var button = document.createElement('button');
253 var button = document.createElement('button');
210 button.textContent = 'x';
254 button.textContent = 'x';
211 buttonDiv.appendChild(button);
255 buttonDiv.appendChild(button);
212 div.appendChild(buttonDiv);
256 div.appendChild(buttonDiv);
213
257
214 // <div class="followlines-link">
258 // <div class="followlines-link">
215 var aDiv = document.createElement('div');
259 var aDiv = document.createElement('div');
216 aDiv.classList.add('followlines-link');
260 aDiv.classList.add('followlines-link');
217 aDiv.textContent = 'follow history of lines ' + fromline + ':' + toline + ':';
261 aDiv.textContent = 'follow history of lines ' + fromline + ':' + toline + ':';
218 var linesep = document.createElement('br');
262 var linesep = document.createElement('br');
219 aDiv.appendChild(linesep);
263 aDiv.appendChild(linesep);
220 // link to "ascending" followlines
264 // link to "ascending" followlines
221 var aAsc = document.createElement('a');
265 var aAsc = document.createElement('a');
222 var url = targetUri + '?patch=&linerange=' + fromline + ':' + toline;
266 var url = targetUri + '?patch=&linerange=' + fromline + ':' + toline;
223 aAsc.setAttribute('href', url);
267 aAsc.setAttribute('href', url);
224 aAsc.textContent = 'older';
268 aAsc.textContent = 'older';
225 aDiv.appendChild(aAsc);
269 aDiv.appendChild(aAsc);
226
270
227 if (!isHead) {
271 if (!isHead) {
228 var sep = document.createTextNode(' / ');
272 var sep = document.createTextNode(' / ');
229 aDiv.appendChild(sep);
273 aDiv.appendChild(sep);
230 // link to "descending" followlines
274 // link to "descending" followlines
231 var aDesc = document.createElement('a');
275 var aDesc = document.createElement('a');
232 aDesc.setAttribute('href', url + '&descend=');
276 aDesc.setAttribute('href', url + '&descend=');
233 aDesc.textContent = 'newer';
277 aDesc.textContent = 'newer';
234 aDiv.appendChild(aDesc);
278 aDiv.appendChild(aDesc);
235 }
279 }
236
280
237 div.appendChild(aDiv);
281 div.appendChild(aDiv);
238
282
239 return [div, button];
283 return [div, button];
240 }
284 }
241
285
242 }, false);
286 }, false);
@@ -1,346 +1,383 b''
1 body { font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px; margin:10px; background: white; color: black; }
1 body { font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px; margin:10px; background: white; color: black; }
2 a { color:#0000cc; }
2 a { color:#0000cc; }
3 a:hover, a:visited, a:active { color:#880000; }
3 a:hover, a:visited, a:active { color:#880000; }
4 div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
4 div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
5 div.page_header a:visited { color:#0000cc; }
5 div.page_header a:visited { color:#0000cc; }
6 div.page_header a:hover { color:#880000; }
6 div.page_header a:hover { color:#880000; }
7 div.page_nav {
7 div.page_nav {
8 padding:8px;
8 padding:8px;
9 display: flex;
9 display: flex;
10 justify-content: space-between;
10 justify-content: space-between;
11 align-items: center;
11 align-items: center;
12 }
12 }
13 div.page_nav a:visited { color:#0000cc; }
13 div.page_nav a:visited { color:#0000cc; }
14 div.extra_nav {
14 div.extra_nav {
15 padding: 8px;
15 padding: 8px;
16 }
16 }
17 div.extra_nav a:visited {
17 div.extra_nav a:visited {
18 color: #0000cc;
18 color: #0000cc;
19 }
19 }
20 div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
20 div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
21 div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
21 div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
22 div.page_footer_text { float:left; color:#555555; font-style:italic; }
22 div.page_footer_text { float:left; color:#555555; font-style:italic; }
23 div.page_body { padding:8px; }
23 div.page_body { padding:8px; }
24 div.title, a.title {
24 div.title, a.title {
25 display:block; padding:6px 8px;
25 display:block; padding:6px 8px;
26 font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
26 font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
27 }
27 }
28 a.title:hover { background-color: #d9d8d1; }
28 a.title:hover { background-color: #d9d8d1; }
29 div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
29 div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
30 div.log_body { padding:8px 8px 8px 150px; }
30 div.log_body { padding:8px 8px 8px 150px; }
31 .age { white-space:nowrap; }
31 .age { white-space:nowrap; }
32 span.age { position:relative; float:left; width:142px; font-style:italic; }
32 span.age { position:relative; float:left; width:142px; font-style:italic; }
33 div.log_link {
33 div.log_link {
34 padding:0px 8px;
34 padding:0px 8px;
35 font-size:10px; font-family:sans-serif; font-style:normal;
35 font-size:10px; font-family:sans-serif; font-style:normal;
36 position:relative; float:left; width:136px;
36 position:relative; float:left; width:136px;
37 }
37 }
38 div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
38 div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
39 a.list { text-decoration:none; color:#000000; }
39 a.list { text-decoration:none; color:#000000; }
40 a.list:hover { text-decoration:underline; color:#880000; }
40 a.list:hover { text-decoration:underline; color:#880000; }
41 table { padding:8px 4px; }
41 table { padding:8px 4px; }
42 th { padding:2px 5px; font-size:12px; text-align:left; }
42 th { padding:2px 5px; font-size:12px; text-align:left; }
43 .parity0 { background-color:#ffffff; }
43 .parity0 { background-color:#ffffff; }
44 tr.dark, .parity1, pre.sourcelines.stripes > :nth-child(4n+4) { background-color:#f6f6f0; }
44 tr.dark, .parity1, pre.sourcelines.stripes > :nth-child(4n+4) { background-color:#f6f6f0; }
45 tr.light:hover, .parity0:hover, tr.dark:hover, .parity1:hover,
45 tr.light:hover, .parity0:hover, tr.dark:hover, .parity1:hover,
46 pre.sourcelines.stripes > :nth-child(4n+2):hover,
46 pre.sourcelines.stripes > :nth-child(4n+2):hover,
47 pre.sourcelines.stripes > :nth-child(4n+4):hover,
47 pre.sourcelines.stripes > :nth-child(4n+4):hover,
48 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
48 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
49 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color:#edece6; }
49 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color:#edece6; }
50 td { padding:2px 5px; font-size:12px; vertical-align:top; }
50 td { padding:2px 5px; font-size:12px; vertical-align:top; }
51 td.closed { background-color: #99f; }
51 td.closed { background-color: #99f; }
52 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
52 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
53 td.indexlinks { white-space: nowrap; }
53 td.indexlinks { white-space: nowrap; }
54 td.indexlinks a {
54 td.indexlinks a {
55 padding: 2px 5px; line-height: 10px;
55 padding: 2px 5px; line-height: 10px;
56 border: 1px solid;
56 border: 1px solid;
57 color: #ffffff; background-color: #7777bb;
57 color: #ffffff; background-color: #7777bb;
58 border-color: #aaaadd #333366 #333366 #aaaadd;
58 border-color: #aaaadd #333366 #333366 #aaaadd;
59 font-weight: bold; text-align: center; text-decoration: none;
59 font-weight: bold; text-align: center; text-decoration: none;
60 font-size: 10px;
60 font-size: 10px;
61 }
61 }
62 td.indexlinks a:hover { background-color: #6666aa; }
62 td.indexlinks a:hover { background-color: #6666aa; }
63 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
63 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
64 div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
64 div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
65 div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
65 div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
66
66
67 .search {
67 .search {
68 margin-right: 8px;
68 margin-right: 8px;
69 }
69 }
70
70
71 div#hint {
71 div#hint {
72 position: absolute;
72 position: absolute;
73 display: none;
73 display: none;
74 width: 250px;
74 width: 250px;
75 padding: 5px;
75 padding: 5px;
76 background: #ffc;
76 background: #ffc;
77 border: 1px solid yellow;
77 border: 1px solid yellow;
78 border-radius: 5px;
78 border-radius: 5px;
79 }
79 }
80
80
81 #searchform:hover div#hint { display: block; }
81 #searchform:hover div#hint { display: block; }
82
82
83 tr.thisrev a { color:#999999; text-decoration: none; }
83 tr.thisrev a { color:#999999; text-decoration: none; }
84 tr.thisrev pre { color:#009900; }
84 tr.thisrev pre { color:#009900; }
85 td.annotate {
85 td.annotate {
86 white-space: nowrap;
86 white-space: nowrap;
87 }
87 }
88 div.annotate-info {
88 div.annotate-info {
89 z-index: 5;
89 display: none;
90 display: none;
90 position: absolute;
91 position: absolute;
91 background-color: #FFFFFF;
92 background-color: #FFFFFF;
92 border: 1px solid #d9d8d1;
93 border: 1px solid #d9d8d1;
93 text-align: left;
94 text-align: left;
94 color: #000000;
95 color: #000000;
95 padding: 5px;
96 padding: 5px;
96 }
97 }
97 div.annotate-info a { color: #0000FF; text-decoration: underline; }
98 div.annotate-info a { color: #0000FF; text-decoration: underline; }
98 td.annotate:hover div.annotate-info { display: inline; }
99 td.annotate:hover div.annotate-info { display: inline; }
99 .linenr { color:#999999; text-decoration:none }
100 .linenr { color:#999999; text-decoration:none }
100 div.rss_logo { float: right; white-space: nowrap; }
101 div.rss_logo { float: right; white-space: nowrap; }
101 div.rss_logo a {
102 div.rss_logo a {
102 padding:3px 6px; line-height:10px;
103 padding:3px 6px; line-height:10px;
103 border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
104 border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
104 color:#ffffff; background-color:#ff6600;
105 color:#ffffff; background-color:#ff6600;
105 font-weight:bold; font-family:sans-serif; font-size:10px;
106 font-weight:bold; font-family:sans-serif; font-size:10px;
106 text-align:center; text-decoration:none;
107 text-align:center; text-decoration:none;
107 }
108 }
108 div.rss_logo a:hover { background-color:#ee5500; }
109 div.rss_logo a:hover { background-color:#ee5500; }
109 pre { margin: 0; }
110 pre { margin: 0; }
110 span.logtags span {
111 span.logtags span {
111 padding: 0px 4px;
112 padding: 0px 4px;
112 font-size: 10px;
113 font-size: 10px;
113 font-weight: normal;
114 font-weight: normal;
114 border: 1px solid;
115 border: 1px solid;
115 background-color: #ffaaff;
116 background-color: #ffaaff;
116 border-color: #ffccff #ff00ee #ff00ee #ffccff;
117 border-color: #ffccff #ff00ee #ff00ee #ffccff;
117 }
118 }
118 span.logtags span.tagtag {
119 span.logtags span.tagtag {
119 background-color: #ffffaa;
120 background-color: #ffffaa;
120 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
121 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
121 }
122 }
122 span.logtags span.branchtag {
123 span.logtags span.branchtag {
123 background-color: #aaffaa;
124 background-color: #aaffaa;
124 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
125 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
125 }
126 }
126 span.logtags span.inbranchtag {
127 span.logtags span.inbranchtag {
127 background-color: #d5dde6;
128 background-color: #d5dde6;
128 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
129 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
129 }
130 }
130 span.logtags span.bookmarktag {
131 span.logtags span.bookmarktag {
131 background-color: #afdffa;
132 background-color: #afdffa;
132 border-color: #ccecff #46ace6 #46ace6 #ccecff;
133 border-color: #ccecff #46ace6 #46ace6 #ccecff;
133 }
134 }
134 span.difflineplus { color:#008800; }
135 span.difflineplus { color:#008800; }
135 span.difflineminus { color:#cc0000; }
136 span.difflineminus { color:#cc0000; }
136 span.difflineat { color:#990099; }
137 span.difflineat { color:#990099; }
137 div.diffblocks { counter-reset: lineno; }
138 div.diffblocks { counter-reset: lineno; }
138 div.diffblock { counter-increment: lineno; }
139 div.diffblock { counter-increment: lineno; }
139 pre.sourcelines { position: relative; counter-reset: lineno; }
140 pre.sourcelines { position: relative; counter-reset: lineno; }
140 pre.sourcelines > span {
141 pre.sourcelines > span {
141 display: inline-block;
142 display: inline-block;
142 box-sizing: border-box;
143 box-sizing: border-box;
143 width: 100%;
144 width: 100%;
144 padding: 0 0 0 5em;
145 padding: 0 0 0 5em;
145 counter-increment: lineno;
146 counter-increment: lineno;
146 vertical-align: top;
147 vertical-align: top;
147 }
148 }
148 pre.sourcelines > span:before {
149 pre.sourcelines > span:before {
149 -moz-user-select: -moz-none;
150 -moz-user-select: -moz-none;
150 -khtml-user-select: none;
151 -khtml-user-select: none;
151 -webkit-user-select: none;
152 -webkit-user-select: none;
152 -ms-user-select: none;
153 -ms-user-select: none;
153 user-select: none;
154 user-select: none;
154 display: inline-block;
155 display: inline-block;
155 margin-left: -5em;
156 margin-left: -6em;
156 width: 4em;
157 width: 4em;
157 color: #999;
158 color: #999;
158 text-align: right;
159 text-align: right;
159 content: counters(lineno,".");
160 content: counters(lineno,".");
160 float: left;
161 float: left;
161 }
162 }
162 pre.sourcelines > a {
163 pre.sourcelines > a {
163 display: inline-block;
164 display: inline-block;
164 position: absolute;
165 position: absolute;
165 left: 0px;
166 left: 0px;
166 width: 4em;
167 width: 4em;
167 height: 1em;
168 height: 1em;
168 }
169 }
169 tr:target td,
170 tr:target td,
170 pre.sourcelines > span:target,
171 pre.sourcelines > span:target,
171 pre.sourcelines.stripes > span:target {
172 pre.sourcelines.stripes > span:target {
172 background-color: #bfdfff;
173 background-color: #bfdfff;
173 }
174 }
174
175
175 .description {
176 .description {
176 font-family: monospace;
177 font-family: monospace;
177 }
178 }
178
179
179 /* Followlines */
180 /* Followlines */
180 div.page_body table tbody.sourcelines > tr.followlines-select:hover,
181 div.page_body pre.sourcelines > span.followlines-select:hover {
182 cursor: cell;
183 }
184
185 tbody.sourcelines > tr.followlines-selected,
181 tbody.sourcelines > tr.followlines-selected,
186 pre.sourcelines > span.followlines-selected {
182 pre.sourcelines > span.followlines-selected {
187 background-color: #99C7E9 !important;
183 background-color: #99C7E9 !important;
188 }
184 }
189
185
190 div#followlines {
186 div#followlines {
191 background-color: #B7B7B7;
187 background-color: #B7B7B7;
192 border: 1px solid #CCC;
188 border: 1px solid #CCC;
193 border-radius: 5px;
189 border-radius: 5px;
194 padding: 4px;
190 padding: 4px;
195 position: fixed;
191 position: fixed;
196 }
192 }
197
193
198 div.followlines-cancel {
194 div.followlines-cancel {
199 text-align: right;
195 text-align: right;
200 }
196 }
201
197
202 div.followlines-cancel > button {
198 div.followlines-cancel > button {
203 line-height: 80%;
199 line-height: 80%;
204 padding: 0;
200 padding: 0;
205 border: 0;
201 border: 0;
206 border-radius: 2px;
202 border-radius: 2px;
207 background-color: inherit;
203 background-color: inherit;
208 font-weight: bold;
204 font-weight: bold;
209 }
205 }
210
206
211 div.followlines-cancel > button:hover {
207 div.followlines-cancel > button:hover {
212 color: #FFFFFF;
208 color: #FFFFFF;
213 background-color: #CF1F1F;
209 background-color: #CF1F1F;
214 }
210 }
215
211
216 div.followlines-link {
212 div.followlines-link {
217 margin: 2px;
213 margin: 2px;
218 margin-top: 4px;
214 margin-top: 4px;
219 font-family: sans-serif;
215 font-family: sans-serif;
220 }
216 }
221
217
222 div#followlines-tooltip {
218 .btn-followlines {
223 display: none;
219 display: none;
224 position: fixed;
220 cursor: pointer;
225 background-color: #ffc;
221 box-sizing: content-box;
226 border: 1px solid #999;
222 font-size: 11px;
227 padding: 2px;
223 width: 13px;
224 height: 13px;
225 border-radius: 3px;
226 margin: 0px;
227 margin-top: -2px;
228 padding: 0px;
229 background-color: #E5FDE5;
230 border: 1px solid #9BC19B;
231 font-family: monospace;
232 text-align: center;
233 line-height: 5px;
234 }
235
236 tr .btn-followlines {
237 position: absolute;
228 }
238 }
229
239
230 .sourcelines:hover > div#followlines-tooltip {
240 span .btn-followlines {
241 float: left;
242 }
243
244 span.followlines-select .btn-followlines {
245 margin-left: -1.6em;
246 }
247
248 .btn-followlines:hover {
249 transform: scale(1.1, 1.1);
250 }
251
252 .btn-followlines .followlines-plus {
253 color: green;
254 }
255
256 .btn-followlines .followlines-minus {
257 color: red;
258 }
259
260 .btn-followlines-end {
261 background-color: #ffdcdc;
262 }
263
264 .sourcelines tr:hover .btn-followlines,
265 .sourcelines span.followlines-select:hover > .btn-followlines {
231 display: inline;
266 display: inline;
232 }
267 }
233
268
234 .sourcelines:hover > div#followlines-tooltip.hidden {
269 .btn-followlines-hidden,
270 .sourcelines tr:hover .btn-followlines-hidden {
235 display: none;
271 display: none;
236 }
272 }
273
237 /* Graph */
274 /* Graph */
238 div#wrapper {
275 div#wrapper {
239 position: relative;
276 position: relative;
240 margin: 0;
277 margin: 0;
241 padding: 0;
278 padding: 0;
242 margin-top: 3px;
279 margin-top: 3px;
243 }
280 }
244
281
245 canvas {
282 canvas {
246 position: absolute;
283 position: absolute;
247 z-index: 5;
284 z-index: 5;
248 top: -0.9em;
285 top: -0.9em;
249 margin: 0;
286 margin: 0;
250 }
287 }
251
288
252 ul#nodebgs {
289 ul#nodebgs {
253 list-style: none inside none;
290 list-style: none inside none;
254 padding: 0;
291 padding: 0;
255 margin: 0;
292 margin: 0;
256 top: -0.7em;
293 top: -0.7em;
257 }
294 }
258
295
259 ul#graphnodes li, ul#nodebgs li {
296 ul#graphnodes li, ul#nodebgs li {
260 height: 39px;
297 height: 39px;
261 }
298 }
262
299
263 ul#graphnodes {
300 ul#graphnodes {
264 position: absolute;
301 position: absolute;
265 z-index: 10;
302 z-index: 10;
266 top: -0.8em;
303 top: -0.8em;
267 list-style: none inside none;
304 list-style: none inside none;
268 padding: 0;
305 padding: 0;
269 }
306 }
270
307
271 ul#graphnodes li .info {
308 ul#graphnodes li .info {
272 display: block;
309 display: block;
273 font-size: 100%;
310 font-size: 100%;
274 position: relative;
311 position: relative;
275 top: -3px;
312 top: -3px;
276 font-style: italic;
313 font-style: italic;
277 }
314 }
278
315
279 /* Comparison */
316 /* Comparison */
280 .legend {
317 .legend {
281 padding: 1.5% 0 1.5% 0;
318 padding: 1.5% 0 1.5% 0;
282 }
319 }
283
320
284 .legendinfo {
321 .legendinfo {
285 border: 1px solid #d9d8d1;
322 border: 1px solid #d9d8d1;
286 font-size: 80%;
323 font-size: 80%;
287 text-align: center;
324 text-align: center;
288 padding: 0.5%;
325 padding: 0.5%;
289 }
326 }
290
327
291 .equal {
328 .equal {
292 background-color: #ffffff;
329 background-color: #ffffff;
293 }
330 }
294
331
295 .delete {
332 .delete {
296 background-color: #faa;
333 background-color: #faa;
297 color: #333;
334 color: #333;
298 }
335 }
299
336
300 .insert {
337 .insert {
301 background-color: #ffa;
338 background-color: #ffa;
302 }
339 }
303
340
304 .replace {
341 .replace {
305 background-color: #e8e8e8;
342 background-color: #e8e8e8;
306 }
343 }
307
344
308 .comparison {
345 .comparison {
309 overflow-x: auto;
346 overflow-x: auto;
310 }
347 }
311
348
312 .header th {
349 .header th {
313 text-align: center;
350 text-align: center;
314 }
351 }
315
352
316 .block {
353 .block {
317 border-top: 1px solid #d9d8d1;
354 border-top: 1px solid #d9d8d1;
318 }
355 }
319
356
320 .scroll-loading {
357 .scroll-loading {
321 -webkit-animation: change_color 1s linear 0s infinite alternate;
358 -webkit-animation: change_color 1s linear 0s infinite alternate;
322 -moz-animation: change_color 1s linear 0s infinite alternate;
359 -moz-animation: change_color 1s linear 0s infinite alternate;
323 -o-animation: change_color 1s linear 0s infinite alternate;
360 -o-animation: change_color 1s linear 0s infinite alternate;
324 animation: change_color 1s linear 0s infinite alternate;
361 animation: change_color 1s linear 0s infinite alternate;
325 }
362 }
326
363
327 @-webkit-keyframes change_color {
364 @-webkit-keyframes change_color {
328 from { background-color: #A0CEFF; } to { }
365 from { background-color: #A0CEFF; } to { }
329 }
366 }
330 @-moz-keyframes change_color {
367 @-moz-keyframes change_color {
331 from { background-color: #A0CEFF; } to { }
368 from { background-color: #A0CEFF; } to { }
332 }
369 }
333 @-o-keyframes change_color {
370 @-o-keyframes change_color {
334 from { background-color: #A0CEFF; } to { }
371 from { background-color: #A0CEFF; } to { }
335 }
372 }
336 @keyframes change_color {
373 @keyframes change_color {
337 from { background-color: #A0CEFF; } to { }
374 from { background-color: #A0CEFF; } to { }
338 }
375 }
339
376
340 .scroll-loading-error {
377 .scroll-loading-error {
341 background-color: #FFCCCC !important;
378 background-color: #FFCCCC !important;
342 }
379 }
343
380
344 #doc {
381 #doc {
345 margin: 0 8px;
382 margin: 0 8px;
346 }
383 }
@@ -1,489 +1,526 b''
1 body {
1 body {
2 margin: 0;
2 margin: 0;
3 padding: 0;
3 padding: 0;
4 background: white;
4 background: white;
5 color: black;
5 color: black;
6 font-family: sans-serif;
6 font-family: sans-serif;
7 }
7 }
8
8
9 .container {
9 .container {
10 padding-left: 115px;
10 padding-left: 115px;
11 }
11 }
12
12
13 .main {
13 .main {
14 position: relative;
14 position: relative;
15 background: white;
15 background: white;
16 padding: 2em 2em 2em 0;
16 padding: 2em 2em 2em 0;
17 }
17 }
18
18
19 #.main {
19 #.main {
20 width: 98%;
20 width: 98%;
21 }
21 }
22
22
23 .overflow {
23 .overflow {
24 width: 100%;
24 width: 100%;
25 overflow: auto;
25 overflow: auto;
26 }
26 }
27
27
28 .menu {
28 .menu {
29 width: 90px;
29 width: 90px;
30 margin: 0;
30 margin: 0;
31 font-size: 80%;
31 font-size: 80%;
32 text-align: left;
32 text-align: left;
33 position: absolute;
33 position: absolute;
34 top: 20px;
34 top: 20px;
35 left: 20px;
35 left: 20px;
36 right: auto;
36 right: auto;
37 }
37 }
38
38
39 .menu ul {
39 .menu ul {
40 list-style: none;
40 list-style: none;
41 padding: 0;
41 padding: 0;
42 margin: 10px 0 0 0;
42 margin: 10px 0 0 0;
43 border-left: 2px solid #999;
43 border-left: 2px solid #999;
44 }
44 }
45
45
46 .menu li {
46 .menu li {
47 margin-bottom: 3px;
47 margin-bottom: 3px;
48 padding: 2px 4px;
48 padding: 2px 4px;
49 background: white;
49 background: white;
50 color: black;
50 color: black;
51 font-weight: normal;
51 font-weight: normal;
52 }
52 }
53
53
54 .menu li.active {
54 .menu li.active {
55 font-weight: bold;
55 font-weight: bold;
56 }
56 }
57
57
58 .menu img {
58 .menu img {
59 width: 75px;
59 width: 75px;
60 height: 90px;
60 height: 90px;
61 border: 0;
61 border: 0;
62 }
62 }
63
63
64 div.atom-logo {
64 div.atom-logo {
65 margin-top: 10px;
65 margin-top: 10px;
66 }
66 }
67
67
68 .atom-logo img{
68 .atom-logo img{
69 width: 14px;
69 width: 14px;
70 height: 14px;
70 height: 14px;
71 border: 0;
71 border: 0;
72 }
72 }
73
73
74 .menu a { color: black; display: block; }
74 .menu a { color: black; display: block; }
75
75
76 .search {
76 .search {
77 position: absolute;
77 position: absolute;
78 top: .7em;
78 top: .7em;
79 right: 2em;
79 right: 2em;
80 }
80 }
81
81
82 form.search div#hint {
82 form.search div#hint {
83 display: none;
83 display: none;
84 position: absolute;
84 position: absolute;
85 top: 40px;
85 top: 40px;
86 right: 0px;
86 right: 0px;
87 width: 190px;
87 width: 190px;
88 padding: 5px;
88 padding: 5px;
89 background: #ffc;
89 background: #ffc;
90 font-size: 70%;
90 font-size: 70%;
91 border: 1px solid yellow;
91 border: 1px solid yellow;
92 border-radius: 5px;
92 border-radius: 5px;
93 }
93 }
94
94
95 form.search:hover div#hint { display: block; }
95 form.search:hover div#hint { display: block; }
96
96
97 a { text-decoration:none; }
97 a { text-decoration:none; }
98 .age { white-space:nowrap; }
98 .age { white-space:nowrap; }
99 .date { white-space:nowrap; }
99 .date { white-space:nowrap; }
100 .indexlinks { white-space:nowrap; }
100 .indexlinks { white-space:nowrap; }
101 .parity0,
101 .parity0,
102 .stripes4 > :nth-child(4n+1),
102 .stripes4 > :nth-child(4n+1),
103 .stripes2 > :nth-child(2n+1) { background-color: #f0f0f0; }
103 .stripes2 > :nth-child(2n+1) { background-color: #f0f0f0; }
104 .parity1,
104 .parity1,
105 .stripes4 > :nth-child(4n+3),
105 .stripes4 > :nth-child(4n+3),
106 .stripes2 > :nth-child(2n+2) { background-color: white; }
106 .stripes2 > :nth-child(2n+2) { background-color: white; }
107 .plusline { color: green; }
107 .plusline { color: green; }
108 .minusline { color: #dc143c; } /* crimson */
108 .minusline { color: #dc143c; } /* crimson */
109 .atline { color: purple; }
109 .atline { color: purple; }
110
110
111 .diffstat-table {
111 .diffstat-table {
112 margin-top: 1em;
112 margin-top: 1em;
113 }
113 }
114 .diffstat-file {
114 .diffstat-file {
115 white-space: nowrap;
115 white-space: nowrap;
116 font-size: 90%;
116 font-size: 90%;
117 }
117 }
118 .diffstat-total {
118 .diffstat-total {
119 white-space: nowrap;
119 white-space: nowrap;
120 font-size: 90%;
120 font-size: 90%;
121 }
121 }
122 .diffstat-graph {
122 .diffstat-graph {
123 width: 100%;
123 width: 100%;
124 }
124 }
125 .diffstat-add {
125 .diffstat-add {
126 background-color: green;
126 background-color: green;
127 float: left;
127 float: left;
128 }
128 }
129 .diffstat-remove {
129 .diffstat-remove {
130 background-color: red;
130 background-color: red;
131 float: left;
131 float: left;
132 }
132 }
133
133
134 .navigate {
134 .navigate {
135 text-align: right;
135 text-align: right;
136 font-size: 60%;
136 font-size: 60%;
137 margin: 1em 0;
137 margin: 1em 0;
138 }
138 }
139
139
140 .tag {
140 .tag {
141 color: #999;
141 color: #999;
142 font-size: 70%;
142 font-size: 70%;
143 font-weight: normal;
143 font-weight: normal;
144 margin-left: .5em;
144 margin-left: .5em;
145 vertical-align: baseline;
145 vertical-align: baseline;
146 }
146 }
147
147
148 .branchhead {
148 .branchhead {
149 color: #000;
149 color: #000;
150 font-size: 80%;
150 font-size: 80%;
151 font-weight: normal;
151 font-weight: normal;
152 margin-left: .5em;
152 margin-left: .5em;
153 vertical-align: baseline;
153 vertical-align: baseline;
154 }
154 }
155
155
156 ul#graphnodes .branchhead {
156 ul#graphnodes .branchhead {
157 font-size: 75%;
157 font-size: 75%;
158 }
158 }
159
159
160 .branchname {
160 .branchname {
161 color: #000;
161 color: #000;
162 font-size: 60%;
162 font-size: 60%;
163 font-weight: normal;
163 font-weight: normal;
164 margin-left: .5em;
164 margin-left: .5em;
165 vertical-align: baseline;
165 vertical-align: baseline;
166 }
166 }
167
167
168 h3 .branchname {
168 h3 .branchname {
169 font-size: 80%;
169 font-size: 80%;
170 }
170 }
171
171
172 /* Common */
172 /* Common */
173 pre { margin: 0; }
173 pre { margin: 0; }
174
174
175 h2 { font-size: 120%; border-bottom: 1px solid #999; }
175 h2 { font-size: 120%; border-bottom: 1px solid #999; }
176 h2 a { color: #000; }
176 h2 a { color: #000; }
177 h3 {
177 h3 {
178 margin-top: +.7em;
178 margin-top: +.7em;
179 font-size: 100%;
179 font-size: 100%;
180 }
180 }
181
181
182 /* log and tags tables */
182 /* log and tags tables */
183 .bigtable {
183 .bigtable {
184 border-bottom: 1px solid #999;
184 border-bottom: 1px solid #999;
185 border-collapse: collapse;
185 border-collapse: collapse;
186 font-size: 90%;
186 font-size: 90%;
187 width: 100%;
187 width: 100%;
188 font-weight: normal;
188 font-weight: normal;
189 text-align: left;
189 text-align: left;
190 }
190 }
191
191
192 .bigtable td {
192 .bigtable td {
193 vertical-align: top;
193 vertical-align: top;
194 }
194 }
195
195
196 .bigtable th {
196 .bigtable th {
197 padding: 1px 4px;
197 padding: 1px 4px;
198 border-bottom: 1px solid #999;
198 border-bottom: 1px solid #999;
199 }
199 }
200 .bigtable tr { border: none; }
200 .bigtable tr { border: none; }
201 .bigtable .age { width: 7em; }
201 .bigtable .age { width: 7em; }
202 .bigtable .author { width: 15em; }
202 .bigtable .author { width: 15em; }
203 .bigtable .description { }
203 .bigtable .description { }
204 .bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; }
204 .bigtable .description .base { font-size: 70%; float: right; line-height: 1.66; }
205 .bigtable .node { width: 5em; font-family: monospace;}
205 .bigtable .node { width: 5em; font-family: monospace;}
206 .bigtable .permissions { width: 8em; text-align: left;}
206 .bigtable .permissions { width: 8em; text-align: left;}
207 .bigtable .size { width: 5em; text-align: right; }
207 .bigtable .size { width: 5em; text-align: right; }
208 .bigtable .annotate { text-align: right; }
208 .bigtable .annotate { text-align: right; }
209 .bigtable td.annotate { font-size: smaller; }
209 .bigtable td.annotate { font-size: smaller; }
210 .bigtable td.source { font-size: inherit; }
210 .bigtable td.source { font-size: inherit; }
211 tr.thisrev a { color:#999999; text-decoration: none; }
211 tr.thisrev a { color:#999999; text-decoration: none; }
212 tr.thisrev td.source { color:#009900; }
212 tr.thisrev td.source { color:#009900; }
213 td.annotate {
213 td.annotate {
214 white-space: nowrap;
214 white-space: nowrap;
215 }
215 }
216 div.annotate-info {
216 div.annotate-info {
217 z-index: 5;
217 display: none;
218 display: none;
218 position: absolute;
219 position: absolute;
219 background-color: #FFFFFF;
220 background-color: #FFFFFF;
220 border: 1px solid #999;
221 border: 1px solid #999;
221 text-align: left;
222 text-align: left;
222 color: #000000;
223 color: #000000;
223 padding: 5px;
224 padding: 5px;
224 }
225 }
225 div.annotate-info a { color: #0000FF; }
226 div.annotate-info a { color: #0000FF; }
226 td.annotate:hover div.annotate-info { display: inline; }
227 td.annotate:hover div.annotate-info { display: inline; }
227
228
228 .source, .sourcefirst {
229 .source, .sourcefirst {
229 font-family: monospace;
230 font-family: monospace;
230 white-space: pre;
231 white-space: pre;
231 padding: 1px 4px;
232 padding: 1px 4px;
232 font-size: 90%;
233 font-size: 90%;
233 }
234 }
234 .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
235 .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
235 .source a { color: #999; font-size: smaller; font-family: monospace;}
236 .source a { color: #999; font-size: smaller; font-family: monospace;}
236 .bottomline { border-bottom: 1px solid #999; }
237 .bottomline { border-bottom: 1px solid #999; }
237
238
238 .sourcelines {
239 .sourcelines {
239 font-size: 90%;
240 font-size: 90%;
240 position: relative;
241 position: relative;
241 counter-reset: lineno;
242 counter-reset: lineno;
242 }
243 }
243
244
244 .wrap > span {
245 .wrap > span {
245 white-space: pre-wrap;
246 white-space: pre-wrap;
246 }
247 }
247
248
248 .linewraptoggle {
249 .linewraptoggle {
249 float: right;
250 float: right;
250 }
251 }
251
252
252 .diffblocks { counter-reset: lineno; }
253 .diffblocks { counter-reset: lineno; }
253 .diffblocks > div { counter-increment: lineno; }
254 .diffblocks > div { counter-increment: lineno; }
254
255
255 .sourcelines > span {
256 .sourcelines > span {
256 display: inline-block;
257 display: inline-block;
257 box-sizing: border-box;
258 box-sizing: border-box;
258 width: 100%;
259 width: 100%;
259 padding: 1px 0px 1px 5em;
260 padding: 1px 0px 1px 5em;
260 counter-increment: lineno;
261 counter-increment: lineno;
261 }
262 }
262
263
263 .sourcelines > span:before {
264 .sourcelines > span:before {
264 -moz-user-select: -moz-none;
265 -moz-user-select: -moz-none;
265 -khtml-user-select: none;
266 -khtml-user-select: none;
266 -webkit-user-select: none;
267 -webkit-user-select: none;
267 -ms-user-select: none;
268 -ms-user-select: none;
268 user-select: none;
269 user-select: none;
269 display: inline-block;
270 display: inline-block;
270 margin-left: -5em;
271 margin-left: -6em;
271 width: 4em;
272 width: 4em;
272 font-size: smaller;
273 font-size: smaller;
273 color: #999;
274 color: #999;
274 text-align: right;
275 text-align: right;
275 content: counters(lineno, ".");
276 content: counters(lineno, ".");
276 float: left;
277 float: left;
277 }
278 }
278
279
279 .sourcelines > span:target, tr:target td {
280 .sourcelines > span:target, tr:target td {
280 background-color: #bfdfff;
281 background-color: #bfdfff;
281 }
282 }
282
283
283 div.overflow table tbody.sourcelines > tr.followlines-select:hover,
284 /* Followlines */
284 div.overflow pre.sourcelines > span.followlines-select:hover {
285 cursor: cell;
286 }
287
288 tbody.sourcelines > tr.followlines-selected,
285 tbody.sourcelines > tr.followlines-selected,
289 pre.sourcelines > span.followlines-selected {
286 pre.sourcelines > span.followlines-selected {
290 background-color: #99C7E9;
287 background-color: #99C7E9;
291 }
288 }
292
289
293 div#followlines {
290 div#followlines {
294 background-color: #B7B7B7;
291 background-color: #B7B7B7;
295 border: 1px solid #CCC;
292 border: 1px solid #CCC;
296 border-radius: 5px;
293 border-radius: 5px;
297 padding: 4px;
294 padding: 4px;
298 position: fixed;
295 position: fixed;
299 }
296 }
300
297
301 div.followlines-cancel {
298 div.followlines-cancel {
302 text-align: right;
299 text-align: right;
303 }
300 }
304
301
305 div.followlines-cancel > button {
302 div.followlines-cancel > button {
306 line-height: 80%;
303 line-height: 80%;
307 padding: 0;
304 padding: 0;
308 border: 0;
305 border: 0;
309 border-radius: 2px;
306 border-radius: 2px;
310 background-color: inherit;
307 background-color: inherit;
311 font-weight: bold;
308 font-weight: bold;
312 }
309 }
313
310
314 div.followlines-cancel > button:hover {
311 div.followlines-cancel > button:hover {
315 color: #FFFFFF;
312 color: #FFFFFF;
316 background-color: #CF1F1F;
313 background-color: #CF1F1F;
317 }
314 }
318
315
319 div.followlines-link {
316 div.followlines-link {
320 margin: 2px;
317 margin: 2px;
321 margin-top: 4px;
318 margin-top: 4px;
322 font-family: sans-serif;
319 font-family: sans-serif;
323 }
320 }
324
321
325 div#followlines-tooltip {
322 .btn-followlines {
326 display: none;
323 display: none;
327 position: fixed;
324 cursor: pointer;
328 background-color: #ffc;
325 box-sizing: content-box;
329 border: 1px solid #999;
326 font-size: 12px;
330 padding: 2px;
327 width: 13px;
328 height: 13px;
329 border-radius: 3px;
330 margin: 0px;
331 margin-top: -2px;
332 padding: 0px;
333 background-color: #E5FDE5;
334 border: 1px solid #9BC19B;
335 font-family: monospace;
336 text-align: center;
337 line-height: 5px;
338 }
339
340 tr .btn-followlines {
341 position: absolute;
331 }
342 }
332
343
333 .sourcelines:hover > div#followlines-tooltip {
344 span .btn-followlines {
345 float: left;
346 }
347
348 span.followlines-select .btn-followlines {
349 margin-left: -1.5em;
350 }
351
352 .btn-followlines:hover {
353 transform: scale(1.2, 1.2);
354 }
355
356 .btn-followlines .followlines-plus {
357 color: green;
358 }
359
360 .btn-followlines .followlines-minus {
361 color: red;
362 }
363
364 .btn-followlines-end {
365 background-color: #ffdcdc;
366 }
367
368 .sourcelines tr:hover .btn-followlines,
369 .sourcelines span.followlines-select:hover > .btn-followlines {
334 display: inline;
370 display: inline;
335 }
371 }
336
372
337 .sourcelines:hover > div#followlines-tooltip.hidden {
373 .btn-followlines-hidden,
374 .sourcelines tr:hover .btn-followlines-hidden {
338 display: none;
375 display: none;
339 }
376 }
340
377
341 .sourcelines > a {
378 .sourcelines > a {
342 display: inline-block;
379 display: inline-block;
343 position: absolute;
380 position: absolute;
344 left: 0px;
381 left: 0px;
345 width: 4em;
382 width: 4em;
346 height: 1em;
383 height: 1em;
347 }
384 }
348
385
349 .fileline { font-family: monospace; }
386 .fileline { font-family: monospace; }
350 .fileline img { border: 0; }
387 .fileline img { border: 0; }
351
388
352 .tagEntry .closed { color: #99f; }
389 .tagEntry .closed { color: #99f; }
353
390
354 /* Changeset entry */
391 /* Changeset entry */
355 #changesetEntry {
392 #changesetEntry {
356 border-collapse: collapse;
393 border-collapse: collapse;
357 font-size: 90%;
394 font-size: 90%;
358 width: 100%;
395 width: 100%;
359 margin-bottom: 1em;
396 margin-bottom: 1em;
360 }
397 }
361
398
362 #changesetEntry th {
399 #changesetEntry th {
363 padding: 1px 4px;
400 padding: 1px 4px;
364 width: 4em;
401 width: 4em;
365 text-align: right;
402 text-align: right;
366 font-weight: normal;
403 font-weight: normal;
367 color: #999;
404 color: #999;
368 margin-right: .5em;
405 margin-right: .5em;
369 vertical-align: top;
406 vertical-align: top;
370 }
407 }
371
408
372 div.description {
409 div.description {
373 border-left: 2px solid #999;
410 border-left: 2px solid #999;
374 margin: 1em 0 1em 0;
411 margin: 1em 0 1em 0;
375 padding: .3em;
412 padding: .3em;
376 white-space: pre;
413 white-space: pre;
377 font-family: monospace;
414 font-family: monospace;
378 }
415 }
379
416
380 /* Graph */
417 /* Graph */
381 div#wrapper {
418 div#wrapper {
382 position: relative;
419 position: relative;
383 border-top: 1px solid black;
420 border-top: 1px solid black;
384 border-bottom: 1px solid black;
421 border-bottom: 1px solid black;
385 margin: 0;
422 margin: 0;
386 padding: 0;
423 padding: 0;
387 }
424 }
388
425
389 canvas {
426 canvas {
390 position: absolute;
427 position: absolute;
391 z-index: 5;
428 z-index: 5;
392 top: -0.7em;
429 top: -0.7em;
393 margin: 0;
430 margin: 0;
394 }
431 }
395
432
396 ul#graphnodes {
433 ul#graphnodes {
397 position: absolute;
434 position: absolute;
398 z-index: 10;
435 z-index: 10;
399 top: -1.0em;
436 top: -1.0em;
400 list-style: none inside none;
437 list-style: none inside none;
401 padding: 0;
438 padding: 0;
402 }
439 }
403
440
404 ul#nodebgs {
441 ul#nodebgs {
405 list-style: none inside none;
442 list-style: none inside none;
406 padding: 0;
443 padding: 0;
407 margin: 0;
444 margin: 0;
408 top: -0.7em;
445 top: -0.7em;
409 }
446 }
410
447
411 ul#graphnodes li, ul#nodebgs li {
448 ul#graphnodes li, ul#nodebgs li {
412 height: 39px;
449 height: 39px;
413 }
450 }
414
451
415 ul#graphnodes li .info {
452 ul#graphnodes li .info {
416 display: block;
453 display: block;
417 font-size: 70%;
454 font-size: 70%;
418 position: relative;
455 position: relative;
419 top: -3px;
456 top: -3px;
420 }
457 }
421
458
422 /* Comparison */
459 /* Comparison */
423 .legend {
460 .legend {
424 padding: 1.5% 0 1.5% 0;
461 padding: 1.5% 0 1.5% 0;
425 }
462 }
426
463
427 .legendinfo {
464 .legendinfo {
428 border: 1px solid #999;
465 border: 1px solid #999;
429 font-size: 80%;
466 font-size: 80%;
430 text-align: center;
467 text-align: center;
431 padding: 0.5%;
468 padding: 0.5%;
432 }
469 }
433
470
434 .equal {
471 .equal {
435 background-color: #ffffff;
472 background-color: #ffffff;
436 }
473 }
437
474
438 .delete {
475 .delete {
439 background-color: #faa;
476 background-color: #faa;
440 color: #333;
477 color: #333;
441 }
478 }
442
479
443 .insert {
480 .insert {
444 background-color: #ffa;
481 background-color: #ffa;
445 }
482 }
446
483
447 .replace {
484 .replace {
448 background-color: #e8e8e8;
485 background-color: #e8e8e8;
449 }
486 }
450
487
451 .header {
488 .header {
452 text-align: center;
489 text-align: center;
453 }
490 }
454
491
455 .block {
492 .block {
456 border-top: 1px solid #999;
493 border-top: 1px solid #999;
457 }
494 }
458
495
459 .breadcrumb {
496 .breadcrumb {
460 color: gray;
497 color: gray;
461 }
498 }
462
499
463 .breadcrumb a {
500 .breadcrumb a {
464 color: blue;
501 color: blue;
465 }
502 }
466
503
467 .scroll-loading {
504 .scroll-loading {
468 -webkit-animation: change_color 1s linear 0s infinite alternate;
505 -webkit-animation: change_color 1s linear 0s infinite alternate;
469 -moz-animation: change_color 1s linear 0s infinite alternate;
506 -moz-animation: change_color 1s linear 0s infinite alternate;
470 -o-animation: change_color 1s linear 0s infinite alternate;
507 -o-animation: change_color 1s linear 0s infinite alternate;
471 animation: change_color 1s linear 0s infinite alternate;
508 animation: change_color 1s linear 0s infinite alternate;
472 }
509 }
473
510
474 @-webkit-keyframes change_color {
511 @-webkit-keyframes change_color {
475 from { background-color: #A0CEFF; } to { }
512 from { background-color: #A0CEFF; } to { }
476 }
513 }
477 @-moz-keyframes change_color {
514 @-moz-keyframes change_color {
478 from { background-color: #A0CEFF; } to { }
515 from { background-color: #A0CEFF; } to { }
479 }
516 }
480 @-o-keyframes change_color {
517 @-o-keyframes change_color {
481 from { background-color: #A0CEFF; } to { }
518 from { background-color: #A0CEFF; } to { }
482 }
519 }
483 @keyframes change_color {
520 @keyframes change_color {
484 from { background-color: #A0CEFF; } to { }
521 from { background-color: #A0CEFF; } to { }
485 }
522 }
486
523
487 .scroll-loading-error {
524 .scroll-loading-error {
488 background-color: #FFCCCC !important;
525 background-color: #FFCCCC !important;
489 }
526 }
@@ -1,836 +1,873 b''
1 #require serve
1 #require serve
2
2
3 Some tests for hgweb. Tests static files, plain files and different 404's.
3 Some tests for hgweb. Tests static files, plain files and different 404's.
4
4
5 $ hg init test
5 $ hg init test
6 $ cd test
6 $ cd test
7 $ mkdir da
7 $ mkdir da
8 $ echo foo > da/foo
8 $ echo foo > da/foo
9 $ echo foo > foo
9 $ echo foo > foo
10 $ hg ci -Ambase
10 $ hg ci -Ambase
11 adding da/foo
11 adding da/foo
12 adding foo
12 adding foo
13 $ hg bookmark -r0 '@'
13 $ hg bookmark -r0 '@'
14 $ hg bookmark -r0 'a b c'
14 $ hg bookmark -r0 'a b c'
15 $ hg bookmark -r0 'd/e/f'
15 $ hg bookmark -r0 'd/e/f'
16 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
16 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
17 $ cat hg.pid >> $DAEMON_PIDS
17 $ cat hg.pid >> $DAEMON_PIDS
18
18
19 manifest
19 manifest
20
20
21 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=raw')
21 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=raw')
22 200 Script output follows
22 200 Script output follows
23
23
24
24
25 drwxr-xr-x da
25 drwxr-xr-x da
26 -rw-r--r-- 4 foo
26 -rw-r--r-- 4 foo
27
27
28
28
29 $ (get-with-headers.py localhost:$HGPORT 'file/tip/da?style=raw')
29 $ (get-with-headers.py localhost:$HGPORT 'file/tip/da?style=raw')
30 200 Script output follows
30 200 Script output follows
31
31
32
32
33 -rw-r--r-- 4 foo
33 -rw-r--r-- 4 foo
34
34
35
35
36
36
37 plain file
37 plain file
38
38
39 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?style=raw'
39 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?style=raw'
40 200 Script output follows
40 200 Script output follows
41
41
42 foo
42 foo
43
43
44 should give a 404 - static file that does not exist
44 should give a 404 - static file that does not exist
45
45
46 $ get-with-headers.py localhost:$HGPORT 'static/bogus'
46 $ get-with-headers.py localhost:$HGPORT 'static/bogus'
47 404 Not Found
47 404 Not Found
48
48
49 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
49 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
50 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
50 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
51 <head>
51 <head>
52 <link rel="icon" href="/static/hgicon.png" type="image/png" />
52 <link rel="icon" href="/static/hgicon.png" type="image/png" />
53 <meta name="robots" content="index, nofollow" />
53 <meta name="robots" content="index, nofollow" />
54 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
54 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
55 <script type="text/javascript" src="/static/mercurial.js"></script>
55 <script type="text/javascript" src="/static/mercurial.js"></script>
56
56
57 <title>test: error</title>
57 <title>test: error</title>
58 </head>
58 </head>
59 <body>
59 <body>
60
60
61 <div class="container">
61 <div class="container">
62 <div class="menu">
62 <div class="menu">
63 <div class="logo">
63 <div class="logo">
64 <a href="https://mercurial-scm.org/">
64 <a href="https://mercurial-scm.org/">
65 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
65 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
66 </div>
66 </div>
67 <ul>
67 <ul>
68 <li><a href="/shortlog">log</a></li>
68 <li><a href="/shortlog">log</a></li>
69 <li><a href="/graph">graph</a></li>
69 <li><a href="/graph">graph</a></li>
70 <li><a href="/tags">tags</a></li>
70 <li><a href="/tags">tags</a></li>
71 <li><a href="/bookmarks">bookmarks</a></li>
71 <li><a href="/bookmarks">bookmarks</a></li>
72 <li><a href="/branches">branches</a></li>
72 <li><a href="/branches">branches</a></li>
73 </ul>
73 </ul>
74 <ul>
74 <ul>
75 <li><a href="/help">help</a></li>
75 <li><a href="/help">help</a></li>
76 </ul>
76 </ul>
77 </div>
77 </div>
78
78
79 <div class="main">
79 <div class="main">
80
80
81 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
81 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
82 <h3>error</h3>
82 <h3>error</h3>
83
83
84
84
85 <form class="search" action="/log">
85 <form class="search" action="/log">
86
86
87 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
87 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
88 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
88 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
89 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
89 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
90 </form>
90 </form>
91
91
92 <div class="description">
92 <div class="description">
93 <p>
93 <p>
94 An error occurred while processing your request:
94 An error occurred while processing your request:
95 </p>
95 </p>
96 <p>
96 <p>
97 Not Found
97 Not Found
98 </p>
98 </p>
99 </div>
99 </div>
100 </div>
100 </div>
101 </div>
101 </div>
102
102
103
103
104
104
105 </body>
105 </body>
106 </html>
106 </html>
107
107
108 [1]
108 [1]
109
109
110 should give a 404 - bad revision
110 should give a 404 - bad revision
111
111
112 $ get-with-headers.py localhost:$HGPORT 'file/spam/foo?style=raw'
112 $ get-with-headers.py localhost:$HGPORT 'file/spam/foo?style=raw'
113 404 Not Found
113 404 Not Found
114
114
115
115
116 error: revision not found: spam
116 error: revision not found: spam
117 [1]
117 [1]
118
118
119 should give a 400 - bad command
119 should give a 400 - bad command
120
120
121 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?cmd=spam&style=raw'
121 $ get-with-headers.py localhost:$HGPORT 'file/tip/foo?cmd=spam&style=raw'
122 400* (glob)
122 400* (glob)
123
123
124
124
125 error: no such method: spam
125 error: no such method: spam
126 [1]
126 [1]
127
127
128 $ get-with-headers.py --headeronly localhost:$HGPORT '?cmd=spam'
128 $ get-with-headers.py --headeronly localhost:$HGPORT '?cmd=spam'
129 400 no such method: spam
129 400 no such method: spam
130 [1]
130 [1]
131
131
132 should give a 400 - bad command as a part of url path (issue4071)
132 should give a 400 - bad command as a part of url path (issue4071)
133
133
134 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam'
134 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam'
135 400 no such method: spam
135 400 no such method: spam
136 [1]
136 [1]
137
137
138 $ get-with-headers.py --headeronly localhost:$HGPORT 'raw-spam'
138 $ get-with-headers.py --headeronly localhost:$HGPORT 'raw-spam'
139 400 no such method: spam
139 400 no such method: spam
140 [1]
140 [1]
141
141
142 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam/tip/foo'
142 $ get-with-headers.py --headeronly localhost:$HGPORT 'spam/tip/foo'
143 400 no such method: spam
143 400 no such method: spam
144 [1]
144 [1]
145
145
146 should give a 404 - file does not exist
146 should give a 404 - file does not exist
147
147
148 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork?style=raw'
148 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork?style=raw'
149 404 Not Found
149 404 Not Found
150
150
151
151
152 error: bork@2ef0ac749a14: not found in manifest
152 error: bork@2ef0ac749a14: not found in manifest
153 [1]
153 [1]
154 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork'
154 $ get-with-headers.py localhost:$HGPORT 'file/tip/bork'
155 404 Not Found
155 404 Not Found
156
156
157 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
157 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
158 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
158 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
159 <head>
159 <head>
160 <link rel="icon" href="/static/hgicon.png" type="image/png" />
160 <link rel="icon" href="/static/hgicon.png" type="image/png" />
161 <meta name="robots" content="index, nofollow" />
161 <meta name="robots" content="index, nofollow" />
162 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
162 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
163 <script type="text/javascript" src="/static/mercurial.js"></script>
163 <script type="text/javascript" src="/static/mercurial.js"></script>
164
164
165 <title>test: error</title>
165 <title>test: error</title>
166 </head>
166 </head>
167 <body>
167 <body>
168
168
169 <div class="container">
169 <div class="container">
170 <div class="menu">
170 <div class="menu">
171 <div class="logo">
171 <div class="logo">
172 <a href="https://mercurial-scm.org/">
172 <a href="https://mercurial-scm.org/">
173 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
173 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
174 </div>
174 </div>
175 <ul>
175 <ul>
176 <li><a href="/shortlog">log</a></li>
176 <li><a href="/shortlog">log</a></li>
177 <li><a href="/graph">graph</a></li>
177 <li><a href="/graph">graph</a></li>
178 <li><a href="/tags">tags</a></li>
178 <li><a href="/tags">tags</a></li>
179 <li><a href="/bookmarks">bookmarks</a></li>
179 <li><a href="/bookmarks">bookmarks</a></li>
180 <li><a href="/branches">branches</a></li>
180 <li><a href="/branches">branches</a></li>
181 </ul>
181 </ul>
182 <ul>
182 <ul>
183 <li><a href="/help">help</a></li>
183 <li><a href="/help">help</a></li>
184 </ul>
184 </ul>
185 </div>
185 </div>
186
186
187 <div class="main">
187 <div class="main">
188
188
189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
189 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
190 <h3>error</h3>
190 <h3>error</h3>
191
191
192
192
193 <form class="search" action="/log">
193 <form class="search" action="/log">
194
194
195 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
195 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
196 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
196 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
197 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
197 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
198 </form>
198 </form>
199
199
200 <div class="description">
200 <div class="description">
201 <p>
201 <p>
202 An error occurred while processing your request:
202 An error occurred while processing your request:
203 </p>
203 </p>
204 <p>
204 <p>
205 bork@2ef0ac749a14: not found in manifest
205 bork@2ef0ac749a14: not found in manifest
206 </p>
206 </p>
207 </div>
207 </div>
208 </div>
208 </div>
209 </div>
209 </div>
210
210
211
211
212
212
213 </body>
213 </body>
214 </html>
214 </html>
215
215
216 [1]
216 [1]
217 $ get-with-headers.py localhost:$HGPORT 'diff/tip/bork?style=raw'
217 $ get-with-headers.py localhost:$HGPORT 'diff/tip/bork?style=raw'
218 404 Not Found
218 404 Not Found
219
219
220
220
221 error: bork@2ef0ac749a14: not found in manifest
221 error: bork@2ef0ac749a14: not found in manifest
222 [1]
222 [1]
223
223
224 try bad style
224 try bad style
225
225
226 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=foobar')
226 $ (get-with-headers.py localhost:$HGPORT 'file/tip/?style=foobar')
227 200 Script output follows
227 200 Script output follows
228
228
229 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
229 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
230 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
230 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
231 <head>
231 <head>
232 <link rel="icon" href="/static/hgicon.png" type="image/png" />
232 <link rel="icon" href="/static/hgicon.png" type="image/png" />
233 <meta name="robots" content="index, nofollow" />
233 <meta name="robots" content="index, nofollow" />
234 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
234 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
235 <script type="text/javascript" src="/static/mercurial.js"></script>
235 <script type="text/javascript" src="/static/mercurial.js"></script>
236
236
237 <title>test: 2ef0ac749a14 /</title>
237 <title>test: 2ef0ac749a14 /</title>
238 </head>
238 </head>
239 <body>
239 <body>
240
240
241 <div class="container">
241 <div class="container">
242 <div class="menu">
242 <div class="menu">
243 <div class="logo">
243 <div class="logo">
244 <a href="https://mercurial-scm.org/">
244 <a href="https://mercurial-scm.org/">
245 <img src="/static/hglogo.png" alt="mercurial" /></a>
245 <img src="/static/hglogo.png" alt="mercurial" /></a>
246 </div>
246 </div>
247 <ul>
247 <ul>
248 <li><a href="/shortlog/tip">log</a></li>
248 <li><a href="/shortlog/tip">log</a></li>
249 <li><a href="/graph/tip">graph</a></li>
249 <li><a href="/graph/tip">graph</a></li>
250 <li><a href="/tags">tags</a></li>
250 <li><a href="/tags">tags</a></li>
251 <li><a href="/bookmarks">bookmarks</a></li>
251 <li><a href="/bookmarks">bookmarks</a></li>
252 <li><a href="/branches">branches</a></li>
252 <li><a href="/branches">branches</a></li>
253 </ul>
253 </ul>
254 <ul>
254 <ul>
255 <li><a href="/rev/tip">changeset</a></li>
255 <li><a href="/rev/tip">changeset</a></li>
256 <li class="active">browse</li>
256 <li class="active">browse</li>
257 </ul>
257 </ul>
258 <ul>
258 <ul>
259
259
260 </ul>
260 </ul>
261 <ul>
261 <ul>
262 <li><a href="/help">help</a></li>
262 <li><a href="/help">help</a></li>
263 </ul>
263 </ul>
264 </div>
264 </div>
265
265
266 <div class="main">
266 <div class="main">
267 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
267 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
268 <h3>
268 <h3>
269 directory / @ 0:<a href="/rev/2ef0ac749a14">2ef0ac749a14</a>
269 directory / @ 0:<a href="/rev/2ef0ac749a14">2ef0ac749a14</a>
270 <span class="tag">tip</span> <span class="tag">@</span> <span class="tag">a b c</span> <span class="tag">d/e/f</span>
270 <span class="tag">tip</span> <span class="tag">@</span> <span class="tag">a b c</span> <span class="tag">d/e/f</span>
271 </h3>
271 </h3>
272
272
273
273
274 <form class="search" action="/log">
274 <form class="search" action="/log">
275
275
276 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
276 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
277 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
277 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
278 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
278 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
279 </form>
279 </form>
280
280
281 <table class="bigtable">
281 <table class="bigtable">
282 <thead>
282 <thead>
283 <tr>
283 <tr>
284 <th class="name">name</th>
284 <th class="name">name</th>
285 <th class="size">size</th>
285 <th class="size">size</th>
286 <th class="permissions">permissions</th>
286 <th class="permissions">permissions</th>
287 </tr>
287 </tr>
288 </thead>
288 </thead>
289 <tbody class="stripes2">
289 <tbody class="stripes2">
290 <tr class="fileline">
290 <tr class="fileline">
291 <td class="name"><a href="/file/tip/">[up]</a></td>
291 <td class="name"><a href="/file/tip/">[up]</a></td>
292 <td class="size"></td>
292 <td class="size"></td>
293 <td class="permissions">drwxr-xr-x</td>
293 <td class="permissions">drwxr-xr-x</td>
294 </tr>
294 </tr>
295
295
296 <tr class="fileline">
296 <tr class="fileline">
297 <td class="name">
297 <td class="name">
298 <a href="/file/tip/da">
298 <a href="/file/tip/da">
299 <img src="/static/coal-folder.png" alt="dir."/> da/
299 <img src="/static/coal-folder.png" alt="dir."/> da/
300 </a>
300 </a>
301 <a href="/file/tip/da/">
301 <a href="/file/tip/da/">
302
302
303 </a>
303 </a>
304 </td>
304 </td>
305 <td class="size"></td>
305 <td class="size"></td>
306 <td class="permissions">drwxr-xr-x</td>
306 <td class="permissions">drwxr-xr-x</td>
307 </tr>
307 </tr>
308
308
309 <tr class="fileline">
309 <tr class="fileline">
310 <td class="filename">
310 <td class="filename">
311 <a href="/file/tip/foo">
311 <a href="/file/tip/foo">
312 <img src="/static/coal-file.png" alt="file"/> foo
312 <img src="/static/coal-file.png" alt="file"/> foo
313 </a>
313 </a>
314 </td>
314 </td>
315 <td class="size">4</td>
315 <td class="size">4</td>
316 <td class="permissions">-rw-r--r--</td>
316 <td class="permissions">-rw-r--r--</td>
317 </tr>
317 </tr>
318 </tbody>
318 </tbody>
319 </table>
319 </table>
320 </div>
320 </div>
321 </div>
321 </div>
322
322
323
323
324 </body>
324 </body>
325 </html>
325 </html>
326
326
327
327
328 stop and restart
328 stop and restart
329
329
330 $ killdaemons.py
330 $ killdaemons.py
331 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log
331 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log
332 $ cat hg.pid >> $DAEMON_PIDS
332 $ cat hg.pid >> $DAEMON_PIDS
333
333
334 Test the access/error files are opened in append mode
334 Test the access/error files are opened in append mode
335
335
336 $ $PYTHON -c "print len(file('access.log').readlines()), 'log lines written'"
336 $ $PYTHON -c "print len(file('access.log').readlines()), 'log lines written'"
337 14 log lines written
337 14 log lines written
338
338
339 static file
339 static file
340
340
341 $ get-with-headers.py --twice localhost:$HGPORT 'static/style-gitweb.css' - date etag server
341 $ get-with-headers.py --twice localhost:$HGPORT 'static/style-gitweb.css' - date etag server
342 200 Script output follows
342 200 Script output follows
343 content-length: 8463
343 content-length: 8985
344 content-type: text/css
344 content-type: text/css
345
345
346 body { font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px; margin:10px; background: white; color: black; }
346 body { font-family: sans-serif; font-size: 12px; border:solid #d9d8d1; border-width:1px; margin:10px; background: white; color: black; }
347 a { color:#0000cc; }
347 a { color:#0000cc; }
348 a:hover, a:visited, a:active { color:#880000; }
348 a:hover, a:visited, a:active { color:#880000; }
349 div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
349 div.page_header { height:25px; padding:8px; font-size:18px; font-weight:bold; background-color:#d9d8d1; }
350 div.page_header a:visited { color:#0000cc; }
350 div.page_header a:visited { color:#0000cc; }
351 div.page_header a:hover { color:#880000; }
351 div.page_header a:hover { color:#880000; }
352 div.page_nav {
352 div.page_nav {
353 padding:8px;
353 padding:8px;
354 display: flex;
354 display: flex;
355 justify-content: space-between;
355 justify-content: space-between;
356 align-items: center;
356 align-items: center;
357 }
357 }
358 div.page_nav a:visited { color:#0000cc; }
358 div.page_nav a:visited { color:#0000cc; }
359 div.extra_nav {
359 div.extra_nav {
360 padding: 8px;
360 padding: 8px;
361 }
361 }
362 div.extra_nav a:visited {
362 div.extra_nav a:visited {
363 color: #0000cc;
363 color: #0000cc;
364 }
364 }
365 div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
365 div.page_path { padding:8px; border:solid #d9d8d1; border-width:0px 0px 1px}
366 div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
366 div.page_footer { padding:4px 8px; background-color: #d9d8d1; }
367 div.page_footer_text { float:left; color:#555555; font-style:italic; }
367 div.page_footer_text { float:left; color:#555555; font-style:italic; }
368 div.page_body { padding:8px; }
368 div.page_body { padding:8px; }
369 div.title, a.title {
369 div.title, a.title {
370 display:block; padding:6px 8px;
370 display:block; padding:6px 8px;
371 font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
371 font-weight:bold; background-color:#edece6; text-decoration:none; color:#000000;
372 }
372 }
373 a.title:hover { background-color: #d9d8d1; }
373 a.title:hover { background-color: #d9d8d1; }
374 div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
374 div.title_text { padding:6px 0px; border: solid #d9d8d1; border-width:0px 0px 1px; }
375 div.log_body { padding:8px 8px 8px 150px; }
375 div.log_body { padding:8px 8px 8px 150px; }
376 .age { white-space:nowrap; }
376 .age { white-space:nowrap; }
377 span.age { position:relative; float:left; width:142px; font-style:italic; }
377 span.age { position:relative; float:left; width:142px; font-style:italic; }
378 div.log_link {
378 div.log_link {
379 padding:0px 8px;
379 padding:0px 8px;
380 font-size:10px; font-family:sans-serif; font-style:normal;
380 font-size:10px; font-family:sans-serif; font-style:normal;
381 position:relative; float:left; width:136px;
381 position:relative; float:left; width:136px;
382 }
382 }
383 div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
383 div.list_head { padding:6px 8px 4px; border:solid #d9d8d1; border-width:1px 0px 0px; font-style:italic; }
384 a.list { text-decoration:none; color:#000000; }
384 a.list { text-decoration:none; color:#000000; }
385 a.list:hover { text-decoration:underline; color:#880000; }
385 a.list:hover { text-decoration:underline; color:#880000; }
386 table { padding:8px 4px; }
386 table { padding:8px 4px; }
387 th { padding:2px 5px; font-size:12px; text-align:left; }
387 th { padding:2px 5px; font-size:12px; text-align:left; }
388 .parity0 { background-color:#ffffff; }
388 .parity0 { background-color:#ffffff; }
389 tr.dark, .parity1, pre.sourcelines.stripes > :nth-child(4n+4) { background-color:#f6f6f0; }
389 tr.dark, .parity1, pre.sourcelines.stripes > :nth-child(4n+4) { background-color:#f6f6f0; }
390 tr.light:hover, .parity0:hover, tr.dark:hover, .parity1:hover,
390 tr.light:hover, .parity0:hover, tr.dark:hover, .parity1:hover,
391 pre.sourcelines.stripes > :nth-child(4n+2):hover,
391 pre.sourcelines.stripes > :nth-child(4n+2):hover,
392 pre.sourcelines.stripes > :nth-child(4n+4):hover,
392 pre.sourcelines.stripes > :nth-child(4n+4):hover,
393 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
393 pre.sourcelines.stripes > :nth-child(4n+1):hover + :nth-child(4n+2),
394 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color:#edece6; }
394 pre.sourcelines.stripes > :nth-child(4n+3):hover + :nth-child(4n+4) { background-color:#edece6; }
395 td { padding:2px 5px; font-size:12px; vertical-align:top; }
395 td { padding:2px 5px; font-size:12px; vertical-align:top; }
396 td.closed { background-color: #99f; }
396 td.closed { background-color: #99f; }
397 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
397 td.link { padding:2px 5px; font-family:sans-serif; font-size:10px; }
398 td.indexlinks { white-space: nowrap; }
398 td.indexlinks { white-space: nowrap; }
399 td.indexlinks a {
399 td.indexlinks a {
400 padding: 2px 5px; line-height: 10px;
400 padding: 2px 5px; line-height: 10px;
401 border: 1px solid;
401 border: 1px solid;
402 color: #ffffff; background-color: #7777bb;
402 color: #ffffff; background-color: #7777bb;
403 border-color: #aaaadd #333366 #333366 #aaaadd;
403 border-color: #aaaadd #333366 #333366 #aaaadd;
404 font-weight: bold; text-align: center; text-decoration: none;
404 font-weight: bold; text-align: center; text-decoration: none;
405 font-size: 10px;
405 font-size: 10px;
406 }
406 }
407 td.indexlinks a:hover { background-color: #6666aa; }
407 td.indexlinks a:hover { background-color: #6666aa; }
408 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
408 div.pre { font-family:monospace; font-size:12px; white-space:pre; }
409 div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
409 div.diff_info { font-family:monospace; color:#000099; background-color:#edece6; font-style:italic; }
410 div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
410 div.index_include { border:solid #d9d8d1; border-width:0px 0px 1px; padding:12px 8px; }
411
411
412 .search {
412 .search {
413 margin-right: 8px;
413 margin-right: 8px;
414 }
414 }
415
415
416 div#hint {
416 div#hint {
417 position: absolute;
417 position: absolute;
418 display: none;
418 display: none;
419 width: 250px;
419 width: 250px;
420 padding: 5px;
420 padding: 5px;
421 background: #ffc;
421 background: #ffc;
422 border: 1px solid yellow;
422 border: 1px solid yellow;
423 border-radius: 5px;
423 border-radius: 5px;
424 }
424 }
425
425
426 #searchform:hover div#hint { display: block; }
426 #searchform:hover div#hint { display: block; }
427
427
428 tr.thisrev a { color:#999999; text-decoration: none; }
428 tr.thisrev a { color:#999999; text-decoration: none; }
429 tr.thisrev pre { color:#009900; }
429 tr.thisrev pre { color:#009900; }
430 td.annotate {
430 td.annotate {
431 white-space: nowrap;
431 white-space: nowrap;
432 }
432 }
433 div.annotate-info {
433 div.annotate-info {
434 z-index: 5;
434 display: none;
435 display: none;
435 position: absolute;
436 position: absolute;
436 background-color: #FFFFFF;
437 background-color: #FFFFFF;
437 border: 1px solid #d9d8d1;
438 border: 1px solid #d9d8d1;
438 text-align: left;
439 text-align: left;
439 color: #000000;
440 color: #000000;
440 padding: 5px;
441 padding: 5px;
441 }
442 }
442 div.annotate-info a { color: #0000FF; text-decoration: underline; }
443 div.annotate-info a { color: #0000FF; text-decoration: underline; }
443 td.annotate:hover div.annotate-info { display: inline; }
444 td.annotate:hover div.annotate-info { display: inline; }
444 .linenr { color:#999999; text-decoration:none }
445 .linenr { color:#999999; text-decoration:none }
445 div.rss_logo { float: right; white-space: nowrap; }
446 div.rss_logo { float: right; white-space: nowrap; }
446 div.rss_logo a {
447 div.rss_logo a {
447 padding:3px 6px; line-height:10px;
448 padding:3px 6px; line-height:10px;
448 border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
449 border:1px solid; border-color:#fcc7a5 #7d3302 #3e1a01 #ff954e;
449 color:#ffffff; background-color:#ff6600;
450 color:#ffffff; background-color:#ff6600;
450 font-weight:bold; font-family:sans-serif; font-size:10px;
451 font-weight:bold; font-family:sans-serif; font-size:10px;
451 text-align:center; text-decoration:none;
452 text-align:center; text-decoration:none;
452 }
453 }
453 div.rss_logo a:hover { background-color:#ee5500; }
454 div.rss_logo a:hover { background-color:#ee5500; }
454 pre { margin: 0; }
455 pre { margin: 0; }
455 span.logtags span {
456 span.logtags span {
456 padding: 0px 4px;
457 padding: 0px 4px;
457 font-size: 10px;
458 font-size: 10px;
458 font-weight: normal;
459 font-weight: normal;
459 border: 1px solid;
460 border: 1px solid;
460 background-color: #ffaaff;
461 background-color: #ffaaff;
461 border-color: #ffccff #ff00ee #ff00ee #ffccff;
462 border-color: #ffccff #ff00ee #ff00ee #ffccff;
462 }
463 }
463 span.logtags span.tagtag {
464 span.logtags span.tagtag {
464 background-color: #ffffaa;
465 background-color: #ffffaa;
465 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
466 border-color: #ffffcc #ffee00 #ffee00 #ffffcc;
466 }
467 }
467 span.logtags span.branchtag {
468 span.logtags span.branchtag {
468 background-color: #aaffaa;
469 background-color: #aaffaa;
469 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
470 border-color: #ccffcc #00cc33 #00cc33 #ccffcc;
470 }
471 }
471 span.logtags span.inbranchtag {
472 span.logtags span.inbranchtag {
472 background-color: #d5dde6;
473 background-color: #d5dde6;
473 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
474 border-color: #e3ecf4 #9398f4 #9398f4 #e3ecf4;
474 }
475 }
475 span.logtags span.bookmarktag {
476 span.logtags span.bookmarktag {
476 background-color: #afdffa;
477 background-color: #afdffa;
477 border-color: #ccecff #46ace6 #46ace6 #ccecff;
478 border-color: #ccecff #46ace6 #46ace6 #ccecff;
478 }
479 }
479 span.difflineplus { color:#008800; }
480 span.difflineplus { color:#008800; }
480 span.difflineminus { color:#cc0000; }
481 span.difflineminus { color:#cc0000; }
481 span.difflineat { color:#990099; }
482 span.difflineat { color:#990099; }
482 div.diffblocks { counter-reset: lineno; }
483 div.diffblocks { counter-reset: lineno; }
483 div.diffblock { counter-increment: lineno; }
484 div.diffblock { counter-increment: lineno; }
484 pre.sourcelines { position: relative; counter-reset: lineno; }
485 pre.sourcelines { position: relative; counter-reset: lineno; }
485 pre.sourcelines > span {
486 pre.sourcelines > span {
486 display: inline-block;
487 display: inline-block;
487 box-sizing: border-box;
488 box-sizing: border-box;
488 width: 100%;
489 width: 100%;
489 padding: 0 0 0 5em;
490 padding: 0 0 0 5em;
490 counter-increment: lineno;
491 counter-increment: lineno;
491 vertical-align: top;
492 vertical-align: top;
492 }
493 }
493 pre.sourcelines > span:before {
494 pre.sourcelines > span:before {
494 -moz-user-select: -moz-none;
495 -moz-user-select: -moz-none;
495 -khtml-user-select: none;
496 -khtml-user-select: none;
496 -webkit-user-select: none;
497 -webkit-user-select: none;
497 -ms-user-select: none;
498 -ms-user-select: none;
498 user-select: none;
499 user-select: none;
499 display: inline-block;
500 display: inline-block;
500 margin-left: -5em;
501 margin-left: -6em;
501 width: 4em;
502 width: 4em;
502 color: #999;
503 color: #999;
503 text-align: right;
504 text-align: right;
504 content: counters(lineno,".");
505 content: counters(lineno,".");
505 float: left;
506 float: left;
506 }
507 }
507 pre.sourcelines > a {
508 pre.sourcelines > a {
508 display: inline-block;
509 display: inline-block;
509 position: absolute;
510 position: absolute;
510 left: 0px;
511 left: 0px;
511 width: 4em;
512 width: 4em;
512 height: 1em;
513 height: 1em;
513 }
514 }
514 tr:target td,
515 tr:target td,
515 pre.sourcelines > span:target,
516 pre.sourcelines > span:target,
516 pre.sourcelines.stripes > span:target {
517 pre.sourcelines.stripes > span:target {
517 background-color: #bfdfff;
518 background-color: #bfdfff;
518 }
519 }
519
520
520 .description {
521 .description {
521 font-family: monospace;
522 font-family: monospace;
522 }
523 }
523
524
524 /* Followlines */
525 /* Followlines */
525 div.page_body table tbody.sourcelines > tr.followlines-select:hover,
526 div.page_body pre.sourcelines > span.followlines-select:hover {
527 cursor: cell;
528 }
529
530 tbody.sourcelines > tr.followlines-selected,
526 tbody.sourcelines > tr.followlines-selected,
531 pre.sourcelines > span.followlines-selected {
527 pre.sourcelines > span.followlines-selected {
532 background-color: #99C7E9 !important;
528 background-color: #99C7E9 !important;
533 }
529 }
534
530
535 div#followlines {
531 div#followlines {
536 background-color: #B7B7B7;
532 background-color: #B7B7B7;
537 border: 1px solid #CCC;
533 border: 1px solid #CCC;
538 border-radius: 5px;
534 border-radius: 5px;
539 padding: 4px;
535 padding: 4px;
540 position: fixed;
536 position: fixed;
541 }
537 }
542
538
543 div.followlines-cancel {
539 div.followlines-cancel {
544 text-align: right;
540 text-align: right;
545 }
541 }
546
542
547 div.followlines-cancel > button {
543 div.followlines-cancel > button {
548 line-height: 80%;
544 line-height: 80%;
549 padding: 0;
545 padding: 0;
550 border: 0;
546 border: 0;
551 border-radius: 2px;
547 border-radius: 2px;
552 background-color: inherit;
548 background-color: inherit;
553 font-weight: bold;
549 font-weight: bold;
554 }
550 }
555
551
556 div.followlines-cancel > button:hover {
552 div.followlines-cancel > button:hover {
557 color: #FFFFFF;
553 color: #FFFFFF;
558 background-color: #CF1F1F;
554 background-color: #CF1F1F;
559 }
555 }
560
556
561 div.followlines-link {
557 div.followlines-link {
562 margin: 2px;
558 margin: 2px;
563 margin-top: 4px;
559 margin-top: 4px;
564 font-family: sans-serif;
560 font-family: sans-serif;
565 }
561 }
566
562
567 div#followlines-tooltip {
563 .btn-followlines {
568 display: none;
564 display: none;
569 position: fixed;
565 cursor: pointer;
570 background-color: #ffc;
566 box-sizing: content-box;
571 border: 1px solid #999;
567 font-size: 11px;
572 padding: 2px;
568 width: 13px;
569 height: 13px;
570 border-radius: 3px;
571 margin: 0px;
572 margin-top: -2px;
573 padding: 0px;
574 background-color: #E5FDE5;
575 border: 1px solid #9BC19B;
576 font-family: monospace;
577 text-align: center;
578 line-height: 5px;
579 }
580
581 tr .btn-followlines {
582 position: absolute;
573 }
583 }
574
584
575 .sourcelines:hover > div#followlines-tooltip {
585 span .btn-followlines {
586 float: left;
587 }
588
589 span.followlines-select .btn-followlines {
590 margin-left: -1.6em;
591 }
592
593 .btn-followlines:hover {
594 transform: scale(1.1, 1.1);
595 }
596
597 .btn-followlines .followlines-plus {
598 color: green;
599 }
600
601 .btn-followlines .followlines-minus {
602 color: red;
603 }
604
605 .btn-followlines-end {
606 background-color: #ffdcdc;
607 }
608
609 .sourcelines tr:hover .btn-followlines,
610 .sourcelines span.followlines-select:hover > .btn-followlines {
576 display: inline;
611 display: inline;
577 }
612 }
578
613
579 .sourcelines:hover > div#followlines-tooltip.hidden {
614 .btn-followlines-hidden,
615 .sourcelines tr:hover .btn-followlines-hidden {
580 display: none;
616 display: none;
581 }
617 }
618
582 /* Graph */
619 /* Graph */
583 div#wrapper {
620 div#wrapper {
584 position: relative;
621 position: relative;
585 margin: 0;
622 margin: 0;
586 padding: 0;
623 padding: 0;
587 margin-top: 3px;
624 margin-top: 3px;
588 }
625 }
589
626
590 canvas {
627 canvas {
591 position: absolute;
628 position: absolute;
592 z-index: 5;
629 z-index: 5;
593 top: -0.9em;
630 top: -0.9em;
594 margin: 0;
631 margin: 0;
595 }
632 }
596
633
597 ul#nodebgs {
634 ul#nodebgs {
598 list-style: none inside none;
635 list-style: none inside none;
599 padding: 0;
636 padding: 0;
600 margin: 0;
637 margin: 0;
601 top: -0.7em;
638 top: -0.7em;
602 }
639 }
603
640
604 ul#graphnodes li, ul#nodebgs li {
641 ul#graphnodes li, ul#nodebgs li {
605 height: 39px;
642 height: 39px;
606 }
643 }
607
644
608 ul#graphnodes {
645 ul#graphnodes {
609 position: absolute;
646 position: absolute;
610 z-index: 10;
647 z-index: 10;
611 top: -0.8em;
648 top: -0.8em;
612 list-style: none inside none;
649 list-style: none inside none;
613 padding: 0;
650 padding: 0;
614 }
651 }
615
652
616 ul#graphnodes li .info {
653 ul#graphnodes li .info {
617 display: block;
654 display: block;
618 font-size: 100%;
655 font-size: 100%;
619 position: relative;
656 position: relative;
620 top: -3px;
657 top: -3px;
621 font-style: italic;
658 font-style: italic;
622 }
659 }
623
660
624 /* Comparison */
661 /* Comparison */
625 .legend {
662 .legend {
626 padding: 1.5% 0 1.5% 0;
663 padding: 1.5% 0 1.5% 0;
627 }
664 }
628
665
629 .legendinfo {
666 .legendinfo {
630 border: 1px solid #d9d8d1;
667 border: 1px solid #d9d8d1;
631 font-size: 80%;
668 font-size: 80%;
632 text-align: center;
669 text-align: center;
633 padding: 0.5%;
670 padding: 0.5%;
634 }
671 }
635
672
636 .equal {
673 .equal {
637 background-color: #ffffff;
674 background-color: #ffffff;
638 }
675 }
639
676
640 .delete {
677 .delete {
641 background-color: #faa;
678 background-color: #faa;
642 color: #333;
679 color: #333;
643 }
680 }
644
681
645 .insert {
682 .insert {
646 background-color: #ffa;
683 background-color: #ffa;
647 }
684 }
648
685
649 .replace {
686 .replace {
650 background-color: #e8e8e8;
687 background-color: #e8e8e8;
651 }
688 }
652
689
653 .comparison {
690 .comparison {
654 overflow-x: auto;
691 overflow-x: auto;
655 }
692 }
656
693
657 .header th {
694 .header th {
658 text-align: center;
695 text-align: center;
659 }
696 }
660
697
661 .block {
698 .block {
662 border-top: 1px solid #d9d8d1;
699 border-top: 1px solid #d9d8d1;
663 }
700 }
664
701
665 .scroll-loading {
702 .scroll-loading {
666 -webkit-animation: change_color 1s linear 0s infinite alternate;
703 -webkit-animation: change_color 1s linear 0s infinite alternate;
667 -moz-animation: change_color 1s linear 0s infinite alternate;
704 -moz-animation: change_color 1s linear 0s infinite alternate;
668 -o-animation: change_color 1s linear 0s infinite alternate;
705 -o-animation: change_color 1s linear 0s infinite alternate;
669 animation: change_color 1s linear 0s infinite alternate;
706 animation: change_color 1s linear 0s infinite alternate;
670 }
707 }
671
708
672 @-webkit-keyframes change_color {
709 @-webkit-keyframes change_color {
673 from { background-color: #A0CEFF; } to { }
710 from { background-color: #A0CEFF; } to { }
674 }
711 }
675 @-moz-keyframes change_color {
712 @-moz-keyframes change_color {
676 from { background-color: #A0CEFF; } to { }
713 from { background-color: #A0CEFF; } to { }
677 }
714 }
678 @-o-keyframes change_color {
715 @-o-keyframes change_color {
679 from { background-color: #A0CEFF; } to { }
716 from { background-color: #A0CEFF; } to { }
680 }
717 }
681 @keyframes change_color {
718 @keyframes change_color {
682 from { background-color: #A0CEFF; } to { }
719 from { background-color: #A0CEFF; } to { }
683 }
720 }
684
721
685 .scroll-loading-error {
722 .scroll-loading-error {
686 background-color: #FFCCCC !important;
723 background-color: #FFCCCC !important;
687 }
724 }
688
725
689 #doc {
726 #doc {
690 margin: 0 8px;
727 margin: 0 8px;
691 }
728 }
692 304 Not Modified
729 304 Not Modified
693
730
694
731
695 phase changes are refreshed (issue4061)
732 phase changes are refreshed (issue4061)
696
733
697 $ echo bar >> foo
734 $ echo bar >> foo
698 $ hg ci -msecret --secret
735 $ hg ci -msecret --secret
699 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
736 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
700 200 Script output follows
737 200 Script output follows
701
738
702
739
703 # HG changelog
740 # HG changelog
704 # Node ID 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
741 # Node ID 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
705
742
706 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
743 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
707 revision: 0
744 revision: 0
708 user: test
745 user: test
709 date: Thu, 01 Jan 1970 00:00:00 +0000
746 date: Thu, 01 Jan 1970 00:00:00 +0000
710 summary: base
747 summary: base
711 branch: default
748 branch: default
712 tag: tip
749 tag: tip
713 bookmark: @
750 bookmark: @
714 bookmark: a b c
751 bookmark: a b c
715 bookmark: d/e/f
752 bookmark: d/e/f
716
753
717
754
718 $ hg phase --draft tip
755 $ hg phase --draft tip
719 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
756 $ get-with-headers.py localhost:$HGPORT 'log?style=raw'
720 200 Script output follows
757 200 Script output follows
721
758
722
759
723 # HG changelog
760 # HG changelog
724 # Node ID a084749e708a9c4c0a5b652a2a446322ce290e04
761 # Node ID a084749e708a9c4c0a5b652a2a446322ce290e04
725
762
726 changeset: a084749e708a9c4c0a5b652a2a446322ce290e04
763 changeset: a084749e708a9c4c0a5b652a2a446322ce290e04
727 revision: 1
764 revision: 1
728 user: test
765 user: test
729 date: Thu, 01 Jan 1970 00:00:00 +0000
766 date: Thu, 01 Jan 1970 00:00:00 +0000
730 summary: secret
767 summary: secret
731 branch: default
768 branch: default
732 tag: tip
769 tag: tip
733
770
734 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
771 changeset: 2ef0ac749a14e4f57a5a822464a0902c6f7f448f
735 revision: 0
772 revision: 0
736 user: test
773 user: test
737 date: Thu, 01 Jan 1970 00:00:00 +0000
774 date: Thu, 01 Jan 1970 00:00:00 +0000
738 summary: base
775 summary: base
739 bookmark: @
776 bookmark: @
740 bookmark: a b c
777 bookmark: a b c
741 bookmark: d/e/f
778 bookmark: d/e/f
742
779
743
780
744
781
745 access bookmarks
782 access bookmarks
746
783
747 $ get-with-headers.py localhost:$HGPORT 'rev/@?style=paper' | egrep '^200|changeset 0:'
784 $ get-with-headers.py localhost:$HGPORT 'rev/@?style=paper' | egrep '^200|changeset 0:'
748 200 Script output follows
785 200 Script output follows
749 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
786 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
750
787
751 $ get-with-headers.py localhost:$HGPORT 'rev/%40?style=paper' | egrep '^200|changeset 0:'
788 $ get-with-headers.py localhost:$HGPORT 'rev/%40?style=paper' | egrep '^200|changeset 0:'
752 200 Script output follows
789 200 Script output follows
753 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
790 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
754
791
755 $ get-with-headers.py localhost:$HGPORT 'rev/a%20b%20c?style=paper' | egrep '^200|changeset 0:'
792 $ get-with-headers.py localhost:$HGPORT 'rev/a%20b%20c?style=paper' | egrep '^200|changeset 0:'
756 200 Script output follows
793 200 Script output follows
757 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
794 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
758
795
759 $ get-with-headers.py localhost:$HGPORT 'rev/d%252Fe%252Ff?style=paper' | egrep '^200|changeset 0:'
796 $ get-with-headers.py localhost:$HGPORT 'rev/d%252Fe%252Ff?style=paper' | egrep '^200|changeset 0:'
760 200 Script output follows
797 200 Script output follows
761 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
798 changeset 0:<a href="/rev/2ef0ac749a14?style=paper">2ef0ac749a14</a>
762
799
763 no style can be loaded from directories other than the specified paths
800 no style can be loaded from directories other than the specified paths
764
801
765 $ mkdir -p x/templates/fallback
802 $ mkdir -p x/templates/fallback
766 $ cat <<EOF > x/templates/fallback/map
803 $ cat <<EOF > x/templates/fallback/map
767 > default = 'shortlog'
804 > default = 'shortlog'
768 > shortlog = 'fall back to default\n'
805 > shortlog = 'fall back to default\n'
769 > mimetype = 'text/plain'
806 > mimetype = 'text/plain'
770 > EOF
807 > EOF
771 $ cat <<EOF > x/map
808 $ cat <<EOF > x/map
772 > default = 'shortlog'
809 > default = 'shortlog'
773 > shortlog = 'access to outside of templates directory\n'
810 > shortlog = 'access to outside of templates directory\n'
774 > mimetype = 'text/plain'
811 > mimetype = 'text/plain'
775 > EOF
812 > EOF
776
813
777 $ killdaemons.py
814 $ killdaemons.py
778 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log \
815 $ hg serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log \
779 > --config web.style=fallback --config web.templates=x/templates
816 > --config web.style=fallback --config web.templates=x/templates
780 $ cat hg.pid >> $DAEMON_PIDS
817 $ cat hg.pid >> $DAEMON_PIDS
781
818
782 $ get-with-headers.py localhost:$HGPORT "?style=`pwd`/x"
819 $ get-with-headers.py localhost:$HGPORT "?style=`pwd`/x"
783 200 Script output follows
820 200 Script output follows
784
821
785 fall back to default
822 fall back to default
786
823
787 $ get-with-headers.py localhost:$HGPORT '?style=..'
824 $ get-with-headers.py localhost:$HGPORT '?style=..'
788 200 Script output follows
825 200 Script output follows
789
826
790 fall back to default
827 fall back to default
791
828
792 $ get-with-headers.py localhost:$HGPORT '?style=./..'
829 $ get-with-headers.py localhost:$HGPORT '?style=./..'
793 200 Script output follows
830 200 Script output follows
794
831
795 fall back to default
832 fall back to default
796
833
797 $ get-with-headers.py localhost:$HGPORT '?style=.../.../'
834 $ get-with-headers.py localhost:$HGPORT '?style=.../.../'
798 200 Script output follows
835 200 Script output follows
799
836
800 fall back to default
837 fall back to default
801
838
802 errors
839 errors
803
840
804 $ cat errors.log
841 $ cat errors.log
805
842
806 Uncaught exceptions result in a logged error and canned HTTP response
843 Uncaught exceptions result in a logged error and canned HTTP response
807
844
808 $ killdaemons.py
845 $ killdaemons.py
809 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
846 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
810 $ cat hg.pid >> $DAEMON_PIDS
847 $ cat hg.pid >> $DAEMON_PIDS
811
848
812 $ get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type
849 $ get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type
813 500 Internal Server Error
850 500 Internal Server Error
814 transfer-encoding: chunked
851 transfer-encoding: chunked
815
852
816 Internal Server Error (no-eol)
853 Internal Server Error (no-eol)
817 [1]
854 [1]
818
855
819 $ killdaemons.py
856 $ killdaemons.py
820 $ head -1 errors.log
857 $ head -1 errors.log
821 .* Exception happened during processing request '/raiseerror': (re)
858 .* Exception happened during processing request '/raiseerror': (re)
822
859
823 Uncaught exception after partial content sent
860 Uncaught exception after partial content sent
824
861
825 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
862 $ hg serve --config extensions.hgweberror=$TESTDIR/hgweberror.py -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
826 $ cat hg.pid >> $DAEMON_PIDS
863 $ cat hg.pid >> $DAEMON_PIDS
827 $ get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type
864 $ get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type
828 200 Script output follows
865 200 Script output follows
829 transfer-encoding: chunked
866 transfer-encoding: chunked
830 content-type: text/plain
867 content-type: text/plain
831
868
832 partial content
869 partial content
833 Internal Server Error (no-eol)
870 Internal Server Error (no-eol)
834
871
835 $ killdaemons.py
872 $ killdaemons.py
836 $ cd ..
873 $ cd ..
@@ -1,998 +1,998 b''
1 #require pygments serve
1 #require pygments serve
2
2
3 $ cat <<EOF >> $HGRCPATH
3 $ cat <<EOF >> $HGRCPATH
4 > [extensions]
4 > [extensions]
5 > highlight =
5 > highlight =
6 > [web]
6 > [web]
7 > pygments_style = friendly
7 > pygments_style = friendly
8 > highlightfiles = **.py and size('<100KB')
8 > highlightfiles = **.py and size('<100KB')
9 > EOF
9 > EOF
10 $ hg init test
10 $ hg init test
11 $ cd test
11 $ cd test
12
12
13 $ filterhtml () {
13 $ filterhtml () {
14 > sed -e "s/class=\"k\"/class=\"kn\"/g" \
14 > sed -e "s/class=\"k\"/class=\"kn\"/g" \
15 > -e "s/class=\"mf\"/class=\"mi\"/g" \
15 > -e "s/class=\"mf\"/class=\"mi\"/g" \
16 > -e "s/class=\"vm\"/class=\"n\"/g" \
16 > -e "s/class=\"vm\"/class=\"n\"/g" \
17 > -e "s/class=\"\([cs]\)[h12]\"/class=\"\1\"/g"
17 > -e "s/class=\"\([cs]\)[h12]\"/class=\"\1\"/g"
18 > }
18 > }
19
19
20 create random Python file to exercise Pygments
20 create random Python file to exercise Pygments
21
21
22 $ cat <<EOF > primes.py
22 $ cat <<EOF > primes.py
23 > """Fun with generators. Corresponding Haskell implementation:
23 > """Fun with generators. Corresponding Haskell implementation:
24 >
24 >
25 > primes = 2 : sieve [3, 5..]
25 > primes = 2 : sieve [3, 5..]
26 > where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]
26 > where sieve (p:ns) = p : sieve [n | n <- ns, mod n p /= 0]
27 > """
27 > """
28 >
28 >
29 > from itertools import dropwhile, ifilter, islice, count, chain
29 > from itertools import dropwhile, ifilter, islice, count, chain
30 >
30 >
31 > def primes():
31 > def primes():
32 > """Generate all primes."""
32 > """Generate all primes."""
33 > def sieve(ns):
33 > def sieve(ns):
34 > p = ns.next()
34 > p = ns.next()
35 > # It is important to yield *here* in order to stop the
35 > # It is important to yield *here* in order to stop the
36 > # infinite recursion.
36 > # infinite recursion.
37 > yield p
37 > yield p
38 > ns = ifilter(lambda n: n % p != 0, ns)
38 > ns = ifilter(lambda n: n % p != 0, ns)
39 > for n in sieve(ns):
39 > for n in sieve(ns):
40 > yield n
40 > yield n
41 >
41 >
42 > odds = ifilter(lambda i: i % 2 == 1, count())
42 > odds = ifilter(lambda i: i % 2 == 1, count())
43 > return chain([2], sieve(dropwhile(lambda n: n < 3, odds)))
43 > return chain([2], sieve(dropwhile(lambda n: n < 3, odds)))
44 >
44 >
45 > if __name__ == "__main__":
45 > if __name__ == "__main__":
46 > import sys
46 > import sys
47 > try:
47 > try:
48 > n = int(sys.argv[1])
48 > n = int(sys.argv[1])
49 > except (ValueError, IndexError):
49 > except (ValueError, IndexError):
50 > n = 10
50 > n = 10
51 > p = primes()
51 > p = primes()
52 > print "The first %d primes: %s" % (n, list(islice(p, n)))
52 > print "The first %d primes: %s" % (n, list(islice(p, n)))
53 > EOF
53 > EOF
54 $ echo >> primes.py # to test html markup with an empty line just before EOF
54 $ echo >> primes.py # to test html markup with an empty line just before EOF
55 $ hg ci -Ama
55 $ hg ci -Ama
56 adding primes.py
56 adding primes.py
57
57
58 hg serve
58 hg serve
59
59
60 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
60 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
61 $ cat hg.pid >> $DAEMON_PIDS
61 $ cat hg.pid >> $DAEMON_PIDS
62
62
63 hgweb filerevision, html
63 hgweb filerevision, html
64
64
65 $ (get-with-headers.py localhost:$HGPORT 'file/tip/primes.py') | filterhtml
65 $ (get-with-headers.py localhost:$HGPORT 'file/tip/primes.py') | filterhtml
66 200 Script output follows
66 200 Script output follows
67
67
68 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
68 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
69 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
69 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
70 <head>
70 <head>
71 <link rel="icon" href="/static/hgicon.png" type="image/png" />
71 <link rel="icon" href="/static/hgicon.png" type="image/png" />
72 <meta name="robots" content="index, nofollow" />
72 <meta name="robots" content="index, nofollow" />
73 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
73 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
74 <script type="text/javascript" src="/static/mercurial.js"></script>
74 <script type="text/javascript" src="/static/mercurial.js"></script>
75
75
76 <link rel="stylesheet" href="/highlightcss" type="text/css" />
76 <link rel="stylesheet" href="/highlightcss" type="text/css" />
77 <title>test: 1af356141006 primes.py</title>
77 <title>test: 1af356141006 primes.py</title>
78 </head>
78 </head>
79 <body>
79 <body>
80
80
81 <div class="container">
81 <div class="container">
82 <div class="menu">
82 <div class="menu">
83 <div class="logo">
83 <div class="logo">
84 <a href="https://mercurial-scm.org/">
84 <a href="https://mercurial-scm.org/">
85 <img src="/static/hglogo.png" alt="mercurial" /></a>
85 <img src="/static/hglogo.png" alt="mercurial" /></a>
86 </div>
86 </div>
87 <ul>
87 <ul>
88 <li><a href="/shortlog/tip">log</a></li>
88 <li><a href="/shortlog/tip">log</a></li>
89 <li><a href="/graph/tip">graph</a></li>
89 <li><a href="/graph/tip">graph</a></li>
90 <li><a href="/tags">tags</a></li>
90 <li><a href="/tags">tags</a></li>
91 <li><a href="/bookmarks">bookmarks</a></li>
91 <li><a href="/bookmarks">bookmarks</a></li>
92 <li><a href="/branches">branches</a></li>
92 <li><a href="/branches">branches</a></li>
93 </ul>
93 </ul>
94 <ul>
94 <ul>
95 <li><a href="/rev/tip">changeset</a></li>
95 <li><a href="/rev/tip">changeset</a></li>
96 <li><a href="/file/tip/">browse</a></li>
96 <li><a href="/file/tip/">browse</a></li>
97 </ul>
97 </ul>
98 <ul>
98 <ul>
99 <li class="active">file</li>
99 <li class="active">file</li>
100 <li><a href="/file/tip/primes.py">latest</a></li>
100 <li><a href="/file/tip/primes.py">latest</a></li>
101 <li><a href="/diff/tip/primes.py">diff</a></li>
101 <li><a href="/diff/tip/primes.py">diff</a></li>
102 <li><a href="/comparison/tip/primes.py">comparison</a></li>
102 <li><a href="/comparison/tip/primes.py">comparison</a></li>
103 <li><a href="/annotate/tip/primes.py">annotate</a></li>
103 <li><a href="/annotate/tip/primes.py">annotate</a></li>
104 <li><a href="/log/tip/primes.py">file log</a></li>
104 <li><a href="/log/tip/primes.py">file log</a></li>
105 <li><a href="/raw-file/tip/primes.py">raw</a></li>
105 <li><a href="/raw-file/tip/primes.py">raw</a></li>
106 </ul>
106 </ul>
107 <ul>
107 <ul>
108 <li><a href="/help">help</a></li>
108 <li><a href="/help">help</a></li>
109 </ul>
109 </ul>
110 </div>
110 </div>
111
111
112 <div class="main">
112 <div class="main">
113 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
113 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
114 <h3>
114 <h3>
115 view primes.py @ 0:<a href="/rev/1af356141006">1af356141006</a>
115 view primes.py @ 0:<a href="/rev/1af356141006">1af356141006</a>
116 <span class="tag">tip</span>
116 <span class="tag">tip</span>
117 </h3>
117 </h3>
118
118
119
119
120 <form class="search" action="/log">
120 <form class="search" action="/log">
121
121
122 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
122 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
123 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
123 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
124 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
124 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
125 </form>
125 </form>
126
126
127 <div class="description">a</div>
127 <div class="description">a</div>
128
128
129 <table id="changesetEntry">
129 <table id="changesetEntry">
130 <tr>
130 <tr>
131 <th class="author">author</th>
131 <th class="author">author</th>
132 <td class="author">&#116;&#101;&#115;&#116;</td>
132 <td class="author">&#116;&#101;&#115;&#116;</td>
133 </tr>
133 </tr>
134 <tr>
134 <tr>
135 <th class="date">date</th>
135 <th class="date">date</th>
136 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
136 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
137 </tr>
137 </tr>
138 <tr>
138 <tr>
139 <th class="author">parents</th>
139 <th class="author">parents</th>
140 <td class="author"></td>
140 <td class="author"></td>
141 </tr>
141 </tr>
142 <tr>
142 <tr>
143 <th class="author">children</th>
143 <th class="author">children</th>
144 <td class="author"></td>
144 <td class="author"></td>
145 </tr>
145 </tr>
146 </table>
146 </table>
147
147
148 <div class="overflow">
148 <div class="overflow">
149 <div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="javascript:toggleLinewrap()">on</a></div>
149 <div class="sourcefirst linewraptoggle">line wrap: <a class="linewraplink" href="javascript:toggleLinewrap()">on</a></div>
150 <div class="sourcefirst"> line source</div>
150 <div class="sourcefirst"> line source</div>
151 <pre class="sourcelines stripes4 wrap bottomline"
151 <pre class="sourcelines stripes4 wrap bottomline"
152 data-logurl="/log/tip/primes.py"
152 data-logurl="/log/tip/primes.py"
153 data-selectabletag="SPAN"
153 data-selectabletag="SPAN"
154 data-ishead="1">
154 data-ishead="1">
155
155
156 <span id="l1"><span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></span><a href="#l1"></a>
156 <span id="l1"><span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></span><a href="#l1"></a>
157 <span id="l2"></span><a href="#l2"></a>
157 <span id="l2"></span><a href="#l2"></a>
158 <span id="l3"><span class="sd">primes = 2 : sieve [3, 5..]</span></span><a href="#l3"></a>
158 <span id="l3"><span class="sd">primes = 2 : sieve [3, 5..]</span></span><a href="#l3"></a>
159 <span id="l4"><span class="sd"> where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></span><a href="#l4"></a>
159 <span id="l4"><span class="sd"> where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></span><a href="#l4"></a>
160 <span id="l5"><span class="sd">&quot;&quot;&quot;</span></span><a href="#l5"></a>
160 <span id="l5"><span class="sd">&quot;&quot;&quot;</span></span><a href="#l5"></a>
161 <span id="l6"></span><a href="#l6"></a>
161 <span id="l6"></span><a href="#l6"></a>
162 <span id="l7"><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></span><a href="#l7"></a>
162 <span id="l7"><span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></span><a href="#l7"></a>
163 <span id="l8"></span><a href="#l8"></a>
163 <span id="l8"></span><a href="#l8"></a>
164 <span id="l9"><span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></span><a href="#l9"></a>
164 <span id="l9"><span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></span><a href="#l9"></a>
165 <span id="l10"> <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></span><a href="#l10"></a>
165 <span id="l10"> <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></span><a href="#l10"></a>
166 <span id="l11"> <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></span><a href="#l11"></a>
166 <span id="l11"> <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></span><a href="#l11"></a>
167 <span id="l12"> <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></span><a href="#l12"></a>
167 <span id="l12"> <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></span><a href="#l12"></a>
168 <span id="l13"> <span class="c"># It is important to yield *here* in order to stop the</span></span><a href="#l13"></a>
168 <span id="l13"> <span class="c"># It is important to yield *here* in order to stop the</span></span><a href="#l13"></a>
169 <span id="l14"> <span class="c"># infinite recursion.</span></span><a href="#l14"></a>
169 <span id="l14"> <span class="c"># infinite recursion.</span></span><a href="#l14"></a>
170 <span id="l15"> <span class="kn">yield</span> <span class="n">p</span></span><a href="#l15"></a>
170 <span id="l15"> <span class="kn">yield</span> <span class="n">p</span></span><a href="#l15"></a>
171 <span id="l16"> <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></span><a href="#l16"></a>
171 <span id="l16"> <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></span><a href="#l16"></a>
172 <span id="l17"> <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></span><a href="#l17"></a>
172 <span id="l17"> <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></span><a href="#l17"></a>
173 <span id="l18"> <span class="kn">yield</span> <span class="n">n</span></span><a href="#l18"></a>
173 <span id="l18"> <span class="kn">yield</span> <span class="n">n</span></span><a href="#l18"></a>
174 <span id="l19"></span><a href="#l19"></a>
174 <span id="l19"></span><a href="#l19"></a>
175 <span id="l20"> <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></span><a href="#l20"></a>
175 <span id="l20"> <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></span><a href="#l20"></a>
176 <span id="l21"> <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></span><a href="#l21"></a>
176 <span id="l21"> <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></span><a href="#l21"></a>
177 <span id="l22"></span><a href="#l22"></a>
177 <span id="l22"></span><a href="#l22"></a>
178 <span id="l23"><span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></span><a href="#l23"></a>
178 <span id="l23"><span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></span><a href="#l23"></a>
179 <span id="l24"> <span class="kn">import</span> <span class="nn">sys</span></span><a href="#l24"></a>
179 <span id="l24"> <span class="kn">import</span> <span class="nn">sys</span></span><a href="#l24"></a>
180 <span id="l25"> <span class="kn">try</span><span class="p">:</span></span><a href="#l25"></a>
180 <span id="l25"> <span class="kn">try</span><span class="p">:</span></span><a href="#l25"></a>
181 <span id="l26"> <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></span><a href="#l26"></a>
181 <span id="l26"> <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></span><a href="#l26"></a>
182 <span id="l27"> <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></span><a href="#l27"></a>
182 <span id="l27"> <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></span><a href="#l27"></a>
183 <span id="l28"> <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></span><a href="#l28"></a>
183 <span id="l28"> <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></span><a href="#l28"></a>
184 <span id="l29"> <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></span><a href="#l29"></a>
184 <span id="l29"> <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></span><a href="#l29"></a>
185 <span id="l30"> <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></span><a href="#l30"></a>
185 <span id="l30"> <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></span><a href="#l30"></a>
186 <span id="l31"></span><a href="#l31"></a>
186 <span id="l31"></span><a href="#l31"></a>
187 </pre>
187 </pre>
188 </div>
188 </div>
189
189
190 <script type="text/javascript" src="/static/followlines.js"></script>
190 <script type="text/javascript" src="/static/followlines.js"></script>
191
191
192 </div>
192 </div>
193 </div>
193 </div>
194
194
195
195
196
196
197 </body>
197 </body>
198 </html>
198 </html>
199
199
200
200
201 hgweb fileannotate, html
201 hgweb fileannotate, html
202
202
203 $ (get-with-headers.py localhost:$HGPORT 'annotate/tip/primes.py') | filterhtml
203 $ (get-with-headers.py localhost:$HGPORT 'annotate/tip/primes.py') | filterhtml
204 200 Script output follows
204 200 Script output follows
205
205
206 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
206 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
207 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
207 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
208 <head>
208 <head>
209 <link rel="icon" href="/static/hgicon.png" type="image/png" />
209 <link rel="icon" href="/static/hgicon.png" type="image/png" />
210 <meta name="robots" content="index, nofollow" />
210 <meta name="robots" content="index, nofollow" />
211 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
211 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
212 <script type="text/javascript" src="/static/mercurial.js"></script>
212 <script type="text/javascript" src="/static/mercurial.js"></script>
213
213
214 <link rel="stylesheet" href="/highlightcss" type="text/css" />
214 <link rel="stylesheet" href="/highlightcss" type="text/css" />
215 <title>test: primes.py annotate</title>
215 <title>test: primes.py annotate</title>
216 </head>
216 </head>
217 <body>
217 <body>
218
218
219 <div class="container">
219 <div class="container">
220 <div class="menu">
220 <div class="menu">
221 <div class="logo">
221 <div class="logo">
222 <a href="https://mercurial-scm.org/">
222 <a href="https://mercurial-scm.org/">
223 <img src="/static/hglogo.png" alt="mercurial" /></a>
223 <img src="/static/hglogo.png" alt="mercurial" /></a>
224 </div>
224 </div>
225 <ul>
225 <ul>
226 <li><a href="/shortlog/tip">log</a></li>
226 <li><a href="/shortlog/tip">log</a></li>
227 <li><a href="/graph/tip">graph</a></li>
227 <li><a href="/graph/tip">graph</a></li>
228 <li><a href="/tags">tags</a></li>
228 <li><a href="/tags">tags</a></li>
229 <li><a href="/bookmarks">bookmarks</a></li>
229 <li><a href="/bookmarks">bookmarks</a></li>
230 <li><a href="/branches">branches</a></li>
230 <li><a href="/branches">branches</a></li>
231 </ul>
231 </ul>
232
232
233 <ul>
233 <ul>
234 <li><a href="/rev/tip">changeset</a></li>
234 <li><a href="/rev/tip">changeset</a></li>
235 <li><a href="/file/tip/">browse</a></li>
235 <li><a href="/file/tip/">browse</a></li>
236 </ul>
236 </ul>
237 <ul>
237 <ul>
238 <li><a href="/file/tip/primes.py">file</a></li>
238 <li><a href="/file/tip/primes.py">file</a></li>
239 <li><a href="/file/tip/primes.py">latest</a></li>
239 <li><a href="/file/tip/primes.py">latest</a></li>
240 <li><a href="/diff/tip/primes.py">diff</a></li>
240 <li><a href="/diff/tip/primes.py">diff</a></li>
241 <li><a href="/comparison/tip/primes.py">comparison</a></li>
241 <li><a href="/comparison/tip/primes.py">comparison</a></li>
242 <li class="active">annotate</li>
242 <li class="active">annotate</li>
243 <li><a href="/log/tip/primes.py">file log</a></li>
243 <li><a href="/log/tip/primes.py">file log</a></li>
244 <li><a href="/raw-file/tip/primes.py">raw</a></li>
244 <li><a href="/raw-file/tip/primes.py">raw</a></li>
245 </ul>
245 </ul>
246 <ul>
246 <ul>
247 <li><a href="/help">help</a></li>
247 <li><a href="/help">help</a></li>
248 </ul>
248 </ul>
249 </div>
249 </div>
250
250
251 <div class="main">
251 <div class="main">
252 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
252 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
253 <h3>
253 <h3>
254 annotate primes.py @ 0:<a href="/rev/1af356141006">1af356141006</a>
254 annotate primes.py @ 0:<a href="/rev/1af356141006">1af356141006</a>
255 <span class="tag">tip</span>
255 <span class="tag">tip</span>
256 </h3>
256 </h3>
257
257
258
258
259 <form class="search" action="/log">
259 <form class="search" action="/log">
260
260
261 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
261 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
262 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
262 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
263 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
263 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
264 </form>
264 </form>
265
265
266 <div class="description">a</div>
266 <div class="description">a</div>
267
267
268 <table id="changesetEntry">
268 <table id="changesetEntry">
269 <tr>
269 <tr>
270 <th class="author">author</th>
270 <th class="author">author</th>
271 <td class="author">&#116;&#101;&#115;&#116;</td>
271 <td class="author">&#116;&#101;&#115;&#116;</td>
272 </tr>
272 </tr>
273 <tr>
273 <tr>
274 <th class="date">date</th>
274 <th class="date">date</th>
275 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
275 <td class="date age">Thu, 01 Jan 1970 00:00:00 +0000</td>
276 </tr>
276 </tr>
277 <tr>
277 <tr>
278 <th class="author">parents</th>
278 <th class="author">parents</th>
279 <td class="author"></td>
279 <td class="author"></td>
280 </tr>
280 </tr>
281 <tr>
281 <tr>
282 <th class="author">children</th>
282 <th class="author">children</th>
283 <td class="author"></td>
283 <td class="author"></td>
284 </tr>
284 </tr>
285 </table>
285 </table>
286
286
287 <div class="overflow">
287 <div class="overflow">
288 <table class="bigtable">
288 <table class="bigtable">
289 <thead>
289 <thead>
290 <tr>
290 <tr>
291 <th class="annotate">rev</th>
291 <th class="annotate">rev</th>
292 <th class="line">&nbsp;&nbsp;line source</th>
292 <th class="line">&nbsp;&nbsp;line source</th>
293 </tr>
293 </tr>
294 </thead>
294 </thead>
295 <tbody class="stripes2 sourcelines"
295 <tbody class="stripes2 sourcelines"
296 data-logurl="/log/tip/primes.py"
296 data-logurl="/log/tip/primes.py"
297 data-selectabletag="TR"
297 data-selectabletag="TR"
298 data-ishead="1">
298 data-ishead="1">
299
299
300 <tr id="l1" class="thisrev">
300 <tr id="l1" class="thisrev">
301 <td class="annotate parity0">
301 <td class="annotate parity0">
302 <a href="/annotate/1af356141006/primes.py#l1">
302 <a href="/annotate/1af356141006/primes.py#l1">
303 0
303 0
304 </a>
304 </a>
305 <div class="annotate-info">
305 <div class="annotate-info">
306 <div>
306 <div>
307 <a href="/annotate/1af356141006/primes.py#l1">
307 <a href="/annotate/1af356141006/primes.py#l1">
308 1af356141006</a>
308 1af356141006</a>
309 a
309 a
310 </div>
310 </div>
311 <div><em>&#116;&#101;&#115;&#116;</em></div>
311 <div><em>&#116;&#101;&#115;&#116;</em></div>
312 <div>parents: </div>
312 <div>parents: </div>
313 <a href="/diff/1af356141006/primes.py">diff</a>
313 <a href="/diff/1af356141006/primes.py">diff</a>
314 <a href="/rev/1af356141006">changeset</a>
314 <a href="/rev/1af356141006">changeset</a>
315 </div>
315 </div>
316 </td>
316 </td>
317 <td class="source"><a href="#l1"> 1</a> <span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></td>
317 <td class="source followlines-btn-parent"><a href="#l1"> 1</a> <span class="sd">&quot;&quot;&quot;Fun with generators. Corresponding Haskell implementation:</span></td>
318 </tr>
318 </tr>
319 <tr id="l2" class="thisrev">
319 <tr id="l2" class="thisrev">
320 <td class="annotate parity0">
320 <td class="annotate parity0">
321
321
322 <div class="annotate-info">
322 <div class="annotate-info">
323 <div>
323 <div>
324 <a href="/annotate/1af356141006/primes.py#l2">
324 <a href="/annotate/1af356141006/primes.py#l2">
325 1af356141006</a>
325 1af356141006</a>
326 a
326 a
327 </div>
327 </div>
328 <div><em>&#116;&#101;&#115;&#116;</em></div>
328 <div><em>&#116;&#101;&#115;&#116;</em></div>
329 <div>parents: </div>
329 <div>parents: </div>
330 <a href="/diff/1af356141006/primes.py">diff</a>
330 <a href="/diff/1af356141006/primes.py">diff</a>
331 <a href="/rev/1af356141006">changeset</a>
331 <a href="/rev/1af356141006">changeset</a>
332 </div>
332 </div>
333 </td>
333 </td>
334 <td class="source"><a href="#l2"> 2</a> </td>
334 <td class="source followlines-btn-parent"><a href="#l2"> 2</a> </td>
335 </tr>
335 </tr>
336 <tr id="l3" class="thisrev">
336 <tr id="l3" class="thisrev">
337 <td class="annotate parity0">
337 <td class="annotate parity0">
338
338
339 <div class="annotate-info">
339 <div class="annotate-info">
340 <div>
340 <div>
341 <a href="/annotate/1af356141006/primes.py#l3">
341 <a href="/annotate/1af356141006/primes.py#l3">
342 1af356141006</a>
342 1af356141006</a>
343 a
343 a
344 </div>
344 </div>
345 <div><em>&#116;&#101;&#115;&#116;</em></div>
345 <div><em>&#116;&#101;&#115;&#116;</em></div>
346 <div>parents: </div>
346 <div>parents: </div>
347 <a href="/diff/1af356141006/primes.py">diff</a>
347 <a href="/diff/1af356141006/primes.py">diff</a>
348 <a href="/rev/1af356141006">changeset</a>
348 <a href="/rev/1af356141006">changeset</a>
349 </div>
349 </div>
350 </td>
350 </td>
351 <td class="source"><a href="#l3"> 3</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></td>
351 <td class="source followlines-btn-parent"><a href="#l3"> 3</a> <span class="sd">primes = 2 : sieve [3, 5..]</span></td>
352 </tr>
352 </tr>
353 <tr id="l4" class="thisrev">
353 <tr id="l4" class="thisrev">
354 <td class="annotate parity0">
354 <td class="annotate parity0">
355
355
356 <div class="annotate-info">
356 <div class="annotate-info">
357 <div>
357 <div>
358 <a href="/annotate/1af356141006/primes.py#l4">
358 <a href="/annotate/1af356141006/primes.py#l4">
359 1af356141006</a>
359 1af356141006</a>
360 a
360 a
361 </div>
361 </div>
362 <div><em>&#116;&#101;&#115;&#116;</em></div>
362 <div><em>&#116;&#101;&#115;&#116;</em></div>
363 <div>parents: </div>
363 <div>parents: </div>
364 <a href="/diff/1af356141006/primes.py">diff</a>
364 <a href="/diff/1af356141006/primes.py">diff</a>
365 <a href="/rev/1af356141006">changeset</a>
365 <a href="/rev/1af356141006">changeset</a>
366 </div>
366 </div>
367 </td>
367 </td>
368 <td class="source"><a href="#l4"> 4</a> <span class="sd"> where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></td>
368 <td class="source followlines-btn-parent"><a href="#l4"> 4</a> <span class="sd"> where sieve (p:ns) = p : sieve [n | n &lt;- ns, mod n p /= 0]</span></td>
369 </tr>
369 </tr>
370 <tr id="l5" class="thisrev">
370 <tr id="l5" class="thisrev">
371 <td class="annotate parity0">
371 <td class="annotate parity0">
372
372
373 <div class="annotate-info">
373 <div class="annotate-info">
374 <div>
374 <div>
375 <a href="/annotate/1af356141006/primes.py#l5">
375 <a href="/annotate/1af356141006/primes.py#l5">
376 1af356141006</a>
376 1af356141006</a>
377 a
377 a
378 </div>
378 </div>
379 <div><em>&#116;&#101;&#115;&#116;</em></div>
379 <div><em>&#116;&#101;&#115;&#116;</em></div>
380 <div>parents: </div>
380 <div>parents: </div>
381 <a href="/diff/1af356141006/primes.py">diff</a>
381 <a href="/diff/1af356141006/primes.py">diff</a>
382 <a href="/rev/1af356141006">changeset</a>
382 <a href="/rev/1af356141006">changeset</a>
383 </div>
383 </div>
384 </td>
384 </td>
385 <td class="source"><a href="#l5"> 5</a> <span class="sd">&quot;&quot;&quot;</span></td>
385 <td class="source followlines-btn-parent"><a href="#l5"> 5</a> <span class="sd">&quot;&quot;&quot;</span></td>
386 </tr>
386 </tr>
387 <tr id="l6" class="thisrev">
387 <tr id="l6" class="thisrev">
388 <td class="annotate parity0">
388 <td class="annotate parity0">
389
389
390 <div class="annotate-info">
390 <div class="annotate-info">
391 <div>
391 <div>
392 <a href="/annotate/1af356141006/primes.py#l6">
392 <a href="/annotate/1af356141006/primes.py#l6">
393 1af356141006</a>
393 1af356141006</a>
394 a
394 a
395 </div>
395 </div>
396 <div><em>&#116;&#101;&#115;&#116;</em></div>
396 <div><em>&#116;&#101;&#115;&#116;</em></div>
397 <div>parents: </div>
397 <div>parents: </div>
398 <a href="/diff/1af356141006/primes.py">diff</a>
398 <a href="/diff/1af356141006/primes.py">diff</a>
399 <a href="/rev/1af356141006">changeset</a>
399 <a href="/rev/1af356141006">changeset</a>
400 </div>
400 </div>
401 </td>
401 </td>
402 <td class="source"><a href="#l6"> 6</a> </td>
402 <td class="source followlines-btn-parent"><a href="#l6"> 6</a> </td>
403 </tr>
403 </tr>
404 <tr id="l7" class="thisrev">
404 <tr id="l7" class="thisrev">
405 <td class="annotate parity0">
405 <td class="annotate parity0">
406
406
407 <div class="annotate-info">
407 <div class="annotate-info">
408 <div>
408 <div>
409 <a href="/annotate/1af356141006/primes.py#l7">
409 <a href="/annotate/1af356141006/primes.py#l7">
410 1af356141006</a>
410 1af356141006</a>
411 a
411 a
412 </div>
412 </div>
413 <div><em>&#116;&#101;&#115;&#116;</em></div>
413 <div><em>&#116;&#101;&#115;&#116;</em></div>
414 <div>parents: </div>
414 <div>parents: </div>
415 <a href="/diff/1af356141006/primes.py">diff</a>
415 <a href="/diff/1af356141006/primes.py">diff</a>
416 <a href="/rev/1af356141006">changeset</a>
416 <a href="/rev/1af356141006">changeset</a>
417 </div>
417 </div>
418 </td>
418 </td>
419 <td class="source"><a href="#l7"> 7</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></td>
419 <td class="source followlines-btn-parent"><a href="#l7"> 7</a> <span class="kn">from</span> <span class="nn">itertools</span> <span class="kn">import</span> <span class="n">dropwhile</span><span class="p">,</span> <span class="n">ifilter</span><span class="p">,</span> <span class="n">islice</span><span class="p">,</span> <span class="n">count</span><span class="p">,</span> <span class="n">chain</span></td>
420 </tr>
420 </tr>
421 <tr id="l8" class="thisrev">
421 <tr id="l8" class="thisrev">
422 <td class="annotate parity0">
422 <td class="annotate parity0">
423
423
424 <div class="annotate-info">
424 <div class="annotate-info">
425 <div>
425 <div>
426 <a href="/annotate/1af356141006/primes.py#l8">
426 <a href="/annotate/1af356141006/primes.py#l8">
427 1af356141006</a>
427 1af356141006</a>
428 a
428 a
429 </div>
429 </div>
430 <div><em>&#116;&#101;&#115;&#116;</em></div>
430 <div><em>&#116;&#101;&#115;&#116;</em></div>
431 <div>parents: </div>
431 <div>parents: </div>
432 <a href="/diff/1af356141006/primes.py">diff</a>
432 <a href="/diff/1af356141006/primes.py">diff</a>
433 <a href="/rev/1af356141006">changeset</a>
433 <a href="/rev/1af356141006">changeset</a>
434 </div>
434 </div>
435 </td>
435 </td>
436 <td class="source"><a href="#l8"> 8</a> </td>
436 <td class="source followlines-btn-parent"><a href="#l8"> 8</a> </td>
437 </tr>
437 </tr>
438 <tr id="l9" class="thisrev">
438 <tr id="l9" class="thisrev">
439 <td class="annotate parity0">
439 <td class="annotate parity0">
440
440
441 <div class="annotate-info">
441 <div class="annotate-info">
442 <div>
442 <div>
443 <a href="/annotate/1af356141006/primes.py#l9">
443 <a href="/annotate/1af356141006/primes.py#l9">
444 1af356141006</a>
444 1af356141006</a>
445 a
445 a
446 </div>
446 </div>
447 <div><em>&#116;&#101;&#115;&#116;</em></div>
447 <div><em>&#116;&#101;&#115;&#116;</em></div>
448 <div>parents: </div>
448 <div>parents: </div>
449 <a href="/diff/1af356141006/primes.py">diff</a>
449 <a href="/diff/1af356141006/primes.py">diff</a>
450 <a href="/rev/1af356141006">changeset</a>
450 <a href="/rev/1af356141006">changeset</a>
451 </div>
451 </div>
452 </td>
452 </td>
453 <td class="source"><a href="#l9"> 9</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></td>
453 <td class="source followlines-btn-parent"><a href="#l9"> 9</a> <span class="kn">def</span> <span class="nf">primes</span><span class="p">():</span></td>
454 </tr>
454 </tr>
455 <tr id="l10" class="thisrev">
455 <tr id="l10" class="thisrev">
456 <td class="annotate parity0">
456 <td class="annotate parity0">
457
457
458 <div class="annotate-info">
458 <div class="annotate-info">
459 <div>
459 <div>
460 <a href="/annotate/1af356141006/primes.py#l10">
460 <a href="/annotate/1af356141006/primes.py#l10">
461 1af356141006</a>
461 1af356141006</a>
462 a
462 a
463 </div>
463 </div>
464 <div><em>&#116;&#101;&#115;&#116;</em></div>
464 <div><em>&#116;&#101;&#115;&#116;</em></div>
465 <div>parents: </div>
465 <div>parents: </div>
466 <a href="/diff/1af356141006/primes.py">diff</a>
466 <a href="/diff/1af356141006/primes.py">diff</a>
467 <a href="/rev/1af356141006">changeset</a>
467 <a href="/rev/1af356141006">changeset</a>
468 </div>
468 </div>
469 </td>
469 </td>
470 <td class="source"><a href="#l10"> 10</a> <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></td>
470 <td class="source followlines-btn-parent"><a href="#l10"> 10</a> <span class="sd">&quot;&quot;&quot;Generate all primes.&quot;&quot;&quot;</span></td>
471 </tr>
471 </tr>
472 <tr id="l11" class="thisrev">
472 <tr id="l11" class="thisrev">
473 <td class="annotate parity0">
473 <td class="annotate parity0">
474
474
475 <div class="annotate-info">
475 <div class="annotate-info">
476 <div>
476 <div>
477 <a href="/annotate/1af356141006/primes.py#l11">
477 <a href="/annotate/1af356141006/primes.py#l11">
478 1af356141006</a>
478 1af356141006</a>
479 a
479 a
480 </div>
480 </div>
481 <div><em>&#116;&#101;&#115;&#116;</em></div>
481 <div><em>&#116;&#101;&#115;&#116;</em></div>
482 <div>parents: </div>
482 <div>parents: </div>
483 <a href="/diff/1af356141006/primes.py">diff</a>
483 <a href="/diff/1af356141006/primes.py">diff</a>
484 <a href="/rev/1af356141006">changeset</a>
484 <a href="/rev/1af356141006">changeset</a>
485 </div>
485 </div>
486 </td>
486 </td>
487 <td class="source"><a href="#l11"> 11</a> <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
487 <td class="source followlines-btn-parent"><a href="#l11"> 11</a> <span class="kn">def</span> <span class="nf">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
488 </tr>
488 </tr>
489 <tr id="l12" class="thisrev">
489 <tr id="l12" class="thisrev">
490 <td class="annotate parity0">
490 <td class="annotate parity0">
491
491
492 <div class="annotate-info">
492 <div class="annotate-info">
493 <div>
493 <div>
494 <a href="/annotate/1af356141006/primes.py#l12">
494 <a href="/annotate/1af356141006/primes.py#l12">
495 1af356141006</a>
495 1af356141006</a>
496 a
496 a
497 </div>
497 </div>
498 <div><em>&#116;&#101;&#115;&#116;</em></div>
498 <div><em>&#116;&#101;&#115;&#116;</em></div>
499 <div>parents: </div>
499 <div>parents: </div>
500 <a href="/diff/1af356141006/primes.py">diff</a>
500 <a href="/diff/1af356141006/primes.py">diff</a>
501 <a href="/rev/1af356141006">changeset</a>
501 <a href="/rev/1af356141006">changeset</a>
502 </div>
502 </div>
503 </td>
503 </td>
504 <td class="source"><a href="#l12"> 12</a> <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></td>
504 <td class="source followlines-btn-parent"><a href="#l12"> 12</a> <span class="n">p</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">next</span><span class="p">()</span></td>
505 </tr>
505 </tr>
506 <tr id="l13" class="thisrev">
506 <tr id="l13" class="thisrev">
507 <td class="annotate parity0">
507 <td class="annotate parity0">
508
508
509 <div class="annotate-info">
509 <div class="annotate-info">
510 <div>
510 <div>
511 <a href="/annotate/1af356141006/primes.py#l13">
511 <a href="/annotate/1af356141006/primes.py#l13">
512 1af356141006</a>
512 1af356141006</a>
513 a
513 a
514 </div>
514 </div>
515 <div><em>&#116;&#101;&#115;&#116;</em></div>
515 <div><em>&#116;&#101;&#115;&#116;</em></div>
516 <div>parents: </div>
516 <div>parents: </div>
517 <a href="/diff/1af356141006/primes.py">diff</a>
517 <a href="/diff/1af356141006/primes.py">diff</a>
518 <a href="/rev/1af356141006">changeset</a>
518 <a href="/rev/1af356141006">changeset</a>
519 </div>
519 </div>
520 </td>
520 </td>
521 <td class="source"><a href="#l13"> 13</a> <span class="c"># It is important to yield *here* in order to stop the</span></td>
521 <td class="source followlines-btn-parent"><a href="#l13"> 13</a> <span class="c"># It is important to yield *here* in order to stop the</span></td>
522 </tr>
522 </tr>
523 <tr id="l14" class="thisrev">
523 <tr id="l14" class="thisrev">
524 <td class="annotate parity0">
524 <td class="annotate parity0">
525
525
526 <div class="annotate-info">
526 <div class="annotate-info">
527 <div>
527 <div>
528 <a href="/annotate/1af356141006/primes.py#l14">
528 <a href="/annotate/1af356141006/primes.py#l14">
529 1af356141006</a>
529 1af356141006</a>
530 a
530 a
531 </div>
531 </div>
532 <div><em>&#116;&#101;&#115;&#116;</em></div>
532 <div><em>&#116;&#101;&#115;&#116;</em></div>
533 <div>parents: </div>
533 <div>parents: </div>
534 <a href="/diff/1af356141006/primes.py">diff</a>
534 <a href="/diff/1af356141006/primes.py">diff</a>
535 <a href="/rev/1af356141006">changeset</a>
535 <a href="/rev/1af356141006">changeset</a>
536 </div>
536 </div>
537 </td>
537 </td>
538 <td class="source"><a href="#l14"> 14</a> <span class="c"># infinite recursion.</span></td>
538 <td class="source followlines-btn-parent"><a href="#l14"> 14</a> <span class="c"># infinite recursion.</span></td>
539 </tr>
539 </tr>
540 <tr id="l15" class="thisrev">
540 <tr id="l15" class="thisrev">
541 <td class="annotate parity0">
541 <td class="annotate parity0">
542
542
543 <div class="annotate-info">
543 <div class="annotate-info">
544 <div>
544 <div>
545 <a href="/annotate/1af356141006/primes.py#l15">
545 <a href="/annotate/1af356141006/primes.py#l15">
546 1af356141006</a>
546 1af356141006</a>
547 a
547 a
548 </div>
548 </div>
549 <div><em>&#116;&#101;&#115;&#116;</em></div>
549 <div><em>&#116;&#101;&#115;&#116;</em></div>
550 <div>parents: </div>
550 <div>parents: </div>
551 <a href="/diff/1af356141006/primes.py">diff</a>
551 <a href="/diff/1af356141006/primes.py">diff</a>
552 <a href="/rev/1af356141006">changeset</a>
552 <a href="/rev/1af356141006">changeset</a>
553 </div>
553 </div>
554 </td>
554 </td>
555 <td class="source"><a href="#l15"> 15</a> <span class="kn">yield</span> <span class="n">p</span></td>
555 <td class="source followlines-btn-parent"><a href="#l15"> 15</a> <span class="kn">yield</span> <span class="n">p</span></td>
556 </tr>
556 </tr>
557 <tr id="l16" class="thisrev">
557 <tr id="l16" class="thisrev">
558 <td class="annotate parity0">
558 <td class="annotate parity0">
559
559
560 <div class="annotate-info">
560 <div class="annotate-info">
561 <div>
561 <div>
562 <a href="/annotate/1af356141006/primes.py#l16">
562 <a href="/annotate/1af356141006/primes.py#l16">
563 1af356141006</a>
563 1af356141006</a>
564 a
564 a
565 </div>
565 </div>
566 <div><em>&#116;&#101;&#115;&#116;</em></div>
566 <div><em>&#116;&#101;&#115;&#116;</em></div>
567 <div>parents: </div>
567 <div>parents: </div>
568 <a href="/diff/1af356141006/primes.py">diff</a>
568 <a href="/diff/1af356141006/primes.py">diff</a>
569 <a href="/rev/1af356141006">changeset</a>
569 <a href="/rev/1af356141006">changeset</a>
570 </div>
570 </div>
571 </td>
571 </td>
572 <td class="source"><a href="#l16"> 16</a> <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></td>
572 <td class="source followlines-btn-parent"><a href="#l16"> 16</a> <span class="n">ns</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">%</span> <span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ns</span><span class="p">)</span></td>
573 </tr>
573 </tr>
574 <tr id="l17" class="thisrev">
574 <tr id="l17" class="thisrev">
575 <td class="annotate parity0">
575 <td class="annotate parity0">
576
576
577 <div class="annotate-info">
577 <div class="annotate-info">
578 <div>
578 <div>
579 <a href="/annotate/1af356141006/primes.py#l17">
579 <a href="/annotate/1af356141006/primes.py#l17">
580 1af356141006</a>
580 1af356141006</a>
581 a
581 a
582 </div>
582 </div>
583 <div><em>&#116;&#101;&#115;&#116;</em></div>
583 <div><em>&#116;&#101;&#115;&#116;</em></div>
584 <div>parents: </div>
584 <div>parents: </div>
585 <a href="/diff/1af356141006/primes.py">diff</a>
585 <a href="/diff/1af356141006/primes.py">diff</a>
586 <a href="/rev/1af356141006">changeset</a>
586 <a href="/rev/1af356141006">changeset</a>
587 </div>
587 </div>
588 </td>
588 </td>
589 <td class="source"><a href="#l17"> 17</a> <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
589 <td class="source followlines-btn-parent"><a href="#l17"> 17</a> <span class="kn">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">sieve</span><span class="p">(</span><span class="n">ns</span><span class="p">):</span></td>
590 </tr>
590 </tr>
591 <tr id="l18" class="thisrev">
591 <tr id="l18" class="thisrev">
592 <td class="annotate parity0">
592 <td class="annotate parity0">
593
593
594 <div class="annotate-info">
594 <div class="annotate-info">
595 <div>
595 <div>
596 <a href="/annotate/1af356141006/primes.py#l18">
596 <a href="/annotate/1af356141006/primes.py#l18">
597 1af356141006</a>
597 1af356141006</a>
598 a
598 a
599 </div>
599 </div>
600 <div><em>&#116;&#101;&#115;&#116;</em></div>
600 <div><em>&#116;&#101;&#115;&#116;</em></div>
601 <div>parents: </div>
601 <div>parents: </div>
602 <a href="/diff/1af356141006/primes.py">diff</a>
602 <a href="/diff/1af356141006/primes.py">diff</a>
603 <a href="/rev/1af356141006">changeset</a>
603 <a href="/rev/1af356141006">changeset</a>
604 </div>
604 </div>
605 </td>
605 </td>
606 <td class="source"><a href="#l18"> 18</a> <span class="kn">yield</span> <span class="n">n</span></td>
606 <td class="source followlines-btn-parent"><a href="#l18"> 18</a> <span class="kn">yield</span> <span class="n">n</span></td>
607 </tr>
607 </tr>
608 <tr id="l19" class="thisrev">
608 <tr id="l19" class="thisrev">
609 <td class="annotate parity0">
609 <td class="annotate parity0">
610
610
611 <div class="annotate-info">
611 <div class="annotate-info">
612 <div>
612 <div>
613 <a href="/annotate/1af356141006/primes.py#l19">
613 <a href="/annotate/1af356141006/primes.py#l19">
614 1af356141006</a>
614 1af356141006</a>
615 a
615 a
616 </div>
616 </div>
617 <div><em>&#116;&#101;&#115;&#116;</em></div>
617 <div><em>&#116;&#101;&#115;&#116;</em></div>
618 <div>parents: </div>
618 <div>parents: </div>
619 <a href="/diff/1af356141006/primes.py">diff</a>
619 <a href="/diff/1af356141006/primes.py">diff</a>
620 <a href="/rev/1af356141006">changeset</a>
620 <a href="/rev/1af356141006">changeset</a>
621 </div>
621 </div>
622 </td>
622 </td>
623 <td class="source"><a href="#l19"> 19</a> </td>
623 <td class="source followlines-btn-parent"><a href="#l19"> 19</a> </td>
624 </tr>
624 </tr>
625 <tr id="l20" class="thisrev">
625 <tr id="l20" class="thisrev">
626 <td class="annotate parity0">
626 <td class="annotate parity0">
627
627
628 <div class="annotate-info">
628 <div class="annotate-info">
629 <div>
629 <div>
630 <a href="/annotate/1af356141006/primes.py#l20">
630 <a href="/annotate/1af356141006/primes.py#l20">
631 1af356141006</a>
631 1af356141006</a>
632 a
632 a
633 </div>
633 </div>
634 <div><em>&#116;&#101;&#115;&#116;</em></div>
634 <div><em>&#116;&#101;&#115;&#116;</em></div>
635 <div>parents: </div>
635 <div>parents: </div>
636 <a href="/diff/1af356141006/primes.py">diff</a>
636 <a href="/diff/1af356141006/primes.py">diff</a>
637 <a href="/rev/1af356141006">changeset</a>
637 <a href="/rev/1af356141006">changeset</a>
638 </div>
638 </div>
639 </td>
639 </td>
640 <td class="source"><a href="#l20"> 20</a> <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></td>
640 <td class="source followlines-btn-parent"><a href="#l20"> 20</a> <span class="n">odds</span> <span class="o">=</span> <span class="n">ifilter</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">i</span><span class="p">:</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="n">count</span><span class="p">())</span></td>
641 </tr>
641 </tr>
642 <tr id="l21" class="thisrev">
642 <tr id="l21" class="thisrev">
643 <td class="annotate parity0">
643 <td class="annotate parity0">
644
644
645 <div class="annotate-info">
645 <div class="annotate-info">
646 <div>
646 <div>
647 <a href="/annotate/1af356141006/primes.py#l21">
647 <a href="/annotate/1af356141006/primes.py#l21">
648 1af356141006</a>
648 1af356141006</a>
649 a
649 a
650 </div>
650 </div>
651 <div><em>&#116;&#101;&#115;&#116;</em></div>
651 <div><em>&#116;&#101;&#115;&#116;</em></div>
652 <div>parents: </div>
652 <div>parents: </div>
653 <a href="/diff/1af356141006/primes.py">diff</a>
653 <a href="/diff/1af356141006/primes.py">diff</a>
654 <a href="/rev/1af356141006">changeset</a>
654 <a href="/rev/1af356141006">changeset</a>
655 </div>
655 </div>
656 </td>
656 </td>
657 <td class="source"><a href="#l21"> 21</a> <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></td>
657 <td class="source followlines-btn-parent"><a href="#l21"> 21</a> <span class="kn">return</span> <span class="n">chain</span><span class="p">([</span><span class="mi">2</span><span class="p">],</span> <span class="n">sieve</span><span class="p">(</span><span class="n">dropwhile</span><span class="p">(</span><span class="kn">lambda</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">,</span> <span class="n">odds</span><span class="p">)))</span></td>
658 </tr>
658 </tr>
659 <tr id="l22" class="thisrev">
659 <tr id="l22" class="thisrev">
660 <td class="annotate parity0">
660 <td class="annotate parity0">
661
661
662 <div class="annotate-info">
662 <div class="annotate-info">
663 <div>
663 <div>
664 <a href="/annotate/1af356141006/primes.py#l22">
664 <a href="/annotate/1af356141006/primes.py#l22">
665 1af356141006</a>
665 1af356141006</a>
666 a
666 a
667 </div>
667 </div>
668 <div><em>&#116;&#101;&#115;&#116;</em></div>
668 <div><em>&#116;&#101;&#115;&#116;</em></div>
669 <div>parents: </div>
669 <div>parents: </div>
670 <a href="/diff/1af356141006/primes.py">diff</a>
670 <a href="/diff/1af356141006/primes.py">diff</a>
671 <a href="/rev/1af356141006">changeset</a>
671 <a href="/rev/1af356141006">changeset</a>
672 </div>
672 </div>
673 </td>
673 </td>
674 <td class="source"><a href="#l22"> 22</a> </td>
674 <td class="source followlines-btn-parent"><a href="#l22"> 22</a> </td>
675 </tr>
675 </tr>
676 <tr id="l23" class="thisrev">
676 <tr id="l23" class="thisrev">
677 <td class="annotate parity0">
677 <td class="annotate parity0">
678
678
679 <div class="annotate-info">
679 <div class="annotate-info">
680 <div>
680 <div>
681 <a href="/annotate/1af356141006/primes.py#l23">
681 <a href="/annotate/1af356141006/primes.py#l23">
682 1af356141006</a>
682 1af356141006</a>
683 a
683 a
684 </div>
684 </div>
685 <div><em>&#116;&#101;&#115;&#116;</em></div>
685 <div><em>&#116;&#101;&#115;&#116;</em></div>
686 <div>parents: </div>
686 <div>parents: </div>
687 <a href="/diff/1af356141006/primes.py">diff</a>
687 <a href="/diff/1af356141006/primes.py">diff</a>
688 <a href="/rev/1af356141006">changeset</a>
688 <a href="/rev/1af356141006">changeset</a>
689 </div>
689 </div>
690 </td>
690 </td>
691 <td class="source"><a href="#l23"> 23</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></td>
691 <td class="source followlines-btn-parent"><a href="#l23"> 23</a> <span class="kn">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&quot;__main__&quot;</span><span class="p">:</span></td>
692 </tr>
692 </tr>
693 <tr id="l24" class="thisrev">
693 <tr id="l24" class="thisrev">
694 <td class="annotate parity0">
694 <td class="annotate parity0">
695
695
696 <div class="annotate-info">
696 <div class="annotate-info">
697 <div>
697 <div>
698 <a href="/annotate/1af356141006/primes.py#l24">
698 <a href="/annotate/1af356141006/primes.py#l24">
699 1af356141006</a>
699 1af356141006</a>
700 a
700 a
701 </div>
701 </div>
702 <div><em>&#116;&#101;&#115;&#116;</em></div>
702 <div><em>&#116;&#101;&#115;&#116;</em></div>
703 <div>parents: </div>
703 <div>parents: </div>
704 <a href="/diff/1af356141006/primes.py">diff</a>
704 <a href="/diff/1af356141006/primes.py">diff</a>
705 <a href="/rev/1af356141006">changeset</a>
705 <a href="/rev/1af356141006">changeset</a>
706 </div>
706 </div>
707 </td>
707 </td>
708 <td class="source"><a href="#l24"> 24</a> <span class="kn">import</span> <span class="nn">sys</span></td>
708 <td class="source followlines-btn-parent"><a href="#l24"> 24</a> <span class="kn">import</span> <span class="nn">sys</span></td>
709 </tr>
709 </tr>
710 <tr id="l25" class="thisrev">
710 <tr id="l25" class="thisrev">
711 <td class="annotate parity0">
711 <td class="annotate parity0">
712
712
713 <div class="annotate-info">
713 <div class="annotate-info">
714 <div>
714 <div>
715 <a href="/annotate/1af356141006/primes.py#l25">
715 <a href="/annotate/1af356141006/primes.py#l25">
716 1af356141006</a>
716 1af356141006</a>
717 a
717 a
718 </div>
718 </div>
719 <div><em>&#116;&#101;&#115;&#116;</em></div>
719 <div><em>&#116;&#101;&#115;&#116;</em></div>
720 <div>parents: </div>
720 <div>parents: </div>
721 <a href="/diff/1af356141006/primes.py">diff</a>
721 <a href="/diff/1af356141006/primes.py">diff</a>
722 <a href="/rev/1af356141006">changeset</a>
722 <a href="/rev/1af356141006">changeset</a>
723 </div>
723 </div>
724 </td>
724 </td>
725 <td class="source"><a href="#l25"> 25</a> <span class="kn">try</span><span class="p">:</span></td>
725 <td class="source followlines-btn-parent"><a href="#l25"> 25</a> <span class="kn">try</span><span class="p">:</span></td>
726 </tr>
726 </tr>
727 <tr id="l26" class="thisrev">
727 <tr id="l26" class="thisrev">
728 <td class="annotate parity0">
728 <td class="annotate parity0">
729
729
730 <div class="annotate-info">
730 <div class="annotate-info">
731 <div>
731 <div>
732 <a href="/annotate/1af356141006/primes.py#l26">
732 <a href="/annotate/1af356141006/primes.py#l26">
733 1af356141006</a>
733 1af356141006</a>
734 a
734 a
735 </div>
735 </div>
736 <div><em>&#116;&#101;&#115;&#116;</em></div>
736 <div><em>&#116;&#101;&#115;&#116;</em></div>
737 <div>parents: </div>
737 <div>parents: </div>
738 <a href="/diff/1af356141006/primes.py">diff</a>
738 <a href="/diff/1af356141006/primes.py">diff</a>
739 <a href="/rev/1af356141006">changeset</a>
739 <a href="/rev/1af356141006">changeset</a>
740 </div>
740 </div>
741 </td>
741 </td>
742 <td class="source"><a href="#l26"> 26</a> <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></td>
742 <td class="source followlines-btn-parent"><a href="#l26"> 26</a> <span class="n">n</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></td>
743 </tr>
743 </tr>
744 <tr id="l27" class="thisrev">
744 <tr id="l27" class="thisrev">
745 <td class="annotate parity0">
745 <td class="annotate parity0">
746
746
747 <div class="annotate-info">
747 <div class="annotate-info">
748 <div>
748 <div>
749 <a href="/annotate/1af356141006/primes.py#l27">
749 <a href="/annotate/1af356141006/primes.py#l27">
750 1af356141006</a>
750 1af356141006</a>
751 a
751 a
752 </div>
752 </div>
753 <div><em>&#116;&#101;&#115;&#116;</em></div>
753 <div><em>&#116;&#101;&#115;&#116;</em></div>
754 <div>parents: </div>
754 <div>parents: </div>
755 <a href="/diff/1af356141006/primes.py">diff</a>
755 <a href="/diff/1af356141006/primes.py">diff</a>
756 <a href="/rev/1af356141006">changeset</a>
756 <a href="/rev/1af356141006">changeset</a>
757 </div>
757 </div>
758 </td>
758 </td>
759 <td class="source"><a href="#l27"> 27</a> <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></td>
759 <td class="source followlines-btn-parent"><a href="#l27"> 27</a> <span class="kn">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">IndexError</span><span class="p">):</span></td>
760 </tr>
760 </tr>
761 <tr id="l28" class="thisrev">
761 <tr id="l28" class="thisrev">
762 <td class="annotate parity0">
762 <td class="annotate parity0">
763
763
764 <div class="annotate-info">
764 <div class="annotate-info">
765 <div>
765 <div>
766 <a href="/annotate/1af356141006/primes.py#l28">
766 <a href="/annotate/1af356141006/primes.py#l28">
767 1af356141006</a>
767 1af356141006</a>
768 a
768 a
769 </div>
769 </div>
770 <div><em>&#116;&#101;&#115;&#116;</em></div>
770 <div><em>&#116;&#101;&#115;&#116;</em></div>
771 <div>parents: </div>
771 <div>parents: </div>
772 <a href="/diff/1af356141006/primes.py">diff</a>
772 <a href="/diff/1af356141006/primes.py">diff</a>
773 <a href="/rev/1af356141006">changeset</a>
773 <a href="/rev/1af356141006">changeset</a>
774 </div>
774 </div>
775 </td>
775 </td>
776 <td class="source"><a href="#l28"> 28</a> <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></td>
776 <td class="source followlines-btn-parent"><a href="#l28"> 28</a> <span class="n">n</span> <span class="o">=</span> <span class="mi">10</span></td>
777 </tr>
777 </tr>
778 <tr id="l29" class="thisrev">
778 <tr id="l29" class="thisrev">
779 <td class="annotate parity0">
779 <td class="annotate parity0">
780
780
781 <div class="annotate-info">
781 <div class="annotate-info">
782 <div>
782 <div>
783 <a href="/annotate/1af356141006/primes.py#l29">
783 <a href="/annotate/1af356141006/primes.py#l29">
784 1af356141006</a>
784 1af356141006</a>
785 a
785 a
786 </div>
786 </div>
787 <div><em>&#116;&#101;&#115;&#116;</em></div>
787 <div><em>&#116;&#101;&#115;&#116;</em></div>
788 <div>parents: </div>
788 <div>parents: </div>
789 <a href="/diff/1af356141006/primes.py">diff</a>
789 <a href="/diff/1af356141006/primes.py">diff</a>
790 <a href="/rev/1af356141006">changeset</a>
790 <a href="/rev/1af356141006">changeset</a>
791 </div>
791 </div>
792 </td>
792 </td>
793 <td class="source"><a href="#l29"> 29</a> <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></td>
793 <td class="source followlines-btn-parent"><a href="#l29"> 29</a> <span class="n">p</span> <span class="o">=</span> <span class="n">primes</span><span class="p">()</span></td>
794 </tr>
794 </tr>
795 <tr id="l30" class="thisrev">
795 <tr id="l30" class="thisrev">
796 <td class="annotate parity0">
796 <td class="annotate parity0">
797
797
798 <div class="annotate-info">
798 <div class="annotate-info">
799 <div>
799 <div>
800 <a href="/annotate/1af356141006/primes.py#l30">
800 <a href="/annotate/1af356141006/primes.py#l30">
801 1af356141006</a>
801 1af356141006</a>
802 a
802 a
803 </div>
803 </div>
804 <div><em>&#116;&#101;&#115;&#116;</em></div>
804 <div><em>&#116;&#101;&#115;&#116;</em></div>
805 <div>parents: </div>
805 <div>parents: </div>
806 <a href="/diff/1af356141006/primes.py">diff</a>
806 <a href="/diff/1af356141006/primes.py">diff</a>
807 <a href="/rev/1af356141006">changeset</a>
807 <a href="/rev/1af356141006">changeset</a>
808 </div>
808 </div>
809 </td>
809 </td>
810 <td class="source"><a href="#l30"> 30</a> <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></td>
810 <td class="source followlines-btn-parent"><a href="#l30"> 30</a> <span class="kn">print</span> <span class="s">&quot;The first </span><span class="si">%d</span><span class="s"> primes: </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="nb">list</span><span class="p">(</span><span class="n">islice</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">n</span><span class="p">)))</span></td>
811 </tr>
811 </tr>
812 <tr id="l31" class="thisrev">
812 <tr id="l31" class="thisrev">
813 <td class="annotate parity0">
813 <td class="annotate parity0">
814
814
815 <div class="annotate-info">
815 <div class="annotate-info">
816 <div>
816 <div>
817 <a href="/annotate/1af356141006/primes.py#l31">
817 <a href="/annotate/1af356141006/primes.py#l31">
818 1af356141006</a>
818 1af356141006</a>
819 a
819 a
820 </div>
820 </div>
821 <div><em>&#116;&#101;&#115;&#116;</em></div>
821 <div><em>&#116;&#101;&#115;&#116;</em></div>
822 <div>parents: </div>
822 <div>parents: </div>
823 <a href="/diff/1af356141006/primes.py">diff</a>
823 <a href="/diff/1af356141006/primes.py">diff</a>
824 <a href="/rev/1af356141006">changeset</a>
824 <a href="/rev/1af356141006">changeset</a>
825 </div>
825 </div>
826 </td>
826 </td>
827 <td class="source"><a href="#l31"> 31</a> </td>
827 <td class="source followlines-btn-parent"><a href="#l31"> 31</a> </td>
828 </tr>
828 </tr>
829 </tbody>
829 </tbody>
830 </table>
830 </table>
831 </div>
831 </div>
832 </div>
832 </div>
833 </div>
833 </div>
834
834
835 <script type="text/javascript" src="/static/followlines.js"></script>
835 <script type="text/javascript" src="/static/followlines.js"></script>
836
836
837
837
838
838
839 </body>
839 </body>
840 </html>
840 </html>
841
841
842
842
843 hgweb fileannotate, raw
843 hgweb fileannotate, raw
844
844
845 $ (get-with-headers.py localhost:$HGPORT 'annotate/tip/primes.py?style=raw') \
845 $ (get-with-headers.py localhost:$HGPORT 'annotate/tip/primes.py?style=raw') \
846 > | sed "s/test@//" > a
846 > | sed "s/test@//" > a
847 $ echo "200 Script output follows" > b
847 $ echo "200 Script output follows" > b
848 $ echo "" >> b
848 $ echo "" >> b
849 $ echo "" >> b
849 $ echo "" >> b
850 $ hg annotate "primes.py" >> b
850 $ hg annotate "primes.py" >> b
851 $ echo "" >> b
851 $ echo "" >> b
852 $ echo "" >> b
852 $ echo "" >> b
853 $ echo "" >> b
853 $ echo "" >> b
854 $ echo "" >> b
854 $ echo "" >> b
855 $ cmp b a || diff -u b a
855 $ cmp b a || diff -u b a
856
856
857 hgweb filerevision, raw
857 hgweb filerevision, raw
858
858
859 $ (get-with-headers.py localhost:$HGPORT 'file/tip/primes.py?style=raw') \
859 $ (get-with-headers.py localhost:$HGPORT 'file/tip/primes.py?style=raw') \
860 > > a
860 > > a
861 $ echo "200 Script output follows" > b
861 $ echo "200 Script output follows" > b
862 $ echo "" >> b
862 $ echo "" >> b
863 $ hg cat primes.py >> b
863 $ hg cat primes.py >> b
864 $ cmp b a || diff -u b a
864 $ cmp b a || diff -u b a
865
865
866 hgweb highlightcss friendly
866 hgweb highlightcss friendly
867
867
868 $ get-with-headers.py localhost:$HGPORT 'highlightcss' > out
868 $ get-with-headers.py localhost:$HGPORT 'highlightcss' > out
869 $ head -n 4 out
869 $ head -n 4 out
870 200 Script output follows
870 200 Script output follows
871
871
872 /* pygments_style = friendly */
872 /* pygments_style = friendly */
873
873
874 $ rm out
874 $ rm out
875
875
876 errors encountered
876 errors encountered
877
877
878 $ cat errors.log
878 $ cat errors.log
879 $ killdaemons.py
879 $ killdaemons.py
880
880
881 Change the pygments style
881 Change the pygments style
882
882
883 $ cat > .hg/hgrc <<EOF
883 $ cat > .hg/hgrc <<EOF
884 > [web]
884 > [web]
885 > pygments_style = fruity
885 > pygments_style = fruity
886 > EOF
886 > EOF
887
887
888 hg serve again
888 hg serve again
889
889
890 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
890 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
891 $ cat hg.pid >> $DAEMON_PIDS
891 $ cat hg.pid >> $DAEMON_PIDS
892
892
893 hgweb highlightcss fruity
893 hgweb highlightcss fruity
894
894
895 $ get-with-headers.py localhost:$HGPORT 'highlightcss' > out
895 $ get-with-headers.py localhost:$HGPORT 'highlightcss' > out
896 $ head -n 4 out
896 $ head -n 4 out
897 200 Script output follows
897 200 Script output follows
898
898
899 /* pygments_style = fruity */
899 /* pygments_style = fruity */
900
900
901 $ rm out
901 $ rm out
902
902
903 errors encountered
903 errors encountered
904
904
905 $ cat errors.log
905 $ cat errors.log
906 $ killdaemons.py
906 $ killdaemons.py
907
907
908 only highlight C source files
908 only highlight C source files
909
909
910 $ cat > .hg/hgrc <<EOF
910 $ cat > .hg/hgrc <<EOF
911 > [web]
911 > [web]
912 > highlightfiles = **.c
912 > highlightfiles = **.c
913 > EOF
913 > EOF
914
914
915 hg serve again
915 hg serve again
916
916
917 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
917 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid -A access.log -E errors.log
918 $ cat hg.pid >> $DAEMON_PIDS
918 $ cat hg.pid >> $DAEMON_PIDS
919
919
920 test that fileset in highlightfiles works and primes.py is not highlighted
920 test that fileset in highlightfiles works and primes.py is not highlighted
921
921
922 $ get-with-headers.py localhost:$HGPORT 'file/tip/primes.py' | grep 'id="l11"'
922 $ get-with-headers.py localhost:$HGPORT 'file/tip/primes.py' | grep 'id="l11"'
923 <span id="l11"> def sieve(ns):</span><a href="#l11"></a>
923 <span id="l11"> def sieve(ns):</span><a href="#l11"></a>
924
924
925 errors encountered
925 errors encountered
926
926
927 $ cat errors.log
927 $ cat errors.log
928 $ cd ..
928 $ cd ..
929 $ hg init eucjp
929 $ hg init eucjp
930 $ cd eucjp
930 $ cd eucjp
931 $ $PYTHON -c 'print("\265\376")' >> eucjp.txt # Japanese kanji "Kyo"
931 $ $PYTHON -c 'print("\265\376")' >> eucjp.txt # Japanese kanji "Kyo"
932 $ hg ci -Ama
932 $ hg ci -Ama
933 adding eucjp.txt
933 adding eucjp.txt
934 $ hgserveget () {
934 $ hgserveget () {
935 > killdaemons.py
935 > killdaemons.py
936 > echo % HGENCODING="$1" hg serve
936 > echo % HGENCODING="$1" hg serve
937 > HGENCODING="$1" hg serve -p $HGPORT -d -n test --pid-file=hg.pid -E errors.log
937 > HGENCODING="$1" hg serve -p $HGPORT -d -n test --pid-file=hg.pid -E errors.log
938 > cat hg.pid >> $DAEMON_PIDS
938 > cat hg.pid >> $DAEMON_PIDS
939 >
939 >
940 > echo % hgweb filerevision, html
940 > echo % hgweb filerevision, html
941 > get-with-headers.py localhost:$HGPORT "file/tip/$2" \
941 > get-with-headers.py localhost:$HGPORT "file/tip/$2" \
942 > | grep '<div class="parity0 source">'
942 > | grep '<div class="parity0 source">'
943 > echo % errors encountered
943 > echo % errors encountered
944 > cat errors.log
944 > cat errors.log
945 > }
945 > }
946 $ hgserveget euc-jp eucjp.txt
946 $ hgserveget euc-jp eucjp.txt
947 % HGENCODING=euc-jp hg serve
947 % HGENCODING=euc-jp hg serve
948 % hgweb filerevision, html
948 % hgweb filerevision, html
949 % errors encountered
949 % errors encountered
950 $ hgserveget utf-8 eucjp.txt
950 $ hgserveget utf-8 eucjp.txt
951 % HGENCODING=utf-8 hg serve
951 % HGENCODING=utf-8 hg serve
952 % hgweb filerevision, html
952 % hgweb filerevision, html
953 % errors encountered
953 % errors encountered
954 $ hgserveget us-ascii eucjp.txt
954 $ hgserveget us-ascii eucjp.txt
955 % HGENCODING=us-ascii hg serve
955 % HGENCODING=us-ascii hg serve
956 % hgweb filerevision, html
956 % hgweb filerevision, html
957 % errors encountered
957 % errors encountered
958
958
959 We attempt to highlight unknown files by default
959 We attempt to highlight unknown files by default
960
960
961 $ killdaemons.py
961 $ killdaemons.py
962
962
963 $ cat > .hg/hgrc << EOF
963 $ cat > .hg/hgrc << EOF
964 > [web]
964 > [web]
965 > highlightfiles = **
965 > highlightfiles = **
966 > EOF
966 > EOF
967
967
968 $ cat > unknownfile << EOF
968 $ cat > unknownfile << EOF
969 > #!$PYTHON
969 > #!$PYTHON
970 > def foo():
970 > def foo():
971 > pass
971 > pass
972 > EOF
972 > EOF
973
973
974 $ hg add unknownfile
974 $ hg add unknownfile
975 $ hg commit -m unknown unknownfile
975 $ hg commit -m unknown unknownfile
976
976
977 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid
977 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid
978 $ cat hg.pid >> $DAEMON_PIDS
978 $ cat hg.pid >> $DAEMON_PIDS
979
979
980 $ get-with-headers.py localhost:$HGPORT 'file/tip/unknownfile' | grep l2
980 $ get-with-headers.py localhost:$HGPORT 'file/tip/unknownfile' | grep l2
981 <span id="l2"><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span></span><a href="#l2"></a>
981 <span id="l2"><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span></span><a href="#l2"></a>
982
982
983 We can prevent Pygments from falling back to a non filename-based
983 We can prevent Pygments from falling back to a non filename-based
984 detection mode
984 detection mode
985
985
986 $ cat > .hg/hgrc << EOF
986 $ cat > .hg/hgrc << EOF
987 > [web]
987 > [web]
988 > highlightfiles = **
988 > highlightfiles = **
989 > highlightonlymatchfilename = true
989 > highlightonlymatchfilename = true
990 > EOF
990 > EOF
991
991
992 $ killdaemons.py
992 $ killdaemons.py
993 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid
993 $ hg serve -p $HGPORT -d -n test --pid-file=hg.pid
994 $ cat hg.pid >> $DAEMON_PIDS
994 $ cat hg.pid >> $DAEMON_PIDS
995 $ get-with-headers.py localhost:$HGPORT 'file/tip/unknownfile' | grep l2
995 $ get-with-headers.py localhost:$HGPORT 'file/tip/unknownfile' | grep l2
996 <span id="l2">def foo():</span><a href="#l2"></a>
996 <span id="l2">def foo():</span><a href="#l2"></a>
997
997
998 $ cd ..
998 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now