rtMedia for WordPress, BuddyPress and bbPress - Version 3.7.32

Version Description

  • Update all translation files
  • Update templates
  • Fix media title issue
  • Fix warnings
Download this release

Release Info

Developer rtcamp
Plugin Icon 128x128 rtMedia for WordPress, BuddyPress and bbPress
Version 3.7.32
Comparing to
See all releases

Code changes from version 3.7.31 to 3.7.32

Files changed (41) hide show
  1. app/admin/RTMediaAdmin.php +9 -9
  2. app/admin/RTMediaFormHandler.php +9 -9
  3. app/assets/css/vendor/bootstrap-switch.css +184 -0
  4. app/assets/css/vendor/grid-foundation.css +222 -0
  5. app/assets/css/vendor/jquery.powertip.min.css +1 -0
  6. app/assets/css/vendor/jquery.sliderTabs.min.css +1 -0
  7. app/assets/js/admin.js +23 -14
  8. app/assets/js/vendor/bootstrap-switch.js +255 -0
  9. app/assets/js/vendor/jquery.observehashchange.pack.js +87 -0
  10. app/assets/js/vendor/jquery.powertip.min.js +1166 -0
  11. app/assets/js/vendor/jquery.sliderTabs.min.js +831 -0
  12. app/helper/RTMediaAddon.php +3 -3
  13. app/main/RTMedia.php +9 -7
  14. app/main/controllers/template/RTMediaTemplate.php +3 -3
  15. app/main/controllers/template/rt-template-functions.php +6 -4
  16. app/main/interactions/RTMediaInteraction.php +2 -2
  17. app/schema/rtm_api.schema +2 -1
  18. app/services/RTMediaEncoding.php +1 -1
  19. index.php +1 -1
  20. languages/rtmedia-ar_AR.mo +0 -0
  21. languages/rtmedia-de_DE.mo +0 -0
  22. languages/rtmedia-es_ES.mo +0 -0
  23. languages/rtmedia-fa_IR.mo +0 -0
  24. languages/rtmedia-fr_FR.mo +0 -0
  25. languages/rtmedia-hu_HU.mo +0 -0
  26. languages/rtmedia-it_IT.mo +0 -0
  27. languages/rtmedia-ja_JA.mo +0 -0
  28. languages/rtmedia-nb_NO.mo +0 -0
  29. languages/rtmedia-nl_NL.mo +0 -0
  30. languages/rtmedia-pl_PL.mo +0 -0
  31. languages/rtmedia-pt_BR.mo +0 -0
  32. languages/rtmedia-ro_RO.mo +0 -0
  33. languages/rtmedia-ru_RU.mo +0 -0
  34. languages/rtmedia-sk_SK.mo +0 -0
  35. languages/rtmedia-sr_SR.mo +0 -0
  36. languages/rtmedia-sv_SE.mo +0 -0
  37. languages/rtmedia.mo +0 -0
  38. languages/rtmedia.po +303 -296
  39. readme.txt +13 -7
  40. templates/main.php +92 -94
  41. templates/media/media-gallery.php +2 -0
