1// JavaScript 2import { Controller } from "../stimulus.js"; 3 4export default class extends Controller { 5 static targets = [ 6 "list", 7 "listLower", 8 "label", 9 "showMoreBtn", 10 "toggleLabelsBtn", 11 "knob", 12 "toggleLabelsText", 13 "biases", 14 "bias", 15 "owner", 16 "applyBtn", 17 "dialog", 18 "toggleAll", 19 "applyHint", 20 ]; 21 static values = { 22 classifications: String, 23 }; 24 25 expanded = false; 26 expandedLower = false; 27 labels = false; 28 animationCount = 10; 29 showHint = false; 30 currentParams = null; 31 localClassifications = this.classificationsValue; 32 33 connect() { 34 this._setLables(true); 35 this._createParams(); 36 } 37 38 disconnect() { 39 this.animationCount = -1; 40 } 41 42 _setLables(isInitial = false, onlyController = false) { 43 const biases = !onlyController 44 ? this.biasTargets 45 : this.biasTargets.filter((bias) => bias.classList.value.split(" ").includes("bias-label-controller")); 46 biases.forEach((bias) => { 47 bias.classList.remove("bias-label-deselected"); 48 }); 49 if (this.localClassifications.length || !isInitial) { 50 biases 51 .filter((bias) => !this.localClassifications.split(",").includes(bias.id)) 52 .forEach((bias) => { 53 bias.classList.add("bias-label-deselected"); 54 }); 55 } else { 56 this.localClassifications = [...new Set(biases.map((bias) => bias.id))].join(","); 57 setTimeout(() => this._labelsAnimation(), 1000); 58 } 59 } 60 61 _sleep(ms) { 62 return new Promise((resolve) => setTimeout(resolve, ms)); 63 } 64 65 async _labelsAnimation() { 66 if (this.animationCount >= 0) { 67 const biases = this.biasTargets.filter((bias) => bias.classList.value.split(" ").includes("bias-label")); 68 setTimeout(() => { 69 this._labelsAnimation(); 70 this.animationCount--; 71 }, 300); 72 for (let i = 0; i < biases.length; i++) { 73 biases[i].classList.toggle("bias-label-bounce"); 74 await new Promise((r) => setTimeout(r, 50)); 75 } 76 } 77 } 78 79 manualToggleLabels() { 80 this._toggleLabels(); 81 } 82 83 toggleBias(e) { 84 if (this.localClassifications.split(",").includes(e.target.id)) { 85 this.localClassifications = this.localClassifications 86 .split(",") 87 .filter((c) => c !== e.target.id) 88 .join(","); 89 } else { 90 this.localClassifications = this.localClassifications 91 ? this.localClassifications + `,${e.target.id}` 92 : e.target.id; 93 } 94 e.target.classList.toggle("bias-label-deselected"); 95 this._createParams(); 96 } 97 98 _updateToggleAllButton() { 99 this.toggleAllTarget.innerHTML = !this._allClasifications() ? "Select All" : "Deselect All"; 100 } 101 102 toggleAll() { 103 if (this._allClasifications()) { 104 this.localClassifications = ""; 105 } else { 106 this.localClassifications = [...new Set(this.biasTargets.map((bias) => bias.id))].join(","); 107 } 108 this._setLables(false, true); 109 this._createParams(); 110 } 111 112 _getNumberOfLabels() { 113 return this.biasTargets.filter((bias) => bias.classList.value.split(" ").includes("bias-label")).length; 114 } 115 116 resertFilters() { 117 this.localClassifications = this.classificationsValue; 118 this._setLables(true); 119 this._createParams(); 120 } 121 122 _allClasifications() { 123 return this.localClassifications.split(",").length === this._getNumberOfLabels(); 124 } 125 126 _createParams() { 127 let newParams = null; 128 if (!this.currentParams) { 129 newParams = new URLSearchParams(window.location.search); 130 } else { 131 newParams = this.currentParams; 132 } 133 newParams.set("classifications", `${this.localClassifications}`); 134 this.currentParams = newParams; 135 this._updateToggleAllButton(); 136 this._updateApplyButton(); 137 } 138 139 _updateApplyButton() { 140 if (!this.localClassifications.length) { 141 this.applyBtnTarget.classList.add("button-diabled"); 142 this.applyHintTarget.classList.remove("hidden"); 143 } else { 144 this.applyBtnTarget.classList.remove("button-diabled"); 145 this.applyHintTarget.classList.add("hidden"); 146 } 147 } 148 149 applyFilters(e) { 150 e.preventDefault(); 151 e.target.innerHTML = ` 152 <div class="loader"> 153 </div>`; 154
155 Turbo.visit(`?${this.currentParams.toString()}`, { 156 action: "replace", 157 }); 158 } 159 160 _onDocumentClick() { 161 this.toggleHint(); 162 } 163 164 _toggleLabels() { 165 this.labels = !this.labels; 166 if (this.labels) { 167 this.toggleLabelsTextTargets.forEach((el) => { el.innerHTML = 'Labels<span class="max-md:hidden"> Off</span>'; }); 168 this.animationCount = -1; 169 } else { 170 this.toggleLabelsTextTargets.forEach((el) => { el.innerHTML = 'Labels<span class="max-md:hidden"> On</span>'; }); 171 } 172 this.toggleLabelsBtnTargets.forEach((el) => { 173 el.classList.toggle("toggle-button-right"); 174 el.classList.toggle("toggle-button-left"); 175 }); 176 this.knobTargets.forEach((el) => { el.classList.toggle("toggle-knob-transport"); }); 177 this.biasesTarget.classList.toggle("hidden"); 178 this.labelTargets.forEach((label) => { 179 label.classList.toggle("hidden"); 180 }); 181 this.ownerTargets.forEach((owner) => { 182 owner.classList.toggle("article-owner-short"); 183 }); 184 } 185 186 _changeBtnName(el, open) { 187 if (open) { 188 el.target.innerHTML = "Show Less"; 189 } else { 190 el.target.innerHTML = "Show More"; 191 } 192 } 193 194 toggleExpand(e) { 195 this.expanded = !this.expanded; 196 this._changeBtnName(e, this.expanded); 197 this.listTargets.forEach((t) => t.classList.toggle("list-short")); 198 } 199 200 toggleExpandLower(e) { 201 this.expandedLower = !this.expandedLower; 202 this._changeBtnName(e, this.expandedLower); 203 this.listLowerTargets.forEach((t) => t.classList.toggle("list-short")); 204 } 205 206 openDialog() { 207 this.dialogTarget.showModal(); 208 this.dialogTarget.classList.remove("menu-close"); 209 this.dialogTarget.classList.add("menu-open"); 210 } 211 212 closeDialog() { 213 this.dialogTarget.classList.remove("menu-open"); 214 this.dialogTarget.classList.add("menu-close"); 215 216 // Wait for animation to finish before closing 217 setTimeout(() => { 218 this.resertFilters(); 219 this.dialogTarget.close(); 220 }, 300); 221 } 222 223 toggleDialog() { 224 this.dialogTarget.open ? this.closeDialog() : this.openDialog(); 225 } 226 227 clickOutsideDialog(event) { 228 if (event.target === this.dialogTarget) { 229 this.closeDialog(); 230 } 231 } 232}
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.