PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.1.4
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.1.4
3.1.4 3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 93 releases
ultimate-store-kit / src / vendor / js / toolslide.js

toolslide.js in Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder 3.1.4, at src/vendor/js/toolslide.js

368 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function (root, factory) {
2 if (typeof define === 'function' && define.amd) {
3 // AMD. Register as an anonymous module unless amdModuleId is set
4 define([], function () {
5 return (factory());
6 });
7 } else if (typeof module === 'object' && module.exports) {
8 // Node. Does not work with strict CommonJS, but
9 // only CommonJS-like environments that support module.exports,
10 // like Node.
11 module.exports = factory();
12 } else {
13 root['toolslide'] = factory();
14 }
15 }(this, function () {
16
17 'use strict';
18
19 var TOOLSLIDE_CLASS = "toolslide",
20 TOOLSLIDE_EMBED_CONTAINER_CLASS = "ts-embed-container";
21
22 var defaults = {
23 position: "left",
24 height: "100%",
25 width: "25%",
26 startOpen: true,
27 closeable: true,
28 minClosedSize: 0,
29 toggleButton: "",
30 embed: false,
31 navigationItemWidth: "0px",
32 navigationItemHeight: "0px",
33 autoclose: false,
34 autocloseDelay: 5000,
35 clickOutsideToClose: true,
36 animations: {
37 replace: "crossfade 0.5s ease-in-out",
38 toggle: "slide 0.5s ease",
39 }
40 }
41
42 function Toolslide() {
43 this.init.apply(this, arguments)
44 };
45
46 Toolslide.prototype = {
47
48 init: function (target, config) {
49 this.config = Object.assign({}, defaults, config);
50
51 if (!target) {
52 throw new Error("Missing required attribute: target element (css selector or DOM node) must be provided");
53 }
54 else if (this.__isString(target)) {
55 this.targetElement = document.querySelector(target);
56 }
57 else if (this.__isDOMElement(target)) {
58 this.targetElement = target;
59 }
60 else {
61 throw new Error("Incorrect type: target element must be DOM node or string css selector");
62 }
63 this.targetElement.classList.add(TOOLSLIDE_CLASS);
64 if (this.config.embed) this.targetElement.parentElement.classList.add(TOOLSLIDE_EMBED_CONTAINER_CLASS);
65 this.containerElement = this.targetElement.querySelector(".ts-container");
66 this.contentElement = this.targetElement.querySelector(".ts-content-container");
67 this.navElement = this.targetElement.querySelector(".ts-nav-container");
68 this.__applyConfig(this.config);
69 this.__attachEventListeners();
70 },
71
72 setPosition: function(position) {
73 this.targetElement.classList.add("ts-" + position);
74 },
75
76 setHeight: function(height) {
77 this.targetElement.style.height = height;
78 if (this.config.position === "top" || this.config.position === "bottom") {
79 this.containerElement.style.height = "calc(100% - " + this.navElement.clientHeight + "px)";
80 }
81 },
82
83 setWidth: function(width) {
84 this.targetElement.style.width = width;
85 if (this.config.position === "left" || this.config.position === "right") {
86 this.containerElement.style.width = "calc(100% - " + this.navElement.clientWidth + "px)";
87 }
88 },
89
90 setNavigationSize: function(width, height) {
91 if (this.config.position === "left" || this.config.position === "right") {
92 this.navElement.style.width = width;
93 }
94 if (this.config.position === "top" || this.config.position === "bottom") {
95 this.navElement.style.height = height;
96 }
97 var navItems = this.navElement.querySelectorAll(".ts-nav-item"),
98 l = navItems.length;
99
100 while (l--) {
101 navItems[l].style.width = width;
102 navItems[l].style.height = height;
103 }
104 },
105
106 setAutoClose: function(delay) {
107 if (this.autocloseTimeout) {
108 clearTimeout(this.autocloseTimeout);
109 }
110 this.autocloseTimeout = setTimeout(this.close.bind(this), delay);
111 },
112
113 setActiveById: function(panel) {
114 var previousActivePanel = this.targetElement.querySelector(".ts-content-item.active");
115 var id;
116
117 if (this.__isDOMElement(panel)) {
118 id = panel.id;
119 }
120 else if (this.__isString(panel)) {
121 id = panel;
122 }
123 else {
124 return;
125 }
126
127 if (previousActivePanel && id === previousActivePanel.id) {
128 return;
129 }
130
131 this.fire("beforeToggle",[previousActivePanel, currentActivePanel]);
132 var activeNavButton = this.targetElement.querySelector(".ts-nav-item[ts-target='" + id + "']");
133 var currentActivePanel = this.targetElement.querySelector("#" + id);
134
135 this.__deactivateAll();
136 currentActivePanel &&currentActivePanel.classList.add("active");
137 activeNavButton && activeNavButton.classList.add("active");
138 this.fire("afterToggle",[previousActivePanel, currentActivePanel]);
139 },
140
141 setActiveByIndex: function(index) {
142 var allPanels = this.contentElement && this.contentElement.children;
143 this.setActiveById(allPanels[index] && allPanels[index].id)
144 },
145
146 open: function() {
147 this.fire("beforeOpen", [this.targetElement]);
148 this.targetElement.classList.remove("closed");
149 this.targetElement.classList.add("open");
150 this.containerElement.style.left = "";
151 this.__updateEmbeding();
152 this.fire("afterOpen", [this.targetElement]);
153 },
154
155 close: function() {
156 this.fire("beforeClose", [this.targetElement]);
157 this.targetElement.classList.remove("open");
158 this.targetElement.classList.add("closed");
159 this.containerElement.style.left = this.config.minClosedSize + "px";
160 this.__updateEmbeding()
161 this.fire("afterClose", [this.targetElement]);
162 },
163
164 isOpen: function() {
165 return this.targetElement.classList.contains("open");
166 },
167
168 isActive: function(target) {
169 if (this.__isString(target)) {
170 target = document.getElementById(target);
171 }
172 else if (this.__isDOMElement(target)) {
173 }
174 else {
175 return false;
176 }
177
178 return target.classList.contains("active");
179 },
180
181 __applyConfig: function(config) {
182 this.setPosition(config.position);
183 config.startOpen ? this.open() : this.close();
184 this.setNavigationSize(config.navigationItemWidth, config.navigationItemHeight);
185
186 this.setWidth(config.width);
187 this.setHeight(config.height);
188 this.__updateEmbeding();
189 if (config.autoclose) {
190 this.setAutoClose();
191 }
192 this.__setAnimations(config.animations);
193 this.setActiveById(this.config.activePanel || this.__getContentPanel(0));
194 },
195
196 __attachEventListeners: function() {
197 var navButtons = this.navElement.children;
198 var l = navButtons.length;
199
200 while (l--) {
201 navButtons[l].onclick = this.onNavButtonClick.bind(this);
202 }
203
204 if (this.autocloseTimeout) {
205 this.containerElement.onmouseover = this.onMouseOver.bind(this);
206 this.containerElement.onmouseout = this.onMouseOut.bind(this);
207 }
208 if (this.config.clickOutsideToClose) {
209 document.addEventListener("click", this.onDocumentClick.bind(this), false);
210 }
211 if (this.config.toggleButton) {
212 this.toggleButtonElement = document.querySelector(this.config.toggleButton);
213 if (this.toggleButtonElement) {
214 this.toggleButtonElement.onclick = this.onToggleButtonClick.bind(this);
215 }
216 }
217 },
218
219 __updateEmbeding: function() {
220 if (!this.config.embed) return;
221
222 if (this.config.position === "left") {
223 this.targetElement.parentElement.style.marginLeft = this.isOpen() ? "calc(" + this.config.width + " - " + this.config.navigationItemWidth + ")" : this.config.minClosedSize + "px";
224 }
225 else if (this.config.position === "right") {
226 this.targetElement.parentElement.style.marginRight = this.isOpen() ? "calc(" + this.config.width + " - " + this.config.navigationItemWidth + ")" : this.config.minClosedSize + "px";
227 this.targetElement.parentElement.style.marginLeft = this.isOpen() ? "calc(-" + this.config.width + " + " + this.config.navigationItemWidth + ")" : this.config.minClosedSize + "px";
228 }
229 else if (this.config.position === "top") {
230 this.targetElement.parentElement.style.marginTop = this.isOpen() ? "calc(" + this.config.height + " - " + this.config.navigationItemHeight + ")" : this.config.minClosedSize + "px";
231 }
232 else if (this.config.position === "bottom") {
233 this.targetElement.parentElement.style.marginBottom = this.isOpen() ? "calc(" + this.config.height + " - " + this.config.navigationItemHeight + ")" : this.config.minClosedSize + "px";
234 }
235 },
236
237 __setAnimations: function(animations) {
238 if (!animations || !Object.keys(animations).length) {
239 return;
240 }
241
242 if (animations.replace) {
243 var animation = this.__getAnimationFromString(animations.replace);
244 var allContentPanels = this.contentElement.children;
245 var l = allContentPanels.length;
246 while (l--) {
247 this.__setVendorStyleProperty(allContentPanels[l], "transition", this.__getTransitionFromAnimation(animation));
248 allContentPanels[l].classList.add(animation.type);
249 }
250 }
251 if (animations.toggle) {
252 var animation = this.__getAnimationFromString(animations.toggle);
253 this.__setVendorStyleProperty(this.targetElement, "transition", this.__getTransitionFromAnimation(animation));
254 }
255 },
256
257 onNavButtonClick: function(event) {
258 if (!this.isOpen()) {
259 this.open();
260 }
261 else if (this.isActive(event.currentTarget) && this.config.closeable) {
262 this.close();
263 }
264
265 this.setActiveById(event.currentTarget.getAttribute("ts-target"));
266 },
267
268 onMouseOver: function(event) {
269 clearTimeout(this.autocloseTimeout);
270 },
271
272 onMouseOut: function(event) {
273 this.setAutoClose(this.config.autocloseDelay);
274 },
275
276 onDocumentClick: function(event) {
277 if (!this.targetElement.contains(event.target) && !(this.toggleButtonElement && this.toggleButtonElement.contains(event.target))) {
278 this.close();
279 }
280 },
281
282 onToggleButtonClick: function(event) {
283 if (!this.isOpen()) {
284 this.open();
285 }
286 else {
287 this.close();
288 }
289 },
290
291 fire: function(eventName, args) {
292 if (!this.config.listeners || !this.config.listeners[eventName]) {
293 return;
294 }
295 this.config.listeners[eventName].apply(this, args)
296 },
297
298 __deactivateAll: function() {
299 var allPanels = this.contentElement && this.contentElement.children;
300 var allNavButtons = this.navElement && this.navElement.children;
301 var l = allPanels.length;
302 var ll = allNavButtons.length;
303 while (l--) {
304 allPanels[l].classList.remove("active");
305 }
306 while (ll--) {
307 allNavButtons[ll].classList.remove("active");
308 }
309 },
310
311 __getContentPanel: function(index) {
312 return this.contentElement && this.contentElement.children && this.contentElement.children[index];
313 },
314
315 __isDOMElement: function (target) {
316 return target && (target.nodeType === document.ELEMENT_NODE || target.nodeType === document.DOCUMENT_FRAGMENT_NODE);
317 },
318
319 __isString: function (target) {
320 return typeof target === "string";
321 },
322
323 __getAnimationFromString: function(input) {
324 var animationOptions = input.split(" ");
325 return {
326 type: animationOptions[0],
327 speed: animationOptions[1],
328 easing: animationOptions[2]
329 }
330 },
331
332 __getTransitionFromAnimation: function(animation) {
333 var transitionString = "";
334 if(animation.type === "slide") {
335 transitionString += "transform " + animation.speed + " " + animation.easing;
336 }
337 else if (animation.type === "crossfade") {
338 transitionString += "opacity " + animation.speed + " " + animation.easing;
339 }
340 else if (animation.type === "slidefade"){
341 transitionString += "opacity " + animation.speed + " " + animation.easing + ", ";
342 transitionString += "transform " + animation.speed + " " + animation.easing;
343 }
344 return transitionString;
345 },
346
347 __setVendorStyleProperty: function (target, propertyName, value) {
348 var capitalizedPropertyName = this.__capitalizeFirstLetter(propertyName);
349 target.style["webkit" + capitalizedPropertyName] = value;
350 target.style["Moz" + capitalizedPropertyName] = value;
351 target.style["ms" + capitalizedPropertyName] = value;
352 target.style["O" + capitalizedPropertyName] = value;
353 target.style[propertyName] = value;
354 },
355
356 __capitalizeFirstLetter: function(input) {
357 return input.charAt(0).toUpperCase() + input.slice(1);
358 }
359 };
360
361 function toolslide(target, config) {
362 return new Toolslide(target, config);
363 }
364
365 return toolslide;
366
367 }));
368