PluginProbe
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder / 51.1.86
King Addons for Elementor – 100+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce Builder, Mega Menu, Popup Builder v51.1.86
51.1.86 51.1.84 51.1.85 51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 All 40 releases
← All changes | includes/widgets/Image_Accordion/script.js +99 -25 51.1.38 → 51.1.86 View file →
@@ -7,8 +7,22 @@
7 7 function ($scope) {
8 8 elementorFrontend.elementsHandler.addHandler(
9 9 elementorModules.frontend.handlers.Base.extend({
10 10 onInit() {
11 + const normalizeSafeUrl = (rawUrl) => {
12 + if (!rawUrl || typeof rawUrl !== "string") return null;
13 + try {
14 + const url = new URL(rawUrl, window.location.href);
15 + const allowedProtocols = ["http:", "https:", "mailto:", "tel:"];
16 + if (allowedProtocols.includes(url.protocol)) {
17 + return url.href;
18 + }
19 + } catch (e) {
20 + // ignore
21 + }
22 + return null;
23 + };
24 +
11 25 const $elem = this.$element,
12 26 $wrap = $elem.find(".king-addons-image-accordion"),
13 27 $wrapContainer = $elem.find(".king-addons-image-accordion-wrap"),
14 28 settings = JSON.parse(
@@ -19,8 +33,56 @@
19 33 lightboxAttr = $wrap.attr("lightbox"),
20 34 lightboxSettings = lightboxAttr ? JSON.parse(lightboxAttr) : "",
21 35 $accordionItems = $elem.find(".king-addons-image-accordion-item");
22 36
37 + // Content stays at the open-item size for the whole animation.
38 + // Clearing that size when the transition ends was an instant
39 + // resize: the text wrapped and the block jumped.
40 + const contentAxis = () =>
41 + $wrap.css("flex-direction") === "column" ? "height" : "width";
42 +
43 + const setOpenContentSize = () => {
44 + const axis = contentAxis();
45 + const margin = axis === "height" ? "margin-bottom" : "margin-right";
46 + const count = $accordionItems.length;
47 + let gaps = 0;
48 +
49 + $accordionItems.each(function (index) {
50 + if (index < count - 1) {
51 + gaps += parseFloat($(this).css(margin)) || 0;
52 + }
53 + });
54 +
55 + const total =
56 + ($wrap[axis === "height" ? "innerHeight" : "innerWidth"]() || 0) - gaps;
57 + const activeGrow = parseFloat(settings.activeItem.activeWidth) || 1;
58 + let inactiveGrow = 1;
59 +
60 + $accordionItems.each(function () {
61 + if (!$(this).hasClass("king-addons-image-accordion-item-grow")) {
62 + inactiveGrow = parseFloat(window.getComputedStyle(this).flexGrow) || 1;
63 + return false;
64 + }
65 + });
66 +
67 + const sum = activeGrow + inactiveGrow * Math.max(count - 1, 0);
68 + if (total <= 0 || sum <= 0) {
69 + return;
70 + }
71 +
72 + $wrap[0].style.setProperty(
73 + "--king-acc-open-size",
74 + Math.round((total * activeGrow) / sum) + "px"
75 + );
76 + };
77 +
78 + setOpenContentSize();
79 + const resizeEvent = "resize.kingAddonsImageAccordion" + ($elem.data("id") || "item");
80 + $(window).off(resizeEvent).on(resizeEvent, setOpenContentSize);
81 + this.onDestroy = () => {
82 + $(window).off(resizeEvent);
83 + };
84 +
23 85 // Adjust row/column layout if necessary
24 86 if ($wrapContainer.hasClass("king-addons-acc-no-column")) {
25 87 if (!$elem.hasClass("king-addons-image-accordion-row")) {
26 88 $elem
@@ -132,16 +194,20 @@
132 194 ".king-addons-img-accordion-item-lightbox"
133 195 ).length
134 196 ) {
135 197 const itemUrl = thisSettings.activeItem.overlayLink;
136 - if (itemUrl) {
198 + const safeUrl = normalizeSafeUrl(itemUrl);
199 + if (safeUrl) {
137 200 if (
138 201 thisSettings.activeItem.overlayLinkTarget ===
139 202 "_blank"
140 203 ) {
141 - window.open(itemUrl, "_blank").focus();
204 + const w = window.open(safeUrl, "_blank");
205 + if (w && typeof w.focus === "function") {
206 + w.focus();
207 + }
142 208 } else {
143 - window.location.href = itemUrl;
209 + window.location.href = safeUrl;
144 210 }
145 211 }
146 212 }
147 213 });
@@ -151,28 +217,32 @@
151 217 // Interaction type: "hover"
152 218 if (settings.activeItem.interaction === "hover") {
153 219 mediaHoverLink();
154 220
155 - $accordionItems
156 - .on("mouseenter", function () {
157 - $accordionItems.removeClass(
158 - "king-addons-image-accordion-item-grow"
159 - );
160 - $accordionItems
161 - .find(".king-addons-animation-wrap")
162 - .removeClass("king-addons-animation-wrap-active");
221 + $accordionItems.on("mouseenter", function () {
222 + if ($(this).hasClass("king-addons-image-accordion-item-grow")) {
223 + return;
224 + }
225 + $accordionItems.removeClass(
226 + "king-addons-image-accordion-item-grow"
227 + );
228 + $accordionItems
229 + .find(".king-addons-animation-wrap")
230 + .removeClass("king-addons-animation-wrap-active");
163 231
164 - $(this).addClass("king-addons-image-accordion-item-grow");
165 - $(this)
166 - .find(".king-addons-animation-wrap")
167 - .addClass("king-addons-animation-wrap-active");
168 - })
169 - .on("mouseleave", function () {
170 - $(this).removeClass("king-addons-image-accordion-item-grow");
171 - $(this)
172 - .find(".king-addons-animation-wrap")
173 - .removeClass("king-addons-animation-wrap-active");
174 - });
232 + $(this).addClass("king-addons-image-accordion-item-grow");
233 + $(this)
234 + .find(".king-addons-animation-wrap")
235 + .addClass("king-addons-animation-wrap-active");
236 + });
237 + $wrap.on("mouseleave", function () {
238 + $accordionItems.removeClass(
239 + "king-addons-image-accordion-item-grow"
240 + );
241 + $accordionItems
242 + .find(".king-addons-animation-wrap")
243 + .removeClass("king-addons-animation-wrap-active");
244 + });
175 245
176 246 // Interaction type: "click"
177 247 } else if (settings.activeItem.interaction === "click") {
178 248 $elem
@@ -215,16 +285,20 @@
215 285 ".king-addons-img-accordion-item-lightbox"
216 286 ).length
217 287 ) {
218 288 const itemUrl = thisSettings.activeItem.overlayLink;
219 - if (itemUrl) {
289 + const safeUrl = normalizeSafeUrl(itemUrl);
290 + if (safeUrl) {
220 291 if (
221 292 thisSettings.activeItem.overlayLinkTarget ===
222 293 "_blank"
223 294 ) {
224 - window.open(itemUrl, "_blank").focus();
295 + const w = window.open(safeUrl, "_blank");
296 + if (w && typeof w.focus === "function") {
297 + w.focus();
298 + }
225 299 } else {
226 - window.location.href = itemUrl;
300 + window.location.href = safeUrl;
227 301 }
228 302 }
229 303 }
230 304 } else {