##// END OF EJS Templates
hgweb: add a floating tooltip to invite on followlines action...
Denis Laxalde -
r31848:7160bdd5 default
parent child Browse files
Show More
@@ -1,166 +1,212
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 // tooltip to invite on lines selection
21 var tooltip = document.createElement('div');
22 tooltip.id = 'followlines-tooltip';
23 tooltip.classList.add('hidden');
24 var initTooltipText = 'click to start following lines history from here';
25 tooltip.textContent = initTooltipText;
26 sourcelines.appendChild(tooltip);
27
28 var tooltipTimeoutID;
29 //* move the "tooltip" with cursor (top-right) and show it after 1s */
30 function moveAndShowTooltip(e) {
31 if (typeof tooltipTimeoutID !== 'undefined') {
32 // avoid accumulation of timeout callbacks (blinking)
33 window.clearTimeout(tooltipTimeoutID);
34 }
35 tooltip.classList.add('hidden');
36 var x = (e.clientX + 10) + 'px',
37 y = (e.clientY - 20) + 'px';
38 tooltip.style.top = y;
39 tooltip.style.left = x;
40 tooltipTimeoutID = window.setTimeout(function() {
41 tooltip.classList.remove('hidden');
42 }, 1000);
43 }
44
45 // on mousemove, show tooltip close to cursor position
46 sourcelines.addEventListener('mousemove', moveAndShowTooltip);
47
20 // retrieve all direct <span> children of <pre class="sourcelines">
48 // retrieve all direct <span> children of <pre class="sourcelines">
21 var spans = Array.prototype.filter.call(
49 var spans = Array.prototype.filter.call(
22 sourcelines.children,
50 sourcelines.children,
23 function(x) { return x.tagName === 'SPAN' });
51 function(x) { return x.tagName === 'SPAN' });
24
52
25 // add a "followlines-select" class to change cursor type in CSS
53 // add a "followlines-select" class to change cursor type in CSS
26 for (var i = 0; i < spans.length; i++) {
54 for (var i = 0; i < spans.length; i++) {
27 spans[i].classList.add('followlines-select');
55 spans[i].classList.add('followlines-select');
28 }
56 }
29
57
30 var lineSelectedCSSClass = 'followlines-selected';
58 var lineSelectedCSSClass = 'followlines-selected';
31
59
32 //** add CSS class on <span> element in `from`-`to` line range */
60 //** add CSS class on <span> element in `from`-`to` line range */
33 function addSelectedCSSClass(from, to) {
61 function addSelectedCSSClass(from, to) {
34 for (var i = from; i <= to; i++) {
62 for (var i = from; i <= to; i++) {
35 spans[i].classList.add(lineSelectedCSSClass);
63 spans[i].classList.add(lineSelectedCSSClass);
36 }
64 }
37 }
65 }
38
66
39 //** remove CSS class from previously selected lines */
67 //** remove CSS class from previously selected lines */
40 function removeSelectedCSSClass() {
68 function removeSelectedCSSClass() {
41 var elements = sourcelines.getElementsByClassName(
69 var elements = sourcelines.getElementsByClassName(
42 lineSelectedCSSClass);
70 lineSelectedCSSClass);
43 while (elements.length) {
71 while (elements.length) {
44 elements[0].classList.remove(lineSelectedCSSClass);
72 elements[0].classList.remove(lineSelectedCSSClass);
45 }
73 }
46 }
74 }
47
75
48 // ** return the <span> element parent of `element` */
76 // ** return the <span> element parent of `element` */
49 function findParentSpan(element) {
77 function findParentSpan(element) {
50 var parent = element.parentElement;
78 var parent = element.parentElement;
51 if (parent === null) {
79 if (parent === null) {
52 return null;
80 return null;
53 }
81 }
54 if (element.tagName == 'SPAN' && parent.isSameNode(sourcelines)) {
82 if (element.tagName == 'SPAN' && parent.isSameNode(sourcelines)) {
55 return element;
83 return element;
56 }
84 }
57 return findParentSpan(parent);
85 return findParentSpan(parent);
58 }
86 }
59
87
60 //** event handler for "click" on the first line of a block */
88 //** event handler for "click" on the first line of a block */
61 function lineSelectStart(e) {
89 function lineSelectStart(e) {
62 var startElement = findParentSpan(e.target);
90 var startElement = findParentSpan(e.target);
63 if (startElement === null) {
91 if (startElement === null) {
64 // not a <span> (maybe <a>): abort, keeping event listener
92 // not a <span> (maybe <a>): abort, keeping event listener
65 // registered for other click with <span> target
93 // registered for other click with <span> target
66 return;
94 return;
67 }
95 }
96
97 // update tooltip text
98 tooltip.textContent = 'click again to terminate line block selection here';
99
68 var startId = parseInt(startElement.id.slice(1));
100 var startId = parseInt(startElement.id.slice(1));
69 startElement.classList.add(lineSelectedCSSClass); // CSS
101 startElement.classList.add(lineSelectedCSSClass); // CSS
70
102
71 // remove this event listener
103 // remove this event listener
72 sourcelines.removeEventListener('click', lineSelectStart);
104 sourcelines.removeEventListener('click', lineSelectStart);
73
105
74 //** event handler for "click" on the last line of the block */
106 //** event handler for "click" on the last line of the block */
75 function lineSelectEnd(e) {
107 function lineSelectEnd(e) {
76 var endElement = findParentSpan(e.target);
108 var endElement = findParentSpan(e.target);
77 if (endElement === null) {
109 if (endElement === null) {
78 // not a <span> (maybe <a>): abort, keeping event listener
110 // not a <span> (maybe <a>): abort, keeping event listener
79 // registered for other click with <span> target
111 // registered for other click with <span> target
80 return;
112 return;
81 }
113 }
82
114
83 // remove this event listener
115 // remove this event listener
84 sourcelines.removeEventListener('click', lineSelectEnd);
116 sourcelines.removeEventListener('click', lineSelectEnd);
85
117
118 // hide tooltip and disable motion tracking
119 tooltip.classList.add('hidden');
120 sourcelines.removeEventListener('mousemove', moveAndShowTooltip);
121 window.clearTimeout(tooltipTimeoutID);
122
123 //* restore initial "tooltip" state */
124 function restoreTooltip() {
125 tooltip.textContent = initTooltipText;
126 sourcelines.addEventListener('mousemove', moveAndShowTooltip);
127 }
128
86 // compute line range (startId, endId)
129 // compute line range (startId, endId)
87 var endId = parseInt(endElement.id.slice(1));
130 var endId = parseInt(endElement.id.slice(1));
88 if (endId == startId) {
131 if (endId == startId) {
89 // clicked twice the same line, cancel and reset initial state
132 // clicked twice the same line, cancel and reset initial state
90 // (CSS and event listener for selection start)
133 // (CSS, event listener for selection start, tooltip)
91 removeSelectedCSSClass();
134 removeSelectedCSSClass();
92 sourcelines.addEventListener('click', lineSelectStart);
135 sourcelines.addEventListener('click', lineSelectStart);
136 restoreTooltip();
93 return;
137 return;
94 }
138 }
95 var inviteElement = endElement;
139 var inviteElement = endElement;
96 if (endId < startId) {
140 if (endId < startId) {
97 var tmp = endId;
141 var tmp = endId;
98 endId = startId;
142 endId = startId;
99 startId = tmp;
143 startId = tmp;
100 inviteElement = startElement;
144 inviteElement = startElement;
101 }
145 }
102
146
103 addSelectedCSSClass(startId - 1, endId -1); // CSS
147 addSelectedCSSClass(startId - 1, endId -1); // CSS
104
148
105 // append the <div id="followlines"> element to last line of the
149 // append the <div id="followlines"> element to last line of the
106 // selection block
150 // selection block
107 var divAndButton = followlinesBox(targetUri, startId, endId);
151 var divAndButton = followlinesBox(targetUri, startId, endId);
108 var div = divAndButton[0],
152 var div = divAndButton[0],
109 button = divAndButton[1];
153 button = divAndButton[1];
110 inviteElement.appendChild(div);
154 inviteElement.appendChild(div);
111
155
112 //** event handler for cancelling selection */
156 //** event handler for cancelling selection */
113 function cancel() {
157 function cancel() {
114 // remove invite box
158 // remove invite box
115 div.parentNode.removeChild(div);
159 div.parentNode.removeChild(div);
116 // restore initial event listeners
160 // restore initial event listeners
117 sourcelines.addEventListener('click', lineSelectStart);
161 sourcelines.addEventListener('click', lineSelectStart);
118 sourcelines.removeEventListener('click', cancel);
162 sourcelines.removeEventListener('click', cancel);
119 // remove styles on selected lines
163 // remove styles on selected lines
120 removeSelectedCSSClass();
164 removeSelectedCSSClass();
165 // restore tooltip element
166 restoreTooltip();
121 }
167 }
122
168
123 // bind cancel event to click on <button>
169 // bind cancel event to click on <button>
124 button.addEventListener('click', cancel);
170 button.addEventListener('click', cancel);
125 // as well as on an click on any source line
171 // as well as on an click on any source line
126 sourcelines.addEventListener('click', cancel);
172 sourcelines.addEventListener('click', cancel);
127 }
173 }
128
174
129 sourcelines.addEventListener('click', lineSelectEnd);
175 sourcelines.addEventListener('click', lineSelectEnd);
130
176
131 }
177 }
132
178
133 sourcelines.addEventListener('click', lineSelectStart);
179 sourcelines.addEventListener('click', lineSelectStart);
134
180
135 //** return a <div id="followlines"> and inner cancel <button> elements */
181 //** return a <div id="followlines"> and inner cancel <button> elements */
136 function followlinesBox(targetUri, fromline, toline) {
182 function followlinesBox(targetUri, fromline, toline) {
137 // <div id="followlines">
183 // <div id="followlines">
138 var div = document.createElement('div');
184 var div = document.createElement('div');
139 div.id = 'followlines';
185 div.id = 'followlines';
140
186
141 // <div class="followlines-cancel">
187 // <div class="followlines-cancel">
142 var buttonDiv = document.createElement('div');
188 var buttonDiv = document.createElement('div');
143 buttonDiv.classList.add('followlines-cancel');
189 buttonDiv.classList.add('followlines-cancel');
144
190
145 // <button>x</button>
191 // <button>x</button>
146 var button = document.createElement('button');
192 var button = document.createElement('button');
147 button.textContent = 'x';
193 button.textContent = 'x';
148 buttonDiv.appendChild(button);
194 buttonDiv.appendChild(button);
149 div.appendChild(buttonDiv);
195 div.appendChild(buttonDiv);
150
196
151 // <div class="followlines-link">
197 // <div class="followlines-link">
152 var aDiv = document.createElement('div');
198 var aDiv = document.createElement('div');
153 aDiv.classList.add('followlines-link');
199 aDiv.classList.add('followlines-link');
154
200
155 // <a href="/log/<rev>/<file>?patch=&linerange=...">
201 // <a href="/log/<rev>/<file>?patch=&linerange=...">
156 var a = document.createElement('a');
202 var a = document.createElement('a');
157 var url = targetUri + '?patch=&linerange=' + fromline + ':' + toline;
203 var url = targetUri + '?patch=&linerange=' + fromline + ':' + toline;
158 a.setAttribute('href', url);
204 a.setAttribute('href', url);
159 a.textContent = 'follow lines ' + fromline + ':' + toline;
205 a.textContent = 'follow lines ' + fromline + ':' + toline;
160 aDiv.appendChild(a);
206 aDiv.appendChild(a);
161 div.appendChild(aDiv);
207 div.appendChild(aDiv);
162
208
163 return [div, button];
209 return [div, button];
164 }
210 }
165
211
166 }, false);
212 }, false);
@@ -1,471 +1,487
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 display: none;
217 display: none;
218 position: absolute;
218 position: absolute;
219 background-color: #FFFFFF;
219 background-color: #FFFFFF;
220 border: 1px solid #999;
220 border: 1px solid #999;
221 text-align: left;
221 text-align: left;
222 color: #000000;
222 color: #000000;
223 padding: 5px;
223 padding: 5px;
224 }
224 }
225 div.annotate-info a { color: #0000FF; }
225 div.annotate-info a { color: #0000FF; }
226 td.annotate:hover div.annotate-info { display: inline; }
226 td.annotate:hover div.annotate-info { display: inline; }
227
227
228 .source, .sourcefirst {
228 .source, .sourcefirst {
229 font-family: monospace;
229 font-family: monospace;
230 white-space: pre;
230 white-space: pre;
231 padding: 1px 4px;
231 padding: 1px 4px;
232 font-size: 90%;
232 font-size: 90%;
233 }
233 }
234 .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
234 .sourcefirst { border-bottom: 1px solid #999; font-weight: bold; }
235 .source a { color: #999; font-size: smaller; font-family: monospace;}
235 .source a { color: #999; font-size: smaller; font-family: monospace;}
236 .bottomline { border-bottom: 1px solid #999; }
236 .bottomline { border-bottom: 1px solid #999; }
237
237
238 .sourcelines {
238 .sourcelines {
239 font-size: 90%;
239 font-size: 90%;
240 position: relative;
240 position: relative;
241 counter-reset: lineno;
241 counter-reset: lineno;
242 }
242 }
243
243
244 .wrap > span {
244 .wrap > span {
245 white-space: pre-wrap;
245 white-space: pre-wrap;
246 }
246 }
247
247
248 .linewraptoggle {
248 .linewraptoggle {
249 float: right;
249 float: right;
250 }
250 }
251
251
252 .diffblocks { counter-reset: lineno; }
252 .diffblocks { counter-reset: lineno; }
253 .diffblocks > div { counter-increment: lineno; }
253 .diffblocks > div { counter-increment: lineno; }
254
254
255 .sourcelines > span {
255 .sourcelines > span {
256 display: inline-block;
256 display: inline-block;
257 box-sizing: border-box;
257 box-sizing: border-box;
258 width: 100%;
258 width: 100%;
259 padding: 1px 0px 1px 5em;
259 padding: 1px 0px 1px 5em;
260 counter-increment: lineno;
260 counter-increment: lineno;
261 }
261 }
262
262
263 .sourcelines > span:before {
263 .sourcelines > span:before {
264 -moz-user-select: -moz-none;
264 -moz-user-select: -moz-none;
265 -khtml-user-select: none;
265 -khtml-user-select: none;
266 -webkit-user-select: none;
266 -webkit-user-select: none;
267 -ms-user-select: none;
267 -ms-user-select: none;
268 user-select: none;
268 user-select: none;
269 display: inline-block;
269 display: inline-block;
270 margin-left: -5em;
270 margin-left: -5em;
271 width: 4em;
271 width: 4em;
272 font-size: smaller;
272 font-size: smaller;
273 color: #999;
273 color: #999;
274 text-align: right;
274 text-align: right;
275 content: counters(lineno, ".");
275 content: counters(lineno, ".");
276 float: left;
276 float: left;
277 }
277 }
278
278
279 .sourcelines > span:target, tr:target td {
279 .sourcelines > span:target, tr:target td {
280 background-color: #bfdfff;
280 background-color: #bfdfff;
281 }
281 }
282
282
283 div.overflow pre.sourcelines > span.followlines-select:hover {
283 div.overflow pre.sourcelines > span.followlines-select:hover {
284 cursor: cell;
284 cursor: cell;
285 }
285 }
286
286
287 pre.sourcelines > span.followlines-selected {
287 pre.sourcelines > span.followlines-selected {
288 background-color: #99C7E9;
288 background-color: #99C7E9;
289 }
289 }
290
290
291 div#followlines {
291 div#followlines {
292 background-color: #B7B7B7;
292 background-color: #B7B7B7;
293 border: 1px solid #CCC;
293 border: 1px solid #CCC;
294 border-radius: 5px;
294 border-radius: 5px;
295 padding: 4px;
295 padding: 4px;
296 position: absolute;
296 position: absolute;
297 }
297 }
298
298
299 div.followlines-cancel {
299 div.followlines-cancel {
300 text-align: right;
300 text-align: right;
301 }
301 }
302
302
303 div.followlines-cancel > button {
303 div.followlines-cancel > button {
304 line-height: 80%;
304 line-height: 80%;
305 padding: 0;
305 padding: 0;
306 border: 0;
306 border: 0;
307 border-radius: 2px;
307 border-radius: 2px;
308 background-color: inherit;
308 background-color: inherit;
309 font-weight: bold;
309 font-weight: bold;
310 }
310 }
311
311
312 div.followlines-cancel > button:hover {
312 div.followlines-cancel > button:hover {
313 color: #FFFFFF;
313 color: #FFFFFF;
314 background-color: #CF1F1F;
314 background-color: #CF1F1F;
315 }
315 }
316
316
317 div.followlines-link {
317 div.followlines-link {
318 margin: 2px;
318 margin: 2px;
319 margin-top: 4px;
319 margin-top: 4px;
320 font-family: sans-serif;
320 font-family: sans-serif;
321 }
321 }
322
322
323 div#followlines-tooltip {
324 display: none;
325 position: fixed;
326 background-color: #ffc;
327 border: 1px solid #999;
328 padding: 2px;
329 }
330
331 .sourcelines:hover > div#followlines-tooltip {
332 display: inline;
333 }
334
335 .sourcelines:hover > div#followlines-tooltip.hidden {
336 display: none;
337 }
338
323 .sourcelines > a {
339 .sourcelines > a {
324 display: inline-block;
340 display: inline-block;
325 position: absolute;
341 position: absolute;
326 left: 0px;
342 left: 0px;
327 width: 4em;
343 width: 4em;
328 height: 1em;
344 height: 1em;
329 }
345 }
330
346
331 .fileline { font-family: monospace; }
347 .fileline { font-family: monospace; }
332 .fileline img { border: 0; }
348 .fileline img { border: 0; }
333
349
334 .tagEntry .closed { color: #99f; }
350 .tagEntry .closed { color: #99f; }
335
351
336 /* Changeset entry */
352 /* Changeset entry */
337 #changesetEntry {
353 #changesetEntry {
338 border-collapse: collapse;
354 border-collapse: collapse;
339 font-size: 90%;
355 font-size: 90%;
340 width: 100%;
356 width: 100%;
341 margin-bottom: 1em;
357 margin-bottom: 1em;
342 }
358 }
343
359
344 #changesetEntry th {
360 #changesetEntry th {
345 padding: 1px 4px;
361 padding: 1px 4px;
346 width: 4em;
362 width: 4em;
347 text-align: right;
363 text-align: right;
348 font-weight: normal;
364 font-weight: normal;
349 color: #999;
365 color: #999;
350 margin-right: .5em;
366 margin-right: .5em;
351 vertical-align: top;
367 vertical-align: top;
352 }
368 }
353
369
354 div.description {
370 div.description {
355 border-left: 2px solid #999;
371 border-left: 2px solid #999;
356 margin: 1em 0 1em 0;
372 margin: 1em 0 1em 0;
357 padding: .3em;
373 padding: .3em;
358 white-space: pre;
374 white-space: pre;
359 font-family: monospace;
375 font-family: monospace;
360 }
376 }
361
377
362 /* Graph */
378 /* Graph */
363 div#wrapper {
379 div#wrapper {
364 position: relative;
380 position: relative;
365 border-top: 1px solid black;
381 border-top: 1px solid black;
366 border-bottom: 1px solid black;
382 border-bottom: 1px solid black;
367 margin: 0;
383 margin: 0;
368 padding: 0;
384 padding: 0;
369 }
385 }
370
386
371 canvas {
387 canvas {
372 position: absolute;
388 position: absolute;
373 z-index: 5;
389 z-index: 5;
374 top: -0.7em;
390 top: -0.7em;
375 margin: 0;
391 margin: 0;
376 }
392 }
377
393
378 ul#graphnodes {
394 ul#graphnodes {
379 position: absolute;
395 position: absolute;
380 z-index: 10;
396 z-index: 10;
381 top: -1.0em;
397 top: -1.0em;
382 list-style: none inside none;
398 list-style: none inside none;
383 padding: 0;
399 padding: 0;
384 }
400 }
385
401
386 ul#nodebgs {
402 ul#nodebgs {
387 list-style: none inside none;
403 list-style: none inside none;
388 padding: 0;
404 padding: 0;
389 margin: 0;
405 margin: 0;
390 top: -0.7em;
406 top: -0.7em;
391 }
407 }
392
408
393 ul#graphnodes li, ul#nodebgs li {
409 ul#graphnodes li, ul#nodebgs li {
394 height: 39px;
410 height: 39px;
395 }
411 }
396
412
397 ul#graphnodes li .info {
413 ul#graphnodes li .info {
398 display: block;
414 display: block;
399 font-size: 70%;
415 font-size: 70%;
400 position: relative;
416 position: relative;
401 top: -3px;
417 top: -3px;
402 }
418 }
403
419
404 /* Comparison */
420 /* Comparison */
405 .legend {
421 .legend {
406 padding: 1.5% 0 1.5% 0;
422 padding: 1.5% 0 1.5% 0;
407 }
423 }
408
424
409 .legendinfo {
425 .legendinfo {
410 border: 1px solid #999;
426 border: 1px solid #999;
411 font-size: 80%;
427 font-size: 80%;
412 text-align: center;
428 text-align: center;
413 padding: 0.5%;
429 padding: 0.5%;
414 }
430 }
415
431
416 .equal {
432 .equal {
417 background-color: #ffffff;
433 background-color: #ffffff;
418 }
434 }
419
435
420 .delete {
436 .delete {
421 background-color: #faa;
437 background-color: #faa;
422 color: #333;
438 color: #333;
423 }
439 }
424
440
425 .insert {
441 .insert {
426 background-color: #ffa;
442 background-color: #ffa;
427 }
443 }
428
444
429 .replace {
445 .replace {
430 background-color: #e8e8e8;
446 background-color: #e8e8e8;
431 }
447 }
432
448
433 .header {
449 .header {
434 text-align: center;
450 text-align: center;
435 }
451 }
436
452
437 .block {
453 .block {
438 border-top: 1px solid #999;
454 border-top: 1px solid #999;
439 }
455 }
440
456
441 .breadcrumb {
457 .breadcrumb {
442 color: gray;
458 color: gray;
443 }
459 }
444
460
445 .breadcrumb a {
461 .breadcrumb a {
446 color: blue;
462 color: blue;
447 }
463 }
448
464
449 .scroll-loading {
465 .scroll-loading {
450 -webkit-animation: change_color 1s linear 0s infinite alternate;
466 -webkit-animation: change_color 1s linear 0s infinite alternate;
451 -moz-animation: change_color 1s linear 0s infinite alternate;
467 -moz-animation: change_color 1s linear 0s infinite alternate;
452 -o-animation: change_color 1s linear 0s infinite alternate;
468 -o-animation: change_color 1s linear 0s infinite alternate;
453 animation: change_color 1s linear 0s infinite alternate;
469 animation: change_color 1s linear 0s infinite alternate;
454 }
470 }
455
471
456 @-webkit-keyframes change_color {
472 @-webkit-keyframes change_color {
457 from { background-color: #A0CEFF; } to { }
473 from { background-color: #A0CEFF; } to { }
458 }
474 }
459 @-moz-keyframes change_color {
475 @-moz-keyframes change_color {
460 from { background-color: #A0CEFF; } to { }
476 from { background-color: #A0CEFF; } to { }
461 }
477 }
462 @-o-keyframes change_color {
478 @-o-keyframes change_color {
463 from { background-color: #A0CEFF; } to { }
479 from { background-color: #A0CEFF; } to { }
464 }
480 }
465 @keyframes change_color {
481 @keyframes change_color {
466 from { background-color: #A0CEFF; } to { }
482 from { background-color: #A0CEFF; } to { }
467 }
483 }
468
484
469 .scroll-loading-error {
485 .scroll-loading-error {
470 background-color: #FFCCCC !important;
486 background-color: #FFCCCC !important;
471 }
487 }
General Comments 0
You need to be logged in to leave comments. Login now