PluginProbe
FV Player 8 / 8.1
FV Player 8 v8.1
trunk 8.0.18 8.0.19 8.0.20 8.0.21 8.0.25 8.0.27 8.1 8.1.3
fv-player / js / admin.js

admin.js in FV Player 8 8.1, at js/admin.js

432 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*global cm_settings */
2
3 (function ($) {
4 ('use strict');
5
6 /*
7 * Skin live preview
8 */
9 function hexToRgb(hex) {
10 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
11 return result ? [
12 parseInt(result[1], 16),
13 parseInt(result[2], 16),
14 parseInt(result[3], 16)
15 ] : null;
16 }
17
18 function rgb2hex(rgb){
19 rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i);
20 return (rgb && rgb.length === 4) ? "#" +
21 ("0" + parseInt(rgb[1],10).toString(16)).slice(-2).toUpperCase() +
22 ("0" + parseInt(rgb[2],10).toString(16)).slice(-2).toUpperCase() +
23 ("0" + parseInt(rgb[3],10).toString(16)).slice(-2).toUpperCase() : '';
24 }
25
26
27 function sanitizeCSS(val) {
28 if (val.indexOf('#rgba') > -1) {
29 val = val.replace(/#rgba/g, 'rgba');
30 } else if (val.indexOf('#transparent') > -1) {
31 val = val.replace(/#transparent/g, 'transparent');
32 }
33
34 if( val.match(/# !/) ) {
35 val = false;
36 }
37
38 return val;
39 }
40
41 if (!String.prototype.endsWith)
42 String.prototype.endsWith = function(searchStr, Position) {
43 // This works much better than >= because
44 // it compensates for NaN:
45 if (!(Position < this.length))
46 Position = this.length;
47 else
48 Position |= 0; // round position
49 return this.substr(Position - searchStr.length,
50 searchStr.length) === searchStr;
51 };
52
53 $(document).ready(function () {
54 $('[data-fv-skin]').on('input click', function () {
55 $('[data-fv-skin]').each( function() {
56 $('.flowplayer').removeClass( 'skin-'+$(this).val() );
57 });
58 $('.flowplayer').addClass( 'skin-'+$(this).val() );
59
60 // hide currently visible settings tables
61 $('#skin-Custom-settings, #skin-Slim-settings, #skin-YouTuby-settings').hide();
62
63 // show the relevant settings table
64 $('#' + this.id + '-settings').show();
65
66
67
68 // update CSS
69 skinPreviewInputChanged();
70 });
71
72 // cache this, it's quite expensive to select via data attribute
73 var $previewElements = $('[data-fv-preview]');
74
75 // dropdown value changes (slim type, icon types)
76 function skinPreviewDropdownChanged() {
77 style = '';
78 $previewElements.each(function() {
79 var
80 $this = $(this),
81 $parent = $this.closest('table');
82
83 // don't change to values of another skin but to our currently visible skin type
84 if ($parent.css('display') == 'none') {
85 return;
86 }
87
88 // playlist design style change
89 if ($this.attr('name').endsWith('playlist-design')) {
90 var
91 $external_playlist = $('.fp-playlist-external'),
92 match = $external_playlist.attr('class').match(/fv-playlist-design-\S+/);
93
94 if (match) {
95 $external_playlist.removeClass(match[0]);
96 }
97
98 $external_playlist
99 .removeClass('visible-captions')
100 .addClass('fv-playlist-design-' + $this.val());
101
102 } else if ($this.attr('name').endsWith('design-timeline]')) {
103 // timeline design style change
104 $('.flowplayer')
105 .removeClass('fp-slim fp-full fp-fat fp-minimal')
106 .addClass($this.val());
107 } else if ($this.attr('name').endsWith('design-icons]')) {
108 $('.flowplayer')
109 .removeClass('fp-edgy fp-outlined fp-playful')
110 .addClass($this.val());
111
112 } else if ( 'logoPosition' === $this.attr('name') ) {
113 if ( fv_player_admin.css_logo_positions[ $this.val() ] ) {
114 style += "\n" + '.flowplayer-wrapper .freedomplayer .fp-logo img { ' + fv_player_admin.css_logo_positions[ $this.val() ] + ' }';
115 }
116 }
117 });
118
119 return style;
120 }
121
122 // input (textbox, checkbox) value changes
123 function skinPreviewInputChanged() {
124 var style = '';
125
126 $previewElements.each(function () {
127
128 var
129 newStyle = '',
130 $this = $(this),
131 $parent = $this.closest('table');
132
133 var preview = $this.data('fv-preview').replace(/\.flowplayer/g,'.flowplayer.skin-'+jQuery('[data-fv-skin]:checked').val() );
134
135 if ($parent.css('display') == 'none') {
136 return;
137 }
138
139 if ( 'logo' === $this.attr('name') ) {
140 let player = $( '.flowplayer-wrapper .freedomplayer' ),
141 logo_url = $this.val();
142
143 /**
144 * Only show preview if the logo is valid and is different from the default.
145 * This prevents the logo showing before the video is started, but at the same
146 * time show if if user picks are different image.
147 */
148 if ( logo_url.match( /^https?:\/\/.*?\.(jpg|jpe|jpeg|gif|png)$/i ) && ( logo_url !== freedomplayer.conf.logo || player.hasClass( 'is-ready' ) ) ) {
149 player.find( '.fp-logo' ).remove();
150
151 // Update the logo in the loaded player
152 let api = player.data( 'freedomplayer' )
153 if ( api ) {
154 api.conf.logo = logo_url.trim();
155 }
156
157 let img = new Image();
158 img.src = logo_url.trim();
159
160 let logo = $( '<a class="fp-logo"></a>' );
161 logo.append( img );
162
163 $( '.flowplayer-wrapper .freedomplayer .fp-ui' ).eq(0).after( logo );
164
165 if ( api ) {
166 api.setLogoPosition();
167 }
168 }
169
170 } else if($this.attr('type') == 'checkbox' ) {
171 if ($this.prop('checked')) {
172 newStyle = preview.replace(/%val%/g, '1');
173 } else {
174 newStyle = preview.replace(/%val%/g, '0');
175 }
176 style += sanitizeCSS(newStyle);
177
178 } else {
179 var value = $this.val().replace(/^#/,''),
180 opacity = $this.minicolors('opacity'),
181 color = hexToRgb(value);
182
183 if( opacity && color ) {
184 value = 'rgba('+color[0]+','+color[1]+','+color[2]+','+opacity+')';
185 }
186 newStyle = preview.replace(/%val%/g, value);
187 style += sanitizeCSS(newStyle);
188
189 }
190 }, 0);
191
192 // update progress bar + icons style
193 style += skinPreviewDropdownChanged();
194
195 show_player_controls_for_preview();
196
197 $('#fv-style-preview').html(style);
198 }
199
200 // color inputs + checkbox changes
201 $previewElements.on('input change', skinPreviewInputChanged);
202 $previewElements.eq(0).trigger('input');
203
204 $('[data-fv-preview]').on('select change', skinPreviewDropdownChanged);
205
206 /**
207 * Preview code for Controls tab of Skin
208 */
209 let player = $( '.freedomplayer' );
210
211 $( '#show_controlbar' ).on( 'change', function() {
212 player.toggleClass( 'fixed-controls', $( this ).prop( 'checked' ) );
213 } );
214
215
216 function show_player_controls_for_preview() {
217 $( '.freedomplayer' ).addClass( 'is-mouseover' ).removeClass( 'is-mouseout is-poster is-splash' );
218 }
219
220 /**
221 *
222 * @param {string} selector
223 * @param {Object[]} options
224 * @param {string} options.cb_enabled api method to call when checkbox is checked
225 * @param {string} options.cb_disabled api method to call when checkbox is unchecked
226 * @param {string} options.conf_key api.conf key to set to true/false
227 * @param {string} options.data Player element data-{data} attribute to set to true/false
228 * @param {string} options.selector_disabled Element to remove when checkbox is unchecked
229 * @param {string} options.show_hide Element to show/hide
230 */
231 function controlsPreviewCheckbox( selector, options ) {
232 $(selector).on('change', function() {
233 let api = player.data( 'freedomplayer' ),
234 is_checked = $(this).prop('checked');
235
236 if ( options.conf_key ) {
237 api.conf[ options.conf_key ] = is_checked;
238 }
239
240 if ( options.data ) {
241 player.attr( 'data-' + options.data, is_checked );
242 }
243
244 if ( options.show_hide ) {
245 player.find( options.show_hide ).toggle( is_checked );
246 }
247
248 if ( is_checked ) {
249 if ( options.cb_enabled ) {
250 api[ options.cb_enabled ]();
251 }
252
253 } else {
254 if ( options.cb_disabled ) {
255 api[ options.cb_disabled ]();
256 }
257
258 if ( options.selector_disabled ) {
259 player.find( options.selector_disabled ).remove();
260 }
261 }
262
263 show_player_controls_for_preview();
264 });
265 }
266
267 // Airplay
268 controlsPreviewCheckbox( '#ui_airplay', {
269 conf_key: 'airplay',
270 cb_enabled: 'createAirplayButton',
271 selector_disabled: '.fp-airplay'
272 } );
273
274 // Chromecast
275 controlsPreviewCheckbox( '#chromecast', {
276 conf_key: 'chromecast',
277 cb_enabled: 'createChromecastButton',
278 selector_disabled: '.fp-chromecast'
279 } );
280
281 // Fullscreen
282 // TODO: Not working when initially off and then enabled
283 controlsPreviewCheckbox( '#allowfullscreen', {
284 conf_key: 'fullscreen',
285 data: 'fullscreen',
286 show_hide: '.fp-fullscreen'
287 } );
288
289 // No Picture
290 controlsPreviewCheckbox( '#ui_no_picture_button', {
291 cb_enabled: 'createNoPictureButton',
292 data: 'button-no_picture',
293 selector_disabled: '.fv-fp-no-picture'
294 } );
295
296 // Repeat
297 controlsPreviewCheckbox( '#ui_repeat_button', {
298 cb_enabled: 'createRepeatButton',
299 data: 'button-repeat',
300 selector_disabled: '.fv-fp-playlist, .fv-fp-playlist-menu'
301 } );
302
303 // Rewind/Forward
304 controlsPreviewCheckbox( '#ui_rewind_button', {
305 cb_enabled: 'createRewindForwardButtons',
306 data: 'button-rewind',
307 selector_disabled: '.fv-fp-rewind, .fv-fp-forward'
308 } );
309
310 // Speed
311 controlsPreviewCheckbox( '#ui_speed', {
312 cb_disabled: 'removeSpeedButton',
313 cb_enabled: 'createSpeedButton',
314 data: 'speedb',
315 } );
316
317 // Logo -> Align to video
318 controlsPreviewCheckbox( '#logo_over_video', {
319 conf_key: 'logo_over_video',
320 cb_enabled: 'setLogoPosition',
321 cb_disabled: 'setLogoPosition',
322 } );
323 });
324
325 $(document).ready( function() {
326 var settings = {
327 animationSpeed: 0,
328 changeDelay: 10,
329 letterCase: 'uppercase'
330 }
331 $('input.color').minicolors(settings);
332 settings.opacity = true;
333 $('input.color-opacity').minicolors(settings);
334
335 $('input.color, input.color-opacity').on('change', color_inputs);
336 $('input.color, input.color-opacity').each(color_inputs);
337
338 $('form#wpfp_options').on('submit', function(e) {
339 $( document ).trigger( 'fv-wordpress-flowplayer-save' );
340 });
341
342 $( document ).on( 'fv-wordpress-flowplayer-save', function() {
343 $('input.color-opacity').each( function() {
344 var input = $(this),
345 opacity = input.minicolors('opacity'),
346 color = hexToRgb( input.val() );
347
348 if( opacity && color ) {
349 input.val( 'rgba('+color[0]+','+color[1]+','+color[2]+','+opacity+')' );
350 }
351 });
352 });
353 });
354
355 $(document).ready( function() {
356 $(document).on('click', 'a[data-setting-change]', function(e) {
357 e.preventDefault();
358
359 var name = $(this).data('setting-change'),
360 index,
361 hidden_input,
362 password_input;
363
364 if(name.match(/-index-(\d)+$/)) {
365 var match = name.match(/-index-(\d)+$/);
366 index = parseInt(match[1]);
367 name = name.replace( match[0],'');
368 hidden_input = $("[name='"+name+"']").eq(index);
369 password_input = $("[name='"+name.replace('_is_secret_', '')+"']").eq(index);
370 } else {
371 hidden_input = $("[name='"+name+"']");
372 password_input = $("[name='"+name.replace('_is_secret_', '')+"']");
373 }
374
375 var secret_preview = $(this).siblings('.secret-preview');
376
377 if( hidden_input.val() == '1' ) {
378 hidden_input.val('0');
379 password_input.show();
380 secret_preview.hide();
381 $(this).text('Cancel');
382 } else {
383 hidden_input.val('1');
384 password_input.hide();
385 if( password_input.val() || !$(this).data('is-empty') ) {
386 $(this).text('Change');
387 secret_preview.show();
388 }
389 }
390
391 });
392 });
393
394 function color_inputs() {
395 var input = $(this);
396 var color = input.val();
397 var rgba = hexToRgb( color );
398 if( color.match(/rgba\(.*?\)/) ) {
399 rgba = hexToRgb( rgb2hex(color) );
400 input.val( rgb2hex(color) );
401 }
402
403 var opacity = input.minicolors('opacity');
404
405 if( rgba && ( opacity ) ) {
406 input.css('box-shadow', 'inset 0 0 0 1000px rgba('+rgba[0]+','+rgba[1]+','+rgba[2]+','+opacity+')' );
407 } else {
408 input.css('background-color', input.val());
409 }
410
411 if( rgba && (
412 (rgba[0] < 160 && rgba[1] < 160) || (rgba[1] < 160 && rgba[2] < 160) || (rgba[0] < 160 && rgba[2] < 160)
413 ) ) {
414 input.css('color', 'white');
415 } else {
416 input.css('color', '');
417 }
418 }
419
420 /* CodeMirror */
421 jQuery(function($) {
422 if( $('#customCSS').length && wp.codeEditor ) {
423 var editor_instance = wp.codeEditor.initialize($('#customCSS'), cm_settings);
424
425 // Used in ajax saving
426 window.fv_player_settings_custom_css_codeMirror = editor_instance;
427
428 }
429 });
430
431 }(jQuery));
432