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