1(function (global) { 2 3 function SocialwallWidget(args) { 4 this.args = args; 5 // arguments 6 this.displayType = (args.displayType !== undefined) ? args.displayType : 'classic'; 7 this.orderBy = (args.orderBy !== undefined) ? args.orderBy : 'dateDesc'; 8 this.debug = args.debug || false; 9 this.defaultFilter = 'all'; 10 this.activeFilter = args.defaultFilter || this.defaultFilter; 11 this.hiddenClass = args.hiddenClass || 'hide is-hidden'; 12 this.unfilteredClass = args.unfilteredClass || 'unfiltered'; 13 this.animationInterval = args.animationInterval || 100; 14 15 // variables 16 this.$widget = $(this.args.selector); 17 this.$container = $(this.args.containerSelector || '#sw_flux'); 18 this.posts = []; 19 this.theseNetworksHasPosts = []; 20 this.isFiltering = false; 21 this.interval_SW = undefined; 22 this.$filters = $('#sw_filters li > button, #sw_filters li > a'); 23 this.macy = undefined; 24 this.macyConfig = this.args.macyConfig || {}; 25 this.activeFilterClass = this.args.activeFilterClass || 'filter_act iso-active'; 26 27 if (this.debug) this.log('Debug mode is active'); 28 29 this.bind(); 30 this.init(); 31 32 return this; 33 } 34 35 SocialwallWidget.prototype.setDebug = function (active) { 36 this.debug = active; 37 }; 38 39 SocialwallWidget.prototype.init = function () { 40 let $this = this; 41 42 for (let i = 0; i < $this.args.ajaxUriList.length; i++) { 43 $.ajax({
44 method: 'POST', 45 url: $this.args.ajaxUriList[i], 46 dataType: 'json', 47 cache: false, 48 success: function (response) { 49 $this.injectPosts(response); 50 $this.updateFilterButtons(); 51 }, 52 error: function (jqXHR, textStatus, errorThrow) { 53 $this.log('ajax error', jqXHR, textStatus, errorThrow); 54 } 55 }); 56 } 57 58 if ( 59 $($this.args.containerSelector).length && 60 $this.displayType === 'masonry' && 61 typeof window.Macy !== 'undefined' 62 ) { 63 $this.macy = Macy($.extend({ 64 container: $this.args.containerSelector, 65 }, $this.macyConfig)); 66 } 67 }; 68 69 SocialwallWidget.prototype.bind = function () { 70 let $this = this; 71 72 $(document).on('click', '#sw_filters li > button, #sw_filters li > a', function () { 73 let network = $(this).attr('data-network') || $this.defaultFilter; 74 $this.onFilterClicked(network); 75 }); 76 }; 77 78 SocialwallWidget.prototype.injectPosts = function (result) { 79 let $this = this; 80 if (result.posts) { 81 // add returned posts to global posts array 82 result.posts.forEach(function (post, index) { 83 post.page = result.page; 84 $this.posts.push(post); 85 }); 86 87 if (result.posts.length > 0) { 88 $this.theseNetworksHasPosts[result.page.network] = result.posts.length; 89 } 90 91 // sort items 92 if ($this.orderBy === 'dateDesc') { // DATE DESC 93 94 $this.posts.sort(sortByDateDesc); 95 96 } else if ($this.orderBy === 'random') { // RANDOM 97 // since this shuffle method only invert the position with neighbours, we have to do it multiple times 98 // FAUDRA QUE JE TROUVE UNE AUTRE METHODE, PARCE QUE C'EST UN PEU DEGUEULASSE QUAND MEME 99 $this.posts.sort(shuffle); 100 $this.posts.sort(shuffle); 101 $this.posts.sort(shuffle); 102 $this.posts.sort(shuffle); 103 $this.posts.sort(shuffle); 104 $this.posts.sort(shuffle); 105 $this.posts.sort(shuffle); 106 $this.posts.sort(shuffle); 107 $this.posts.sort(shuffle); 108 $this.posts.sort(shuffle); 109 } 110 111 function sortByDateDesc(a, b) { 112 return (b.post.date.localeCompare(a.post.date)); // simple shuffle 113 } 114 115 function shuffle(a, b) { 116 return (0.5 - Math.random()); // simple shuffle 117 } 118 119 // remove all items 120 $this.$container.find('.sw_item').remove(); 121 122 let metroIndices = [ 123 {name: 'facebook', index: 0}, 124 {name: 'twitter', index: 0}, 125 {name: 'youtube', index: 0}, 126 {name: 'instagram', index: 0}, 127 ]; 128 129 function getIndiceIdByNetwork(network) { 130 for (let i = 0; i < metroIndices.length; i++) { 131 if (metroIndices[i].name === network) 132 return i; 133 } 134 } 135 136 function getPostByNetworkAndIndex(targetNetwork, targetIndex) { 137 let currentIndex = 0; 138 for (let i = 0; i < $this.posts.length; i++) { 139 let post = $this.posts[i]; 140 if (post.page.network === targetNetwork) { 141 if (currentIndex >= targetIndex) { 142 return post; 143 } 144 currentIndex++; 145 } 146 } 147 return undefined; 148 } 149 150 // display the posts according to the metro config 151 if ($this.displayType === 'metro') { 152 if ($this.args.metroConfig.length > 0) { 153 for (let networkIndex = 0; networkIndex < $this.args.metroConfig.length; networkIndex++) { 154 let network = $this.args.metroConfig[networkIndex].network; 155 let metroIndicesIndex = getIndiceIdByNetwork(network); 156 157 let post = getPostByNetworkAndIndex(network, metroIndices[metroIndicesIndex].index); 158 159 if (post !== undefined) { 160 $(post.html).appendTo($this.$container); 161 metroIndices[metroIndicesIndex].index++; 162 } 163 } 164 } 165 } 166 167 // enqueue the posts array 168 let networkCounter = { 169 'facebook': 0, 170 'twitter': 0, 171 'youtube': 0, 172 'instagram': 0, 173 }; 174 let $posts = []; 175 for (let i = 0; i < $this.posts.length; i++) { 176 let post = $this.posts[i]; 177 let metroIndicesIndex = getIndiceIdByNetwork(post.page.network); 178 179 if (networkCounter[post.page.network] >= metroIndices[metroIndicesIndex].index) { 180 let $post = $(post.html); 181 $posts.push($post); 182 $post.appendTo($this.$container); 183 } 184 networkCounter[post.page.network]++; 185 } 186 187 // update masonry 188 if (typeof $this.$container.masonry !== 'undefined') { 189 $this.$container.masonry('appended', $posts); 190 $this.$container.masonry('layout'); 191 } 192 193 // Set additional classes 194 if ($this.displayType === 'metro') { 195 if ($this.args.metroConfig.length > 0) {
196 let $items = $($this.args.selector + " .sw_item"); 197 for (let networkIndex = 0; networkIndex < $this.args.metroConfig.length; networkIndex++) { 198 let classesUnfiltered = $this.args.metroConfig[networkIndex].classesUnfiltered, 199 classesFiltered = $this.args.metroConfig[networkIndex].classesFiltered; 200 201 $items.eq(networkIndex) 202 .addClass(classesUnfiltered) 203 .attr('data-class-unfiltered', classesUnfiltered) 204 .attr('data-class-filtered', classesFiltered); 205 } 206 } 207 } 208 209 // set 'first' class 210 $this.onFilterClicked($this.activeFilter); 211 212 // lazy load for images 213 if (typeof window.Hunt !== 'undefined') { 214 let $images = document.querySelectorAll($this.args.selector + " img.lazy"); 215 new Hunt($images, { 216 enter: function (e) { 217 e.src = e.dataset.src; 218 } 219 }); 220 } 221 222 // filter posts + appear animation 223 $this.isFiltering = ($this.activeFilter !== "all"); 224 $this.filterPosts($this.defaultFilter); 225 226 } 227 }; 228 229 SocialwallWidget.prototype.updateFilterButtons = function () { 230 let $this = this; 231 232 // update the 'unfiltered' class of the container 233 if ($this.activeFilter === $this.defaultFilter) { 234 $this.$container.addClass($this.unfilteredClass); 235 } else { 236 $this.$container.removeClass($this.unfilteredClass); 237 } 238 239 if (Object.keys($this.theseNetworksHasPosts).length > 1 && $(this)) { 240 241 let atLeastOneNetwork = false; 242 243 $this.$filters.each(function () { 244 245 let $button = $(this); 246 let $parent = $button.parents('li'); 247 let network = $button.attr("data-network").toLowerCase(); 248 249 if (!$this.$filters.hasClass($this.defaultFilter)) { 250 251 let countPost = $this.theseNetworksHasPosts[network]; 252 253 254 if (countPost > 0) atLeastOneNetwork = true; 255 256 if (countPost > 0) { 257 $parent.removeClass($this.hiddenClass); 258 $this.log('updateFilterButtons', network + ' is visible'); 259 } else { 260 // $parent.addClass($this.hiddenClass); 261 $this.log('updateFilterButtons', network + ' is hidden'); 262 } 263 264 } 265 266 // update the title 267 if (network === $this.activeFilter) { 268 $button.attr('title', $button.attr('data-title-active')); 269 $button.attr('aria-pressed', true); 270 } else { 271 $button.attr('title', $button.attr('data-title')); 272 $button.attr('aria-pressed', false); 273 } 274 275 }); 276 277 if (atLeastOneNetwork) { 278 $this.$filters.eq(0).parents('li').removeClass($this.hiddenClass); 279 } 280 281 } else { 282 283 // hide all filters 284 $this.$filters.parents('li').addClass($this.hiddenClass); 285 $this.log('updateFilterButtons', 'all filters are hidden'); 286 287 } 288 }; 289 290 SocialwallWidget.prototype.onFilterClicked = function (network, $button) { 291 let $this = this; 292 293 let $allItems = $this.$container.find('.sw_item'); 294 295 // remove first class 296 $allItems.removeClass('first'); 297 298 // select only the posts to show 299 let $itemsToShow = (network === 'all') 300 ? $allItems 301 : $this.$container.find('.sw_item.item_' + network); 302 303 // add class 'first' on the first item of selected network 304 let $firstItem = $itemsToShow.eq(0); 305 $firstItem.addClass('first'); 306 307 // set active filter 308 $this.activeFilter = network; 309 310 $this.log('onFilterClicked', 'The active filter is ' + network); 311 312 $this.updateFilterButtons(); 313 $this.filterPosts(network); 314 315 }; 316 317 SocialwallWidget.prototype.filterPosts = function () {
318 let $this = this, 319 metroCount = $this.$widget.attr('data-metro-count'), 320 $itemsToShow, $itemsToHide, 321 index = 0; 322 323 // get the posts to show / hide depending on the current filter 324 if ($this.activeFilter === $this.defaultFilter) { 325 $itemsToShow = $this.$widget.find(".sw_item:lt(" + (metroCount) + ")"); 326 $itemsToHide = $this.$widget.find(".sw_item:gt(" + (metroCount - 1) + ")"); 327 } else { 328 $itemsToShow = $this.$widget.find(".sw_item.item_" + $this.activeFilter); 329 $itemsToHide = $this.$widget.find(".sw_item:not(.item_" + $this.activeFilter + ")"); 330 } 331 332 // update the hidden state (by class) 333 $this.$container.find('.sw_item') 334 .addClass($this.hiddenClass) 335 .removeClass('mui-enter-active'); 336 $itemsToShow.removeClass($this.hiddenClass); 337 338 if ($this.isFiltering === false) { 339 $itemsToHide.addClass($this.hiddenClass); 340 } 341 342 // update the active filter 343 $this.$widget.find('#sw_filters li, #sw_filters li > button, #sw_filters li > a').removeClass($this.activeFilterClass); 344 $this.$widget.find('#sw_filters li.' + $this.activeFilter + ', #sw_filters li.' + $this.activeFilter + ' > button, #sw_filters li.' + $this.activeFilter + ' > a').addClass($this.activeFilterClass); 345 346 clearInterval($this.interval_SW); 347 $this.interval_SW = setInterval(function () { 348 let $item = $itemsToShow.eq(index); 349 350 if (index < metroCount) { 351 $item.addClass('mui-enter-active'); 352 353 let classUnfiltered = $item.attr('data-class-unfiltered'), 354 classFiltered = $item.attr('data-class-filtered'); 355 356 if ($this.activeFilter !== $this.defaultFilter) { 357 $item.removeClass(classUnfiltered).addClass(classFiltered); 358 } else { 359 $item.removeClass(classFiltered).addClass(classUnfiltered); 360 } 361 362 } else { 363 clearInterval($this.interval_SW); 364 $this.interval_SW = undefined; 365 } 366 index++; 367 }, $this.animationInterval); 368 369 if ( 370 $($this.args.containerSelector).length && 371 $this.displayType === 'masonry' && 372 typeof window.Macy !== 'undefined' 373 ) { 374 setTimeout(function () { 375 $this.macy.reInit(); 376 }, 100); 377 } 378 }; 379 380 SocialwallWidget.prototype.log = function (...args) { 381 if (this.debug) console.log('SocialWall', ...args); 382 }; 383 384 let socialwallWidget = function (args) { 385 return new SocialwallWidget(args); 386 }; 387 388 global.SocialwallWidget = socialwallWidget; 389 390})(this);
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.