Version Description
A new cool update! We added for our new users a tour (of course, if you are already using Buttonizer, feel free to take the tour!). If someone has some feedback, about the tour, contact us through the plugin! :)
We've added something magical! For each button it's now possible to use one of the following actions: - Website URL: For opening a webpage - Phone number: Direct action - E-mail: Opens the desktop client from the user with your mail address filled in already
New this release: - Information tour for our new users - Button actions easier
Changed: - Re-ordered the settings page a bit
Fixed: - When enabling 'show on hover' with only one button, the label won't be visible anymore - Some caching plugins liked to cache our javascript, we've added a fix to that - Other bugs
Release Info
Developer | buttonizer |
Plugin | Smart Floating / Sticky Buttons – Call, Sharing, Chat Widgets & More – Buttonizer |
Version | 1.0.9 |
Comparing to | |
See all releases |
Code changes from version 1.0.8 to 1.0.9
- buttonizer.php +18 -11
- classes/admin/Buttons.php +87 -94
- classes/admin/General.php +15 -11
- classes/admin/InitializeAdmin.php +6 -2
- classes/default/license.php +3 -2
- classes/default/main.php +21 -12
- css/buttonizer.css +5 -3
- css/introjs.css +552 -0
- css/style.css +58 -7
- freemius/.gitignore +16 -0
- js/buttonizer.js +5 -1
- js/dashboard.js +492 -2
- js/intro.js +2139 -0
- readme.txt +21 -1
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: Buttonizer - Smart Floating Action Button
|
4 |
Plugin URI: https://buttonizer.pro
|
5 |
Description: The Buttonizer is a new way to give a boost to your number of interactions, actions and conversions from your website visitor by adding one or multiple Customizable Smart Floating Button in the corner of your website.
|
6 |
-
Version: 1.0.
|
7 |
Author: Buttonizer
|
8 |
Author URI: https://buttonizer.pro
|
9 |
License: GPL2
|
@@ -28,11 +28,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
28 |
Copyright 2017 Buttonizer
|
29 |
*/
|
30 |
|
|
|
|
|
31 |
define('BUTTONIZER_NAME', 'buttonizer');
|
32 |
define('BUTTONIZER_DIR', dirname(__FILE__));
|
33 |
define('BUTTONIZER_SLUG', basename(BUTTONIZER_DIR));
|
34 |
define('BUTTONIZER_PLUGIN_DIR', __FILE__ );
|
35 |
-
define('BUTTONIZER_VERSION','1.0.
|
36 |
|
37 |
# No script kiddies
|
38 |
defined( 'ABSPATH' ) or die('No script kiddies please!');
|
@@ -114,16 +116,21 @@ else
|
|
114 |
/* LAST FEW FUNCTIONS */
|
115 |
if(!function_exists("buttonizer_custom_connect_message_on_update")) {
|
116 |
function buttonizer_custom_connect_message_on_update(
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
return sprintf(
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
127 |
$user_first_name,
|
128 |
'<b>' . $plugin_title . '</b>',
|
129 |
'<b>' . $user_login . '</b>',
|
3 |
Plugin Name: Buttonizer - Smart Floating Action Button
|
4 |
Plugin URI: https://buttonizer.pro
|
5 |
Description: The Buttonizer is a new way to give a boost to your number of interactions, actions and conversions from your website visitor by adding one or multiple Customizable Smart Floating Button in the corner of your website.
|
6 |
+
Version: 1.0.9
|
7 |
Author: Buttonizer
|
8 |
Author URI: https://buttonizer.pro
|
9 |
License: GPL2
|
28 |
Copyright 2017 Buttonizer
|
29 |
*/
|
30 |
|
31 |
+
// error_reporting(E_ALL);
|
32 |
+
|
33 |
define('BUTTONIZER_NAME', 'buttonizer');
|
34 |
define('BUTTONIZER_DIR', dirname(__FILE__));
|
35 |
define('BUTTONIZER_SLUG', basename(BUTTONIZER_DIR));
|
36 |
define('BUTTONIZER_PLUGIN_DIR', __FILE__ );
|
37 |
+
define('BUTTONIZER_VERSION','1.0.9');
|
38 |
|
39 |
# No script kiddies
|
40 |
defined( 'ABSPATH' ) or die('No script kiddies please!');
|
116 |
/* LAST FEW FUNCTIONS */
|
117 |
if(!function_exists("buttonizer_custom_connect_message_on_update")) {
|
118 |
function buttonizer_custom_connect_message_on_update(
|
119 |
+
$message,
|
120 |
+
$user_first_name,
|
121 |
+
$plugin_title,
|
122 |
+
$user_login,
|
123 |
+
$site_link,
|
124 |
+
$freemius_link
|
125 |
+
) {
|
126 |
return sprintf(
|
127 |
+
__( 'Hey %1$s' ) . ',<br>' .
|
128 |
+
'<br />' .
|
129 |
+
__( 'Click on Allow & Continue to start Buttonizing your website :)! Create Floating Action Buttons & Floating Menu\'s. Decide on a number of click actions like start chatting with Whatsapp, click-to-call, open a URL and more.') . '<br />' .
|
130 |
+
__('Never miss an important update -- opt-in to our security and feature updates notifications.') . '<br />' .
|
131 |
+
'<br />' .
|
132 |
+
__('See you on the other side.')
|
133 |
+
,
|
134 |
$user_first_name,
|
135 |
'<b>' . $plugin_title . '</b>',
|
136 |
'<b>' . $user_login . '</b>',
|
@@ -46,9 +46,9 @@ class Buttons
|
|
46 |
private function loadButtons()
|
47 |
{
|
48 |
// Get buttons
|
49 |
-
$aButtons = ( isset( $this->aSavedData['buttonorder'] ) && is_array( $this->aSavedData['buttonorder'] ) ? $this->aSavedData['buttonorder'] :
|
50 |
0 => -1,
|
51 |
-
|
52 |
if ( $aButtons[0] != '-1' ) {
|
53 |
$aButtons[-1] = '-1';
|
54 |
}
|
@@ -71,55 +71,45 @@ class Buttons
|
|
71 |
<li>
|
72 |
<div class="button-row" id="btn_row_<?php
|
73 |
echo $iButtonId ;
|
74 |
-
?>
|
75 |
-
" button-id="<?php
|
76 |
echo $iButtonId ;
|
77 |
-
?>
|
78 |
-
|
|
|
79 |
if ( $iButtonId == -1 ) {
|
80 |
echo ' style="display: none"' ;
|
81 |
}
|
82 |
-
|
83 |
-
>
|
84 |
<input type="checkbox" name="buttonizer_buttons[buttonorder][]" value="<?php
|
85 |
echo $iButtonId ;
|
86 |
-
?>
|
87 |
-
" checked="checked" style="display: none;" />
|
88 |
|
89 |
<div class="row-info drag-handle">
|
90 |
<div class="mover"></div>
|
91 |
<span><i class="fa <?php
|
92 |
echo $this->buttonOutputIcon( $iButtonId ) ;
|
93 |
-
?>
|
94 |
-
button-icon"></i> <span class="row-title"><?php
|
95 |
echo ( $iButtonId == -1 ? 'New button' : $sButtonTitle ) ;
|
96 |
-
|
97 |
-
</span> <i class="fa fa-pencil pencil-edit"></i></span>
|
98 |
|
99 |
<a href="javascript:buttonizer.removeRow(<?php
|
100 |
echo $iButtonId ;
|
101 |
-
?>
|
102 |
-
)" class="delete-button">Delete <i class="fa fa-trash-o"></i></a>
|
103 |
|
104 |
<a href="javascript:buttonizer.toggleMobile(<?php
|
105 |
echo $iButtonId ;
|
106 |
-
?>
|
107 |
-
|
108 |
-
|
109 |
-
?>
|
110 |
-
"><i class="fa fa-mobile"></i></a>
|
111 |
<a href="javascript:buttonizer.toggleDesktop(<?php
|
112 |
echo $iButtonId ;
|
113 |
-
?>
|
114 |
-
|
115 |
-
|
116 |
-
?>
|
117 |
-
"><i class="fa fa-desktop"></i></a>
|
118 |
|
119 |
<a href="javascript:void(0)" class="is-live-button" style="<?php
|
120 |
-
echo ( $onMobile !=
|
121 |
-
?>
|
122 |
-
"><i class="fa fa-circle"></i> Live</a>
|
123 |
|
124 |
<button type="submit" class="must-save-button savebutton " style="display: none;"><i class="fa fa-floppy-o"></i> Save changes</button>
|
125 |
</div>
|
@@ -138,11 +128,9 @@ class Buttons
|
|
138 |
</label>
|
139 |
<input type="text" name="buttonizer_buttons[button_<?php
|
140 |
echo $iButtonId ;
|
141 |
-
?>
|
142 |
-
_title]" value="<?php
|
143 |
echo $sButtonTitle ;
|
144 |
-
?>
|
145 |
-
" class="button_title" />
|
146 |
</td>
|
147 |
<td class="button-pdr">
|
148 |
<label for="button_icon" class="label-top">
|
@@ -186,28 +174,30 @@ _title]" value="<?php
|
|
186 |
<td></td>
|
187 |
</tr>
|
188 |
|
189 |
-
<tr class="settings-row">
|
190 |
-
|
191 |
-
<i class="fa fa-globe setting-icon"></i>
|
192 |
-
<span class="info-class"><i class="fa fa-info-circle"></i> <span>This is the click-action of your button.
|
193 |
-
|
194 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
195 |
echo $this->buttonGetUrl( $iButtonId ) ;
|
196 |
?>
|
197 |
-
</td>
|
198 |
-
</tr>
|
199 |
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
?>
|
210 |
-
_is_phonenumber"> Yes</label></td>
|
211 |
</tr>
|
212 |
|
213 |
<tr class="settings-row setting-new-tab">
|
@@ -216,22 +206,19 @@ _is_phonenumber"> Yes</label></td>
|
|
216 |
</td>
|
217 |
<td><?php
|
218 |
echo $this->buttonGetNewTab( $iButtonId ) ;
|
219 |
-
|
220 |
-
<label for="button_<?php
|
221 |
echo $iButtonId ;
|
222 |
-
?>
|
223 |
-
_url_newtab"> Yes</label></td>
|
224 |
</tr>
|
225 |
|
226 |
<tr class="settings-row">
|
227 |
<td>
|
228 |
<i class="fa fa-paint-brush setting-icon"></i> Button colors
|
229 |
-
<span class="info-class"><i class="fa fa-info-circle"></i> <span
|
230 |
</td>
|
231 |
<td><?php
|
232 |
echo $this->buttonColors( $iButtonId ) ;
|
233 |
-
|
234 |
-
</td>
|
235 |
</tr>
|
236 |
|
237 |
<tr>
|
@@ -239,30 +226,26 @@ _url_newtab"> Yes</label></td>
|
|
239 |
<td></td>
|
240 |
</tr>
|
241 |
|
242 |
-
<tr class="settings-row">
|
243 |
<td>
|
244 |
<i class="fa fa-mobile setting-icon"></i> Show on mobile
|
245 |
</td>
|
246 |
<td><?php
|
247 |
echo $this->buttonGetShowPhone( $iButtonId ) ;
|
248 |
-
|
249 |
-
<label for="button_<?php
|
250 |
echo $iButtonId ;
|
251 |
-
?>
|
252 |
-
_show_on_phone"> Yes</label></td>
|
253 |
</tr>
|
254 |
|
255 |
-
<tr class="settings-row">
|
256 |
<td>
|
257 |
<i class="fa fa-desktop setting-icon"></i> Show on desktop
|
258 |
</td>
|
259 |
<td><?php
|
260 |
echo $this->buttonGetShowDesktop( $iButtonId ) ;
|
261 |
-
|
262 |
-
<label for="button_<?php
|
263 |
echo $iButtonId ;
|
264 |
-
?>
|
265 |
-
_show_on_desktop"> Yes</label></td>
|
266 |
</tr>
|
267 |
|
268 |
<tr class="settings-row">
|
@@ -278,11 +261,9 @@ _show_on_desktop"> Yes</label></td>
|
|
278 |
</td>
|
279 |
<td><?php
|
280 |
echo $this->buttonGetHideLabel( $iButtonId ) ;
|
281 |
-
|
282 |
-
<label for="button_<?php
|
283 |
echo $iButtonId ;
|
284 |
-
?>
|
285 |
-
_hide_label"> Yes</label></td>
|
286 |
</tr>
|
287 |
|
288 |
<tr>
|
@@ -318,7 +299,7 @@ _hide_label"> Yes</label></td>
|
|
318 |
* Form functions
|
319 |
*/
|
320 |
// Get the text of the button
|
321 |
-
|
322 |
{
|
323 |
$fieldName = 'button_' . $iButtonId . '_text';
|
324 |
$fieldValue = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : 'New button' );
|
@@ -326,26 +307,26 @@ _hide_label"> Yes</label></td>
|
|
326 |
}
|
327 |
|
328 |
// Get button icon
|
329 |
-
|
330 |
{
|
331 |
-
return $this->oIconManager->generator(
|
332 |
'icon' => ( isset( $this->aSavedData['button_' . $iButtonId . '_icon'] ) ? $this->aSavedData['button_' . $iButtonId . '_icon'] : '' ),
|
333 |
'icon_fieldname' => 'buttonizer_buttons[button_' . $iButtonId . '_icon]',
|
334 |
'image' => ( isset( $this->aSavedData['button_' . $iButtonId . '_image'] ) ? $this->aSavedData['button_' . $iButtonId . '_image'] : '' ),
|
335 |
'image_fieldname' => 'buttonizer_buttons[button_' . $iButtonId . '_image]',
|
336 |
'choose_type' => true,
|
337 |
-
|
338 |
}
|
339 |
|
340 |
// Get button icon
|
341 |
-
|
342 |
{
|
343 |
$fieldName = 'button_' . $iButtonId . '_icon';
|
344 |
return ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : 'fa-info' );
|
345 |
}
|
346 |
|
347 |
// Only show this button on phone?
|
348 |
-
|
349 |
{
|
350 |
$fieldName = 'button_' . $iButtonId . '_show_on_phone';
|
351 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
@@ -353,11 +334,11 @@ _hide_label"> Yes</label></td>
|
|
353 |
}
|
354 |
|
355 |
// buttonGetShowOnPages
|
356 |
-
|
357 |
{
|
358 |
$fieldName = 'button_' . $iButtonId . '_show_on_pages';
|
359 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
360 |
-
$pageOrders = ( isset( $this->aPageCategories['categorieOrder'] ) ? $this->aPageCategories['categorieOrder'] :
|
361 |
/*
|
362 |
* Generate <select>
|
363 |
*/
|
@@ -372,7 +353,7 @@ _hide_label"> Yes</label></td>
|
|
372 |
}
|
373 |
|
374 |
// Only show this button on desktop?
|
375 |
-
|
376 |
{
|
377 |
$fieldName = 'button_' . $iButtonId . '_show_on_desktop';
|
378 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
@@ -380,7 +361,7 @@ _hide_label"> Yes</label></td>
|
|
380 |
}
|
381 |
|
382 |
// Only show when company is open?
|
383 |
-
|
384 |
{
|
385 |
$fieldName = 'button_' . $iButtonId . '_show_when_opened';
|
386 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
@@ -388,44 +369,56 @@ _hide_label"> Yes</label></td>
|
|
388 |
}
|
389 |
|
390 |
// Only show when company is open?
|
391 |
-
|
392 |
{
|
393 |
$fieldName = 'button_' . $iButtonId . '_show_not_when_opened';
|
394 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
395 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_showwhenopened" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
396 |
}
|
397 |
|
398 |
-
|
399 |
{
|
400 |
$fieldName = 'button_' . $iButtonId . '_hide_label';
|
401 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
402 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_hidelabel" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
403 |
}
|
404 |
|
405 |
-
|
406 |
-
public function buttonGetIsPhoneNumber( $iButtonId = 0 )
|
407 |
{
|
408 |
-
$
|
409 |
-
|
410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
}
|
412 |
|
413 |
-
|
414 |
{
|
415 |
$fieldName = 'button_' . $iButtonId . '_url';
|
416 |
$fieldValue = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
417 |
-
return '<input type="text" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="' . $fieldValue . '" class="
|
418 |
}
|
419 |
|
420 |
// Only show this button on phone?
|
421 |
-
|
422 |
{
|
423 |
$fieldName = 'button_' . $iButtonId . '_url_newtab';
|
424 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
425 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_isnewtab" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
426 |
}
|
427 |
|
428 |
-
|
429 |
{
|
430 |
// Default button colors
|
431 |
$sDefaultColor1 = $this->aSystemSettings['button_unpushed'];
|
46 |
private function loadButtons()
|
47 |
{
|
48 |
// Get buttons
|
49 |
+
$aButtons = ( isset( $this->aSavedData['buttonorder'] ) && is_array( $this->aSavedData['buttonorder'] ) ? $this->aSavedData['buttonorder'] : [
|
50 |
0 => -1,
|
51 |
+
] );
|
52 |
if ( $aButtons[0] != '-1' ) {
|
53 |
$aButtons[-1] = '-1';
|
54 |
}
|
71 |
<li>
|
72 |
<div class="button-row" id="btn_row_<?php
|
73 |
echo $iButtonId ;
|
74 |
+
?>" button-id="<?php
|
|
|
75 |
echo $iButtonId ;
|
76 |
+
?>" data-button-action="<?php
|
77 |
+
echo ( isset( $this->aSavedData['button_' . $iButtonId . '_type'] ) ? $this->aSavedData['button_' . $iButtonId . '_type'] : 'url' ) ;
|
78 |
+
?>" <?php
|
79 |
if ( $iButtonId == -1 ) {
|
80 |
echo ' style="display: none"' ;
|
81 |
}
|
82 |
+
?>>
|
|
|
83 |
<input type="checkbox" name="buttonizer_buttons[buttonorder][]" value="<?php
|
84 |
echo $iButtonId ;
|
85 |
+
?>" checked="checked" style="display: none;" />
|
|
|
86 |
|
87 |
<div class="row-info drag-handle">
|
88 |
<div class="mover"></div>
|
89 |
<span><i class="fa <?php
|
90 |
echo $this->buttonOutputIcon( $iButtonId ) ;
|
91 |
+
?> button-icon"></i> <span class="row-title"><?php
|
|
|
92 |
echo ( $iButtonId == -1 ? 'New button' : $sButtonTitle ) ;
|
93 |
+
?></span> <i class="fa fa-pencil pencil-edit"></i></span>
|
|
|
94 |
|
95 |
<a href="javascript:buttonizer.removeRow(<?php
|
96 |
echo $iButtonId ;
|
97 |
+
?>)" class="delete-button">Delete <i class="fa fa-trash-o"></i></a>
|
|
|
98 |
|
99 |
<a href="javascript:buttonizer.toggleMobile(<?php
|
100 |
echo $iButtonId ;
|
101 |
+
?>)" class="mobiledesktop mobile-button <?php
|
102 |
+
echo ( $onMobile == "" ? 'selected' : '' ) ;
|
103 |
+
?>"><i class="fa fa-mobile"></i></a>
|
|
|
|
|
104 |
<a href="javascript:buttonizer.toggleDesktop(<?php
|
105 |
echo $iButtonId ;
|
106 |
+
?>)" class="mobiledesktop desktop-button <?php
|
107 |
+
echo ( $onDesktop == "" ? 'selected' : '' ) ;
|
108 |
+
?>"><i class="fa fa-desktop"></i></a>
|
|
|
|
|
109 |
|
110 |
<a href="javascript:void(0)" class="is-live-button" style="<?php
|
111 |
+
echo ( $onMobile != "" || $onDesktop != "" ? '' : 'display: none;' ) ;
|
112 |
+
?>"><i class="fa fa-circle"></i> Live</a>
|
|
|
113 |
|
114 |
<button type="submit" class="must-save-button savebutton " style="display: none;"><i class="fa fa-floppy-o"></i> Save changes</button>
|
115 |
</div>
|
128 |
</label>
|
129 |
<input type="text" name="buttonizer_buttons[button_<?php
|
130 |
echo $iButtonId ;
|
131 |
+
?>_title]" value="<?php
|
|
|
132 |
echo $sButtonTitle ;
|
133 |
+
?>" class="button_title" />
|
|
|
134 |
</td>
|
135 |
<td class="button-pdr">
|
136 |
<label for="button_icon" class="label-top">
|
174 |
<td></td>
|
175 |
</tr>
|
176 |
|
177 |
+
<tr class="settings-row button-action">
|
178 |
+
<td colspan="2">
|
179 |
+
<i class="fa fa-globe setting-icon"></i> Button action
|
180 |
+
<span class="info-class"><i class="fa fa-info-circle"></i> <span>This is the click-action of your button. When you choose for a phone number, it will be a direct click-to-call action.</span></span>
|
181 |
+
|
182 |
+
<table width="100%" class="settings-row-type">
|
183 |
+
<tr>
|
184 |
+
<td width="200"><?php
|
185 |
+
echo $this->buttonGetType( $iButtonId ) ;
|
186 |
+
?></td>
|
187 |
+
<td>
|
188 |
+
<?php
|
189 |
echo $this->buttonGetUrl( $iButtonId ) ;
|
190 |
?>
|
|
|
|
|
191 |
|
192 |
+
<div class="input_error" style="display: none;"></div>
|
193 |
+
|
194 |
+
<div class="extra_info" data-button-type="phone">
|
195 |
+
|
196 |
+
</div>
|
197 |
+
</td>
|
198 |
+
</tr>
|
199 |
+
</table>
|
200 |
+
</td>
|
|
|
|
|
201 |
</tr>
|
202 |
|
203 |
<tr class="settings-row setting-new-tab">
|
206 |
</td>
|
207 |
<td><?php
|
208 |
echo $this->buttonGetNewTab( $iButtonId ) ;
|
209 |
+
?><label for="button_<?php
|
|
|
210 |
echo $iButtonId ;
|
211 |
+
?>_url_newtab"> Yes</label></td>
|
|
|
212 |
</tr>
|
213 |
|
214 |
<tr class="settings-row">
|
215 |
<td>
|
216 |
<i class="fa fa-paint-brush setting-icon"></i> Button colors
|
217 |
+
<span class="info-class"><i class="fa fa-info-circle"></i> <span>You can change the colors of this button, like the default background, the background on hover or the icon color. You can undo them too. Click the palet for changing the colors.</span></span>
|
218 |
</td>
|
219 |
<td><?php
|
220 |
echo $this->buttonColors( $iButtonId ) ;
|
221 |
+
?></td>
|
|
|
222 |
</tr>
|
223 |
|
224 |
<tr>
|
226 |
<td></td>
|
227 |
</tr>
|
228 |
|
229 |
+
<tr class="settings-row show-mobile-btn">
|
230 |
<td>
|
231 |
<i class="fa fa-mobile setting-icon"></i> Show on mobile
|
232 |
</td>
|
233 |
<td><?php
|
234 |
echo $this->buttonGetShowPhone( $iButtonId ) ;
|
235 |
+
?><label for="button_<?php
|
|
|
236 |
echo $iButtonId ;
|
237 |
+
?>_show_on_phone"> Yes</label></td>
|
|
|
238 |
</tr>
|
239 |
|
240 |
+
<tr class="settings-row show-desktop-btn">
|
241 |
<td>
|
242 |
<i class="fa fa-desktop setting-icon"></i> Show on desktop
|
243 |
</td>
|
244 |
<td><?php
|
245 |
echo $this->buttonGetShowDesktop( $iButtonId ) ;
|
246 |
+
?><label for="button_<?php
|
|
|
247 |
echo $iButtonId ;
|
248 |
+
?>_show_on_desktop"> Yes</label></td>
|
|
|
249 |
</tr>
|
250 |
|
251 |
<tr class="settings-row">
|
261 |
</td>
|
262 |
<td><?php
|
263 |
echo $this->buttonGetHideLabel( $iButtonId ) ;
|
264 |
+
?><label for="button_<?php
|
|
|
265 |
echo $iButtonId ;
|
266 |
+
?>_hide_label"> Yes</label></td>
|
|
|
267 |
</tr>
|
268 |
|
269 |
<tr>
|
299 |
* Form functions
|
300 |
*/
|
301 |
// Get the text of the button
|
302 |
+
function buttonGetText( $iButtonId = 0 )
|
303 |
{
|
304 |
$fieldName = 'button_' . $iButtonId . '_text';
|
305 |
$fieldValue = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : 'New button' );
|
307 |
}
|
308 |
|
309 |
// Get button icon
|
310 |
+
function buttonGetIcon( $iButtonId = 0 )
|
311 |
{
|
312 |
+
return $this->oIconManager->generator( [
|
313 |
'icon' => ( isset( $this->aSavedData['button_' . $iButtonId . '_icon'] ) ? $this->aSavedData['button_' . $iButtonId . '_icon'] : '' ),
|
314 |
'icon_fieldname' => 'buttonizer_buttons[button_' . $iButtonId . '_icon]',
|
315 |
'image' => ( isset( $this->aSavedData['button_' . $iButtonId . '_image'] ) ? $this->aSavedData['button_' . $iButtonId . '_image'] : '' ),
|
316 |
'image_fieldname' => 'buttonizer_buttons[button_' . $iButtonId . '_image]',
|
317 |
'choose_type' => true,
|
318 |
+
] );
|
319 |
}
|
320 |
|
321 |
// Get button icon
|
322 |
+
function buttonOutputIcon( $iButtonId = 0 )
|
323 |
{
|
324 |
$fieldName = 'button_' . $iButtonId . '_icon';
|
325 |
return ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : 'fa-info' );
|
326 |
}
|
327 |
|
328 |
// Only show this button on phone?
|
329 |
+
function buttonGetShowPhone( $iButtonId = 0 )
|
330 |
{
|
331 |
$fieldName = 'button_' . $iButtonId . '_show_on_phone';
|
332 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
334 |
}
|
335 |
|
336 |
// buttonGetShowOnPages
|
337 |
+
function buttonGetShowOnPages( $iButtonId = 0 )
|
338 |
{
|
339 |
$fieldName = 'button_' . $iButtonId . '_show_on_pages';
|
340 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
341 |
+
$pageOrders = ( isset( $this->aPageCategories['categorieOrder'] ) ? $this->aPageCategories['categorieOrder'] : [] );
|
342 |
/*
|
343 |
* Generate <select>
|
344 |
*/
|
353 |
}
|
354 |
|
355 |
// Only show this button on desktop?
|
356 |
+
function buttonGetShowDesktop( $iButtonId = 0 )
|
357 |
{
|
358 |
$fieldName = 'button_' . $iButtonId . '_show_on_desktop';
|
359 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
361 |
}
|
362 |
|
363 |
// Only show when company is open?
|
364 |
+
function buttonGetShowWenOpen( $iButtonId = 0 )
|
365 |
{
|
366 |
$fieldName = 'button_' . $iButtonId . '_show_when_opened';
|
367 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
369 |
}
|
370 |
|
371 |
// Only show when company is open?
|
372 |
+
function buttonGetShowNotWenOpen( $iButtonId = 0 )
|
373 |
{
|
374 |
$fieldName = 'button_' . $iButtonId . '_show_not_when_opened';
|
375 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
376 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_showwhenopened" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
377 |
}
|
378 |
|
379 |
+
function buttonGetHideLabel( $iButtonId = 0 )
|
380 |
{
|
381 |
$fieldName = 'button_' . $iButtonId . '_hide_label';
|
382 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
383 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_hidelabel" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
384 |
}
|
385 |
|
386 |
+
function buttonGetType( $iButtonId = 0 )
|
|
|
387 |
{
|
388 |
+
$aTypes = [
|
389 |
+
'url' => 'Website URL',
|
390 |
+
'phone' => 'Phone number',
|
391 |
+
'mail' => 'E-mail',
|
392 |
+
];
|
393 |
+
$aTypes = array_merge( $aTypes, [
|
394 |
+
'disabled_whatsapp' => 'Open whatsapp (phone number) - PRO ONLY',
|
395 |
+
'disabled_javascript' => 'Javascript function - PRO ONLY',
|
396 |
+
] );
|
397 |
+
$fieldName = 'button_' . $iButtonId . '_action';
|
398 |
+
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : 'url' );
|
399 |
+
$html = '<select name="buttonizer_buttons[' . $fieldName . ']" id="button_type" class="button_action">';
|
400 |
+
foreach ( $aTypes as $sType => $sTitle ) {
|
401 |
+
$html .= '<option value="' . str_replace( 'disabled_', '', $sType ) . '"' . (( $sType == $is_selected ? 'selected="selected"' : '' )) . ' ' . (( strpos( $sType, 'disabled_' ) !== false > 0 ? 'disabled' : '' )) . '>' . $sTitle . '</option>';
|
402 |
+
}
|
403 |
+
return $html . '</select>';
|
404 |
}
|
405 |
|
406 |
+
function buttonGetUrl( $iButtonId = 0 )
|
407 |
{
|
408 |
$fieldName = 'button_' . $iButtonId . '_url';
|
409 |
$fieldValue = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
410 |
+
return '<input type="text" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="' . $fieldValue . '" class="button_input" placeholder="URL/Phone number" />';
|
411 |
}
|
412 |
|
413 |
// Only show this button on phone?
|
414 |
+
function buttonGetNewTab( $iButtonId = 0 )
|
415 |
{
|
416 |
$fieldName = 'button_' . $iButtonId . '_url_newtab';
|
417 |
$is_selected = ( isset( $this->aSavedData[$fieldName] ) ? $this->aSavedData[$fieldName] : '' );
|
418 |
return '<input type="checkbox" name="buttonizer_buttons[' . $fieldName . ']" id="' . $fieldName . '" value="1" class="button_isnewtab" ' . (( $is_selected == '1' ? 'checked="checked"' : '' )) . ' />';
|
419 |
}
|
420 |
|
421 |
+
function buttonColors( $iButtonId = 0 )
|
422 |
{
|
423 |
// Default button colors
|
424 |
$sDefaultColor1 = $this->aSystemSettings['button_unpushed'];
|
@@ -34,8 +34,8 @@ class General
|
|
34 |
$this->aFontAwesome = $aFontAwesome;
|
35 |
$this->oIconManager = $oIconManager;
|
36 |
$this->loadData();
|
37 |
-
$this->registerPlacingSettings();
|
38 |
$this->registerDesignSettings();
|
|
|
39 |
$this->registerAdvancedSettings();
|
40 |
$this->registerSocialSettings();
|
41 |
$this->registerOther();
|
@@ -78,10 +78,10 @@ class General
|
|
78 |
<h2>Placing & animations</h2>
|
79 |
<p>You can change here the button position and the button animation.</p>
|
80 |
</td></tr>';
|
81 |
-
$this->aSubPages['placing'] .= $this->createFormField( 'Right', array( &$this, 'field_position_right' ) );
|
82 |
$this->aSubPages['placing'] .= $this->createFormField( 'Bottom', array( &$this, 'field_position_bottom' ) );
|
83 |
-
$this->aSubPages['placing'] .= $this->createFormField( 'Button animation', array( &$this, 'field_button_animation' ) );
|
84 |
-
$this->aSubPages['placing'] .= $this->createFormField( 'Attention animation', array( &$this, 'field_attention_animation' ) );
|
85 |
$this->aSubPages['placing'] .= '</tbody></table>';
|
86 |
}
|
87 |
|
@@ -97,11 +97,15 @@ class General
|
|
97 |
<h2>Design</h2>
|
98 |
<p>Style your button, make it blinky as you wish. You can change here the main color, main label and set the label hover types.</p>
|
99 |
</td></tr>';
|
|
|
|
|
100 |
$this->aSubPages['design'] .= $this->createFormField( 'Color button unpushed', array( &$this, 'field_button_unpushed' ) );
|
101 |
$this->aSubPages['design'] .= $this->createFormField( 'Color button pushed', array( &$this, 'field_button_pushed' ) );
|
102 |
$this->aSubPages['design'] .= $this->createFormField( 'Icon color', array( &$this, 'field_icon_color' ) );
|
103 |
-
$this->aSubPages['design'] .=
|
104 |
-
$this->aSubPages['design'] .=
|
|
|
|
|
105 |
$this->aSubPages['design'] .= $this->createFormField( 'Only show labels on hover<br /><br /><small>Only show the label when you hover the button.</small>', array( &$this, 'field_label_show_on_hover' ) );
|
106 |
$this->aSubPages['design'] .= '</tbody></table>';
|
107 |
}
|
@@ -228,9 +232,9 @@ class General
|
|
228 |
$this->aSubPages['other'] .= '</tbody></table>';
|
229 |
}
|
230 |
|
231 |
-
private function createFormField( $sLabel, $aFunction )
|
232 |
{
|
233 |
-
return '<tr><th scope="row">' . $sLabel . '</th><td class="r-sit">' . $aFunction() . '</td></tr>';
|
234 |
}
|
235 |
|
236 |
private function createFieldset( $sLabel )
|
@@ -368,21 +372,21 @@ class General
|
|
368 |
{
|
369 |
$share_facebook = ( isset( $this->aSavedData['share_facebook'] ) ? $this->aSavedData['share_facebook'] : '' );
|
370 |
$share_facebook_text = ( isset( $this->aSavedData['share_facebook_text'] ) ? $this->aSavedData['share_facebook_text'] : 'Share this on Facebook' );
|
371 |
-
return '<span class="
|
372 |
}
|
373 |
|
374 |
function field_share_linkedin()
|
375 |
{
|
376 |
$share_linkedin = ( isset( $this->aSavedData['share_linkedin'] ) ? $this->aSavedData['share_linkedin'] : '' );
|
377 |
$share_linkedin_text = ( isset( $this->aSavedData['share_linkedin_text'] ) ? $this->aSavedData['share_linkedin_text'] : 'Share this on LinkedIn' );
|
378 |
-
return '<span class="
|
379 |
}
|
380 |
|
381 |
function field_share_twitter()
|
382 |
{
|
383 |
$share_twitter = ( isset( $this->aSavedData['share_twitter'] ) ? $this->aSavedData['share_twitter'] : '' );
|
384 |
$share_twitter_text = ( isset( $this->aSavedData['share_twitter_text'] ) ? $this->aSavedData['share_twitter_text'] : 'Share this on Twitter' );
|
385 |
-
return '<span class="
|
386 |
}
|
387 |
|
388 |
}
|
34 |
$this->aFontAwesome = $aFontAwesome;
|
35 |
$this->oIconManager = $oIconManager;
|
36 |
$this->loadData();
|
|
|
37 |
$this->registerDesignSettings();
|
38 |
+
$this->registerPlacingSettings();
|
39 |
$this->registerAdvancedSettings();
|
40 |
$this->registerSocialSettings();
|
41 |
$this->registerOther();
|
78 |
<h2>Placing & animations</h2>
|
79 |
<p>You can change here the button position and the button animation.</p>
|
80 |
</td></tr>';
|
81 |
+
$this->aSubPages['placing'] .= $this->createFormField( 'Right', array( &$this, 'field_position_right' ), 'intro-position' );
|
82 |
$this->aSubPages['placing'] .= $this->createFormField( 'Bottom', array( &$this, 'field_position_bottom' ) );
|
83 |
+
$this->aSubPages['placing'] .= $this->createFormField( 'Button animation', array( &$this, 'field_button_animation' ), 'intro-animaton' );
|
84 |
+
$this->aSubPages['placing'] .= $this->createFormField( 'Attention animation', array( &$this, 'field_attention_animation' ), 'intro-attention' );
|
85 |
$this->aSubPages['placing'] .= '</tbody></table>';
|
86 |
}
|
87 |
|
97 |
<h2>Design</h2>
|
98 |
<p>Style your button, make it blinky as you wish. You can change here the main color, main label and set the label hover types.</p>
|
99 |
</td></tr>';
|
100 |
+
$this->aSubPages['design'] .= '</tbody></table>';
|
101 |
+
$this->aSubPages['design'] .= '<table class="form-table intro-styling"><tbody>';
|
102 |
$this->aSubPages['design'] .= $this->createFormField( 'Color button unpushed', array( &$this, 'field_button_unpushed' ) );
|
103 |
$this->aSubPages['design'] .= $this->createFormField( 'Color button pushed', array( &$this, 'field_button_pushed' ) );
|
104 |
$this->aSubPages['design'] .= $this->createFormField( 'Icon color', array( &$this, 'field_icon_color' ) );
|
105 |
+
$this->aSubPages['design'] .= '</tbody></table>';
|
106 |
+
$this->aSubPages['design'] .= '<table class="form-table" style="margin-top: 0;"><tbody>';
|
107 |
+
$this->aSubPages['design'] .= $this->createFormField( 'Main icon<br /><br /><small>This icon will apear in a button when you have multiple floating action buttons on one page. When you click on the icon the other floating action button will \'pop\' open.</small>', array( &$this, 'field_icon_icon' ), 'intro-icon' );
|
108 |
+
$this->aSubPages['design'] .= $this->createFormField( 'Main label<br /><br /><small>This label will apear next to the \'main button\' when you have multiple floating action buttons on one page.</small>', array( &$this, 'field_icon_label' ), 'intro-label' );
|
109 |
$this->aSubPages['design'] .= $this->createFormField( 'Only show labels on hover<br /><br /><small>Only show the label when you hover the button.</small>', array( &$this, 'field_label_show_on_hover' ) );
|
110 |
$this->aSubPages['design'] .= '</tbody></table>';
|
111 |
}
|
232 |
$this->aSubPages['other'] .= '</tbody></table>';
|
233 |
}
|
234 |
|
235 |
+
private function createFormField( $sLabel, $aFunction, $sClass = '' )
|
236 |
{
|
237 |
+
return '<tr class="' . $sClass . '"><th scope="row">' . $sLabel . '</th><td class="r-sit">' . $aFunction() . '</td></tr>';
|
238 |
}
|
239 |
|
240 |
private function createFieldset( $sLabel )
|
372 |
{
|
373 |
$share_facebook = ( isset( $this->aSavedData['share_facebook'] ) ? $this->aSavedData['share_facebook'] : '' );
|
374 |
$share_facebook_text = ( isset( $this->aSavedData['share_facebook_text'] ) ? $this->aSavedData['share_facebook_text'] : 'Share this on Facebook' );
|
375 |
+
return '<span class="before-input"><input type="checkbox" name="buttonizer_general_settings[share_facebook]" value="1" ' . (( $share_facebook == '1' ? 'checked="checked"' : '' )) . ' /></span> <input type="text" name="buttonizer_general_settings[share_facebook_text]" value="' . $share_facebook_text . '" class="before-input-padding" placeholder="Share this on Facebook" />';
|
376 |
}
|
377 |
|
378 |
function field_share_linkedin()
|
379 |
{
|
380 |
$share_linkedin = ( isset( $this->aSavedData['share_linkedin'] ) ? $this->aSavedData['share_linkedin'] : '' );
|
381 |
$share_linkedin_text = ( isset( $this->aSavedData['share_linkedin_text'] ) ? $this->aSavedData['share_linkedin_text'] : 'Share this on LinkedIn' );
|
382 |
+
return '<span class="before-input"><input type="checkbox" name="buttonizer_general_settings[share_linkedin]" value="1" ' . (( $share_linkedin == '1' ? 'checked="checked"' : '' )) . ' /></span> <input type="text" name="buttonizer_general_settings[share_linkedin_text]" value="' . $share_linkedin_text . '" class="before-input-padding" placeholder="Share this on LinkedIn" />';
|
383 |
}
|
384 |
|
385 |
function field_share_twitter()
|
386 |
{
|
387 |
$share_twitter = ( isset( $this->aSavedData['share_twitter'] ) ? $this->aSavedData['share_twitter'] : '' );
|
388 |
$share_twitter_text = ( isset( $this->aSavedData['share_twitter_text'] ) ? $this->aSavedData['share_twitter_text'] : 'Share this on Twitter' );
|
389 |
+
return '<span class="before-input"><input type="checkbox" name="buttonizer_general_settings[share_twitter]" value="1" ' . (( $share_twitter == '1' ? 'checked="checked"' : '' )) . ' /></span> <input type="text" name="buttonizer_general_settings[share_twitter_text]" value="' . $share_twitter_text . '" class="before-input-padding" placeholder="Share this on Twitter" />';
|
390 |
}
|
391 |
|
392 |
}
|
@@ -86,11 +86,13 @@ class InitializeAdmin {
|
|
86 |
wp_enqueue_script('sortable', plugins_url('/js/sortable.min.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
87 |
wp_enqueue_script('dashboard-script', plugins_url('/js/dashboard.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
88 |
wp_enqueue_script('opening-script', plugins_url('/js/company-openingtimes.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
89 |
-
|
|
|
90 |
|
91 |
wp_enqueue_style('font-awesome','//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css');
|
92 |
|
93 |
-
|
|
|
94 |
|
95 |
}
|
96 |
|
@@ -195,6 +197,8 @@ class InitializeAdmin {
|
|
195 |
echo '<a href="'. ButtonizerLicense()->get_account_url() .'" class="nav-tab" style="float: right; border: 0; background: none; outline: none !important;">My Account</a>';
|
196 |
}
|
197 |
|
|
|
|
|
198 |
echo '</h1>';
|
199 |
}
|
200 |
|
86 |
wp_enqueue_script('sortable', plugins_url('/js/sortable.min.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
87 |
wp_enqueue_script('dashboard-script', plugins_url('/js/dashboard.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
88 |
wp_enqueue_script('opening-script', plugins_url('/js/company-openingtimes.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
89 |
+
wp_enqueue_script('advanced-settings-script', plugins_url('/js/advanced-settings.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
90 |
+
wp_enqueue_script('intro', plugins_url('/js/intro.js?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
91 |
|
92 |
wp_enqueue_style('font-awesome','//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css');
|
93 |
|
94 |
+
wp_enqueue_style('dialog-boxes', plugins_url('/freemius/assets/css/admin/dialog-boxes.css', BUTTONIZER_PLUGIN_DIR));
|
95 |
+
wp_enqueue_style('intro', plugins_url('/css/introjs.css?v=' . md5(BUTTONIZER_VERSION), BUTTONIZER_PLUGIN_DIR));
|
96 |
|
97 |
}
|
98 |
|
197 |
echo '<a href="'. ButtonizerLicense()->get_account_url() .'" class="nav-tab" style="float: right; border: 0; background: none; outline: none !important;">My Account</a>';
|
198 |
}
|
199 |
|
200 |
+
echo '<a href="?page=Buttonizer&tab=buttonizer_general_settings#buttonizer-tour" class="nav-tab" style="float: right; border: 0; background: none; outline: none !important;" id="take-the-tour">Take the tour</a>';
|
201 |
+
|
202 |
echo '</h1>';
|
203 |
}
|
204 |
|
@@ -41,8 +41,9 @@ class License
|
|
41 |
'has_addons' => false,
|
42 |
'has_paid_plans' => true,
|
43 |
'menu' => array(
|
44 |
-
'
|
45 |
-
'
|
|
|
46 |
),
|
47 |
'is_live' => true,
|
48 |
) );
|
41 |
'has_addons' => false,
|
42 |
'has_paid_plans' => true,
|
43 |
'menu' => array(
|
44 |
+
'first-path' => 'admin.php?page=Buttonizer&welcome-splash=true',
|
45 |
+
'slug' => 'Buttonizer',
|
46 |
+
'support' => false,
|
47 |
),
|
48 |
'is_live' => true,
|
49 |
) );
|
@@ -149,14 +149,21 @@ class Button
|
|
149 |
$buttonText = ( isset( $this->aButtons['button_' . $bNmbr . '_text'] ) ? $this->aButtons['button_' . $bNmbr . '_text'] : 'Button ' . $bNmbr );
|
150 |
$buttonTitle = ( isset( $this->aButtons['button_' . $bNmbr . '_title'] ) ? $this->aButtons['button_' . $bNmbr . '_title'] : 'Button ' . $bNmbr );
|
151 |
$buttonIsPhone = ( isset( $this->aButtons['button_' . $bNmbr . '_is_phonenumber'] ) ? $this->aButtons['button_' . $bNmbr . '_is_phonenumber'] : '' );
|
152 |
-
$link = ( isset( $this->aButtons['button_' . $bNmbr . '_url'] ) ? $this->aButtons['button_' . $bNmbr . '_url'] : '' );
|
153 |
$linkNewTab = ( isset( $this->aButtons['button_' . $bNmbr . '_url_newtab'] ) ? 'target="_blank"' : '' );
|
154 |
$hideLabel = ( isset( $this->aButtons['button_' . $bNmbr . '_hide_label'] ) ? $this->aButtons['button_' . $bNmbr . '_hide_label'] : '' );
|
|
|
|
|
155 |
|
156 |
-
if (
|
157 |
-
$
|
158 |
-
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
}
|
161 |
}
|
162 |
|
@@ -184,7 +191,7 @@ class Button
|
|
184 |
color: ' . $this->aButtons['button_' . $bNmbr . '_colors_icon'] . ';
|
185 |
} ';
|
186 |
}
|
187 |
-
return '<a href="' .
|
188 |
// Thanks, end
|
189 |
}
|
190 |
|
@@ -352,13 +359,15 @@ class Button
|
|
352 |
echo '<style>.buttonizer-button a:hover, .buttonizer-button a:focus{ background:' . $this->aSettings['button_pushed'] . '; } .buttonizer-button a { background:' . $this->aSettings['button_unpushed'] . '; } .buttonizer-button a i { color: ' . $this->aSettings['icon_color'] . '; } ' . $this->sButtonCss . '</style>
|
353 |
<div class="buttonizer-button ' . (( $showOnScroll > 0 || $showAfterTimeout > 0 ? 'hide' : '' )) . ' ' . (( isset( $this->aSettings['buttons_label_show_on_hover'] ) && $this->aSettings['buttons_label_show_on_hover'] == '1' ? ' show_labels_on_hover' : '' )) . '" button-animation="' . $sButtonAnimation . '" attention-animation="' . $sAttentionAnimation . '" style=" right: ' . $this->aSettings['position_right'] . '%; bottom: ' . $this->aSettings['position_bottom'] . '%;" id="buttonizer-button"><div class="buttonizer_inner" id="buttonizer-sys">' . $output . '</div></div>' ;
|
354 |
echo '
|
355 |
-
<script type="text/javascript" src="' . plugins_url( '/js/buttonizer.js?v=' . md5( BUTTONIZER_VERSION ), BUTTONIZER_PLUGIN_DIR ) . '"></script>
|
356 |
<script type="text/javascript">
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
|
|
|
|
362 |
});
|
363 |
</script>' ;
|
364 |
}
|
149 |
$buttonText = ( isset( $this->aButtons['button_' . $bNmbr . '_text'] ) ? $this->aButtons['button_' . $bNmbr . '_text'] : 'Button ' . $bNmbr );
|
150 |
$buttonTitle = ( isset( $this->aButtons['button_' . $bNmbr . '_title'] ) ? $this->aButtons['button_' . $bNmbr . '_title'] : 'Button ' . $bNmbr );
|
151 |
$buttonIsPhone = ( isset( $this->aButtons['button_' . $bNmbr . '_is_phonenumber'] ) ? $this->aButtons['button_' . $bNmbr . '_is_phonenumber'] : '' );
|
|
|
152 |
$linkNewTab = ( isset( $this->aButtons['button_' . $bNmbr . '_url_newtab'] ) ? 'target="_blank"' : '' );
|
153 |
$hideLabel = ( isset( $this->aButtons['button_' . $bNmbr . '_hide_label'] ) ? $this->aButtons['button_' . $bNmbr . '_hide_label'] : '' );
|
154 |
+
$sButtonAction = ( isset( $this->aButtons['button_' . $bNmbr . '_action'] ) ? $this->aButtons['button_' . $bNmbr . '_action'] : '' );
|
155 |
+
$sButtonActionLink = ( isset( $this->aButtons['button_' . $bNmbr . '_url'] ) ? $this->aButtons['button_' . $bNmbr . '_url'] : '' );
|
156 |
|
157 |
+
if ( 'phone' == $sButtonAction || $buttonIsPhone ) {
|
158 |
+
$sButtonActionLink = 'tel:' . str_replace( [
|
159 |
+
' ',
|
160 |
+
'+',
|
161 |
+
'?',
|
162 |
+
'#'
|
163 |
+
], '', $sButtonActionLink );
|
164 |
+
} else {
|
165 |
+
if ( 'mail' == $sButtonAction ) {
|
166 |
+
$sButtonActionLink = 'mailto:' . $sButtonActionLink;
|
167 |
}
|
168 |
}
|
169 |
|
191 |
color: ' . $this->aButtons['button_' . $bNmbr . '_colors_icon'] . ';
|
192 |
} ';
|
193 |
}
|
194 |
+
return '<a href="' . $sButtonActionLink . '" class="' . $sButtonClasses . ' buttonizer_' . $bNmbr . '" ' . $linkNewTab . ' onclick="onButtonizerClickEvent(\'' . $buttonText . '\')">' . (( $buttonText != "" ? '<div class="text"' . (( $hideLabel == '1' ? 'style="display: none;"' : '' )) . '><div>' . $buttonText . '</div></div>' : '' )) . $sButtonIcon . '</a>';
|
195 |
// Thanks, end
|
196 |
}
|
197 |
|
359 |
echo '<style>.buttonizer-button a:hover, .buttonizer-button a:focus{ background:' . $this->aSettings['button_pushed'] . '; } .buttonizer-button a { background:' . $this->aSettings['button_unpushed'] . '; } .buttonizer-button a i { color: ' . $this->aSettings['icon_color'] . '; } ' . $this->sButtonCss . '</style>
|
360 |
<div class="buttonizer-button ' . (( $showOnScroll > 0 || $showAfterTimeout > 0 ? 'hide' : '' )) . ' ' . (( isset( $this->aSettings['buttons_label_show_on_hover'] ) && $this->aSettings['buttons_label_show_on_hover'] == '1' ? ' show_labels_on_hover' : '' )) . '" button-animation="' . $sButtonAnimation . '" attention-animation="' . $sAttentionAnimation . '" style=" right: ' . $this->aSettings['position_right'] . '%; bottom: ' . $this->aSettings['position_bottom'] . '%;" id="buttonizer-button"><div class="buttonizer_inner" id="buttonizer-sys">' . $output . '</div></div>' ;
|
361 |
echo '
|
362 |
+
<script defer type="text/javascript" src="' . plugins_url( '/js/buttonizer.js?v=' . md5( BUTTONIZER_VERSION ), BUTTONIZER_PLUGIN_DIR ) . '"></script>
|
363 |
<script type="text/javascript">
|
364 |
+
document.addEventListener(\'DOMContentLoaded\', function(){
|
365 |
+
buttonizer.init({
|
366 |
+
scrollBarTop: ' . $showOnScroll . ',
|
367 |
+
showAfter: ' . $showAfterTimeout . ',
|
368 |
+
' . (( ButtonizerLicense()->is__premium_only() ? 'exitIntent: ' . $this->enableExitIntent() . ',' : '' )) . '
|
369 |
+
' . (( ButtonizerLicense()->is__premium_only() ? 'exitIntentText: "' . $this->enableExitIntentText() . '",' : '' )) . '
|
370 |
+
});
|
371 |
});
|
372 |
</script>' ;
|
373 |
}
|
@@ -74,7 +74,7 @@
|
|
74 |
}
|
75 |
|
76 |
.buttonizer-button .buttonizer_inner a.buttonizer_head i {
|
77 |
-
font-size:
|
78 |
font-style: normal;
|
79 |
width: 56px !important;
|
80 |
height: 56px !important;
|
@@ -348,12 +348,14 @@
|
|
348 |
transition-delay: 300ms;
|
349 |
}
|
350 |
|
351 |
-
.buttonizer-button.show_labels_on_hover a > .text
|
|
|
352 |
opacity: 0;
|
353 |
visibility: hidden;
|
354 |
}
|
355 |
|
356 |
-
.buttonizer-button.show_labels_on_hover a:hover > .text
|
|
|
357 |
opacity: 1;
|
358 |
visibility: visible;
|
359 |
}
|
74 |
}
|
75 |
|
76 |
.buttonizer-button .buttonizer_inner a.buttonizer_head i {
|
77 |
+
font-size: 28px !important;
|
78 |
font-style: normal;
|
79 |
width: 56px !important;
|
80 |
height: 56px !important;
|
348 |
transition-delay: 300ms;
|
349 |
}
|
350 |
|
351 |
+
.buttonizer-button.show_labels_on_hover a > .text,
|
352 |
+
.buttonizer-button.show_labels_on_hover .buttonizer_head.onlyone > .text {
|
353 |
opacity: 0;
|
354 |
visibility: hidden;
|
355 |
}
|
356 |
|
357 |
+
.buttonizer-button.show_labels_on_hover a:hover > .text,
|
358 |
+
.buttonizer-button.show_labels_on_hover .buttonizer_head.onlyone:hover > .text {
|
359 |
opacity: 1;
|
360 |
visibility: visible;
|
361 |
}
|
@@ -0,0 +1,552 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.introjs-overlay {
|
2 |
+
position: absolute;
|
3 |
+
box-sizing: content-box;
|
4 |
+
z-index: 999999;
|
5 |
+
background-color: #000;
|
6 |
+
opacity: 0;
|
7 |
+
background: -moz-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
|
8 |
+
background: -webkit-gradient(radial,center center,0px,center center,100%,color-stop(0%,rgba(0,0,0,0.4)),color-stop(100%,rgba(0,0,0,0.9)));
|
9 |
+
background: -webkit-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
|
10 |
+
background: -o-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
|
11 |
+
background: -ms-radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
|
12 |
+
background: radial-gradient(center,ellipse cover,rgba(0,0,0,0.4) 0,rgba(0,0,0,0.9) 100%);
|
13 |
+
filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#66000000',endColorstr='#e6000000',GradientType=1)";
|
14 |
+
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
|
15 |
+
filter: alpha(opacity=50);
|
16 |
+
-webkit-transition: all 0.3s ease-out;
|
17 |
+
-moz-transition: all 0.3s ease-out;
|
18 |
+
-ms-transition: all 0.3s ease-out;
|
19 |
+
-o-transition: all 0.3s ease-out;
|
20 |
+
transition: all 0.3s ease-out;
|
21 |
+
}
|
22 |
+
|
23 |
+
.introjs-fixParent {
|
24 |
+
z-index: auto !important;
|
25 |
+
opacity: 1.0 !important;
|
26 |
+
-webkit-transform: none !important;
|
27 |
+
-moz-transform: none !important;
|
28 |
+
-ms-transform: none !important;
|
29 |
+
-o-transform: none !important;
|
30 |
+
transform: none !important;
|
31 |
+
}
|
32 |
+
|
33 |
+
.introjs-showElement,
|
34 |
+
tr.introjs-showElement > td,
|
35 |
+
tr.introjs-showElement > th {
|
36 |
+
z-index: 9999999 !important;
|
37 |
+
}
|
38 |
+
|
39 |
+
.introjs-disableInteraction {
|
40 |
+
z-index: 99999999 !important;
|
41 |
+
position: absolute;
|
42 |
+
background-color: white;
|
43 |
+
opacity: 0;
|
44 |
+
filter: alpha(opacity=0);
|
45 |
+
}
|
46 |
+
|
47 |
+
.introjs-relativePosition,
|
48 |
+
tr.introjs-showElement > td,
|
49 |
+
tr.introjs-showElement > th {
|
50 |
+
position: relative;
|
51 |
+
}
|
52 |
+
|
53 |
+
.introjs-helperLayer {
|
54 |
+
box-sizing: content-box;
|
55 |
+
position: absolute;
|
56 |
+
z-index: 9999998;
|
57 |
+
background-color: #FFF;
|
58 |
+
background-color: rgba(255,255,255,.9);
|
59 |
+
border: 1px solid #777;
|
60 |
+
border: 1px solid rgba(0,0,0,.5);
|
61 |
+
border-radius: 4px;
|
62 |
+
box-shadow: 0 2px 15px rgba(0,0,0,.4);
|
63 |
+
-webkit-transition: all 0.3s ease-out;
|
64 |
+
-moz-transition: all 0.3s ease-out;
|
65 |
+
-ms-transition: all 0.3s ease-out;
|
66 |
+
-o-transition: all 0.3s ease-out;
|
67 |
+
transition: all 0.3s ease-out;
|
68 |
+
}
|
69 |
+
|
70 |
+
.introjs-tooltipReferenceLayer {
|
71 |
+
box-sizing: content-box;
|
72 |
+
position: absolute;
|
73 |
+
visibility: hidden;
|
74 |
+
z-index: 10000000;
|
75 |
+
background-color: transparent;
|
76 |
+
-webkit-transition: all 0.3s ease-out;
|
77 |
+
-moz-transition: all 0.3s ease-out;
|
78 |
+
-ms-transition: all 0.3s ease-out;
|
79 |
+
-o-transition: all 0.3s ease-out;
|
80 |
+
transition: all 0.3s ease-out;
|
81 |
+
}
|
82 |
+
|
83 |
+
.introjs-helperLayer *,
|
84 |
+
.introjs-helperLayer *:before,
|
85 |
+
.introjs-helperLayer *:after {
|
86 |
+
-webkit-box-sizing: content-box;
|
87 |
+
-moz-box-sizing: content-box;
|
88 |
+
-ms-box-sizing: content-box;
|
89 |
+
-o-box-sizing: content-box;
|
90 |
+
box-sizing: content-box;
|
91 |
+
}
|
92 |
+
|
93 |
+
.introjs-helperNumberLayer {
|
94 |
+
box-sizing: content-box;
|
95 |
+
position: absolute;
|
96 |
+
visibility: visible;
|
97 |
+
top: -16px;
|
98 |
+
left: -16px;
|
99 |
+
z-index: 9999999999 !important;
|
100 |
+
padding: 2px;
|
101 |
+
font-family: Arial, verdana, tahoma;
|
102 |
+
font-size: 13px;
|
103 |
+
font-weight: bold;
|
104 |
+
color: white;
|
105 |
+
text-align: center;
|
106 |
+
text-shadow: 1px 1px 1px rgba(0,0,0,.3);
|
107 |
+
background: #ff3019; /* Old browsers */
|
108 |
+
background: -webkit-linear-gradient(top, #ff8319 0%, #cf5804 100%); /* Chrome10+,Safari5.1+ */
|
109 |
+
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ff8319), color-stop(100%, #cf5804)); /* Chrome,Safari4+ */
|
110 |
+
background: -moz-linear-gradient(top, #ff8319 0%, #cf5804 100%); /* FF3.6+ */
|
111 |
+
background: -ms-linear-gradient(top, #ff8319 0%, #cf5804 100%); /* IE10+ */
|
112 |
+
background: -o-linear-gradient(top, #ff8319 0%, #cf5804 100%); /* Opera 11.10+ */
|
113 |
+
background: linear-gradient(to bottom, #ff8319 0%, #cf5804 100%); /* W3C */
|
114 |
+
width: 20px;
|
115 |
+
height:20px;
|
116 |
+
line-height: 20px;
|
117 |
+
border: 3px solid white;
|
118 |
+
border-radius: 50%;
|
119 |
+
filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8319', endColorstr='#cf5804', GradientType=0)"; /* IE6-9 */
|
120 |
+
filter: "progid:DXImageTransform.Microsoft.Shadow(direction=135, strength=2, color=ff0000)"; /* IE10 text shadows */
|
121 |
+
box-shadow: 0 2px 5px rgba(0,0,0,.4);
|
122 |
+
}
|
123 |
+
|
124 |
+
.introjs-arrow {
|
125 |
+
border: 5px solid white;
|
126 |
+
content:'';
|
127 |
+
position: absolute;
|
128 |
+
}
|
129 |
+
.introjs-arrow.top {
|
130 |
+
top: -10px;
|
131 |
+
border-top-color:transparent;
|
132 |
+
border-right-color:transparent;
|
133 |
+
border-bottom-color:white;
|
134 |
+
border-left-color:transparent;
|
135 |
+
}
|
136 |
+
.introjs-arrow.top-right {
|
137 |
+
top: -10px;
|
138 |
+
right: 10px;
|
139 |
+
border-top-color:transparent;
|
140 |
+
border-right-color:transparent;
|
141 |
+
border-bottom-color:white;
|
142 |
+
border-left-color:transparent;
|
143 |
+
}
|
144 |
+
.introjs-arrow.top-middle {
|
145 |
+
top: -10px;
|
146 |
+
left: 50%;
|
147 |
+
margin-left: -5px;
|
148 |
+
border-top-color:transparent;
|
149 |
+
border-right-color:transparent;
|
150 |
+
border-bottom-color:white;
|
151 |
+
border-left-color:transparent;
|
152 |
+
}
|
153 |
+
.introjs-arrow.right {
|
154 |
+
right: -10px;
|
155 |
+
top: 10px;
|
156 |
+
border-top-color:transparent;
|
157 |
+
border-right-color:transparent;
|
158 |
+
border-bottom-color:transparent;
|
159 |
+
border-left-color:white;
|
160 |
+
}
|
161 |
+
.introjs-arrow.right-bottom {
|
162 |
+
bottom:10px;
|
163 |
+
right: -10px;
|
164 |
+
border-top-color:transparent;
|
165 |
+
border-right-color:transparent;
|
166 |
+
border-bottom-color:transparent;
|
167 |
+
border-left-color:white;
|
168 |
+
}
|
169 |
+
.introjs-arrow.bottom {
|
170 |
+
bottom: -10px;
|
171 |
+
border-top-color:white;
|
172 |
+
border-right-color:transparent;
|
173 |
+
border-bottom-color:transparent;
|
174 |
+
border-left-color:transparent;
|
175 |
+
}
|
176 |
+
.introjs-arrow.left {
|
177 |
+
left: -10px;
|
178 |
+
top: 10px;
|
179 |
+
border-top-color:transparent;
|
180 |
+
border-right-color:white;
|
181 |
+
border-bottom-color:transparent;
|
182 |
+
border-left-color:transparent;
|
183 |
+
}
|
184 |
+
.introjs-arrow.left-bottom {
|
185 |
+
left: -10px;
|
186 |
+
bottom:10px;
|
187 |
+
border-top-color:transparent;
|
188 |
+
border-right-color:white;
|
189 |
+
border-bottom-color:transparent;
|
190 |
+
border-left-color:transparent;
|
191 |
+
}
|
192 |
+
|
193 |
+
.introjs-tooltip {
|
194 |
+
box-sizing: content-box;
|
195 |
+
position: absolute;
|
196 |
+
visibility: visible;
|
197 |
+
padding: 10px;
|
198 |
+
background-color: white;
|
199 |
+
min-width: 200px;
|
200 |
+
max-width: 300px;
|
201 |
+
border-radius: 3px;
|
202 |
+
box-shadow: 0 1px 10px rgba(0,0,0,.4);
|
203 |
+
-webkit-transition: opacity 0.1s ease-out;
|
204 |
+
-moz-transition: opacity 0.1s ease-out;
|
205 |
+
-ms-transition: opacity 0.1s ease-out;
|
206 |
+
-o-transition: opacity 0.1s ease-out;
|
207 |
+
transition: opacity 0.1s ease-out;
|
208 |
+
}
|
209 |
+
|
210 |
+
.introjs-tooltipbuttons {
|
211 |
+
text-align: right;
|
212 |
+
white-space: nowrap;
|
213 |
+
margin-top: 20px;
|
214 |
+
}
|
215 |
+
|
216 |
+
/*
|
217 |
+
Buttons style by http://nicolasgallagher.com/lab/css3-github-buttons/
|
218 |
+
Changed by Afshin Mehrabani
|
219 |
+
*/
|
220 |
+
.introjs-button {
|
221 |
+
box-sizing: content-box;
|
222 |
+
position: relative;
|
223 |
+
overflow: visible;
|
224 |
+
display: inline-block;
|
225 |
+
padding: 6px 17px;
|
226 |
+
margin: 0;
|
227 |
+
text-decoration: none;
|
228 |
+
font: 12px/normal sans-serif;
|
229 |
+
white-space: nowrap;
|
230 |
+
cursor: pointer;
|
231 |
+
outline: none;
|
232 |
+
-webkit-background-clip: padding;
|
233 |
+
-moz-background-clip: padding;
|
234 |
+
-o-background-clip: padding-box;
|
235 |
+
/*background-clip: padding-box;*/ /* commented out due to Opera 11.10 bug */
|
236 |
+
-webkit-border-radius: 0.2em;
|
237 |
+
-moz-border-radius: 0.2em;
|
238 |
+
border-radius: 0.2em;
|
239 |
+
/* IE hacks */
|
240 |
+
zoom: 1;
|
241 |
+
*display: inline;
|
242 |
+
margin-top: 10px;
|
243 |
+
color: #FFFFFF;
|
244 |
+
font-weight: 500;
|
245 |
+
|
246 |
+
background: #0085ba;
|
247 |
+
border: 1px solid #006799;
|
248 |
+
border-bottom-width: 2px;
|
249 |
+
border-color: #0073aa #006799 #006799;
|
250 |
+
-webkit-box-shadow: 0 1px 0 #006799;
|
251 |
+
box-shadow: 0 1px 0 #006799;
|
252 |
+
color: #fff;
|
253 |
+
text-decoration: none;
|
254 |
+
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
|
255 |
+
font-weight: 700 !important;
|
256 |
+
-webkit-touch-callout: none; /* iOS Safari */
|
257 |
+
-webkit-user-select: none; /* Safari */
|
258 |
+
-khtml-user-select: none; /* Konqueror HTML */
|
259 |
+
-moz-user-select: none; /* Firefox */
|
260 |
+
-ms-user-select: none; /* Internet Explorer/Edge */
|
261 |
+
user-select: none; /* Non-prefixed version, currently*/
|
262 |
+
|
263 |
+
}
|
264 |
+
|
265 |
+
.introjs-button:hover {
|
266 |
+
background: #008ec2;
|
267 |
+
border-color: #006799;
|
268 |
+
color: #fff;
|
269 |
+
}
|
270 |
+
|
271 |
+
.introjs-button:active {
|
272 |
+
background: #0073aa;
|
273 |
+
border-color: #006799;
|
274 |
+
-webkit-box-shadow: inset 0 2px 0 #006799;
|
275 |
+
box-shadow: inset 0 2px 0 #006799;
|
276 |
+
vertical-align: top;
|
277 |
+
}
|
278 |
+
|
279 |
+
.introjs-button:focus {
|
280 |
+
color: #FFFFFF;
|
281 |
+
}
|
282 |
+
|
283 |
+
/* overrides extra padding on button elements in Firefox */
|
284 |
+
.introjs-button::-moz-focus-inner {
|
285 |
+
padding: 0;
|
286 |
+
border: 0;
|
287 |
+
}
|
288 |
+
|
289 |
+
.introjs-skipbutton {
|
290 |
+
box-sizing: content-box;
|
291 |
+
margin-right: 5px;
|
292 |
+
}
|
293 |
+
|
294 |
+
.introjs-prevbutton {
|
295 |
+
-webkit-border-radius: 0.2em 0 0 0.2em;
|
296 |
+
-moz-border-radius: 0.2em 0 0 0.2em;
|
297 |
+
border-radius: 0.2em 0 0 0.2em;
|
298 |
+
border-right: none;
|
299 |
+
}
|
300 |
+
|
301 |
+
.introjs-prevbutton.introjs-fullbutton {
|
302 |
+
border: 1px solid #d4d4d4;
|
303 |
+
-webkit-border-radius: 0.2em;
|
304 |
+
-moz-border-radius: 0.2em;
|
305 |
+
border-radius: 0.2em;
|
306 |
+
}
|
307 |
+
|
308 |
+
.introjs-nextbutton {
|
309 |
+
-webkit-border-radius: 0 0.2em 0.2em 0;
|
310 |
+
-moz-border-radius: 0 0.2em 0.2em 0;
|
311 |
+
border-radius: 0 0.2em 0.2em 0;
|
312 |
+
|
313 |
+
background: #ee8014;
|
314 |
+
border-color: #aa6e00 #994700 #9f5b4b;
|
315 |
+
-webkit-box-shadow: 0 1px 0 #ffffff;
|
316 |
+
box-shadow: 0 1px 0 #ffffff;
|
317 |
+
color: #fff;
|
318 |
+
text-decoration: none;
|
319 |
+
text-shadow: 0 -1px 1px #995500, 1px 0 1px #994700, 0 1px 1px #993800, -1px 0 1px #995500;
|
320 |
+
padding: 6px 17px 7px;
|
321 |
+
}
|
322 |
+
|
323 |
+
.introjs-nextbutton:hover {
|
324 |
+
background: #cc750b;
|
325 |
+
border-color: #764301;
|
326 |
+
color: #fff;
|
327 |
+
}
|
328 |
+
|
329 |
+
.introjs-nextbutton:active {
|
330 |
+
background: #aa4e00;
|
331 |
+
border-color: #993100;
|
332 |
+
-webkit-box-shadow: inset 0 2px 0 #993800;
|
333 |
+
box-shadow: inset 0 2px 0 #993800;
|
334 |
+
vertical-align: top;
|
335 |
+
}
|
336 |
+
|
337 |
+
.introjs-nextbutton.introjs-fullbutton {
|
338 |
+
-webkit-border-radius: 0.2em;
|
339 |
+
-moz-border-radius: 0.2em;
|
340 |
+
border-radius: 0.2em;
|
341 |
+
}
|
342 |
+
|
343 |
+
.introjs-disabled, .introjs-disabled:hover, .introjs-disabled:focus {
|
344 |
+
opacity: 0.8;
|
345 |
+
}
|
346 |
+
|
347 |
+
.introjs-hidden {
|
348 |
+
display: none;
|
349 |
+
}
|
350 |
+
|
351 |
+
.introjs-bullets {
|
352 |
+
text-align: center;
|
353 |
+
}
|
354 |
+
.introjs-bullets ul {
|
355 |
+
box-sizing: content-box;
|
356 |
+
clear: both;
|
357 |
+
margin: 15px auto 0;
|
358 |
+
padding: 0;
|
359 |
+
display: inline-block;
|
360 |
+
}
|
361 |
+
.introjs-bullets ul li {
|
362 |
+
box-sizing: content-box;
|
363 |
+
list-style: none;
|
364 |
+
float: left;
|
365 |
+
margin: 0 2px;
|
366 |
+
}
|
367 |
+
.introjs-bullets ul li a {
|
368 |
+
box-sizing: content-box;
|
369 |
+
display: block;
|
370 |
+
width: 6px;
|
371 |
+
height: 6px;
|
372 |
+
background: #ccc;
|
373 |
+
border-radius: 10px;
|
374 |
+
-moz-border-radius: 10px;
|
375 |
+
-webkit-border-radius: 10px;
|
376 |
+
text-decoration: none;
|
377 |
+
cursor: pointer;
|
378 |
+
}
|
379 |
+
.introjs-bullets ul li a:hover {
|
380 |
+
background: #999;
|
381 |
+
}
|
382 |
+
.introjs-bullets ul li a.active {
|
383 |
+
background: #999;
|
384 |
+
}
|
385 |
+
|
386 |
+
.introjs-progress {
|
387 |
+
box-sizing: content-box;
|
388 |
+
overflow: hidden;
|
389 |
+
height: 10px;
|
390 |
+
margin: 10px 0 5px 0;
|
391 |
+
border-radius: 4px;
|
392 |
+
background-color: #ecf0f1
|
393 |
+
}
|
394 |
+
.introjs-progressbar {
|
395 |
+
box-sizing: content-box;
|
396 |
+
float: left;
|
397 |
+
width: 0%;
|
398 |
+
height: 100%;
|
399 |
+
font-size: 10px;
|
400 |
+
line-height: 10px;
|
401 |
+
text-align: center;
|
402 |
+
background-color: #08c;
|
403 |
+
}
|
404 |
+
|
405 |
+
.introjsFloatingElement {
|
406 |
+
position: absolute;
|
407 |
+
height: 0;
|
408 |
+
width: 0;
|
409 |
+
left: 50%;
|
410 |
+
top: 50%;
|
411 |
+
}
|
412 |
+
|
413 |
+
.introjs-fixedTooltip {
|
414 |
+
position: fixed;
|
415 |
+
}
|
416 |
+
|
417 |
+
.introjs-hint {
|
418 |
+
box-sizing: content-box;
|
419 |
+
position: absolute;
|
420 |
+
background: transparent;
|
421 |
+
width: 20px;
|
422 |
+
height: 15px;
|
423 |
+
cursor: pointer;
|
424 |
+
}
|
425 |
+
.introjs-hint:focus {
|
426 |
+
border: 0;
|
427 |
+
outline: 0;
|
428 |
+
}
|
429 |
+
.introjs-hidehint {
|
430 |
+
display: none;
|
431 |
+
}
|
432 |
+
|
433 |
+
.introjs-fixedhint {
|
434 |
+
position: fixed;
|
435 |
+
}
|
436 |
+
|
437 |
+
.introjs-hint:hover > .introjs-hint-pulse {
|
438 |
+
border: 5px solid rgba(60, 60, 60, 0.57);
|
439 |
+
}
|
440 |
+
|
441 |
+
.introjs-hint-pulse {
|
442 |
+
box-sizing: content-box;
|
443 |
+
width: 10px;
|
444 |
+
height: 10px;
|
445 |
+
border: 5px solid rgba(60, 60, 60, 0.27);
|
446 |
+
-webkit-border-radius: 30px;
|
447 |
+
-moz-border-radius: 30px;
|
448 |
+
border-radius: 30px;
|
449 |
+
background-color: rgba(136, 136, 136, 0.24);
|
450 |
+
z-index: 10;
|
451 |
+
position: absolute;
|
452 |
+
-webkit-transition: all 0.2s ease-out;
|
453 |
+
-moz-transition: all 0.2s ease-out;
|
454 |
+
-ms-transition: all 0.2s ease-out;
|
455 |
+
-o-transition: all 0.2s ease-out;
|
456 |
+
transition: all 0.2s ease-out;
|
457 |
+
}
|
458 |
+
.introjs-hint-no-anim .introjs-hint-dot {
|
459 |
+
-webkit-animation: none;
|
460 |
+
-moz-animation: none;
|
461 |
+
animation: none;
|
462 |
+
}
|
463 |
+
.introjs-hint-dot {
|
464 |
+
box-sizing: content-box;
|
465 |
+
border: 10px solid rgba(146, 146, 146, 0.36);
|
466 |
+
background: transparent;
|
467 |
+
-webkit-border-radius: 60px;
|
468 |
+
-moz-border-radius: 60px;
|
469 |
+
border-radius: 60px;
|
470 |
+
height: 50px;
|
471 |
+
width: 50px;
|
472 |
+
-webkit-animation: introjspulse 3s ease-out;
|
473 |
+
-moz-animation: introjspulse 3s ease-out;
|
474 |
+
animation: introjspulse 3s ease-out;
|
475 |
+
-webkit-animation-iteration-count: infinite;
|
476 |
+
-moz-animation-iteration-count: infinite;
|
477 |
+
animation-iteration-count: infinite;
|
478 |
+
position: absolute;
|
479 |
+
top: -25px;
|
480 |
+
left: -25px;
|
481 |
+
z-index: 1;
|
482 |
+
opacity: 0;
|
483 |
+
}
|
484 |
+
|
485 |
+
@-webkit-keyframes introjspulse {
|
486 |
+
0% {
|
487 |
+
-webkit-transform: scale(0);
|
488 |
+
opacity: 0.0;
|
489 |
+
}
|
490 |
+
25% {
|
491 |
+
-webkit-transform: scale(0);
|
492 |
+
opacity: 0.1;
|
493 |
+
}
|
494 |
+
50% {
|
495 |
+
-webkit-transform: scale(0.1);
|
496 |
+
opacity: 0.3;
|
497 |
+
}
|
498 |
+
75% {
|
499 |
+
-webkit-transform: scale(0.5);
|
500 |
+
opacity: 0.5;
|
501 |
+
}
|
502 |
+
100% {
|
503 |
+
-webkit-transform: scale(1);
|
504 |
+
opacity: 0.0;
|
505 |
+
}
|
506 |
+
}
|
507 |
+
|
508 |
+
@-moz-keyframes introjspulse {
|
509 |
+
0% {
|
510 |
+
-moz-transform: scale(0);
|
511 |
+
opacity: 0.0;
|
512 |
+
}
|
513 |
+
25% {
|
514 |
+
-moz-transform: scale(0);
|
515 |
+
opacity: 0.1;
|
516 |
+
}
|
517 |
+
50% {
|
518 |
+
-moz-transform: scale(0.1);
|
519 |
+
opacity: 0.3;
|
520 |
+
}
|
521 |
+
75% {
|
522 |
+
-moz-transform: scale(0.5);
|
523 |
+
opacity: 0.5;
|
524 |
+
}
|
525 |
+
100% {
|
526 |
+
-moz-transform: scale(1);
|
527 |
+
opacity: 0.0;
|
528 |
+
}
|
529 |
+
}
|
530 |
+
|
531 |
+
@keyframes introjspulse {
|
532 |
+
0% {
|
533 |
+
transform: scale(0);
|
534 |
+
opacity: 0.0;
|
535 |
+
}
|
536 |
+
25% {
|
537 |
+
transform: scale(0);
|
538 |
+
opacity: 0.1;
|
539 |
+
}
|
540 |
+
50% {
|
541 |
+
transform: scale(0.1);
|
542 |
+
opacity: 0.3;
|
543 |
+
}
|
544 |
+
75% {
|
545 |
+
transform: scale(0.5);
|
546 |
+
opacity: 0.5;
|
547 |
+
}
|
548 |
+
100% {
|
549 |
+
transform: scale(1);
|
550 |
+
opacity: 0.0;
|
551 |
+
}
|
552 |
+
}
|
@@ -46,6 +46,7 @@ h2 .button {
|
|
46 |
color: #9d8a7e;
|
47 |
padding: 3px 5px;
|
48 |
margin-right: 4px;
|
|
|
49 |
}
|
50 |
|
51 |
.info-class >span {
|
@@ -65,14 +66,17 @@ h2 .button {
|
|
65 |
-webkit-border-top-left-radius: 0;
|
66 |
min-width: 200px;
|
67 |
padding: 10px;
|
68 |
-
background-color:
|
69 |
-
color: #
|
70 |
font-weight: 200;
|
|
|
|
|
71 |
}
|
72 |
|
73 |
.info-class:hover >i {
|
74 |
-
background-color:
|
75 |
-
color:
|
|
|
76 |
|
77 |
border-top-left-radius: 3px;
|
78 |
-moz-border-top-left-radius: 3px;
|
@@ -82,6 +86,9 @@ h2 .button {
|
|
82 |
-moz-border-top-right-radius: 3px;
|
83 |
-webkit-border-top-right-radius: 3px;
|
84 |
|
|
|
|
|
|
|
85 |
}
|
86 |
|
87 |
.info-class:hover >span {
|
@@ -307,6 +314,25 @@ h2 .button {
|
|
307 |
background-color: blue;
|
308 |
}
|
309 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
.button-row .button-color-palet {
|
311 |
border: 1px solid #ccc;
|
312 |
-webkit-box-shadow: 0 1px 0 #ccc;
|
@@ -359,6 +385,11 @@ h2 .button {
|
|
359 |
height: 24px;
|
360 |
}
|
361 |
|
|
|
|
|
|
|
|
|
|
|
362 |
.button-preview {
|
363 |
border-radius: 50%;
|
364 |
width: 56px;
|
@@ -450,7 +481,8 @@ h2 .button {
|
|
450 |
padding-top: 15px;
|
451 |
}
|
452 |
|
453 |
-
.form-table .r-sit .after-input
|
|
|
454 |
position: absolute;
|
455 |
right: 11px;
|
456 |
top: 20px;
|
@@ -458,10 +490,20 @@ h2 .button {
|
|
458 |
line-height: 35px;
|
459 |
}
|
460 |
|
461 |
-
.form-table .r-sit
|
|
|
|
|
|
|
|
|
|
|
|
|
462 |
top: 17px;
|
463 |
}
|
464 |
|
|
|
|
|
|
|
|
|
465 |
.form-table fieldset {
|
466 |
border: 1px solid #d7d7d7;
|
467 |
background-color: #f7f7f7;
|
@@ -510,6 +552,15 @@ h2 .button {
|
|
510 |
left: 200px;
|
511 |
}
|
512 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
/* Categories */
|
514 |
.categories-load-more {
|
515 |
display: block;
|
@@ -586,7 +637,7 @@ h2 .button {
|
|
586 |
box-shadow: 0px 0px 10px rgba(183, 183, 183, 0.18);
|
587 |
min-width: 250px;
|
588 |
border: 1px solid #e7e7e7;
|
589 |
-
z-index:
|
590 |
}
|
591 |
|
592 |
.fontawesome-searcher .fontawesome-searcher-searchbar {
|
46 |
color: #9d8a7e;
|
47 |
padding: 3px 5px;
|
48 |
margin-right: 4px;
|
49 |
+
border: 1px solid rgba(0, 0, 0, 0);
|
50 |
}
|
51 |
|
52 |
.info-class >span {
|
66 |
-webkit-border-top-left-radius: 0;
|
67 |
min-width: 200px;
|
68 |
padding: 10px;
|
69 |
+
background-color: #FFFFFF;
|
70 |
+
color: #333333;
|
71 |
font-weight: 200;
|
72 |
+
line-height: 20px;
|
73 |
+
border: 1px solid #d2d2d2;
|
74 |
}
|
75 |
|
76 |
.info-class:hover >i {
|
77 |
+
background-color: #FFFFFF;
|
78 |
+
color: #f08216;
|
79 |
+
border-color: #d2d2d2;
|
80 |
|
81 |
border-top-left-radius: 3px;
|
82 |
-moz-border-top-left-radius: 3px;
|
86 |
-moz-border-top-right-radius: 3px;
|
87 |
-webkit-border-top-right-radius: 3px;
|
88 |
|
89 |
+
position: relative;
|
90 |
+
z-index: 800;
|
91 |
+
border-bottom: 0;
|
92 |
}
|
93 |
|
94 |
.info-class:hover >span {
|
314 |
background-color: blue;
|
315 |
}
|
316 |
|
317 |
+
.button-row table.settings-row-type tr td {
|
318 |
+
vertical-align: top;
|
319 |
+
}
|
320 |
+
|
321 |
+
.button-row table.settings-row-type .input_error {
|
322 |
+
background-color: #ffcfcf;
|
323 |
+
color: #ff0000;
|
324 |
+
border: 1px solid #cc6a6a;
|
325 |
+
padding: 10px 20px;
|
326 |
+
margin-top: 8px;
|
327 |
+
border-radius: 2px;
|
328 |
+
-webkit-border-radius: 2px;
|
329 |
+
-moz-border-radius: 2px;
|
330 |
+
}
|
331 |
+
|
332 |
+
.button-row table.settings-row-type .input_error p {
|
333 |
+
margin: 0;
|
334 |
+
}
|
335 |
+
|
336 |
.button-row .button-color-palet {
|
337 |
border: 1px solid #ccc;
|
338 |
-webkit-box-shadow: 0 1px 0 #ccc;
|
385 |
height: 24px;
|
386 |
}
|
387 |
|
388 |
+
.button-row .extra_info {
|
389 |
+
padding: 5px;
|
390 |
+
line-height: 20px;
|
391 |
+
}
|
392 |
+
|
393 |
.button-preview {
|
394 |
border-radius: 50%;
|
395 |
width: 56px;
|
481 |
padding-top: 15px;
|
482 |
}
|
483 |
|
484 |
+
.form-table .r-sit .after-input,
|
485 |
+
.form-table .r-sit .before-input {
|
486 |
position: absolute;
|
487 |
right: 11px;
|
488 |
top: 20px;
|
490 |
line-height: 35px;
|
491 |
}
|
492 |
|
493 |
+
.form-table .r-sit .before-input {
|
494 |
+
right: auto;
|
495 |
+
left: 11px;
|
496 |
+
}
|
497 |
+
|
498 |
+
.form-table .r-sit small.after-input,
|
499 |
+
.form-table .r-sit small.before-input {
|
500 |
top: 17px;
|
501 |
}
|
502 |
|
503 |
+
.form-table .r-sit .before-input-padding {
|
504 |
+
padding-left: 40px;
|
505 |
+
}
|
506 |
+
|
507 |
.form-table fieldset {
|
508 |
border: 1px solid #d7d7d7;
|
509 |
background-color: #f7f7f7;
|
552 |
left: 200px;
|
553 |
}
|
554 |
|
555 |
+
.form-table .wp-picker-container {
|
556 |
+
position: relative;
|
557 |
+
}
|
558 |
+
|
559 |
+
.form-table .wp-picker-container.wp-picker-active .wp-picker-holder {
|
560 |
+
position: absolute;
|
561 |
+
z-index: 99999;
|
562 |
+
}
|
563 |
+
|
564 |
/* Categories */
|
565 |
.categories-load-more {
|
566 |
display: block;
|
637 |
box-shadow: 0px 0px 10px rgba(183, 183, 183, 0.18);
|
638 |
min-width: 250px;
|
639 |
border: 1px solid #e7e7e7;
|
640 |
+
z-index: 99999999;
|
641 |
}
|
642 |
|
643 |
.fontawesome-searcher .fontawesome-searcher-searchbar {
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
output/
|
2 |
+
assets/img/icon.*
|
3 |
+
|
4 |
+
pootle-page-builder.png
|
5 |
+
rating-widget.jpg
|
6 |
+
hello-dolly-pro.png
|
7 |
+
woocommerce-fiscalita-italiana.png
|
8 |
+
assets/img/content-aware-sidebars.png
|
9 |
+
assets/img/custom-post-type-ui.png
|
10 |
+
.idea
|
11 |
+
nextgen-gallery.png
|
12 |
+
node_modules
|
13 |
+
languages/_freemius-en.mo
|
14 |
+
languages/_freemius-en.po
|
15 |
+
foobox-image-lightbox.png
|
16 |
+
transifex-config.json
|
@@ -26,7 +26,7 @@ var buttonizer = {
|
|
26 |
this.settings.exitIntent = options.exitIntent;
|
27 |
this.settings.exitIntentText = options.exitIntentText;
|
28 |
|
29 |
-
|
30 |
},
|
31 |
ready: function() {
|
32 |
if(document.getElementById("buttonizer-sys") != null) {
|
@@ -42,6 +42,10 @@ var buttonizer = {
|
|
42 |
}, false);
|
43 |
|
44 |
document.getElementById("buttonizer-sys").addEventListener("click", function() {
|
|
|
|
|
|
|
|
|
45 |
if(buttonizer.settings.buttonizerOpened == true) {
|
46 |
document.getElementById("buttonizer-sys").className = 'buttonizer_inner';
|
47 |
buttonizer.settings.buttonizerOpened = false;
|
26 |
this.settings.exitIntent = options.exitIntent;
|
27 |
this.settings.exitIntentText = options.exitIntentText;
|
28 |
|
29 |
+
this.ready();
|
30 |
},
|
31 |
ready: function() {
|
32 |
if(document.getElementById("buttonizer-sys") != null) {
|
42 |
}, false);
|
43 |
|
44 |
document.getElementById("buttonizer-sys").addEventListener("click", function() {
|
45 |
+
if(document.querySelector("#buttonizer-sys .buttonizer_head.onlyone") != null) {
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
|
49 |
if(buttonizer.settings.buttonizerOpened == true) {
|
50 |
document.getElementById("buttonizer-sys").className = 'buttonizer_inner';
|
51 |
buttonizer.settings.buttonizerOpened = false;
|
@@ -21,6 +21,7 @@ var buttonizer = {
|
|
21 |
buttonizer.overwriteFavIcon();
|
22 |
buttonizer.faInit();
|
23 |
buttonizer.initButtons();
|
|
|
24 |
|
25 |
// WP color picker
|
26 |
jQuery('#button_unpushed').wpColorPicker();
|
@@ -74,8 +75,10 @@ var buttonizer = {
|
|
74 |
|
75 |
// Hash
|
76 |
if(document.location.hash != "") {
|
77 |
-
|
78 |
-
|
|
|
|
|
79 |
}
|
80 |
|
81 |
jQuery(".buttonizer-click-to-pro").each(function() {
|
@@ -335,6 +338,7 @@ var buttonizer = {
|
|
335 |
scroll: true,
|
336 |
scrollSensitivity: 30,
|
337 |
scrollSpeed: 10,
|
|
|
338 |
|
339 |
onSort: function (evt) {
|
340 |
jQuery("#" + evt.clone.children[0].id + " .row-info").css({
|
@@ -470,6 +474,8 @@ var buttonizer = {
|
|
470 |
// Image icon handler
|
471 |
buttonizer.iconImageHandler(rowObj.find(".icon-or-image"));
|
472 |
buttonizer.colorPaletHandler(rowObj.find(".button-color-palet"));
|
|
|
|
|
473 |
}
|
474 |
});
|
475 |
},
|
@@ -650,6 +656,13 @@ var buttonizer = {
|
|
650 |
jQuery("#btn_row_"+ buttonId + " input.pushed").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_colors_pushed]");
|
651 |
jQuery("#btn_row_"+ buttonId + " input.icon").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_colors_icon]");
|
652 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
653 |
// Show on phone
|
654 |
jQuery("#btn_row_"+ buttonId + " .button_showonphone")
|
655 |
.attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_show_on_phone]")
|
@@ -713,6 +726,176 @@ var buttonizer = {
|
|
713 |
jQuery("#btn_row_"+ buttonId + " .mobiledesktop.desktop-button").attr("href", "javascript:buttonizer.toggleDesktop("+ buttonId +")");
|
714 |
},
|
715 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
716 |
createWindow: function(data) {
|
717 |
this.settings.windowNumber++;
|
718 |
var currentWindow = this.settings.windowNumber;
|
@@ -741,6 +924,10 @@ var buttonizer = {
|
|
741 |
data.onConfirm = function() {};
|
742 |
}
|
743 |
|
|
|
|
|
|
|
|
|
744 |
if(!data.onClose) {
|
745 |
data.onClose = function() {};
|
746 |
}
|
@@ -773,6 +960,10 @@ var buttonizer = {
|
|
773 |
data.onConfirm();
|
774 |
}
|
775 |
|
|
|
|
|
|
|
|
|
776 |
data.onClose();
|
777 |
})
|
778 |
},
|
@@ -879,6 +1070,305 @@ var buttonizer = {
|
|
879 |
buttonizer.faSettings.currentSelect.val(icon).change();
|
880 |
buttonizer.faSettings.currentObject.html("Icon: "+ icon +" <i class=\"fa "+ icon +"\"></i>");
|
881 |
jQuery("#" + buttonizer.faSettings.currentObject.attr("id")).click();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
882 |
}
|
883 |
}
|
884 |
|
21 |
buttonizer.overwriteFavIcon();
|
22 |
buttonizer.faInit();
|
23 |
buttonizer.initButtons();
|
24 |
+
buttonizer.initIntro();
|
25 |
|
26 |
// WP color picker
|
27 |
jQuery('#button_unpushed').wpColorPicker();
|
75 |
|
76 |
// Hash
|
77 |
if(document.location.hash != "") {
|
78 |
+
if(document.location.hash != "#buttonizer-tour") {
|
79 |
+
var tabKey = document.location.hash;
|
80 |
+
buttonizer.tabNavigate(tabKey.replace("#tab_", ""));
|
81 |
+
}
|
82 |
}
|
83 |
|
84 |
jQuery(".buttonizer-click-to-pro").each(function() {
|
338 |
scroll: true,
|
339 |
scrollSensitivity: 30,
|
340 |
scrollSpeed: 10,
|
341 |
+
handle: ".drag-handle",
|
342 |
|
343 |
onSort: function (evt) {
|
344 |
jQuery("#" + evt.clone.children[0].id + " .row-info").css({
|
474 |
// Image icon handler
|
475 |
buttonizer.iconImageHandler(rowObj.find(".icon-or-image"));
|
476 |
buttonizer.colorPaletHandler(rowObj.find(".button-color-palet"));
|
477 |
+
|
478 |
+
buttonizer.buttonTypeHandler(rowObj);
|
479 |
}
|
480 |
});
|
481 |
},
|
656 |
jQuery("#btn_row_"+ buttonId + " input.pushed").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_colors_pushed]");
|
657 |
jQuery("#btn_row_"+ buttonId + " input.icon").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_colors_icon]");
|
658 |
|
659 |
+
// Button action
|
660 |
+
jQuery("#btn_row_"+ buttonId + " .button_action").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_action]");
|
661 |
+
|
662 |
+
// Button value
|
663 |
+
jQuery("#btn_row_"+ buttonId + " .button_input").attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_url]");
|
664 |
+
|
665 |
+
|
666 |
// Show on phone
|
667 |
jQuery("#btn_row_"+ buttonId + " .button_showonphone")
|
668 |
.attr("name", buttonizer.settings.wpButtonSaveKey + "[button_"+ buttonId +"_show_on_phone]")
|
726 |
jQuery("#btn_row_"+ buttonId + " .mobiledesktop.desktop-button").attr("href", "javascript:buttonizer.toggleDesktop("+ buttonId +")");
|
727 |
},
|
728 |
|
729 |
+
/* Button type handler */
|
730 |
+
buttonTypeHandler: function(rowObj) {
|
731 |
+
var currentButtonType = rowObj.find(".button_action");
|
732 |
+
var currentButtonInput = rowObj.find(".button_input");
|
733 |
+
var newTab = rowObj.find(".setting-new-tab");
|
734 |
+
|
735 |
+
var isInitializing = true;
|
736 |
+
|
737 |
+
var waitUntilTriggering = setTimeout(function() {});
|
738 |
+
|
739 |
+
// The button type
|
740 |
+
currentButtonType.change(function() {
|
741 |
+
isInitializing = true;
|
742 |
+
checkInput();
|
743 |
+
});
|
744 |
+
|
745 |
+
currentButtonInput.keyup(function() {
|
746 |
+
clearInterval(waitUntilTriggering);
|
747 |
+
|
748 |
+
waitUntilTriggering = setTimeout(function(){
|
749 |
+
isInitializing = true;
|
750 |
+
checkInput();
|
751 |
+
}, 250);
|
752 |
+
});
|
753 |
+
|
754 |
+
currentButtonInput.change(checkInput);
|
755 |
+
|
756 |
+
//
|
757 |
+
function checkInput() {
|
758 |
+
var inputError = false;
|
759 |
+
var currentAction = currentButtonType.val();
|
760 |
+
var currentValueText = currentButtonInput.val();
|
761 |
+
|
762 |
+
// if(!isInitializing && currentValueText == '') {
|
763 |
+
// isInitializing = false;
|
764 |
+
// rowObj.find(".input_error").html('Hello there... You left the input empty here... Do you want to fill him up? It\'s up to you.').show();
|
765 |
+
// return;
|
766 |
+
// }
|
767 |
+
|
768 |
+
if(currentButtonType.val() == 'url') {
|
769 |
+
newTab.show();
|
770 |
+
}else{
|
771 |
+
newTab.hide();
|
772 |
+
}
|
773 |
+
|
774 |
+
if(currentAction == 'url' && currentValueText == '#') {
|
775 |
+
inputError = true;
|
776 |
+
rowObj.find(".input_error").html('<p>You only have #... That doesn\'t open anything...</p>');
|
777 |
+
}else if(currentAction == 'url' && !buttonizer.buttonTypeInputController(currentValueText, 'url')) {
|
778 |
+
inputError = true;
|
779 |
+
rowObj.find(".input_error").html('<p>This looks like an invalid URL. The button may not work as expected.</p><p> </p><p>Do you miss <b>http://</b> or <b>https://</b>? A space somewhere on the wrong place?</p>');
|
780 |
+
}
|
781 |
+
|
782 |
+
if((currentAction == 'phone' || currentAction == 'whatsapp') && !/^(?=.*\d)[\d ]+$/.test(currentValueText)) {
|
783 |
+
inputError = true;
|
784 |
+
rowObj.find(".input_error").html('Invalid phone number. Please use only the number format. Omit any zeroes, brackets or dashes when adding the phone number in international format.');
|
785 |
+
}
|
786 |
+
|
787 |
+
if(currentAction == 'mail' && !buttonizer.buttonTypeInputController(currentValueText, 'mail')) {
|
788 |
+
inputError = true;
|
789 |
+
rowObj.find(".input_error").html('<p>This looks like an invalid mail address. Make sure the mail address looks like <b><i>user</i>@domain.com</b></p>');
|
790 |
+
}
|
791 |
+
|
792 |
+
|
793 |
+
/* Premium Code Stripped by Freemius */
|
794 |
+
|
795 |
+
|
796 |
+
if(!isInitializing && currentValueText == '') {
|
797 |
+
rowObj.find(".input_error").html('Uhm... You forgot something to fill in...').show();
|
798 |
+
return;
|
799 |
+
}
|
800 |
+
|
801 |
+
// Stay here
|
802 |
+
if(!isInitializing) {
|
803 |
+
if(currentAction != 'phone' && currentAction != 'whatsapp' && /^(?=.*\d)[\d ]+$/.test(currentValueText)) {
|
804 |
+
buttonizer.createWindow({
|
805 |
+
title: 'Uhm? Shall I call you?',
|
806 |
+
text:
|
807 |
+
'<p>It\'s looks like you are having a phone number as value. Do you want to let this button behave as a call button?</p>' +
|
808 |
+
'<p>If it\'s not a phone number, you can click \'No thanks\'. If you click \'Yes please\' I will change it for you.</p>',
|
809 |
+
|
810 |
+
confirmText: 'Yes please',
|
811 |
+
canCancel: true,
|
812 |
+
cancelText: 'No thanks',
|
813 |
+
|
814 |
+
onConfirm: function() {
|
815 |
+
currentButtonType.val('phone');
|
816 |
+
rowObj.find(".input_error").hide();
|
817 |
+
}
|
818 |
+
});
|
819 |
+
}
|
820 |
+
|
821 |
+
if(currentAction != 'url' && buttonizer.buttonTypeInputController(currentValueText, 'url')) {
|
822 |
+
buttonizer.createWindow({
|
823 |
+
title: 'Uhm? WWW.?',
|
824 |
+
text:
|
825 |
+
'<p>It\'s looks like you are having a website URL as value. Do you want to let this button behave as a link?</p>' +
|
826 |
+
'<p>If you just about to change that, you can click \'No thanks\'. If you click \'Yes please\' I will change it for you.</p>',
|
827 |
+
|
828 |
+
confirmText: 'Yes please',
|
829 |
+
canCancel: true,
|
830 |
+
cancelText: 'No thanks',
|
831 |
+
|
832 |
+
onConfirm: function() {
|
833 |
+
currentButtonType.val('url');
|
834 |
+
rowObj.find(".input_error").hide();
|
835 |
+
}
|
836 |
+
});
|
837 |
+
}
|
838 |
+
|
839 |
+
if(currentAction != 'mail' && buttonizer.buttonTypeInputController(currentValueText, 'mail')) {
|
840 |
+
buttonizer.createWindow({
|
841 |
+
title: 'Uhm? That\'s a mail address?',
|
842 |
+
text:
|
843 |
+
'<p>It\'s looks like you are having a mail address as value. Do you want to change the button action to open the mail program?</p>' +
|
844 |
+
'<p>If you just about to change that, you can click \'No thanks\'. If you click \'Yes please\' I will change it for you.</p>',
|
845 |
+
|
846 |
+
confirmText: 'Yes please',
|
847 |
+
canCancel: true,
|
848 |
+
cancelText: 'No thanks',
|
849 |
+
|
850 |
+
onConfirm: function() {
|
851 |
+
currentButtonType.val('mail');
|
852 |
+
currentButtonInput.val(currentValueText.replace("mailto:", ""));
|
853 |
+
rowObj.find(".input_error").hide();
|
854 |
+
}
|
855 |
+
});
|
856 |
+
}
|
857 |
+
|
858 |
+
|
859 |
+
/* Premium Code Stripped by Freemius */
|
860 |
+
|
861 |
+
}
|
862 |
+
|
863 |
+
if(inputError) {
|
864 |
+
rowObj.find(".input_error").show();
|
865 |
+
}else{
|
866 |
+
rowObj.find(".input_error").hide();
|
867 |
+
}
|
868 |
+
|
869 |
+
isInitializing = false;
|
870 |
+
};
|
871 |
+
|
872 |
+
// Start
|
873 |
+
checkInput();
|
874 |
+
},
|
875 |
+
|
876 |
+
buttonTypeInputController: function(inputValue, action) {
|
877 |
+
var websiteUrlPattern = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
|
878 |
+
var mailUrlPattern = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
|
879 |
+
|
880 |
+
// URL
|
881 |
+
if(action == 'url') {
|
882 |
+
if(!websiteUrlPattern.test(inputValue) && !websiteUrlPattern.substring(0, 1) == '#') {
|
883 |
+
return false;
|
884 |
+
} else {
|
885 |
+
return true;
|
886 |
+
}
|
887 |
+
}else
|
888 |
+
|
889 |
+
// E-mail
|
890 |
+
if(action == 'mail') {
|
891 |
+
if(!mailUrlPattern.test(inputValue) && inputValue.indexOf("mailto:") == -1) {
|
892 |
+
return false;
|
893 |
+
} else {
|
894 |
+
return true;
|
895 |
+
}
|
896 |
+
}
|
897 |
+
},
|
898 |
+
|
899 |
createWindow: function(data) {
|
900 |
this.settings.windowNumber++;
|
901 |
var currentWindow = this.settings.windowNumber;
|
924 |
data.onConfirm = function() {};
|
925 |
}
|
926 |
|
927 |
+
if(!data.onCancel) {
|
928 |
+
data.onCancel = function() {};
|
929 |
+
}
|
930 |
+
|
931 |
if(!data.onClose) {
|
932 |
data.onClose = function() {};
|
933 |
}
|
960 |
data.onConfirm();
|
961 |
}
|
962 |
|
963 |
+
if(jQuery(this).hasClass("cancel")) {
|
964 |
+
data.onCancel();
|
965 |
+
}
|
966 |
+
|
967 |
data.onClose();
|
968 |
})
|
969 |
},
|
1070 |
buttonizer.faSettings.currentSelect.val(icon).change();
|
1071 |
buttonizer.faSettings.currentObject.html("Icon: "+ icon +" <i class=\"fa "+ icon +"\"></i>");
|
1072 |
jQuery("#" + buttonizer.faSettings.currentObject.attr("id")).click();
|
1073 |
+
},
|
1074 |
+
|
1075 |
+
/* intro */
|
1076 |
+
initIntro: function() {
|
1077 |
+
var openedDesign = false;
|
1078 |
+
|
1079 |
+
if(RegExp("welcome-splash", "gi").test(document.location.href)) {
|
1080 |
+
buttonizer.createWindow({
|
1081 |
+
title: 'Welcome to Buttonizer',
|
1082 |
+
text:
|
1083 |
+
'<img src="'+ jQuery(".buttonizer-logo img").attr("src").replace("logo.png", "plugin-icon.png") +'" width="100" align="left" style="margin-right: 20px; margin-bottom: 50px;" />' +
|
1084 |
+
'<p>We are pleasured to welcome you to Buttonizer!</p>' +
|
1085 |
+
'<p>We\'ve created a tour for our new users, would you like to take the tour? We will make your first Buttonizer button there and show some things how it works!</p>' +
|
1086 |
+
'<p>Would you like to take the tour?</p>',
|
1087 |
+
|
1088 |
+
confirmText: 'Yes please <i class="fa fa-chevron-right" style="margin-left: 10px; vertical-align: middle;" aria-hidden="true"></i>',
|
1089 |
+
canCancel: true,
|
1090 |
+
cancelText: 'No thanks, I know how it works',
|
1091 |
+
|
1092 |
+
onConfirm: function() {
|
1093 |
+
document.location.href = '?page=Buttonizer&tab=buttonizer_general_settings#buttonizer-tour';
|
1094 |
+
},
|
1095 |
+
|
1096 |
+
onCancel: function() {
|
1097 |
+
document.location.href = '?page=Buttonizer';
|
1098 |
+
}
|
1099 |
+
});
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
// Check if we need to send the user to the next page
|
1103 |
+
if(RegExp("buttonizer_tour_ready=toStep2", "gi").test(document.cookie)) {
|
1104 |
+
var d = new Date();
|
1105 |
+
d.setTime(d.getTime() - 10);
|
1106 |
+
document.cookie = "buttonizer_tour_ready=toStep2;expires="+ d.toUTCString() + ";path=/";
|
1107 |
+
|
1108 |
+
document.location.href = './admin.php?page=Buttonizer&tab=buttonizer_buttons#buttonizer-tour';
|
1109 |
+
return;
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
jQuery("#take-the-tour").click(function() {
|
1113 |
+
setTimeout(function() {
|
1114 |
+
if (RegExp("buttonizer_general_settings", "gi").test(window.location.href)) {
|
1115 |
+
buttonizer.initIntro();
|
1116 |
+
}
|
1117 |
+
}, 250);
|
1118 |
+
});
|
1119 |
+
|
1120 |
+
if (RegExp("buttonizer-tour", "gi").test(window.location.href)) {
|
1121 |
+
|
1122 |
+
// Page one: General settings
|
1123 |
+
if(document.location.href.indexOf('buttonizer_general_settings') != -1) {
|
1124 |
+
var buttonizer_tour_1 = buttonizer.startTour('design');
|
1125 |
+
buttonizer.tabNavigate('design');
|
1126 |
+
|
1127 |
+
buttonizer_tour_1.onbeforechange(function(targetElement) {
|
1128 |
+
if (buttonizer_tour_1._currentStep == 5 && buttonizer_tour_1._direction == "forward") {
|
1129 |
+
buttonizer.tabNavigate('placing');
|
1130 |
+
openedDesign = true;
|
1131 |
+
}else if(buttonizer_tour_1._currentStep == 4 && buttonizer_tour_1._direction == "backward") {
|
1132 |
+
buttonizer.tabNavigate('design');
|
1133 |
+
|
1134 |
+
openedDesign = false;
|
1135 |
+
}
|
1136 |
+
}).oncomplete(function() {
|
1137 |
+
document.querySelector('.button.savebutton').click();
|
1138 |
+
}).setOptions({
|
1139 |
+
doneLabel: 'Save →'
|
1140 |
+
}).start();
|
1141 |
+
|
1142 |
+
jQuery("#tab_container_placing").click(function() {
|
1143 |
+
buttonizer_tour_1.nextStep();
|
1144 |
+
});
|
1145 |
+
|
1146 |
+
jQuery('.button.savebutton').click(function() {
|
1147 |
+
var d = new Date();
|
1148 |
+
d.setTime(d.getTime() + (2*24*60*60*1000));
|
1149 |
+
document.cookie = "buttonizer_tour_ready=toStep2;expires="+ d.toUTCString() + ";path=/";
|
1150 |
+
});
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
if(document.location.href.indexOf('buttonizer_buttons') != -1) {
|
1154 |
+
var buttonizer_tour_2 = buttonizer.startTour('buttons');
|
1155 |
+
var buttonCreated = true;
|
1156 |
+
|
1157 |
+
buttonizer_tour_2.onchange(function(targetElement) {
|
1158 |
+
if(buttonizer_tour_2._currentStep == 4) {
|
1159 |
+
jQuery("#new-button").click();
|
1160 |
+
}
|
1161 |
+
}).setOptions({
|
1162 |
+
doneLabel: 'Next',
|
1163 |
+
hidePrev: true,
|
1164 |
+
hideNext: true,
|
1165 |
+
}).start();
|
1166 |
+
|
1167 |
+
// Create button
|
1168 |
+
var buttonCreated = false;
|
1169 |
+
jQuery("#new-button").click(function() {
|
1170 |
+
if(buttonCreated) {
|
1171 |
+
alert("Please finish the tour first.")
|
1172 |
+
return;
|
1173 |
+
}
|
1174 |
+
buttonCreated = true;
|
1175 |
+
buttonizer.addRow();
|
1176 |
+
|
1177 |
+
setTimeout(function() {
|
1178 |
+
var id = jQuery("#button-rows .button-row.opened").attr("id");
|
1179 |
+
buttonizer_tour_2.exit(true);
|
1180 |
+
|
1181 |
+
var buttonizer_tour_3 = buttonizer.startTour('edit-button', id);
|
1182 |
+
|
1183 |
+
buttonizer_tour_3.onchange(function(targetElement) {
|
1184 |
+
if(buttonizer_tour_3._currentStep == 1) {
|
1185 |
+
// buttonizer_tour_3.nextStep();
|
1186 |
+
}
|
1187 |
+
}).setOptions({
|
1188 |
+
doneLabel: 'Finish tour',
|
1189 |
+
hidePrev: true,
|
1190 |
+
hideNext: true,
|
1191 |
+
}).start();
|
1192 |
+
}, 400);
|
1193 |
+
});
|
1194 |
+
}
|
1195 |
+
}
|
1196 |
+
},
|
1197 |
+
|
1198 |
+
startTour: function(type, newButtonId) {
|
1199 |
+
var intro = introJs();
|
1200 |
+
|
1201 |
+
if(!newButtonId) {
|
1202 |
+
newButtonId = false;
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
intro.setOption('tooltipPosition', 'top');
|
1206 |
+
intro.setOptions({
|
1207 |
+
showBullets: false,
|
1208 |
+
exitOnOverlayClick: false,
|
1209 |
+
skipLabel: 'Exit tour'
|
1210 |
+
});
|
1211 |
+
|
1212 |
+
if(type == 'design') {
|
1213 |
+
intro.setOptions({
|
1214 |
+
steps: [
|
1215 |
+
{
|
1216 |
+
intro: "Let's start the tour through Buttonizer. You can skip this every second."
|
1217 |
+
},
|
1218 |
+
{
|
1219 |
+
element: document.querySelector('.intro-styling'),
|
1220 |
+
intro: "Set the default colors of your Floating Action Button. We recommend to use the colors of your corporate identity.",
|
1221 |
+
position: 'top'
|
1222 |
+
},
|
1223 |
+
{
|
1224 |
+
element: document.querySelector('.intro-icon'),
|
1225 |
+
intro: "Select the main icon. This icon will appear when you have multiple floating action buttons on one page (So you can create a Floating Menu).<br><br>When you have PRO featues, you will be able to choose a custom image.",
|
1226 |
+
position: 'top'
|
1227 |
+
},
|
1228 |
+
{
|
1229 |
+
element: document.querySelector('.intro-label'),
|
1230 |
+
intro: "Optional: Add text If you want to have a label next to your button to explain the button action like 'Click here' or 'Contact options'.",
|
1231 |
+
position: 'top'
|
1232 |
+
},
|
1233 |
+
{
|
1234 |
+
element: document.querySelector('#tab_container_placing'),
|
1235 |
+
intro: "Click here to get to the position and animation page",
|
1236 |
+
position: 'right'
|
1237 |
+
},
|
1238 |
+
{
|
1239 |
+
element: document.querySelector('.intro-position'),
|
1240 |
+
intro: "Decide where you want to place your floating action buttons. 5% right means 5% from the right side of the screen. The default setting is bottom 5% and right 5%. It will place itself on the right corner of your screen (mobile & desktop).",
|
1241 |
+
position: 'top'
|
1242 |
+
},
|
1243 |
+
{
|
1244 |
+
element: document.querySelector('.intro-animaton'),
|
1245 |
+
intro: "The Button animation option is only relevant if you are going to add multiple floating action buttons on one page (create a floating menu). This options lets you choose how the different buttons will 'pop' open.",
|
1246 |
+
position: 'top'
|
1247 |
+
},
|
1248 |
+
{
|
1249 |
+
element: document.querySelector('.intro-attention'),
|
1250 |
+
intro: "If you want your floating action button to have extra attention from your website visitors you can add a attention animation. The button will make a specific 'move' each 10 seconds.",
|
1251 |
+
position: 'top'
|
1252 |
+
},
|
1253 |
+
{
|
1254 |
+
element: document.querySelector('.button.savebutton'),
|
1255 |
+
intro: "For now, we are finished here. Click the save button.",
|
1256 |
+
position: 'left'
|
1257 |
+
}
|
1258 |
+
]});
|
1259 |
+
}else if(type == 'buttons') {
|
1260 |
+
intro.setOptions({
|
1261 |
+
steps: [
|
1262 |
+
{
|
1263 |
+
element: document.querySelector('#new-button'),
|
1264 |
+
intro: "Great! You are ready to make your first Floating Action Buttons. As an example we will make a Click-to-Call button. To start click on 'New Button'.",
|
1265 |
+
position: 'left'
|
1266 |
+
},
|
1267 |
+
{
|
1268 |
+
element: document.querySelector('#new-button'),
|
1269 |
+
intro: "Waiting on you for clicking the button at the right... It says '+ New button'",
|
1270 |
+
position: 'left'
|
1271 |
+
},
|
1272 |
+
{
|
1273 |
+
element: document.querySelector('#new-button'),
|
1274 |
+
intro: "Hello? Please click that button...",
|
1275 |
+
position: 'left'
|
1276 |
+
},
|
1277 |
+
{
|
1278 |
+
element: document.querySelector('#new-button'),
|
1279 |
+
intro: "Here, on the right... If you won't click it, I will click it >:-)",
|
1280 |
+
position: 'left'
|
1281 |
+
},
|
1282 |
+
{
|
1283 |
+
element: document.querySelector('#new-button'),
|
1284 |
+
intro: "Okay. Nothing to say.",
|
1285 |
+
position: 'bottom'
|
1286 |
+
},
|
1287 |
+
]});
|
1288 |
+
}
|
1289 |
+
else if(type == 'edit-button') {
|
1290 |
+
intro.setOptions({
|
1291 |
+
steps: [
|
1292 |
+
{
|
1293 |
+
element: document.querySelector('#' + newButtonId + " .row-info"),
|
1294 |
+
intro: "This is the button-quick info bar.<br /><br />When you have multiple buttons, you can drag them to position them on the right place.",
|
1295 |
+
position: 'bottom',
|
1296 |
+
disableInteraction: true
|
1297 |
+
},
|
1298 |
+
{
|
1299 |
+
element: document.querySelector('#' + newButtonId + " .row-info .row-title"),
|
1300 |
+
intro: "This is the button title. Your webvisitors won't see this name, this is just for here. We will change the name in 2 steps.",
|
1301 |
+
position: 'right',
|
1302 |
+
disableInteraction: true
|
1303 |
+
},
|
1304 |
+
{
|
1305 |
+
element: document.querySelector('#' + newButtonId + " .row-info .desktop-button"),
|
1306 |
+
intro: "This is a quick-button to enable the button on desktop. When it's blue it's enabled. When grey it's disabled for desktop.",
|
1307 |
+
position: 'left',
|
1308 |
+
disableInteraction: true
|
1309 |
+
},
|
1310 |
+
{
|
1311 |
+
element: document.querySelector('#' + newButtonId + " .row-info .mobile-button"),
|
1312 |
+
intro: "Like we have one for desktop, this one is for mobile.",
|
1313 |
+
position: 'left',
|
1314 |
+
disableInteraction: true
|
1315 |
+
},
|
1316 |
+
{
|
1317 |
+
element: document.querySelector('#' + newButtonId + " .button_title"),
|
1318 |
+
intro: "Create a descend name for your Button like 'Call Buttons Sales department'. Your webvisitors won't see this name. It will also appear on Google Analytics on your 'event tracking' section so you know for each button how many times it is clicked on.",
|
1319 |
+
position: 'bottom'
|
1320 |
+
},
|
1321 |
+
{
|
1322 |
+
element: document.querySelector('#' + newButtonId + " .button-pdr"),
|
1323 |
+
intro: "Choose a appropriate icon or upload your own. Type 'phone' and select the phone icon to make a call button.",
|
1324 |
+
position: 'bottom'
|
1325 |
+
},
|
1326 |
+
{
|
1327 |
+
element: document.querySelector('#' + newButtonId + " .button_textfield"),
|
1328 |
+
intro: "Optional - Add text If you want to have a label next to your button to explain the button action like 'Call our sales department'. This label will be shown next to the button.",
|
1329 |
+
position: 'bottom'
|
1330 |
+
},
|
1331 |
+
{
|
1332 |
+
element: document.querySelector('#' + newButtonId + " .button-action"),
|
1333 |
+
intro: "Choose the appropriate click action. When you want to add a click-to-call button select the option phone-number. Type in the phone-number you want your visitors to call when clicking on the button.",
|
1334 |
+
position: 'bottom'
|
1335 |
+
},
|
1336 |
+
{
|
1337 |
+
element: document.querySelector('#' + newButtonId + " #button_category"),
|
1338 |
+
intro: "Premium function - By default the button is shown on every page. If you want to show your button on selected pages you can add 'page categories'. You have to have a premium account if you want to do this.",
|
1339 |
+
position: 'bottom'
|
1340 |
+
},
|
1341 |
+
{
|
1342 |
+
element: document.querySelector('#' + newButtonId + " .show-mobile-btn"),
|
1343 |
+
intro: "Decide if your button is shown on mobile, desktop or both by selecting the show on mobile and desktop functions. If you don't select at least one of both the button won't show on your website. In the case of a call button we recommend only selecting the option 'show on mobile'. ",
|
1344 |
+
position: 'top'
|
1345 |
+
},
|
1346 |
+
{
|
1347 |
+
element: document.querySelector('#' + newButtonId + " .show-desktop-btn"),
|
1348 |
+
intro: "Do you like to enable this button on desktop too?",
|
1349 |
+
position: 'bottom'
|
1350 |
+
},
|
1351 |
+
{
|
1352 |
+
element: document.querySelector('#' + newButtonId + " .must-save-button"),
|
1353 |
+
intro: "This is a quick Save button. It will save all buttons witch has changes. When the button has no changes, it says 'live'.",
|
1354 |
+
position: 'left',
|
1355 |
+
disableInteraction: true
|
1356 |
+
},
|
1357 |
+
{
|
1358 |
+
intro: "Congratzz! Your first Floating Action button is ready! Click on save and take a look at the result. Go to your website on your mobile phone and test your button.",
|
1359 |
+
},
|
1360 |
+
{
|
1361 |
+
intro: "Now it's time to get creative. Add another button on your website like a navigation button or just a url like your contact page or maybe even opening Facebook Messenger. By adding a second page you will see that your floating menu icon will appear and the animation you selected (In General Settings) when you click on the button.",
|
1362 |
+
},
|
1363 |
+
{
|
1364 |
+
element: document.querySelector('h2 .savebutton'),
|
1365 |
+
intro: "Do you have creative ideas or do you need support? Feel free to contact us! Push the save button to finish the tour.",
|
1366 |
+
position: 'left',
|
1367 |
+
},
|
1368 |
+
]});
|
1369 |
+
}
|
1370 |
+
|
1371 |
+
return intro;
|
1372 |
}
|
1373 |
}
|
1374 |
|
@@ -0,0 +1,2139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Intro.js v2.7.0
|
3 |
+
* https://github.com/usablica/intro.js
|
4 |
+
*
|
5 |
+
* Copyright (C) 2017 Afshin Mehrabani (@afshinmeh)
|
6 |
+
*/
|
7 |
+
|
8 |
+
(function (root, factory) {
|
9 |
+
if (typeof exports === 'object') {
|
10 |
+
// CommonJS
|
11 |
+
factory(exports);
|
12 |
+
} else if (typeof define === 'function' && define.amd) {
|
13 |
+
// AMD. Register as an anonymous module.
|
14 |
+
define(['exports'], factory);
|
15 |
+
} else {
|
16 |
+
// Browser globals
|
17 |
+
factory(root);
|
18 |
+
}
|
19 |
+
} (this, function (exports) {
|
20 |
+
//Default config/variables
|
21 |
+
var VERSION = '2.7.0';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* IntroJs main class
|
25 |
+
*
|
26 |
+
* @class IntroJs
|
27 |
+
*/
|
28 |
+
function IntroJs(obj) {
|
29 |
+
this._targetElement = obj;
|
30 |
+
this._introItems = [];
|
31 |
+
|
32 |
+
this._options = {
|
33 |
+
/* Next button label in tooltip box */
|
34 |
+
nextLabel: 'Next →',
|
35 |
+
/* Previous button label in tooltip box */
|
36 |
+
prevLabel: '← Back',
|
37 |
+
/* Skip button label in tooltip box */
|
38 |
+
skipLabel: 'Skip',
|
39 |
+
/* Done button label in tooltip box */
|
40 |
+
doneLabel: 'Done',
|
41 |
+
/* Hide previous button in the first step? Otherwise, it will be disabled button. */
|
42 |
+
hidePrev: false,
|
43 |
+
/* Hide next button in the last step? Otherwise, it will be disabled button. */
|
44 |
+
hideNext: false,
|
45 |
+
/* Default tooltip box position */
|
46 |
+
tooltipPosition: 'bottom',
|
47 |
+
/* Next CSS class for tooltip boxes */
|
48 |
+
tooltipClass: '',
|
49 |
+
/* CSS class that is added to the helperLayer */
|
50 |
+
highlightClass: '',
|
51 |
+
/* Close introduction when pressing Escape button? */
|
52 |
+
exitOnEsc: true,
|
53 |
+
/* Close introduction when clicking on overlay layer? */
|
54 |
+
exitOnOverlayClick: true,
|
55 |
+
/* Show step numbers in introduction? */
|
56 |
+
showStepNumbers: true,
|
57 |
+
/* Let user use keyboard to navigate the tour? */
|
58 |
+
keyboardNavigation: true,
|
59 |
+
/* Show tour control buttons? */
|
60 |
+
showButtons: true,
|
61 |
+
/* Show tour bullets? */
|
62 |
+
showBullets: true,
|
63 |
+
/* Show tour progress? */
|
64 |
+
showProgress: false,
|
65 |
+
/* Scroll to highlighted element? */
|
66 |
+
scrollToElement: true,
|
67 |
+
/*
|
68 |
+
* Should we scroll the tooltip or target element?
|
69 |
+
*
|
70 |
+
* Options are: 'element' or 'tooltip'
|
71 |
+
*/
|
72 |
+
scrollTo: 'element',
|
73 |
+
/* Padding to add after scrolling when element is not in the viewport (in pixels) */
|
74 |
+
scrollPadding: 30,
|
75 |
+
/* Set the overlay opacity */
|
76 |
+
overlayOpacity: 0.8,
|
77 |
+
/* Precedence of positions, when auto is enabled */
|
78 |
+
positionPrecedence: ["bottom", "top", "right", "left"],
|
79 |
+
/* Disable an interaction with element? */
|
80 |
+
disableInteraction: false,
|
81 |
+
/* Default hint position */
|
82 |
+
hintPosition: 'top-middle',
|
83 |
+
/* Hint button label */
|
84 |
+
hintButtonLabel: 'Got it',
|
85 |
+
/* Adding animation to hints? */
|
86 |
+
hintAnimation: true
|
87 |
+
};
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Initiate a new introduction/guide from an element in the page
|
92 |
+
*
|
93 |
+
* @api private
|
94 |
+
* @method _introForElement
|
95 |
+
* @param {Object} targetElm
|
96 |
+
* @returns {Boolean} Success or not?
|
97 |
+
*/
|
98 |
+
function _introForElement(targetElm) {
|
99 |
+
var introItems = [],
|
100 |
+
self = this;
|
101 |
+
|
102 |
+
if (this._options.steps) {
|
103 |
+
//use steps passed programmatically
|
104 |
+
for (var i = 0, stepsLength = this._options.steps.length; i < stepsLength; i++) {
|
105 |
+
var currentItem = _cloneObject(this._options.steps[i]);
|
106 |
+
|
107 |
+
//set the step
|
108 |
+
currentItem.step = introItems.length + 1;
|
109 |
+
|
110 |
+
//use querySelector function only when developer used CSS selector
|
111 |
+
if (typeof (currentItem.element) === 'string') {
|
112 |
+
//grab the element with given selector from the page
|
113 |
+
currentItem.element = document.querySelector(currentItem.element);
|
114 |
+
}
|
115 |
+
|
116 |
+
//intro without element
|
117 |
+
if (typeof (currentItem.element) === 'undefined' || currentItem.element == null) {
|
118 |
+
var floatingElementQuery = document.querySelector(".introjsFloatingElement");
|
119 |
+
|
120 |
+
if (floatingElementQuery == null) {
|
121 |
+
floatingElementQuery = document.createElement('div');
|
122 |
+
floatingElementQuery.className = 'introjsFloatingElement';
|
123 |
+
|
124 |
+
document.body.appendChild(floatingElementQuery);
|
125 |
+
}
|
126 |
+
|
127 |
+
currentItem.element = floatingElementQuery;
|
128 |
+
currentItem.position = 'floating';
|
129 |
+
}
|
130 |
+
|
131 |
+
currentItem.scrollTo = currentItem.scrollTo || this._options.scrollTo;
|
132 |
+
|
133 |
+
if (typeof (currentItem.disableInteraction) === 'undefined') {
|
134 |
+
currentItem.disableInteraction = this._options.disableInteraction;
|
135 |
+
}
|
136 |
+
|
137 |
+
if (currentItem.element != null) {
|
138 |
+
introItems.push(currentItem);
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
} else {
|
143 |
+
//use steps from data-* annotations
|
144 |
+
var allIntroSteps = targetElm.querySelectorAll('*[data-intro]');
|
145 |
+
//if there's no element to intro
|
146 |
+
if (allIntroSteps.length < 1) {
|
147 |
+
return false;
|
148 |
+
}
|
149 |
+
|
150 |
+
//first add intro items with data-step
|
151 |
+
for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
|
152 |
+
var currentElement = allIntroSteps[i];
|
153 |
+
|
154 |
+
// skip hidden elements
|
155 |
+
if (currentElement.style.display == 'none') {
|
156 |
+
continue;
|
157 |
+
}
|
158 |
+
|
159 |
+
var step = parseInt(currentElement.getAttribute('data-step'), 10);
|
160 |
+
|
161 |
+
var disableInteraction = this._options.disableInteraction;
|
162 |
+
|
163 |
+
if (typeof (currentElement.getAttribute('data-disable-interaction')) != 'undefined') {
|
164 |
+
disableInteraction = !!currentElement.getAttribute('data-disable-interaction');
|
165 |
+
}
|
166 |
+
|
167 |
+
if (step > 0) {
|
168 |
+
introItems[step - 1] = {
|
169 |
+
element: currentElement,
|
170 |
+
intro: currentElement.getAttribute('data-intro'),
|
171 |
+
step: parseInt(currentElement.getAttribute('data-step'), 10),
|
172 |
+
tooltipClass: currentElement.getAttribute('data-tooltipClass'),
|
173 |
+
highlightClass: currentElement.getAttribute('data-highlightClass'),
|
174 |
+
position: currentElement.getAttribute('data-position') || this._options.tooltipPosition,
|
175 |
+
scrollTo: currentElement.getAttribute('data-scrollTo') || this._options.scrollTo,
|
176 |
+
disableInteraction: disableInteraction
|
177 |
+
};
|
178 |
+
}
|
179 |
+
}
|
180 |
+
|
181 |
+
//next add intro items without data-step
|
182 |
+
//todo: we need a cleanup here, two loops are redundant
|
183 |
+
var nextStep = 0;
|
184 |
+
for (var i = 0, elmsLength = allIntroSteps.length; i < elmsLength; i++) {
|
185 |
+
var currentElement = allIntroSteps[i];
|
186 |
+
|
187 |
+
if (currentElement.getAttribute('data-step') == null) {
|
188 |
+
|
189 |
+
while (true) {
|
190 |
+
if (typeof introItems[nextStep] == 'undefined') {
|
191 |
+
break;
|
192 |
+
} else {
|
193 |
+
nextStep++;
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
var disableInteraction = this._options.disableInteraction;
|
198 |
+
|
199 |
+
if (typeof (currentElement.getAttribute('data-disable-interaction')) != 'undefined') {
|
200 |
+
disableInteraction = !!currentElement.getAttribute('data-disable-interaction');
|
201 |
+
}
|
202 |
+
|
203 |
+
introItems[nextStep] = {
|
204 |
+
element: currentElement,
|
205 |
+
intro: currentElement.getAttribute('data-intro'),
|
206 |
+
step: nextStep + 1,
|
207 |
+
tooltipClass: currentElement.getAttribute('data-tooltipClass'),
|
208 |
+
highlightClass: currentElement.getAttribute('data-highlightClass'),
|
209 |
+
position: currentElement.getAttribute('data-position') || this._options.tooltipPosition,
|
210 |
+
scrollTo: currentElement.getAttribute('data-scrollTo') || this._options.scrollTo,
|
211 |
+
disableInteraction: disableInteraction
|
212 |
+
};
|
213 |
+
}
|
214 |
+
}
|
215 |
+
}
|
216 |
+
|
217 |
+
//removing undefined/null elements
|
218 |
+
var tempIntroItems = [];
|
219 |
+
for (var z = 0; z < introItems.length; z++) {
|
220 |
+
introItems[z] && tempIntroItems.push(introItems[z]); // copy non-empty values to the end of the array
|
221 |
+
}
|
222 |
+
|
223 |
+
introItems = tempIntroItems;
|
224 |
+
|
225 |
+
//Ok, sort all items with given steps
|
226 |
+
introItems.sort(function (a, b) {
|
227 |
+
return a.step - b.step;
|
228 |
+
});
|
229 |
+
|
230 |
+
//set it to the introJs object
|
231 |
+
self._introItems = introItems;
|
232 |
+
|
233 |
+
//add overlay layer to the page
|
234 |
+
if(_addOverlayLayer.call(self, targetElm)) {
|
235 |
+
//then, start the show
|
236 |
+
_nextStep.call(self);
|
237 |
+
|
238 |
+
var skipButton = targetElm.querySelector('.introjs-skipbutton'),
|
239 |
+
nextStepButton = targetElm.querySelector('.introjs-nextbutton');
|
240 |
+
|
241 |
+
self._onKeyDown = function(e) {
|
242 |
+
if (e.keyCode === 27 && self._options.exitOnEsc == true) {
|
243 |
+
//escape key pressed, exit the intro
|
244 |
+
//check if exit callback is defined
|
245 |
+
_exitIntro.call(self, targetElm);
|
246 |
+
} else if(e.keyCode === 37) {
|
247 |
+
//left arrow
|
248 |
+
_previousStep.call(self);
|
249 |
+
} else if (e.keyCode === 39) {
|
250 |
+
//right arrow
|
251 |
+
_nextStep.call(self);
|
252 |
+
} else if (e.keyCode === 13) {
|
253 |
+
//srcElement === ie
|
254 |
+
var target = e.target || e.srcElement;
|
255 |
+
if (target && target.className.indexOf('introjs-prevbutton') > 0) {
|
256 |
+
//user hit enter while focusing on previous button
|
257 |
+
_previousStep.call(self);
|
258 |
+
} else if (target && target.className.indexOf('introjs-skipbutton') > 0) {
|
259 |
+
//user hit enter while focusing on skip button
|
260 |
+
if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
|
261 |
+
self._introCompleteCallback.call(self);
|
262 |
+
}
|
263 |
+
|
264 |
+
_exitIntro.call(self, targetElm);
|
265 |
+
} else {
|
266 |
+
//default behavior for responding to enter
|
267 |
+
_nextStep.call(self);
|
268 |
+
}
|
269 |
+
|
270 |
+
//prevent default behaviour on hitting Enter, to prevent steps being skipped in some browsers
|
271 |
+
if(e.preventDefault) {
|
272 |
+
e.preventDefault();
|
273 |
+
} else {
|
274 |
+
e.returnValue = false;
|
275 |
+
}
|
276 |
+
}
|
277 |
+
};
|
278 |
+
|
279 |
+
self._onResize = function(e) {
|
280 |
+
self.refresh.call(self);
|
281 |
+
};
|
282 |
+
|
283 |
+
if (window.addEventListener) {
|
284 |
+
if (this._options.keyboardNavigation) {
|
285 |
+
window.addEventListener('keydown', self._onKeyDown, true);
|
286 |
+
}
|
287 |
+
//for window resize
|
288 |
+
window.addEventListener('resize', self._onResize, true);
|
289 |
+
} else if (document.attachEvent) { //IE
|
290 |
+
if (this._options.keyboardNavigation) {
|
291 |
+
document.attachEvent('onkeydown', self._onKeyDown);
|
292 |
+
}
|
293 |
+
//for window resize
|
294 |
+
document.attachEvent('onresize', self._onResize);
|
295 |
+
}
|
296 |
+
}
|
297 |
+
return false;
|
298 |
+
}
|
299 |
+
|
300 |
+
/*
|
301 |
+
* makes a copy of the object
|
302 |
+
* @api private
|
303 |
+
* @method _cloneObject
|
304 |
+
*/
|
305 |
+
function _cloneObject(object) {
|
306 |
+
if (object == null || typeof (object) != 'object' || typeof (object.nodeType) != 'undefined') {
|
307 |
+
return object;
|
308 |
+
}
|
309 |
+
var temp = {};
|
310 |
+
for (var key in object) {
|
311 |
+
if (typeof (jQuery) != 'undefined' && object[key] instanceof jQuery) {
|
312 |
+
temp[key] = object[key];
|
313 |
+
} else {
|
314 |
+
temp[key] = _cloneObject(object[key]);
|
315 |
+
}
|
316 |
+
}
|
317 |
+
return temp;
|
318 |
+
}
|
319 |
+
/**
|
320 |
+
* Go to specific step of introduction
|
321 |
+
*
|
322 |
+
* @api private
|
323 |
+
* @method _goToStep
|
324 |
+
*/
|
325 |
+
function _goToStep(step) {
|
326 |
+
//because steps starts with zero
|
327 |
+
this._currentStep = step - 2;
|
328 |
+
if (typeof (this._introItems) !== 'undefined') {
|
329 |
+
_nextStep.call(this);
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
/**
|
334 |
+
* Go to the specific step of introduction with the explicit [data-step] number
|
335 |
+
*
|
336 |
+
* @api private
|
337 |
+
* @method _goToStepNumber
|
338 |
+
*/
|
339 |
+
function _goToStepNumber(step) {
|
340 |
+
this._currentStepNumber = step;
|
341 |
+
if (typeof (this._introItems) !== 'undefined') {
|
342 |
+
_nextStep.call(this);
|
343 |
+
}
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Go to next step on intro
|
348 |
+
*
|
349 |
+
* @api private
|
350 |
+
* @method _nextStep
|
351 |
+
*/
|
352 |
+
function _nextStep() {
|
353 |
+
this._direction = 'forward';
|
354 |
+
|
355 |
+
if (typeof (this._currentStepNumber) !== 'undefined') {
|
356 |
+
for( var i = 0, len = this._introItems.length; i < len; i++ ) {
|
357 |
+
var item = this._introItems[i];
|
358 |
+
if( item.step === this._currentStepNumber ) {
|
359 |
+
this._currentStep = i - 1;
|
360 |
+
this._currentStepNumber = undefined;
|
361 |
+
}
|
362 |
+
}
|
363 |
+
}
|
364 |
+
|
365 |
+
if (typeof (this._currentStep) === 'undefined') {
|
366 |
+
this._currentStep = 0;
|
367 |
+
} else {
|
368 |
+
++this._currentStep;
|
369 |
+
}
|
370 |
+
|
371 |
+
if ((this._introItems.length) <= this._currentStep) {
|
372 |
+
//end of the intro
|
373 |
+
//check if any callback is defined
|
374 |
+
if (typeof (this._introCompleteCallback) === 'function') {
|
375 |
+
this._introCompleteCallback.call(this);
|
376 |
+
}
|
377 |
+
_exitIntro.call(this, this._targetElement);
|
378 |
+
return;
|
379 |
+
}
|
380 |
+
|
381 |
+
var nextStep = this._introItems[this._currentStep];
|
382 |
+
if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
|
383 |
+
this._introBeforeChangeCallback.call(this, nextStep.element);
|
384 |
+
}
|
385 |
+
|
386 |
+
_showElement.call(this, nextStep);
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Go to previous step on intro
|
391 |
+
*
|
392 |
+
* @api private
|
393 |
+
* @method _previousStep
|
394 |
+
*/
|
395 |
+
function _previousStep() {
|
396 |
+
this._direction = 'backward';
|
397 |
+
|
398 |
+
if (this._currentStep === 0) {
|
399 |
+
return false;
|
400 |
+
}
|
401 |
+
|
402 |
+
var nextStep = this._introItems[--this._currentStep];
|
403 |
+
if (typeof (this._introBeforeChangeCallback) !== 'undefined') {
|
404 |
+
this._introBeforeChangeCallback.call(this, nextStep.element);
|
405 |
+
}
|
406 |
+
|
407 |
+
_showElement.call(this, nextStep);
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* Update placement of the intro objects on the screen
|
412 |
+
* @api private
|
413 |
+
*/
|
414 |
+
function _refresh() {
|
415 |
+
// re-align intros
|
416 |
+
_setHelperLayerPosition.call(this, document.querySelector('.introjs-helperLayer'));
|
417 |
+
_setHelperLayerPosition.call(this, document.querySelector('.introjs-tooltipReferenceLayer'));
|
418 |
+
|
419 |
+
// re-align tooltip
|
420 |
+
if(this._currentStep !== undefined && this._currentStep !== null) {
|
421 |
+
var oldHelperNumberLayer = document.querySelector('.introjs-helperNumberLayer'),
|
422 |
+
oldArrowLayer = document.querySelector('.introjs-arrow'),
|
423 |
+
oldtooltipContainer = document.querySelector('.introjs-tooltip');
|
424 |
+
_placeTooltip.call(this, this._introItems[this._currentStep].element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
|
425 |
+
}
|
426 |
+
|
427 |
+
//re-align hints
|
428 |
+
_reAlignHints.call(this);
|
429 |
+
return this;
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Exit from intro
|
434 |
+
*
|
435 |
+
* @api private
|
436 |
+
* @method _exitIntro
|
437 |
+
* @param {Object} targetElement
|
438 |
+
* @param {Boolean} force - Setting to `true` will skip the result of beforeExit callback
|
439 |
+
*/
|
440 |
+
function _exitIntro(targetElement, force) {
|
441 |
+
var continueExit = true;
|
442 |
+
|
443 |
+
// calling onbeforeexit callback
|
444 |
+
//
|
445 |
+
// If this callback return `false`, it would halt the process
|
446 |
+
if (this._introBeforeExitCallback != undefined) {
|
447 |
+
continueExit = this._introBeforeExitCallback.call(self);
|
448 |
+
}
|
449 |
+
|
450 |
+
// skip this check if `force` parameter is `true`
|
451 |
+
// otherwise, if `onbeforeexit` returned `false`, don't exit the intro
|
452 |
+
if (!force && continueExit === false) return;
|
453 |
+
|
454 |
+
//remove overlay layers from the page
|
455 |
+
var overlayLayers = targetElement.querySelectorAll('.introjs-overlay');
|
456 |
+
|
457 |
+
if (overlayLayers && overlayLayers.length > 0) {
|
458 |
+
for (var i = overlayLayers.length - 1; i >= 0; i--) {
|
459 |
+
//for fade-out animation
|
460 |
+
var overlayLayer = overlayLayers[i];
|
461 |
+
overlayLayer.style.opacity = 0;
|
462 |
+
setTimeout(function () {
|
463 |
+
if (this.parentNode) {
|
464 |
+
this.parentNode.removeChild(this);
|
465 |
+
}
|
466 |
+
}.bind(overlayLayer), 500);
|
467 |
+
};
|
468 |
+
}
|
469 |
+
|
470 |
+
//remove all helper layers
|
471 |
+
var helperLayer = targetElement.querySelector('.introjs-helperLayer');
|
472 |
+
if (helperLayer) {
|
473 |
+
helperLayer.parentNode.removeChild(helperLayer);
|
474 |
+
}
|
475 |
+
|
476 |
+
var referenceLayer = targetElement.querySelector('.introjs-tooltipReferenceLayer');
|
477 |
+
if (referenceLayer) {
|
478 |
+
referenceLayer.parentNode.removeChild(referenceLayer);
|
479 |
+
}
|
480 |
+
|
481 |
+
//remove disableInteractionLayer
|
482 |
+
var disableInteractionLayer = targetElement.querySelector('.introjs-disableInteraction');
|
483 |
+
if (disableInteractionLayer) {
|
484 |
+
disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
|
485 |
+
}
|
486 |
+
|
487 |
+
//remove intro floating element
|
488 |
+
var floatingElement = document.querySelector('.introjsFloatingElement');
|
489 |
+
if (floatingElement) {
|
490 |
+
floatingElement.parentNode.removeChild(floatingElement);
|
491 |
+
}
|
492 |
+
|
493 |
+
_removeShowElement();
|
494 |
+
|
495 |
+
//remove `introjs-fixParent` class from the elements
|
496 |
+
var fixParents = document.querySelectorAll('.introjs-fixParent');
|
497 |
+
if (fixParents && fixParents.length > 0) {
|
498 |
+
for (var i = fixParents.length - 1; i >= 0; i--) {
|
499 |
+
fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
|
500 |
+
}
|
501 |
+
}
|
502 |
+
|
503 |
+
//clean listeners
|
504 |
+
if (window.removeEventListener) {
|
505 |
+
window.removeEventListener('keydown', this._onKeyDown, true);
|
506 |
+
} else if (document.detachEvent) { //IE
|
507 |
+
document.detachEvent('onkeydown', this._onKeyDown);
|
508 |
+
}
|
509 |
+
|
510 |
+
//check if any callback is defined
|
511 |
+
if (this._introExitCallback != undefined) {
|
512 |
+
this._introExitCallback.call(self);
|
513 |
+
}
|
514 |
+
|
515 |
+
//set the step to zero
|
516 |
+
this._currentStep = undefined;
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Render tooltip box in the page
|
521 |
+
*
|
522 |
+
* @api private
|
523 |
+
* @method _placeTooltip
|
524 |
+
* @param {HTMLElement} targetElement
|
525 |
+
* @param {HTMLElement} tooltipLayer
|
526 |
+
* @param {HTMLElement} arrowLayer
|
527 |
+
* @param {HTMLElement} helperNumberLayer
|
528 |
+
* @param {Boolean} hintMode
|
529 |
+
*/
|
530 |
+
function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer, hintMode) {
|
531 |
+
var tooltipCssClass = '',
|
532 |
+
currentStepObj,
|
533 |
+
tooltipOffset,
|
534 |
+
targetOffset,
|
535 |
+
windowSize,
|
536 |
+
currentTooltipPosition;
|
537 |
+
|
538 |
+
hintMode = hintMode || false;
|
539 |
+
|
540 |
+
//reset the old style
|
541 |
+
tooltipLayer.style.top = null;
|
542 |
+
tooltipLayer.style.right = null;
|
543 |
+
tooltipLayer.style.bottom = null;
|
544 |
+
tooltipLayer.style.left = null;
|
545 |
+
tooltipLayer.style.marginLeft = null;
|
546 |
+
tooltipLayer.style.marginTop = null;
|
547 |
+
|
548 |
+
arrowLayer.style.display = 'inherit';
|
549 |
+
|
550 |
+
if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
|
551 |
+
helperNumberLayer.style.top = null;
|
552 |
+
helperNumberLayer.style.left = null;
|
553 |
+
}
|
554 |
+
|
555 |
+
//prevent error when `this._currentStep` is undefined
|
556 |
+
if (!this._introItems[this._currentStep]) return;
|
557 |
+
|
558 |
+
//if we have a custom css class for each step
|
559 |
+
currentStepObj = this._introItems[this._currentStep];
|
560 |
+
if (typeof (currentStepObj.tooltipClass) === 'string') {
|
561 |
+
tooltipCssClass = currentStepObj.tooltipClass;
|
562 |
+
} else {
|
563 |
+
tooltipCssClass = this._options.tooltipClass;
|
564 |
+
}
|
565 |
+
|
566 |
+
tooltipLayer.className = ('introjs-tooltip ' + tooltipCssClass).replace(/^\s+|\s+$/g, '');
|
567 |
+
|
568 |
+
currentTooltipPosition = this._introItems[this._currentStep].position;
|
569 |
+
|
570 |
+
if (currentTooltipPosition != "floating") { // Floating is always valid, no point in calculating
|
571 |
+
if (currentTooltipPosition === "auto") {
|
572 |
+
currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer);
|
573 |
+
} else {
|
574 |
+
currentTooltipPosition = _determineAutoPosition.call(this, targetElement, tooltipLayer, currentTooltipPosition);
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
targetOffset = _getOffset(targetElement);
|
579 |
+
tooltipOffset = _getOffset(tooltipLayer);
|
580 |
+
windowSize = _getWinSize();
|
581 |
+
|
582 |
+
switch (currentTooltipPosition) {
|
583 |
+
case 'top':
|
584 |
+
arrowLayer.className = 'introjs-arrow bottom';
|
585 |
+
|
586 |
+
if (hintMode) {
|
587 |
+
var tooltipLayerStyleLeft = 0;
|
588 |
+
} else {
|
589 |
+
var tooltipLayerStyleLeft = 15;
|
590 |
+
}
|
591 |
+
|
592 |
+
_checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
|
593 |
+
tooltipLayer.style.bottom = (targetOffset.height + 20) + 'px';
|
594 |
+
break;
|
595 |
+
case 'right':
|
596 |
+
tooltipLayer.style.left = (targetOffset.width + 20) + 'px';
|
597 |
+
if (targetOffset.top + tooltipOffset.height > windowSize.height) {
|
598 |
+
// In this case, right would have fallen below the bottom of the screen.
|
599 |
+
// Modify so that the bottom of the tooltip connects with the target
|
600 |
+
arrowLayer.className = "introjs-arrow left-bottom";
|
601 |
+
tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
|
602 |
+
} else {
|
603 |
+
arrowLayer.className = 'introjs-arrow left';
|
604 |
+
}
|
605 |
+
break;
|
606 |
+
case 'left':
|
607 |
+
if (!hintMode && this._options.showStepNumbers == true) {
|
608 |
+
tooltipLayer.style.top = '15px';
|
609 |
+
}
|
610 |
+
|
611 |
+
if (targetOffset.top + tooltipOffset.height > windowSize.height) {
|
612 |
+
// In this case, left would have fallen below the bottom of the screen.
|
613 |
+
// Modify so that the bottom of the tooltip connects with the target
|
614 |
+
tooltipLayer.style.top = "-" + (tooltipOffset.height - targetOffset.height - 20) + "px";
|
615 |
+
arrowLayer.className = 'introjs-arrow right-bottom';
|
616 |
+
} else {
|
617 |
+
arrowLayer.className = 'introjs-arrow right';
|
618 |
+
}
|
619 |
+
tooltipLayer.style.right = (targetOffset.width + 20) + 'px';
|
620 |
+
|
621 |
+
break;
|
622 |
+
case 'floating':
|
623 |
+
arrowLayer.style.display = 'none';
|
624 |
+
|
625 |
+
//we have to adjust the top and left of layer manually for intro items without element
|
626 |
+
tooltipLayer.style.left = '50%';
|
627 |
+
tooltipLayer.style.top = '50%';
|
628 |
+
tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px';
|
629 |
+
tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px';
|
630 |
+
|
631 |
+
if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
|
632 |
+
helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px';
|
633 |
+
helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px';
|
634 |
+
}
|
635 |
+
|
636 |
+
break;
|
637 |
+
case 'bottom-right-aligned':
|
638 |
+
arrowLayer.className = 'introjs-arrow top-right';
|
639 |
+
|
640 |
+
var tooltipLayerStyleRight = 0;
|
641 |
+
_checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer);
|
642 |
+
tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
|
643 |
+
break;
|
644 |
+
|
645 |
+
case 'bottom-middle-aligned':
|
646 |
+
arrowLayer.className = 'introjs-arrow top-middle';
|
647 |
+
|
648 |
+
var tooltipLayerStyleLeftRight = targetOffset.width / 2 - tooltipOffset.width / 2;
|
649 |
+
|
650 |
+
// a fix for middle aligned hints
|
651 |
+
if (hintMode) {
|
652 |
+
tooltipLayerStyleLeftRight += 5;
|
653 |
+
}
|
654 |
+
|
655 |
+
if (_checkLeft(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, tooltipLayer)) {
|
656 |
+
tooltipLayer.style.right = null;
|
657 |
+
_checkRight(targetOffset, tooltipLayerStyleLeftRight, tooltipOffset, windowSize, tooltipLayer);
|
658 |
+
}
|
659 |
+
tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
|
660 |
+
break;
|
661 |
+
|
662 |
+
case 'bottom-left-aligned':
|
663 |
+
// Bottom-left-aligned is the same as the default bottom
|
664 |
+
case 'bottom':
|
665 |
+
// Bottom going to follow the default behavior
|
666 |
+
default:
|
667 |
+
arrowLayer.className = 'introjs-arrow top';
|
668 |
+
|
669 |
+
var tooltipLayerStyleLeft = 0;
|
670 |
+
_checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer);
|
671 |
+
tooltipLayer.style.top = (targetOffset.height + 20) + 'px';
|
672 |
+
break;
|
673 |
+
}
|
674 |
+
}
|
675 |
+
|
676 |
+
/**
|
677 |
+
* Set tooltip left so it doesn't go off the right side of the window
|
678 |
+
*
|
679 |
+
* @return boolean true, if tooltipLayerStyleLeft is ok. false, otherwise.
|
680 |
+
*/
|
681 |
+
function _checkRight(targetOffset, tooltipLayerStyleLeft, tooltipOffset, windowSize, tooltipLayer) {
|
682 |
+
if (targetOffset.left + tooltipLayerStyleLeft + tooltipOffset.width > windowSize.width) {
|
683 |
+
// off the right side of the window
|
684 |
+
tooltipLayer.style.left = (windowSize.width - tooltipOffset.width - targetOffset.left) + 'px';
|
685 |
+
return false;
|
686 |
+
}
|
687 |
+
tooltipLayer.style.left = tooltipLayerStyleLeft + 'px';
|
688 |
+
return true;
|
689 |
+
}
|
690 |
+
|
691 |
+
/**
|
692 |
+
* Set tooltip right so it doesn't go off the left side of the window
|
693 |
+
*
|
694 |
+
* @return boolean true, if tooltipLayerStyleRight is ok. false, otherwise.
|
695 |
+
*/
|
696 |
+
function _checkLeft(targetOffset, tooltipLayerStyleRight, tooltipOffset, tooltipLayer) {
|
697 |
+
if (targetOffset.left + targetOffset.width - tooltipLayerStyleRight - tooltipOffset.width < 0) {
|
698 |
+
// off the left side of the window
|
699 |
+
tooltipLayer.style.left = (-targetOffset.left) + 'px';
|
700 |
+
return false;
|
701 |
+
}
|
702 |
+
tooltipLayer.style.right = tooltipLayerStyleRight + 'px';
|
703 |
+
return true;
|
704 |
+
}
|
705 |
+
|
706 |
+
/**
|
707 |
+
* Determines the position of the tooltip based on the position precedence and availability
|
708 |
+
* of screen space.
|
709 |
+
*
|
710 |
+
* @param {Object} targetElement
|
711 |
+
* @param {Object} tooltipLayer
|
712 |
+
* @param {Object} desiredTooltipPosition
|
713 |
+
*
|
714 |
+
*/
|
715 |
+
function _determineAutoPosition(targetElement, tooltipLayer, desiredTooltipPosition) {
|
716 |
+
|
717 |
+
// Take a clone of position precedence. These will be the available
|
718 |
+
var possiblePositions = this._options.positionPrecedence.slice();
|
719 |
+
|
720 |
+
var windowSize = _getWinSize();
|
721 |
+
var tooltipHeight = _getOffset(tooltipLayer).height + 10;
|
722 |
+
var tooltipWidth = _getOffset(tooltipLayer).width + 20;
|
723 |
+
var targetOffset = _getOffset(targetElement);
|
724 |
+
|
725 |
+
// If we check all the possible areas, and there are no valid places for the tooltip, the element
|
726 |
+
// must take up most of the screen real estate. Show the tooltip floating in the middle of the screen.
|
727 |
+
var calculatedPosition = "floating";
|
728 |
+
|
729 |
+
// Check if the width of the tooltip + the starting point would spill off the right side of the screen
|
730 |
+
// If no, neither bottom or top are valid
|
731 |
+
if (targetOffset.left + tooltipWidth > windowSize.width || ((targetOffset.left + (targetOffset.width / 2)) - tooltipWidth) < 0) {
|
732 |
+
_removeEntry(possiblePositions, "bottom");
|
733 |
+
_removeEntry(possiblePositions, "top");
|
734 |
+
} else {
|
735 |
+
// Check for space below
|
736 |
+
if ((targetOffset.height + targetOffset.top + tooltipHeight) > windowSize.height) {
|
737 |
+
_removeEntry(possiblePositions, "bottom");
|
738 |
+
}
|
739 |
+
|
740 |
+
// Check for space above
|
741 |
+
if (targetOffset.top - tooltipHeight < 0) {
|
742 |
+
_removeEntry(possiblePositions, "top");
|
743 |
+
}
|
744 |
+
}
|
745 |
+
|
746 |
+
// Check for space to the right
|
747 |
+
if (targetOffset.width + targetOffset.left + tooltipWidth > windowSize.width) {
|
748 |
+
_removeEntry(possiblePositions, "right");
|
749 |
+
}
|
750 |
+
|
751 |
+
// Check for space to the left
|
752 |
+
if (targetOffset.left - tooltipWidth < 0) {
|
753 |
+
_removeEntry(possiblePositions, "left");
|
754 |
+
}
|
755 |
+
|
756 |
+
// At this point, our array only has positions that are valid. Pick the first one, as it remains in order
|
757 |
+
if (possiblePositions.length > 0) {
|
758 |
+
calculatedPosition = possiblePositions[0];
|
759 |
+
}
|
760 |
+
|
761 |
+
// If the requested position is in the list, replace our calculated choice with that
|
762 |
+
if (desiredTooltipPosition && desiredTooltipPosition != "auto") {
|
763 |
+
if (possiblePositions.indexOf(desiredTooltipPosition) > -1) {
|
764 |
+
calculatedPosition = desiredTooltipPosition;
|
765 |
+
}
|
766 |
+
}
|
767 |
+
|
768 |
+
return calculatedPosition;
|
769 |
+
}
|
770 |
+
|
771 |
+
/**
|
772 |
+
* Remove an entry from a string array if it's there, does nothing if it isn't there.
|
773 |
+
*
|
774 |
+
* @param {Array} stringArray
|
775 |
+
* @param {String} stringToRemove
|
776 |
+
*/
|
777 |
+
function _removeEntry(stringArray, stringToRemove) {
|
778 |
+
if (stringArray.indexOf(stringToRemove) > -1) {
|
779 |
+
stringArray.splice(stringArray.indexOf(stringToRemove), 1);
|
780 |
+
}
|
781 |
+
}
|
782 |
+
|
783 |
+
/**
|
784 |
+
* Update the position of the helper layer on the screen
|
785 |
+
*
|
786 |
+
* @api private
|
787 |
+
* @method _setHelperLayerPosition
|
788 |
+
* @param {Object} helperLayer
|
789 |
+
*/
|
790 |
+
function _setHelperLayerPosition(helperLayer) {
|
791 |
+
if (helperLayer) {
|
792 |
+
//prevent error when `this._currentStep` in undefined
|
793 |
+
if (!this._introItems[this._currentStep]) return;
|
794 |
+
|
795 |
+
var currentElement = this._introItems[this._currentStep],
|
796 |
+
elementPosition = _getOffset(currentElement.element),
|
797 |
+
widthHeightPadding = 10;
|
798 |
+
|
799 |
+
// If the target element is fixed, the tooltip should be fixed as well.
|
800 |
+
// Otherwise, remove a fixed class that may be left over from the previous
|
801 |
+
// step.
|
802 |
+
if (_isFixed(currentElement.element)) {
|
803 |
+
helperLayer.className += ' introjs-fixedTooltip';
|
804 |
+
} else {
|
805 |
+
helperLayer.className = helperLayer.className.replace(' introjs-fixedTooltip', '');
|
806 |
+
}
|
807 |
+
|
808 |
+
if (currentElement.position == 'floating') {
|
809 |
+
widthHeightPadding = 0;
|
810 |
+
}
|
811 |
+
|
812 |
+
//set new position to helper layer
|
813 |
+
helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' +
|
814 |
+
'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' +
|
815 |
+
'top:' + (elementPosition.top - 5) + 'px;' +
|
816 |
+
'left: ' + (elementPosition.left - 5) + 'px;');
|
817 |
+
|
818 |
+
}
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Add disableinteraction layer and adjust the size and position of the layer
|
823 |
+
*
|
824 |
+
* @api private
|
825 |
+
* @method _disableInteraction
|
826 |
+
*/
|
827 |
+
function _disableInteraction() {
|
828 |
+
var disableInteractionLayer = document.querySelector('.introjs-disableInteraction');
|
829 |
+
|
830 |
+
if (disableInteractionLayer === null) {
|
831 |
+
disableInteractionLayer = document.createElement('div');
|
832 |
+
disableInteractionLayer.className = 'introjs-disableInteraction';
|
833 |
+
this._targetElement.appendChild(disableInteractionLayer);
|
834 |
+
}
|
835 |
+
|
836 |
+
_setHelperLayerPosition.call(this, disableInteractionLayer);
|
837 |
+
}
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Setting anchors to behave like buttons
|
841 |
+
*
|
842 |
+
* @api private
|
843 |
+
* @method _setAnchorAsButton
|
844 |
+
*/
|
845 |
+
function _setAnchorAsButton(anchor){
|
846 |
+
anchor.setAttribute('role', 'button');
|
847 |
+
anchor.tabIndex = 0;
|
848 |
+
}
|
849 |
+
|
850 |
+
/**
|
851 |
+
* Show an element on the page
|
852 |
+
*
|
853 |
+
* @api private
|
854 |
+
* @method _showElement
|
855 |
+
* @param {Object} targetElement
|
856 |
+
*/
|
857 |
+
function _showElement(targetElement) {
|
858 |
+
if (typeof (this._introChangeCallback) !== 'undefined') {
|
859 |
+
this._introChangeCallback.call(this, targetElement.element);
|
860 |
+
}
|
861 |
+
|
862 |
+
var self = this,
|
863 |
+
oldHelperLayer = document.querySelector('.introjs-helperLayer'),
|
864 |
+
oldReferenceLayer = document.querySelector('.introjs-tooltipReferenceLayer'),
|
865 |
+
highlightClass = 'introjs-helperLayer',
|
866 |
+
elementPosition = _getOffset(targetElement.element);
|
867 |
+
|
868 |
+
//check for a current step highlight class
|
869 |
+
if (typeof (targetElement.highlightClass) === 'string') {
|
870 |
+
highlightClass += (' ' + targetElement.highlightClass);
|
871 |
+
}
|
872 |
+
//check for options highlight class
|
873 |
+
if (typeof (this._options.highlightClass) === 'string') {
|
874 |
+
highlightClass += (' ' + this._options.highlightClass);
|
875 |
+
}
|
876 |
+
|
877 |
+
if (oldHelperLayer != null) {
|
878 |
+
var oldHelperNumberLayer = oldReferenceLayer.querySelector('.introjs-helperNumberLayer'),
|
879 |
+
oldtooltipLayer = oldReferenceLayer.querySelector('.introjs-tooltiptext'),
|
880 |
+
oldArrowLayer = oldReferenceLayer.querySelector('.introjs-arrow'),
|
881 |
+
oldtooltipContainer = oldReferenceLayer.querySelector('.introjs-tooltip'),
|
882 |
+
skipTooltipButton = oldReferenceLayer.querySelector('.introjs-skipbutton'),
|
883 |
+
prevTooltipButton = oldReferenceLayer.querySelector('.introjs-prevbutton'),
|
884 |
+
nextTooltipButton = oldReferenceLayer.querySelector('.introjs-nextbutton');
|
885 |
+
|
886 |
+
//update or reset the helper highlight class
|
887 |
+
oldHelperLayer.className = highlightClass;
|
888 |
+
//hide the tooltip
|
889 |
+
oldtooltipContainer.style.opacity = 0;
|
890 |
+
oldtooltipContainer.style.display = "none";
|
891 |
+
|
892 |
+
if (oldHelperNumberLayer != null) {
|
893 |
+
var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)];
|
894 |
+
|
895 |
+
if (lastIntroItem != null && (this._direction == 'forward' && lastIntroItem.position == 'floating') || (this._direction == 'backward' && targetElement.position == 'floating')) {
|
896 |
+
oldHelperNumberLayer.style.opacity = 0;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
|
900 |
+
//set new position to helper layer
|
901 |
+
_setHelperLayerPosition.call(self, oldHelperLayer);
|
902 |
+
_setHelperLayerPosition.call(self, oldReferenceLayer);
|
903 |
+
|
904 |
+
//remove `introjs-fixParent` class from the elements
|
905 |
+
var fixParents = document.querySelectorAll('.introjs-fixParent');
|
906 |
+
if (fixParents && fixParents.length > 0) {
|
907 |
+
for (var i = fixParents.length - 1; i >= 0; i--) {
|
908 |
+
fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
|
909 |
+
};
|
910 |
+
}
|
911 |
+
|
912 |
+
//remove old classes if the element still exist
|
913 |
+
_removeShowElement();
|
914 |
+
|
915 |
+
//we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
|
916 |
+
if (self._lastShowElementTimer) {
|
917 |
+
clearTimeout(self._lastShowElementTimer);
|
918 |
+
}
|
919 |
+
|
920 |
+
self._lastShowElementTimer = setTimeout(function() {
|
921 |
+
//set current step to the label
|
922 |
+
if (oldHelperNumberLayer != null) {
|
923 |
+
oldHelperNumberLayer.innerHTML = targetElement.step;
|
924 |
+
}
|
925 |
+
//set current tooltip text
|
926 |
+
oldtooltipLayer.innerHTML = targetElement.intro;
|
927 |
+
//set the tooltip position
|
928 |
+
oldtooltipContainer.style.display = "block";
|
929 |
+
_placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
|
930 |
+
|
931 |
+
//change active bullet
|
932 |
+
if (self._options.showBullets) {
|
933 |
+
oldReferenceLayer.querySelector('.introjs-bullets li > a.active').className = '';
|
934 |
+
oldReferenceLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active';
|
935 |
+
}
|
936 |
+
oldReferenceLayer.querySelector('.introjs-progress .introjs-progressbar').setAttribute('style', 'width:' + _getProgress.call(self) + '%;');
|
937 |
+
|
938 |
+
//show the tooltip
|
939 |
+
oldtooltipContainer.style.opacity = 1;
|
940 |
+
if (oldHelperNumberLayer) oldHelperNumberLayer.style.opacity = 1;
|
941 |
+
|
942 |
+
//reset button focus
|
943 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null && /introjs-donebutton/gi.test(skipTooltipButton.className)) {
|
944 |
+
// skip button is now "done" button
|
945 |
+
skipTooltipButton.focus();
|
946 |
+
} else if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
947 |
+
//still in the tour, focus on next
|
948 |
+
nextTooltipButton.focus();
|
949 |
+
}
|
950 |
+
|
951 |
+
// change the scroll of the window, if needed
|
952 |
+
_scrollTo.call(self, targetElement.scrollTo, targetElement, oldtooltipLayer);
|
953 |
+
}, 350);
|
954 |
+
|
955 |
+
// end of old element if-else condition
|
956 |
+
} else {
|
957 |
+
var helperLayer = document.createElement('div'),
|
958 |
+
referenceLayer = document.createElement('div'),
|
959 |
+
arrowLayer = document.createElement('div'),
|
960 |
+
tooltipLayer = document.createElement('div'),
|
961 |
+
tooltipTextLayer = document.createElement('div'),
|
962 |
+
bulletsLayer = document.createElement('div'),
|
963 |
+
progressLayer = document.createElement('div'),
|
964 |
+
buttonsLayer = document.createElement('div');
|
965 |
+
|
966 |
+
helperLayer.className = highlightClass;
|
967 |
+
referenceLayer.className = 'introjs-tooltipReferenceLayer';
|
968 |
+
|
969 |
+
//set new position to helper layer
|
970 |
+
_setHelperLayerPosition.call(self, helperLayer);
|
971 |
+
_setHelperLayerPosition.call(self, referenceLayer);
|
972 |
+
|
973 |
+
//add helper layer to target element
|
974 |
+
this._targetElement.appendChild(helperLayer);
|
975 |
+
this._targetElement.appendChild(referenceLayer);
|
976 |
+
|
977 |
+
arrowLayer.className = 'introjs-arrow';
|
978 |
+
|
979 |
+
tooltipTextLayer.className = 'introjs-tooltiptext';
|
980 |
+
tooltipTextLayer.innerHTML = targetElement.intro;
|
981 |
+
|
982 |
+
bulletsLayer.className = 'introjs-bullets';
|
983 |
+
|
984 |
+
if (this._options.showBullets === false) {
|
985 |
+
bulletsLayer.style.display = 'none';
|
986 |
+
}
|
987 |
+
|
988 |
+
var ulContainer = document.createElement('ul');
|
989 |
+
|
990 |
+
for (var i = 0, stepsLength = this._introItems.length; i < stepsLength; i++) {
|
991 |
+
var innerLi = document.createElement('li');
|
992 |
+
var anchorLink = document.createElement('a');
|
993 |
+
|
994 |
+
anchorLink.onclick = function() {
|
995 |
+
self.goToStep(this.getAttribute('data-stepnumber'));
|
996 |
+
};
|
997 |
+
|
998 |
+
if (i === (targetElement.step-1)) anchorLink.className = 'active';
|
999 |
+
|
1000 |
+
_setAnchorAsButton(anchorLink);
|
1001 |
+
anchorLink.innerHTML = " ";
|
1002 |
+
anchorLink.setAttribute('data-stepnumber', this._introItems[i].step);
|
1003 |
+
|
1004 |
+
innerLi.appendChild(anchorLink);
|
1005 |
+
ulContainer.appendChild(innerLi);
|
1006 |
+
}
|
1007 |
+
|
1008 |
+
bulletsLayer.appendChild(ulContainer);
|
1009 |
+
|
1010 |
+
progressLayer.className = 'introjs-progress';
|
1011 |
+
|
1012 |
+
if (this._options.showProgress === false) {
|
1013 |
+
progressLayer.style.display = 'none';
|
1014 |
+
}
|
1015 |
+
var progressBar = document.createElement('div');
|
1016 |
+
progressBar.className = 'introjs-progressbar';
|
1017 |
+
progressBar.setAttribute('style', 'width:' + _getProgress.call(this) + '%;');
|
1018 |
+
|
1019 |
+
progressLayer.appendChild(progressBar);
|
1020 |
+
|
1021 |
+
buttonsLayer.className = 'introjs-tooltipbuttons';
|
1022 |
+
if (this._options.showButtons === false) {
|
1023 |
+
buttonsLayer.style.display = 'none';
|
1024 |
+
}
|
1025 |
+
|
1026 |
+
tooltipLayer.className = 'introjs-tooltip';
|
1027 |
+
tooltipLayer.appendChild(tooltipTextLayer);
|
1028 |
+
tooltipLayer.appendChild(bulletsLayer);
|
1029 |
+
tooltipLayer.appendChild(progressLayer);
|
1030 |
+
|
1031 |
+
//add helper layer number
|
1032 |
+
if (this._options.showStepNumbers == true) {
|
1033 |
+
var helperNumberLayer = document.createElement('span');
|
1034 |
+
helperNumberLayer.className = 'introjs-helperNumberLayer';
|
1035 |
+
helperNumberLayer.innerHTML = targetElement.step;
|
1036 |
+
referenceLayer.appendChild(helperNumberLayer);
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
tooltipLayer.appendChild(arrowLayer);
|
1040 |
+
referenceLayer.appendChild(tooltipLayer);
|
1041 |
+
|
1042 |
+
//next button
|
1043 |
+
var nextTooltipButton = document.createElement('a');
|
1044 |
+
|
1045 |
+
nextTooltipButton.onclick = function() {
|
1046 |
+
if (self._introItems.length - 1 != self._currentStep) {
|
1047 |
+
_nextStep.call(self);
|
1048 |
+
}
|
1049 |
+
};
|
1050 |
+
|
1051 |
+
_setAnchorAsButton(nextTooltipButton);
|
1052 |
+
nextTooltipButton.innerHTML = this._options.nextLabel;
|
1053 |
+
|
1054 |
+
//previous button
|
1055 |
+
var prevTooltipButton = document.createElement('a');
|
1056 |
+
|
1057 |
+
prevTooltipButton.onclick = function() {
|
1058 |
+
if (self._currentStep != 0) {
|
1059 |
+
_previousStep.call(self);
|
1060 |
+
}
|
1061 |
+
};
|
1062 |
+
|
1063 |
+
_setAnchorAsButton(prevTooltipButton);
|
1064 |
+
prevTooltipButton.innerHTML = this._options.prevLabel;
|
1065 |
+
|
1066 |
+
//skip button
|
1067 |
+
var skipTooltipButton = document.createElement('a');
|
1068 |
+
skipTooltipButton.className = 'introjs-button introjs-skipbutton';
|
1069 |
+
_setAnchorAsButton(skipTooltipButton);
|
1070 |
+
skipTooltipButton.innerHTML = this._options.skipLabel;
|
1071 |
+
|
1072 |
+
skipTooltipButton.onclick = function() {
|
1073 |
+
if (self._introItems.length - 1 == self._currentStep && typeof (self._introCompleteCallback) === 'function') {
|
1074 |
+
self._introCompleteCallback.call(self);
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
_exitIntro.call(self, self._targetElement);
|
1078 |
+
};
|
1079 |
+
|
1080 |
+
buttonsLayer.appendChild(skipTooltipButton);
|
1081 |
+
|
1082 |
+
//in order to prevent displaying next/previous button always
|
1083 |
+
if (this._introItems.length > 1) {
|
1084 |
+
buttonsLayer.appendChild(prevTooltipButton);
|
1085 |
+
buttonsLayer.appendChild(nextTooltipButton);
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
tooltipLayer.appendChild(buttonsLayer);
|
1089 |
+
|
1090 |
+
//set proper position
|
1091 |
+
_placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
|
1092 |
+
|
1093 |
+
// change the scroll of the window, if needed
|
1094 |
+
_scrollTo.call(this, targetElement.scrollTo, targetElement, tooltipLayer);
|
1095 |
+
|
1096 |
+
//end of new element if-else condition
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
// removing previous disable interaction layer
|
1100 |
+
var disableInteractionLayer = self._targetElement.querySelector('.introjs-disableInteraction');
|
1101 |
+
if (disableInteractionLayer) {
|
1102 |
+
disableInteractionLayer.parentNode.removeChild(disableInteractionLayer);
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
//disable interaction
|
1106 |
+
if (targetElement.disableInteraction) {
|
1107 |
+
_disableInteraction.call(self);
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1111 |
+
nextTooltipButton.removeAttribute('tabIndex');
|
1112 |
+
}
|
1113 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1114 |
+
prevTooltipButton.removeAttribute('tabIndex');
|
1115 |
+
}
|
1116 |
+
|
1117 |
+
// when it's the first step of tour
|
1118 |
+
if (this._currentStep == 0 && this._introItems.length > 1) {
|
1119 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null) {
|
1120 |
+
skipTooltipButton.className = 'introjs-button introjs-skipbutton';
|
1121 |
+
}
|
1122 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1123 |
+
nextTooltipButton.className = 'introjs-button introjs-nextbutton';
|
1124 |
+
}
|
1125 |
+
|
1126 |
+
if (this._options.hidePrev == true) {
|
1127 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1128 |
+
prevTooltipButton.className = 'introjs-button introjs-prevbutton introjs-hidden';
|
1129 |
+
}
|
1130 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1131 |
+
nextTooltipButton.className += ' introjs-fullbutton';
|
1132 |
+
}
|
1133 |
+
} else {
|
1134 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1135 |
+
prevTooltipButton.className = 'introjs-button introjs-prevbutton introjs-disabled';
|
1136 |
+
}
|
1137 |
+
}
|
1138 |
+
|
1139 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1140 |
+
prevTooltipButton.tabIndex = '-1';
|
1141 |
+
}
|
1142 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null) {
|
1143 |
+
skipTooltipButton.innerHTML = this._options.skipLabel;
|
1144 |
+
}
|
1145 |
+
} else if (this._introItems.length - 1 == this._currentStep || this._introItems.length == 1) {
|
1146 |
+
// last step of tour
|
1147 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null) {
|
1148 |
+
skipTooltipButton.innerHTML = this._options.doneLabel;
|
1149 |
+
// adding donebutton class in addition to skipbutton
|
1150 |
+
skipTooltipButton.className += ' introjs-donebutton';
|
1151 |
+
}
|
1152 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1153 |
+
prevTooltipButton.className = 'introjs-button introjs-prevbutton';
|
1154 |
+
}
|
1155 |
+
|
1156 |
+
if (this._options.hideNext == true) {
|
1157 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1158 |
+
nextTooltipButton.className = 'introjs-button introjs-nextbutton introjs-hidden';
|
1159 |
+
}
|
1160 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1161 |
+
prevTooltipButton.className += ' introjs-fullbutton';
|
1162 |
+
}
|
1163 |
+
} else {
|
1164 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1165 |
+
nextTooltipButton.className = 'introjs-button introjs-nextbutton introjs-disabled';
|
1166 |
+
}
|
1167 |
+
}
|
1168 |
+
|
1169 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1170 |
+
nextTooltipButton.tabIndex = '-1';
|
1171 |
+
}
|
1172 |
+
} else {
|
1173 |
+
// steps between start and end
|
1174 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null) {
|
1175 |
+
skipTooltipButton.className = 'introjs-button introjs-skipbutton';
|
1176 |
+
}
|
1177 |
+
if (typeof prevTooltipButton !== "undefined" && prevTooltipButton != null) {
|
1178 |
+
prevTooltipButton.className = 'introjs-button introjs-prevbutton';
|
1179 |
+
}
|
1180 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1181 |
+
nextTooltipButton.className = 'introjs-button introjs-nextbutton';
|
1182 |
+
}
|
1183 |
+
if (typeof skipTooltipButton !== "undefined" && skipTooltipButton != null) {
|
1184 |
+
skipTooltipButton.innerHTML = this._options.skipLabel;
|
1185 |
+
}
|
1186 |
+
}
|
1187 |
+
|
1188 |
+
//Set focus on "next" button, so that hitting Enter always moves you onto the next step
|
1189 |
+
if (typeof nextTooltipButton !== "undefined" && nextTooltipButton != null) {
|
1190 |
+
nextTooltipButton.focus();
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
_setShowElement(targetElement);
|
1194 |
+
|
1195 |
+
if (typeof (this._introAfterChangeCallback) !== 'undefined') {
|
1196 |
+
this._introAfterChangeCallback.call(this, targetElement.element);
|
1197 |
+
}
|
1198 |
+
}
|
1199 |
+
|
1200 |
+
/**
|
1201 |
+
* To change the scroll of `window` after highlighting an element
|
1202 |
+
*
|
1203 |
+
* @api private
|
1204 |
+
* @method _scrollTo
|
1205 |
+
* @param {String} scrollTo
|
1206 |
+
* @param {Object} targetElement
|
1207 |
+
* @param {Object} tooltipLayer
|
1208 |
+
*/
|
1209 |
+
function _scrollTo(scrollTo, targetElement, tooltipLayer) {
|
1210 |
+
if (!this._options.scrollToElement) return;
|
1211 |
+
|
1212 |
+
if (scrollTo === 'tooltip') {
|
1213 |
+
var rect = tooltipLayer.getBoundingClientRect();
|
1214 |
+
} else {
|
1215 |
+
var rect = targetElement.element.getBoundingClientRect();
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
if (!_elementInViewport(targetElement.element)) {
|
1219 |
+
var winHeight = _getWinSize().height;
|
1220 |
+
var top = rect.bottom - (rect.bottom - rect.top);
|
1221 |
+
var bottom = rect.bottom - winHeight;
|
1222 |
+
|
1223 |
+
// TODO (afshinm): do we need scroll padding now?
|
1224 |
+
// I have changed the scroll option and now it scrolls the window to
|
1225 |
+
// the center of the target element or tooltip.
|
1226 |
+
|
1227 |
+
if (top < 0 || targetElement.element.clientHeight > winHeight) {
|
1228 |
+
window.scrollBy(0, rect.top - ((winHeight / 2) - (rect.height / 2)) - this._options.scrollPadding); // 30px padding from edge to look nice
|
1229 |
+
|
1230 |
+
//Scroll down
|
1231 |
+
} else {
|
1232 |
+
window.scrollBy(0, rect.top - ((winHeight / 2) - (rect.height / 2)) + this._options.scrollPadding); // 30px padding from edge to look nice
|
1233 |
+
}
|
1234 |
+
}
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
/**
|
1238 |
+
* To remove all show element(s)
|
1239 |
+
*
|
1240 |
+
* @api private
|
1241 |
+
* @method _removeShowElement
|
1242 |
+
*/
|
1243 |
+
function _removeShowElement() {
|
1244 |
+
var elms = document.querySelectorAll('.introjs-showElement');
|
1245 |
+
|
1246 |
+
for (var i = 0, l = elms.length; i < l; i++) {
|
1247 |
+
var elm = elms[i];
|
1248 |
+
_removeClass(elm, /introjs-[a-zA-Z]+/g);
|
1249 |
+
}
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
/**
|
1253 |
+
* To set the show element
|
1254 |
+
* This function set a relative (in most cases) position and changes the z-index
|
1255 |
+
*
|
1256 |
+
* @api private
|
1257 |
+
* @method _setShowElement
|
1258 |
+
* @param {Object} targetElement
|
1259 |
+
*/
|
1260 |
+
function _setShowElement(targetElement) {
|
1261 |
+
// we need to add this show element class to the parent of SVG elements
|
1262 |
+
// because the SVG elements can't have independent z-index
|
1263 |
+
if (targetElement.element instanceof SVGElement) {
|
1264 |
+
var parentElm = targetElement.element.parentNode;
|
1265 |
+
|
1266 |
+
while (targetElement.element.parentNode != null) {
|
1267 |
+
if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
|
1268 |
+
|
1269 |
+
if (parentElm.tagName.toLowerCase() === 'svg') {
|
1270 |
+
_setClass(parentElm, 'introjs-showElement introjs-relativePosition');
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
parentElm = parentElm.parentNode;
|
1274 |
+
}
|
1275 |
+
}
|
1276 |
+
|
1277 |
+
_setClass(targetElement.element, 'introjs-showElement');
|
1278 |
+
|
1279 |
+
var currentElementPosition = _getPropValue(targetElement.element, 'position');
|
1280 |
+
if (currentElementPosition !== 'absolute' &&
|
1281 |
+
currentElementPosition !== 'relative' &&
|
1282 |
+
currentElementPosition !== 'fixed') {
|
1283 |
+
//change to new intro item
|
1284 |
+
//targetElement.element.className += ' introjs-relativePosition';
|
1285 |
+
_setClass(targetElement.element, 'introjs-relativePosition')
|
1286 |
+
}
|
1287 |
+
|
1288 |
+
var parentElm = targetElement.element.parentNode;
|
1289 |
+
while (parentElm != null) {
|
1290 |
+
if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
|
1291 |
+
|
1292 |
+
//fix The Stacking Context problem.
|
1293 |
+
//More detail: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context
|
1294 |
+
var zIndex = _getPropValue(parentElm, 'z-index');
|
1295 |
+
var opacity = parseFloat(_getPropValue(parentElm, 'opacity'));
|
1296 |
+
var transform = _getPropValue(parentElm, 'transform') || _getPropValue(parentElm, '-webkit-transform') || _getPropValue(parentElm, '-moz-transform') || _getPropValue(parentElm, '-ms-transform') || _getPropValue(parentElm, '-o-transform');
|
1297 |
+
if (/[0-9]+/.test(zIndex) || opacity < 1 || (transform !== 'none' && transform !== undefined)) {
|
1298 |
+
parentElm.className += ' introjs-fixParent';
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
parentElm = parentElm.parentNode;
|
1302 |
+
}
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
function _setClass(element, className) {
|
1306 |
+
if (element instanceof SVGElement) {
|
1307 |
+
var pre = element.getAttribute('class') || '';
|
1308 |
+
|
1309 |
+
element.setAttribute('class', pre + ' ' + className);
|
1310 |
+
} else {
|
1311 |
+
element.className += ' ' + className;
|
1312 |
+
}
|
1313 |
+
}
|
1314 |
+
|
1315 |
+
function _removeClass(element, classNameRegex) {
|
1316 |
+
if (element instanceof SVGElement) {
|
1317 |
+
var pre = element.getAttribute('class') || '';
|
1318 |
+
|
1319 |
+
element.setAttribute('class', pre.replace(classNameRegex, '').replace(/^\s+|\s+$/g, ''));
|
1320 |
+
} else {
|
1321 |
+
element.className = element.className.replace(classNameRegex, '').replace(/^\s+|\s+$/g, '');
|
1322 |
+
}
|
1323 |
+
}
|
1324 |
+
|
1325 |
+
/**
|
1326 |
+
* Get an element CSS property on the page
|
1327 |
+
* Thanks to JavaScript Kit: http://www.javascriptkit.com/dhtmltutors/dhtmlcascade4.shtml
|
1328 |
+
*
|
1329 |
+
* @api private
|
1330 |
+
* @method _getPropValue
|
1331 |
+
* @param {Object} element
|
1332 |
+
* @param {String} propName
|
1333 |
+
* @returns Element's property value
|
1334 |
+
*/
|
1335 |
+
function _getPropValue (element, propName) {
|
1336 |
+
var propValue = '';
|
1337 |
+
if (element.currentStyle) { //IE
|
1338 |
+
propValue = element.currentStyle[propName];
|
1339 |
+
} else if (document.defaultView && document.defaultView.getComputedStyle) { //Others
|
1340 |
+
propValue = document.defaultView.getComputedStyle(element, null).getPropertyValue(propName);
|
1341 |
+
}
|
1342 |
+
|
1343 |
+
//Prevent exception in IE
|
1344 |
+
if (propValue && propValue.toLowerCase) {
|
1345 |
+
return propValue.toLowerCase();
|
1346 |
+
} else {
|
1347 |
+
return propValue;
|
1348 |
+
}
|
1349 |
+
}
|
1350 |
+
|
1351 |
+
/**
|
1352 |
+
* Checks to see if target element (or parents) position is fixed or not
|
1353 |
+
*
|
1354 |
+
* @api private
|
1355 |
+
* @method _isFixed
|
1356 |
+
* @param {Object} element
|
1357 |
+
* @returns Boolean
|
1358 |
+
*/
|
1359 |
+
function _isFixed (element) {
|
1360 |
+
var p = element.parentNode;
|
1361 |
+
|
1362 |
+
if (!p || p.nodeName === 'HTML') {
|
1363 |
+
return false;
|
1364 |
+
}
|
1365 |
+
|
1366 |
+
if (_getPropValue(element, 'position') == 'fixed') {
|
1367 |
+
return true;
|
1368 |
+
}
|
1369 |
+
|
1370 |
+
return _isFixed(p);
|
1371 |
+
}
|
1372 |
+
|
1373 |
+
/**
|
1374 |
+
* Provides a cross-browser way to get the screen dimensions
|
1375 |
+
* via: http://stackoverflow.com/questions/5864467/internet-explorer-innerheight
|
1376 |
+
*
|
1377 |
+
* @api private
|
1378 |
+
* @method _getWinSize
|
1379 |
+
* @returns {Object} width and height attributes
|
1380 |
+
*/
|
1381 |
+
function _getWinSize() {
|
1382 |
+
if (window.innerWidth != undefined) {
|
1383 |
+
return { width: window.innerWidth, height: window.innerHeight };
|
1384 |
+
} else {
|
1385 |
+
var D = document.documentElement;
|
1386 |
+
return { width: D.clientWidth, height: D.clientHeight };
|
1387 |
+
}
|
1388 |
+
}
|
1389 |
+
|
1390 |
+
/**
|
1391 |
+
* Check to see if the element is in the viewport or not
|
1392 |
+
* http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
|
1393 |
+
*
|
1394 |
+
* @api private
|
1395 |
+
* @method _elementInViewport
|
1396 |
+
* @param {Object} el
|
1397 |
+
*/
|
1398 |
+
function _elementInViewport(el) {
|
1399 |
+
var rect = el.getBoundingClientRect();
|
1400 |
+
|
1401 |
+
return (
|
1402 |
+
rect.top >= 0 &&
|
1403 |
+
rect.left >= 0 &&
|
1404 |
+
(rect.bottom+80) <= window.innerHeight && // add 80 to get the text right
|
1405 |
+
rect.right <= window.innerWidth
|
1406 |
+
);
|
1407 |
+
}
|
1408 |
+
|
1409 |
+
/**
|
1410 |
+
* Add overlay layer to the page
|
1411 |
+
*
|
1412 |
+
* @api private
|
1413 |
+
* @method _addOverlayLayer
|
1414 |
+
* @param {Object} targetElm
|
1415 |
+
*/
|
1416 |
+
function _addOverlayLayer(targetElm) {
|
1417 |
+
var overlayLayer = document.createElement('div'),
|
1418 |
+
styleText = '',
|
1419 |
+
self = this;
|
1420 |
+
|
1421 |
+
//set css class name
|
1422 |
+
overlayLayer.className = 'introjs-overlay';
|
1423 |
+
|
1424 |
+
//check if the target element is body, we should calculate the size of overlay layer in a better way
|
1425 |
+
if (!targetElm.tagName || targetElm.tagName.toLowerCase() === 'body') {
|
1426 |
+
styleText += 'top: 0;bottom: 0; left: 0;right: 0;position: fixed;';
|
1427 |
+
overlayLayer.setAttribute('style', styleText);
|
1428 |
+
} else {
|
1429 |
+
//set overlay layer position
|
1430 |
+
var elementPosition = _getOffset(targetElm);
|
1431 |
+
if (elementPosition) {
|
1432 |
+
styleText += 'width: ' + elementPosition.width + 'px; height:' + elementPosition.height + 'px; top:' + elementPosition.top + 'px;left: ' + elementPosition.left + 'px;';
|
1433 |
+
overlayLayer.setAttribute('style', styleText);
|
1434 |
+
}
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
targetElm.appendChild(overlayLayer);
|
1438 |
+
|
1439 |
+
overlayLayer.onclick = function() {
|
1440 |
+
if (self._options.exitOnOverlayClick == true) {
|
1441 |
+
_exitIntro.call(self, targetElm);
|
1442 |
+
}
|
1443 |
+
};
|
1444 |
+
|
1445 |
+
setTimeout(function() {
|
1446 |
+
styleText += 'opacity: ' + self._options.overlayOpacity.toString() + ';';
|
1447 |
+
overlayLayer.setAttribute('style', styleText);
|
1448 |
+
}, 10);
|
1449 |
+
|
1450 |
+
return true;
|
1451 |
+
}
|
1452 |
+
|
1453 |
+
/**
|
1454 |
+
* Removes open hint (tooltip hint)
|
1455 |
+
*
|
1456 |
+
* @api private
|
1457 |
+
* @method _removeHintTooltip
|
1458 |
+
*/
|
1459 |
+
function _removeHintTooltip() {
|
1460 |
+
var tooltip = this._targetElement.querySelector('.introjs-hintReference');
|
1461 |
+
|
1462 |
+
if (tooltip) {
|
1463 |
+
var step = tooltip.getAttribute('data-step');
|
1464 |
+
tooltip.parentNode.removeChild(tooltip);
|
1465 |
+
return step;
|
1466 |
+
}
|
1467 |
+
}
|
1468 |
+
|
1469 |
+
/**
|
1470 |
+
* Start parsing hint items
|
1471 |
+
*
|
1472 |
+
* @api private
|
1473 |
+
* @param {Object} targetElm
|
1474 |
+
* @method _startHint
|
1475 |
+
*/
|
1476 |
+
function _populateHints(targetElm) {
|
1477 |
+
var self = this;
|
1478 |
+
this._introItems = [];
|
1479 |
+
|
1480 |
+
if (this._options.hints) {
|
1481 |
+
for (var i = 0, l = this._options.hints.length; i < l; i++) {
|
1482 |
+
var currentItem = _cloneObject(this._options.hints[i]);
|
1483 |
+
|
1484 |
+
if (typeof(currentItem.element) === 'string') {
|
1485 |
+
//grab the element with given selector from the page
|
1486 |
+
currentItem.element = document.querySelector(currentItem.element);
|
1487 |
+
}
|
1488 |
+
|
1489 |
+
currentItem.hintPosition = currentItem.hintPosition || this._options.hintPosition;
|
1490 |
+
currentItem.hintAnimation = currentItem.hintAnimation || this._options.hintAnimation;
|
1491 |
+
|
1492 |
+
if (currentItem.element != null) {
|
1493 |
+
this._introItems.push(currentItem);
|
1494 |
+
}
|
1495 |
+
}
|
1496 |
+
} else {
|
1497 |
+
var hints = targetElm.querySelectorAll('*[data-hint]');
|
1498 |
+
|
1499 |
+
if (hints.length < 1) {
|
1500 |
+
return false;
|
1501 |
+
}
|
1502 |
+
|
1503 |
+
//first add intro items with data-step
|
1504 |
+
for (var i = 0, l = hints.length; i < l; i++) {
|
1505 |
+
var currentElement = hints[i];
|
1506 |
+
|
1507 |
+
// hint animation
|
1508 |
+
var hintAnimation = currentElement.getAttribute('data-hintAnimation');
|
1509 |
+
|
1510 |
+
if (hintAnimation) {
|
1511 |
+
hintAnimation = (hintAnimation == 'true');
|
1512 |
+
} else {
|
1513 |
+
hintAnimation = this._options.hintAnimation;
|
1514 |
+
}
|
1515 |
+
|
1516 |
+
this._introItems.push({
|
1517 |
+
element: currentElement,
|
1518 |
+
hint: currentElement.getAttribute('data-hint'),
|
1519 |
+
hintPosition: currentElement.getAttribute('data-hintPosition') || this._options.hintPosition,
|
1520 |
+
hintAnimation: hintAnimation,
|
1521 |
+
tooltipClass: currentElement.getAttribute('data-tooltipClass'),
|
1522 |
+
position: currentElement.getAttribute('data-position') || this._options.tooltipPosition
|
1523 |
+
});
|
1524 |
+
}
|
1525 |
+
}
|
1526 |
+
|
1527 |
+
_addHints.call(this);
|
1528 |
+
|
1529 |
+
if (document.addEventListener) {
|
1530 |
+
document.addEventListener('click', _removeHintTooltip.bind(this), false);
|
1531 |
+
//for window resize
|
1532 |
+
window.addEventListener('resize', _reAlignHints.bind(this), true);
|
1533 |
+
} else if (document.attachEvent) { //IE
|
1534 |
+
//for window resize
|
1535 |
+
document.attachEvent('onclick', _removeHintTooltip.bind(this));
|
1536 |
+
document.attachEvent('onresize', _reAlignHints.bind(this));
|
1537 |
+
}
|
1538 |
+
}
|
1539 |
+
|
1540 |
+
/**
|
1541 |
+
* Re-aligns all hint elements
|
1542 |
+
*
|
1543 |
+
* @api private
|
1544 |
+
* @method _reAlignHints
|
1545 |
+
*/
|
1546 |
+
function _reAlignHints() {
|
1547 |
+
for (var i = 0, l = this._introItems.length; i < l; i++) {
|
1548 |
+
var item = this._introItems[i];
|
1549 |
+
|
1550 |
+
if (typeof (item.targetElement) == 'undefined') continue;
|
1551 |
+
|
1552 |
+
_alignHintPosition.call(this, item.hintPosition, item.element, item.targetElement)
|
1553 |
+
}
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
/**
|
1557 |
+
* Hide a hint
|
1558 |
+
*
|
1559 |
+
* @api private
|
1560 |
+
* @method _hideHint
|
1561 |
+
*/
|
1562 |
+
function _hideHint(stepId) {
|
1563 |
+
_removeHintTooltip.call(this);
|
1564 |
+
var hint = this._targetElement.querySelector('.introjs-hint[data-step="' + stepId + '"]');
|
1565 |
+
|
1566 |
+
if (hint) {
|
1567 |
+
hint.className += ' introjs-hidehint';
|
1568 |
+
}
|
1569 |
+
|
1570 |
+
// call the callback function (if any)
|
1571 |
+
if (typeof (this._hintCloseCallback) !== 'undefined') {
|
1572 |
+
this._hintCloseCallback.call(this, stepId);
|
1573 |
+
}
|
1574 |
+
}
|
1575 |
+
|
1576 |
+
/**
|
1577 |
+
* Hide all hints
|
1578 |
+
*
|
1579 |
+
* @api private
|
1580 |
+
* @method _hideHints
|
1581 |
+
*/
|
1582 |
+
function _hideHints() {
|
1583 |
+
var hints = this._targetElement.querySelectorAll('.introjs-hint');
|
1584 |
+
|
1585 |
+
if (hints && hints.length > 0) {
|
1586 |
+
for (var i = 0; i < hints.length; i++) {
|
1587 |
+
_hideHint.call(this, hints[i].getAttribute('data-step'));
|
1588 |
+
}
|
1589 |
+
}
|
1590 |
+
}
|
1591 |
+
|
1592 |
+
/**
|
1593 |
+
* Show all hints
|
1594 |
+
*
|
1595 |
+
* @api private
|
1596 |
+
* @method _showHints
|
1597 |
+
*/
|
1598 |
+
function _showHints() {
|
1599 |
+
var hints = this._targetElement.querySelectorAll('.introjs-hint');
|
1600 |
+
|
1601 |
+
if (hints && hints.length > 0) {
|
1602 |
+
for (var i = 0; i < hints.length; i++) {
|
1603 |
+
_showHint.call(this, hints[i].getAttribute('data-step'));
|
1604 |
+
}
|
1605 |
+
} else {
|
1606 |
+
_populateHints.call(this, this._targetElement);
|
1607 |
+
}
|
1608 |
+
};
|
1609 |
+
|
1610 |
+
/**
|
1611 |
+
* Show a hint
|
1612 |
+
*
|
1613 |
+
* @api private
|
1614 |
+
* @method _showHint
|
1615 |
+
*/
|
1616 |
+
function _showHint(stepId) {
|
1617 |
+
var hint = this._targetElement.querySelector('.introjs-hint[data-step="' + stepId + '"]');
|
1618 |
+
|
1619 |
+
if (hint) {
|
1620 |
+
hint.className = hint.className.replace(/introjs\-hidehint/g, '');
|
1621 |
+
}
|
1622 |
+
};
|
1623 |
+
|
1624 |
+
/**
|
1625 |
+
* Removes all hint elements on the page
|
1626 |
+
* Useful when you want to destroy the elements and add them again (e.g. a modal or popup)
|
1627 |
+
*
|
1628 |
+
* @api private
|
1629 |
+
* @method _removeHints
|
1630 |
+
*/
|
1631 |
+
function _removeHints() {
|
1632 |
+
var hints = this._targetElement.querySelectorAll('.introjs-hint');
|
1633 |
+
|
1634 |
+
if (hints && hints.length > 0) {
|
1635 |
+
for (var i = 0; i < hints.length; i++) {
|
1636 |
+
_removeHint.call(this, hints[i].getAttribute('data-step'));
|
1637 |
+
}
|
1638 |
+
}
|
1639 |
+
};
|
1640 |
+
|
1641 |
+
/**
|
1642 |
+
* Remove one single hint element from the page
|
1643 |
+
* Useful when you want to destroy the element and add them again (e.g. a modal or popup)
|
1644 |
+
* Use removeHints if you want to remove all elements.
|
1645 |
+
*
|
1646 |
+
* @api private
|
1647 |
+
* @method _removeHint
|
1648 |
+
*/
|
1649 |
+
function _removeHint(stepId) {
|
1650 |
+
var hint = this._targetElement.querySelector('.introjs-hint[data-step="' + stepId + '"]');
|
1651 |
+
|
1652 |
+
if (hint) {
|
1653 |
+
hint.parentNode.removeChild(hint);
|
1654 |
+
}
|
1655 |
+
};
|
1656 |
+
|
1657 |
+
/**
|
1658 |
+
* Add all available hints to the page
|
1659 |
+
*
|
1660 |
+
* @api private
|
1661 |
+
* @method _addHints
|
1662 |
+
*/
|
1663 |
+
function _addHints() {
|
1664 |
+
var self = this;
|
1665 |
+
|
1666 |
+
var oldHintsWrapper = document.querySelector('.introjs-hints');
|
1667 |
+
|
1668 |
+
if (oldHintsWrapper != null) {
|
1669 |
+
hintsWrapper = oldHintsWrapper;
|
1670 |
+
} else {
|
1671 |
+
var hintsWrapper = document.createElement('div');
|
1672 |
+
hintsWrapper.className = 'introjs-hints';
|
1673 |
+
}
|
1674 |
+
|
1675 |
+
for (var i = 0, l = this._introItems.length; i < l; i++) {
|
1676 |
+
var item = this._introItems[i];
|
1677 |
+
|
1678 |
+
// avoid append a hint twice
|
1679 |
+
if (document.querySelector('.introjs-hint[data-step="' + i + '"]'))
|
1680 |
+
continue;
|
1681 |
+
|
1682 |
+
var hint = document.createElement('a');
|
1683 |
+
_setAnchorAsButton(hint);
|
1684 |
+
|
1685 |
+
(function (hint, item, i) {
|
1686 |
+
// when user clicks on the hint element
|
1687 |
+
hint.onclick = function(e) {
|
1688 |
+
var evt = e ? e : window.event;
|
1689 |
+
if (evt.stopPropagation) evt.stopPropagation();
|
1690 |
+
if (evt.cancelBubble != null) evt.cancelBubble = true;
|
1691 |
+
|
1692 |
+
_showHintDialog.call(self, i);
|
1693 |
+
};
|
1694 |
+
}(hint, item, i));
|
1695 |
+
|
1696 |
+
hint.className = 'introjs-hint';
|
1697 |
+
|
1698 |
+
if (!item.hintAnimation) {
|
1699 |
+
hint.className += ' introjs-hint-no-anim';
|
1700 |
+
}
|
1701 |
+
|
1702 |
+
// hint's position should be fixed if the target element's position is fixed
|
1703 |
+
if (_isFixed(item.element)) {
|
1704 |
+
hint.className += ' introjs-fixedhint';
|
1705 |
+
}
|
1706 |
+
|
1707 |
+
var hintDot = document.createElement('div');
|
1708 |
+
hintDot.className = 'introjs-hint-dot';
|
1709 |
+
var hintPulse = document.createElement('div');
|
1710 |
+
hintPulse.className = 'introjs-hint-pulse';
|
1711 |
+
|
1712 |
+
hint.appendChild(hintDot);
|
1713 |
+
hint.appendChild(hintPulse);
|
1714 |
+
hint.setAttribute('data-step', i);
|
1715 |
+
|
1716 |
+
// we swap the hint element with target element
|
1717 |
+
// because _setHelperLayerPosition uses `element` property
|
1718 |
+
item.targetElement = item.element;
|
1719 |
+
item.element = hint;
|
1720 |
+
|
1721 |
+
// align the hint position
|
1722 |
+
_alignHintPosition.call(this, item.hintPosition, hint, item.targetElement);
|
1723 |
+
|
1724 |
+
hintsWrapper.appendChild(hint);
|
1725 |
+
}
|
1726 |
+
|
1727 |
+
// adding the hints wrapper
|
1728 |
+
document.body.appendChild(hintsWrapper);
|
1729 |
+
|
1730 |
+
// call the callback function (if any)
|
1731 |
+
if (typeof (this._hintsAddedCallback) !== 'undefined') {
|
1732 |
+
this._hintsAddedCallback.call(this);
|
1733 |
+
}
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
/**
|
1737 |
+
* Aligns hint position
|
1738 |
+
*
|
1739 |
+
* @api private
|
1740 |
+
* @method _alignHintPosition
|
1741 |
+
* @param {String} position
|
1742 |
+
* @param {Object} hint
|
1743 |
+
* @param {Object} element
|
1744 |
+
*/
|
1745 |
+
function _alignHintPosition(position, hint, element) {
|
1746 |
+
// get/calculate offset of target element
|
1747 |
+
var offset = _getOffset.call(this, element);
|
1748 |
+
var iconWidth = 20;
|
1749 |
+
var iconHeight = 20;
|
1750 |
+
|
1751 |
+
// align the hint element
|
1752 |
+
switch (position) {
|
1753 |
+
default:
|
1754 |
+
case 'top-left':
|
1755 |
+
hint.style.left = offset.left + 'px';
|
1756 |
+
hint.style.top = offset.top + 'px';
|
1757 |
+
break;
|
1758 |
+
case 'top-right':
|
1759 |
+
hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
|
1760 |
+
hint.style.top = offset.top + 'px';
|
1761 |
+
break;
|
1762 |
+
case 'bottom-left':
|
1763 |
+
hint.style.left = offset.left + 'px';
|
1764 |
+
hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
|
1765 |
+
break;
|
1766 |
+
case 'bottom-right':
|
1767 |
+
hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
|
1768 |
+
hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
|
1769 |
+
break;
|
1770 |
+
case 'middle-left':
|
1771 |
+
hint.style.left = offset.left + 'px';
|
1772 |
+
hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
|
1773 |
+
break;
|
1774 |
+
case 'middle-right':
|
1775 |
+
hint.style.left = (offset.left + offset.width - iconWidth) + 'px';
|
1776 |
+
hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
|
1777 |
+
break;
|
1778 |
+
case 'middle-middle':
|
1779 |
+
hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
|
1780 |
+
hint.style.top = (offset.top + (offset.height - iconHeight) / 2) + 'px';
|
1781 |
+
break;
|
1782 |
+
case 'bottom-middle':
|
1783 |
+
hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
|
1784 |
+
hint.style.top = (offset.top + offset.height - iconHeight) + 'px';
|
1785 |
+
break;
|
1786 |
+
case 'top-middle':
|
1787 |
+
hint.style.left = (offset.left + (offset.width - iconWidth) / 2) + 'px';
|
1788 |
+
hint.style.top = offset.top + 'px';
|
1789 |
+
break;
|
1790 |
+
}
|
1791 |
+
}
|
1792 |
+
|
1793 |
+
/**
|
1794 |
+
* Triggers when user clicks on the hint element
|
1795 |
+
*
|
1796 |
+
* @api private
|
1797 |
+
* @method _showHintDialog
|
1798 |
+
* @param {Number} stepId
|
1799 |
+
*/
|
1800 |
+
function _showHintDialog(stepId) {
|
1801 |
+
var hintElement = document.querySelector('.introjs-hint[data-step="' + stepId + '"]');
|
1802 |
+
var item = this._introItems[stepId];
|
1803 |
+
|
1804 |
+
// call the callback function (if any)
|
1805 |
+
if (typeof (this._hintClickCallback) !== 'undefined') {
|
1806 |
+
this._hintClickCallback.call(this, hintElement, item, stepId);
|
1807 |
+
}
|
1808 |
+
|
1809 |
+
// remove all open tooltips
|
1810 |
+
var removedStep = _removeHintTooltip.call(this);
|
1811 |
+
|
1812 |
+
// to toggle the tooltip
|
1813 |
+
if (parseInt(removedStep, 10) == stepId) {
|
1814 |
+
return;
|
1815 |
+
}
|
1816 |
+
|
1817 |
+
var tooltipLayer = document.createElement('div');
|
1818 |
+
var tooltipTextLayer = document.createElement('div');
|
1819 |
+
var arrowLayer = document.createElement('div');
|
1820 |
+
var referenceLayer = document.createElement('div');
|
1821 |
+
|
1822 |
+
tooltipLayer.className = 'introjs-tooltip';
|
1823 |
+
|
1824 |
+
tooltipLayer.onclick = function (e) {
|
1825 |
+
//IE9 & Other Browsers
|
1826 |
+
if (e.stopPropagation) {
|
1827 |
+
e.stopPropagation();
|
1828 |
+
}
|
1829 |
+
//IE8 and Lower
|
1830 |
+
else {
|
1831 |
+
e.cancelBubble = true;
|
1832 |
+
}
|
1833 |
+
};
|
1834 |
+
|
1835 |
+
tooltipTextLayer.className = 'introjs-tooltiptext';
|
1836 |
+
|
1837 |
+
var tooltipWrapper = document.createElement('p');
|
1838 |
+
tooltipWrapper.innerHTML = item.hint;
|
1839 |
+
|
1840 |
+
var closeButton = document.createElement('a');
|
1841 |
+
closeButton.className = 'introjs-button';
|
1842 |
+
closeButton.innerHTML = this._options.hintButtonLabel;
|
1843 |
+
closeButton.onclick = _hideHint.bind(this, stepId);
|
1844 |
+
|
1845 |
+
tooltipTextLayer.appendChild(tooltipWrapper);
|
1846 |
+
tooltipTextLayer.appendChild(closeButton);
|
1847 |
+
|
1848 |
+
arrowLayer.className = 'introjs-arrow';
|
1849 |
+
tooltipLayer.appendChild(arrowLayer);
|
1850 |
+
|
1851 |
+
tooltipLayer.appendChild(tooltipTextLayer);
|
1852 |
+
|
1853 |
+
// set current step for _placeTooltip function
|
1854 |
+
this._currentStep = hintElement.getAttribute('data-step');
|
1855 |
+
|
1856 |
+
// align reference layer position
|
1857 |
+
referenceLayer.className = 'introjs-tooltipReferenceLayer introjs-hintReference';
|
1858 |
+
referenceLayer.setAttribute('data-step', hintElement.getAttribute('data-step'));
|
1859 |
+
_setHelperLayerPosition.call(this, referenceLayer);
|
1860 |
+
|
1861 |
+
referenceLayer.appendChild(tooltipLayer);
|
1862 |
+
document.body.appendChild(referenceLayer);
|
1863 |
+
|
1864 |
+
//set proper position
|
1865 |
+
_placeTooltip.call(this, hintElement, tooltipLayer, arrowLayer, null, true);
|
1866 |
+
}
|
1867 |
+
|
1868 |
+
/**
|
1869 |
+
* Get an element position on the page
|
1870 |
+
* Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
|
1871 |
+
*
|
1872 |
+
* @api private
|
1873 |
+
* @method _getOffset
|
1874 |
+
* @param {Object} element
|
1875 |
+
* @returns Element's position info
|
1876 |
+
*/
|
1877 |
+
function _getOffset(element) {
|
1878 |
+
var elementPosition = {};
|
1879 |
+
|
1880 |
+
var body = document.body;
|
1881 |
+
var docEl = document.documentElement;
|
1882 |
+
|
1883 |
+
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
|
1884 |
+
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
|
1885 |
+
|
1886 |
+
if (element instanceof SVGElement) {
|
1887 |
+
var x = element.getBoundingClientRect()
|
1888 |
+
elementPosition.top = x.top + scrollTop;
|
1889 |
+
elementPosition.width = x.width;
|
1890 |
+
elementPosition.height = x.height;
|
1891 |
+
elementPosition.left = x.left + scrollLeft;
|
1892 |
+
} else {
|
1893 |
+
//set width
|
1894 |
+
elementPosition.width = element.offsetWidth;
|
1895 |
+
|
1896 |
+
//set height
|
1897 |
+
elementPosition.height = element.offsetHeight;
|
1898 |
+
|
1899 |
+
//calculate element top and left
|
1900 |
+
var _x = 0;
|
1901 |
+
var _y = 0;
|
1902 |
+
while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
|
1903 |
+
_x += element.offsetLeft;
|
1904 |
+
_y += element.offsetTop;
|
1905 |
+
element = element.offsetParent;
|
1906 |
+
}
|
1907 |
+
//set top
|
1908 |
+
elementPosition.top = _y;
|
1909 |
+
//set left
|
1910 |
+
elementPosition.left = _x;
|
1911 |
+
}
|
1912 |
+
|
1913 |
+
return elementPosition;
|
1914 |
+
}
|
1915 |
+
|
1916 |
+
/**
|
1917 |
+
* Gets the current progress percentage
|
1918 |
+
*
|
1919 |
+
* @api private
|
1920 |
+
* @method _getProgress
|
1921 |
+
* @returns current progress percentage
|
1922 |
+
*/
|
1923 |
+
function _getProgress() {
|
1924 |
+
// Steps are 0 indexed
|
1925 |
+
var currentStep = parseInt((this._currentStep + 1), 10);
|
1926 |
+
return ((currentStep / this._introItems.length) * 100);
|
1927 |
+
}
|
1928 |
+
|
1929 |
+
/**
|
1930 |
+
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
|
1931 |
+
* via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
|
1932 |
+
*
|
1933 |
+
* @param obj1
|
1934 |
+
* @param obj2
|
1935 |
+
* @returns obj3 a new object based on obj1 and obj2
|
1936 |
+
*/
|
1937 |
+
function _mergeOptions(obj1,obj2) {
|
1938 |
+
var obj3 = {};
|
1939 |
+
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
|
1940 |
+
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
|
1941 |
+
return obj3;
|
1942 |
+
}
|
1943 |
+
|
1944 |
+
var introJs = function (targetElm) {
|
1945 |
+
if (typeof (targetElm) === 'object') {
|
1946 |
+
//Ok, create a new instance
|
1947 |
+
return new IntroJs(targetElm);
|
1948 |
+
|
1949 |
+
} else if (typeof (targetElm) === 'string') {
|
1950 |
+
//select the target element with query selector
|
1951 |
+
var targetElement = document.querySelector(targetElm);
|
1952 |
+
|
1953 |
+
if (targetElement) {
|
1954 |
+
return new IntroJs(targetElement);
|
1955 |
+
} else {
|
1956 |
+
throw new Error('There is no element with given selector.');
|
1957 |
+
}
|
1958 |
+
} else {
|
1959 |
+
return new IntroJs(document.body);
|
1960 |
+
}
|
1961 |
+
};
|
1962 |
+
|
1963 |
+
/**
|
1964 |
+
* Current IntroJs version
|
1965 |
+
*
|
1966 |
+
* @property version
|
1967 |
+
* @type String
|
1968 |
+
*/
|
1969 |
+
introJs.version = VERSION;
|
1970 |
+
|
1971 |
+
//Prototype
|
1972 |
+
introJs.fn = IntroJs.prototype = {
|
1973 |
+
clone: function () {
|
1974 |
+
return new IntroJs(this);
|
1975 |
+
},
|
1976 |
+
setOption: function(option, value) {
|
1977 |
+
this._options[option] = value;
|
1978 |
+
return this;
|
1979 |
+
},
|
1980 |
+
setOptions: function(options) {
|
1981 |
+
this._options = _mergeOptions(this._options, options);
|
1982 |
+
return this;
|
1983 |
+
},
|
1984 |
+
start: function () {
|
1985 |
+
_introForElement.call(this, this._targetElement);
|
1986 |
+
return this;
|
1987 |
+
},
|
1988 |
+
goToStep: function(step) {
|
1989 |
+
_goToStep.call(this, step);
|
1990 |
+
return this;
|
1991 |
+
},
|
1992 |
+
addStep: function(options) {
|
1993 |
+
if (!this._options.steps) {
|
1994 |
+
this._options.steps = [];
|
1995 |
+
}
|
1996 |
+
|
1997 |
+
this._options.steps.push(options);
|
1998 |
+
|
1999 |
+
return this;
|
2000 |
+
},
|
2001 |
+
addSteps: function(steps) {
|
2002 |
+
if (!steps.length) return;
|
2003 |
+
|
2004 |
+
for(var index = 0; index < steps.length; index++) {
|
2005 |
+
this.addStep(steps[index]);
|
2006 |
+
}
|
2007 |
+
|
2008 |
+
return this;
|
2009 |
+
},
|
2010 |
+
goToStepNumber: function(step) {
|
2011 |
+
_goToStepNumber.call(this, step);
|
2012 |
+
|
2013 |
+
return this;
|
2014 |
+
},
|
2015 |
+
nextStep: function() {
|
2016 |
+
_nextStep.call(this);
|
2017 |
+
return this;
|
2018 |
+
},
|
2019 |
+
previousStep: function() {
|
2020 |
+
_previousStep.call(this);
|
2021 |
+
return this;
|
2022 |
+
},
|
2023 |
+
exit: function(force) {
|
2024 |
+
_exitIntro.call(this, this._targetElement, force);
|
2025 |
+
return this;
|
2026 |
+
},
|
2027 |
+
refresh: function() {
|
2028 |
+
_refresh.call(this);
|
2029 |
+
return this;
|
2030 |
+
},
|
2031 |
+
onbeforechange: function(providedCallback) {
|
2032 |
+
if (typeof (providedCallback) === 'function') {
|
2033 |
+
this._introBeforeChangeCallback = providedCallback;
|
2034 |
+
} else {
|
2035 |
+
throw new Error('Provided callback for onbeforechange was not a function');
|
2036 |
+
}
|
2037 |
+
return this;
|
2038 |
+
},
|
2039 |
+
onchange: function(providedCallback) {
|
2040 |
+
if (typeof (providedCallback) === 'function') {
|
2041 |
+
this._introChangeCallback = providedCallback;
|
2042 |
+
} else {
|
2043 |
+
throw new Error('Provided callback for onchange was not a function.');
|
2044 |
+
}
|
2045 |
+
return this;
|
2046 |
+
},
|
2047 |
+
onafterchange: function(providedCallback) {
|
2048 |
+
if (typeof (providedCallback) === 'function') {
|
2049 |
+
this._introAfterChangeCallback = providedCallback;
|
2050 |
+
} else {
|
2051 |
+
throw new Error('Provided callback for onafterchange was not a function');
|
2052 |
+
}
|
2053 |
+
return this;
|
2054 |
+
},
|
2055 |
+
oncomplete: function(providedCallback) {
|
2056 |
+
if (typeof (providedCallback) === 'function') {
|
2057 |
+
this._introCompleteCallback = providedCallback;
|
2058 |
+
} else {
|
2059 |
+
throw new Error('Provided callback for oncomplete was not a function.');
|
2060 |
+
}
|
2061 |
+
return this;
|
2062 |
+
},
|
2063 |
+
onhintsadded: function(providedCallback) {
|
2064 |
+
if (typeof (providedCallback) === 'function') {
|
2065 |
+
this._hintsAddedCallback = providedCallback;
|
2066 |
+
} else {
|
2067 |
+
throw new Error('Provided callback for onhintsadded was not a function.');
|
2068 |
+
}
|
2069 |
+
return this;
|
2070 |
+
},
|
2071 |
+
onhintclick: function(providedCallback) {
|
2072 |
+
if (typeof (providedCallback) === 'function') {
|
2073 |
+
this._hintClickCallback = providedCallback;
|
2074 |
+
} else {
|
2075 |
+
throw new Error('Provided callback for onhintclick was not a function.');
|
2076 |
+
}
|
2077 |
+
return this;
|
2078 |
+
},
|
2079 |
+
onhintclose: function(providedCallback) {
|
2080 |
+
if (typeof (providedCallback) === 'function') {
|
2081 |
+
this._hintCloseCallback = providedCallback;
|
2082 |
+
} else {
|
2083 |
+
throw new Error('Provided callback for onhintclose was not a function.');
|
2084 |
+
}
|
2085 |
+
return this;
|
2086 |
+
},
|
2087 |
+
onexit: function(providedCallback) {
|
2088 |
+
if (typeof (providedCallback) === 'function') {
|
2089 |
+
this._introExitCallback = providedCallback;
|
2090 |
+
} else {
|
2091 |
+
throw new Error('Provided callback for onexit was not a function.');
|
2092 |
+
}
|
2093 |
+
return this;
|
2094 |
+
},
|
2095 |
+
onbeforeexit: function(providedCallback) {
|
2096 |
+
if (typeof (providedCallback) === 'function') {
|
2097 |
+
this._introBeforeExitCallback = providedCallback;
|
2098 |
+
} else {
|
2099 |
+
throw new Error('Provided callback for onbeforeexit was not a function.');
|
2100 |
+
}
|
2101 |
+
return this;
|
2102 |
+
},
|
2103 |
+
addHints: function() {
|
2104 |
+
_populateHints.call(this, this._targetElement);
|
2105 |
+
return this;
|
2106 |
+
},
|
2107 |
+
hideHint: function (stepId) {
|
2108 |
+
_hideHint.call(this, stepId);
|
2109 |
+
return this;
|
2110 |
+
},
|
2111 |
+
hideHints: function () {
|
2112 |
+
_hideHints.call(this);
|
2113 |
+
return this;
|
2114 |
+
},
|
2115 |
+
showHint: function (stepId) {
|
2116 |
+
_showHint.call(this, stepId);
|
2117 |
+
return this;
|
2118 |
+
},
|
2119 |
+
showHints: function () {
|
2120 |
+
_showHints.call(this);
|
2121 |
+
return this;
|
2122 |
+
},
|
2123 |
+
removeHints: function () {
|
2124 |
+
_removeHints.call(this);
|
2125 |
+
return this;
|
2126 |
+
},
|
2127 |
+
removeHint: function (stepId) {
|
2128 |
+
_removeHint.call(this, stepId);
|
2129 |
+
return this;
|
2130 |
+
},
|
2131 |
+
showHintDialog: function (stepId) {
|
2132 |
+
_showHintDialog.call(this, stepId);
|
2133 |
+
return this;
|
2134 |
+
}
|
2135 |
+
};
|
2136 |
+
|
2137 |
+
exports.introJs = introJs;
|
2138 |
+
return introJs;
|
2139 |
+
}));
|
@@ -4,7 +4,7 @@ Buy plugin: https://buttonizer.pro
|
|
4 |
Tags: floating menu, action button, call button, floating action button, Social Sharing button
|
5 |
Requires at least: 4.2
|
6 |
Tested up to: 4.8.1
|
7 |
-
Stable tag: 1.0.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -116,6 +116,26 @@ And the beauty of all: All actions are hidden in one button. The moment a visito
|
|
116 |
In fact the Buttonizer is an addiction to use. You're website visitors will interact as never before.
|
117 |
|
118 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
= 1.0.8 =
|
120 |
There are multiple changes inside Buttonizer. Like the settings page is better organised now and re-styled.
|
121 |
|
4 |
Tags: floating menu, action button, call button, floating action button, Social Sharing button
|
5 |
Requires at least: 4.2
|
6 |
Tested up to: 4.8.1
|
7 |
+
Stable tag: 1.0.9
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
116 |
In fact the Buttonizer is an addiction to use. You're website visitors will interact as never before.
|
117 |
|
118 |
== Changelog ==
|
119 |
+
= 1.0.9 =
|
120 |
+
A new cool update! We added for our new users a tour (of course, if you are already using Buttonizer, feel free to take the tour!). If someone has some feedback, about the tour, contact us through the plugin! :)
|
121 |
+
|
122 |
+
We've added something magical! For each button it's now possible to use one of the following actions:
|
123 |
+
- Website URL: For opening a webpage
|
124 |
+
- Phone number: Direct action
|
125 |
+
- E-mail: Opens the desktop client from the user with your mail address filled in already
|
126 |
+
|
127 |
+
New this release:
|
128 |
+
- Information tour for our new users
|
129 |
+
- Button actions easier
|
130 |
+
|
131 |
+
Changed:
|
132 |
+
- Re-ordered the settings page a bit
|
133 |
+
|
134 |
+
Fixed:
|
135 |
+
- When enabling 'show on hover' with only one button, the label won't be visible anymore
|
136 |
+
- Some caching plugins liked to cache our javascript, we've added a fix to that
|
137 |
+
- Other bugs
|
138 |
+
|
139 |
= 1.0.8 =
|
140 |
There are multiple changes inside Buttonizer. Like the settings page is better organised now and re-styled.
|
141 |
|