PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.82
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.82
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 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / features / Wrapper_Link / wrapper-link.js

wrapper-link.js in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.82, at includes/features/Wrapper_Link/wrapper-link.js

108 lines 3.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Wrapper Link — makes a whole container clickable.
3 *
4 * The wrapper only acts when the click was not meant for something inside it.
5 * A link, a button or a form control inside the container has to keep working
6 * on its own; letting both fire sends the visitor to two places at once.
7 */
8 (function () {
9 'use strict';
10
11 var WRAPPER_SELECTOR = '[data-kng-wrapper-link]';
12
13 /**
14 * Things a visitor can click on purpose. A click that starts on any of
15 * these belongs to that element, not to the wrapper around it.
16 */
17 var INTERACTIVE_SELECTOR = [
18 'a[href]',
19 'button',
20 'input',
21 'select',
22 'textarea',
23 'label',
24 'summary',
25 'video',
26 'audio',
27 'iframe',
28 '[role="button"]',
29 '[role="link"]',
30 '[role="tab"]',
31 '[contenteditable="true"]',
32 '[data-kng-wrapper-link]'
33 ].join(',');
34
35 function closest(node, selector) {
36 if (!node) {
37 return null;
38 }
39 if (typeof node.closest === 'function') {
40 return node.closest(selector);
41 }
42 // Very old browsers: walk up by hand.
43 var el = node.nodeType === 1 ? node : node.parentElement;
44 while (el) {
45 if (el.matches && el.matches(selector)) {
46 return el;
47 }
48 el = el.parentElement;
49 }
50 return null;
51 }
52
53 function hasTextSelection() {
54 try {
55 var selection = window.getSelection();
56 return !!selection && String(selection).trim().length > 0;
57 } catch (e) {
58 return false;
59 }
60 }
61
62 function onClick(event) {
63 // Only plain left clicks navigate; the rest is the browser's business.
64 if (event.defaultPrevented || (typeof event.button === 'number' && event.button !== 0)) {
65 return;
66 }
67
68 var wrapper = closest(event.target, WRAPPER_SELECTOR);
69 if (!wrapper) {
70 return;
71 }
72
73 // Editing the page should not navigate away from it.
74 if (document.body && document.body.classList.contains('elementor-editor-active')) {
75 return;
76 }
77
78 // The click landed on something clickable in its own right — or on a
79 // nested wrapper, which owns the click instead of this one.
80 var inner = closest(event.target, INTERACTIVE_SELECTOR);
81 if (inner && inner !== wrapper) {
82 return;
83 }
84
85 // Selecting text inside the container is not a request to leave it.
86 if (hasTextSelection()) {
87 return;
88 }
89
90 var url = wrapper.getAttribute('data-kng-wrapper-link');
91 if (!url) {
92 return;
93 }
94
95 var target = wrapper.getAttribute('data-kng-wrapper-link-target') || '_self';
96
97 // Behave like a real link under the modifier keys people expect.
98 if (target === '_blank' || event.metaKey || event.ctrlKey || event.shiftKey) {
99 window.open(url, '_blank', 'noopener');
100 return;
101 }
102
103 window.location.href = url;
104 }
105
106 document.addEventListener('click', onClick, false);
107 }());
108