PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.4.0
Responsive Lightbox & Gallery v2.4.0
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 4 years ago admin-galleries.js 4 years ago admin-gallery.js 4 years ago admin-media.js 5 years ago admin-plugins.js 5 years ago admin-widgets.js 5 years ago admin.js 5 years ago front-basicmasonry.js 4 years ago front-basicslider.js 4 years ago front.js 4 years ago gutenberg.min.js 4 years ago
admin-galleries.js
1207 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.post_id,
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', 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', 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.post_id,
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 // try {
904 if ( response.success ) {
905 container.find( 'tr[data-field_type]' ).each( function() {
906 var el = $( this );
907
908 // any response data fields?
909 if ( el.data( 'field_type' ) === 'hidden' && el.data( 'field_name' ) === 'response_data' ) {
910 var responseData = response.data.response_data;
911
912 // loop through all providers
913 for ( var provider in responseData ) {
914 if ( responseData.hasOwnProperty( provider ) ) {
915 var arguments = responseData[provider];
916
917 // loop through all arguments
918 for ( var argument in arguments ) {
919 if ( arguments.hasOwnProperty( argument ) ) {
920 $( '#rl_images_remote_library_response_data_' + provider + '_' + argument ).data( 'value', arguments[argument] );
921 }
922 }
923 }
924 }
925 }
926 } );
927
928 // update images
929 $( '.rl-gallery-images' ).empty().append( response.data.images );
930
931 // update pagination
932 $( '.rl-gallery-preview-pagination' ).replaceWith( response.data.pagination );
933 } else {
934 // @todo
935 }
936 // } catch ( e ) {
937 // console.log( 'err' );
938 // }
939 } ).always( function() {
940 // hide spinner
941 spinner.fadeOut( 'fast' );
942
943 // enable content
944 inside.removeClass( 'rl-loading-content' );
945
946 // enable inside content
947 disabledContent.find( '.rl-gallery-content' ).removeClass( 'rl-content-disabled' );
948 disabledContent.find( '.rl-gallery-preview-pagination' ).removeClass( 'rl-content-disabled' );
949 } );
950
951 return false;
952 } );
953
954 /**
955 * Handle remote library search string change.
956 */
957 $( 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() {
958 disableInsideContent( $( this ) );
959 } );
960
961 /**
962 * Handle remote library media provider change.
963 */
964 $( 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() {
965 disableInsideContent( $( this ) );
966 } );
967 } );
968
969 /**
970 * Handle featured image change.
971 */
972 $( document ).on( 'change', '#postimagediv .inside', function() {
973 var el = $( this ).find( 'input[name="rl_gallery_featured_image"]:checked' );
974 var value = $( el ).val();
975
976 $( '#postimagediv .inside' ).attr( 'data-featured-type', value );
977 $( '.rl-gallery-featured-image-select' ).children( 'div' ).hide();
978 $( '.rl-gallery-featured-image-select-' + value ).show();
979
980 // media library
981 if ( value === 'id' ) {
982 var thumbnail_id = parseInt( $( '#_thumbnail_id' ).attr( 'data-featured-id' ) );
983
984 if ( thumbnail_id > 0 )
985 $( '#_thumbnail_id' ).val( thumbnail_id ).attr( 'data-featured-id', - 1 );
986 // custom URL or first gallery image
987 } else {
988 var thumbnail_id = parseInt( $( '#_thumbnail_id' ).val() );
989
990 if ( thumbnail_id > 0 )
991 $( '#_thumbnail_id' ).attr( 'data-featured-id', thumbnail_id ).val( - 1 );
992 }
993 } );
994
995 /**
996 * Reinitialize select2.
997 */
998 $( document ).on( 'ajaxComplete', function() {
999 initSelect2();
1000 } );
1001
1002 /**
1003 * Initialize galleries.
1004 */
1005 function initGalleries() {
1006 initSelect2();
1007
1008 // color picker
1009 $( '.rl-gallery-tab-content .color-picker' ).wpColorPicker();
1010
1011 // make sure HTML5 validation is turned off
1012 $( 'form#post' ).attr( 'novalidate', 'novalidate' );
1013
1014 // make sure to dispay images metabox at start
1015 $( '#responsive-gallery-images' ).show();
1016
1017 // get gallery metabox
1018 var metabox = document.getElementById( 'responsive_lightbox_metaboxes-sortables' );
1019
1020 // observe sortables
1021 if ( metabox !== null && typeof MutationObserver !== 'undefined' ) {
1022 function disableFirstButton() {
1023 $( '#' + $( '.meta-box-sortables:visible:first' ).attr( 'id' ) ).find( '.postbox:visible:first .handle-order-higher' ).attr( 'aria-disabled', 'true' );
1024 }
1025
1026 var observer = new MutationObserver( function( mutations ) {
1027 _.each( mutations, function( mutation ) {
1028 if ( mutation.attributeName === 'class' ) {
1029 // get metaboxes
1030 var target = $( mutation.target );
1031
1032 if ( target.hasClass( 'ui-sortable' ) && ! target.hasClass( 'ui-sortable-disabled' ) ) {
1033 setTimeout( function() {
1034 // disable sortable
1035 target.sortable( 'disable' );
1036
1037 // destroy sortable
1038 target.sortable( 'destroy' );
1039
1040 // remove all classes
1041 target.removeClass();
1042
1043 // find and disable first button
1044 disableFirstButton();
1045
1046 // get sortable
1047 var sortables = $( '.meta-box-sortables' );
1048
1049 // get instance
1050 var instance = sortables.sortable( 'instance' );
1051
1052 // store original stop event function
1053 var stopSortable = instance.options.stop;
1054
1055 // set flag
1056 var allowOriginalStop = true;
1057
1058 // replace stop event
1059 sortables.sortable( {
1060 stop: function() {
1061 if ( allowOriginalStop ) {
1062 allowOriginalStop = false;
1063 stopSortable();
1064 }
1065
1066 allowOriginalStop = true;
1067
1068 // find and disable first button
1069 disableFirstButton();
1070 }
1071 } );
1072
1073 // handle toggling postboxes
1074 $( document ).on( 'postbox-toggled', disableFirstButton );
1075
1076 // handle moving postboxes
1077 $( '.postbox .handle-order-higher, .postbox .handle-order-lower' ).on( 'click.postboxes', disableFirstButton );
1078
1079 // stop observer
1080 observer.disconnect();
1081 }, 50 );
1082 }
1083 }
1084 } );
1085 } );
1086
1087 // start observing
1088 observer.observe( metabox, {attributes: true} );
1089 }
1090 }
1091
1092 /**
1093 * Disable remote library inside content.
1094 */
1095 function disableInsideContent( el ) {
1096 var container = el.closest( 'table' ).find( 'tr[data-field_type="media_preview"]' );
1097
1098 // disable content
1099 container.find( '.rl-gallery-content' ).addClass( 'rl-content-disabled' );
1100 container.find( '.rl-gallery-preview-pagination' ).addClass( 'rl-content-disabled' );
1101 }
1102
1103 /**
1104 * Initialize select2.
1105 */
1106 function initSelect2() {
1107 $( '.rl-gallery-tab-inside select.select2' ).select2( {
1108 closeOnSelect: true,
1109 multiple: true,
1110 width: 300,
1111 minimumInputLength: 0
1112 } );
1113 }
1114
1115 /**
1116 * Get gallery item exclude input.
1117 */
1118 function getExcludeInput( container ) {
1119 var tabId = $( 'input[name="rl_active_tab"]' ).val();
1120 var menuItem = $( '.rl-gallery-tab-menu-' + tabId ).find( '.rl-gallery-tab-menu-item:checked' ).val();
1121 var fieldName = container.closest( 'tr[data-field_name]' ).data( 'field_name' );
1122
1123 return rlArgsGalleries.mediaExcludeTemplate
1124 .replace( /__MEDIA_TAB_ID__/g, tabId )
1125 .replace( /__MEDIA_MENU_ITEM__/g, menuItem )
1126 .replace( /__MEDIA_FIELD_NAME__/g, fieldName );
1127 }
1128
1129 /**
1130 * Get attachment IDs.
1131 */
1132 function getCurrentAttachments( ids, onlyAttachments ) {
1133 var attachments = ids.val();
1134 var parsedAttachments = [];
1135
1136 if ( attachments !== '' ) {
1137 attachments.split( ',' ).forEach( function( val, i ) {
1138 var parsedInt = parseInt( val );
1139
1140 // only real attachments?
1141 if ( onlyAttachments ) {
1142 // integer ids
1143 if ( Number.isInteger( parsedInt ) && parsedInt > 0 )
1144 parsedAttachments.push( parsedInt );
1145 } else {
1146 // integer ids
1147 if ( parsedInt == val )
1148 parsedAttachments.push( parsedInt );
1149 // embed strings
1150 else if ( /^e\d+$/.test( val ) )
1151 parsedAttachments.push( val );
1152 }
1153 } );
1154 }
1155
1156 return parsedAttachments;
1157 }
1158
1159 /**
1160 * Make media gallery sortable.
1161 */
1162 function mediaGallerySortable( gallery, ids, type ) {
1163 if ( type === 'media' ) {
1164 // images order
1165 gallery.sortable( {
1166 items: 'li.rl-gallery-image',
1167 cursor: 'move',
1168 scrollSensitivity: 40,
1169 forcePlaceholderSize: true,
1170 forceHelperSize: false,
1171 helper: 'clone',
1172 opacity: 0.65,
1173 placeholder: 'rl-gallery-sortable-placeholder',
1174 start: function( event, ui ) {
1175 ui.item.css( 'border-color', '#f6f6f6' );
1176 },
1177 stop: function( event, ui ) {
1178 ui.item.removeAttr( 'style' );
1179 },
1180 update: function( event, ui ) {
1181 var attachmentIds = [];
1182
1183 gallery.find( 'li.rl-gallery-image' ).each( function() {
1184 attachmentIds.push( $( this ).attr( 'data-attachment_id' ) );
1185 } );
1186
1187 ids.val( _.uniq( attachmentIds ).join( ',' ) );
1188 }
1189 } );
1190 }
1191 }
1192
1193 /**
1194 * Toggle attachment selection.
1195 */
1196 function toggleSelection() {
1197 if ( 'event' in this ) {
1198 var value = parseInt( this.el.text() );
1199
1200 if ( this.event === 'add' )
1201 this.el.text( value + 1 );
1202 else if ( this.event === 'remove' )
1203 this.el.text( value - 1 );
1204 }
1205 }
1206
1207 } )( jQuery );