changelog shortlog graph tags branches changeset files file revisions raw help

Mercurial > infra > home / annotate static/followlines.js

changeset 53: d25f982fb8a6
author: Richard Westhaver <ellis@rwest.io>
date: Sat, 20 Jul 2024 22:31:54 -0400
permissions: -rwxr-xr-x
description: init vc
53
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
1
 // followlines.js - JavaScript utilities for followlines UI
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
2
 //
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
3
 // Copyright 2017 Logilab SA <contact@logilab.fr>
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
4
 //
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
5
 // This software may be used and distributed according to the terms of the
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
6
 // GNU General Public License version 2 or any later version.
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
7
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
8
 //** Install event listeners for line block selection and followlines action */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
9
 document.addEventListener('DOMContentLoaded', function() {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
10
     var sourcelines = document.getElementsByClassName('sourcelines')[0];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
11
     if (typeof sourcelines === 'undefined') {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
12
         return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
13
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
14
     // URL to complement with "linerange" query parameter
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
15
     var targetUri = sourcelines.dataset.logurl;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
16
     if (typeof targetUri === 'undefined') {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
17
         return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
18
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
19
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
20
     // Tag of children of "sourcelines" element on which to add "line
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
21
     // selection" style.
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
22
     var selectableTag = sourcelines.dataset.selectabletag;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
23
     if (typeof selectableTag === 'undefined') {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
24
         return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
25
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
26
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
27
     var isHead = parseInt(sourcelines.dataset.ishead || "0");
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
28
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
29
     //* position "element" on top-right of cursor */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
30
     function positionTopRight(element, event) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
31
         var x = (event.clientX + 10) + 'px',
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
32
             y = (event.clientY - 20) + 'px';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
33
         element.style.top = y;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
34
         element.style.left = x;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
35
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
36
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
37
     // retrieve all direct *selectable* children of class="sourcelines"
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
38
     // element
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
39
     var selectableElements = Array.prototype.filter.call(
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
40
         sourcelines.children,
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
41
         function(x) { return x.tagName === selectableTag; });
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
42
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
43
     var btnTitleStart = 'start following lines history from here';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
44
     var btnTitleEnd = 'terminate line block selection here';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
45
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
46
     //** return a <button> element with +/- spans */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
47
     function createButton() {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
48
         var btn = document.createElement('button');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
49
         btn.title = btnTitleStart;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
50
         btn.classList.add('btn-followlines');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
51
         var plusSpan = document.createElement('span');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
52
         plusSpan.classList.add('followlines-plus');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
53
         plusSpan.textContent = '+';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
54
         btn.appendChild(plusSpan);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
55
         var br = document.createElement('br');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
56
         btn.appendChild(br);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
57
         var minusSpan = document.createElement('span');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
58
         minusSpan.classList.add('followlines-minus');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
59
         minusSpan.textContent = '−';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
60
         btn.appendChild(minusSpan);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
61
         return btn;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
62
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
63
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
64
     // extend DOM with CSS class for selection highlight and action buttons
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
65
     var followlinesButtons = [];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
66
     for (var i = 0; i < selectableElements.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
67
         selectableElements[i].classList.add('followlines-select');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
68
         var btn = createButton();
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
69
         followlinesButtons.push(btn);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
70
         // insert the <button> as child of `selectableElements[i]` unless the
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
71
         // latter has itself a child  with a "followlines-btn-parent" class
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
72
         // (annotate view)
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
73
         var btnSupportElm = selectableElements[i];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
74
         var childSupportElms = btnSupportElm.getElementsByClassName(
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
75
             'followlines-btn-parent');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
76
         if ( childSupportElms.length > 0 ) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
77
             btnSupportElm = childSupportElms[0];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
78
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
79
         var refNode = btnSupportElm.childNodes[0]; // node to insert <button> before
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
80
         btnSupportElm.insertBefore(btn, refNode);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
81
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
82
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
83
     // ** re-initialize followlines buttons */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
84
     function resetButtons() {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
85
         for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
86
             var btn = followlinesButtons[i];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
87
             btn.title = btnTitleStart;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
88
             btn.classList.remove('btn-followlines-end');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
89
             btn.classList.remove('btn-followlines-hidden');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
90
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
91
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
92
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
93
     var lineSelectedCSSClass = 'followlines-selected';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
94
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
95
     //** add CSS class on selectable elements in `from`-`to` line range */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
96
     function addSelectedCSSClass(from, to) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
97
         for (var i = from; i <= to; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
98
             selectableElements[i].classList.add(lineSelectedCSSClass);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
99
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
100
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
101
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
102
     //** remove CSS class from previously selected lines */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
103
     function removeSelectedCSSClass() {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
104
         var elements = sourcelines.getElementsByClassName(
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
105
             lineSelectedCSSClass);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
106
         while (elements.length) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
107
             elements[0].classList.remove(lineSelectedCSSClass);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
108
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
109
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
110
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
111
     // ** return the element of type "selectableTag" parent of `element` */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
112
     function selectableParent(element) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
113
         var parent = element.parentElement;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
114
         if (parent === null) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
115
             return null;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
116
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
117
         if (element.tagName === selectableTag && parent.isSameNode(sourcelines)) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
118
             return element;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
119
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
120
         return selectableParent(parent);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
121
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
122
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
123
     // ** update buttons title and style upon first click */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
124
     function updateButtons(selectable) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
125
         for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
126
             var btn = followlinesButtons[i];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
127
             btn.title = btnTitleEnd;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
128
             btn.classList.add('btn-followlines-end');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
129
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
130
         // on clicked button, change title to "cancel"
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
131
         var clicked = selectable.getElementsByClassName('btn-followlines')[0];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
132
         clicked.title = 'cancel';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
133
         clicked.classList.remove('btn-followlines-end');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
134
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
135
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
136
     //** add `listener` on "click" event for all `followlinesButtons` */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
137
     function buttonsAddEventListener(listener) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
138
         for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
139
             followlinesButtons[i].addEventListener('click', listener);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
140
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
141
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
142
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
143
     //** remove `listener` on "click" event for all `followlinesButtons` */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
144
     function buttonsRemoveEventListener(listener) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
145
         for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
146
             followlinesButtons[i].removeEventListener('click', listener);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
147
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
148
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
149
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
150
     //** event handler for "click" on the first line of a block */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
151
     function lineSelectStart(e) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
152
         var startElement = selectableParent(e.target.parentElement);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
153
         if (startElement === null) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
154
             // not a "selectable" element (maybe <a>): abort, keeping event
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
155
             // listener registered for other click with a "selectable" target
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
156
             return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
157
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
158
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
159
         // update button tooltip text and CSS
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
160
         updateButtons(startElement);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
161
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
162
         var startId = parseInt(startElement.id.slice(1));
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
163
         startElement.classList.add(lineSelectedCSSClass); // CSS
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
164
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
165
         // remove this event listener
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
166
         buttonsRemoveEventListener(lineSelectStart);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
167
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
168
         //** event handler for "click" on the last line of the block */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
169
         function lineSelectEnd(e) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
170
             var endElement = selectableParent(e.target.parentElement);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
171
             if (endElement === null) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
172
                 // not a <span> (maybe <a>): abort, keeping event listener
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
173
                 // registered for other click with <span> target
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
174
                 return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
175
             }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
176
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
177
             // remove this event listener
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
178
             buttonsRemoveEventListener(lineSelectEnd);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
179
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
180
             // reset button tooltip text
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
181
             resetButtons();
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
182
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
183
             // compute line range (startId, endId)
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
184
             var endId = parseInt(endElement.id.slice(1));
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
185
             if (endId === startId) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
186
                 // clicked twice the same line, cancel and reset initial state
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
187
                 // (CSS, event listener for selection start)
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
188
                 removeSelectedCSSClass();
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
189
                 buttonsAddEventListener(lineSelectStart);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
190
                 return;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
191
             }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
192
             var inviteElement = endElement;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
193
             if (endId < startId) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
194
                 var tmp = endId;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
195
                 endId = startId;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
196
                 startId = tmp;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
197
                 inviteElement = startElement;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
198
             }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
199
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
200
             addSelectedCSSClass(startId - 1, endId -1);  // CSS
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
201
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
202
             // append the <div id="followlines"> element to last line of the
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
203
             // selection block
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
204
             var divAndButton = followlinesBox(targetUri, startId, endId, isHead);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
205
             var div = divAndButton[0],
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
206
                 button = divAndButton[1];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
207
             inviteElement.appendChild(div);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
208
             // set position close to cursor (top-right)
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
209
             positionTopRight(div, e);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
210
             // hide all buttons
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
211
             for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
212
                 followlinesButtons[i].classList.add('btn-followlines-hidden');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
213
             }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
214
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
215
             //** event handler for cancelling selection */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
216
             function cancel() {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
217
                 // remove invite box
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
218
                 div.parentNode.removeChild(div);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
219
                 // restore initial event listeners
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
220
                 buttonsAddEventListener(lineSelectStart);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
221
                 buttonsRemoveEventListener(cancel);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
222
                 for (var i = 0; i < followlinesButtons.length; i++) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
223
                     followlinesButtons[i].classList.remove('btn-followlines-hidden');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
224
                 }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
225
                 // remove styles on selected lines
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
226
                 removeSelectedCSSClass();
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
227
                 resetButtons();
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
228
             }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
229
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
230
             // bind cancel event to click on <button>
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
231
             button.addEventListener('click', cancel);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
232
             // as well as on an click on any source line
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
233
             buttonsAddEventListener(cancel);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
234
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
235
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
236
         buttonsAddEventListener(lineSelectEnd);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
237
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
238
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
239
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
240
     buttonsAddEventListener(lineSelectStart);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
241
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
242
     //** return a <div id="followlines"> and inner cancel <button> elements */
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
243
     function followlinesBox(targetUri, fromline, toline, isHead) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
244
         // <div id="followlines">
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
245
         var div = document.createElement('div');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
246
         div.id = 'followlines';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
247
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
248
         //   <div class="followlines-cancel">
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
249
         var buttonDiv = document.createElement('div');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
250
         buttonDiv.classList.add('followlines-cancel');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
251
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
252
         //     <button>x</button>
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
253
         var button = document.createElement('button');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
254
         button.textContent = 'x';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
255
         buttonDiv.appendChild(button);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
256
         div.appendChild(buttonDiv);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
257
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
258
         //   <div class="followlines-link">
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
259
         var aDiv = document.createElement('div');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
260
         aDiv.classList.add('followlines-link');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
261
         aDiv.textContent = 'follow history of lines ' + fromline + ':' + toline + ':';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
262
         var linesep = document.createElement('br');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
263
         aDiv.appendChild(linesep);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
264
         //     link to "ascending" followlines
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
265
         var aAsc = document.createElement('a');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
266
         var url = targetUri + '?patch=&linerange=' + fromline + ':' + toline;
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
267
         aAsc.setAttribute('href', url);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
268
         aAsc.textContent = 'older';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
269
         aDiv.appendChild(aAsc);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
270
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
271
         if (!isHead) {
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
272
             var sep = document.createTextNode(' / ');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
273
             aDiv.appendChild(sep);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
274
             //     link to "descending" followlines
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
275
             var aDesc = document.createElement('a');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
276
             aDesc.setAttribute('href', url + '&descend=');
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
277
             aDesc.textContent = 'newer';
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
278
             aDiv.appendChild(aDesc);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
279
         }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
280
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
281
         div.appendChild(aDiv);
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
282
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
283
         return [div, button];
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
284
     }
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
285
 
d25f982fb8a6 init vc
Richard Westhaver <ellis@rwest.io>
parents:
diff changeset
286
 }, false);