PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.5.4
Responsive Lightbox & Gallery v2.5.4
2.7.8 trunk 1.0.0 1.0.1 1.0.1.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4.0 1.4.0.1 1.4.1 1.4.11 1.4.12 1.4.13 1.4.14 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3.1 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.3.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7
responsive-lightbox / js / admin-galleries.js
responsive-lightbox / js Last commit date
admin-folders.js 7 months ago admin-galleries.js 3 years ago admin-gallery.js 4 years ago admin-media.js 1 year ago admin-plugins.js 3 years ago admin-widgets.js 3 years ago admin.js 3 years ago front-basicmasonry.js 3 years ago front-basicslider.js 1 year ago front.js 7 months ago gutenberg.min.js 7 months ago
admin-galleries.js
1203 lines
1 ( function( $ ) {
2
3 /**
4 * Ready event.
5 */
6 $( function() {
7 var galleryFrame = null;
8 var embedFrame = null;
9 var attachmentFrame = null;
10 var galleryContainer = $( '.rl-gallery-images' );
11 var galleryIds = $( '.rl-gallery-ids' );
12 var embedNumber = galleryContainer.find( 'li[data-type="embed"]' ).length;
13 var mediaProviders = {};
14 var secondaryToolbar = false;
15
16 // activate sortable media gallery
17 mediaGallerySortable( galleryContainer, galleryIds, $( 'input[name="rl_gallery[images][menu_item]"]:checked' ).val() );
18
19 // init galleries
20 initGalleries();
21
22 /**
23 * Handle navigation menu in the "Gallery Images" tab.
24 */
25 $( document ).on( 'change', '.rl-gallery-tab-menu-item', function() {
26 var tab = $( this ).closest( '.postbox' ).attr( 'id' ).replace( 'responsive-gallery-', '' );
27 var source = $( this ).closest( '.rl-gallery-tab-menu' );
28 var container = $( this ).closest( '.inside' ).find( '.rl-gallery-tab-content' );
29 var spinner = source.find( '.spinner' );
30 var menuItem = $( this ).val();
31
32 // disable nav on ajax
33 container.addClass( 'rl-loading-content' );
34 source.addClass( 'rl-loading-content' );
35
36 // display spinner
37 spinner.fadeIn( 'fast' ).css( 'visibility', 'visible' );
38
39 // post ajax request
40 $.post( ajaxurl, {
41 action: 'rl-get-menu-content',
42 post_id: rlArgsGalleries.postId,
43 tab: tab,
44 menu_item: menuItem,
45 nonce: rlArgsGalleries.nonce
46 } ).done( function( response ) {
47 try {
48 if ( response.success ) {
49 // replace HTML
50 container.html( response.data );
51
52 // enable nav after ajax
53 container.removeClass( 'rl-loading-content' );
54 source.removeClass( 'rl-loading-content' );
55
56 // update gallery data
57 galleryFrame = null;
58 galleryContainer = $( '.rl-gallery-images' );
59 galleryIds = $( '.rl-gallery-ids' );
60
61 // refresh sortable only for media library
62 mediaGallerySortable( galleryContainer, galleryIds, menuItem );
63
64 // refresh color picker
65 container.find( '.color-picker' ).wpColorPicker();
66 } else {
67 // @todo
68 }
69 } catch ( e ) {
70 // @todo
71 }
72 } ).always( function() {
73 // hide spinner
74 spinner.fadeOut( 'fast' );
75 } );
76 } );
77
78 /**
79 * Handle navigation menu of tabs.
80 */
81 $( document ).on( 'click', '.nav-tab', function( e ) {
82 e.preventDefault();
83
84 var anchor = $( this ).attr( 'href' ).substr( 1 );
85
86 // remove active class
87 $( '.nav-tab' ).removeClass( 'nav-tab-active' );
88
89 // add active class
90 $( this ).addClass( 'nav-tab-active' );
91
92 // hide all normal metaboxes
93 $( '#responsive_lightbox_metaboxes-sortables div[id^="responsive-gallery-"]' ).removeClass( 'rl-display-metabox' ).addClass( 'rl-hide-metabox' );
94
95 // display needed metabox
96 if ( anchor === '' )
97 $( '#responsive-gallery-images' ).addClass( 'rl-display-metabox' ).removeClass( 'rl-hide-metabox' );
98 else
99 $( '#responsive-gallery-' + anchor ).addClass( 'rl-display-metabox' ).removeClass( 'rl-hide-metabox' );
100
101 $( 'input[name="rl_active_tab"]' ).val( anchor );
102 } );
103
104 /**
105 * Mark shortcode.
106 */
107 $( '.rl-shortcode' ).on( 'click', function() {
108 var number = $( this ).data( 'number' );
109 var el = document.getElementsByClassName( 'rl-shortcode' ).item( number );
110 var selection = window.getSelection();
111
112 // remove all selections
113 selection.removeAllRanges();
114
115 var range = document.createRange();
116
117 // select node
118 range.selectNodeContents( el );
119
120 // select content
121 selection.addRange( range );
122 } );
123
124 /**
125 * Remove image.
126 */
127 $( document ).on( 'click', '.rl-gallery-image-remove', function( e ) {
128 e.preventDefault();
129
130 // prevent featured images being removed
131 if ( $( this ).closest( '.rl-gallery-images-featured' ).length === 1 )
132 return false;
133
134 var li = $( this ).closest( 'li.rl-gallery-image' );
135 var attachmentIds = getCurrentAttachments( galleryIds, false );
136
137 // remove id
138 attachmentIds = _.without( attachmentIds, li.data( 'attachment_id' ) );
139
140 // remove attachment
141 li.remove();
142
143 // update attachment ids
144 galleryIds.val( _.uniq( attachmentIds ).join( ',' ) );
145
146 return false;
147 } );
148
149 /**
150 * Edit image.
151 */
152 $( document ).on( 'click', '.rl-gallery-image-edit', function( e ) {
153 e.preventDefault();
154
155 var attachmentId = $( this ).closest( 'li.rl-gallery-image' ).data( 'attachment_id' );
156 var parsedInt = parseInt( attachmentId );
157
158 // integer id
159 if ( parsedInt == attachmentId ) {
160 attachmentId = parsedInt;
161
162 // frame already exists?
163 if ( attachmentFrame !== null ) {
164 attachmentFrame.detach();
165 attachmentFrame.dispose();
166 attachmentFrame = null;
167 }
168
169 // create new frame
170 attachmentFrame = wp.media( {
171 id: 'rl-edit-attachment-modal',
172 frame: 'select',
173 uploader: false,
174 title: rlArgsGalleries.editAttachment,
175 library: {
176 post__in: [attachmentId],
177 type: rlArgsGalleries.supports.default,
178 content: 'browse',
179 contentUserSetting: false,
180 router: 'browse',
181 searchable: false,
182 sortable: false,
183 multiple: false,
184 editable: true
185 },
186 button: {
187 text: rlArgsGalleries.saveChanges
188 }
189 } ).on( 'open', function() {
190 var attachment = wp.media.attachment( attachmentId );
191 var selection = attachmentFrame.state().get( 'selection' );
192
193 // set browser mode
194 attachmentFrame.content.mode( 'browse' );
195
196 // add classes
197 attachmentFrame.$el.closest( '.media-modal' ).addClass( 'rl-edit-modal' );
198 attachmentFrame.$el.closest( '.media-frame' ).addClass( 'hide-router' );
199
200 // get attachment
201 attachment.fetch();
202
203 // add attachment
204 selection.add( attachment );
205 } ).on( 'close', function() {
206 var selection = attachmentFrame.state().get( 'selection' );
207
208 // unselect attachment to avoid issues with videos
209 selection.reset();
210 } );
211
212 attachmentFrame.open();
213 // embed string
214 } else if ( /^e\d+$/.test( attachmentId ) ) {
215 // attachmentId = 0;
216
217 // frame already exists?
218 if ( attachmentFrame !== null ) {
219 attachmentFrame.detach();
220 attachmentFrame.dispose();
221 attachmentFrame = null;
222 }
223
224 // create new frame
225 attachmentFrame = wp.media( {
226 id: 'rl-edit-attachment-modal',
227 frame: 'select',
228 uploader: false,
229 title: rlArgsGalleries.editEmbed,
230 library: {
231 post__in: [0]
232 },
233 button: {
234 text: rlArgsGalleries.saveChanges
235 }
236 } ).on( 'open', function() {
237 var attachment = wp.media.attachment( attachmentId );
238 var selection = attachmentFrame.state().get( 'selection' );
239 var embedItem = $( '.rl-gallery-image[data-attachment_id="' + attachmentId + '"]' );
240
241 // set browser mode
242 attachmentFrame.content.mode( 'browse' );
243
244 // add classes
245 attachmentFrame.$el.closest( '.media-modal' ).addClass( 'rl-edit-modal' );
246 attachmentFrame.$el.closest( '.media-frame' ).addClass( 'hide-router' );
247
248 // get attachment
249 attachment.fetch();
250
251 // simulate real attachment
252 attachment.id = attachmentId;
253 attachment.attributes = {
254 id: attachmentId,
255 filename: embedItem.find( 'input[data-type="url"]' ).val(),
256 dateFormatted: embedItem.find( 'input[data-type="date"]' ).val(),
257 width: embedItem.find( 'input[data-type="width"]' ).val(),
258 height: embedItem.find( 'input[data-type="height"]' ).val(),
259 title: embedItem.find( 'input[data-type="title"]' ).val(),
260 description: embedItem.find( 'textarea[data-type="caption"]' ).val(),
261 url: embedItem.find( 'input[data-type="url"]' ).val(),
262 sizes: {
263 thumbnail: {
264 width: embedItem.find( 'input[data-type="thumbnail_width"]' ).val(),
265 height: embedItem.find( 'input[data-type="thumbnail_height"]' ).val(),
266 url: embedItem.find( 'input[data-type="thumbnail_url"]' ).val(),
267 orientation: 'landscape'
268 }
269 },
270 type: 'image',
271 };
272
273 // add attachment
274 selection.add( attachment );
275
276 // update details label
277 attachmentFrame.$el.find( '.media-sidebar h2' ).text( rlArgsGalleries.videoDetails );
278
279 var detailsItem = attachmentFrame.$el.find( '.attachment-details' );
280
281 // hide unwanted html
282 detailsItem.find( 'p.description' ).hide();
283 detailsItem.find( '[data-setting="alt"]' ).hide();
284 detailsItem.find( '[data-setting="caption"]' ).hide();
285 detailsItem.find( '[data-setting="title"] input' ).prop( 'readonly', false );
286 detailsItem.find( '[data-setting="description"] textarea' ).prop( 'readonly', false );
287
288 // get media toolbar
289 var toolbar = attachmentFrame.toolbar.get();
290
291 toolbar.primary.$el.find( 'button' ).on( 'click', function() {
292 embedItem.find( 'input[data-type="title"]' ).val( detailsItem.find( '[data-setting="title"] input' ).val() );
293 embedItem.find( 'textarea[data-type="caption"]' ).val( detailsItem.find( '[data-setting="description"] textarea' ).val() );
294 } );
295 } );
296
297 attachmentFrame.open();
298 }
299
300 return false;
301 } );
302
303 /**
304 * Handle changing image status.
305 */
306 $( document ).on( 'click', '.rl-gallery-image-status', function( e ) {
307 e.preventDefault();
308
309 var li = $( this ).closest( 'li.rl-gallery-image' );
310
311 // active?
312 if ( li.hasClass( 'rl-status-active' ) ) {
313 li.addClass( 'rl-status-inactive' ).removeClass( 'rl-status-active' );
314
315 // add item
316 li.find( '.rl-gallery-exclude' ).val( li.data( 'attachment_id' ) );
317 } else {
318 li.addClass( 'rl-status-active' ).removeClass( 'rl-status-inactive' );
319
320 // remove item
321 li.find( '.rl-gallery-exclude' ).val( '' );
322 }
323
324 return false;
325 } );
326
327 /**
328 * Handle gallery modal.
329 */
330 $( document ).on( 'click', '.rl-gallery-select:not(.button-disabled)', function( e ) {
331 e.preventDefault();
332
333 // open media frame if already exists
334 if ( galleryFrame !== null ) {
335 galleryFrame.open();
336
337 return;
338 }
339
340 // create the media frame
341 galleryFrame = wp.media( {
342 title: rlArgsGalleries.textSelectImages,
343 multiple: 'add',
344 autoSelect: true,
345 filters: 'all',
346 library: {
347 type: rlArgsGalleries.supports.default,
348 filters: 'all'
349 },
350 button: {
351 text: rlArgsGalleries.textUseImages
352 }
353 } ).on( 'content:render', function( view ) {
354 if ( view !== null ) {
355 // get all selects
356 var selects = view.toolbar.secondary.$el.find( 'select.attachment-filters' );
357
358 // fix it only for more then 1 select (default wp)
359 if ( selects.length > 1 ) {
360 // calculate new width
361 var number = parseInt( 100 / selects.length ) - 2;
362
363 $( selects ).each( function( i, el ) {
364 $( el ).css( 'width', 'calc(' + number + '% - 12px)' );
365 } );
366 }
367 }
368 } ).on( 'open', function() {
369 // get media toolbar
370 var toolbar = galleryFrame.toolbar.get();
371
372 // add clear button
373 toolbar.set( 'rl-clear-selection', {
374 style: 'secondary',
375 priority: 0,
376 text: rlArgsGalleries.clearSelection,
377 requires: {
378 selection: true
379 },
380 click: function() {
381 var state = this.controller.state();
382 var selection = state.get( 'selection' );
383
384 // clear selected images
385 selection.reset();
386
387 // reset counter
388 toolbar.secondary.$el.find( '.rl-gallery-count' ).text( 0 );
389 }
390 } );
391
392 var selection = galleryFrame.state().get( 'selection' );
393 var attachmentIds = getCurrentAttachments( galleryIds, true );
394
395 if ( ! secondaryToolbar ) {
396 toolbar.secondary.$el.append(
397 '<div class="media-selection">' +
398 '<div class="selection-info">' +
399 '<span class="count">' + rlArgsGalleries.selectedImages + ': <span class="rl-gallery-count">' + attachmentIds.length + '</span></span>' +
400 '</div>' +
401 '</div>'
402 );
403
404 secondaryToolbar = true;
405 } else
406 toolbar.secondary.$el.find( '.rl-gallery-count' ).text( attachmentIds.length );
407
408 // clear selected images
409 selection.reset();
410
411 $.each( attachmentIds, function() {
412 // prepare attachment
413 attachment = wp.media.attachment( this );
414
415 // turn off counters
416 selection.off( 'add', toggleSelection );
417 selection.off( 'remove', toggleSelection );
418
419 // select attachment
420 selection.add( attachment ? [attachment] : [] );
421 } );
422
423 var span = toolbar.secondary.$el.find( '.rl-gallery-count' );
424
425 // turn on counters
426 selection.on( 'add', toggleSelection, {
427 el: span,
428 event: 'add'
429 } ).on( 'remove', toggleSelection, {
430 el: span,
431 event: 'remove'
432 } );
433 } ).on( 'select', function() {
434 var selection = galleryFrame.state().get( 'selection' );
435 var attachmentIds = getCurrentAttachments( galleryIds, false );
436 var selectedIds = [];
437
438 if ( selection ) {
439 selection.map( function( attachment ) {
440 // fetched attachment? attachment visible in modal
441 if ( typeof attachment.id === 'number' ) {
442 // add attachment
443 selectedIds.push( attachment.id );
444
445 // is image already in gallery?
446 if ( $.inArray( attachment.id, attachmentIds ) !== - 1 )
447 return;
448
449 // add attachment
450 attachmentIds.push( attachment.id );
451 attachment = attachment.toJSON();
452
453 // default size
454 var size = {
455 width: 150,
456 height: 150,
457 orientation: 'landscape',
458 url: attachment.url
459 };
460
461 // image?
462 if ( attachment.type === 'image' ) {
463 // is preview size available?
464 if ( attachment.sizes && attachment.sizes.thumbnail ) {
465 if ( attachment.sizes.thumbnail.url )
466 size.url = attachment.sizes.thumbnail.url;
467
468 if ( attachment.sizes.thumbnail.height )
469 size.height = attachment.sizes.thumbnail.height;
470
471 if ( attachment.sizes.thumbnail.width )
472 size.width = attachment.sizes.thumbnail.width;
473
474 if ( attachment.sizes.thumbnail.orientation )
475 size.orientation = attachment.sizes.thumbnail.orientation;
476 }
477 // video?
478 } else if ( attachment.type === 'video' ) {
479 size.url = rlArgsGalleries.videoIcon;
480
481 // is preview size available?
482 if ( attachment.thumb ) {
483 if ( attachment.thumb.src && attachment.icon !== attachment.thumb.src )
484 size.url = attachment.thumb.src;
485
486 if ( attachment.thumb.height )
487 size.height = attachment.thumb.height;
488
489 if ( attachment.thumb.width )
490 size.width = attachment.thumb.width;
491
492 if ( attachment.thumb.orientation )
493 size.orientation = attachment.thumb.orientation;
494 // fallback to full size preview image
495 } else if ( attachment.image ) {
496 if ( attachment.image.src && attachment.icon !== attachment.image.src )
497 size.url = attachment.image.src;
498
499 if ( attachment.image.height )
500 size.height = attachment.image.height;
501
502 if ( attachment.image.width )
503 size.width = attachment.image.width;
504
505 if ( attachment.image.orientation )
506 size.orientation = attachment.image.orientation;
507 }
508 }
509
510 // append new image
511 galleryContainer.append( rlArgsGalleries.mediaItemTemplate.replace( /__MEDIA_ID__/g, attachment.id ).replace( /__MEDIA_DATA__/g, getExcludeInput( galleryContainer ) + '<img width="' + size.width + '" height="' + size.height + '" src="' + rlArgsGalleries.thumbnail[0] + '" class="attachment-thumbnail size-thumbnail format-' + size.orientation + '" alt="" />' ).replace( /__MEDIA_STATUS__/g, ' rl-status-active' ).replace( /__MEDIA_TYPE__/g, attachment.type ) );
512
513 // update image src and alt the safe way
514 $( 'li[data-attachment_id="' + attachment.id + '"]' ).find( 'img' ).attr( 'alt', attachment.alt ).attr( 'src', size.url );
515 // only attachment id? attachment not visible in modal
516 } else {
517 // add attachment
518 selectedIds.push( + attachment.id );
519
520 // is image already in gallery?
521 if ( $.inArray( + attachment.id, attachmentIds ) !== - 1 )
522 return;
523
524 // add attachment
525 attachmentIds.push( + attachment.id );
526 }
527 } );
528 }
529
530 // assign copy of attachment ids
531 var copy = attachmentIds;
532
533 for ( var i = 0; i < attachmentIds.length; i ++ ) {
534 // unselected image?
535 if ( $.inArray( attachmentIds[i], selectedIds ) === - 1 ) {
536 // skip embed
537 if ( /^e\d+$/.test( attachmentIds[i] ) )
538 continue;
539
540 // remove unselected attachment
541 galleryContainer.find( 'li.rl-gallery-image[data-attachment_id="' + attachmentIds[i] + '"]' ).remove();
542
543 // update attachment ids
544 copy = _.without( copy, attachmentIds[i] );
545 }
546 }
547
548 // update gallery ids
549 galleryIds.val( _.uniq( copy ).join( ',' ) );
550 } );
551
552 // open media frame
553 galleryFrame.open();
554 } );
555
556 // extend Embed
557 var RLToolbarEmbed = wp.media.view.Toolbar.Embed;
558
559 wp.media.view.Toolbar.Embed = wp.media.view.Toolbar.Embed.extend( {
560 initialize: function() {
561 // replace button text
562 this.options.text = rlArgsGalleries.embedVideo;
563
564 // call original function
565 RLToolbarEmbed.prototype.initialize.apply( this, arguments );
566 }
567 } );
568
569 // extend EmbedLink
570 var RLEmbedLink = wp.media.view.EmbedLink;
571
572 wp.media.view.EmbedLink = wp.media.view.EmbedLink.extend( {
573 rlVideoFrameToolbar: null,
574 rlDisableButton: function() {
575 this.rlVideoFrameToolbar.primary.$el.find( 'button' ).prop( 'disabled', true );
576 },
577 updateoEmbed: function( model, url ) {
578 var youtube = new RegExp( 'https?://((m|www)\.)?youtube\.com/watch.*', 'i' );
579 var vimeo = new RegExp( 'https?://(.+\.)?vimeo\.com/.*', 'i' );
580
581 if ( ( rlArgsGalleries.supports.youtube && youtube.test( url ) ) || ( rlArgsGalleries.supports.vimeo && vimeo.test( url ) ) ) {
582 this.$el.find( '.rl-embed-video-text' ).hide();
583 } else {
584 // clear url
585 model.set( 'url', '' );
586
587 this.$el.find( '.rl-embed-video-text' ).show();
588 }
589
590 // call original function
591 RLEmbedLink.prototype.updateoEmbed.apply( this, arguments );
592 },
593 fetch: function() {
594 // no url?
595 if ( ! this.controller.state().props.get( 'url' ) )
596 return;
597
598 // call original function
599 RLEmbedLink.prototype.fetch.apply( this, arguments );
600
601 this.dfd.done( function( response, status, xhr ) {
602 // save response for later use
603 embedFrame.rlOembedResponse = response;
604
605 this.rlVideoFrameToolbar.primary.$el.find( 'button' ).prop( 'disabled', false );
606 } );
607 },
608 initialize: function() {
609 this.rlVideoFrameToolbar = embedFrame.toolbar.get();
610
611 // call original function
612 RLEmbedLink.prototype.initialize.apply( this, arguments );
613
614 this.listenTo( this.model, 'change:url', this.rlDisableButton );
615 }
616 } );
617
618 /**
619 * Handle gallery modal.
620 */
621 $( document ).on( 'click', '.rl-gallery-select-videos:not(.button-disabled)', function( e ) {
622 e.preventDefault();
623
624 // open media frame if already exists
625 if ( embedFrame !== null ) {
626 embedFrame.open();
627
628 return;
629 }
630
631 // create the media frame
632 embedFrame = wp.media( {
633 frame: 'post',
634 state: 'embed',
635 type: 'link',
636 metadata: {}
637 } ).on( 'open', function() {
638 // clear response
639 embedFrame.rlOembedResponse = {};
640
641 // get content
642 var content = embedFrame.content.get();
643
644 // hide setting link text
645 content.$( '.setting' ).hide();
646
647 var supportedEmbeds = [];
648
649 if ( rlArgsGalleries.supports.youtube )
650 supportedEmbeds.push( 'YouTube' );
651
652 if ( rlArgsGalleries.supports.vimeo )
653 supportedEmbeds.push( 'Vimeo' );
654
655 if ( content.$( '.embed-link-settings' ).find( '.rl-embed-video-text' ).length === 0 ) {
656 // append text
657 content.$( '.embed-link-settings' ).prepend( '<span class="rl-embed-video-text">' + rlArgsGalleries.onlyEmbedProviders.replace( '%s', supportedEmbeds.join( ', ' ) ) + '</span>' );
658 }
659
660 // get menu
661 var menu = embedFrame.$el;
662
663 // hide menu
664 if ( menu.length > 0 )
665 $( menu ).addClass( 'hide-menu' );
666
667 // get media toolbar
668 var toolbar = embedFrame.toolbar.get();
669
670 // update button
671 toolbar.primary.$el.find( 'button' ).prop( 'disabled', true );
672 } ).on( 'close', function() {
673 var state = embedFrame.state();
674
675 // save url before clearing
676 embedFrame.rlSelectedUrl = state.props.get( 'url' );
677
678 // clear url
679 state.props.set( 'url', 'http://' );
680 } ).on( 'select', function() {
681 var attachmentIds = getCurrentAttachments( galleryIds, false );
682
683 // embed id
684 var embedId = 'e' + embedNumber;
685
686 // add attachment
687 attachmentIds.push( embedId );
688
689 // update gallery ids
690 galleryIds.val( _.uniq( attachmentIds ).join( ',' ) );
691
692 // get embed item
693 var embedItem = $( rlArgsGalleries.mediaEmbedTemplate.replace( /__EMBED_ID__/g, embedId ) );
694
695 // update embed item values
696 embedItem.find( 'input[data-type="url"]' ).val( embedFrame.rlSelectedUrl );
697
698 // check width
699 if ( 'width' in embedFrame.rlOembedResponse )
700 embedItem.find( 'input[data-type="width"]' ).val( embedFrame.rlOembedResponse.width );
701 else
702 embedItem.find( 'input[data-type="width"]' ).val( 0 );
703
704 // check height
705 if ( 'height' in embedFrame.rlOembedResponse )
706 embedItem.find( 'input[data-type="height"]' ).val( embedFrame.rlOembedResponse.height );
707 else
708 embedItem.find( 'input[data-type="height"]' ).val( 0 );
709
710 // check thumbnail url
711 if ( 'thumbnail_url' in embedFrame.rlOembedResponse )
712 embedItem.find( 'input[data-type="thumbnail_url"]' ).val( embedFrame.rlOembedResponse.thumbnail_url );
713 else
714 embedItem.find( 'input[data-type="thumbnail_url"]' ).val( '' );
715
716 // check thumbnail width
717 if ( 'thumbnail_width' in embedFrame.rlOembedResponse )
718 embedItem.find( 'input[data-type="thumbnail_width"]' ).val( embedFrame.rlOembedResponse.thumbnail_width );
719 else
720 embedItem.find( 'input[data-type="thumbnail_width"]' ).val( 0 );
721
722 // check thumbnail height
723 if ( 'thumbnail_height' in embedFrame.rlOembedResponse )
724 embedItem.find( 'input[data-type="thumbnail_height"]' ).val( embedFrame.rlOembedResponse.thumbnail_height );
725 else
726 embedItem.find( 'input[data-type="thumbnail_height"]' ).val( 0 );
727
728 // check title
729 if ( 'title' in embedFrame.rlOembedResponse )
730 embedItem.find( 'input[data-type="title"]' ).val( embedFrame.rlOembedResponse.title );
731 else
732 embedItem.find( 'input[data-type="title"]' ).val( '' );
733
734 // check description
735 if ( 'description' in embedFrame.rlOembedResponse )
736 embedItem.find( 'textarea[data-type="caption"]' ).text( embedFrame.rlOembedResponse.description );
737 else
738 embedItem.find( 'textarea[data-type="caption"]' ).text( '' );
739
740 // check upload date
741 if ( 'upload_date' in embedFrame.rlOembedResponse )
742 embedItem.find( 'input[data-type="date"]' ).val( embedFrame.rlOembedResponse.upload_date );
743 else
744 embedItem.find( 'input[data-type="date"]' ).val( '' );
745
746 // append new image
747 galleryContainer.append(
748 rlArgsGalleries.mediaItemTemplate
749 .replace( /__MEDIA_ID__/g, embedId )
750 .replace( /__MEDIA_DATA__/g, getExcludeInput( galleryContainer ) + embedItem.html() + '<img width="' + embedFrame.rlOembedResponse.thumbnail_width + '" height="' + embedFrame.rlOembedResponse.thumbnail_height + '" src="' + embedFrame.rlOembedResponse.thumbnail_url + '" class="attachment-thumbnail size-thumbnail format-' + ( embedFrame.rlOembedResponse.thumbnail_width > embedFrame.rlOembedResponse.thumbnail_height ? 'landscape' : 'portrait' ) + '" alt="" />' )
751 .replace( /__MEDIA_STATUS__/g, ' rl-status-active' )
752 .replace( /__MEDIA_TYPE__/g, 'embed' )
753 );
754
755 embedNumber++
756 } );
757
758 // open media frame
759 embedFrame.open();
760 } );
761
762 /**
763 * Handle updating gallery preview.
764 */
765 $( document ).on( 'click', '.rl-gallery-update-preview, .rl-gallery-preview-pagination a', function( e ) {
766 e.preventDefault();
767
768 var click = $( this );
769 var type = click.hasClass( 'rl-gallery-update-preview' ) ? 'update' : 'page';
770 var menuItem = $( '.rl-gallery-tab-menu-images input:checked' ).val();
771 var container = $( '.rl-gallery-tab-inside-images-' + menuItem );
772 var spinner = click.closest( 'td' ).find( '.rl-gallery-preview-inside .spinner' );
773 var inside = $( this ).closest( '.inside' ).find( '.rl-gallery-tab-content' );
774 var disabledContent = inside.find( 'tr[data-field_type="media_preview"]' );
775 var queryArgs = {};
776
777 // disable whole content
778 inside.addClass( 'rl-loading-content' );
779
780 // enable inside content
781 disabledContent.find( '.rl-gallery-content' ).removeClass( 'rl-content-disabled' );
782 disabledContent.find( '.rl-gallery-preview-pagination' ).removeClass( 'rl-content-disabled' );
783
784 // pagination?
785 if ( type === 'page' ) {
786 var content = click.attr( 'href' ).match( 'preview_page/\\d+' );
787 var page = 1;
788
789 // get valid page number
790 if ( content !== null )
791 page = content[0].split( '/' )[1];
792
793 queryArgs['preview_page'] = page;
794 } else
795 queryArgs['preview_page'] = 1;
796
797 // get all field values
798 container.find( 'tr[data-field_type]' ).each( function() {
799 var el = $( this );
800 var fieldName = el.data( 'field_name' );
801 var value = null;
802
803 switch ( el.data( 'field_type' ) ) {
804 case 'text':
805 value = el.find( 'input' ).val();
806
807 if ( ! value )
808 value = '';
809 break;
810
811 case 'number':
812 value = parseInt( el.find( 'input' ).val() );
813
814 if ( ! value )
815 value = 0;
816 break;
817
818 case 'taxonomy':
819 value = {
820 'id': parseInt( el.find( 'select option:selected' ).val() ),
821 'children': el.find( 'input[type="checkbox"]' ).prop( 'checked' )
822 };
823
824 if ( ! value )
825 value = {
826 'id': 0,
827 'children': false
828 };
829 break;
830
831 case 'select':
832 value = el.find( 'select option:selected' ).val();
833
834 if ( ! value )
835 value = '';
836 break;
837
838 case 'radio':
839 value = el.find( 'input:checked' ).val();
840
841 if ( ! value )
842 value = '';
843 break;
844
845 case 'multiselect':
846 value = el.find( 'select' ).val();
847
848 if ( ! value )
849 value = [];
850 break;
851
852 case 'hidden':
853 // get all response data elements
854 var elements = el.find( 'span[class="rl-response-data"]' );
855
856 var currentPage = queryArgs['preview_page'];
857
858 value = {};
859
860 if ( elements.length > 0 ) {
861 elements.each( function( i, element ) {
862 var subElement = $( element );
863 var provider = subElement.data( 'provider' );
864 var subName = subElement.data( 'name' )
865 var subValue = subElement.data( 'value' );
866
867 if ( ! ( provider in value ) )
868 value[provider] = {};
869
870 if ( ! ( provider in mediaProviders ) )
871 mediaProviders[provider] = {};
872
873 if ( ! ( currentPage in mediaProviders[provider] ) )
874 mediaProviders[provider][currentPage] = {};
875
876 // save response data for every page
877 mediaProviders[provider][currentPage][subName] = subValue;
878
879 value[provider][subName] = subValue;
880 } );
881 }
882 break;
883 }
884
885 queryArgs[fieldName] = value;
886 } );
887
888 // display spinner
889 spinner.fadeIn( 'fast' ).css( 'visibility', 'visible' );
890
891 // post ajax request
892 $.post( ajaxurl, {
893 action: 'rl-get-preview-content',
894 post_id: rlArgsGalleries.postId,
895 menu_item: menuItem,
896 query: queryArgs,
897 preview_type: type,
898 excluded: $( '.rl-gallery-exclude' ).map( function( i, elem ) {
899 return $( elem ).val();
900 } ).get(),
901 nonce: rlArgsGalleries.nonce
902 } ).done( function( response ) {
903 if ( response.success ) {
904 container.find( 'tr[data-field_type]' ).each( function() {
905 var el = $( this );
906
907 // any response data fields?
908 if ( el.data( 'field_type' ) === 'hidden' && el.data( 'field_name' ) === 'response_data' ) {
909 var responseData = response.data.response_data;
910
911 // loop through all providers
912 for ( var provider in responseData ) {
913 if ( responseData.hasOwnProperty( provider ) ) {
914 var arguments = responseData[provider];
915
916 // loop through all arguments
917 for ( var argument in arguments ) {
918 if ( arguments.hasOwnProperty( argument ) ) {
919 $( '#rl_images_remote_library_response_data_' + provider + '_' + argument ).data( 'value', arguments[argument] );
920 }
921 }
922 }
923 }
924 }
925 } );
926
927 // update images
928 $( '.rl-gallery-images' ).empty().append( response.data.images );
929
930 // update pagination
931 $( '.rl-gallery-preview-pagination' ).replaceWith( response.data.pagination );
932 } else {
933 // @todo
934 }
935 } ).always( function() {
936 // hide spinner
937 spinner.fadeOut( 'fast' );
938
939 // enable content
940 inside.removeClass( 'rl-loading-content' );
941
942 // enable inside content
943 disabledContent.find( '.rl-gallery-content' ).removeClass( 'rl-content-disabled' );
944 disabledContent.find( '.rl-gallery-preview-pagination' ).removeClass( 'rl-content-disabled' );
945 } );
946
947 return false;
948 } );
949
950 /**
951 * Handle remote library search string change.
952 */
953 $( document ).on( 'keyup', '#rl-images-remote_library-media_search, #rl-images-featured-number_of_posts, #rl-images-featured-offset, #rl-images-featured-images_per_post', function() {
954 disableInsideContent( $( this ) );
955 } );
956
957 /**
958 * Handle remote library media provider change.
959 */
960 $( document ).on( 'change', '#rl-images-remote_library-media_provider, #rl-images-folders-folder, #rl-images-folders-folder-include-children, #rl-images-featured-orderby, input[name="rl_gallery[images][featured][order]"], input[name="rl_gallery[images][featured][image_source]"], #rl-images-featured-post_type, #rl-images-featured-post_status, #rl-images-featured-post_format, #rl-images-featured-post_term, #rl-images-featured-post_author, #rl-images-featured-page_parent, #rl-images-featured-page_template, #rl-images-featured-number_of_posts, #rl-images-featured-offset, #rl-images-featured-images_per_post', function() {
961 disableInsideContent( $( this ) );
962 } );
963 } );
964
965 /**
966 * Handle featured image change.
967 */
968 $( document ).on( 'change', '#postimagediv .inside', function() {
969 var el = $( this ).find( 'input[name="rl_gallery_featured_image"]:checked' );
970 var value = $( el ).val();
971
972 $( '#postimagediv .inside' ).attr( 'data-featured-type', value );
973 $( '.rl-gallery-featured-image-select' ).children( 'div' ).hide();
974 $( '.rl-gallery-featured-image-select-' + value ).show();
975
976 // media library
977 if ( value === 'id' ) {
978 var thumbnail_id = parseInt( $( '#_thumbnail_id' ).attr( 'data-featured-id' ) );
979
980 if ( thumbnail_id > 0 )
981 $( '#_thumbnail_id' ).val( thumbnail_id ).attr( 'data-featured-id', - 1 );
982 // custom URL or first gallery image
983 } else {
984 var thumbnail_id = parseInt( $( '#_thumbnail_id' ).val() );
985
986 if ( thumbnail_id > 0 )
987 $( '#_thumbnail_id' ).attr( 'data-featured-id', thumbnail_id ).val( - 1 );
988 }
989 } );
990
991 /**
992 * Reinitialize select2.
993 */
994 $( document ).on( 'ajaxComplete', function() {
995 initSelect2();
996 } );
997
998 /**
999 * Initialize galleries.
1000 */
1001 function initGalleries() {
1002 initSelect2();
1003
1004 // color picker
1005 $( '.rl-gallery-tab-content .color-picker' ).wpColorPicker();
1006
1007 // make sure HTML5 validation is turned off
1008 $( 'form#post' ).attr( 'novalidate', 'novalidate' );
1009
1010 // make sure to dispay images metabox at start
1011 $( '#responsive-gallery-images' ).show();
1012
1013 // get gallery metabox
1014 var metabox = document.getElementById( 'responsive_lightbox_metaboxes-sortables' );
1015
1016 // observe sortables
1017 if ( metabox !== null && typeof MutationObserver !== 'undefined' ) {
1018 function disableFirstButton() {
1019 $( '#' + $( '.meta-box-sortables:visible:first' ).attr( 'id' ) ).find( '.postbox:visible:first .handle-order-higher' ).attr( 'aria-disabled', 'true' );
1020 }
1021
1022 var observer = new MutationObserver( function( mutations ) {
1023 _.each( mutations, function( mutation ) {
1024 if ( mutation.attributeName === 'class' ) {
1025 // get metaboxes
1026 var target = $( mutation.target );
1027
1028 if ( target.hasClass( 'ui-sortable' ) && ! target.hasClass( 'ui-sortable-disabled' ) ) {
1029 setTimeout( function() {
1030 // disable sortable
1031 target.sortable( 'disable' );
1032
1033 // destroy sortable
1034 target.sortable( 'destroy' );
1035
1036 // remove all classes
1037 target.removeClass();
1038
1039 // find and disable first button
1040 disableFirstButton();
1041
1042 // get sortable
1043 var sortables = $( '.meta-box-sortables' );
1044
1045 // get instance
1046 var instance = sortables.sortable( 'instance' );
1047
1048 // store original stop event function
1049 var stopSortable = instance.options.stop;
1050
1051 // set flag
1052 var allowOriginalStop = true;
1053
1054 // replace stop event
1055 sortables.sortable( {
1056 stop: function() {
1057 if ( allowOriginalStop ) {
1058 allowOriginalStop = false;
1059 stopSortable();
1060 }
1061
1062 allowOriginalStop = true;
1063
1064 // find and disable first button
1065 disableFirstButton();
1066 }
1067 } );
1068
1069 // handle toggling postboxes
1070 $( document ).on( 'postbox-toggled', disableFirstButton );
1071
1072 // handle moving postboxes
1073 $( '.postbox .handle-order-higher, .postbox .handle-order-lower' ).on( 'click.postboxes', disableFirstButton );
1074
1075 // stop observer
1076 observer.disconnect();
1077 }, 50 );
1078 }
1079 }
1080 } );
1081 } );
1082
1083 // start observing
1084 observer.observe( metabox, {attributes: true} );
1085 }
1086 }
1087
1088 /**
1089 * Disable remote library inside content.
1090 */
1091 function disableInsideContent( el ) {
1092 var container = el.closest( 'table' ).find( 'tr[data-field_type="media_preview"]' );
1093
1094 // disable content
1095 container.find( '.rl-gallery-content' ).addClass( 'rl-content-disabled' );
1096 container.find( '.rl-gallery-preview-pagination' ).addClass( 'rl-content-disabled' );
1097 }
1098
1099 /**
1100 * Initialize select2.
1101 */
1102 function initSelect2() {
1103 $( '.rl-gallery-tab-inside select.select2' ).select2( {
1104 closeOnSelect: true,
1105 multiple: true,
1106 width: 300,
1107 minimumInputLength: 0
1108 } );
1109 }
1110
1111 /**
1112 * Get gallery item exclude input.
1113 */
1114 function getExcludeInput( container ) {
1115 var tabId = $( 'input[name="rl_active_tab"]' ).val();
1116 var menuItem = $( '.rl-gallery-tab-menu-' + tabId ).find( '.rl-gallery-tab-menu-item:checked' ).val();
1117 var fieldName = container.closest( 'tr[data-field_name]' ).data( 'field_name' );
1118
1119 return rlArgsGalleries.mediaExcludeTemplate
1120 .replace( /__MEDIA_TAB_ID__/g, tabId )
1121 .replace( /__MEDIA_MENU_ITEM__/g, menuItem )
1122 .replace( /__MEDIA_FIELD_NAME__/g, fieldName );
1123 }
1124
1125 /**
1126 * Get attachment IDs.
1127 */
1128 function getCurrentAttachments( ids, onlyAttachments ) {
1129 var attachments = ids.val();
1130 var parsedAttachments = [];
1131
1132 if ( attachments !== '' ) {
1133 attachments.split( ',' ).forEach( function( val, i ) {
1134 var parsedInt = parseInt( val );
1135
1136 // only real attachments?
1137 if ( onlyAttachments ) {
1138 // integer ids
1139 if ( Number.isInteger( parsedInt ) && parsedInt > 0 )
1140 parsedAttachments.push( parsedInt );
1141 } else {
1142 // integer ids
1143 if ( parsedInt == val )
1144 parsedAttachments.push( parsedInt );
1145 // embed strings
1146 else if ( /^e\d+$/.test( val ) )
1147 parsedAttachments.push( val );
1148 }
1149 } );
1150 }
1151
1152 return parsedAttachments;
1153 }
1154
1155 /**
1156 * Make media gallery sortable.
1157 */
1158 function mediaGallerySortable( gallery, ids, type ) {
1159 if ( type === 'media' ) {
1160 // images order
1161 gallery.sortable( {
1162 items: 'li.rl-gallery-image',
1163 cursor: 'move',
1164 scrollSensitivity: 40,
1165 forcePlaceholderSize: true,
1166 forceHelperSize: false,
1167 helper: 'clone',
1168 opacity: 0.65,
1169 placeholder: 'rl-gallery-sortable-placeholder',
1170 start: function( event, ui ) {
1171 ui.item.css( 'border-color', '#f6f6f6' );
1172 },
1173 stop: function( event, ui ) {
1174 ui.item.removeAttr( 'style' );
1175 },
1176 update: function( event, ui ) {
1177 var attachmentIds = [];
1178
1179 gallery.find( 'li.rl-gallery-image' ).each( function() {
1180 attachmentIds.push( $( this ).attr( 'data-attachment_id' ) );
1181 } );
1182
1183 ids.val( _.uniq( attachmentIds ).join( ',' ) );
1184 }
1185 } );
1186 }
1187 }
1188
1189 /**
1190 * Toggle attachment selection.
1191 */
1192 function toggleSelection() {
1193 if ( 'event' in this ) {
1194 var value = parseInt( this.el.text() );
1195
1196 if ( this.event === 'add' )
1197 this.el.text( value + 1 );
1198 else if ( this.event === 'remove' )
1199 this.el.text( value - 1 );
1200 }
1201 }
1202
1203 } )( jQuery );