Version Description
Download this release
Release Info
Developer | colorlibplugins |
Plugin | Shapely Companion |
Version | 1.2.8 |
Comparing to | |
See all releases |
Code changes from version 1.2.7 to 1.2.8
- assets/css/admin.css +50 -50
- assets/js/admin.js +113 -113
- assets/js/nav-menu.js +46 -46
- assets/js/previewer.js +74 -74
- assets/js/vendor/jquery-cloneya.js +517 -517
- assets/js/vendor/jquery-cloneya.min.js +1 -1
- assets/js/vendor/jquery.vide.js +501 -501
- assets/js/vendor/jquery.vide.min.js +8 -8
- assets/js/vendor/jquery.youtubebackground.js +334 -334
- assets/js/vendor/player.js +2118 -2118
- assets/js/vendor/player.min.js +2 -2
- assets/js/widget.js +113 -113
- inc/class-shapely-walker-nav-menu-edit.php +210 -208
- inc/epsilon-dashboard/class-epsilon-dashboard.php +224 -224
- inc/shapely-demo-content.php +167 -167
- inc/shapely-enqueues.php +34 -34
- inc/shapely-helper.php +64 -64
- inc/shapely-metabox.php +84 -84
- inc/shapely-navmenu.php +95 -95
- inc/shapely-widgets.php +53 -53
- inc/views/shapely-demo-content.php +33 -33
- inc/widgets/class-shapely-categories.php +148 -148
- inc/widgets/class-shapely-home-call-for-action.php +122 -122
- inc/widgets/class-shapely-home-clients.php +177 -177
- inc/widgets/class-shapely-home-contact.php +271 -271
- inc/widgets/class-shapely-home-features.php +752 -752
- inc/widgets/class-shapely-home-parallax.php +284 -284
- inc/widgets/class-shapely-home-portfolio.php +254 -254
- inc/widgets/class-shapely-home-testimonials.php +170 -170
- inc/widgets/class-shapely-page-content.php +70 -70
- inc/widgets/class-shapely-page-title.php +48 -48
- inc/widgets/class-shapely-recent-posts.php +164 -164
- inc/widgets/class-shapely-social.php +115 -115
- inc/widgets/class-shapely-video.php +250 -250
- languages/shapely.pot +425 -425
- license.txt +673 -673
- readme.txt +101 -101
- shapely-companion.php +92 -92
assets/css/admin.css
CHANGED
@@ -1,51 +1,51 @@
|
|
1 |
-
.shapely-media-control img {
|
2 |
-
width: 100%;
|
3 |
-
height: auto;
|
4 |
-
}
|
5 |
-
|
6 |
-
.logo_heading {
|
7 |
-
display: block;
|
8 |
-
width: 100%;
|
9 |
-
}
|
10 |
-
|
11 |
-
#setting-error-tgmpa.notice {
|
12 |
-
display: block;
|
13 |
-
}
|
14 |
-
|
15 |
-
.client-sortable .logo_heading {
|
16 |
-
background: #f3f3f3;
|
17 |
-
border: 1px dotted;
|
18 |
-
cursor: move;
|
19 |
-
display: block;
|
20 |
-
font-size: 14px;
|
21 |
-
padding: 8px 0;
|
22 |
-
text-align: center;
|
23 |
-
width: 100%;
|
24 |
-
}
|
25 |
-
|
26 |
-
.client-sortable .logo_heading:hover {
|
27 |
-
border: 1px solid;
|
28 |
-
}
|
29 |
-
|
30 |
-
.client-sortable .cloneya a.clone,
|
31 |
-
.client-sortable .cloneya a.delete {
|
32 |
-
display: none;
|
33 |
-
}
|
34 |
-
|
35 |
-
.client-sortable .cloneya:last-child a.clone,
|
36 |
-
.client-sortable .cloneya:last-child a.delete {
|
37 |
-
display: inline-block;
|
38 |
-
}
|
39 |
-
|
40 |
-
.shapely-media-control img {
|
41 |
-
width: 100%;
|
42 |
-
}
|
43 |
-
|
44 |
-
.shapely-editor-container label {
|
45 |
-
position: relative;
|
46 |
-
top: 30px;
|
47 |
-
}
|
48 |
-
|
49 |
-
.checkbox_switch {
|
50 |
-
margin: 10px auto;
|
51 |
}
|
1 |
+
.shapely-media-control img {
|
2 |
+
width: 100%;
|
3 |
+
height: auto;
|
4 |
+
}
|
5 |
+
|
6 |
+
.logo_heading {
|
7 |
+
display: block;
|
8 |
+
width: 100%;
|
9 |
+
}
|
10 |
+
|
11 |
+
#setting-error-tgmpa.notice {
|
12 |
+
display: block;
|
13 |
+
}
|
14 |
+
|
15 |
+
.client-sortable .logo_heading {
|
16 |
+
background: #f3f3f3;
|
17 |
+
border: 1px dotted;
|
18 |
+
cursor: move;
|
19 |
+
display: block;
|
20 |
+
font-size: 14px;
|
21 |
+
padding: 8px 0;
|
22 |
+
text-align: center;
|
23 |
+
width: 100%;
|
24 |
+
}
|
25 |
+
|
26 |
+
.client-sortable .logo_heading:hover {
|
27 |
+
border: 1px solid;
|
28 |
+
}
|
29 |
+
|
30 |
+
.client-sortable .cloneya a.clone,
|
31 |
+
.client-sortable .cloneya a.delete {
|
32 |
+
display: none;
|
33 |
+
}
|
34 |
+
|
35 |
+
.client-sortable .cloneya:last-child a.clone,
|
36 |
+
.client-sortable .cloneya:last-child a.delete {
|
37 |
+
display: inline-block;
|
38 |
+
}
|
39 |
+
|
40 |
+
.shapely-media-control img {
|
41 |
+
width: 100%;
|
42 |
+
}
|
43 |
+
|
44 |
+
.shapely-editor-container label {
|
45 |
+
position: relative;
|
46 |
+
top: 30px;
|
47 |
+
}
|
48 |
+
|
49 |
+
.checkbox_switch {
|
50 |
+
margin: 10px auto;
|
51 |
}
|
assets/js/admin.js
CHANGED
@@ -1,113 +1,113 @@
|
|
1 |
-
jQuery( document ).ready(function() {// jscs:ignore validateLineBreaks
|
2 |
-
|
3 |
-
jQuery( '#demo_content .button' ).on('click', function( evt ) {
|
4 |
-
var currentButton = jQuery( this );
|
5 |
-
var ajaxData = { 'action': 'shapely_companion_import_content', 'import': jQuery( this ).data( 'action' ), 'nonce': shapelyCompanion.nonce };
|
6 |
-
evt.preventDefault();
|
7 |
-
jQuery( this ).addClass( 'disabled' );
|
8 |
-
jQuery( this ).next( '.spinner' ).addClass( 'is-active' );
|
9 |
-
jQuery.ajax({
|
10 |
-
type: 'POST',
|
11 |
-
data: ajaxData,
|
12 |
-
url: shapelyCompanion.ajaxurl,
|
13 |
-
success: function( data ) {
|
14 |
-
if ( 'succes' === data ) {
|
15 |
-
currentButton.removeClass( 'disabled' );
|
16 |
-
currentButton.next( '.spinner' ).removeClass( 'is-active' );
|
17 |
-
currentButton.parent().parent().find( '.updated-message' ).show();
|
18 |
-
location.reload();
|
19 |
-
}
|
20 |
-
|
21 |
-
}
|
22 |
-
|
23 |
-
});
|
24 |
-
|
25 |
-
});
|
26 |
-
|
27 |
-
});
|
28 |
-
|
29 |
-
jQuery(function( $ ) {
|
30 |
-
var mediaControl = {
|
31 |
-
|
32 |
-
// Initializes a new media manager or returns an existing frame.
|
33 |
-
// @see wp.media.featuredImage.frame()
|
34 |
-
selector: null,
|
35 |
-
size: null,
|
36 |
-
container: null,
|
37 |
-
frame: function() {
|
38 |
-
if ( this._frame ) {
|
39 |
-
return this._frame;
|
40 |
-
|
41 |
-
}
|
42 |
-
|
43 |
-
this._frame = wp.media({
|
44 |
-
title: 'Media',
|
45 |
-
button: {
|
46 |
-
text: 'Update'
|
47 |
-
},
|
48 |
-
multiple: false
|
49 |
-
});
|
50 |
-
|
51 |
-
this._frame.on( 'open', this.updateFrame ).state( 'library' ).on( 'select', this.select );
|
52 |
-
|
53 |
-
return this._frame;
|
54 |
-
|
55 |
-
},
|
56 |
-
|
57 |
-
select: function() {
|
58 |
-
|
59 |
-
// Do something when the "update" button is clicked after a selection is made.
|
60 |
-
var id = $( '.attachments' ).find( '.selected' ).attr( 'data-id' );
|
61 |
-
var selector = $( '.shapely-media-control' ).find( mediaControl.selector );
|
62 |
-
var data = {
|
63 |
-
action: 'shapely_get_attachment_media',
|
64 |
-
attachment_id: id
|
65 |
-
};
|
66 |
-
|
67 |
-
if ( ! selector.length ) {
|
68 |
-
return false;
|
69 |
-
|
70 |
-
}
|
71 |
-
|
72 |
-
jQuery.post( shapelyCompanion.ajaxurl, data, function( response ) {
|
73 |
-
var ext = response.substr( ( response.lastIndexOf( '.' ) + 1 ) );
|
74 |
-
if ( 'mp4' !== ext ) {
|
75 |
-
$( mediaControl.container ).find( 'img' ).attr( 'src', response );
|
76 |
-
}
|
77 |
-
|
78 |
-
selector.val( response ).trigger('change');
|
79 |
-
|
80 |
-
});
|
81 |
-
|
82 |
-
},
|
83 |
-
|
84 |
-
init: function() {
|
85 |
-
var context = $( '#wpbody, .wp-customizer' );
|
86 |
-
context.on( 'click', '.shapely-media-control > .upload-button', function( e ) {
|
87 |
-
var container = $( this ).parent(),
|
88 |
-
sibling = container.find( '.image-id' ),
|
89 |
-
id = sibling.attr( 'id' );
|
90 |
-
e.preventDefault();
|
91 |
-
mediaControl.size = $( '[data-delegate="' + id + '"]' ).val();
|
92 |
-
mediaControl.container = container;
|
93 |
-
mediaControl.selector = '#' + id;
|
94 |
-
mediaControl.frame().open();
|
95 |
-
|
96 |
-
});
|
97 |
-
|
98 |
-
context.on( 'click', '.shapely-media-control > .remove-button', function( e ) {
|
99 |
-
var container = $( this ).parent(),
|
100 |
-
sibling = container.find( '.image-id' ),
|
101 |
-
img = container.find( 'img' );
|
102 |
-
e.preventDefault();
|
103 |
-
img.attr( 'src', img.attr( 'data-default' ) );
|
104 |
-
sibling.val( '' ).trigger( 'change' );
|
105 |
-
|
106 |
-
});
|
107 |
-
|
108 |
-
}
|
109 |
-
|
110 |
-
};
|
111 |
-
|
112 |
-
mediaControl.init();
|
113 |
-
});
|
1 |
+
jQuery( document ).ready(function() {// jscs:ignore validateLineBreaks
|
2 |
+
|
3 |
+
jQuery( '#demo_content .button' ).on('click', function( evt ) {
|
4 |
+
var currentButton = jQuery( this );
|
5 |
+
var ajaxData = { 'action': 'shapely_companion_import_content', 'import': jQuery( this ).data( 'action' ), 'nonce': shapelyCompanion.nonce };
|
6 |
+
evt.preventDefault();
|
7 |
+
jQuery( this ).addClass( 'disabled' );
|
8 |
+
jQuery( this ).next( '.spinner' ).addClass( 'is-active' );
|
9 |
+
jQuery.ajax({
|
10 |
+
type: 'POST',
|
11 |
+
data: ajaxData,
|
12 |
+
url: shapelyCompanion.ajaxurl,
|
13 |
+
success: function( data ) {
|
14 |
+
if ( 'succes' === data ) {
|
15 |
+
currentButton.removeClass( 'disabled' );
|
16 |
+
currentButton.next( '.spinner' ).removeClass( 'is-active' );
|
17 |
+
currentButton.parent().parent().find( '.updated-message' ).show();
|
18 |
+
location.reload();
|
19 |
+
}
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
+
});
|
24 |
+
|
25 |
+
});
|
26 |
+
|
27 |
+
});
|
28 |
+
|
29 |
+
jQuery(function( $ ) {
|
30 |
+
var mediaControl = {
|
31 |
+
|
32 |
+
// Initializes a new media manager or returns an existing frame.
|
33 |
+
// @see wp.media.featuredImage.frame()
|
34 |
+
selector: null,
|
35 |
+
size: null,
|
36 |
+
container: null,
|
37 |
+
frame: function() {
|
38 |
+
if ( this._frame ) {
|
39 |
+
return this._frame;
|
40 |
+
|
41 |
+
}
|
42 |
+
|
43 |
+
this._frame = wp.media({
|
44 |
+
title: 'Media',
|
45 |
+
button: {
|
46 |
+
text: 'Update'
|
47 |
+
},
|
48 |
+
multiple: false
|
49 |
+
});
|
50 |
+
|
51 |
+
this._frame.on( 'open', this.updateFrame ).state( 'library' ).on( 'select', this.select );
|
52 |
+
|
53 |
+
return this._frame;
|
54 |
+
|
55 |
+
},
|
56 |
+
|
57 |
+
select: function() {
|
58 |
+
|
59 |
+
// Do something when the "update" button is clicked after a selection is made.
|
60 |
+
var id = $( '.attachments' ).find( '.selected' ).attr( 'data-id' );
|
61 |
+
var selector = $( '.shapely-media-control' ).find( mediaControl.selector );
|
62 |
+
var data = {
|
63 |
+
action: 'shapely_get_attachment_media',
|
64 |
+
attachment_id: id
|
65 |
+
};
|
66 |
+
|
67 |
+
if ( ! selector.length ) {
|
68 |
+
return false;
|
69 |
+
|
70 |
+
}
|
71 |
+
|
72 |
+
jQuery.post( shapelyCompanion.ajaxurl, data, function( response ) {
|
73 |
+
var ext = response.substr( ( response.lastIndexOf( '.' ) + 1 ) );
|
74 |
+
if ( 'mp4' !== ext ) {
|
75 |
+
$( mediaControl.container ).find( 'img' ).attr( 'src', response );
|
76 |
+
}
|
77 |
+
|
78 |
+
selector.val( response ).trigger('change');
|
79 |
+
|
80 |
+
});
|
81 |
+
|
82 |
+
},
|
83 |
+
|
84 |
+
init: function() {
|
85 |
+
var context = $( '#wpbody, .wp-customizer' );
|
86 |
+
context.on( 'click', '.shapely-media-control > .upload-button', function( e ) {
|
87 |
+
var container = $( this ).parent(),
|
88 |
+
sibling = container.find( '.image-id' ),
|
89 |
+
id = sibling.attr( 'id' );
|
90 |
+
e.preventDefault();
|
91 |
+
mediaControl.size = $( '[data-delegate="' + id + '"]' ).val();
|
92 |
+
mediaControl.container = container;
|
93 |
+
mediaControl.selector = '#' + id;
|
94 |
+
mediaControl.frame().open();
|
95 |
+
|
96 |
+
});
|
97 |
+
|
98 |
+
context.on( 'click', '.shapely-media-control > .remove-button', function( e ) {
|
99 |
+
var container = $( this ).parent(),
|
100 |
+
sibling = container.find( '.image-id' ),
|
101 |
+
img = container.find( 'img' );
|
102 |
+
e.preventDefault();
|
103 |
+
img.attr( 'src', img.attr( 'data-default' ) );
|
104 |
+
sibling.val( '' ).trigger( 'change' );
|
105 |
+
|
106 |
+
});
|
107 |
+
|
108 |
+
}
|
109 |
+
|
110 |
+
};
|
111 |
+
|
112 |
+
mediaControl.init();
|
113 |
+
});
|
assets/js/nav-menu.js
CHANGED
@@ -1,46 +1,46 @@
|
|
1 |
-
(function( $ ) {// jscs:ignore validateLineBreaks
|
2 |
-
|
3 |
-
'use strict';
|
4 |
-
var api;
|
5 |
-
|
6 |
-
api = wpNavMenu;
|
7 |
-
|
8 |
-
$( '#submit-shapelysection' ).on('click', function( evt ) {
|
9 |
-
var section = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-widget' ).val(),
|
10 |
-
label = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-name' ).val(),
|
11 |
-
url = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-url' ).val();
|
12 |
-
|
13 |
-
evt.preventDefault();
|
14 |
-
|
15 |
-
if ( '0' === section || '' === label || '' === url ) {
|
16 |
-
$( '#shapelysectionsdiv' ).addClass( 'form-invalid' );
|
17 |
-
return false;
|
18 |
-
}
|
19 |
-
|
20 |
-
$( '.customlinkdiv .spinner' ).addClass( 'is-active' );
|
21 |
-
|
22 |
-
api.addItemToMenu( {
|
23 |
-
'-1': {
|
24 |
-
'menu-item-type': 'custom',
|
25 |
-
'menu-item-extra': 'shapely-section',
|
26 |
-
'menu-item-url': url,
|
27 |
-
'menu-item-widget': section,
|
28 |
-
'menu-item-title': label
|
29 |
-
}
|
30 |
-
}, api.addMenuItemToBottom, shapelyMenuAdded );
|
31 |
-
|
32 |
-
} );
|
33 |
-
|
34 |
-
function shapelyMenuAdded() {
|
35 |
-
|
36 |
-
// Remove the ajax spinner
|
37 |
-
$( '#shapelysectionsdiv .spinner' ).removeClass( 'is-active' );
|
38 |
-
|
39 |
-
// Set custom link form back to defaults
|
40 |
-
$( '#shapelysectionsdiv #shapely-section-item-widget' ).val( '0' ).trigger('blur');
|
41 |
-
$( '#shapelysectionsdiv #shapely-section-item-url' ).val( '' ).trigger('blur');
|
42 |
-
$( '#shapelysectionsdiv #shapely-section-item-name' ).val( '' ).trigger('blur');
|
43 |
-
|
44 |
-
}
|
45 |
-
|
46 |
-
})( jQuery );
|
1 |
+
(function( $ ) {// jscs:ignore validateLineBreaks
|
2 |
+
|
3 |
+
'use strict';
|
4 |
+
var api;
|
5 |
+
|
6 |
+
api = wpNavMenu;
|
7 |
+
|
8 |
+
$( '#submit-shapelysection' ).on('click', function( evt ) {
|
9 |
+
var section = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-widget' ).val(),
|
10 |
+
label = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-name' ).val(),
|
11 |
+
url = $( '#shapelysectionsdiv' ).find( '#shapely-section-item-url' ).val();
|
12 |
+
|
13 |
+
evt.preventDefault();
|
14 |
+
|
15 |
+
if ( '0' === section || '' === label || '' === url ) {
|
16 |
+
$( '#shapelysectionsdiv' ).addClass( 'form-invalid' );
|
17 |
+
return false;
|
18 |
+
}
|
19 |
+
|
20 |
+
$( '.customlinkdiv .spinner' ).addClass( 'is-active' );
|
21 |
+
|
22 |
+
api.addItemToMenu( {
|
23 |
+
'-1': {
|
24 |
+
'menu-item-type': 'custom',
|
25 |
+
'menu-item-extra': 'shapely-section',
|
26 |
+
'menu-item-url': url,
|
27 |
+
'menu-item-widget': section,
|
28 |
+
'menu-item-title': label
|
29 |
+
}
|
30 |
+
}, api.addMenuItemToBottom, shapelyMenuAdded );
|
31 |
+
|
32 |
+
} );
|
33 |
+
|
34 |
+
function shapelyMenuAdded() {
|
35 |
+
|
36 |
+
// Remove the ajax spinner
|
37 |
+
$( '#shapelysectionsdiv .spinner' ).removeClass( 'is-active' );
|
38 |
+
|
39 |
+
// Set custom link form back to defaults
|
40 |
+
$( '#shapelysectionsdiv #shapely-section-item-widget' ).val( '0' ).trigger('blur');
|
41 |
+
$( '#shapelysectionsdiv #shapely-section-item-url' ).val( '' ).trigger('blur');
|
42 |
+
$( '#shapelysectionsdiv #shapely-section-item-name' ).val( '' ).trigger('blur');
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
})( jQuery );
|
assets/js/previewer.js
CHANGED
@@ -1,74 +1,74 @@
|
|
1 |
-
(function( $ ) {// jscs:ignore validateLineBreaks
|
2 |
-
|
3 |
-
'use strict';
|
4 |
-
|
5 |
-
$( document ).ready( function() {
|
6 |
-
if ( 'undefined' === typeof wp || ! wp.customize || ! wp.customize.selectiveRefresh ) {
|
7 |
-
return;
|
8 |
-
}
|
9 |
-
|
10 |
-
wp.customize.selectiveRefresh.bind( 'widget-updated', function( placement ) {
|
11 |
-
var maxHeight, container, msnry, element;
|
12 |
-
$( '.logo-carousel' ).flexslider( {
|
13 |
-
minItems: 1,
|
14 |
-
maxItems: 4,
|
15 |
-
move: 1,
|
16 |
-
itemWidth: 200,
|
17 |
-
itemMargin: 0,
|
18 |
-
animation: 'slide',
|
19 |
-
slideshow: true,
|
20 |
-
slideshowSpeed: 3000,
|
21 |
-
directionNav: false,
|
22 |
-
controlNav: false
|
23 |
-
} );
|
24 |
-
|
25 |
-
if ( 'function' === typeof $( '.parallax-window' ).parallax ) {
|
26 |
-
$( '.parallax-window' ).parallax();
|
27 |
-
}
|
28 |
-
|
29 |
-
if ( $( '.masonry' ).length && 'undefined' !== typeof Masonry ) {
|
30 |
-
container = document.querySelector( '.masonry' );
|
31 |
-
msnry = new Masonry( container, {
|
32 |
-
itemSelector: '.masonry-item'
|
33 |
-
} );
|
34 |
-
maxHeight = -1;
|
35 |
-
msnry.on( 'layoutComplete', function() {
|
36 |
-
var element = jQuery( msnry.element ),
|
37 |
-
cols = element.find( '.masonry-item img' );
|
38 |
-
jQuery.each( cols, function() {
|
39 |
-
if ( parseInt( jQuery( this ).attr( 'height' ), 10 ) > maxHeight ) {
|
40 |
-
maxHeight = parseInt( jQuery( this ).attr( 'height' ), 10 );
|
41 |
-
}
|
42 |
-
} );
|
43 |
-
|
44 |
-
} );
|
45 |
-
|
46 |
-
msnry.layout();
|
47 |
-
element = jQuery( msnry.element );
|
48 |
-
|
49 |
-
jQuery( element ).css( 'height', maxHeight + 'px' );
|
50 |
-
}
|
51 |
-
|
52 |
-
if ( 0 !== jQuery( '.testimonial-section' ).length ) {
|
53 |
-
testimonialHeight();
|
54 |
-
setTimeout( function() {
|
55 |
-
testimonialHeight();
|
56 |
-
}, 3000 );
|
57 |
-
}
|
58 |
-
|
59 |
-
$( '.slider-arrow-controls' ).flexslider( {
|
60 |
-
controlNav: false
|
61 |
-
} );
|
62 |
-
|
63 |
-
/*
|
64 |
-
* Resetting testimonial parallax height
|
65 |
-
*/
|
66 |
-
function testimonialHeight() {
|
67 |
-
var testimonialHeight = jQuery( '.testimonial-section .parallax-window .container' ).outerHeight() + 150;
|
68 |
-
jQuery( '.testimonial-section .parallax-window' ).css( 'height', testimonialHeight );
|
69 |
-
jQuery( window ).trigger( 'resize' ).trigger( 'scroll' );
|
70 |
-
}
|
71 |
-
} );
|
72 |
-
} );
|
73 |
-
|
74 |
-
})( jQuery );
|
1 |
+
(function( $ ) {// jscs:ignore validateLineBreaks
|
2 |
+
|
3 |
+
'use strict';
|
4 |
+
|
5 |
+
$( document ).ready( function() {
|
6 |
+
if ( 'undefined' === typeof wp || ! wp.customize || ! wp.customize.selectiveRefresh ) {
|
7 |
+
return;
|
8 |
+
}
|
9 |
+
|
10 |
+
wp.customize.selectiveRefresh.bind( 'widget-updated', function( placement ) {
|
11 |
+
var maxHeight, container, msnry, element;
|
12 |
+
$( '.logo-carousel' ).flexslider( {
|
13 |
+
minItems: 1,
|
14 |
+
maxItems: 4,
|
15 |
+
move: 1,
|
16 |
+
itemWidth: 200,
|
17 |
+
itemMargin: 0,
|
18 |
+
animation: 'slide',
|
19 |
+
slideshow: true,
|
20 |
+
slideshowSpeed: 3000,
|
21 |
+
directionNav: false,
|
22 |
+
controlNav: false
|
23 |
+
} );
|
24 |
+
|
25 |
+
if ( 'function' === typeof $( '.parallax-window' ).parallax ) {
|
26 |
+
$( '.parallax-window' ).parallax();
|
27 |
+
}
|
28 |
+
|
29 |
+
if ( $( '.masonry' ).length && 'undefined' !== typeof Masonry ) {
|
30 |
+
container = document.querySelector( '.masonry' );
|
31 |
+
msnry = new Masonry( container, {
|
32 |
+
itemSelector: '.masonry-item'
|
33 |
+
} );
|
34 |
+
maxHeight = -1;
|
35 |
+
msnry.on( 'layoutComplete', function() {
|
36 |
+
var element = jQuery( msnry.element ),
|
37 |
+
cols = element.find( '.masonry-item img' );
|
38 |
+
jQuery.each( cols, function() {
|
39 |
+
if ( parseInt( jQuery( this ).attr( 'height' ), 10 ) > maxHeight ) {
|
40 |
+
maxHeight = parseInt( jQuery( this ).attr( 'height' ), 10 );
|
41 |
+
}
|
42 |
+
} );
|
43 |
+
|
44 |
+
} );
|
45 |
+
|
46 |
+
msnry.layout();
|
47 |
+
element = jQuery( msnry.element );
|
48 |
+
|
49 |
+
jQuery( element ).css( 'height', maxHeight + 'px' );
|
50 |
+
}
|
51 |
+
|
52 |
+
if ( 0 !== jQuery( '.testimonial-section' ).length ) {
|
53 |
+
testimonialHeight();
|
54 |
+
setTimeout( function() {
|
55 |
+
testimonialHeight();
|
56 |
+
}, 3000 );
|
57 |
+
}
|
58 |
+
|
59 |
+
$( '.slider-arrow-controls' ).flexslider( {
|
60 |
+
controlNav: false
|
61 |
+
} );
|
62 |
+
|
63 |
+
/*
|
64 |
+
* Resetting testimonial parallax height
|
65 |
+
*/
|
66 |
+
function testimonialHeight() {
|
67 |
+
var testimonialHeight = jQuery( '.testimonial-section .parallax-window .container' ).outerHeight() + 150;
|
68 |
+
jQuery( '.testimonial-section .parallax-window' ).css( 'height', testimonialHeight );
|
69 |
+
jQuery( window ).trigger( 'resize' ).trigger( 'scroll' );
|
70 |
+
}
|
71 |
+
} );
|
72 |
+
} );
|
73 |
+
|
74 |
+
})( jQuery );
|
assets/js/vendor/jquery-cloneya.js
CHANGED
@@ -1,518 +1,518 @@
|
|
1 |
-
/**
|
2 |
-
* CloneYa!: Plugin to clone form elements in a nested manner
|
3 |
-
* @author Saurabh Shukla <saurabh@yapapaya.com>
|
4 |
-
* http://hookrefineandtinker.com
|
5 |
-
* License GNU/GPL & MIT
|
6 |
-
*/
|
7 |
-
|
8 |
-
(function( $ ) {
|
9 |
-
|
10 |
-
"use strict";
|
11 |
-
|
12 |
-
var name = "cloneya", defaults = {
|
13 |
-
cloneThis: '.toclone',
|
14 |
-
cloneButton: '.clone',
|
15 |
-
deleteButton: '.delete',
|
16 |
-
clonePosition: 'after',
|
17 |
-
minimum: 1,
|
18 |
-
// renaming limit
|
19 |
-
maximum: 999, //setting it to a high number, by default
|
20 |
-
|
21 |
-
//limit: 999,
|
22 |
-
|
23 |
-
valueClone: false,
|
24 |
-
dataClone: false,
|
25 |
-
deepClone: false,
|
26 |
-
serializeID: true,
|
27 |
-
ignore: 'label.error',
|
28 |
-
preserveChildCount: false
|
29 |
-
};
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Create the class CloneYa
|
33 |
-
*
|
34 |
-
* @class CloneYa
|
35 |
-
* @classdesc Adds cloning functionality to element
|
36 |
-
*
|
37 |
-
* @param {String | Object} element - the clone wrapper
|
38 |
-
*
|
39 |
-
* @param {Object} options - options to initialise with
|
40 |
-
*
|
41 |
-
* @param {String} options.cloneThis - Selector for the clone element
|
42 |
-
* @param {String} options.cloneButton - Selector for the clone button
|
43 |
-
* @param {String} options.deleteButton - Selector for the delete button
|
44 |
-
*
|
45 |
-
* @param {String} options.clonePosition - Where should the clone be added 'before' or 'after'
|
46 |
-
*
|
47 |
-
* @param {Number} options.limit - The maximum number of clones
|
48 |
-
*
|
49 |
-
* @param {Boolean} options.valueClone - Clone the input values as well?
|
50 |
-
* @param {Boolean} options.dataClone - Clone the data attributes?
|
51 |
-
* @param {Boolean} options.deepClone - Clone other data added to the jQuery object
|
52 |
-
*
|
53 |
-
* @param {Boolean} options.serializeID - Whether to serialize the IDs, automatically
|
54 |
-
* @param {String} options.ignore - Selectors for clonables' elements that should not be cloned
|
55 |
-
* @param {Boolean} options.defaultRender - Start with this number of clones, by default
|
56 |
-
* @param {Boolean} options.preserveChildCount - whether to preserve the initial number of clone's child clones, works with nesting as well.
|
57 |
-
*
|
58 |
-
* @returns {_L13.CloneYa}
|
59 |
-
*/
|
60 |
-
function CloneYa( element, options ) {
|
61 |
-
/**
|
62 |
-
* regex for recalculating the ids
|
63 |
-
*
|
64 |
-
* @type RegExp
|
65 |
-
*/
|
66 |
-
this.regex = /^(.*)(\d)+$/i;
|
67 |
-
|
68 |
-
this.elem = element;
|
69 |
-
|
70 |
-
this.$elem = $( element );
|
71 |
-
|
72 |
-
this.elemClass = name + '-wrap';
|
73 |
-
|
74 |
-
/**
|
75 |
-
* creating a jQuery object, just in case
|
76 |
-
*
|
77 |
-
* @type @call;$
|
78 |
-
*/
|
79 |
-
//var elem = $(element);
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Support deprecated parameters
|
83 |
-
*/
|
84 |
-
if ( typeof options !== 'undefined' ) {
|
85 |
-
if ( typeof options.limit !== 'undefined' && options.limit > 0 ) {
|
86 |
-
options.maximum = options.limit;
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
/**
|
91 |
-
* merge the passed options object with defaults
|
92 |
-
*
|
93 |
-
* @type @exp;$@call;extend
|
94 |
-
*/
|
95 |
-
this.config = $.extend( {}, defaults, options );
|
96 |
-
|
97 |
-
/**
|
98 |
-
*
|
99 |
-
* @type @exp;elem@call;closestChild
|
100 |
-
*/
|
101 |
-
this.clones = this.$elem.closestChild( this.config.cloneThis );
|
102 |
-
|
103 |
-
this.init();
|
104 |
-
|
105 |
-
}
|
106 |
-
|
107 |
-
CloneYa.prototype = {
|
108 |
-
init: function() {
|
109 |
-
|
110 |
-
var $this = this;
|
111 |
-
|
112 |
-
// add our classes
|
113 |
-
$this.$elem.addClass( $this.elemClass );
|
114 |
-
$this.clones.addClass( name );
|
115 |
-
|
116 |
-
// save the sibling count into data attr
|
117 |
-
$this.clones.data( 'initialCount', $this.clones.length );
|
118 |
-
|
119 |
-
//Now, what if the clone button and delete button are not contained in
|
120 |
-
//the clonable?
|
121 |
-
// add a click handler for the clone buttons
|
122 |
-
$this.$elem.on( 'click.' + name, $this.config.cloneThis + '>' + $this.config.cloneButton, function( event ) {
|
123 |
-
event.preventDefault();
|
124 |
-
event.stopPropagation();
|
125 |
-
|
126 |
-
var toClone = $( this ).closest( $this.config.cloneThis );
|
127 |
-
|
128 |
-
// this is just a wrapper for the custom clone event
|
129 |
-
$this.$elem.triggerAll( 'clone_clone clone.' + name, [ toClone ] );
|
130 |
-
} );
|
131 |
-
|
132 |
-
// the custom clone event
|
133 |
-
$this.$elem.on( 'clone.' + name, function( event, toClone ) {
|
134 |
-
if ( event.namespace === name ) {
|
135 |
-
$this._cloneAndAppend( toClone );
|
136 |
-
}
|
137 |
-
} );
|
138 |
-
|
139 |
-
// click handler for delete button
|
140 |
-
$this.$elem.on( 'click.' + name, $this.config.cloneThis + '>' + $this.config.deleteButton, function( event ) {
|
141 |
-
event.preventDefault();
|
142 |
-
event.stopPropagation();
|
143 |
-
|
144 |
-
var toDelete = $( this ).closest( $this.config.cloneThis );
|
145 |
-
// just a wrapper for delclone event
|
146 |
-
$this.$elem.triggerAll( 'clone_delete delete.' + name, [ toDelete ] );
|
147 |
-
} );
|
148 |
-
|
149 |
-
// the delete clone event
|
150 |
-
$this.$elem.on( 'delete.' + name, function( event, toDelete ) {
|
151 |
-
|
152 |
-
// get the count of all the sibling clones
|
153 |
-
/**
|
154 |
-
*
|
155 |
-
* @type @exp;$todelete@call;closest@call;closestChild@pro;length
|
156 |
-
*/
|
157 |
-
var cloneCount = toDelete.closest( '.' + $this.elemClass ).closestChild( $this.config.cloneThis ).length;
|
158 |
-
|
159 |
-
if ( cloneCount > $this.config.minimum ) {
|
160 |
-
// trigger hook
|
161 |
-
$this.$elem.triggerAll( 'clone_before_delete before_delete.' + name, [ toDelete, cloneCount ] );
|
162 |
-
$this.$elem.triggerHandler( 'remove.' + name, [ toDelete ] );
|
163 |
-
$this.$elem.triggerAll( 'clone_after_delete after_delete.' + name );
|
164 |
-
|
165 |
-
}
|
166 |
-
else {
|
167 |
-
|
168 |
-
$this.$elem.triggerHandler( 'minimum.' + name, $this.config.minimum, [ toDelete ] );
|
169 |
-
|
170 |
-
// First clone form can't be deleted, but the values should be removed from first form
|
171 |
-
// is this expected behaviour? especially since we use minimum?
|
172 |
-
toDelete.find( 'input, textarea, select' ).each( function() {
|
173 |
-
$this._clearForm( $( this ) );
|
174 |
-
} );
|
175 |
-
|
176 |
-
}
|
177 |
-
} );
|
178 |
-
|
179 |
-
$this.$elem.on( 'remove.' + name, function( event, toDelete ) {
|
180 |
-
$( toDelete ).remove();
|
181 |
-
|
182 |
-
} );
|
183 |
-
|
184 |
-
},
|
185 |
-
_clean: function() {
|
186 |
-
var $this = this;
|
187 |
-
$this.$elem.removeClass( name + '-wrap' );
|
188 |
-
$this.clones.removeClass( name );
|
189 |
-
$this.$elem.off( 'click.' + name, $this.config.cloneThis + '>' + $this.config.cloneButton );
|
190 |
-
$this.$elem.off( 'click.' + name, $this.config.cloneThis + '>' + $this.config.deleteButton );
|
191 |
-
$this.$elem.off( 'clone_clone clone_delete clone_before_delete clone.' + name + ' delete.' + name + ' before_delete.' + name );
|
192 |
-
|
193 |
-
},
|
194 |
-
destroy: function() {
|
195 |
-
this._clean();
|
196 |
-
this.$elem.removeData( name );
|
197 |
-
},
|
198 |
-
getOption: function() {
|
199 |
-
return this.config;
|
200 |
-
},
|
201 |
-
setOption: function( lateOptions ) {
|
202 |
-
$.extend( this.config, lateOptions || {} );
|
203 |
-
this._clean();
|
204 |
-
this.init();
|
205 |
-
|
206 |
-
},
|
207 |
-
_cloneAndAppend: function( toClone ) {
|
208 |
-
|
209 |
-
|
210 |
-
// get the count of all the sibling clones
|
211 |
-
/**
|
212 |
-
*
|
213 |
-
* @type @exp;$toclone@call;closest@call;closestChild@pro;length
|
214 |
-
*/
|
215 |
-
var cloneCount = toClone.closest( '.' + this.elemClass ).closestChild( this.config.cloneThis ).length;
|
216 |
-
|
217 |
-
// check if we've reached the maximum limit
|
218 |
-
if ( cloneCount < this.config.maximum ) {
|
219 |
-
|
220 |
-
// trigger a custom event for hooking in
|
221 |
-
this.$elem.triggerAll( 'clone_before_clone before_clone.' + name, [ toClone ] );
|
222 |
-
|
223 |
-
var newClone = this._cloneItem( toClone );
|
224 |
-
|
225 |
-
// trigger custom event on the original element
|
226 |
-
this.$elem.triggerAll( 'clone_after_clone after_clone.' + name, [ toClone, newClone ] );
|
227 |
-
|
228 |
-
// add to our clones object
|
229 |
-
this.clones.add( newClone );
|
230 |
-
|
231 |
-
// trigger custom event on the new clone
|
232 |
-
this.$elem.triggerAll( 'clone_before_append before_append.' + name, [ toClone, newClone ] );
|
233 |
-
|
234 |
-
// get the position where the clone has to be added
|
235 |
-
// and add the newclone
|
236 |
-
if ( this.config.clonePosition !== 'after' ) {
|
237 |
-
toClone.before( newClone );
|
238 |
-
} else {
|
239 |
-
toClone.after( newClone );
|
240 |
-
|
241 |
-
}
|
242 |
-
|
243 |
-
if ( this.config.ignore ) {
|
244 |
-
newClone.find( this.config.ignore ).remove();
|
245 |
-
}
|
246 |
-
|
247 |
-
// reformat the id attributes
|
248 |
-
this._redoIDs();
|
249 |
-
|
250 |
-
// trigger custom event for hooking
|
251 |
-
this.$elem.triggerAll( 'clone_after_append after_append.' + name, [ toClone, newClone ] );
|
252 |
-
} else {
|
253 |
-
// trigger a custom event for hooking
|
254 |
-
this.$elem.triggerAll( 'clone_limit maximum.' + name, this.config.maximum, [ toClone ] );
|
255 |
-
}
|
256 |
-
|
257 |
-
},
|
258 |
-
_cloneItem: function( toClone ) {
|
259 |
-
var $this = this;
|
260 |
-
|
261 |
-
// clone it
|
262 |
-
/**
|
263 |
-
*
|
264 |
-
* @type @exp;$toclone@call;clone
|
265 |
-
*/
|
266 |
-
var newClone = toClone.clone( $this.config.dataClone, $this.config.deepClone );
|
267 |
-
|
268 |
-
// we want to preserve the initial child count
|
269 |
-
if ( $this.config.preserveChildCount !== false ) {
|
270 |
-
// the child count only needs preservation if they are clonable.
|
271 |
-
|
272 |
-
var originalChildren = toClone.find( '.' + name + '-wrap' );
|
273 |
-
|
274 |
-
// for each wrapper
|
275 |
-
newClone.find( '.' + name + '-wrap' ).each( function( index ) {
|
276 |
-
|
277 |
-
/**
|
278 |
-
*
|
279 |
-
* @type @call;jquery-cloneya_L8.$@call;closestChild
|
280 |
-
*/
|
281 |
-
var inNewClone = $( this ).closestChild( '.' + name );
|
282 |
-
|
283 |
-
var inOriginal = $( originalChildren[ index ] ).closestChild( '.' + name );
|
284 |
-
|
285 |
-
/**
|
286 |
-
*
|
287 |
-
* @type @exp;inOriginal@call;data
|
288 |
-
*/
|
289 |
-
var originalCount = inOriginal.data( 'initialCount' );
|
290 |
-
|
291 |
-
/**
|
292 |
-
*
|
293 |
-
* @type @exp;inNewClone@call;slice
|
294 |
-
*/
|
295 |
-
var $extra = inNewClone.slice( originalCount, inNewClone.length );
|
296 |
-
|
297 |
-
$extra.remove();
|
298 |
-
|
299 |
-
inNewClone.data( 'initial-count', originalCount );
|
300 |
-
} );
|
301 |
-
|
302 |
-
}
|
303 |
-
|
304 |
-
// get the form input
|
305 |
-
newClone.find( 'input, textarea, select' ).each( function() {
|
306 |
-
|
307 |
-
// check if the values need to be copied, if not empty them
|
308 |
-
$this._clearForm( $( this ) );
|
309 |
-
|
310 |
-
// removed the portion taking care of the index
|
311 |
-
// each case is specific and I'd rather leave it to the developer
|
312 |
-
|
313 |
-
// custom event hook for index handling
|
314 |
-
$this.$elem.triggerAll( 'clone_form_input form_input.' + name, [ $( this ), toClone, newClone ] );
|
315 |
-
} );
|
316 |
-
|
317 |
-
return newClone;
|
318 |
-
|
319 |
-
},
|
320 |
-
/*
|
321 |
-
* Clear Form will used to clear the values of the form
|
322 |
-
*/
|
323 |
-
/**
|
324 |
-
*
|
325 |
-
* @param {type} $el
|
326 |
-
* @returns {undefined}
|
327 |
-
*/
|
328 |
-
_clearForm: function( $el ) {
|
329 |
-
|
330 |
-
if ( !this.config.valueClone && !$el.hasClass( 'noEmpty' ) ) {
|
331 |
-
|
332 |
-
if ( $el.is( ':checkbox' ) || $el.is( ':radio' ) ) {
|
333 |
-
|
334 |
-
$el.prop( 'checked', false );
|
335 |
-
}
|
336 |
-
else {
|
337 |
-
$el.val( '' );
|
338 |
-
}
|
339 |
-
|
340 |
-
}
|
341 |
-
|
342 |
-
},
|
343 |
-
/**
|
344 |
-
* Redo the id attribute, serially
|
345 |
-
*/
|
346 |
-
/**
|
347 |
-
*
|
348 |
-
* @returns {undefined}
|
349 |
-
*/
|
350 |
-
_redoIDs: function() {
|
351 |
-
|
352 |
-
var $this = this;
|
353 |
-
|
354 |
-
// check if this even needs to be done
|
355 |
-
if ( $this.config.serializeID !== true ) {
|
356 |
-
return;
|
357 |
-
}
|
358 |
-
|
359 |
-
// get the id of the first clone (hoping to increment the ids)
|
360 |
-
/**
|
361 |
-
*
|
362 |
-
* @type @exp;elem@call;find@call;first@call;attr
|
363 |
-
*/
|
364 |
-
var mainid = $this.$elem.find( $this.config.cloneThis ).first().attr( 'id' );
|
365 |
-
|
366 |
-
$this.$elem.find( $this.config.cloneThis ).each( function( i ) {
|
367 |
-
|
368 |
-
var j;
|
369 |
-
// assign the index to a string var for appending to the ids
|
370 |
-
// 0 index will have no number at the end
|
371 |
-
if ( i !== 0 ) {
|
372 |
-
j = i;
|
373 |
-
} else {
|
374 |
-
j = '';
|
375 |
-
}
|
376 |
-
|
377 |
-
// first modify the clone id
|
378 |
-
if ( $( this ).attr( 'id' ) ) {
|
379 |
-
$( this ).attr( 'id', mainid + j );
|
380 |
-
}
|
381 |
-
|
382 |
-
var id, nId;
|
383 |
-
// take all the elements inside the clone
|
384 |
-
$( this ).find( '*' ).each( function() {
|
385 |
-
|
386 |
-
id = $( this ).attr( 'id' );
|
387 |
-
if ( id ) {
|
388 |
-
// match the id with the regex to get the string part
|
389 |
-
// separate from the number part
|
390 |
-
var match = id.match( $this.regex );
|
391 |
-
|
392 |
-
// if there was a number
|
393 |
-
if ( match && match.length === 3 ) {
|
394 |
-
// just take the string part
|
395 |
-
// add the new number to it
|
396 |
-
nId = id.replace( /\d+$/, "" ) + j;
|
397 |
-
|
398 |
-
$( this ).attr( 'id', nId );
|
399 |
-
} else {
|
400 |
-
// else there was no number,
|
401 |
-
// this was earlier the first element
|
402 |
-
// just add the number to its id
|
403 |
-
nId = id + j;
|
404 |
-
$( this ).attr( 'id', nId );
|
405 |
-
}
|
406 |
-
}
|
407 |
-
|
408 |
-
//update label
|
409 |
-
$( this ).closest( $this.config.cloneThis ).find( "label[for='" + id + "']" ).attr( 'for', nId );
|
410 |
-
|
411 |
-
if ( $this.config.serializeIndex ) {
|
412 |
-
var name = $( this ).attr( 'name' );
|
413 |
-
// This will increment the numeric array index for cloned field names
|
414 |
-
if ( name ) {
|
415 |
-
var matches = name.match( /\[([0-9}]+)\]/ );
|
416 |
-
|
417 |
-
if ( matches && matches.length >= 1 ) {
|
418 |
-
|
419 |
-
var st = name;
|
420 |
-
var name = st.replace( matches[ 0 ], "[" + i + "]" );
|
421 |
-
|
422 |
-
$( this ).attr( 'name', name );
|
423 |
-
}
|
424 |
-
}
|
425 |
-
}
|
426 |
-
|
427 |
-
} );
|
428 |
-
} );
|
429 |
-
|
430 |
-
}
|
431 |
-
|
432 |
-
};
|
433 |
-
|
434 |
-
// add the cloneya to the global object
|
435 |
-
/**
|
436 |
-
*
|
437 |
-
* @param {type} options
|
438 |
-
* @returns {jquery-cloneya_L8.$.fn@call;each}
|
439 |
-
*/
|
440 |
-
$.fn[ name ] = function( options ) {
|
441 |
-
var args = arguments;
|
442 |
-
|
443 |
-
if ( options === undefined || typeof options === 'object' ) {
|
444 |
-
// Creates a new plugin instance, for each selected element, and
|
445 |
-
// stores a reference withint the element's data
|
446 |
-
return this.each( function() {
|
447 |
-
if ( !$.data( this, name ) ) {
|
448 |
-
$.data( this, name, new CloneYa( this, options ) );
|
449 |
-
}
|
450 |
-
} );
|
451 |
-
} else if ( typeof options === 'string' && options[ 0 ] !== '_' && options !== 'init' ) {
|
452 |
-
// Call a public pluguin method (not starting with an underscore) for each
|
453 |
-
// selected element.
|
454 |
-
if ( Array.prototype.slice.call( args, 1 ).length === 0 && $.inArray( options, $.fn[ name ].getters ) !== -1 ) {
|
455 |
-
// If the user does not pass any arguments and the method allows to
|
456 |
-
// work as a getter then break the chainability so we can return a value
|
457 |
-
// instead the element reference.
|
458 |
-
var instance = $.data( this[ 0 ], name );
|
459 |
-
return instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
|
460 |
-
} else {
|
461 |
-
// Invoke the speficied method on each selected element
|
462 |
-
return this.each( function() {
|
463 |
-
var instance = $.data( this, name );
|
464 |
-
if ( instance instanceof CloneYa && typeof instance[ options ] === 'function' ) {
|
465 |
-
instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
|
466 |
-
}
|
467 |
-
} );
|
468 |
-
}
|
469 |
-
}
|
470 |
-
};
|
471 |
-
|
472 |
-
$.fn[ name ].getters = [ 'getOption' ];
|
473 |
-
|
474 |
-
/*
|
475 |
-
* jquery.closestchild 0.1.1
|
476 |
-
*
|
477 |
-
* Author: Andrey Mikhaylov aka lolmaus
|
478 |
-
* Email: lolmaus@gmail.com
|
479 |
-
*
|
480 |
-
*/
|
481 |
-
/**
|
482 |
-
*
|
483 |
-
* @param {type} selector
|
484 |
-
* @returns {$}
|
485 |
-
*/
|
486 |
-
$.fn.closestChild = function( selector ) {
|
487 |
-
var $children, $results;
|
488 |
-
|
489 |
-
$children = this.children();
|
490 |
-
|
491 |
-
if ( $children.length === 0 ) {
|
492 |
-
return $();
|
493 |
-
}
|
494 |
-
|
495 |
-
$results = $children.filter( selector );
|
496 |
-
|
497 |
-
if ( $results.length > 0 ) {
|
498 |
-
return $results;
|
499 |
-
} else {
|
500 |
-
return $children.closestChild( selector );
|
501 |
-
}
|
502 |
-
};
|
503 |
-
|
504 |
-
/*
|
505 |
-
* TriggerAll, modified from stackoverflow
|
506 |
-
* http://stackoverflow.com/questions/11850625/jquery-trigger-multiple-events
|
507 |
-
*/
|
508 |
-
$.fn.extend( {
|
509 |
-
triggerAll: function( events, params ) {
|
510 |
-
var el = this, i, evts = events.split( ' ' );
|
511 |
-
for ( i = 0; i < evts.length; i += 1 ) {
|
512 |
-
el.triggerHandler( evts[ i ], params );
|
513 |
-
}
|
514 |
-
return el;
|
515 |
-
}
|
516 |
-
} );
|
517 |
-
|
518 |
})( jQuery );
|
1 |
+
/**
|
2 |
+
* CloneYa!: Plugin to clone form elements in a nested manner
|
3 |
+
* @author Saurabh Shukla <saurabh@yapapaya.com>
|
4 |
+
* http://hookrefineandtinker.com
|
5 |
+
* License GNU/GPL & MIT
|
6 |
+
*/
|
7 |
+
|
8 |
+
(function( $ ) {
|
9 |
+
|
10 |
+
"use strict";
|
11 |
+
|
12 |
+
var name = "cloneya", defaults = {
|
13 |
+
cloneThis: '.toclone',
|
14 |
+
cloneButton: '.clone',
|
15 |
+
deleteButton: '.delete',
|
16 |
+
clonePosition: 'after',
|
17 |
+
minimum: 1,
|
18 |
+
// renaming limit
|
19 |
+
maximum: 999, //setting it to a high number, by default
|
20 |
+
|
21 |
+
//limit: 999,
|
22 |
+
|
23 |
+
valueClone: false,
|
24 |
+
dataClone: false,
|
25 |
+
deepClone: false,
|
26 |
+
serializeID: true,
|
27 |
+
ignore: 'label.error',
|
28 |
+
preserveChildCount: false
|
29 |
+
};
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Create the class CloneYa
|
33 |
+
*
|
34 |
+
* @class CloneYa
|
35 |
+
* @classdesc Adds cloning functionality to element
|
36 |
+
*
|
37 |
+
* @param {String | Object} element - the clone wrapper
|
38 |
+
*
|
39 |
+
* @param {Object} options - options to initialise with
|
40 |
+
*
|
41 |
+
* @param {String} options.cloneThis - Selector for the clone element
|
42 |
+
* @param {String} options.cloneButton - Selector for the clone button
|
43 |
+
* @param {String} options.deleteButton - Selector for the delete button
|
44 |
+
*
|
45 |
+
* @param {String} options.clonePosition - Where should the clone be added 'before' or 'after'
|
46 |
+
*
|
47 |
+
* @param {Number} options.limit - The maximum number of clones
|
48 |
+
*
|
49 |
+
* @param {Boolean} options.valueClone - Clone the input values as well?
|
50 |
+
* @param {Boolean} options.dataClone - Clone the data attributes?
|
51 |
+
* @param {Boolean} options.deepClone - Clone other data added to the jQuery object
|
52 |
+
*
|
53 |
+
* @param {Boolean} options.serializeID - Whether to serialize the IDs, automatically
|
54 |
+
* @param {String} options.ignore - Selectors for clonables' elements that should not be cloned
|
55 |
+
* @param {Boolean} options.defaultRender - Start with this number of clones, by default
|
56 |
+
* @param {Boolean} options.preserveChildCount - whether to preserve the initial number of clone's child clones, works with nesting as well.
|
57 |
+
*
|
58 |
+
* @returns {_L13.CloneYa}
|
59 |
+
*/
|
60 |
+
function CloneYa( element, options ) {
|
61 |
+
/**
|
62 |
+
* regex for recalculating the ids
|
63 |
+
*
|
64 |
+
* @type RegExp
|
65 |
+
*/
|
66 |
+
this.regex = /^(.*)(\d)+$/i;
|
67 |
+
|
68 |
+
this.elem = element;
|
69 |
+
|
70 |
+
this.$elem = $( element );
|
71 |
+
|
72 |
+
this.elemClass = name + '-wrap';
|
73 |
+
|
74 |
+
/**
|
75 |
+
* creating a jQuery object, just in case
|
76 |
+
*
|
77 |
+
* @type @call;$
|
78 |
+
*/
|
79 |
+
//var elem = $(element);
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Support deprecated parameters
|
83 |
+
*/
|
84 |
+
if ( typeof options !== 'undefined' ) {
|
85 |
+
if ( typeof options.limit !== 'undefined' && options.limit > 0 ) {
|
86 |
+
options.maximum = options.limit;
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* merge the passed options object with defaults
|
92 |
+
*
|
93 |
+
* @type @exp;$@call;extend
|
94 |
+
*/
|
95 |
+
this.config = $.extend( {}, defaults, options );
|
96 |
+
|
97 |
+
/**
|
98 |
+
*
|
99 |
+
* @type @exp;elem@call;closestChild
|
100 |
+
*/
|
101 |
+
this.clones = this.$elem.closestChild( this.config.cloneThis );
|
102 |
+
|
103 |
+
this.init();
|
104 |
+
|
105 |
+
}
|
106 |
+
|
107 |
+
CloneYa.prototype = {
|
108 |
+
init: function() {
|
109 |
+
|
110 |
+
var $this = this;
|
111 |
+
|
112 |
+
// add our classes
|
113 |
+
$this.$elem.addClass( $this.elemClass );
|
114 |
+
$this.clones.addClass( name );
|
115 |
+
|
116 |
+
// save the sibling count into data attr
|
117 |
+
$this.clones.data( 'initialCount', $this.clones.length );
|
118 |
+
|
119 |
+
//Now, what if the clone button and delete button are not contained in
|
120 |
+
//the clonable?
|
121 |
+
// add a click handler for the clone buttons
|
122 |
+
$this.$elem.on( 'click.' + name, $this.config.cloneThis + '>' + $this.config.cloneButton, function( event ) {
|
123 |
+
event.preventDefault();
|
124 |
+
event.stopPropagation();
|
125 |
+
|
126 |
+
var toClone = $( this ).closest( $this.config.cloneThis );
|
127 |
+
|
128 |
+
// this is just a wrapper for the custom clone event
|
129 |
+
$this.$elem.triggerAll( 'clone_clone clone.' + name, [ toClone ] );
|
130 |
+
} );
|
131 |
+
|
132 |
+
// the custom clone event
|
133 |
+
$this.$elem.on( 'clone.' + name, function( event, toClone ) {
|
134 |
+
if ( event.namespace === name ) {
|
135 |
+
$this._cloneAndAppend( toClone );
|
136 |
+
}
|
137 |
+
} );
|
138 |
+
|
139 |
+
// click handler for delete button
|
140 |
+
$this.$elem.on( 'click.' + name, $this.config.cloneThis + '>' + $this.config.deleteButton, function( event ) {
|
141 |
+
event.preventDefault();
|
142 |
+
event.stopPropagation();
|
143 |
+
|
144 |
+
var toDelete = $( this ).closest( $this.config.cloneThis );
|
145 |
+
// just a wrapper for delclone event
|
146 |
+
$this.$elem.triggerAll( 'clone_delete delete.' + name, [ toDelete ] );
|
147 |
+
} );
|
148 |
+
|
149 |
+
// the delete clone event
|
150 |
+
$this.$elem.on( 'delete.' + name, function( event, toDelete ) {
|
151 |
+
|
152 |
+
// get the count of all the sibling clones
|
153 |
+
/**
|
154 |
+
*
|
155 |
+
* @type @exp;$todelete@call;closest@call;closestChild@pro;length
|
156 |
+
*/
|
157 |
+
var cloneCount = toDelete.closest( '.' + $this.elemClass ).closestChild( $this.config.cloneThis ).length;
|
158 |
+
|
159 |
+
if ( cloneCount > $this.config.minimum ) {
|
160 |
+
// trigger hook
|
161 |
+
$this.$elem.triggerAll( 'clone_before_delete before_delete.' + name, [ toDelete, cloneCount ] );
|
162 |
+
$this.$elem.triggerHandler( 'remove.' + name, [ toDelete ] );
|
163 |
+
$this.$elem.triggerAll( 'clone_after_delete after_delete.' + name );
|
164 |
+
|
165 |
+
}
|
166 |
+
else {
|
167 |
+
|
168 |
+
$this.$elem.triggerHandler( 'minimum.' + name, $this.config.minimum, [ toDelete ] );
|
169 |
+
|
170 |
+
// First clone form can't be deleted, but the values should be removed from first form
|
171 |
+
// is this expected behaviour? especially since we use minimum?
|
172 |
+
toDelete.find( 'input, textarea, select' ).each( function() {
|
173 |
+
$this._clearForm( $( this ) );
|
174 |
+
} );
|
175 |
+
|
176 |
+
}
|
177 |
+
} );
|
178 |
+
|
179 |
+
$this.$elem.on( 'remove.' + name, function( event, toDelete ) {
|
180 |
+
$( toDelete ).remove();
|
181 |
+
|
182 |
+
} );
|
183 |
+
|
184 |
+
},
|
185 |
+
_clean: function() {
|
186 |
+
var $this = this;
|
187 |
+
$this.$elem.removeClass( name + '-wrap' );
|
188 |
+
$this.clones.removeClass( name );
|
189 |
+
$this.$elem.off( 'click.' + name, $this.config.cloneThis + '>' + $this.config.cloneButton );
|
190 |
+
$this.$elem.off( 'click.' + name, $this.config.cloneThis + '>' + $this.config.deleteButton );
|
191 |
+
$this.$elem.off( 'clone_clone clone_delete clone_before_delete clone.' + name + ' delete.' + name + ' before_delete.' + name );
|
192 |
+
|
193 |
+
},
|
194 |
+
destroy: function() {
|
195 |
+
this._clean();
|
196 |
+
this.$elem.removeData( name );
|
197 |
+
},
|
198 |
+
getOption: function() {
|
199 |
+
return this.config;
|
200 |
+
},
|
201 |
+
setOption: function( lateOptions ) {
|
202 |
+
$.extend( this.config, lateOptions || {} );
|
203 |
+
this._clean();
|
204 |
+
this.init();
|
205 |
+
|
206 |
+
},
|
207 |
+
_cloneAndAppend: function( toClone ) {
|
208 |
+
|
209 |
+
|
210 |
+
// get the count of all the sibling clones
|
211 |
+
/**
|
212 |
+
*
|
213 |
+
* @type @exp;$toclone@call;closest@call;closestChild@pro;length
|
214 |
+
*/
|
215 |
+
var cloneCount = toClone.closest( '.' + this.elemClass ).closestChild( this.config.cloneThis ).length;
|
216 |
+
|
217 |
+
// check if we've reached the maximum limit
|
218 |
+
if ( cloneCount < this.config.maximum ) {
|
219 |
+
|
220 |
+
// trigger a custom event for hooking in
|
221 |
+
this.$elem.triggerAll( 'clone_before_clone before_clone.' + name, [ toClone ] );
|
222 |
+
|
223 |
+
var newClone = this._cloneItem( toClone );
|
224 |
+
|
225 |
+
// trigger custom event on the original element
|
226 |
+
this.$elem.triggerAll( 'clone_after_clone after_clone.' + name, [ toClone, newClone ] );
|
227 |
+
|
228 |
+
// add to our clones object
|
229 |
+
this.clones.add( newClone );
|
230 |
+
|
231 |
+
// trigger custom event on the new clone
|
232 |
+
this.$elem.triggerAll( 'clone_before_append before_append.' + name, [ toClone, newClone ] );
|
233 |
+
|
234 |
+
// get the position where the clone has to be added
|
235 |
+
// and add the newclone
|
236 |
+
if ( this.config.clonePosition !== 'after' ) {
|
237 |
+
toClone.before( newClone );
|
238 |
+
} else {
|
239 |
+
toClone.after( newClone );
|
240 |
+
|
241 |
+
}
|
242 |
+
|
243 |
+
if ( this.config.ignore ) {
|
244 |
+
newClone.find( this.config.ignore ).remove();
|
245 |
+
}
|
246 |
+
|
247 |
+
// reformat the id attributes
|
248 |
+
this._redoIDs();
|
249 |
+
|
250 |
+
// trigger custom event for hooking
|
251 |
+
this.$elem.triggerAll( 'clone_after_append after_append.' + name, [ toClone, newClone ] );
|
252 |
+
} else {
|
253 |
+
// trigger a custom event for hooking
|
254 |
+
this.$elem.triggerAll( 'clone_limit maximum.' + name, this.config.maximum, [ toClone ] );
|
255 |
+
}
|
256 |
+
|
257 |
+
},
|
258 |
+
_cloneItem: function( toClone ) {
|
259 |
+
var $this = this;
|
260 |
+
|
261 |
+
// clone it
|
262 |
+
/**
|
263 |
+
*
|
264 |
+
* @type @exp;$toclone@call;clone
|
265 |
+
*/
|
266 |
+
var newClone = toClone.clone( $this.config.dataClone, $this.config.deepClone );
|
267 |
+
|
268 |
+
// we want to preserve the initial child count
|
269 |
+
if ( $this.config.preserveChildCount !== false ) {
|
270 |
+
// the child count only needs preservation if they are clonable.
|
271 |
+
|
272 |
+
var originalChildren = toClone.find( '.' + name + '-wrap' );
|
273 |
+
|
274 |
+
// for each wrapper
|
275 |
+
newClone.find( '.' + name + '-wrap' ).each( function( index ) {
|
276 |
+
|
277 |
+
/**
|
278 |
+
*
|
279 |
+
* @type @call;jquery-cloneya_L8.$@call;closestChild
|
280 |
+
*/
|
281 |
+
var inNewClone = $( this ).closestChild( '.' + name );
|
282 |
+
|
283 |
+
var inOriginal = $( originalChildren[ index ] ).closestChild( '.' + name );
|
284 |
+
|
285 |
+
/**
|
286 |
+
*
|
287 |
+
* @type @exp;inOriginal@call;data
|
288 |
+
*/
|
289 |
+
var originalCount = inOriginal.data( 'initialCount' );
|
290 |
+
|
291 |
+
/**
|
292 |
+
*
|
293 |
+
* @type @exp;inNewClone@call;slice
|
294 |
+
*/
|
295 |
+
var $extra = inNewClone.slice( originalCount, inNewClone.length );
|
296 |
+
|
297 |
+
$extra.remove();
|
298 |
+
|
299 |
+
inNewClone.data( 'initial-count', originalCount );
|
300 |
+
} );
|
301 |
+
|
302 |
+
}
|
303 |
+
|
304 |
+
// get the form input
|
305 |
+
newClone.find( 'input, textarea, select' ).each( function() {
|
306 |
+
|
307 |
+
// check if the values need to be copied, if not empty them
|
308 |
+
$this._clearForm( $( this ) );
|
309 |
+
|
310 |
+
// removed the portion taking care of the index
|
311 |
+
// each case is specific and I'd rather leave it to the developer
|
312 |
+
|
313 |
+
// custom event hook for index handling
|
314 |
+
$this.$elem.triggerAll( 'clone_form_input form_input.' + name, [ $( this ), toClone, newClone ] );
|
315 |
+
} );
|
316 |
+
|
317 |
+
return newClone;
|
318 |
+
|
319 |
+
},
|
320 |
+
/*
|
321 |
+
* Clear Form will used to clear the values of the form
|
322 |
+
*/
|
323 |
+
/**
|
324 |
+
*
|
325 |
+
* @param {type} $el
|
326 |
+
* @returns {undefined}
|
327 |
+
*/
|
328 |
+
_clearForm: function( $el ) {
|
329 |
+
|
330 |
+
if ( !this.config.valueClone && !$el.hasClass( 'noEmpty' ) ) {
|
331 |
+
|
332 |
+
if ( $el.is( ':checkbox' ) || $el.is( ':radio' ) ) {
|
333 |
+
|
334 |
+
$el.prop( 'checked', false );
|
335 |
+
}
|
336 |
+
else {
|
337 |
+
$el.val( '' );
|
338 |
+
}
|
339 |
+
|
340 |
+
}
|
341 |
+
|
342 |
+
},
|
343 |
+
/**
|
344 |
+
* Redo the id attribute, serially
|
345 |
+
*/
|
346 |
+
/**
|
347 |
+
*
|
348 |
+
* @returns {undefined}
|
349 |
+
*/
|
350 |
+
_redoIDs: function() {
|
351 |
+
|
352 |
+
var $this = this;
|
353 |
+
|
354 |
+
// check if this even needs to be done
|
355 |
+
if ( $this.config.serializeID !== true ) {
|
356 |
+
return;
|
357 |
+
}
|
358 |
+
|
359 |
+
// get the id of the first clone (hoping to increment the ids)
|
360 |
+
/**
|
361 |
+
*
|
362 |
+
* @type @exp;elem@call;find@call;first@call;attr
|
363 |
+
*/
|
364 |
+
var mainid = $this.$elem.find( $this.config.cloneThis ).first().attr( 'id' );
|
365 |
+
|
366 |
+
$this.$elem.find( $this.config.cloneThis ).each( function( i ) {
|
367 |
+
|
368 |
+
var j;
|
369 |
+
// assign the index to a string var for appending to the ids
|
370 |
+
// 0 index will have no number at the end
|
371 |
+
if ( i !== 0 ) {
|
372 |
+
j = i;
|
373 |
+
} else {
|
374 |
+
j = '';
|
375 |
+
}
|
376 |
+
|
377 |
+
// first modify the clone id
|
378 |
+
if ( $( this ).attr( 'id' ) ) {
|
379 |
+
$( this ).attr( 'id', mainid + j );
|
380 |
+
}
|
381 |
+
|
382 |
+
var id, nId;
|
383 |
+
// take all the elements inside the clone
|
384 |
+
$( this ).find( '*' ).each( function() {
|
385 |
+
|
386 |
+
id = $( this ).attr( 'id' );
|
387 |
+
if ( id ) {
|
388 |
+
// match the id with the regex to get the string part
|
389 |
+
// separate from the number part
|
390 |
+
var match = id.match( $this.regex );
|
391 |
+
|
392 |
+
// if there was a number
|
393 |
+
if ( match && match.length === 3 ) {
|
394 |
+
// just take the string part
|
395 |
+
// add the new number to it
|
396 |
+
nId = id.replace( /\d+$/, "" ) + j;
|
397 |
+
|
398 |
+
$( this ).attr( 'id', nId );
|
399 |
+
} else {
|
400 |
+
// else there was no number,
|
401 |
+
// this was earlier the first element
|
402 |
+
// just add the number to its id
|
403 |
+
nId = id + j;
|
404 |
+
$( this ).attr( 'id', nId );
|
405 |
+
}
|
406 |
+
}
|
407 |
+
|
408 |
+
//update label
|
409 |
+
$( this ).closest( $this.config.cloneThis ).find( "label[for='" + id + "']" ).attr( 'for', nId );
|
410 |
+
|
411 |
+
if ( $this.config.serializeIndex ) {
|
412 |
+
var name = $( this ).attr( 'name' );
|
413 |
+
// This will increment the numeric array index for cloned field names
|
414 |
+
if ( name ) {
|
415 |
+
var matches = name.match( /\[([0-9}]+)\]/ );
|
416 |
+
|
417 |
+
if ( matches && matches.length >= 1 ) {
|
418 |
+
|
419 |
+
var st = name;
|
420 |
+
var name = st.replace( matches[ 0 ], "[" + i + "]" );
|
421 |
+
|
422 |
+
$( this ).attr( 'name', name );
|
423 |
+
}
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
+
} );
|
428 |
+
} );
|
429 |
+
|
430 |
+
}
|
431 |
+
|
432 |
+
};
|
433 |
+
|
434 |
+
// add the cloneya to the global object
|
435 |
+
/**
|
436 |
+
*
|
437 |
+
* @param {type} options
|
438 |
+
* @returns {jquery-cloneya_L8.$.fn@call;each}
|
439 |
+
*/
|
440 |
+
$.fn[ name ] = function( options ) {
|
441 |
+
var args = arguments;
|
442 |
+
|
443 |
+
if ( options === undefined || typeof options === 'object' ) {
|
444 |
+
// Creates a new plugin instance, for each selected element, and
|
445 |
+
// stores a reference withint the element's data
|
446 |
+
return this.each( function() {
|
447 |
+
if ( !$.data( this, name ) ) {
|
448 |
+
$.data( this, name, new CloneYa( this, options ) );
|
449 |
+
}
|
450 |
+
} );
|
451 |
+
} else if ( typeof options === 'string' && options[ 0 ] !== '_' && options !== 'init' ) {
|
452 |
+
// Call a public pluguin method (not starting with an underscore) for each
|
453 |
+
// selected element.
|
454 |
+
if ( Array.prototype.slice.call( args, 1 ).length === 0 && $.inArray( options, $.fn[ name ].getters ) !== -1 ) {
|
455 |
+
// If the user does not pass any arguments and the method allows to
|
456 |
+
// work as a getter then break the chainability so we can return a value
|
457 |
+
// instead the element reference.
|
458 |
+
var instance = $.data( this[ 0 ], name );
|
459 |
+
return instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
|
460 |
+
} else {
|
461 |
+
// Invoke the speficied method on each selected element
|
462 |
+
return this.each( function() {
|
463 |
+
var instance = $.data( this, name );
|
464 |
+
if ( instance instanceof CloneYa && typeof instance[ options ] === 'function' ) {
|
465 |
+
instance[ options ].apply( instance, Array.prototype.slice.call( args, 1 ) );
|
466 |
+
}
|
467 |
+
} );
|
468 |
+
}
|
469 |
+
}
|
470 |
+
};
|
471 |
+
|
472 |
+
$.fn[ name ].getters = [ 'getOption' ];
|
473 |
+
|
474 |
+
/*
|
475 |
+
* jquery.closestchild 0.1.1
|
476 |
+
*
|
477 |
+
* Author: Andrey Mikhaylov aka lolmaus
|
478 |
+
* Email: lolmaus@gmail.com
|
479 |
+
*
|
480 |
+
*/
|
481 |
+
/**
|
482 |
+
*
|
483 |
+
* @param {type} selector
|
484 |
+
* @returns {$}
|
485 |
+
*/
|
486 |
+
$.fn.closestChild = function( selector ) {
|
487 |
+
var $children, $results;
|
488 |
+
|
489 |
+
$children = this.children();
|
490 |
+
|
491 |
+
if ( $children.length === 0 ) {
|
492 |
+
return $();
|
493 |
+
}
|
494 |
+
|
495 |
+
$results = $children.filter( selector );
|
496 |
+
|
497 |
+
if ( $results.length > 0 ) {
|
498 |
+
return $results;
|
499 |
+
} else {
|
500 |
+
return $children.closestChild( selector );
|
501 |
+
}
|
502 |
+
};
|
503 |
+
|
504 |
+
/*
|
505 |
+
* TriggerAll, modified from stackoverflow
|
506 |
+
* http://stackoverflow.com/questions/11850625/jquery-trigger-multiple-events
|
507 |
+
*/
|
508 |
+
$.fn.extend( {
|
509 |
+
triggerAll: function( events, params ) {
|
510 |
+
var el = this, i, evts = events.split( ' ' );
|
511 |
+
for ( i = 0; i < evts.length; i += 1 ) {
|
512 |
+
el.triggerHandler( evts[ i ], params );
|
513 |
+
}
|
514 |
+
return el;
|
515 |
+
}
|
516 |
+
} );
|
517 |
+
|
518 |
})( jQuery );
|
assets/js/vendor/jquery-cloneya.min.js
CHANGED
@@ -1 +1 @@
|
|
1 |
-
!function(a){"use strict";function b(b,e){this.regex=/^(.*)(\d)+$/i,this.elem=b,this.$elem=a(b),this.elemClass=c+"-wrap","undefined"!=typeof e&&"undefined"!=typeof e.limit&&e.limit>0&&(e.maximum=e.limit),this.config=a.extend({},d,e),this.clones=this.$elem.closestChild(this.config.cloneThis),this.init()}var c="cloneya",d={cloneThis:".toclone",cloneButton:".clone",deleteButton:".delete",clonePosition:"after",minimum:1,maximum:999,valueClone:!1,dataClone:!1,deepClone:!1,serializeID:!0,ignore:"label.error",preserveChildCount:!1};b.prototype={init:function(){var b=this;b.$elem.addClass(b.elemClass),b.clones.addClass(c),b.clones.data("initialCount",b.clones.length),b.$elem.on("click."+c,b.config.cloneThis+">"+b.config.cloneButton,function(d){d.preventDefault(),d.stopPropagation();var e=a(this).closest(b.config.cloneThis);b.$elem.triggerAll("clone_clone clone."+c,[e])}),b.$elem.on("clone."+c,function(a,c){b._cloneAndAppend(c)}),b.$elem.on("click."+c,b.config.cloneThis+">"+b.config.deleteButton,function(d){d.preventDefault(),d.stopPropagation();var e=a(this).closest(b.config.cloneThis);b.$elem.triggerAll("clone_delete delete."+c,[e])}),b.$elem.on("delete."+c,function(d,e){var f=e.closest("."+b.elemClass).closestChild(b.config.cloneThis).length;f>b.config.minimum?(b.$elem.triggerAll("clone_before_delete before_delete."+c,[e,f]),b.$elem.triggerHandler("remove."+c,[e]),b.$elem.triggerAll("clone_after_delete after_delete."+c)):(b.$elem.triggerHandler("minimum."+c,b.config.minimum,[e]),e.find("input, textarea, select").each(function(){b._clearForm(a(this))}))}),b.$elem.on("remove."+c,function(b,c){a(c).remove()})},_clean:function(){var a=this;a.$elem.removeClass(c+"-wrap"),a.clones.removeClass(c),a.$elem.off("click."+c,a.config.cloneThis+">"+a.config.cloneButton),a.$elem.off("click."+c,a.config.cloneThis+">"+a.config.deleteButton),a.$elem.off("clone_clone clone_delete clone_before_delete clone."+c+" delete."+c+" before_delete."+c)},destroy:function(){this._clean(),this.$elem.removeData(c)},getOption:function(){return this.config},setOption:function(b){a.extend(this.config,b||{}),this._clean(),this.init()},_cloneAndAppend:function(a){var b=a.closest("."+this.elemClass).closestChild(this.config.cloneThis).length;if(b<this.config.maximum){this.$elem.triggerAll("clone_before_clone before_clone."+c,[a]);var d=this._cloneItem(a);this.$elem.triggerAll("clone_after_clone after_clone."+c,[a,d]),this.clones.add(d),this.$elem.triggerAll("clone_before_append before_append."+c,[a,d]),"after"!==this.config.clonePosition?a.before(d):a.after(d),this.config.ignore&&d.find(this.config.ignore).remove(),this._redoIDs(),this.$elem.triggerAll("clone_after_append after_append."+c,[a,d])}else this.$elem.triggerAll("clone_limit maximum."+c,this.config.maximum,[a])},_cloneItem:function(b){var d=this,e=b.clone(d.config.dataClone,d.config.deepClone);if(d.config.preserveChildCount!==!1){var f=b.find("."+c+"-wrap");e.find("."+c+"-wrap").each(function(b){var d=a(this).closestChild("."+c),e=a(f[b]).closestChild("."+c),g=e.data("initialCount"),h=d.slice(g,d.length);h.remove(),d.data("initial-count",g)})}return e.find("input, textarea, select").each(function(){d._clearForm(a(this)),d.$elem.triggerAll("clone_form_input form_input."+c,[a(this),b,e])}),e},_clearForm:function(a){this.config.valueClone||a.hasClass("noEmpty")||(a.is(":checkbox")||a.is(":radio")?a.prop("checked",!1):a.val(""))},_redoIDs:function(){var b=this;if(b.config.serializeID===!0){var c=b.$elem.find(b.config.cloneThis).first().attr("id");b.$elem.find(b.config.cloneThis).each(function(d){var e;e=0!==d?d:"",a(this).attr("id")&&a(this).attr("id",c+e);var f,g;a(this).find("*").each(function(){if(f=a(this).attr("id")){var c=f.match(b.regex);c&&3===c.length?(g=f.replace(/\d+$/,"")+e,a(this).attr("id",g)):(g=f+e,a(this).attr("id",g))}if(a(this).closest(b.config.cloneThis).find("label[for='"+f+"']").attr("for",g),b.config.serializeIndex){var h=a(this).attr("name");if(h){var i=h.match(/\[([^}]+)\]/);if(i&&i.length>=1){var j=h;h=[].map.call(j,function(a,b){return isNaN(+a)||"["!==j[b-1]||"]"!==j[b+1]?a:d}).join(""),a(this).attr("name",h)}}}})})}}},a.fn[c]=function(d){var e=arguments;if(void 0===d||"object"==typeof d)return this.each(function(){a.data(this,c)||a.data(this,c,new b(this,d))});if("string"==typeof d&&"_"!==d[0]&&"init"!==d){if(0===Array.prototype.slice.call(e,1).length&&-1!==a.inArray(d,a.fn[c].getters)){var f=a.data(this[0],c);return f[d].apply(f,Array.prototype.slice.call(e,1))}return this.each(function(){var f=a.data(this,c);f instanceof b&&"function"==typeof f[d]&&f[d].apply(f,Array.prototype.slice.call(e,1))})}},a.fn[c].getters=["getOption"],a.fn.closestChild=function(b){var c,d;return c=this.children(),0===c.length?a():(d=c.filter(b),d.length>0?d:c.closestChild(b))},a.fn.extend({triggerAll:function(a,b){var c,d=this,e=a.split(" ");for(c=0;c<e.length;c+=1)d.triggerHandler(e[c],b);return d}})}(jQuery);
|
1 |
+
!function(a){"use strict";function b(b,e){this.regex=/^(.*)(\d)+$/i,this.elem=b,this.$elem=a(b),this.elemClass=c+"-wrap","undefined"!=typeof e&&"undefined"!=typeof e.limit&&e.limit>0&&(e.maximum=e.limit),this.config=a.extend({},d,e),this.clones=this.$elem.closestChild(this.config.cloneThis),this.init()}var c="cloneya",d={cloneThis:".toclone",cloneButton:".clone",deleteButton:".delete",clonePosition:"after",minimum:1,maximum:999,valueClone:!1,dataClone:!1,deepClone:!1,serializeID:!0,ignore:"label.error",preserveChildCount:!1};b.prototype={init:function(){var b=this;b.$elem.addClass(b.elemClass),b.clones.addClass(c),b.clones.data("initialCount",b.clones.length),b.$elem.on("click."+c,b.config.cloneThis+">"+b.config.cloneButton,function(d){d.preventDefault(),d.stopPropagation();var e=a(this).closest(b.config.cloneThis);b.$elem.triggerAll("clone_clone clone."+c,[e])}),b.$elem.on("clone."+c,function(a,c){b._cloneAndAppend(c)}),b.$elem.on("click."+c,b.config.cloneThis+">"+b.config.deleteButton,function(d){d.preventDefault(),d.stopPropagation();var e=a(this).closest(b.config.cloneThis);b.$elem.triggerAll("clone_delete delete."+c,[e])}),b.$elem.on("delete."+c,function(d,e){var f=e.closest("."+b.elemClass).closestChild(b.config.cloneThis).length;f>b.config.minimum?(b.$elem.triggerAll("clone_before_delete before_delete."+c,[e,f]),b.$elem.triggerHandler("remove."+c,[e]),b.$elem.triggerAll("clone_after_delete after_delete."+c)):(b.$elem.triggerHandler("minimum."+c,b.config.minimum,[e]),e.find("input, textarea, select").each(function(){b._clearForm(a(this))}))}),b.$elem.on("remove."+c,function(b,c){a(c).remove()})},_clean:function(){var a=this;a.$elem.removeClass(c+"-wrap"),a.clones.removeClass(c),a.$elem.off("click."+c,a.config.cloneThis+">"+a.config.cloneButton),a.$elem.off("click."+c,a.config.cloneThis+">"+a.config.deleteButton),a.$elem.off("clone_clone clone_delete clone_before_delete clone."+c+" delete."+c+" before_delete."+c)},destroy:function(){this._clean(),this.$elem.removeData(c)},getOption:function(){return this.config},setOption:function(b){a.extend(this.config,b||{}),this._clean(),this.init()},_cloneAndAppend:function(a){var b=a.closest("."+this.elemClass).closestChild(this.config.cloneThis).length;if(b<this.config.maximum){this.$elem.triggerAll("clone_before_clone before_clone."+c,[a]);var d=this._cloneItem(a);this.$elem.triggerAll("clone_after_clone after_clone."+c,[a,d]),this.clones.add(d),this.$elem.triggerAll("clone_before_append before_append."+c,[a,d]),"after"!==this.config.clonePosition?a.before(d):a.after(d),this.config.ignore&&d.find(this.config.ignore).remove(),this._redoIDs(),this.$elem.triggerAll("clone_after_append after_append."+c,[a,d])}else this.$elem.triggerAll("clone_limit maximum."+c,this.config.maximum,[a])},_cloneItem:function(b){var d=this,e=b.clone(d.config.dataClone,d.config.deepClone);if(d.config.preserveChildCount!==!1){var f=b.find("."+c+"-wrap");e.find("."+c+"-wrap").each(function(b){var d=a(this).closestChild("."+c),e=a(f[b]).closestChild("."+c),g=e.data("initialCount"),h=d.slice(g,d.length);h.remove(),d.data("initial-count",g)})}return e.find("input, textarea, select").each(function(){d._clearForm(a(this)),d.$elem.triggerAll("clone_form_input form_input."+c,[a(this),b,e])}),e},_clearForm:function(a){this.config.valueClone||a.hasClass("noEmpty")||(a.is(":checkbox")||a.is(":radio")?a.prop("checked",!1):a.val(""))},_redoIDs:function(){var b=this;if(b.config.serializeID===!0){var c=b.$elem.find(b.config.cloneThis).first().attr("id");b.$elem.find(b.config.cloneThis).each(function(d){var e;e=0!==d?d:"",a(this).attr("id")&&a(this).attr("id",c+e);var f,g;a(this).find("*").each(function(){if(f=a(this).attr("id")){var c=f.match(b.regex);c&&3===c.length?(g=f.replace(/\d+$/,"")+e,a(this).attr("id",g)):(g=f+e,a(this).attr("id",g))}if(a(this).closest(b.config.cloneThis).find("label[for='"+f+"']").attr("for",g),b.config.serializeIndex){var h=a(this).attr("name");if(h){var i=h.match(/\[([^}]+)\]/);if(i&&i.length>=1){var j=h;h=[].map.call(j,function(a,b){return isNaN(+a)||"["!==j[b-1]||"]"!==j[b+1]?a:d}).join(""),a(this).attr("name",h)}}}})})}}},a.fn[c]=function(d){var e=arguments;if(void 0===d||"object"==typeof d)return this.each(function(){a.data(this,c)||a.data(this,c,new b(this,d))});if("string"==typeof d&&"_"!==d[0]&&"init"!==d){if(0===Array.prototype.slice.call(e,1).length&&-1!==a.inArray(d,a.fn[c].getters)){var f=a.data(this[0],c);return f[d].apply(f,Array.prototype.slice.call(e,1))}return this.each(function(){var f=a.data(this,c);f instanceof b&&"function"==typeof f[d]&&f[d].apply(f,Array.prototype.slice.call(e,1))})}},a.fn[c].getters=["getOption"],a.fn.closestChild=function(b){var c,d;return c=this.children(),0===c.length?a():(d=c.filter(b),d.length>0?d:c.closestChild(b))},a.fn.extend({triggerAll:function(a,b){var c,d=this,e=a.split(" ");for(c=0;c<e.length;c+=1)d.triggerHandler(e[c],b);return d}})}(jQuery);
|
assets/js/vendor/jquery.vide.js
CHANGED
@@ -1,501 +1,501 @@
|
|
1 |
-
/*
|
2 |
-
* Vide - v0.5.1
|
3 |
-
* Easy as hell jQuery plugin for video backgrounds.
|
4 |
-
* http://vodkabears.github.io/vide/
|
5 |
-
*
|
6 |
-
* Made by Ilya Makarov
|
7 |
-
* Under MIT License
|
8 |
-
*/
|
9 |
-
!(function(root, factory) {
|
10 |
-
if (typeof define === 'function' && define.amd) {
|
11 |
-
define(['jquery'], factory);
|
12 |
-
} else if (typeof exports === 'object') {
|
13 |
-
factory(require('jquery'));
|
14 |
-
} else {
|
15 |
-
factory(root.jQuery);
|
16 |
-
}
|
17 |
-
})(this, function($) {
|
18 |
-
|
19 |
-
'use strict';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Name of the plugin
|
23 |
-
* @private
|
24 |
-
* @const
|
25 |
-
* @type {String}
|
26 |
-
*/
|
27 |
-
var PLUGIN_NAME = 'vide';
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Default settings
|
31 |
-
* @private
|
32 |
-
* @const
|
33 |
-
* @type {Object}
|
34 |
-
*/
|
35 |
-
var DEFAULTS = {
|
36 |
-
volume: 1,
|
37 |
-
playbackRate: 1,
|
38 |
-
muted: true,
|
39 |
-
loop: true,
|
40 |
-
autoplay: true,
|
41 |
-
position: '50% 50%',
|
42 |
-
posterType: 'detect',
|
43 |
-
resizing: true,
|
44 |
-
bgColor: 'transparent',
|
45 |
-
className: ''
|
46 |
-
};
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Not implemented error message
|
50 |
-
* @private
|
51 |
-
* @const
|
52 |
-
* @type {String}
|
53 |
-
*/
|
54 |
-
var NOT_IMPLEMENTED_MSG = 'Not implemented';
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Parse a string with options
|
58 |
-
* @private
|
59 |
-
* @param {String} str
|
60 |
-
* @returns {Object|String}
|
61 |
-
*/
|
62 |
-
function parseOptions(str) {
|
63 |
-
var obj = {};
|
64 |
-
var delimiterIndex;
|
65 |
-
var option;
|
66 |
-
var prop;
|
67 |
-
var val;
|
68 |
-
var arr;
|
69 |
-
var len;
|
70 |
-
var i;
|
71 |
-
|
72 |
-
// Remove spaces around delimiters and split
|
73 |
-
arr = str.replace(/\s*:\s*/g, ':').replace(/\s*,\s*/g, ',').split(',');
|
74 |
-
|
75 |
-
// Parse a string
|
76 |
-
for (i = 0, len = arr.length; i < len; i++) {
|
77 |
-
option = arr[i];
|
78 |
-
|
79 |
-
// Ignore urls and a string without colon delimiters
|
80 |
-
if (
|
81 |
-
option.search(/^(http|https|ftp):\/\//) !== -1 ||
|
82 |
-
option.search(':') === -1
|
83 |
-
) {
|
84 |
-
break;
|
85 |
-
}
|
86 |
-
|
87 |
-
delimiterIndex = option.indexOf(':');
|
88 |
-
prop = option.substring(0, delimiterIndex);
|
89 |
-
val = option.substring(delimiterIndex + 1);
|
90 |
-
|
91 |
-
// If val is an empty string, make it undefined
|
92 |
-
if (!val) {
|
93 |
-
val = undefined;
|
94 |
-
}
|
95 |
-
|
96 |
-
// Convert a string value if it is like a boolean
|
97 |
-
if (typeof val === 'string') {
|
98 |
-
val = val === 'true' || (val === 'false' ? false : val);
|
99 |
-
}
|
100 |
-
|
101 |
-
// Convert a string value if it is like a number
|
102 |
-
if (typeof val === 'string') {
|
103 |
-
val = !isNaN(val) ? +val : val;
|
104 |
-
}
|
105 |
-
|
106 |
-
obj[prop] = val;
|
107 |
-
}
|
108 |
-
|
109 |
-
// If nothing is parsed
|
110 |
-
if (prop == null && val == null) {
|
111 |
-
return str;
|
112 |
-
}
|
113 |
-
|
114 |
-
return obj;
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Parse a position option
|
119 |
-
* @private
|
120 |
-
* @param {String} str
|
121 |
-
* @returns {Object}
|
122 |
-
*/
|
123 |
-
function parsePosition(str) {
|
124 |
-
str = '' + str;
|
125 |
-
|
126 |
-
// Default value is a center
|
127 |
-
var args = str.split(/\s+/);
|
128 |
-
var x = '50%';
|
129 |
-
var y = '50%';
|
130 |
-
var len;
|
131 |
-
var arg;
|
132 |
-
var i;
|
133 |
-
|
134 |
-
for (i = 0, len = args.length; i < len; i++) {
|
135 |
-
arg = args[i];
|
136 |
-
|
137 |
-
// Convert values
|
138 |
-
if (arg === 'left') {
|
139 |
-
x = '0%';
|
140 |
-
} else if (arg === 'right') {
|
141 |
-
x = '100%';
|
142 |
-
} else if (arg === 'top') {
|
143 |
-
y = '0%';
|
144 |
-
} else if (arg === 'bottom') {
|
145 |
-
y = '100%';
|
146 |
-
} else if (arg === 'center') {
|
147 |
-
if (i === 0) {
|
148 |
-
x = '50%';
|
149 |
-
} else {
|
150 |
-
y = '50%';
|
151 |
-
}
|
152 |
-
} else {
|
153 |
-
if (i === 0) {
|
154 |
-
x = arg;
|
155 |
-
} else {
|
156 |
-
y = arg;
|
157 |
-
}
|
158 |
-
}
|
159 |
-
}
|
160 |
-
|
161 |
-
return { x: x, y: y };
|
162 |
-
}
|
163 |
-
|
164 |
-
/**
|
165 |
-
* Search a poster
|
166 |
-
* @private
|
167 |
-
* @param {String} path
|
168 |
-
* @param {Function} callback
|
169 |
-
*/
|
170 |
-
function findPoster(path, callback) {
|
171 |
-
var onLoad = function() {
|
172 |
-
callback(this.src);
|
173 |
-
};
|
174 |
-
|
175 |
-
$('<img src="' + path + '.gif">').on('load', onLoad);
|
176 |
-
$('<img src="' + path + '.jpg">').on('load', onLoad);
|
177 |
-
$('<img src="' + path + '.jpeg">').on('load', onLoad);
|
178 |
-
$('<img src="' + path + '.png">').on('load', onLoad);
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Vide constructor
|
183 |
-
* @param {HTMLElement} element
|
184 |
-
* @param {Object|String} path
|
185 |
-
* @param {Object|String} options
|
186 |
-
* @constructor
|
187 |
-
*/
|
188 |
-
function Vide(element, path, options) {
|
189 |
-
this.$element = $(element);
|
190 |
-
|
191 |
-
// Parse path
|
192 |
-
if (typeof path === 'string') {
|
193 |
-
path = parseOptions(path);
|
194 |
-
}
|
195 |
-
|
196 |
-
// Parse options
|
197 |
-
if (!options) {
|
198 |
-
options = {};
|
199 |
-
} else if (typeof options === 'string') {
|
200 |
-
options = parseOptions(options);
|
201 |
-
}
|
202 |
-
|
203 |
-
// Remove an extension
|
204 |
-
if (typeof path === 'string') {
|
205 |
-
path = path.replace(/\.\w*$/, '');
|
206 |
-
} else if (typeof path === 'object') {
|
207 |
-
for (var i in path) {
|
208 |
-
if (path.hasOwnProperty(i)) {
|
209 |
-
path[i] = path[i].replace(/\.\w*$/, '');
|
210 |
-
}
|
211 |
-
}
|
212 |
-
}
|
213 |
-
|
214 |
-
this.settings = $.extend({}, DEFAULTS, options);
|
215 |
-
this.path = path;
|
216 |
-
|
217 |
-
// https://github.com/VodkaBears/Vide/issues/110
|
218 |
-
try {
|
219 |
-
this.init();
|
220 |
-
} catch (e) {
|
221 |
-
if (e.message !== NOT_IMPLEMENTED_MSG) {
|
222 |
-
throw e;
|
223 |
-
}
|
224 |
-
}
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* Initialization
|
229 |
-
* @public
|
230 |
-
*/
|
231 |
-
Vide.prototype.init = function() {
|
232 |
-
var vide = this;
|
233 |
-
var path = vide.path;
|
234 |
-
var poster = path;
|
235 |
-
var sources = '';
|
236 |
-
var $element = vide.$element;
|
237 |
-
var settings = vide.settings;
|
238 |
-
var position = parsePosition(settings.position);
|
239 |
-
var posterType = settings.posterType;
|
240 |
-
var $video;
|
241 |
-
var $wrapper;
|
242 |
-
|
243 |
-
// Set styles of a video wrapper
|
244 |
-
$wrapper = vide.$wrapper = $('<div>')
|
245 |
-
.addClass(settings.className)
|
246 |
-
.css({
|
247 |
-
position: 'absolute',
|
248 |
-
'z-index': -1,
|
249 |
-
top: 0,
|
250 |
-
left: 0,
|
251 |
-
bottom: 0,
|
252 |
-
right: 0,
|
253 |
-
overflow: 'hidden',
|
254 |
-
'-webkit-background-size': 'cover',
|
255 |
-
'-moz-background-size': 'cover',
|
256 |
-
'-o-background-size': 'cover',
|
257 |
-
'background-size': 'cover',
|
258 |
-
'background-color': settings.bgColor,
|
259 |
-
'background-repeat': 'no-repeat',
|
260 |
-
'background-position': position.x + ' ' + position.y
|
261 |
-
});
|
262 |
-
|
263 |
-
// Get a poster path
|
264 |
-
if (typeof path === 'object') {
|
265 |
-
if (path.poster) {
|
266 |
-
poster = path.poster;
|
267 |
-
} else {
|
268 |
-
if (path.mp4) {
|
269 |
-
poster = path.mp4;
|
270 |
-
} else if (path.webm) {
|
271 |
-
poster = path.webm;
|
272 |
-
} else if (path.ogv) {
|
273 |
-
poster = path.ogv;
|
274 |
-
}
|
275 |
-
}
|
276 |
-
}
|
277 |
-
|
278 |
-
// Set a video poster
|
279 |
-
if (posterType === 'detect') {
|
280 |
-
findPoster(poster, function(url) {
|
281 |
-
$wrapper.css('background-image', 'url(' + url + ')');
|
282 |
-
});
|
283 |
-
} else if (posterType !== 'none') {
|
284 |
-
$wrapper.css('background-image', 'url(' + poster + '.' + posterType + ')');
|
285 |
-
}
|
286 |
-
|
287 |
-
// If a parent element has a static position, make it relative
|
288 |
-
if ($element.css('position') === 'static') {
|
289 |
-
$element.css('position', 'relative');
|
290 |
-
}
|
291 |
-
|
292 |
-
$element.prepend($wrapper);
|
293 |
-
|
294 |
-
if (typeof path === 'object') {
|
295 |
-
if (path.mp4) {
|
296 |
-
sources += '<source src="' + path.mp4 + '.mp4" type="video/mp4">';
|
297 |
-
}
|
298 |
-
|
299 |
-
if (path.webm) {
|
300 |
-
sources += '<source src="' + path.webm + '.webm" type="video/webm">';
|
301 |
-
}
|
302 |
-
|
303 |
-
if (path.ogv) {
|
304 |
-
sources += '<source src="' + path.ogv + '.ogv" type="video/ogg">';
|
305 |
-
}
|
306 |
-
|
307 |
-
$video = vide.$video = $('<video>' + sources + '</video>');
|
308 |
-
} else {
|
309 |
-
$video = vide.$video = $('<video>' +
|
310 |
-
'<source src="' + path + '.mp4" type="video/mp4">' +
|
311 |
-
'<source src="' + path + '.webm" type="video/webm">' +
|
312 |
-
'<source src="' + path + '.ogv" type="video/ogg">' +
|
313 |
-
'</video>');
|
314 |
-
}
|
315 |
-
|
316 |
-
// https://github.com/VodkaBears/Vide/issues/110
|
317 |
-
try {
|
318 |
-
$video
|
319 |
-
|
320 |
-
// Set video properties
|
321 |
-
.prop({
|
322 |
-
autoplay: settings.autoplay,
|
323 |
-
loop: settings.loop,
|
324 |
-
volume: settings.volume,
|
325 |
-
muted: settings.muted,
|
326 |
-
defaultMuted: settings.muted,
|
327 |
-
playbackRate: settings.playbackRate,
|
328 |
-
defaultPlaybackRate: settings.playbackRate
|
329 |
-
});
|
330 |
-
} catch (e) {
|
331 |
-
throw new Error(NOT_IMPLEMENTED_MSG);
|
332 |
-
}
|
333 |
-
|
334 |
-
// Video alignment
|
335 |
-
$video.css({
|
336 |
-
margin: 'auto',
|
337 |
-
position: 'absolute',
|
338 |
-
'z-index': -1,
|
339 |
-
top: position.y,
|
340 |
-
left: position.x,
|
341 |
-
'-webkit-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
342 |
-
'-ms-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
343 |
-
'-moz-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
344 |
-
transform: 'translate(-' + position.x + ', -' + position.y + ')',
|
345 |
-
|
346 |
-
// Disable visibility, while loading
|
347 |
-
visibility: 'hidden',
|
348 |
-
opacity: 0
|
349 |
-
})
|
350 |
-
|
351 |
-
// Resize a video, when it's loaded
|
352 |
-
.one('canplaythrough.' + PLUGIN_NAME, function() {
|
353 |
-
vide.resize();
|
354 |
-
})
|
355 |
-
|
356 |
-
// Make it visible, when it's already playing
|
357 |
-
.one('playing.' + PLUGIN_NAME, function() {
|
358 |
-
$video.css({
|
359 |
-
visibility: 'visible',
|
360 |
-
opacity: 1
|
361 |
-
});
|
362 |
-
$wrapper.css('background-image', 'none');
|
363 |
-
});
|
364 |
-
|
365 |
-
// Resize event is available only for 'window'
|
366 |
-
// Use another code solutions to detect DOM elements resizing
|
367 |
-
$element.on('resize.' + PLUGIN_NAME, function() {
|
368 |
-
if (settings.resizing) {
|
369 |
-
vide.resize();
|
370 |
-
}
|
371 |
-
});
|
372 |
-
|
373 |
-
// Append a video
|
374 |
-
$wrapper.append($video);
|
375 |
-
};
|
376 |
-
|
377 |
-
/**
|
378 |
-
* Get a video element
|
379 |
-
* @public
|
380 |
-
* @returns {HTMLVideoElement}
|
381 |
-
*/
|
382 |
-
Vide.prototype.getVideoObject = function() {
|
383 |
-
return this.$video[0];
|
384 |
-
};
|
385 |
-
|
386 |
-
/**
|
387 |
-
* Resize a video background
|
388 |
-
* @public
|
389 |
-
*/
|
390 |
-
Vide.prototype.resize = function() {
|
391 |
-
if (!this.$video) {
|
392 |
-
return;
|
393 |
-
}
|
394 |
-
|
395 |
-
var $wrapper = this.$wrapper;
|
396 |
-
var $video = this.$video;
|
397 |
-
var video = $video[0];
|
398 |
-
|
399 |
-
// Get a native video size
|
400 |
-
var videoHeight = video.videoHeight;
|
401 |
-
var videoWidth = video.videoWidth;
|
402 |
-
|
403 |
-
// Get a wrapper size
|
404 |
-
var wrapperHeight = $wrapper.height();
|
405 |
-
var wrapperWidth = $wrapper.width();
|
406 |
-
|
407 |
-
if (wrapperWidth / videoWidth > wrapperHeight / videoHeight) {
|
408 |
-
$video.css({
|
409 |
-
|
410 |
-
// +2 pixels to prevent an empty space after transformation
|
411 |
-
width: wrapperWidth + 2,
|
412 |
-
height: 'auto'
|
413 |
-
});
|
414 |
-
} else {
|
415 |
-
$video.css({
|
416 |
-
width: 'auto',
|
417 |
-
|
418 |
-
// +2 pixels to prevent an empty space after transformation
|
419 |
-
height: wrapperHeight + 2
|
420 |
-
});
|
421 |
-
}
|
422 |
-
};
|
423 |
-
|
424 |
-
/**
|
425 |
-
* Destroy a video background
|
426 |
-
* @public
|
427 |
-
*/
|
428 |
-
Vide.prototype.destroy = function() {
|
429 |
-
delete $[PLUGIN_NAME].lookup[this.index];
|
430 |
-
this.$video && this.$video.off(PLUGIN_NAME);
|
431 |
-
this.$element.off(PLUGIN_NAME).removeData(PLUGIN_NAME);
|
432 |
-
this.$wrapper.remove();
|
433 |
-
};
|
434 |
-
|
435 |
-
/**
|
436 |
-
* Special plugin object for instances.
|
437 |
-
* @public
|
438 |
-
* @type {Object}
|
439 |
-
*/
|
440 |
-
$[PLUGIN_NAME] = {
|
441 |
-
lookup: []
|
442 |
-
};
|
443 |
-
|
444 |
-
/**
|
445 |
-
* Plugin constructor
|
446 |
-
* @param {Object|String} path
|
447 |
-
* @param {Object|String} options
|
448 |
-
* @returns {JQuery}
|
449 |
-
* @constructor
|
450 |
-
*/
|
451 |
-
$.fn[PLUGIN_NAME] = function(path, options) {
|
452 |
-
var instance;
|
453 |
-
|
454 |
-
this.each(function() {
|
455 |
-
instance = $.data(this, PLUGIN_NAME);
|
456 |
-
|
457 |
-
// Destroy the plugin instance if exists
|
458 |
-
instance && instance.destroy();
|
459 |
-
|
460 |
-
// Create the plugin instance
|
461 |
-
instance = new Vide(this, path, options);
|
462 |
-
instance.index = $[PLUGIN_NAME].lookup.push(instance) - 1;
|
463 |
-
$.data(this, PLUGIN_NAME, instance);
|
464 |
-
});
|
465 |
-
|
466 |
-
return this;
|
467 |
-
};
|
468 |
-
|
469 |
-
$(document).ready(function() {
|
470 |
-
var $window = $(window);
|
471 |
-
|
472 |
-
// Window resize event listener
|
473 |
-
$window.on('resize.' + PLUGIN_NAME, function() {
|
474 |
-
for (var len = $[PLUGIN_NAME].lookup.length, i = 0, instance; i < len; i++) {
|
475 |
-
instance = $[PLUGIN_NAME].lookup[i];
|
476 |
-
|
477 |
-
if (instance && instance.settings.resizing) {
|
478 |
-
instance.resize();
|
479 |
-
}
|
480 |
-
}
|
481 |
-
});
|
482 |
-
|
483 |
-
// https://github.com/VodkaBears/Vide/issues/68
|
484 |
-
$window.on('unload.' + PLUGIN_NAME, function() {
|
485 |
-
return false;
|
486 |
-
});
|
487 |
-
|
488 |
-
// Auto initialization
|
489 |
-
// Add 'data-vide-bg' attribute with a path to the video without extension
|
490 |
-
// Also you can pass options throw the 'data-vide-options' attribute
|
491 |
-
// 'data-vide-options' must be like 'muted: false, volume: 0.5'
|
492 |
-
$(document).find('[data-' + PLUGIN_NAME + '-bg]').each(function(i, element) {
|
493 |
-
var $element = $(element);
|
494 |
-
var options = $element.data(PLUGIN_NAME + '-options');
|
495 |
-
var path = $element.data(PLUGIN_NAME + '-bg');
|
496 |
-
|
497 |
-
$element[PLUGIN_NAME](path, options);
|
498 |
-
});
|
499 |
-
});
|
500 |
-
|
501 |
-
});
|
1 |
+
/*
|
2 |
+
* Vide - v0.5.1
|
3 |
+
* Easy as hell jQuery plugin for video backgrounds.
|
4 |
+
* http://vodkabears.github.io/vide/
|
5 |
+
*
|
6 |
+
* Made by Ilya Makarov
|
7 |
+
* Under MIT License
|
8 |
+
*/
|
9 |
+
!(function(root, factory) {
|
10 |
+
if (typeof define === 'function' && define.amd) {
|
11 |
+
define(['jquery'], factory);
|
12 |
+
} else if (typeof exports === 'object') {
|
13 |
+
factory(require('jquery'));
|
14 |
+
} else {
|
15 |
+
factory(root.jQuery);
|
16 |
+
}
|
17 |
+
})(this, function($) {
|
18 |
+
|
19 |
+
'use strict';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Name of the plugin
|
23 |
+
* @private
|
24 |
+
* @const
|
25 |
+
* @type {String}
|
26 |
+
*/
|
27 |
+
var PLUGIN_NAME = 'vide';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Default settings
|
31 |
+
* @private
|
32 |
+
* @const
|
33 |
+
* @type {Object}
|
34 |
+
*/
|
35 |
+
var DEFAULTS = {
|
36 |
+
volume: 1,
|
37 |
+
playbackRate: 1,
|
38 |
+
muted: true,
|
39 |
+
loop: true,
|
40 |
+
autoplay: true,
|
41 |
+
position: '50% 50%',
|
42 |
+
posterType: 'detect',
|
43 |
+
resizing: true,
|
44 |
+
bgColor: 'transparent',
|
45 |
+
className: ''
|
46 |
+
};
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Not implemented error message
|
50 |
+
* @private
|
51 |
+
* @const
|
52 |
+
* @type {String}
|
53 |
+
*/
|
54 |
+
var NOT_IMPLEMENTED_MSG = 'Not implemented';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Parse a string with options
|
58 |
+
* @private
|
59 |
+
* @param {String} str
|
60 |
+
* @returns {Object|String}
|
61 |
+
*/
|
62 |
+
function parseOptions(str) {
|
63 |
+
var obj = {};
|
64 |
+
var delimiterIndex;
|
65 |
+
var option;
|
66 |
+
var prop;
|
67 |
+
var val;
|
68 |
+
var arr;
|
69 |
+
var len;
|
70 |
+
var i;
|
71 |
+
|
72 |
+
// Remove spaces around delimiters and split
|
73 |
+
arr = str.replace(/\s*:\s*/g, ':').replace(/\s*,\s*/g, ',').split(',');
|
74 |
+
|
75 |
+
// Parse a string
|
76 |
+
for (i = 0, len = arr.length; i < len; i++) {
|
77 |
+
option = arr[i];
|
78 |
+
|
79 |
+
// Ignore urls and a string without colon delimiters
|
80 |
+
if (
|
81 |
+
option.search(/^(http|https|ftp):\/\//) !== -1 ||
|
82 |
+
option.search(':') === -1
|
83 |
+
) {
|
84 |
+
break;
|
85 |
+
}
|
86 |
+
|
87 |
+
delimiterIndex = option.indexOf(':');
|
88 |
+
prop = option.substring(0, delimiterIndex);
|
89 |
+
val = option.substring(delimiterIndex + 1);
|
90 |
+
|
91 |
+
// If val is an empty string, make it undefined
|
92 |
+
if (!val) {
|
93 |
+
val = undefined;
|
94 |
+
}
|
95 |
+
|
96 |
+
// Convert a string value if it is like a boolean
|
97 |
+
if (typeof val === 'string') {
|
98 |
+
val = val === 'true' || (val === 'false' ? false : val);
|
99 |
+
}
|
100 |
+
|
101 |
+
// Convert a string value if it is like a number
|
102 |
+
if (typeof val === 'string') {
|
103 |
+
val = !isNaN(val) ? +val : val;
|
104 |
+
}
|
105 |
+
|
106 |
+
obj[prop] = val;
|
107 |
+
}
|
108 |
+
|
109 |
+
// If nothing is parsed
|
110 |
+
if (prop == null && val == null) {
|
111 |
+
return str;
|
112 |
+
}
|
113 |
+
|
114 |
+
return obj;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Parse a position option
|
119 |
+
* @private
|
120 |
+
* @param {String} str
|
121 |
+
* @returns {Object}
|
122 |
+
*/
|
123 |
+
function parsePosition(str) {
|
124 |
+
str = '' + str;
|
125 |
+
|
126 |
+
// Default value is a center
|
127 |
+
var args = str.split(/\s+/);
|
128 |
+
var x = '50%';
|
129 |
+
var y = '50%';
|
130 |
+
var len;
|
131 |
+
var arg;
|
132 |
+
var i;
|
133 |
+
|
134 |
+
for (i = 0, len = args.length; i < len; i++) {
|
135 |
+
arg = args[i];
|
136 |
+
|
137 |
+
// Convert values
|
138 |
+
if (arg === 'left') {
|
139 |
+
x = '0%';
|
140 |
+
} else if (arg === 'right') {
|
141 |
+
x = '100%';
|
142 |
+
} else if (arg === 'top') {
|
143 |
+
y = '0%';
|
144 |
+
} else if (arg === 'bottom') {
|
145 |
+
y = '100%';
|
146 |
+
} else if (arg === 'center') {
|
147 |
+
if (i === 0) {
|
148 |
+
x = '50%';
|
149 |
+
} else {
|
150 |
+
y = '50%';
|
151 |
+
}
|
152 |
+
} else {
|
153 |
+
if (i === 0) {
|
154 |
+
x = arg;
|
155 |
+
} else {
|
156 |
+
y = arg;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
return { x: x, y: y };
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Search a poster
|
166 |
+
* @private
|
167 |
+
* @param {String} path
|
168 |
+
* @param {Function} callback
|
169 |
+
*/
|
170 |
+
function findPoster(path, callback) {
|
171 |
+
var onLoad = function() {
|
172 |
+
callback(this.src);
|
173 |
+
};
|
174 |
+
|
175 |
+
$('<img src="' + path + '.gif">').on('load', onLoad);
|
176 |
+
$('<img src="' + path + '.jpg">').on('load', onLoad);
|
177 |
+
$('<img src="' + path + '.jpeg">').on('load', onLoad);
|
178 |
+
$('<img src="' + path + '.png">').on('load', onLoad);
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Vide constructor
|
183 |
+
* @param {HTMLElement} element
|
184 |
+
* @param {Object|String} path
|
185 |
+
* @param {Object|String} options
|
186 |
+
* @constructor
|
187 |
+
*/
|
188 |
+
function Vide(element, path, options) {
|
189 |
+
this.$element = $(element);
|
190 |
+
|
191 |
+
// Parse path
|
192 |
+
if (typeof path === 'string') {
|
193 |
+
path = parseOptions(path);
|
194 |
+
}
|
195 |
+
|
196 |
+
// Parse options
|
197 |
+
if (!options) {
|
198 |
+
options = {};
|
199 |
+
} else if (typeof options === 'string') {
|
200 |
+
options = parseOptions(options);
|
201 |
+
}
|
202 |
+
|
203 |
+
// Remove an extension
|
204 |
+
if (typeof path === 'string') {
|
205 |
+
path = path.replace(/\.\w*$/, '');
|
206 |
+
} else if (typeof path === 'object') {
|
207 |
+
for (var i in path) {
|
208 |
+
if (path.hasOwnProperty(i)) {
|
209 |
+
path[i] = path[i].replace(/\.\w*$/, '');
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
|
214 |
+
this.settings = $.extend({}, DEFAULTS, options);
|
215 |
+
this.path = path;
|
216 |
+
|
217 |
+
// https://github.com/VodkaBears/Vide/issues/110
|
218 |
+
try {
|
219 |
+
this.init();
|
220 |
+
} catch (e) {
|
221 |
+
if (e.message !== NOT_IMPLEMENTED_MSG) {
|
222 |
+
throw e;
|
223 |
+
}
|
224 |
+
}
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* Initialization
|
229 |
+
* @public
|
230 |
+
*/
|
231 |
+
Vide.prototype.init = function() {
|
232 |
+
var vide = this;
|
233 |
+
var path = vide.path;
|
234 |
+
var poster = path;
|
235 |
+
var sources = '';
|
236 |
+
var $element = vide.$element;
|
237 |
+
var settings = vide.settings;
|
238 |
+
var position = parsePosition(settings.position);
|
239 |
+
var posterType = settings.posterType;
|
240 |
+
var $video;
|
241 |
+
var $wrapper;
|
242 |
+
|
243 |
+
// Set styles of a video wrapper
|
244 |
+
$wrapper = vide.$wrapper = $('<div>')
|
245 |
+
.addClass(settings.className)
|
246 |
+
.css({
|
247 |
+
position: 'absolute',
|
248 |
+
'z-index': -1,
|
249 |
+
top: 0,
|
250 |
+
left: 0,
|
251 |
+
bottom: 0,
|
252 |
+
right: 0,
|
253 |
+
overflow: 'hidden',
|
254 |
+
'-webkit-background-size': 'cover',
|
255 |
+
'-moz-background-size': 'cover',
|
256 |
+
'-o-background-size': 'cover',
|
257 |
+
'background-size': 'cover',
|
258 |
+
'background-color': settings.bgColor,
|
259 |
+
'background-repeat': 'no-repeat',
|
260 |
+
'background-position': position.x + ' ' + position.y
|
261 |
+
});
|
262 |
+
|
263 |
+
// Get a poster path
|
264 |
+
if (typeof path === 'object') {
|
265 |
+
if (path.poster) {
|
266 |
+
poster = path.poster;
|
267 |
+
} else {
|
268 |
+
if (path.mp4) {
|
269 |
+
poster = path.mp4;
|
270 |
+
} else if (path.webm) {
|
271 |
+
poster = path.webm;
|
272 |
+
} else if (path.ogv) {
|
273 |
+
poster = path.ogv;
|
274 |
+
}
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
// Set a video poster
|
279 |
+
if (posterType === 'detect') {
|
280 |
+
findPoster(poster, function(url) {
|
281 |
+
$wrapper.css('background-image', 'url(' + url + ')');
|
282 |
+
});
|
283 |
+
} else if (posterType !== 'none') {
|
284 |
+
$wrapper.css('background-image', 'url(' + poster + '.' + posterType + ')');
|
285 |
+
}
|
286 |
+
|
287 |
+
// If a parent element has a static position, make it relative
|
288 |
+
if ($element.css('position') === 'static') {
|
289 |
+
$element.css('position', 'relative');
|
290 |
+
}
|
291 |
+
|
292 |
+
$element.prepend($wrapper);
|
293 |
+
|
294 |
+
if (typeof path === 'object') {
|
295 |
+
if (path.mp4) {
|
296 |
+
sources += '<source src="' + path.mp4 + '.mp4" type="video/mp4">';
|
297 |
+
}
|
298 |
+
|
299 |
+
if (path.webm) {
|
300 |
+
sources += '<source src="' + path.webm + '.webm" type="video/webm">';
|
301 |
+
}
|
302 |
+
|
303 |
+
if (path.ogv) {
|
304 |
+
sources += '<source src="' + path.ogv + '.ogv" type="video/ogg">';
|
305 |
+
}
|
306 |
+
|
307 |
+
$video = vide.$video = $('<video>' + sources + '</video>');
|
308 |
+
} else {
|
309 |
+
$video = vide.$video = $('<video>' +
|
310 |
+
'<source src="' + path + '.mp4" type="video/mp4">' +
|
311 |
+
'<source src="' + path + '.webm" type="video/webm">' +
|
312 |
+
'<source src="' + path + '.ogv" type="video/ogg">' +
|
313 |
+
'</video>');
|
314 |
+
}
|
315 |
+
|
316 |
+
// https://github.com/VodkaBears/Vide/issues/110
|
317 |
+
try {
|
318 |
+
$video
|
319 |
+
|
320 |
+
// Set video properties
|
321 |
+
.prop({
|
322 |
+
autoplay: settings.autoplay,
|
323 |
+
loop: settings.loop,
|
324 |
+
volume: settings.volume,
|
325 |
+
muted: settings.muted,
|
326 |
+
defaultMuted: settings.muted,
|
327 |
+
playbackRate: settings.playbackRate,
|
328 |
+
defaultPlaybackRate: settings.playbackRate
|
329 |
+
});
|
330 |
+
} catch (e) {
|
331 |
+
throw new Error(NOT_IMPLEMENTED_MSG);
|
332 |
+
}
|
333 |
+
|
334 |
+
// Video alignment
|
335 |
+
$video.css({
|
336 |
+
margin: 'auto',
|
337 |
+
position: 'absolute',
|
338 |
+
'z-index': -1,
|
339 |
+
top: position.y,
|
340 |
+
left: position.x,
|
341 |
+
'-webkit-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
342 |
+
'-ms-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
343 |
+
'-moz-transform': 'translate(-' + position.x + ', -' + position.y + ')',
|
344 |
+
transform: 'translate(-' + position.x + ', -' + position.y + ')',
|
345 |
+
|
346 |
+
// Disable visibility, while loading
|
347 |
+
visibility: 'hidden',
|
348 |
+
opacity: 0
|
349 |
+
})
|
350 |
+
|
351 |
+
// Resize a video, when it's loaded
|
352 |
+
.one('canplaythrough.' + PLUGIN_NAME, function() {
|
353 |
+
vide.resize();
|
354 |
+
})
|
355 |
+
|
356 |
+
// Make it visible, when it's already playing
|
357 |
+
.one('playing.' + PLUGIN_NAME, function() {
|
358 |
+
$video.css({
|
359 |
+
visibility: 'visible',
|
360 |
+
opacity: 1
|
361 |
+
});
|
362 |
+
$wrapper.css('background-image', 'none');
|
363 |
+
});
|
364 |
+
|
365 |
+
// Resize event is available only for 'window'
|
366 |
+
// Use another code solutions to detect DOM elements resizing
|
367 |
+
$element.on('resize.' + PLUGIN_NAME, function() {
|
368 |
+
if (settings.resizing) {
|
369 |
+
vide.resize();
|
370 |
+
}
|
371 |
+
});
|
372 |
+
|
373 |
+
// Append a video
|
374 |
+
$wrapper.append($video);
|
375 |
+
};
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Get a video element
|
379 |
+
* @public
|
380 |
+
* @returns {HTMLVideoElement}
|
381 |
+
*/
|
382 |
+
Vide.prototype.getVideoObject = function() {
|
383 |
+
return this.$video[0];
|
384 |
+
};
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Resize a video background
|
388 |
+
* @public
|
389 |
+
*/
|
390 |
+
Vide.prototype.resize = function() {
|
391 |
+
if (!this.$video) {
|
392 |
+
return;
|
393 |
+
}
|
394 |
+
|
395 |
+
var $wrapper = this.$wrapper;
|
396 |
+
var $video = this.$video;
|
397 |
+
var video = $video[0];
|
398 |
+
|
399 |
+
// Get a native video size
|
400 |
+
var videoHeight = video.videoHeight;
|
401 |
+
var videoWidth = video.videoWidth;
|
402 |
+
|
403 |
+
// Get a wrapper size
|
404 |
+
var wrapperHeight = $wrapper.height();
|
405 |
+
var wrapperWidth = $wrapper.width();
|
406 |
+
|
407 |
+
if (wrapperWidth / videoWidth > wrapperHeight / videoHeight) {
|
408 |
+
$video.css({
|
409 |
+
|
410 |
+
// +2 pixels to prevent an empty space after transformation
|
411 |
+
width: wrapperWidth + 2,
|
412 |
+
height: 'auto'
|
413 |
+
});
|
414 |
+
} else {
|
415 |
+
$video.css({
|
416 |
+
width: 'auto',
|
417 |
+
|
418 |
+
// +2 pixels to prevent an empty space after transformation
|
419 |
+
height: wrapperHeight + 2
|
420 |
+
});
|
421 |
+
}
|
422 |
+
};
|
423 |
+
|
424 |
+
/**
|
425 |
+
* Destroy a video background
|
426 |
+
* @public
|
427 |
+
*/
|
428 |
+
Vide.prototype.destroy = function() {
|
429 |
+
delete $[PLUGIN_NAME].lookup[this.index];
|
430 |
+
this.$video && this.$video.off(PLUGIN_NAME);
|
431 |
+
this.$element.off(PLUGIN_NAME).removeData(PLUGIN_NAME);
|
432 |
+
this.$wrapper.remove();
|
433 |
+
};
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Special plugin object for instances.
|
437 |
+
* @public
|
438 |
+
* @type {Object}
|
439 |
+
*/
|
440 |
+
$[PLUGIN_NAME] = {
|
441 |
+
lookup: []
|
442 |
+
};
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Plugin constructor
|
446 |
+
* @param {Object|String} path
|
447 |
+
* @param {Object|String} options
|
448 |
+
* @returns {JQuery}
|
449 |
+
* @constructor
|
450 |
+
*/
|
451 |
+
$.fn[PLUGIN_NAME] = function(path, options) {
|
452 |
+
var instance;
|
453 |
+
|
454 |
+
this.each(function() {
|
455 |
+
instance = $.data(this, PLUGIN_NAME);
|
456 |
+
|
457 |
+
// Destroy the plugin instance if exists
|
458 |
+
instance && instance.destroy();
|
459 |
+
|
460 |
+
// Create the plugin instance
|
461 |
+
instance = new Vide(this, path, options);
|
462 |
+
instance.index = $[PLUGIN_NAME].lookup.push(instance) - 1;
|
463 |
+
$.data(this, PLUGIN_NAME, instance);
|
464 |
+
});
|
465 |
+
|
466 |
+
return this;
|
467 |
+
};
|
468 |
+
|
469 |
+
$(document).ready(function() {
|
470 |
+
var $window = $(window);
|
471 |
+
|
472 |
+
// Window resize event listener
|
473 |
+
$window.on('resize.' + PLUGIN_NAME, function() {
|
474 |
+
for (var len = $[PLUGIN_NAME].lookup.length, i = 0, instance; i < len; i++) {
|
475 |
+
instance = $[PLUGIN_NAME].lookup[i];
|
476 |
+
|
477 |
+
if (instance && instance.settings.resizing) {
|
478 |
+
instance.resize();
|
479 |
+
}
|
480 |
+
}
|
481 |
+
});
|
482 |
+
|
483 |
+
// https://github.com/VodkaBears/Vide/issues/68
|
484 |
+
$window.on('unload.' + PLUGIN_NAME, function() {
|
485 |
+
return false;
|
486 |
+
});
|
487 |
+
|
488 |
+
// Auto initialization
|
489 |
+
// Add 'data-vide-bg' attribute with a path to the video without extension
|
490 |
+
// Also you can pass options throw the 'data-vide-options' attribute
|
491 |
+
// 'data-vide-options' must be like 'muted: false, volume: 0.5'
|
492 |
+
$(document).find('[data-' + PLUGIN_NAME + '-bg]').each(function(i, element) {
|
493 |
+
var $element = $(element);
|
494 |
+
var options = $element.data(PLUGIN_NAME + '-options');
|
495 |
+
var path = $element.data(PLUGIN_NAME + '-bg');
|
496 |
+
|
497 |
+
$element[PLUGIN_NAME](path, options);
|
498 |
+
});
|
499 |
+
});
|
500 |
+
|
501 |
+
});
|
assets/js/vendor/jquery.vide.min.js
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
-
/*
|
2 |
-
* Vide - v0.5.1
|
3 |
-
* Easy as hell jQuery plugin for video backgrounds.
|
4 |
-
* http://vodkabears.github.io/vide/
|
5 |
-
*
|
6 |
-
* Made by Ilya Makarov
|
7 |
-
* Under MIT License
|
8 |
-
*/
|
9 |
!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b("object"==typeof exports?require("jquery"):a.jQuery)}(this,function(a){"use strict";function b(a){var b,c,d,e,f,g,h,i={};for(f=a.replace(/\s*:\s*/g,":").replace(/\s*,\s*/g,",").split(","),h=0,g=f.length;h<g&&(c=f[h],c.search(/^(http|https|ftp):\/\//)===-1&&c.search(":")!==-1);h++)b=c.indexOf(":"),d=c.substring(0,b),e=c.substring(b+1),e||(e=void 0),"string"==typeof e&&(e="true"===e||"false"!==e&&e),"string"==typeof e&&(e=isNaN(e)?e:+e),i[d]=e;return null==d&&null==e?a:i}function c(a){a=""+a;var b,c,d,e=a.split(/\s+/),f="50%",g="50%";for(d=0,b=e.length;d<b;d++)c=e[d],"left"===c?f="0%":"right"===c?f="100%":"top"===c?g="0%":"bottom"===c?g="100%":"center"===c?0===d?f="50%":g="50%":0===d?f=c:g=c;return{x:f,y:g}}function d(b,c){var d=function(){c(this.src)};a('<img src="'+b+'.gif">').on("load",d),a('<img src="'+b+'.jpg">').on("load",d),a('<img src="'+b+'.jpeg">').on("load",d),a('<img src="'+b+'.png">').on("load",d)}function e(c,d,e){if(this.$element=a(c),"string"==typeof d&&(d=b(d)),e?"string"==typeof e&&(e=b(e)):e={},"string"==typeof d)d=d.replace(/\.\w*$/,"");else if("object"==typeof d)for(var f in d)d.hasOwnProperty(f)&&(d[f]=d[f].replace(/\.\w*$/,""));this.settings=a.extend({},g,e),this.path=d;try{this.init()}catch(i){if(i.message!==h)throw i}}var f="vide",g={volume:1,playbackRate:1,muted:!0,loop:!0,autoplay:!0,position:"50% 50%",posterType:"detect",resizing:!0,bgColor:"transparent",className:""},h="Not implemented";e.prototype.init=function(){var b,e,f=this,g=f.path,i=g,j="",k=f.$element,l=f.settings,m=c(l.position),n=l.posterType;e=f.$wrapper=a("<div>").addClass(l.className).css({position:"absolute","z-index":-1,top:0,left:0,bottom:0,right:0,overflow:"hidden","-webkit-background-size":"cover","-moz-background-size":"cover","-o-background-size":"cover","background-size":"cover","background-color":l.bgColor,"background-repeat":"no-repeat","background-position":m.x+" "+m.y}),"object"==typeof g&&(g.poster?i=g.poster:g.mp4?i=g.mp4:g.webm?i=g.webm:g.ogv&&(i=g.ogv)),"detect"===n?d(i,function(a){e.css("background-image","url("+a+")")}):"none"!==n&&e.css("background-image","url("+i+"."+n+")"),"static"===k.css("position")&&k.css("position","relative"),k.prepend(e),"object"==typeof g?(g.mp4&&(j+='<source src="'+g.mp4+'.mp4" type="video/mp4">'),g.webm&&(j+='<source src="'+g.webm+'.webm" type="video/webm">'),g.ogv&&(j+='<source src="'+g.ogv+'.ogv" type="video/ogg">'),b=f.$video=a("<video>"+j+"</video>")):b=f.$video=a('<video><source src="'+g+'.mp4" type="video/mp4"><source src="'+g+'.webm" type="video/webm"><source src="'+g+'.ogv" type="video/ogg"></video>');try{b.prop({autoplay:l.autoplay,loop:l.loop,volume:l.volume,muted:l.muted,defaultMuted:l.muted,playbackRate:l.playbackRate,defaultPlaybackRate:l.playbackRate})}catch(o){throw new Error(h)}b.css({margin:"auto",position:"absolute","z-index":-1,top:m.y,left:m.x,"-webkit-transform":"translate(-"+m.x+", -"+m.y+")","-ms-transform":"translate(-"+m.x+", -"+m.y+")","-moz-transform":"translate(-"+m.x+", -"+m.y+")",transform:"translate(-"+m.x+", -"+m.y+")",visibility:"hidden",opacity:0}).one("canplaythrough.vide",function(){f.resize()}).one("playing.vide",function(){b.css({visibility:"visible",opacity:1}),e.css("background-image","none")}),k.on("resize.vide",function(){l.resizing&&f.resize()}),e.append(b)},e.prototype.getVideoObject=function(){return this.$video[0]},e.prototype.resize=function(){if(this.$video){var a=this.$wrapper,b=this.$video,c=b[0],d=c.videoHeight,e=c.videoWidth,f=a.height(),g=a.width();g/e>f/d?b.css({width:g+2,height:"auto"}):b.css({width:"auto",height:f+2})}},e.prototype.destroy=function(){delete a[f].lookup[this.index],this.$video&&this.$video.off(f),this.$element.off(f).removeData(f),this.$wrapper.remove()},a[f]={lookup:[]},a.fn[f]=function(b,c){var d;return this.each(function(){d=a.data(this,f),d&&d.destroy(),d=new e(this,b,c),d.index=a[f].lookup.push(d)-1,a.data(this,f,d)}),this},a(document).ready(function(){var b=a(window);b.on("resize.vide",function(){for(var b,c=a[f].lookup.length,d=0;d<c;d++)b=a[f].lookup[d],b&&b.settings.resizing&&b.resize()}),b.on("unload.vide",function(){return!1}),a(document).find("[data-vide-bg]").each(function(b,c){var d=a(c),e=d.data("vide-options"),g=d.data("vide-bg");d[f](g,e)})})});
|
1 |
+
/*
|
2 |
+
* Vide - v0.5.1
|
3 |
+
* Easy as hell jQuery plugin for video backgrounds.
|
4 |
+
* http://vodkabears.github.io/vide/
|
5 |
+
*
|
6 |
+
* Made by Ilya Makarov
|
7 |
+
* Under MIT License
|
8 |
+
*/
|
9 |
!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],b):b("object"==typeof exports?require("jquery"):a.jQuery)}(this,function(a){"use strict";function b(a){var b,c,d,e,f,g,h,i={};for(f=a.replace(/\s*:\s*/g,":").replace(/\s*,\s*/g,",").split(","),h=0,g=f.length;h<g&&(c=f[h],c.search(/^(http|https|ftp):\/\//)===-1&&c.search(":")!==-1);h++)b=c.indexOf(":"),d=c.substring(0,b),e=c.substring(b+1),e||(e=void 0),"string"==typeof e&&(e="true"===e||"false"!==e&&e),"string"==typeof e&&(e=isNaN(e)?e:+e),i[d]=e;return null==d&&null==e?a:i}function c(a){a=""+a;var b,c,d,e=a.split(/\s+/),f="50%",g="50%";for(d=0,b=e.length;d<b;d++)c=e[d],"left"===c?f="0%":"right"===c?f="100%":"top"===c?g="0%":"bottom"===c?g="100%":"center"===c?0===d?f="50%":g="50%":0===d?f=c:g=c;return{x:f,y:g}}function d(b,c){var d=function(){c(this.src)};a('<img src="'+b+'.gif">').on("load",d),a('<img src="'+b+'.jpg">').on("load",d),a('<img src="'+b+'.jpeg">').on("load",d),a('<img src="'+b+'.png">').on("load",d)}function e(c,d,e){if(this.$element=a(c),"string"==typeof d&&(d=b(d)),e?"string"==typeof e&&(e=b(e)):e={},"string"==typeof d)d=d.replace(/\.\w*$/,"");else if("object"==typeof d)for(var f in d)d.hasOwnProperty(f)&&(d[f]=d[f].replace(/\.\w*$/,""));this.settings=a.extend({},g,e),this.path=d;try{this.init()}catch(i){if(i.message!==h)throw i}}var f="vide",g={volume:1,playbackRate:1,muted:!0,loop:!0,autoplay:!0,position:"50% 50%",posterType:"detect",resizing:!0,bgColor:"transparent",className:""},h="Not implemented";e.prototype.init=function(){var b,e,f=this,g=f.path,i=g,j="",k=f.$element,l=f.settings,m=c(l.position),n=l.posterType;e=f.$wrapper=a("<div>").addClass(l.className).css({position:"absolute","z-index":-1,top:0,left:0,bottom:0,right:0,overflow:"hidden","-webkit-background-size":"cover","-moz-background-size":"cover","-o-background-size":"cover","background-size":"cover","background-color":l.bgColor,"background-repeat":"no-repeat","background-position":m.x+" "+m.y}),"object"==typeof g&&(g.poster?i=g.poster:g.mp4?i=g.mp4:g.webm?i=g.webm:g.ogv&&(i=g.ogv)),"detect"===n?d(i,function(a){e.css("background-image","url("+a+")")}):"none"!==n&&e.css("background-image","url("+i+"."+n+")"),"static"===k.css("position")&&k.css("position","relative"),k.prepend(e),"object"==typeof g?(g.mp4&&(j+='<source src="'+g.mp4+'.mp4" type="video/mp4">'),g.webm&&(j+='<source src="'+g.webm+'.webm" type="video/webm">'),g.ogv&&(j+='<source src="'+g.ogv+'.ogv" type="video/ogg">'),b=f.$video=a("<video>"+j+"</video>")):b=f.$video=a('<video><source src="'+g+'.mp4" type="video/mp4"><source src="'+g+'.webm" type="video/webm"><source src="'+g+'.ogv" type="video/ogg"></video>');try{b.prop({autoplay:l.autoplay,loop:l.loop,volume:l.volume,muted:l.muted,defaultMuted:l.muted,playbackRate:l.playbackRate,defaultPlaybackRate:l.playbackRate})}catch(o){throw new Error(h)}b.css({margin:"auto",position:"absolute","z-index":-1,top:m.y,left:m.x,"-webkit-transform":"translate(-"+m.x+", -"+m.y+")","-ms-transform":"translate(-"+m.x+", -"+m.y+")","-moz-transform":"translate(-"+m.x+", -"+m.y+")",transform:"translate(-"+m.x+", -"+m.y+")",visibility:"hidden",opacity:0}).one("canplaythrough.vide",function(){f.resize()}).one("playing.vide",function(){b.css({visibility:"visible",opacity:1}),e.css("background-image","none")}),k.on("resize.vide",function(){l.resizing&&f.resize()}),e.append(b)},e.prototype.getVideoObject=function(){return this.$video[0]},e.prototype.resize=function(){if(this.$video){var a=this.$wrapper,b=this.$video,c=b[0],d=c.videoHeight,e=c.videoWidth,f=a.height(),g=a.width();g/e>f/d?b.css({width:g+2,height:"auto"}):b.css({width:"auto",height:f+2})}},e.prototype.destroy=function(){delete a[f].lookup[this.index],this.$video&&this.$video.off(f),this.$element.off(f).removeData(f),this.$wrapper.remove()},a[f]={lookup:[]},a.fn[f]=function(b,c){var d;return this.each(function(){d=a.data(this,f),d&&d.destroy(),d=new e(this,b,c),d.index=a[f].lookup.push(d)-1,a.data(this,f,d)}),this},a(document).ready(function(){var b=a(window);b.on("resize.vide",function(){for(var b,c=a[f].lookup.length,d=0;d<c;d++)b=a[f].lookup[d],b&&b.settings.resizing&&b.resize()}),b.on("unload.vide",function(){return!1}),a(document).find("[data-vide-bg]").each(function(b,c){var d=a(c),e=d.data("vide-options"),g=d.data("vide-bg");d[f](g,e)})})});
|
assets/js/vendor/jquery.youtubebackground.js
CHANGED
@@ -1,334 +1,334 @@
|
|
1 |
-
/*
|
2 |
-
* YoutubeBackground - A wrapper for the Youtube API - Great for fullscreen background videos or just regular videos.
|
3 |
-
*
|
4 |
-
* Licensed under the MIT license:
|
5 |
-
* http://www.opensource.org/licenses/mit-license.php
|
6 |
-
*
|
7 |
-
*
|
8 |
-
* Version: 1.0.5
|
9 |
-
*
|
10 |
-
*/
|
11 |
-
|
12 |
-
// Chain of Responsibility pattern. Creates base class that can be overridden.
|
13 |
-
if ( typeof Object.create !== "function" ) {
|
14 |
-
Object.create = function (obj) {
|
15 |
-
function F() {
|
16 |
-
}
|
17 |
-
|
18 |
-
F.prototype = obj;
|
19 |
-
return new F();
|
20 |
-
};
|
21 |
-
}
|
22 |
-
|
23 |
-
(function ($, window, document) {
|
24 |
-
var
|
25 |
-
loadAPI = function loadAPI(callback) {
|
26 |
-
|
27 |
-
// Load Youtube API
|
28 |
-
var tag = document.createElement('script'),
|
29 |
-
head = document.getElementsByTagName('head')[ 0 ];
|
30 |
-
|
31 |
-
if ( window.location.origin == 'file://' ) {
|
32 |
-
tag.src = 'http://www.youtube.com/iframe_api';
|
33 |
-
} else {
|
34 |
-
tag.src = '//www.youtube.com/iframe_api';
|
35 |
-
}
|
36 |
-
|
37 |
-
head.appendChild(tag);
|
38 |
-
|
39 |
-
// Clean up Tags.
|
40 |
-
head = null;
|
41 |
-
tag = null;
|
42 |
-
|
43 |
-
iframeIsReady(callback);
|
44 |
-
},
|
45 |
-
iframeIsReady = function iframeIsReady(callback) {
|
46 |
-
// Listen for Gobal YT player callback
|
47 |
-
if ( typeof YT === 'undefined' && typeof window.loadingPlayer === 'undefined' ) {
|
48 |
-
// Prevents Ready Event from being called twice
|
49 |
-
window.loadingPlayer = true;
|
50 |
-
|
51 |
-
|
52 |
-
// Creates deferred so, other players know when to wait.
|
53 |
-
window.dfd = $.Deferred();
|
54 |
-
window.onYouTubeIframeAPIReady = function () {
|
55 |
-
window.onYouTubeIframeAPIReady = null;
|
56 |
-
window.dfd.resolve("done");
|
57 |
-
callback();
|
58 |
-
};
|
59 |
-
} else if ( typeof YT === 'object' ) {
|
60 |
-
callback();
|
61 |
-
} else {
|
62 |
-
window.dfd.done(function (name) {
|
63 |
-
callback();
|
64 |
-
});
|
65 |
-
}
|
66 |
-
};
|
67 |
-
|
68 |
-
// YTPlayer Object
|
69 |
-
YTPlayer = {
|
70 |
-
player: null,
|
71 |
-
|
72 |
-
// Defaults
|
73 |
-
defaults: {
|
74 |
-
ratio : 16 / 9,
|
75 |
-
videoId : 'LSmgKRx5pBo',
|
76 |
-
mute : true,
|
77 |
-
repeat : true,
|
78 |
-
width : $(window).width(),
|
79 |
-
playButtonClass : 'YTPlayer-play',
|
80 |
-
pauseButtonClass: 'YTPlayer-pause',
|
81 |
-
muteButtonClass : 'YTPlayer-mute',
|
82 |
-
volumeUpClass : 'YTPlayer-volume-up',
|
83 |
-
volumeDownClass : 'YTPlayer-volume-down',
|
84 |
-
start : 0,
|
85 |
-
pauseOnScroll : false,
|
86 |
-
fitToBackground : true,
|
87 |
-
playerVars : {
|
88 |
-
iv_load_policy: 3,
|
89 |
-
modestbranding: 1,
|
90 |
-
autoplay : 1,
|
91 |
-
controls : 0,
|
92 |
-
showinfo : 0,
|
93 |
-
wmode : 'opaque',
|
94 |
-
branding : 0,
|
95 |
-
autohide : 0
|
96 |
-
},
|
97 |
-
events : null
|
98 |
-
},
|
99 |
-
|
100 |
-
/**
|
101 |
-
* @function init
|
102 |
-
* Intializes YTPlayer object
|
103 |
-
*/
|
104 |
-
init: function init(node, userOptions) {
|
105 |
-
var self = this;
|
106 |
-
|
107 |
-
self.userOptions = userOptions;
|
108 |
-
|
109 |
-
self.$body = $('body'),
|
110 |
-
self.$node = $(node),
|
111 |
-
self.$window = $(window);
|
112 |
-
|
113 |
-
// Setup event defaults with the reference to this
|
114 |
-
self.defaults.events = {
|
115 |
-
'onReady' : function (e) {
|
116 |
-
self.onPlayerReady(e);
|
117 |
-
|
118 |
-
// setup up pause on scroll
|
119 |
-
if ( self.options.pauseOnScroll ) {
|
120 |
-
self.pauseOnScroll();
|
121 |
-
}
|
122 |
-
|
123 |
-
// Callback for when finished
|
124 |
-
if ( typeof self.options.callback == 'function' ) {
|
125 |
-
self.options.callback.call(this);
|
126 |
-
}
|
127 |
-
},
|
128 |
-
'onStateChange': function (e) {
|
129 |
-
if ( e.data === 1 ) {
|
130 |
-
|
131 |
-
self.$node.find('img').fadeOut(400);
|
132 |
-
self.$node.addClass('loaded');
|
133 |
-
} else if ( e.data === 0 && self.options.repeat ) { // video ended and repeat option is set true
|
134 |
-
self.player.seekTo(self.options.start);
|
135 |
-
}
|
136 |
-
}
|
137 |
-
}
|
138 |
-
|
139 |
-
|
140 |
-
self.options = $.extend(true, {}, self.defaults, self.userOptions);
|
141 |
-
self.options.height = Math.ceil(self.options.width / self.options.ratio);
|
142 |
-
self.ID = (new Date()).getTime();
|
143 |
-
self.holderID = 'YTPlayer-ID-' + self.ID;
|
144 |
-
|
145 |
-
if ( self.options.fitToBackground ) {
|
146 |
-
self.createBackgroundVideo();
|
147 |
-
} else {
|
148 |
-
self.createContainerVideo();
|
149 |
-
}
|
150 |
-
// Listen for Resize Event
|
151 |
-
self.$window.on('resize.YTplayer' + self.ID, function () {
|
152 |
-
self.resize(self);
|
153 |
-
});
|
154 |
-
|
155 |
-
loadAPI(self.onYouTubeIframeAPIReady.bind(self));
|
156 |
-
|
157 |
-
self.resize(self);
|
158 |
-
|
159 |
-
return self;
|
160 |
-
},
|
161 |
-
|
162 |
-
|
163 |
-
/**
|
164 |
-
* @function pauseOnScroll
|
165 |
-
* Adds window events to pause video on scroll.
|
166 |
-
*/
|
167 |
-
pauseOnScroll : function pauseOnScroll() {
|
168 |
-
var self = this;
|
169 |
-
self.$window.on('scroll.YTplayer' + self.ID, function () {
|
170 |
-
var state = self.player.getPlayerState();
|
171 |
-
if ( state === 1 ) {
|
172 |
-
self.player.pauseVideo();
|
173 |
-
}
|
174 |
-
});
|
175 |
-
self.$window.scrollStopped(function () {
|
176 |
-
var state = self.player.getPlayerState();
|
177 |
-
if ( state === 2 ) {
|
178 |
-
self.player.playVideo();
|
179 |
-
}
|
180 |
-
});
|
181 |
-
},
|
182 |
-
/**
|
183 |
-
* @function createContainerVideo
|
184 |
-
* Adds HTML for video in a container
|
185 |
-
*/
|
186 |
-
createContainerVideo: function createContainerVideo() {
|
187 |
-
var self = this;
|
188 |
-
|
189 |
-
/*jshint multistr: true */
|
190 |
-
var $YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" >\
|
191 |
-
<div id="' + self.holderID + '" class="ytplayer-player-inline"></div> \
|
192 |
-
</div> \
|
193 |
-
<div id="ytplayer-shield" class="ytplayer-shield"></div>');
|
194 |
-
|
195 |
-
self.$node.append($YTPlayerString);
|
196 |
-
self.$YTPlayerString = $YTPlayerString;
|
197 |
-
$YTPlayerString = null;
|
198 |
-
},
|
199 |
-
|
200 |
-
/**
|
201 |
-
* @function createBackgroundVideo
|
202 |
-
* Adds HTML for video background
|
203 |
-
*/
|
204 |
-
createBackgroundVideo: function createBackgroundVideo() {
|
205 |
-
/*jshint multistr: true */
|
206 |
-
var self = this,
|
207 |
-
$YTPlayerString = $('<div id="ytplayer-container' + self.ID + '" class="ytplayer-container background">\
|
208 |
-
<div id="' + self.holderID + '" class="ytplayer-player"></div>\
|
209 |
-
</div>\
|
210 |
-
<div id="ytplayer-shield" class="ytplayer-shield"></div>');
|
211 |
-
|
212 |
-
self.$node.append($YTPlayerString);
|
213 |
-
self.$YTPlayerString = $YTPlayerString;
|
214 |
-
$YTPlayerString = null;
|
215 |
-
},
|
216 |
-
|
217 |
-
/**
|
218 |
-
* @function resize
|
219 |
-
* Resize event to change video size
|
220 |
-
*/
|
221 |
-
resize: function resize(self) {
|
222 |
-
//var self = this;
|
223 |
-
var container = $(window);
|
224 |
-
|
225 |
-
if ( !self.options.fitToBackground ) {
|
226 |
-
container = self.$node;
|
227 |
-
}
|
228 |
-
|
229 |
-
var width = container.width(),
|
230 |
-
pWidth, // player width, to be defined
|
231 |
-
height = container.height(),
|
232 |
-
pHeight, // player height, tbd
|
233 |
-
$YTPlayerPlayer = $('#' + self.holderID);
|
234 |
-
|
235 |
-
// when screen aspect ratio differs from video, video must center and underlay one dimension
|
236 |
-
if ( width / self.options.ratio < height ) {
|
237 |
-
pWidth = Math.ceil(height * self.options.ratio); // get new player width
|
238 |
-
$YTPlayerPlayer.width(pWidth).height(height).css({
|
239 |
-
left: (width - pWidth) / 2,
|
240 |
-
top : 0
|
241 |
-
}); // player width is greater, offset left; reset top
|
242 |
-
} else { // new video width < window width (gap to right)
|
243 |
-
pHeight = Math.ceil(width / self.options.ratio); // get new player height
|
244 |
-
$YTPlayerPlayer.width(width).height(pHeight).css({
|
245 |
-
left: 0,
|
246 |
-
top : (height - pHeight) / 2
|
247 |
-
}); // player height is greater, offset top; reset left
|
248 |
-
}
|
249 |
-
|
250 |
-
$YTPlayerPlayer = null;
|
251 |
-
container = null;
|
252 |
-
},
|
253 |
-
|
254 |
-
/**
|
255 |
-
* @function onYouTubeIframeAPIReady
|
256 |
-
* @ params {object} YTPlayer object for access to options
|
257 |
-
* Youtube API calls this function when the player is ready.
|
258 |
-
*/
|
259 |
-
onYouTubeIframeAPIReady: function onYouTubeIframeAPIReady() {
|
260 |
-
var self = this;
|
261 |
-
self.player = new window.YT.Player(self.holderID, self.options);
|
262 |
-
},
|
263 |
-
|
264 |
-
/**
|
265 |
-
* @function onPlayerReady
|
266 |
-
* @ params {event} window event from youtube player
|
267 |
-
*/
|
268 |
-
onPlayerReady: function onPlayerReady(e) {
|
269 |
-
if ( this.options.mute ) {
|
270 |
-
e.target.mute();
|
271 |
-
}
|
272 |
-
if ( this.options.playerVars.autoplay ) {
|
273 |
-
e.target.playVideo();
|
274 |
-
}
|
275 |
-
$(document).trigger('YTBGREADY', {player: true});
|
276 |
-
},
|
277 |
-
|
278 |
-
/**
|
279 |
-
* @function getPlayer
|
280 |
-
* returns youtube player
|
281 |
-
*/
|
282 |
-
getPlayer: function getPlayer() {
|
283 |
-
return this.player;
|
284 |
-
},
|
285 |
-
|
286 |
-
/**
|
287 |
-
* @function destroy
|
288 |
-
* destroys all!
|
289 |
-
*/
|
290 |
-
destroy: function destroy() {
|
291 |
-
var self = this;
|
292 |
-
|
293 |
-
self.$node
|
294 |
-
.removeData('yt-init')
|
295 |
-
.removeData('ytPlayer')
|
296 |