app/admin/RTMediaAdmin.php CHANGED
@@ -676,9 +676,9 @@ if ( ! class_exists( 'RTMediaAdmin' ) ){
676
677
$admin_ajax = admin_url( 'admin-ajax.php' );
678
679
- wp_enqueue_script( 'bootstrap-switch', RTMEDIA_URL . 'app/assets/js/bootstrap-switch.js', array( 'jquery' ), RTMEDIA_VERSION );
680
- wp_enqueue_script( 'slider-tabs', RTMEDIA_URL . 'app/assets/js/jquery.sliderTabs.min.js', array( 'jquery', 'jquery-effects-core' ), RTMEDIA_VERSION );
681
- wp_enqueue_script( 'observe-hashchange', RTMEDIA_URL . 'app/assets/js/jquery.observehashchange.pack.js', array( 'jquery' ), RTMEDIA_VERSION );
682
wp_enqueue_script( 'rtmedia-admin', RTMEDIA_URL . 'app/assets/js/admin.js', array( 'jquery-ui-dialog' ), RTMEDIA_VERSION );
683
wp_localize_script( 'rtmedia-admin', 'rtmedia_on_label', __( 'ON', 'rtmedia' ) );
684
wp_localize_script( 'rtmedia-admin', 'rtmedia_off_label', __( 'OFF', 'rtmedia' ) );
@@ -700,9 +700,9 @@ if ( ! class_exists( 'RTMediaAdmin' ) ){
700
wp_localize_script( 'rtmedia-admin', 'settings_url', add_query_arg( array( 'page' => 'rtmedia-settings' ), ( is_multisite() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' ) ) ) . '#privacy_enabled' );
701
wp_localize_script( 'rtmedia-admin', 'settings_rt_album_import_url', add_query_arg( array( 'page' => 'rtmedia-settings' ), ( is_multisite() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' ) ) ) );
702
wp_enqueue_style( 'font-awesome', RTMEDIA_URL . 'app/assets/css/font-awesome.min.css', '', RTMEDIA_VERSION );
703
- wp_enqueue_style( 'bootstrap-switch', RTMEDIA_URL . 'app/assets/css/bootstrap-switch.css', '', RTMEDIA_VERSION );
704
- wp_enqueue_style( 'slider-tabs', RTMEDIA_URL . 'app/assets/css/jquery.sliderTabs.min.css', '', RTMEDIA_VERSION );
705
- wp_enqueue_style( 'grid-foundation', RTMEDIA_URL . 'app/assets/css/grid-foundation.css', '', RTMEDIA_VERSION );
706
wp_enqueue_style( 'rtmedia-main', RTMEDIA_URL . 'app/assets/css/main.css', '', RTMEDIA_VERSION );
707
wp_enqueue_style( 'rtmedia-admin', RTMEDIA_URL . 'app/assets/css/admin.css', '', RTMEDIA_VERSION );
708
@@ -1832,10 +1832,10 @@ if ( ! class_exists( 'RTMediaAdmin' ) ){
1832
}
1833
1834
function rtmedia_update_template_notice(){
1835
- $site_option = rtmedia_get_site_option( 'rtmedia-update-template-notice-v3_7_26' );
1836
1837
if ( ! $site_option || 'hide' != $site_option ){
1838
- rtmedia_update_site_option( 'rtmedia-update-template-notice-v3_7_26', 'show' );
1839
if ( is_dir( get_template_directory() . '/rtmedia' ) ){
1840
echo '<div class="error rtmedia-update-template-notice"><p>' . __( 'Please update rtMedia template files if you have overridden the default rtMedia templates in your theme. If not, you can ignore and hide this notice.' ) . '<a href="#" onclick="rtmedia_hide_template_override_notice()" style="float:right">' . __( 'Hide', 'rtmedia' ) . '</a>' . ' </p></div>';
1841
?>
@@ -1856,7 +1856,7 @@ if ( ! class_exists( 'RTMediaAdmin' ) ){
1856
1857
function rtmedia_hide_template_override_notice(){
1858
1859
- if ( rtmedia_update_site_option( 'rtmedia-update-template-notice-v3_7_26', 'hide' ) ){
1860
echo '1';
1861
} else {
1862
echo '0';
676
677
$admin_ajax = admin_url( 'admin-ajax.php' );
678
679
+ wp_enqueue_script( 'bootstrap-switch', RTMEDIA_URL . 'app/assets/js/vendor/bootstrap-switch.js', array( 'jquery' ), RTMEDIA_VERSION );
680
+ wp_enqueue_script( 'slider-tabs', RTMEDIA_URL . 'app/assets/js/vendor/jquery.sliderTabs.min.js', array( 'jquery', 'jquery-effects-core' ), RTMEDIA_VERSION );
681
+ wp_enqueue_script( 'observe-hashchange', RTMEDIA_URL . 'app/assets/js/vendor/jquery.observehashchange.pack.js', array( 'jquery' ), RTMEDIA_VERSION );
682
wp_enqueue_script( 'rtmedia-admin', RTMEDIA_URL . 'app/assets/js/admin.js', array( 'jquery-ui-dialog' ), RTMEDIA_VERSION );
683
wp_localize_script( 'rtmedia-admin', 'rtmedia_on_label', __( 'ON', 'rtmedia' ) );
684
wp_localize_script( 'rtmedia-admin', 'rtmedia_off_label', __( 'OFF', 'rtmedia' ) );
700
wp_localize_script( 'rtmedia-admin', 'settings_url', add_query_arg( array( 'page' => 'rtmedia-settings' ), ( is_multisite() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' ) ) ) . '#privacy_enabled' );
701
wp_localize_script( 'rtmedia-admin', 'settings_rt_album_import_url', add_query_arg( array( 'page' => 'rtmedia-settings' ), ( is_multisite() ? network_admin_url( 'admin.php' ) : admin_url( 'admin.php' ) ) ) );
702
wp_enqueue_style( 'font-awesome', RTMEDIA_URL . 'app/assets/css/font-awesome.min.css', '', RTMEDIA_VERSION );
703
+ wp_enqueue_style( 'bootstrap-switch', RTMEDIA_URL . 'app/assets/css/vendor/bootstrap-switch.css', '', RTMEDIA_VERSION );
704
+ wp_enqueue_style( 'slider-tabs', RTMEDIA_URL . 'app/assets/css/vendor/jquery.sliderTabs.min.css', '', RTMEDIA_VERSION );
705
+ wp_enqueue_style( 'grid-foundation', RTMEDIA_URL . 'app/assets/css/vendor/grid-foundation.css', '', RTMEDIA_VERSION );
706
wp_enqueue_style( 'rtmedia-main', RTMEDIA_URL . 'app/assets/css/main.css', '', RTMEDIA_VERSION );
707
wp_enqueue_style( 'rtmedia-admin', RTMEDIA_URL . 'app/assets/css/admin.css', '', RTMEDIA_VERSION );
708
1832
}
1833
1834
function rtmedia_update_template_notice(){
1835
+ $site_option = rtmedia_get_site_option( 'rtmedia-update-template-notice-v3_7_32' );
1836
1837
if ( ! $site_option || 'hide' != $site_option ){
1838
+ rtmedia_update_site_option( 'rtmedia-update-template-notice-v3_7_32', 'show' );
1839
if ( is_dir( get_template_directory() . '/rtmedia' ) ){
1840
echo '<div class="error rtmedia-update-template-notice"><p>' . __( 'Please update rtMedia template files if you have overridden the default rtMedia templates in your theme. If not, you can ignore and hide this notice.' ) . '<a href="#" onclick="rtmedia_hide_template_override_notice()" style="float:right">' . __( 'Hide', 'rtmedia' ) . '</a>' . ' </p></div>';
1841
?>
1856
1857
function rtmedia_hide_template_override_notice(){
1858
1859
+ if ( rtmedia_update_site_option( 'rtmedia-update-template-notice-v3_7_32', 'hide' ) ){
1860
echo '1';
1861
} else {
1862
echo '0';
app/admin/RTMediaFormHandler.php CHANGED
@@ -640,16 +640,16 @@ class RTMediaFormHandler {
640
<?php do_action( 'rtmedia_media_type_setting_message' ); ?>
641
</h3>
642
</div>
643
- <div class="rt-table large-12">
644
<div class="row rt-header">
645
<?php do_action( 'rtmedia_type_settings_before_heading' ); ?>
646
- <div class="columns large-4"><h4><?php _e( 'Media Type', 'rtmedia' ) ?></h4></div>
647
- <div class="columns large-4">
648
<h4 data-tooltip class="has-tip" title="<?php _e( 'Allows you to upload a particular media type on your post.', 'rtmedia' ); ?>">
649
<abbr><?php _e( 'Allow Upload', 'rtmedia' ); ?></abbr>
650
</h4>
651
</div>
652
- <div class="columns large-4">
653
<h4 data-tooltip class="has-tip" title="<?php _e( 'Place a specific media as a featured content on the post.', 'rtmedia' ); ?>">
654
<abbr><?php _e( 'Set Featured', 'rtmedia' ); ?></abbr>
655
</h4>
@@ -670,15 +670,15 @@ class RTMediaFormHandler {
670
}
671
672
do_action( 'rtmedia_type_settings_before_body' );
673
- echo '<div class="columns large-4">' . $section['name'] . '</div>';
674
$args = array( 'key' => 'allowedTypes_' . $key . '_enabled', 'value' => $section['enabled'] );
675
- echo '<div class="columns large-4">';
676
$allow_upload_checkbox = self::checkbox( $args, $echo = false );
677
$allow_upload_checkbox = apply_filters( 'rtmedia_filter_allow_upload_checkbox', $allow_upload_checkbox, $key, $args );
678
echo $allow_upload_checkbox;
679
echo '</div>';
680
$args = array( 'key' => 'allowedTypes_' . $key . '_featured', 'value' => $section['featured'] );
681
- echo '<div class="columns large-4">';
682
$featured_checkbox = self::checkbox( $args, $echo = false );
683
$featured_checkbox = apply_filters( 'rtmedia_filter_featured_checkbox', $featured_checkbox, $key );
684
echo $featured_checkbox;
@@ -693,8 +693,8 @@ class RTMediaFormHandler {
693
do_action( 'rtmedia_type_settings_after_body', $key, $section );
694
echo '</div>';
695
echo '<div class="row rtmedia-file-extension-wrap">';
696
- echo '<label class="columns large-3">' . __( 'File Extensions', 'rtmedia' ) . ':</label>';
697
- echo '<label class="columns large-9 rtmedia_type_settings_filter_extension">' . $extensions . '</label>';
698
echo '</div>';
699
700
} else {
640
<?php do_action( 'rtmedia_media_type_setting_message' ); ?>
641
</h3>
642
</div>
643
+ <div class="rt-table large-12 medium-12 small-12">
644
<div class="row rt-header">
645
<?php do_action( 'rtmedia_type_settings_before_heading' ); ?>
646
+ <div class="columns large-4 medium-4 small-4"><h4><?php _e( 'Media Type', 'rtmedia' ) ?></h4></div>
647
+ <div class="columns large-4 medium-4 small-4">
648
<h4 data-tooltip class="has-tip" title="<?php _e( 'Allows you to upload a particular media type on your post.', 'rtmedia' ); ?>">
649
<abbr><?php _e( 'Allow Upload', 'rtmedia' ); ?></abbr>
650
</h4>
651
</div>
652
+ <div class="columns large-4 medium-4 small-4">
653
<h4 data-tooltip class="has-tip" title="<?php _e( 'Place a specific media as a featured content on the post.', 'rtmedia' ); ?>">
654
<abbr><?php _e( 'Set Featured', 'rtmedia' ); ?></abbr>
655
</h4>
670
}
671
672
do_action( 'rtmedia_type_settings_before_body' );
673
+ echo '<div class="columns large-4 medium-4 small-4">' . $section['name'] . '</div>';
674
$args = array( 'key' => 'allowedTypes_' . $key . '_enabled', 'value' => $section['enabled'] );
675
+ echo '<div class="columns large-4 medium-4 small-4">';
676
$allow_upload_checkbox = self::checkbox( $args, $echo = false );
677
$allow_upload_checkbox = apply_filters( 'rtmedia_filter_allow_upload_checkbox', $allow_upload_checkbox, $key, $args );
678
echo $allow_upload_checkbox;
679
echo '</div>';
680
$args = array( 'key' => 'allowedTypes_' . $key . '_featured', 'value' => $section['featured'] );
681
+ echo '<div class="columns large-4 medium-4 small-4">';
682
$featured_checkbox = self::checkbox( $args, $echo = false );
683
$featured_checkbox = apply_filters( 'rtmedia_filter_featured_checkbox', $featured_checkbox, $key );
684
echo $featured_checkbox;
693
do_action( 'rtmedia_type_settings_after_body', $key, $section );
694
echo '</div>';
695
echo '<div class="row rtmedia-file-extension-wrap">';
696
+ echo '<label class="columns large-3 medium-3 small-3">' . __( 'File Extensions', 'rtmedia' ) . ':</label>';
697
+ echo '<label class="columns large-9 medium-9 small-9 rtmedia_type_settings_filter_extension">' . $extensions . '</label>';
698
echo '</div>';
699
700
} else {
app/assets/css/vendor/bootstrap-switch.css ADDED
@@ -0,0 +1,184 @@
1
+ /* line 9, ../sass/bootstrap-switch.scss */
2
+ .fui-cross,
3
+ .fui-check {
4
+ display: inline-block;
5
+ speak: none;
6
+ font-style: normal;
7
+ font-weight: normal;
8
+ font-variant: normal;
9
+ text-transform: none;
10
+ -webkit-font-smoothing: antialiased;
11
+ }
12
+
13
+ /* line 18, ../sass/bootstrap-switch.scss */
14
+ .fui-cross:before {
15
+ content: "\2716";
16
+ }
17
+
18
+ /* line 21, ../sass/bootstrap-switch.scss */
19
+ .fui-check:before {
20
+ content: "\2714";
21
+ }
22
+
23
+ /* Switch checkbox */
24
+ /* line 44, ../sass/bootstrap-switch.scss */
25
+ .has-switch {
26
+ border-radius: 30px;
27
+ display: inline-block;
28
+ cursor: pointer;
29
+ line-height: 1.231;
30
+ overflow: hidden;
31
+ position: relative;
32
+ text-align: left;
33
+ width: 55px;
34
+ height: 20px;
35
+ -webkit-mask: url("../../img/mask.png") 0 0 no-repeat;
36
+ mask: url("../../img/mask.png") 0 0 no-repeat;
37
+ -webkit-user-select: none;
38
+ -moz-user-select: none;
39
+ user-select: none;
40
+ }
41
+ /* line 58, ../sass/bootstrap-switch.scss */
42
+ .has-switch.deactivate {
43
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=5000);
44
+ opacity: 50;
45
+ cursor: default !important;
46
+ }
47
+ /* line 61, ../sass/bootstrap-switch.scss */
48
+ .has-switch.deactivate label, .has-switch.deactivate span {
49
+ cursor: default !important;
50
+ }
51
+ /* line 66, ../sass/bootstrap-switch.scss */
52
+ .has-switch > div {
53
+ width: 162%;
54
+ position: relative;
55
+ top: 0;
56
+ }
57
+ /* line 71, ../sass/bootstrap-switch.scss */
58
+ .has-switch > div.switch-animate {
59
+ -webkit-transition: left 0.25s ease-out;
60
+ -moz-transition: left 0.25s ease-out;
61
+ -o-transition: left 0.25s ease-out;
62
+ transition: left 0.25s ease-out;
63
+ }
64
+ /* line 75, ../sass/bootstrap-switch.scss */
65
+ .has-switch > div.switch-off {
66
+ left: -63%;
67
+ }
68
+ /* line 78, ../sass/bootstrap-switch.scss */
69
+ .has-switch > div.switch-off label {
70
+ background-color: #2a95c5;
71
+ border-color: #bdc3c7;
72
+ -webkit-box-shadow: -1px 0 0 rgba(255, 255, 255, 0.5);
73
+ -moz-box-shadow: -1px 0 0 rgba(255, 255, 255, 0.5);
74
+ box-shadow: -1px 0 0 rgba(255, 255, 255, 0.5);
75
+ }
76
+ /* line 85, ../sass/bootstrap-switch.scss */
77
+ .has-switch > div.switch-on {
78
+ left: 0%;
79
+ }
80
+ /* line 88, ../sass/bootstrap-switch.scss */
81
+ .has-switch > div.switch-on label {
82
+ background-color: #bdc3c7;
83
+ }
84
+ /* line 94, ../sass/bootstrap-switch.scss */
85
+ .has-switch input[type=checkbox] {
86
+ display: none;
87
+ }
88
+ /* line 98, ../sass/bootstrap-switch.scss */
89
+ .has-switch span {
90
+ cursor: pointer;
91
+ font-size: 10.71px;
92
+ font-weight: 700;
93
+ float: left;
94
+ height: 20px;
95
+ line-height: 19px;
96
+ margin: 0;
97
+ padding-top: 1px;
98
+ position: relative;
99
+ text-align: center;
100
+ width: 50%;
101
+ z-index: 1;
102
+ -webkit-box-sizing: border-box;
103
+ -moz-box-sizing: border-box;
104
+ box-sizing: border-box;
105
+ -webkit-transition: 0.25s ease-out;
106
+ -moz-transition: 0.25s ease-out;
107
+ -o-transition: 0.25s ease-out;
108
+ transition: 0.25s ease-out;
109
+ }
110
+ /* line 114, ../sass/bootstrap-switch.scss */
111
+ .has-switch span.switch-left {
112
+ border-radius: 30px 0 0 30px;
113
+ background-color: #2a95c5;
114
+ color: white;
115
+ border-left: 1px solid transparent;
116
+ }
117
+ /* line 121, ../sass/bootstrap-switch.scss */
118
+ .has-switch span.switch-right {
119
+ border-radius: 0 30px 30px 0;
120
+ background-color: #bdc3c7;
121
+ color: white;
122
+ text-indent: 7px;
123
+ }
124
+ /* line 127, ../sass/bootstrap-switch.scss */
125
+ .has-switch span.switch-right [class*="fui-"] {
126
+ text-indent: 0;
127
+ }
128
+ /* line 133, ../sass/bootstrap-switch.scss */
129
+ .has-switch label {
130
+ border: 4px solid #2a95c5;
131
+ border-radius: 50%;
132
+ float: left;
133
+ height: 12px;
134
+ margin: 0 -12px 0 -10px;
135
+ padding: 0;
136
+ position: relative;
137
+ vertical-align: middle;
138
+ width: 12px;
139
+ z-index: 100;
140
+ -webkit-transition: 0.25s ease-out;
141
+ -moz-transition: 0.25s ease-out;
142
+ -o-transition: 0.25s ease-out;
143
+ transition: 0.25s ease-out;
144
+ }
145
+
146
+ /* line 150, ../sass/bootstrap-switch.scss */
147
+ .switch-square {
148
+ border-radius: 6px;
149
+ -webkit-mask: url("../../img/mask.png") 0 0 no-repeat;
150
+ mask: url("../../img/mask.png") 0 0 no-repeat;
151
+ }
152
+ /* line 157, ../sass/bootstrap-switch.scss */
153
+ .switch-square > div.switch-off label {
154
+ border-color: #2a95c5;
155
+ border-radius: 6px 0 0 6px;
156
+ }
157
+ /* line 164, ../sass/bootstrap-switch.scss */
158
+ .switch-square span {
159
+ -webkit-transition: 0.25s ease-out;
160
+ -moz-transition: 0.25s ease-out;
161
+ -o-transition: 0.25s ease-out;
162
+ transition: 0.25s ease-out;
163
+ }
164
+ /* line 168, ../sass/bootstrap-switch.scss */
165
+ .switch-square span.switch-left {
166
+ border-radius: 6px 0 0 6px;
167
+ }
168
+ /* line 170, ../sass/bootstrap-switch.scss */
169
+ .switch-square span.switch-left [class*="fui-"] {
170
+ text-indent: -10px;
171
+ }
172
+ /* line 175, ../sass/bootstrap-switch.scss */
173
+ .switch-square span.switch-right {
174
+ border-radius: 0 6px 6px 0;
175
+ }
176
+ /* line 177, ../sass/bootstrap-switch.scss */
177
+ .switch-square span.switch-right [class*="fui-"] {
178
+ text-indent: 5px;
179
+ }
180
+ /* line 183, ../sass/bootstrap-switch.scss */
181
+ .switch-square label {
182
+ border-radius: 0 6px 6px 0;
183
+ border-color: #bdc3c7;
184
+ }
app/assets/css/vendor/grid-foundation.css ADDED
@@ -0,0 +1,222 @@
1
+ /* Grid HTML Classes */
2
+ /* line 116, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
3
+ *, *:before, *:after {
4
+ -moz-box-sizing: border-box;
5
+ -webkit-box-sizing: border-box;
6
+ box-sizing: border-box;
7
+ }
8
+ .row {
9
+ width: 100%;
10
+ margin-left: auto;
11
+ margin-right: auto;
12
+ margin-top: 0;
13
+ margin-bottom: 0;
14
+ max-width: 62.5em;
15
+ *zoom: 1;
16
+ }
17
+ /* line 101, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_global.scss */
18
+ .row:before, .row:after {
19
+ content: " ";
20
+ display: table;
21
+ }
22
+ /* line 102, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_global.scss */
23
+ .row:after {
24
+ clear: both;
25
+ }
26
+ /* line 121, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
27
+ .row.collapse .column,
28
+ .row.collapse .columns {
29
+ position: relative;
30
+ padding-left: 0;
31
+ padding-right: 0;
32
+ float: left;
33
+ }
34
+
35
+ /* line 130, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
36
+ .column,
37
+ .columns {
38
+ position: relative;
39
+ padding-left: 0.9375em;
40
+ padding-right: 0.9375em;
41
+ width: 100%;
42
+ float: left;
43
+ }
44
+
45
+ @media only screen {
46
+ /* line 135, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
47
+ .column,
48
+ .columns {
49
+ position: relative;
50
+ padding-left: 0.9375em;
51
+ padding-right: 0.9375em;
52
+ float: left;
53
+ }
54
+
55
+ /* line 149, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
56
+ .column.small-centered,
57
+ .columns.small-centered {
58
+ position: relative;
59
+ margin-left: auto;
60
+ margin-right: auto;
61
+ float: none !important;
62
+ }
63
+ }
64
+ /* Styles for screens that are atleast 768px; */
65
+ @media only screen and (min-width: 48em) {
66
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
67
+ .large-1 {
68
+ position: relative;
69
+ width: 8.33333%;
70
+ }
71
+
72
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
73
+ .large-2 {
74
+ position: relative;
75
+ width: 16.66667%;
76
+ }
77
+
78
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
79
+ .large-3 {
80
+ position: relative;
81
+ width: 25%;
82
+ }
83
+
84
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
85
+ .large-4 {
86
+ position: relative;
87
+ width: 33.33333%;
88
+ }
89
+
90
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
91
+ .large-5 {
92
+ position: relative;
93
+ width: 41.66667%;
94
+ }
95
+
96
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
97
+ .large-6 {
98
+ position: relative;
99
+ width: 50%;
100
+ }
101
+
102
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
103
+ .large-7 {
104
+ position: relative;
105
+ width: 58.33333%;
106
+ }
107
+
108
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
109
+ .large-8 {
110
+ position: relative;
111
+ width: 66.66667%;
112
+ }
113
+
114
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
115
+ .large-9 {
116
+ position: relative;
117
+ width: 75%;
118
+ }
119
+
120
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
121
+ .large-10 {
122
+ position: relative;
123
+ width: 83.33333%;
124
+ }
125
+
126
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
127
+ .large-11 {
128
+ position: relative;
129
+ width: 91.66667%;
130
+ }
131
+
132
+ /* line 156, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
133
+ .large-12 {
134
+ position: relative;
135
+ width: 100%;
136
+ }
137
+
138
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
139
+ .row .large-offset-1 {
140
+ position: relative;
141
+ margin-left: 8.33333%;
142
+ }
143
+
144
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
145
+ .row .large-offset-2 {
146
+ position: relative;
147
+ margin-left: 16.66667%;
148
+ }
149
+
150
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
151
+ .row .large-offset-3 {
152
+ position: relative;
153
+ margin-left: 25%;
154
+ }
155
+
156
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
157
+ .row .large-offset-4 {
158
+ position: relative;
159
+ margin-left: 33.33333%;
160
+ }
161
+
162
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
163
+ .row .large-offset-5 {
164
+ position: relative;
165
+ margin-left: 41.66667%;
166
+ }
167
+
168
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
169
+ .row .large-offset-6 {
170
+ position: relative;
171
+ margin-left: 50%;
172
+ }
173
+
174
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
175
+ .row .large-offset-7 {
176
+ position: relative;
177
+ margin-left: 58.33333%;
178
+ }
179
+
180
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
181
+ .row .large-offset-8 {
182
+ position: relative;
183
+ margin-left: 66.66667%;
184
+ }
185
+
186
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
187
+ .row .large-offset-9 {
188
+ position: relative;
189
+ margin-left: 75%;
190
+ }
191
+
192
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
193
+ .row .large-offset-10 {
194
+ position: relative;
195
+ margin-left: 83.33333%;
196
+ }
197
+
198
+ /* line 160, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
199
+ .row .large-offset-11 {
200
+ position: relative;
201
+ margin-left: 91.66667%;
202
+ }
203
+
204
+
205
+
206
+ /* line 174, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
207
+ .column.large-centered,
208
+ .columns.large-centered {
209
+ position: relative;
210
+ margin-left: auto;
211
+ margin-right: auto;
212
+ float: none !important;
213
+ }
214
+
215
+ /* line 177, ../../../../../../../usr/lib/ruby/gems/1.8/gems/zurb-foundation-4.1.6/scss/foundation/components/_grid.scss */
216
+ .column.large-uncentered,
217
+ .columns.large-uncentered {
218
+ margin-left: 0;
219
+ margin-right: 0;
220
+ float: none;
221
+ }
222
+ }
app/assets/css/vendor/jquery.powertip.min.css ADDED
@@ -0,0 +1 @@
1
+ #powerTip{cursor:default;background-color:#333;background-color:rgba(0,0,0,.8);border-radius:6px;color:#fff;display:none;padding:10px;position:absolute;white-space:nowrap;z-index:2147483647}#powerTip:before{content:"";position:absolute}#powerTip.n:before,#powerTip.s:before{border-right:5px solid transparent;border-left:5px solid transparent;left:50%;margin-left:-5px}#powerTip.e:before,#powerTip.w:before{border-bottom:5px solid transparent;border-top:5px solid transparent;margin-top:-5px;top:50%}#powerTip.n:before{border-top:10px solid #333;border-top:10px solid rgba(0,0,0,.8);bottom:-10px}#powerTip.e:before{border-right:10px solid #333;border-right:10px solid rgba(0,0,0,.8);left:-10px}#powerTip.s:before{border-bottom:10px solid #333;border-bottom:10px solid rgba(0,0,0,.8);top:-10px}#powerTip.w:before{border-left:10px solid #333;border-left:10px solid rgba(0,0,0,.8);right:-10px}#powerTip.ne:before,#powerTip.se:before{border-right:10px solid transparent;border-left:0;left:10px}#powerTip.nw:before,#powerTip.sw:before{border-left:10px solid transparent;border-right:0;right:10px}#powerTip.ne:before,#powerTip.nw:before{border-top:10px solid #333;border-top:10px solid rgba(0,0,0,.8);bottom:-10px}#powerTip.se:before,#powerTip.sw:before{border-bottom:10px solid #333;border-bottom:10px solid rgba(0,0,0,.8);top:-10px}#powerTip.nw-alt:before,#powerTip.ne-alt:before,#powerTip.sw-alt:before,#powerTip.se-alt:before{border-top:10px solid #333;border-top:10px solid rgba(0,0,0,.8);bottom:-10px;border-left:5px solid transparent;border-right:5px solid transparent;left:10px}#powerTip.ne-alt:before{left:auto;right:10px}#powerTip.sw-alt:before,#powerTip.se-alt:before{border-top:0;border-bottom:10px solid #333;border-bottom:10px solid rgba(0,0,0,.8);bottom:auto;top:-10px}#powerTip.se-alt:before{left:auto;right:10px}
app/assets/css/vendor/jquery.sliderTabs.min.css ADDED
@@ -0,0 +1 @@
1
+ .ui-slider-tabs{}.ui-slider-tabs-list-wrapper{ position: relative;width:100%;font-family:Arial,sans-serif;margin:0 0 -1px 0;z-index:50;}.ui-slider-tabs-list-wrapper.bottom{ margin: -1px 0 0 0;}.ui-slider-tabs-list-container{ overflow: hidden;}.ui-slider-tabs-list{ padding:0;margin:0 0 0 0;list-style: none;}.ui-slider-tabs-list li{ display: inline-block;border-bottom:1px solid #cfcfcf;border-right:1px solid #cfcfcf;border-top:1px solid #cfcfcf;margin:0;font-size:13px;font-weight:bold;background:#fcfcfc;background: -moz-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#fcfcfc),color-stop(100%,#f5f5f5));background: -webkit-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -o-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -ms-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc',endColorstr='#f5f5f5',GradientType=0 );}.ui-slider-tabs-list li a{ display:block;padding:8px 15px;text-decoration: none;color:#555;text-shadow:0px 1px 0px #fff;margin:0;}.ui-slider-tabs-list li a:hover{ color:#000;}.ui-slider-tabs-list li.selected{ border-bottom-color:#fff;border-top-color:#cfcfcf;background:#ffffff;background: -moz-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#ffffff),color-stop(100%,#ffffff));background: -webkit-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -o-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -ms-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: linear-gradient(top,#ffffff 0%,#ffffff 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff',endColorstr='#ffffff',GradientType=0 );}.ui-slider-tabs-list-wrapper.bottom .ui-slider-tabs-list li.selected{ border-top-color:#fff;border-bottom-color:#cfcfcf;}.ui-slider-tabs-list li.selected a{ cursor:default;color:#000;}.ui-slider-tabs-list li:first-of-type{ border-left:1px solid #cfcfcf;}.ui-slider-tabs-content-container{ position: relative;border:1px solid #cfcfcf;z-index:1;overflow: hidden;background-color:#fff;}.ui-slider-tab-content{ position:absolute;display: none;top:0;left:0;padding:10px;}.ui-slider-left-arrow,.ui-slider-right-arrow,.ui-slider-left-arrow.edge:hover,.ui-slider-right-arrow.edge:hover{ display:block;position:absolute;border:1px solid #cfcfcf;background:#fcfcfc;background: -moz-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#fcfcfc),color-stop(100%,#f5f5f5));background: -webkit-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -o-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: -ms-linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);background: linear-gradient(top,#fcfcfc 0%,#f5f5f5 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fcfcfc',endColorstr='#f5f5f5',GradientType=0 );}.ui-slider-left-arrow:hover,.ui-slider-right-arrow:hover{ background:#ffffff;background: -moz-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -webkit-gradient(linear,left top,left bottom,color-stop(0%,#ffffff),color-stop(100%,#ffffff));background: -webkit-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -o-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: -ms-linear-gradient(top,#ffffff 0%,#ffffff 100%);background: linear-gradient(top,#ffffff 0%,#ffffff 100%);filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff',endColorstr='#ffffff',GradientType=0 );}.ui-slider-left-arrow{ left:0;top:0;box-shadow:2px 0px 1px rgba(0,0,0,.06);border-top-left-radius:4px;}.ui-slider-left-arrow div{ background-image: url('../img/leftArrow.png');background-repeat: no-repeat;background-position:center center;height: inherit;}.ui-slider-left-arrow.edge div{ opacity: .25;}.ui-slider-left-arrow.edge{ box-shadow: none;cursor:default;}.ui-slider-tabs-list-wrapper.bottom .ui-slider-left-arrow{ border-top-left-radius:0;border-bottom-left-radius:4px;}.ui-slider-right-arrow{ top:0;right:0;box-shadow: -2px 0px 1px rgba(0,0,0,.06);border-top-right-radius:4px;}.ui-slider-right-arrow div{ background-image: url('../img/rightArrow.png');background-repeat: no-repeat;background-position:center center;height: inherit;}.ui-slider-right-arrow.edge div{ opacity: .25;}.ui-slider-right-arrow.edge{ box-shadow: none;cursor:default;}.ui-slider-tabs-list-wrapper.bottom .ui-slider-right-arrow{ border-top-right-radius:0;border-bottom-right-radius:4px;}.ui-slider-tabs-indicator-container{ position:absolute;bottom:0;left:0;width:100%;text-align:center;}.ui-slider-tabs-indicator{ width:10px;height:10px;background-image: url('../img/indicator.png');background-repeat: no-repeat;display: inline-block;margin-right:3px;cursor: pointer;}.ui-slider-tabs-indicator.selected{ background-image: url('../img/indicatorActive.png');}.ui-slider-tabs-leftPanelArrow{ position:absolute;left:0px;width:30px;height:35px;background-image: url('../img/leftPanelArrow.png');background-repeat: no-repeat;background-position:center center;cursor: pointer;opacity:0.5;-moz-opacity:0.5;filter:alpha(opacity=5);}.ui-slider-tabs-rightPanelArrow{ position:absolute;right:0px;width:30px;height:35px;background-image: url('../img/rightPanelArrow.png');background-repeat: no-repeat;background-position:center center;cursor: pointer;opacity:0.5;-moz-opacity:0.5;filter:alpha(opacity=5);}.ui-slider-tabs-rightPanelArrow.showOnHover,.ui-slider-tabs-leftPanelArrow.showOnHover{ opacity:0;display: none;}.ui-slider-tabs-content-container:hover .ui-slider-tabs-rightPanelArrow.showOnHover,.ui-slider-tabs-content-container:hover .ui-slider-tabs-leftPanelArrow.showOnHover{ opacity: .5;display: inline-block;}.ui-slider-tabs-content-container .ui-slider-tabs-rightPanelArrow:hover,.ui-slider-tabs-content-container .ui-slider-tabs-leftPanelArrow:hover,.ui-slider-tabs-content-container .ui-slider-tabs-rightPanelArrow.showOnHover:hover,.ui-slider-tabs-content-container .ui-slider-tabs-leftPanelArrow.showOnHover:hover{ opacity:1;}
app/assets/js/admin.js CHANGED
@@ -75,7 +75,7 @@ jQuery(document).ready(function($) {
75
var error_msg = "";
76
var general_videothumb_val = 0;
77
if( general_videothumb.val() <= 0 ) {
78
- error_msg += "Number of video thumbnails to be generated should be greater than 0 in image sizes settings. Setting it to round value 2.";
79
general_videothumb_val = 2;
80
} else if( !reg.test( general_videothumb.val() ) ) {
81
error_msg += 'Invalid value for Number of video thumbnails in image sizes settings. Setting it to round value ' + Math.round( general_videothumb.val() ) + ".";
@@ -137,32 +137,41 @@ jQuery(document).ready(function($) {
137
}
138
});
139
140
- jQuery(document).on('click', '#api-key-submit', function(e) {
141
e.preventDefault();
142
- jQuery(this).after('<img style="margin: 0 0 0 10px" src="' + rtmedia_admin_url + 'images/wpspin_light.gif" />')
143
var data = {
144
action: 'rtmedia_enter_api_key',
145
- apikey: jQuery('#new-api-key').val()
146
};
147
148
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
149
- jQuery.getJSON(ajaxurl, data, function(response) {
150
- if (response.error === undefined && response.apikey) {
151
var tempUrl = window.location.href;
152
var hash = window.location.hash;
153
- tempUrl = tempUrl.replace(hash, '');
154
- if (tempUrl.toString().indexOf('&apikey=' + response.apikey) == -1)
155
tempUrl += '&apikey=' + response.apikey;
156
- if (tempUrl.toString().indexOf('&update=true') == -1)
157
tempUrl += '&update=true';
158
document.location.href = tempUrl + hash;
159
-
160
} else {
161
- jQuery('#settings-error-api-key-error').remove();
162
- jQuery('h2:first').after('<div class="error" id="settings-error-api-key-error"><p>' + response.error + '</p></div>');
163
}
164
- });
165
- });
166
167
jQuery(document).on('click', '#disable-encoding', function(e) {
168
e.preventDefault();
75
var error_msg = "";
76
var general_videothumb_val = 0;
77
if( general_videothumb.val() <= 0 ) {
78
+ error_msg += "Number of video thumbnails to be generated should be greater than 0 in image sizes settings. Setting it to default value 2.";
79
general_videothumb_val = 2;
80
} else if( !reg.test( general_videothumb.val() ) ) {
81
error_msg += 'Invalid value for Number of video thumbnails in image sizes settings. Setting it to round value ' + Math.round( general_videothumb.val() ) + ".";
137
}
138
});
139
140
+ jQuery( document ).on( 'click', '#api-key-submit', function( e ) {
141
e.preventDefault();
142
+
143
+ if( jQuery( this ).next( 'img' ).length == 0 ) {
144
+ jQuery( this ).after( '<img style="margin: 0 0 0 10px" src="' + rtmedia_admin_url + 'images/wpspin_light.gif" />' );
145
+ }
146
+
147
var data = {
148
action: 'rtmedia_enter_api_key',
149
+ apikey: jQuery( '#new-api-key' ).val()
150
};
151
152
// since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
153
+ jQuery.getJSON( ajaxurl, data, function( response ) {
154
+ if ( response.error === undefined && response.apikey ) {
155
var tempUrl = window.location.href;
156
var hash = window.location.hash;
157
+ tempUrl = tempUrl.replace( hash, '' );
158
+
159
+ if ( tempUrl.toString().indexOf( '&apikey=' + response.apikey ) == -1 ) {
160
tempUrl += '&apikey=' + response.apikey;
161
+ }
162
+ if ( tempUrl.toString().indexOf( '&update=true' ) == -1 ) {
163
tempUrl += '&update=true';
164
+ }
165
+
166
document.location.href = tempUrl + hash;
167
} else {
168
+ jQuery( '#settings-error-api-key-error' ).remove();
169
+ jQuery( 'h2:first' ).after( '<div class="error" id="settings-error-api-key-error"><p>' + response.error + '</p></div>' );
170
}
171
+
172
+ jQuery( '#api-key-submit' ).next( 'img' ).remove();
173
+ } );
174
+ } );
175
176
jQuery(document).on('click', '#disable-encoding', function(e) {
177
e.preventDefault();
app/assets/js/vendor/bootstrap-switch.js ADDED
@@ -0,0 +1,255 @@
1
+ /* ============================================================
2
+ * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru
3
+ * http://www.larentis.eu/switch/
4
+ * ============================================================
5
+ * Licensed under the Apache License, Version 2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ * ============================================================ */
8
+
9
+ !function ($) {
10
+ "use strict";
11
+
12
+ $.fn['bootstrapSwitch'] = function (method) {
13
+ var methods = {
14
+ init: function () {
15
+ return this.each(function () {
16
+ var $element = $(this)
17
+ , $div
18
+ , $switchLeft
19
+ , $switchRight
20
+ , $label
21
+ , myClasses = ""
22
+ , classes = $element.attr('class')
23
+ , color
24
+ , moving
25
+ , onLabel = "ON"
26
+ , offLabel = "OFF"
27
+ , icon = false;
28
+
29
+ $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) {
30
+ if (classes.indexOf(el) >= 0)
31
+ myClasses = el;
32
+ });
33
+
34
+ $element.addClass('has-switch');
35
+
36
+ if ($element.data('on') !== undefined)
37
+ color = "switch-" + $element.data('on');
38
+
39
+ if ($element.data('on-label') !== undefined)
40
+ onLabel = $element.data('on-label');
41
+
42
+ if ($element.data('off-label') !== undefined)
43
+ offLabel = $element.data('off-label');
44
+
45
+ if ($element.data('icon') !== undefined)
46
+ icon = $element.data('icon');
47
+
48
+ $switchLeft = $('<span>')
49
+ .addClass("switch-left")
50
+ .addClass(myClasses)
51
+ .addClass(color)
52
+ .html(onLabel);
53
+
54
+ color = '';
55
+ if ($element.data('off') !== undefined)
56
+ color = "switch-" + $element.data('off');
57
+
58
+ $switchRight = $('<span>')
59
+ .addClass("switch-right")
60
+ .addClass(myClasses)
61
+ .addClass(color)
62
+ .html(offLabel);
63
+
64
+ $label = $('<label>')
65
+ .html("&nbsp;")
66
+ .addClass(myClasses)
67
+ .attr('for', $element.find('input').attr('id'));
68
+
69
+ if (icon) {
70
+ $label.html('<i class="' + icon + '"></i>');
71
+ }
72
+
73
+ $div = $element.find(':checkbox').wrap($('<div>')).parent().data('animated', false);
74
+
75
+ if ($element.data('animated') !== false)
76
+ $div.addClass('switch-animate').data('animated', true);
77
+
78
+ $div
79
+ .append($switchLeft)
80
+ .append($label)
81
+ .append($switchRight);
82
+
83
+ $element.find('>div').addClass(
84
+ $element.find('input').is(':checked') ? 'switch-on' : 'switch-off'
85
+ );
86
+
87
+ if ($element.find('input').is(':disabled'))
88
+ $(this).addClass('deactivate');
89
+
90
+ var changeStatus = function ($this) {
91
+ $($this).siblings('label').trigger('mousedown').trigger('mouseup').trigger('click');
92
+ };
93
+
94
+ $element.on('keydown', function (e) {
95
+ if (e.keyCode === 32) {
96
+ e.stopImmediatePropagation();
97
+ e.preventDefault();
98
+ changeStatus($(e.target).find('span:first'));
99
+ }
100
+ });
101
+
102
+ $switchLeft.on('click', function (e) {
103
+ changeStatus($(this));
104
+ });
105
+
106
+ $switchRight.on('click', function (e) {
107
+ changeStatus($(this));
108
+ });
109
+
110
+ $element.find('input').on('change', function (e) {
111
+ var $this = $(this)
112
+ , $element = $this.parent()
113
+ , thisState = $this.is(':checked')
114
+ , state = $element.is('.switch-off');
115
+
116
+ e.preventDefault();
117
+
118
+ $element.css('left', '');
119
+
120
+ if (state === thisState) {
121
+
122
+ if (thisState)
123
+ $element.removeClass('switch-off').addClass('switch-on');
124
+ else $element.removeClass('switch-on').addClass('switch-off');
125
+
126
+ if ($element.data('animated') !== false)
127
+ $element.addClass("switch-animate");
128
+
129
+ $element.parent().trigger('switch-change', {'el': $this, 'value': thisState})
130
+ }
131
+ });
132
+
133
+ $element.find('label').on('mousedown touchstart', function (e) {
134
+ var $this = $(this);
135
+ moving = false;
136
+
137
+ e.preventDefault();
138
+ e.stopImmediatePropagation();
139
+
140
+ $this.closest('div').removeClass('switch-animate');
141
+
142
+ if ($this.closest('.has-switch').is('.deactivate'))
143
+ $this.unbind('click');
144
+ else {
145
+ $this.on('mousemove touchmove', function (e) {
146
+ var $element = $(this).closest('.rt-switch')
147
+ , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left
148
+ , percent = (relativeX / $element.width()) * 100
149
+ , left = 25
150
+ , right = 75;
151
+
152
+ moving = true;
153
+
154
+ if (percent < left)
155
+ percent = left;
156
+ else if (percent > right)
157
+ percent = right;
158
+
159
+ $element.find('>div').css('left', (percent - right) + "%")
160
+ });
161
+
162
+ $this.on('click touchend', function (e) {
163
+ var $this = $(this)
164
+ , $target = $(e.target)
165
+ , $myCheckBox = $target.siblings('input');
166
+
167
+ e.stopImmediatePropagation();
168
+ e.preventDefault();
169
+
170
+ $this.unbind('mouseleave');
171
+
172
+ if (moving)
173
+ $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25));
174
+ else $myCheckBox.prop("checked", !$myCheckBox.is(":checked"));
175
+
176
+ moving = false;
177
+ $myCheckBox.trigger('change');
178
+ });
179
+
180
+ $this.on('mouseleave', function (e) {
181
+ var $this = $(this)
182
+ , $myCheckBox = $this.siblings('input');
183
+
184
+ e.preventDefault();
185
+ e.stopImmediatePropagation();
186
+
187
+ $this.unbind('mouseleave');
188
+ $this.trigger('mouseup');
189
+
190
+ $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change');
191
+ });
192
+
193
+ $this.on('mouseup', function (e) {
194
+ e.stopImmediatePropagation();
195
+ e.preventDefault();
196
+
197
+ $(this).unbind('mousemove');
198
+ });
199
+ }
200
+ });
201
+ }
202
+ );
203
+ },
204
+ toggleActivation: function () {
205
+ $(this).toggleClass('deactivate');
206
+ },
207
+ isActive: function () {
208
+ return !$(this).hasClass('deactivate');
209
+ },
210
+ setActive: function (active) {
211
+ if (active)
212
+ $(this).removeClass('deactivate');
213
+ else $(this).addClass('deactivate');
214
+ },
215
+ toggleState: function (skipOnChange) {
216
+ var $input = $(this).find('input:checkbox');
217
+ $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange);
218
+ },
219
+ setState: function (value, skipOnChange) {
220
+ $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange);
221
+ },
222
+ status: function () {
223
+ return $(this).find('input:checkbox').is(':checked');
224
+ },
225
+ destroy: function () {
226
+ var $div = $(this).find('div')
227
+ , $checkbox;
228
+
229
+ $div.find(':not(input:checkbox)').remove();
230
+
231
+ $checkbox = $div.children();
232
+ $checkbox.unwrap().unwrap();
233
+
234
+ $checkbox.unbind('change');
235
+
236
+ return $checkbox;
237
+ }
238
+ };
239
+
240
+ if (methods[method])
241
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
242
+ else if (typeof method === 'object' || !method)
243
+ return methods.init.apply(this, arguments);
244
+ else
245
+ $.error('Method ' + method + ' does not exist!');
246
+ };
247
+ }(jQuery);
248
+
249
+ jQuery(function () {
250
+ jQuery('.rt-switch')['bootstrapSwitch']();
251
+ jQuery(document).on('click' ,'.switch-left,.switch-right',function(e){
252
+ jQuery(this).siblings('label').trigger('click');
253
+ })
254
+
255
+ });
app/assets/js/vendor/jquery.observehashchange.pack.js ADDED
@@ -0,0 +1,87 @@
1
+ /**
2
+ * jQuery.observeHashChange (Version: 1.0)
3
+ *
4
+ * http://finnlabs.github.com/jquery.observehashchange/
5
+ *
6
+ * Copyright (c) 2009, Gregor Schmidt, Finn GmbH
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a
9
+ * copy of this software and associated documentation files (the "Software"),
10
+ * to deal in the Software without restriction, including without limitation
11
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12
+ * and/or sell copies of the Software, and to permit persons to whom the
13
+ * Software is furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ * DEALINGS IN THE SOFTWARE.
25
+ **/
26
+ (function($) {
27
+ $.fn.hashchange = function(fn) {
28
+ $(window).bind("jQuery.hashchange", fn);
29
+ return this;
30
+ };
31
+
32
+ $.observeHashChange = function(options) {
33
+ var opts = $.extend({}, $.observeHashChange.defaults, options);
34
+ if (isHashChangeEventSupported()) {
35
+ nativeVersion();
36
+ }
37
+ else {
38
+ setIntervalVersion(opts);
39
+ }
40
+ };
41
+
42
+ var locationHash = null;
43
+ var functionStore = null;
44
+ var interval = 0;
45
+
46
+ $.observeHashChange.defaults = {
47
+ interval : 500
48
+ };
49
+
50
+ function isHashChangeEventSupported() {
51
+ return "onhashchange" in window;
52
+ }
53
+
54
+ function nativeVersion() {
55
+ locationHash = document.location.hash;
56
+ window.onhashchange = onhashchangeHandler;
57
+ }
58
+
59
+ function onhashchangeHandler(e, data) {
60
+ var oldHash = locationHash;
61
+ locationHash = document.location.hash;
62
+ $(window).trigger("jQuery.hashchange", {before: oldHash, after: locationHash});
63
+ }
64
+
65
+ function setIntervalVersion(opts) {
66
+ if (locationHash == null) {
67
+ locationHash = document.location.hash;
68
+ }
69
+ if (functionStore != null) {
70
+ clearInterval(functionStore);
71
+ }
72
+ if (interval != opts.interval) {
73
+ functionStore = setInterval(checkLocationHash, opts.interval);
74
+ interval = opts.interval;
75
+ }
76
+ }
77
+
78
+ function checkLocationHash() {
79
+ if (locationHash != document.location.hash) {
80
+ var oldHash = locationHash;
81
+ locationHash = document.location.hash;
82
+ $(window).trigger("jQuery.hashchange", {before: oldHash, after: locationHash});
83
+ }
84
+ }
85
+
86
+ $.observeHashChange();
87
+ })(jQuery);
app/assets/js/vendor/jquery.powertip.min.js ADDED
@@ -0,0 +1,1166 @@
1
+ /*!
2
+ PowerTip - v1.2.0 - 2013-04-03
3
+ http://stevenbenner.github.com/jquery-powertip/
4
+ Copyright (c) 2013 Steven Benner (http://stevenbenner.com/).
5
+ Released under MIT license.
6
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
7
+ */
8
+ (function(factory) {
9
+ if (typeof define === 'function' && define.amd) {
10
+ // AMD. Register as an anonymous module.
11
+ define(['jquery'], factory);
12
+ } else {
13
+ // Browser globals
14
+ factory(jQuery);
15
+ }
16
+ }(function($) {
17
+
18
+ // useful private variables
19
+ var $document = $(document),
20
+ $window = $(window),
21
+ $body = $('body');
22
+
23
+ // constants
24
+ var DATA_DISPLAYCONTROLLER = 'displayController',
25
+ DATA_HASACTIVEHOVER = 'hasActiveHover',
26
+ DATA_FORCEDOPEN = 'forcedOpen',
27
+ DATA_HASMOUSEMOVE = 'hasMouseMove',
28
+ DATA_MOUSEONTOTIP = 'mouseOnToPopup',
29
+ DATA_ORIGINALTITLE = 'originalTitle',
30
+ DATA_POWERTIP = 'powertip',
31
+ DATA_POWERTIPJQ = 'powertipjq',
32
+ DATA_POWERTIPTARGET = 'powertiptarget',
33
+ RAD2DEG = 180 / Math.PI;
34
+
35
+ /**
36
+ * Session data
37
+ * Private properties global to all powerTip instances
38
+ */
39
+ var session = {
40
+ isTipOpen: false,
41
+ isFixedTipOpen: false,
42
+ isClosing: false,
43
+ tipOpenImminent: false,
44
+ activeHover: null,
45
+ currentX: 0,
46
+ currentY: 0,
47
+ previousX: 0,
48
+ previousY: 0,
49
+ desyncTimeout: null,
50
+ mouseTrackingActive: false,
51
+ delayInProgress: false,
52
+ windowWidth: 0,
53
+ windowHeight: 0,
54
+ scrollTop: 0,
55
+ scrollLeft: 0
56
+ };
57
+
58
+ /**
59
+ * Collision enumeration
60
+ * @enum {number}
61
+ */
62
+ var Collision = {
63
+ none: 0,
64
+ top: 1,
65
+ bottom: 2,
66
+ left: 4,
67
+ right: 8
68
+ };
69
+
70
+ /**
71
+ * Display hover tooltips on the matched elements.
72
+ * @param {(Object|string)} opts The options object to use for the plugin, or
73
+ * the name of a method to invoke on the first matched element.
74
+ * @param {*=} [arg] Argument for an invoked method (optional).
75
+ * @return {jQuery} jQuery object for the matched selectors.
76
+ */
77
+ $.fn.powerTip = function(opts, arg) {
78
+ // don't do any work if there were no matched elements
79
+ if (!this.length) {
80
+ return this;
81
+ }
82
+
83
+ // handle api method calls on the plugin, e.g. powerTip('hide')
84
+ if ($.type(opts) === 'string' && $.powerTip[opts]) {
85
+ return $.powerTip[opts].call(this, this, arg);
86
+ }
87
+
88
+ // extend options and instantiate TooltipController
89
+ var options = $.extend({}, $.fn.powerTip.defaults, opts),
90
+ tipController = new TooltipController(options);
91
+
92
+ // hook mouse and viewport dimension tracking
93
+ initTracking();
94
+
95
+ // setup the elements
96
+ this.each(function elementSetup() {
97
+ var $this = $(this),
98
+ dataPowertip = $this.data(DATA_POWERTIP),
99
+ dataElem = $this.data(DATA_POWERTIPJQ),
100
+ dataTarget = $this.data(DATA_POWERTIPTARGET),
101
+ title;
102
+
103
+ // handle repeated powerTip calls on the same element by destroying the
104
+ // original instance hooked to it and replacing it with this call
105
+ if ($this.data(DATA_DISPLAYCONTROLLER)) {
106
+ $.powerTip.destroy($this);
107
+ }
108
+
109
+ // attempt to use title attribute text if there is no data-powertip,
110
+ // data-powertipjq or data-powertiptarget. If we do use the title
111
+ // attribute, delete the attribute so the browser will not show it
112
+ title = $this.attr('title');
113
+ if (!dataPowertip && !dataTarget && !dataElem && title) {
114
+ $this.data(DATA_POWERTIP, title);
115
+ $this.data(DATA_ORIGINALTITLE, title);
116
+ $this.removeAttr('title');
117
+ }
118
+
119
+ // create hover controllers for each element
120
+ $this.data(
121
+ DATA_DISPLAYCONTROLLER,
122
+ new DisplayController($this, options, tipController)
123
+ );
124
+ });
125
+
126
+ // attach events to matched elements if the manual options is not enabled
127
+ if (!options.manual) {
128
+ this.on({
129
+ // mouse events
130
+ 'mouseenter.powertip': function elementMouseEnter(event) {
131
+ $.powerTip.show(this, event);
132
+ },
133
+ 'mouseleave.powertip': function elementMouseLeave() {
134
+ $.powerTip.hide(this);
135
+ },
136
+ // keyboard events
137
+ 'focus.powertip': function elementFocus() {
138
+ $.powerTip.show(this);
139
+ },
140
+ 'blur.powertip': function elementBlur() {
141
+ $.powerTip.hide(this, true);
142
+ },
143
+ 'keydown.powertip': function elementKeyDown(event) {
144
+ // close tooltip when the escape key is pressed
145
+ if (event.keyCode === 27) {
146
+ $.powerTip.hide(this, true);
147
+ }
148
+ }
149
+ });
150
+ }
151
+
152
+ return this;
153
+ };
154
+
155
+ /**
156
+ * Default options for the powerTip plugin.
157
+ */
158
+ $.fn.powerTip.defaults = {
159
+ fadeInTime: 200,
160
+ fadeOutTime: 100,
161
+ followMouse: false,
162
+ popupId: 'powerTip',
163
+ intentSensitivity: 7,
164
+ intentPollInterval: 100,
165
+ closeDelay: 100,
166
+ placement: 'n',
167
+ smartPlacement: false,
168
+ offset: 10,
169
+ mouseOnToPopup: false,
170
+ manual: false
171
+ };
172
+
173
+ /**
174
+ * Default smart placement priority lists.
175
+ * The first item in the array is the highest priority, the last is the lowest.
176
+ * The last item is also the default, which will be used if all previous options
177
+ * do not fit.
178
+ */
179
+ $.fn.powerTip.smartPlacementLists = {
180
+ n: ['n', 'ne', 'nw', 's'],
181
+ e: ['e', 'ne', 'se', 'w', 'nw', 'sw', 'n', 's', 'e'],
182
+ s: ['s', 'se', 'sw', 'n'],
183
+ w: ['w', 'nw', 'sw', 'e', 'ne', 'se', 'n', 's', 'w'],
184
+ nw: ['nw', 'w', 'sw', 'n', 's', 'se', 'nw'],
185
+ ne: ['ne', 'e', 'se', 'n', 's', 'sw', 'ne'],
186
+ sw: ['sw', 'w', 'nw', 's', 'n', 'ne', 'sw'],
187
+ se: ['se', 'e', 'ne', 's', 'n', 'nw', 'se'],
188
+ 'nw-alt': ['nw-alt', 'n', 'ne-alt', 'sw-alt', 's', 'se-alt', 'w', 'e'],
189
+ 'ne-alt': ['ne-alt', 'n', 'nw-alt', 'se-alt', 's', 'sw-alt', 'e', 'w'],
190
+ 'sw-alt': ['sw-alt', 's', 'se-alt', 'nw-alt', 'n', 'ne-alt', 'w', 'e'],
191
+ 'se-alt': ['se-alt', 's', 'sw-alt', 'ne-alt', 'n', 'nw-alt', 'e', 'w']
192
+ };
193
+
194
+ /**
195
+ * Public API
196
+ */
197
+ $.powerTip = {
198
+ /**
199
+ * Attempts to show the tooltip for the specified element.
200
+ * @param {jQuery|Element} element The element to open the tooltip for.
201
+ * @param {jQuery.Event=} event jQuery event for hover intent and mouse
202
+ * tracking (optional).
203
+ */
204
+ show: function apiShowTip(element, event) {
205
+ if (event) {
206
+ trackMouse(event);
207
+ session.previousX = event.pageX;
208
+ session.previousY = event.pageY;
209
+ $(element).data(DATA_DISPLAYCONTROLLER).show();
210
+ } else {
211
+ $(element).first().data(DATA_DISPLAYCONTROLLER).show(true, true);
212
+ }
213
+ return element;
214
+ },
215
+
216
+ /**
217
+ * Repositions the tooltip on the element.
218
+ * @param {jQuery|Element} element The element the tooltip is shown for.
219
+ */
220
+ reposition: function apiResetPosition(element) {
221
+ $(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();
222
+ return element;
223
+ },
224
+
225
+ /**
226
+ * Attempts to close any open tooltips.
227
+ * @param {(jQuery|Element)=} element The element with the tooltip that
228
+ * should be closed (optional).
229
+ * @param {boolean=} immediate Disable close delay (optional).
230
+ */
231
+ hide: function apiCloseTip(element, immediate) {
232
+ if (element) {
233
+ $(element).first().data(DATA_DISPLAYCONTROLLER).hide(immediate);
234
+ } else {
235
+ if (session.activeHover) {
236
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).hide(true);
237
+ }
238
+ }
239
+ return element;
240
+ },
241
+
242
+ /**
243
+ * Destroy and roll back any powerTip() instance on the specified element.
244
+ * @param {jQuery|Element} element The element with the powerTip instance.
245
+ */
246
+ destroy: function apiDestroy(element) {
247
+ $(element).off('.powertip').each(function destroy() {
248
+ var $this = $(this),
249
+ dataAttributes = [
250
+ DATA_ORIGINALTITLE,
251
+ DATA_DISPLAYCONTROLLER,
252
+ DATA_HASACTIVEHOVER,
253
+ DATA_FORCEDOPEN
254
+ ];
255
+
256
+ if ($this.data(DATA_ORIGINALTITLE)) {
257
+ $this.attr('title', $this.data(DATA_ORIGINALTITLE));
258
+ dataAttributes.push(DATA_POWERTIP);
259
+ }
260
+
261
+ $this.removeData(dataAttributes);
262
+ });
263
+ return element;
264
+ }
265
+ };
266
+
267
+ // API aliasing
268
+ $.powerTip.showTip = $.powerTip.show;
269
+ $.powerTip.closeTip = $.powerTip.hide;
270
+
271
+ /**
272
+ * Creates a new CSSCoordinates object.
273
+ * @private
274
+ * @constructor
275
+ */
276
+ function CSSCoordinates() {
277
+ var me = this;
278
+
279
+ // initialize object properties
280
+ me.top = 'auto';
281
+ me.left = 'auto';
282
+ me.right = 'auto';
283
+ me.bottom = 'auto';
284
+
285
+ /**
286
+ * Set a property to a value.
287
+ * @private
288
+ * @param {string} property The name of the property.
289
+ * @param {number} value The value of the property.
290
+ */
291
+ me.set = function(property, value) {
292
+ if ($.isNumeric(value)) {
293
+ me[property] = Math.round(value);
294
+ }
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Creates a new tooltip display controller.
300
+ * @private
301
+ * @constructor
302
+ * @param {jQuery} element The element that this controller will handle.
303
+ * @param {Object} options Options object containing settings.
304
+ * @param {TooltipController} tipController The TooltipController object for
305
+ * this instance.
306
+ */
307
+ function DisplayController(element, options, tipController) {
308
+ var hoverTimer = null;
309
+
310
+ /**
311
+ * Begins the process of showing a tooltip.
312
+ * @private
313
+ * @param {boolean=} immediate Skip intent testing (optional).
314
+ * @param {boolean=} forceOpen Ignore cursor position and force tooltip to
315
+ * open (optional).
316
+ */
317
+ function openTooltip(immediate, forceOpen) {
318
+ cancelTimer();
319
+ if (!element.data(DATA_HASACTIVEHOVER)) {
320
+ if (!immediate) {
321
+ session.tipOpenImminent = true;
322
+ hoverTimer = setTimeout(
323
+ function intentDelay() {
324
+ hoverTimer = null;
325
+ checkForIntent();
326
+ },
327
+ options.intentPollInterval
328
+ );
329
+ } else {
330
+ if (forceOpen) {
331
+ element.data(DATA_FORCEDOPEN, true);
332
+ }
333
+ tipController.showTip(element);
334
+ }
335
+ }
336
+ }
337
+
338
+ /**
339
+ * Begins the process of closing a tooltip.
340
+ * @private
341
+ * @param {boolean=} disableDelay Disable close delay (optional).
342
+ */
343
+ function closeTooltip(disableDelay) {
344
+ cancelTimer();
345
+ session.tipOpenImminent = false;
346
+ if (element.data(DATA_HASACTIVEHOVER)) {
347
+ element.data(DATA_FORCEDOPEN, false);
348
+ if (!disableDelay) {
349
+ session.delayInProgress = true;
350
+ hoverTimer = setTimeout(
351
+ function closeDelay() {
352
+ hoverTimer = null;
353
+ tipController.hideTip(element);
354
+ session.delayInProgress = false;
355
+ },
356
+ options.closeDelay
357
+ );
358
+ } else {
359
+ tipController.hideTip(element);
360
+ }
361
+ }
362
+ }
363
+
364
+ /**
365
+ * Checks mouse position to make sure that the user intended to hover on the
366
+ * specified element before showing the tooltip.
367
+ * @private
368
+ */
369
+ function checkForIntent() {
370
+ // calculate mouse position difference
371
+ var xDifference = Math.abs(session.previousX - session.currentX),
372
+ yDifference = Math.abs(session.previousY - session.currentY),
373
+ totalDifference = xDifference + yDifference;
374
+
375
+ // check if difference has passed the sensitivity threshold
376
+ if (totalDifference < options.intentSensitivity) {
377
+ tipController.showTip(element);
378
+ } else {
379
+ // try again
380
+ session.previousX = session.currentX;
381
+ session.previousY = session.currentY;
382
+ openTooltip();
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Cancels active hover timer.
388
+ * @private
389
+ */
390
+ function cancelTimer() {
391
+ hoverTimer = clearTimeout(hoverTimer);
392
+ session.delayInProgress = false;
393
+ }
394
+
395
+ /**
396
+ * Repositions the tooltip on this element.
397
+ * @private
398
+ */
399
+ function repositionTooltip() {
400
+ tipController.resetPosition(element);
401
+ }
402
+
403
+ // expose the methods
404
+ this.show = openTooltip;
405
+ this.hide = closeTooltip;
406
+ this.cancel = cancelTimer;
407
+ this.resetPosition = repositionTooltip;
408
+ }
409
+
410
+ /**
411
+ * Creates a new Placement Calculator.
412
+ * @private
413
+ * @constructor
414
+ */
415
+ function PlacementCalculator() {
416
+ /**
417
+ * Compute the CSS position to display a tooltip at the specified placement
418
+ * relative to the specified element.
419
+ * @private
420
+ * @param {jQuery} element The element that the tooltip should target.
421
+ * @param {string} placement The placement for the tooltip.
422
+ * @param {number} tipWidth Width of the tooltip element in pixels.
423
+ * @param {number} tipHeight Height of the tooltip element in pixels.
424
+ * @param {number} offset Distance to offset tooltips in pixels.
425
+ * @return {CSSCoordinates} A CSSCoordinates object with the position.
426
+ */
427
+ function computePlacementCoords(element, placement, tipWidth, tipHeight, offset) {
428
+ var placementBase = placement.split('-')[0], // ignore 'alt' for corners
429
+ coords = new CSSCoordinates(),
430
+ position;
431
+
432
+ if (isSvgElement(element)) {
433
+ position = getSvgPlacement(element, placementBase);
434
+ } else {
435
+ position = getHtmlPlacement(element, placementBase);
436
+ }
437
+
438
+ // calculate the appropriate x and y position in the document
439
+ switch (placement) {
440
+ case 'n':
441
+ coords.set('left', position.left - (tipWidth / 2));
442
+ coords.set('bottom', session.windowHeight - position.top + offset);
443
+ break;
444
+ case 'e':
445
+ coords.set('left', position.left + offset);
446
+ coords.set('top', position.top - (tipHeight / 2));
447
+ break;
448
+ case 's':
449
+ coords.set('left', position.left - (tipWidth / 2));
450
+ coords.set('top', position.top + offset);
451
+ break;
452
+ case 'w':
453
+ coords.set('top', position.top - (tipHeight / 2));
454
+ coords.set('right', session.windowWidth - position.left + offset);
455
+ break;
456
+ case 'nw':
457
+ coords.set('bottom', session.windowHeight - position.top + offset);
458
+ coords.set('right', session.windowWidth - position.left - 20);
459
+ break;
460
+ case 'nw-alt':
461
+ coords.set('left', position.left);
462
+ coords.set('bottom', session.windowHeight - position.top + offset);
463
+ break;
464
+ case 'ne':
465
+ coords.set('left', position.left - 20);
466
+ coords.set('bottom', session.windowHeight - position.top + offset);
467
+ break;
468
+ case 'ne-alt':
469
+ coords.set('bottom', session.windowHeight - position.top + offset);
470
+ coords.set('right', session.windowWidth - position.left);
471
+ break;
472
+ case 'sw':
473
+ coords.set('top', position.top + offset);
474
+ coords.set('right', session.windowWidth - position.left - 20);
475
+ break;
476
+ case 'sw-alt':
477
+ coords.set('left', position.left);
478
+ coords.set('top', position.top + offset);
479
+ break;
480
+ case 'se':
481
+ coords.set('left', position.left - 20);
482
+ coords.set('top', position.top + offset);
483
+ break;
484
+ case 'se-alt':
485
+ coords.set('top', position.top + offset);
486
+ coords.set('right', session.windowWidth - position.left);
487
+ break;
488
+ }
489
+
490
+ return coords;
491
+ }
492
+
493
+ /**
494
+ * Finds the tooltip attachment point in the document for a HTML DOM element
495
+ * for the specified placement.
496
+ * @private
497
+ * @param {jQuery} element The element that the tooltip should target.
498
+ * @param {string} placement The placement for the tooltip.
499
+ * @return {Object} An object with the top,left position values.
500
+ */
501
+ function getHtmlPlacement(element, placement) {
502
+ var objectOffset = element.offset(),
503
+ objectWidth = element.outerWidth(),
504
+ objectHeight = element.outerHeight(),
505
+ left,
506
+ top;
507
+
508
+ // calculate the appropriate x and y position in the document
509
+ switch (placement) {
510
+ case 'n':
511
+ left = objectOffset.left + objectWidth / 2;
512
+ top = objectOffset.top;
513
+ break;
514
+ case 'e':
515
+ left = objectOffset.left + objectWidth;
516
+ top = objectOffset.top + objectHeight / 2;
517
+ break;
518
+ case 's':
519
+ left = objectOffset.left + objectWidth / 2;
520
+ top = objectOffset.top + objectHeight;
521
+ break;
522
+ case 'w':
523
+ left = objectOffset.left;
524
+ top = objectOffset.top + objectHeight / 2;
525
+ break;
526
+ case 'nw':
527
+ left = objectOffset.left;
528
+ top = objectOffset.top;
529
+ break;
530
+ case 'ne':
531
+ left = objectOffset.left + objectWidth;
532
+ top = objectOffset.top;
533
+ break;
534
+ case 'sw':
535
+ left = objectOffset.left;
536
+ top = objectOffset.top + objectHeight;
537
+ break;
538
+ case 'se':
539
+ left = objectOffset.left + objectWidth;
540
+ top = objectOffset.top + objectHeight;
541
+ break;
542
+ }
543
+
544
+ return {
545
+ top: top,
546
+ left: left
547
+ };
548
+ }
549
+
550
+ /**
551
+ * Finds the tooltip attachment point in the document for a SVG element for
552
+ * the specified placement.
553
+ * @private
554
+ * @param {jQuery} element The element that the tooltip should target.
555
+ * @param {string} placement The placement for the tooltip.
556
+ * @return {Object} An object with the top,left position values.
557
+ */
558
+ function getSvgPlacement(element, placement) {
559
+ var svgElement = element.closest('svg')[0],
560
+ domElement = element[0],
561
+ point = svgElement.createSVGPoint(),
562
+ boundingBox = domElement.getBBox(),
563
+ matrix = domElement.getScreenCTM(),
564
+ halfWidth = boundingBox.width / 2,
565
+ halfHeight = boundingBox.height / 2,
566
+ placements = [],
567
+ placementKeys = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'],
568
+ coords,
569
+ rotation,
570
+ steps,
571
+ x;
572
+
573
+ function pushPlacement() {
574
+ placements.push(point.matrixTransform(matrix));
575
+ }
576
+
577
+ // get bounding box corners and midpoints
578
+ point.x = boundingBox.x;
579
+ point.y = boundingBox.y;
580
+ pushPlacement();
581
+ point.x += halfWidth;
582
+ pushPlacement();
583
+ point.x += halfWidth;
584
+ pushPlacement();
585
+ point.y += halfHeight;
586
+ pushPlacement();
587
+ point.y += halfHeight;
588
+ pushPlacement();
589
+ point.x -= halfWidth;
590
+ pushPlacement();
591
+ point.x -= halfWidth;
592
+ pushPlacement();
593
+ point.y -= halfHeight;
594
+ pushPlacement();
595
+
596
+ // determine rotation
597
+ if (placements[0].y !== placements[1].y || placements[0].x !== placements[7].x) {
598
+ rotation = Math.atan2(matrix.b, matrix.a) * RAD2DEG;
599
+ steps = Math.ceil(((rotation % 360) - 22.5) / 45);
600
+ if (steps < 1) {
601
+ steps += 8;
602
+ }
603
+ while (steps--) {
604
+ placementKeys.push(placementKeys.shift());
605
+ }
606
+ }
607
+
608
+ // find placement
609
+ for (x = 0; x < placements.length; x++) {
610
+ if (placementKeys[x] === placement) {
611
+ coords = placements[x];
612
+ break;
613
+ }
614
+ }
615
+
616
+ return {
617
+ top: coords.y + session.scrollTop,
618
+ left: coords.x + session.scrollLeft
619
+ };
620
+ }
621
+
622
+ // expose methods
623
+ this.compute = computePlacementCoords;
624
+ }
625
+
626
+ /**
627
+ * Creates a new tooltip controller.
628
+ * @private
629
+ * @constructor
630
+ * @param {Object} options Options object containing settings.
631
+ */
632
+ function TooltipController(options) {
633
+ var placementCalculator = new PlacementCalculator(),
634
+ tipElement = $('#' + options.popupId);
635
+
636
+ // build and append tooltip div if it does not already exist
637
+ if (tipElement.length === 0) {
638
+ tipElement = $('<div/>', { id: options.popupId });
639
+ // grab body element if it was not populated when the script loaded
640
+ // note: this hack exists solely for jsfiddle support
641
+ if ($body.length === 0) {
642
+ $body = $('body');
643
+ }
644
+ $body.append(tipElement);
645
+ }
646
+
647
+ // hook mousemove for cursor follow tooltips
648
+ if (options.followMouse) {
649
+ // only one positionTipOnCursor hook per tooltip element, please
650
+ if (!tipElement.data(DATA_HASMOUSEMOVE)) {
651
+ $document.on('mousemove', positionTipOnCursor);
652
+ $window.on('scroll', positionTipOnCursor);
653
+ tipElement.data(DATA_HASMOUSEMOVE, true);
654
+ }
655
+ }
656
+
657
+ // if we want to be able to mouse onto the tooltip then we need to attach
658
+ // hover events to the tooltip that will cancel a close request on hover and
659
+ // start a new close request on mouseleave
660
+ if (options.mouseOnToPopup) {
661
+ tipElement.on({
662
+ mouseenter: function tipMouseEnter() {
663
+ // we only let the mouse stay on the tooltip if it is set to let
664
+ // users interact with it
665
+ if (tipElement.data(DATA_MOUSEONTOTIP)) {
666
+ // check activeHover in case the mouse cursor entered the
667
+ // tooltip during the fadeOut and close cycle
668
+ if (session.activeHover) {
669
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel();
670
+ }
671
+ }
672
+ },
673
+ mouseleave: function tipMouseLeave() {
674
+ // check activeHover in case the mouse cursor entered the
675
+ // tooltip during the fadeOut and close cycle
676
+ if (session.activeHover) {
677
+ session.activeHover.data(DATA_DISPLAYCONTROLLER).hide();
678
+ }
679
+ }
680
+ });
681
+ }
682
+
683
+ /**
684
+ * Gives the specified element the active-hover state and queues up the
685
+ * showTip function.
686
+ * @private
687
+ * @param {jQuery} element The element that the tooltip should target.
688
+ */
689
+ function beginShowTip(element) {
690
+ element.data(DATA_HASACTIVEHOVER, true);
691
+ // show tooltip, asap
692
+ tipElement.queue(function queueTipInit(next) {
693
+ showTip(element);
694
+ next();
695
+ });
696
+ }
697
+
698
+ /**
699
+ * Shows the tooltip, as soon as possible.
700
+ * @private
701
+ * @param {jQuery} element The element that the tooltip should target.
702
+ */
703
+ function showTip(element) {
704
+ var tipContent;
705
+
706
+ // it is possible, especially with keyboard navigation, to move on to
707
+ // another element with a tooltip during the queue to get to this point
708
+ // in the code. if that happens then we need to not proceed or we may
709
+ // have the fadeout callback for the last tooltip execute immediately
710
+ // after this code runs, causing bugs.
711
+ if (!element.data(DATA_HASACTIVEHOVER)) {
712
+ return;
713
+ }
714
+
715
+ // if the tooltip is open and we got asked to open another one then the
716
+ // old one is still in its fadeOut cycle, so wait and try again
717
+ if (session.isTipOpen) {
718
+ if (!session.isClosing) {
719
+ hideTip(session.activeHover);
720
+ }
721
+ tipElement.delay(100).queue(function queueTipAgain(next) {
722
+ showTip(element);
723
+ next();
724
+ });
725
+ return;
726
+ }
727
+
728
+ // trigger powerTipPreRender event
729
+ element.trigger('powerTipPreRender');
730
+
731
+ // set tooltip content
732
+ tipContent = getTooltipContent(element);
733
+ if (tipContent) {
734
+ tipElement.empty().append(tipContent);
735
+ } else {
736
+ // we have no content to display, give up
737
+ return;
738
+ }
739
+
740
+ // trigger powerTipRender event
741
+ element.trigger('powerTipRender');
742
+
743
+ session.activeHover = element;
744
+ session.isTipOpen = true;
745
+
746
+ tipElement.data(DATA_MOUSEONTOTIP, options.mouseOnToPopup);
747
+
748
+ // set tooltip position
749
+ if (!options.followMouse) {
750
+ positionTipOnElement(element);
751
+ session.isFixedTipOpen = true;
752
+ } else {
753
+ positionTipOnCursor();
754
+ }
755
+
756
+ // fadein
757
+ tipElement.fadeIn(options.fadeInTime, function fadeInCallback() {
758
+ // start desync polling
759
+ if (!session.desyncTimeout) {
760
+ session.desyncTimeout = setInterval(closeDesyncedTip, 500);
761
+ }
762
+
763
+ // trigger powerTipOpen event
764
+ element.trigger('powerTipOpen');
765
+ });
766
+ }
767
+
768
+ /**
769
+ * Hides the tooltip.
770
+ * @private
771
+ * @param {jQuery} element The element that the tooltip should target.
772
+ */
773
+ function hideTip(element) {
774
+ // reset session
775
+ session.isClosing = true;
776
+ session.activeHover = null;
777
+ session.isTipOpen = false;
778
+
779
+ // stop desync polling
780
+ session.desyncTimeout = clearInterval(session.desyncTimeout);
781
+
782
+ // reset element state
783
+ element.data(DATA_HASACTIVEHOVER, false);
784
+ element.data(DATA_FORCEDOPEN, false);
785
+
786
+ // fade out
787
+ tipElement.fadeOut(options.fadeOutTime, function fadeOutCallback() {
788
+ var coords = new CSSCoordinates();
789
+
790
+ // reset session and tooltip element
791
+ session.isClosing = false;
792
+ session.isFixedTipOpen = false;
793
+ tipElement.removeClass();
794
+
795
+ // support mouse-follow and fixed position tips at the same time by
796
+ // moving the tooltip to the last cursor location after it is hidden
797
+ coords.set('top', session.currentY + options.offset);
798
+ coords.set('left', session.currentX + options.offset);
799
+ tipElement.css(coords);
800
+
801
+ // trigger powerTipClose event
802
+ element.trigger('powerTipClose');
803
+ });
804
+ }
805
+
806
+ /**
807
+ * Moves the tooltip to the users mouse cursor.
808
+ * @private
809
+ */
810
+ function positionTipOnCursor() {
811
+ // to support having fixed tooltips on the same page as cursor tooltips,
812
+ // where both instances are referencing the same tooltip element, we
813
+ // need to keep track of the mouse position constantly, but we should
814
+ // only set the tip location if a fixed tip is not currently open, a tip
815
+ // open is imminent or active, and the tooltip element in question does
816
+ // have a mouse-follow using it.
817
+ if (!session.isFixedTipOpen && (session.isTipOpen || (session.tipOpenImminent && tipElement.data(DATA_HASMOUSEMOVE)))) {
818
+ // grab measurements
819
+ var tipWidth = tipElement.outerWidth(),
820
+ tipHeight = tipElement.outerHeight(),
821
+ coords = new CSSCoordinates(),
822
+ collisions,
823
+ collisionCount;
824
+
825
+ // grab collisions
826
+ coords.set('top', session.currentY + options.offset);
827
+ coords.set('left', session.currentX + options.offset);
828
+ collisions = getViewportCollisions(
829
+ coords,
830
+ tipWidth,
831
+ tipHeight
832
+ );
833
+
834
+ // handle tooltip view port collisions
835
+ if (collisions !== Collision.none) {
836
+ collisionCount = countFlags(collisions);
837
+ if (collisionCount === 1) {
838
+ // if there is only one collision (bottom or right) then
839
+ // simply constrain the tooltip to the view port
840