summaryrefslogtreecommitdiff
path: root/src/accordion.js
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
committercashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
commit4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch)
treec296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /src/accordion.js
downloadrelic-master.tar.gz
initial commitHEADmaster
Diffstat (limited to 'src/accordion.js')
-rw-r--r--src/accordion.js89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/accordion.js b/src/accordion.js
new file mode 100644
index 0000000..f40d367
--- /dev/null
+++ b/src/accordion.js
@@ -0,0 +1,89 @@
+/*
+** Attach appropriate javascript to each ".accordion" button so that it expands
+** and contracts when clicked.
+**
+** The uncompressed source code for the SVG icons can be found on the wiki page
+** "branch/accordion-experiments" in the Fossil repository.
+**
+** Implementation notes:
+**
+** The `maxHeight' CSS property is quite restrictive for vertical resizing of
+** elements, especially for dynamic-content areas like the diff panels. That's
+** why `maxHeight' is set only during animation, to prevent truncated elements.
+** (The diff panels may get truncated right after page loading, and other
+** elements may get truncated when resizing the browser window to a smaller
+** width, causing vertical growth.)
+**
+** Another problem is that `scrollHeight' used to calculate the expanded height
+** while still in the contracted state may return values with small errors on
+** some browsers, especially for large elements, presumably due to omitting the
+** space required by the vertical scrollbar that may become necessary, causing
+** additional horizontal shrinking and consequently more vertical growth than
+** calculated. That's why setting `maxHeight' to `scrollHeight' is considered
+** "good enough" only during animation, but cleared afterwards.
+**
+** https://fossil-scm.org/forum/forumpost/66d7075f40
+** https://fossil-scm.org/home/timeline?r=accordion-fix
+**
+** To work around the missing support for `overflow-y: clip', this script uses a
+** fallback and sets `overflow-y: hidden' during the accordion panel animations.
+** That's because if `overflow-y: hidden' is set statically from the stylesheet,
+** the shadow of the selected or current timeline entries in the context section
+** of `/info' pages is still truncated on the right (which is strange, as that's
+** not the "y" direction) in all major browsers. Otherwise, the stylesheet might
+** define the fallback using the `@supports(…)' at-rule:
+**
+** .accordion_panel {
+** overflow-y: hidden;
+** }
+** @supports(overflow-y: clip) {
+** .accordion_panel {
+** overflow-y: clip;
+** }
+** }
+*/
+var acc_svgdata = ["data:image/svg+xml,"+
+ "%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E"+
+ "%3Cpath style='fill:black;opacity:0' d='M16,16H0V0h16v16z'/%3E"+
+ "%3Cpath style='fill:rgb(240,240,240)' d='M14,14H2V2h12v12z'/%3E"+
+ "%3Cpath style='fill:rgb(64,64,64)' d='M13,13H3V3h10v10z'/%3E"+
+ "%3Cpath style='fill:rgb(248,248,248)' d='M12,12H4V4h8v8z'/%3E"+
+ "%3Cpath style='fill:rgb(80,128,208)' d='", "'/%3E%3C/svg%3E",
+ "M5,7h2v-2h2v2h2v2h-2v2h-2v-2h-2z", "M11,9H5V7h6v6z"];
+var a = document.getElementsByClassName("accordion");
+for(var i=0; i<a.length; i++){
+ var img = document.createElement("img");
+ img.src = acc_svgdata[0]+acc_svgdata[2]+acc_svgdata[1];
+ img.className = "accordion_btn accordion_btn_plus";
+ a[i].insertBefore(img,a[i].firstChild);
+ img = document.createElement("img");
+ img.src = acc_svgdata[0]+acc_svgdata[3]+acc_svgdata[1];
+ img.className = "accordion_btn accordion_btn_minus";
+ a[i].insertBefore(img,a[i].firstChild);
+ a[i].addEventListener("click",function(evt){
+ /* Ignore clicks to hyperlinks and other "click-responsive" HTML elements in
+ ** ".accordion" headers (for which Fossil uses <DIV> elements that represent
+ ** section headers). */
+ var xClickyHTML = /^(?:A|AREA|BUTTON|INPUT|LABEL|SELECT|TEXTAREA|DETAILS)$/;
+ if( xClickyHTML.test(evt.target.tagName) ) return;
+ var x = this.nextElementSibling;
+ if( this.classList.contains("accordion_closed") ){
+ x.style.maxHeight = x.scrollHeight + "px";
+ setTimeout(function(){
+ x.style.maxHeight = "";
+ if( !window.CSS || !window.CSS.supports("overflow: clip") ){
+ x.style.overflowY = "";
+ }
+ },250); // default.css: .accordion_panel { transition-duration }
+ }else{
+ x.style.maxHeight = x.scrollHeight + "px";
+ if( !window.CSS || !window.CSS.supports("overflow: clip") ){
+ x.style.overflowY = "hidden";
+ }
+ setTimeout(function(){
+ x.style.maxHeight = "0";
+ },1);
+ }
+ this.classList.toggle("accordion_closed");
+ });
+}