1!(function ($) { 2 "use strict"; 3 4 $(window).on("elementor/frontend/init", function () { 5 6 if (typeof elementorModules === "undefined" || typeof elementorFrontend === "undefined") { 7 return; 8 } 9 10 var SoundHandler = elementorModules.frontend.handlers.Base.extend({ 11 12 soundInstance: null, 13 soundId: null, 14 isPlaying: false, 15 16 bindEvents: function () { 17 this.run(); 18 }, 19 20 getFxVal: function (key) { 21 return this.getElementSettings(key); 22 }, 23 24 destroySound: function () { 25 26 var element = this.$element[0]; 27 28 if (element && element._xproSoundEvents) { 29 element._xproSoundEvents.forEach(function (event) { 30 event.target.removeEventListener(event.type, event.handler); 31 }); 32 33 element._xproSoundEvents = []; 34 } 35 36 if (typeof createjs !== "undefined" && createjs.Sound && this.soundInstance) { 37 this.soundInstance.stop(); 38 this.soundInstance = null; 39 } 40 41 this.isPlaying = false; 42 }, 43 44 run: function () { 45 46 this.destroySound(); 47 48 var $element = this.$element; 49 var element = $element[0]; 50 51 if ( 52 !$element.hasClass("xpro-soundjs-effect-yes") || 53 typeof createjs === "undefined" || 54 typeof createjs.Sound === "undefined" 55 ) { 56 return; 57 } 58 59 var enabled = this.getFxVal("xpro_soundjs_enable") === "yes"; 60 var audio = this.getFxVal("xpro_soundjs_audio.url"); 61 var trigger = this.getFxVal("xpro_soundjs_trigger") || "click"; 62 var volume = parseFloat(this.getFxVal("xpro_soundjs_volume.size")) || 0.7; 63 var loop = this.getFxVal("xpro_soundjs_loop") === "yes"; 64 var triggerClass = this.getFxVal("xpro_soundjs_trigger_class") || ""; 65 66 if (!enabled || !audio) { 67 return; 68 } 69 70 this.soundId = "xpro_sound_" + this.getID(); 71 72 createjs.Sound.alternateExtensions = ["mp3", "ogg", "wav"]; 73 74 var self = this; 75 76 function playSound() { 77 78 if (!createjs.Sound.loadComplete(self.soundId)) { 79 return; 80 } 81 82 // Always stop any existing instance before starting a new one. 83 if (self.soundInstance) { 84 self.soundInstance.stop(); 85 self.soundInstance = null; 86 } 87 88 self.soundInstance = createjs.Sound.play(self.soundId, { 89 volume: volume, 90 loop: loop ? -1 : 0 91 }); 92 93 self.isPlaying = true; 94 95 // Reset state automatically once playback finishes on its own 96 // (only relevant for non-looping sounds). 97 self.soundInstance.on("complete", function () { 98 self.isPlaying = false; 99 self.soundInstance = null; 100 }); 101 } 102 103 function stopSound() { 104 105 if (self.soundInstance) { 106 self.soundInstance.stop(); 107 self.soundInstance = null; 108 } 109 110 self.isPlaying = false; 111 } 112 113 function toggleSound() { 114 if (self.isPlaying) { 115 stopSound(); 116 } else { 117 playSound(); 118 } 119 } 120 121 if (!createjs.Sound.loadComplete(this.soundId)) { 122 123 createjs.Sound.registerSound({ 124 src: audio, 125 id: this.soundId 126 }); 127 128 if (trigger === "load") { 129 createjs.Sound.on("fileload", function (event) { 130 if (event.id === self.soundId) { 131 playSound(); 132 } 133 }, null, true); 134 } 135 136 } else if (trigger === "load") { 137 playSound(); 138 } 139 140 element._xproSoundEvents = []; 141 142 function addEvent(target, type, handler) { 143 144 target.addEventListener(type, handler); 145 146 element._xproSoundEvents.push({ 147 target: target, 148 type: type, 149 handler: handler 150 }); 151 } 152 153 switch (trigger) { 154 155 case "hover": 156 157 // Play on hover in, stop automatically on hover out. 158 addEvent(element, "mouseenter", playSound); 159 addEvent(element, "mouseleave", stopSound); 160 161 break; 162 163 case "click": 164 165 // First click plays it, clicking again while it's 166 // still playing stops it. 167 addEvent(element, "click", toggleSound); 168 169 break; 170 171 case "class": 172 173 if (!triggerClass) { 174 break; 175 } 176 177 document.querySelectorAll(triggerClass).forEac
177h(function (el) { 178 addEvent(el, "click", toggleSound); 179 }); 180 181 break; 182 183 case "load": 184 185 // Already handled above. 186 break; 187 } 188 } 189 190 }); 191 192 elementorFrontend.hooks.addAction( 193 "frontend/element_ready/global", 194 function ($scope) { 195 elementorFrontend.elementsHandler.addHandler(SoundHandler, { 196 $element: $scope 197 }); 198 } 199 ); 200 201 }); 202 203})(jQuery);
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.