|
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
|
|