##// END OF EJS Templates
hgweb: re-implement followlines UI selection using buttons...
Denis Laxalde -
r33390:32331f54 default
parent child Browse files
Show More
@@ -113,7 +113,7 b" annotateline = '"
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 = '
@@ -94,7 +94,7 b" annotateline = '"
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>'
@@ -26,14 +26,6 b" document.addEventListener('DOMContentLoa"
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',
@@ -42,32 +34,60 b" document.addEventListener('DOMContentLoa"
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';
@@ -100,27 +120,54 b" document.addEventListener('DOMContentLoa"
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
@@ -128,27 +175,18 b" document.addEventListener('DOMContentLoa"
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;
@@ -169,31 +207,37 b" document.addEventListener('DOMContentLoa"
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) {
@@ -86,6 +86,7 b' 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;
@@ -152,7 +153,7 b' pre.sourcelines > span:before {'
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;
@@ -177,11 +178,6 b' pre.sourcelines.stripes > span:target {'
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;
@@ -219,21 +215,62 b' div.followlines-link {'
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;
@@ -214,6 +214,7 b' 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;
@@ -267,7 +268,7 b' td.annotate:hover div.annotate-info { di'
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;
@@ -280,11 +281,7 b' td.annotate:hover div.annotate-info { di'
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;
@@ -322,19 +319,59 b' div.followlines-link {'
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
@@ -340,7 +340,7 b' 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; }
@@ -431,6 +431,7 b' static file'
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;
@@ -497,7 +498,7 b' static file'
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;
@@ -522,11 +523,6 b' static file'
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;
@@ -564,21 +560,62 b' static file'
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;
@@ -314,7 +314,7 b' hgweb fileannotate, html'
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">
@@ -331,7 +331,7 b' hgweb fileannotate, html'
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">
@@ -348,7 +348,7 b' hgweb fileannotate, html'
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">
@@ -365,7 +365,7 b' hgweb fileannotate, html'
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">
@@ -382,7 +382,7 b' hgweb fileannotate, html'
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">
@@ -399,7 +399,7 b' hgweb fileannotate, html'
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">
@@ -416,7 +416,7 b' hgweb fileannotate, html'
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">
@@ -433,7 +433,7 b' hgweb fileannotate, html'
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">
@@ -450,7 +450,7 b' hgweb fileannotate, html'
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">
@@ -467,7 +467,7 b' hgweb fileannotate, html'
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">
@@ -484,7 +484,7 b' hgweb fileannotate, html'
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">
@@ -501,7 +501,7 b' hgweb fileannotate, html'
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">
@@ -518,7 +518,7 b' hgweb fileannotate, html'
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">
@@ -535,7 +535,7 b' hgweb fileannotate, html'
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">
@@ -552,7 +552,7 b' hgweb fileannotate, html'
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">
@@ -569,7 +569,7 b' hgweb fileannotate, html'
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">
@@ -586,7 +586,7 b' hgweb fileannotate, html'
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">
@@ -603,7 +603,7 b' hgweb fileannotate, html'
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">
@@ -620,7 +620,7 b' hgweb fileannotate, html'
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">
@@ -637,7 +637,7 b' hgweb fileannotate, html'
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">
@@ -654,7 +654,7 b' hgweb fileannotate, html'
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">
@@ -671,7 +671,7 b' hgweb fileannotate, html'
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">
@@ -688,7 +688,7 b' hgweb fileannotate, html'
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">
@@ -705,7 +705,7 b' hgweb fileannotate, html'
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">
@@ -722,7 +722,7 b' hgweb fileannotate, html'
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">
@@ -739,7 +739,7 b' hgweb fileannotate, html'
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">
@@ -756,7 +756,7 b' hgweb fileannotate, html'
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">
@@ -773,7 +773,7 b' hgweb fileannotate, html'
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">
@@ -790,7 +790,7 b' hgweb fileannotate, html'
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">
@@ -807,7 +807,7 b' hgweb fileannotate, html'
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">
@@ -824,7 +824,7 b' hgweb fileannotate, html'
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>
General Comments 0
You need to be logged in to leave comments. Login now