Fossil SCM

fossil-scm / src / accordion.js
Blame History Raw 90 lines
1
/*
2
** Attach appropriate javascript to each ".accordion" button so that it expands
3
** and contracts when clicked.
4
**
5
** The uncompressed source code for the SVG icons can be found on the wiki page
6
** "branch/accordion-experiments" in the Fossil repository.
7
**
8
** Implementation notes:
9
**
10
** The `maxHeight' CSS property is quite restrictive for vertical resizing of
11
** elements, especially for dynamic-content areas like the diff panels. That's
12
** why `maxHeight' is set only during animation, to prevent truncated elements.
13
** (The diff panels may get truncated right after page loading, and other
14
** elements may get truncated when resizing the browser window to a smaller
15
** width, causing vertical growth.)
16
**
17
** Another problem is that `scrollHeight' used to calculate the expanded height
18
** while still in the contracted state may return values with small errors on
19
** some browsers, especially for large elements, presumably due to omitting the
20
** space required by the vertical scrollbar that may become necessary, causing
21
** additional horizontal shrinking and consequently more vertical growth than
22
** calculated. That's why setting `maxHeight' to `scrollHeight' is considered
23
** "good enough" only during animation, but cleared afterwards.
24
**
25
** https://fossil-scm.org/forum/forumpost/66d7075f40
26
** https://fossil-scm.org/home/timeline?r=accordion-fix
27
**
28
** To work around the missing support for `overflow-y: clip', this script uses a
29
** fallback and sets `overflow-y: hidden' during the accordion panel animations.
30
** That's because if `overflow-y: hidden' is set statically from the stylesheet,
31
** the shadow of the selected or current timeline entries in the context section
32
** of `/info' pages is still truncated on the right (which is strange, as that's
33
** not the "y" direction) in all major browsers. Otherwise, the stylesheet might
34
** define the fallback using the `@supports(…)' at-rule:
35
**
36
** .accordion_panel {
37
** overflow-y: hidden;
38
** }
39
** @supports(overflow-y: clip) {
40
** .accordion_panel {
41
** overflow-y: clip;
42
** }
43
** }
44
*/
45
var acc_svgdata = ["data:image/svg+xml,"+
46
"%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E"+
47
"%3Cpath style='fill:black;opacity:0' d='M16,16H0V0h16v16z'/%3E"+
48
"%3Cpath style='fill:rgb(240,240,240)' d='M14,14H2V2h12v12z'/%3E"+
49
"%3Cpath style='fill:rgb(64,64,64)' d='M13,13H3V3h10v10z'/%3E"+
50
"%3Cpath style='fill:rgb(248,248,248)' d='M12,12H4V4h8v8z'/%3E"+
51
"%3Cpath style='fill:rgb(80,128,208)' d='", "'/%3E%3C/svg%3E",
52
"M5,7h2v-2h2v2h2v2h-2v2h-2v-2h-2z", "M11,9H5V7h6v6z"];
53
var a = document.getElementsByClassName("accordion");
54
for(var i=0; i<a.length; i++){
55
var img = document.createElement("img");
56
img.src = acc_svgdata[0]+acc_svgdata[2]+acc_svgdata[1];
57
img.className = "accordion_btn accordion_btn_plus";
58
a[i].insertBefore(img,a[i].firstChild);
59
img = document.createElement("img");
60
img.src = acc_svgdata[0]+acc_svgdata[3]+acc_svgdata[1];
61
img.className = "accordion_btn accordion_btn_minus";
62
a[i].insertBefore(img,a[i].firstChild);
63
a[i].addEventListener("click",function(evt){
64
/* Ignore clicks to hyperlinks and other "click-responsive" HTML elements in
65
** ".accordion" headers (for which Fossil uses <DIV> elements that represent
66
** section headers). */
67
var xClickyHTML = /^(?:A|AREA|BUTTON|INPUT|LABEL|SELECT|TEXTAREA|DETAILS)$/;
68
if( xClickyHTML.test(evt.target.tagName) ) return;
69
var x = this.nextElementSibling;
70
if( this.classList.contains("accordion_closed") ){
71
x.style.maxHeight = x.scrollHeight + "px";
72
setTimeout(function(){
73
x.style.maxHeight = "";
74
if( !window.CSS || !window.CSS.supports("overflow: clip") ){
75
x.style.overflowY = "";
76
}
77
},250); // default.css: .accordion_panel { transition-duration }
78
}else{
79
x.style.maxHeight = x.scrollHeight + "px";
80
if( !window.CSS || !window.CSS.supports("overflow: clip") ){
81
x.style.overflowY = "hidden";
82
}
83
setTimeout(function(){
84
x.style.maxHeight = "0";
85
},1);
86
}
87
this.classList.toggle("accordion_closed");
88
});
89
}
90

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button