1/* 2 * boxFit.js, my own "masonry" code to try to compress the vertical space taken up by "extra" images (watermarks, 3 * embossing, other detail edits, etc). It does this in a pretty brute-force way: 4 * - In the source html code, the list of items to "fit" needs to be surrounded by a container with class "boxFit grid", 5 * and each sorted item container (which can be of any type) needs to have class "grid-item". 6 * - At time of display, this code will search for the item with class "boxFit grid", and add multiple duplicate 7 * code sections that include all the sorted item. Each code section will be a <section class="boxFit-container"> 8 * marked "display:none". 9 * - Each new code section will have the sorted items entered in a different order, with enough sections to create one 10 * for each possible sort order. In practice, there are often 2-4 images, so it's not as bad as it might seem. 11 * - Then, a quick check is made of which section, or the original one, has the shortest height, and that section is 12 * marked visible and the others are deleted from the DOM. 13 * 14 * Author: Dave Mills, 2023 15 */ 16 17var swap = function (array, pos1, pos2) 18/* 19 * Part of the permutation process, swaps two children elements in an array 20 * 21 * Parameters: 22 * array is the list of all children in the section 23 * pos1 and pos2 are the indexes to the children to swap 24 */ 25 { 26 var temp = array[pos1]; 27 array[pos1] = array[pos2]; 28 array[pos2] = temp; 29 }; 30 31 32var heapsPermute = function (array,output,n) 33/* 34 * Create all permutations of the child array and output a <section> with the children for each permutation 35 * 36 * Note: As this creates all permutations, one of them will be the original permutation provided, which has 37 * class ".boxFit .grid", and not the ".boxFit-container" that we add for each of these new <section> groups. 38 * So we end up with a duplicate pair, which always seems to be the last boxFit-container in the list. I have 39 * not figured out how to avoid outputting this last entry in this recursive function. 40 * 41 * Parameters: 42 * array containing a list of html strings, the code to generate each child 43 * output function to create and insert into the DOM a new <section class="boxFit-container"> containing 44 * the current sort of the children array 45 * n 46 * 47 */ 48 { 49 n = n || array.length; // set n default to array.length 50 if (n === 1) 51 { 52 output (array); // 6/5/24 for now, skip last one as it's a duplicate of the original permutation 53 } 54 else 55 { 56 for (var i = 1;i <= n;i += 1) 57 { 58 heapsPermute (array,output,n-1); 59 if (n % 2) 60 { 61 var j = 1; 62 } 63 else 64 { 65 var j = i; 66 } 67 swap (array,j-1,n-1); // -1 to account for array zero-indexing 68 } 69 } 70 }; 71 72 73var addSection = function (list) 74/* 75 * Creates the html list of permuted children and adds it within a <section class="boxFit-container"> 76 * after the .boxFit element 77 * 78 * Parameters: 79 * list is the array of children 80 */ 81 { 82 var str = ""; 83 list.forEach (function (child) 84 { 85 str += child + " "; // in the source html, these elements are separated by a newline and some tabs, creating a space between them. Add that here. 86 }); 87 $('.boxFit').after('<section class="boxFit-container">' + str + '</section>'); 88 } 89 90 91function HighlightBestSection () 92/* 93 * NOTE: Since we've created all permutations of the child array, one of them is the same list as the original (.boxFit) list. This 94 * code is written as if we do not have this duplication, and that the original may be the one we continue to use (which is wmy my 95 * blue border does not show when the best one was the original given). 96 97 * Checked a few examples, and it looks like the last boxFit-container section is a duplicate of the original (ie, same sort) and 98 * could be omitted 99 */ 100 { 101 let bestGroup = -1; 102 let bestHeight = $(".boxFit").height(); // use the existing .boxFit container as the optimal height unless we can make it better 103 var count,height; 104// console.log("HighlightBestGroup: prior to boxfit adjustment, height=",bestHeight); 105 src = document.getElementsByClassName ("boxFit-container"); 106 for (var i = 0;i < src.length;i++) 107 { 108 /* 109 * Loop through all the new .boxFit-container sections, set the data-count attribute on them for future 110 * reference, get their height, and keep track of which one is the smallest (ie, best) to keep. 111 */ 112 src[i].setAttribute("data-count",i); 113 /* 114 * couldn't get .offsetHeight or .clientHeight to give a reasonable value until I 115 * ran this with the JQuery library (even though it is supposedly all native JS 116 */ 117// height = src[i].offsetHeight; 118 height = src[i].clientHeight;
119// src[i].setAttribute("data-height",height); // am I using this attribute? 6/7/24 commented out 120 if (height < bestHeight) 121 { 122 bestGroup = i; 123 bestHeight = height; 124 } 125 } 126// console.log("HighlightBestGroup: determined bestGroup=",bestGroup); 127 /* 128 * Mark the best one with some css for now. Eventually this goes away and we just delete alll the other ones 129 */ 130/* 1316/6/24 merged this with second loop below 132 for (var i = 0;i < src.length;i++) 133 { 134 if (i == bestGroup) 135 { 136// console.log ("marking data-count="+i+" as best fit"); 137 $(src[i]).css({"visibility":"visible"}); 138 } 139 } 140*/ 141 /* 142 * Go back through and remove all the sections that weren't the best and set the best one visible. Can't just loop 143 * thru src[] here, since it changes each time we delete a section, and the array indexes get all goofy. So I'm 144 * referencing them by the data-count attribute instead. 145 */ 146 var len = src.length; 147 for (var i = 0;i < len;i++) 148 { 149 if (i == bestGroup) 150 { 151 $("section[data-count='"+i+"']").css({"visibility":"visible"}); 152// $(src[i]).css({"visibility":"visible"}); 153 } 154 else 155 { 156 var s = "section[data-count='"+i+"']"; 157// console.log ("Deleting boxFit-container ("+s+")"); 158 $("section[data-count='"+i+"']").remove(); 159 } 160 } 161 if (bestGroup != -1) // original view was not optimal, remove it 162 { 163 $(".boxFit").remove(); 164 } 165// console.log("after permutation, height is ",bestGroup,bestHeight); 166 } 167 168 169function GetChildren (id) 170/* 171 * Collect an array of children of the passed container element 172 * 173 * Parameters: 174 * id, a string name of the container element to query for its children 175 * Returns: 176 * Array of the html for each child 177 */ 178 { 179 let a = []; 180 $(id).children().each(function() 181 { 182 a.push ($(this).prop("outerHTML")); 183 }); 184 return (a); 185 } 186 187 188$(window).on("load", function() 189/* 190 * Collect all children of the element with class="boxFit". These are not necessarily <img> tags, but can be any 191 * container element. Then create <section> elements that contain all the permutations of those children and mark 192 * the shortest one to be displayed. 193 */ 194 { 195 var imagelist = GetChildren (".boxFit"); 196 heapsPermute (imagelist,addSection); 197 HighlightBestSection (); 198 }); 199 200
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.