PluginProbe ʕ •ᴥ•ʔ
Responsive Lightbox & Gallery / 2.3.1
Responsive Lightbox & Gallery v2.3.1
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-folders.js
responsive-lightbox / js Last commit date
admin-folders.js 5 years ago admin-galleries.js 5 years ago admin-gallery.js 5 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 5 years ago front-basicslider.js 5 years ago front.js 5 years ago gutenberg.min.js 5 years ago
admin-folders.js
1280 lines
1 ( function( $ ) {
2
3 var rl_folder_id = 0,
4 rl_ps = null,
5 grid_frame = null,
6 active_mode = '',
7 move_node_failed = false,
8 disable_redirect = false,
9 attachments_browser = null,
10 last_priority = 2,
11 event_data = {},
12 allow_modal_media_tag_saving = false;
13
14 function initFolders() {
15 var RLWPMediaViewMediaFramePost = wp.media.view.MediaFrame.Post;
16
17 // extend media frame
18 wp.media.view.MediaFrame.Post = RLWPMediaViewMediaFramePost.extend( {
19 initialize: function() {
20 // calling the initalize method from the current frame before adding new functionality
21 RLWPMediaViewMediaFramePost.prototype.initialize.apply( this, arguments );
22
23 // events
24 this.on( 'content:render', this.contentRender, this );
25 },
26 contentRender: function( view ) {
27 // valid view?
28 if ( view !== null ) {
29 // get all selects
30 var selects = view.toolbar.secondary.$el.find( 'select.attachment-filters' );
31
32 // fix it only for more then 2 selects (default wp)
33 if ( selects.length > 2 ) {
34 // calculate new width
35 var number = parseInt( 100 / selects.length ) - 2;
36
37 $( selects ).each( function( i, el ) {
38 $( el ).css( 'width', 'calc(' + number + '% - 12px)' );
39 } );
40 }
41 }
42 }
43 } );
44
45 // add new media folder filter
46 var RLWPMediaViewAttachmentFilters = wp.media.view.AttachmentFilters.extend( {
47 id: 'media-attachment-rl-folders-filters',
48 className: 'attachment-filters attachment-rl-folders-filter',
49 change: function() {
50 wp.media.view.AttachmentFilters.prototype.change.apply( this, arguments );
51
52 if ( grid_frame !== null )
53 grid_frame.controller.states.get( 'library' ).get( 'library' ).observe( wp.Uploader.queue );
54 },
55 createFilters: function() {
56 var filters = {},
57 term_id = 0,
58 terms = $( $.parseHTML( rlFoldersArgs.terms ) ).find( 'option' );
59
60 // root
61 var root = {
62 text: rlFoldersArgs.root,
63 priority: 1,
64 props: {
65 [rlFoldersArgs.taxonomy]: 0,
66 'force_update': 0,
67 'include_children': false
68 }
69 };
70
71 // media folder
72 if ( rlFoldersArgs.terms !== '' && terms.length > 0 ) {
73 filters[0] = root;
74
75 $( $.parseHTML( rlFoldersArgs.terms ) ).find( 'option' ).each( function( i, option ) {
76 term_id = parseInt( $( option ).val() );
77 term_id = ( term_id === 0 ? 'all' : term_id );
78 last_priority = i + 2;
79
80 filters[term_id] = {
81 text: $( option ).text(),
82 priority: last_priority,
83 props: {
84 [rlFoldersArgs.taxonomy]: term_id,
85 'force_update': 0,
86 'include_children': false
87 }
88 };
89 } );
90 // all files
91 } else {
92 filters['all'] = {
93 text: rlFoldersArgs.all_terms,
94 priority: 1,
95 props: {
96 [rlFoldersArgs.taxonomy]: 'all',
97 'force_update': 0,
98 'include_children': true
99 }
100 };
101
102 filters[0] = root;
103 }
104
105 this.filters = filters;
106 }
107 } );
108
109 var RLFoldersAttachmentsBrowser = wp.media.view.AttachmentsBrowser;
110
111 // extend AttachmentsBrowser
112 wp.media.view.AttachmentsBrowser = wp.media.view.AttachmentsBrowser.extend( {
113 createToolbar: function() {
114 // load the original toolbar
115 RLFoldersAttachmentsBrowser.prototype.createToolbar.call( this );
116
117 attachments_browser = this;
118
119 // skip remote library
120 if ( this.model.get( 'id' ) !== 'rl-remote-library' ) {
121 this.toolbar.set( 'RLfoldersFilterLabel', new wp.media.view.Label( {
122 value: 'Filter by folder',
123 attributes: {
124 'for': 'media-attachment-rl-folders-filters'
125 },
126 priority: -75
127 } ).render() );
128
129 this.toolbar.set( 'RLfoldersAttachmentFilters', new RLWPMediaViewAttachmentFilters( {
130 controller: this.controller,
131 model: this.collection.props,
132 priority: -75
133 } ).render() );
134 }
135 }
136 } );
137
138 // extend AttachmentCompat
139 var RLAttachmentCompat = {
140 save: wp.media.view.AttachmentCompat.prototype.save,
141 postSave: wp.media.view.AttachmentCompat.prototype.postSave
142 };
143
144 $.extend( wp.media.view.AttachmentCompat.prototype, {
145 save: function( event ) {
146 if ( ! allow_modal_media_tag_saving ) {
147 // RLAttachmentCompat.save.apply( this, arguments );
148 // this.$el.closest( '.attachment-details' ).removeClass( 'save-ready' ).addClass( 'save-waiting' );
149
150 return;
151 }
152
153 var select = $( '.rl-media-tag-select2' ),
154 selected = select.select2( 'data' ),
155 tags = [],
156 data = {};
157
158 for ( i = 0; i < selected.length; i++ ) {
159 tags.push( selected[i].id );
160 }
161
162 if ( event )
163 event.preventDefault();
164
165 // get serialized data
166 _.each( this.$el.serializeArray(), function( pair ) {
167 data[ pair.name ] = pair.value;
168 } );
169
170 // update rl media tag
171 data[select.attr( 'name' )] = tags.join( ',' );
172
173 this.controller.trigger( 'attachment:compat:waiting', ['waiting'] );
174 this.model.saveCompat( data ).always( _.bind( this.postSave, this ) );
175
176 // display spinner
177 this.$el.closest( '.attachment-details' ).removeClass( 'save-ready' ).addClass( 'save-waiting' );
178 },
179 postSave: function() {
180 RLAttachmentCompat.postSave.apply( this, arguments );
181
182 // hide spinner
183 this.$el.closest( '.attachment-details' ).addClass( 'save-ready' ).removeClass( 'save-waiting' );
184 }
185 } );
186 }
187
188 // ready event
189 $( function() {
190 // wpuploader
191 if ( typeof wp.Uploader !== 'undefined' ) {
192 // extend uploader to apply dynamic folder ID
193 $.extend( wp.Uploader.prototype, {
194 init: function() {
195 this.uploader.bind( 'BeforeUpload', function( file ) {
196 file.settings.multipart_params.rl_folders_upload_files_term_id = rl_folder_id;
197 } );
198 }
199 } );
200 // plupload
201 } else if ( typeof uploader !== 'undefined' ) {
202 uploader.bind( 'BeforeUpload', function( file ) {
203 uploader.settings.multipart_params.rl_folders_upload_files_term_id = rl_folder_id;
204 } );
205 }
206
207 // wp.media.view.Attachment exists?
208 if ( 'Attachment' in wp.media.view ) {
209 // handle attachments details
210 wp.media.view.Attachment.Details.prototype.on( 'ready', function( ) {
211 // initialize select2
212 setTimeout( initSelect2, 5 );
213 } );
214 }
215
216 // do nothing for wp_enqueue_media
217 if ( rlFoldersArgs.page === 'media' ) {
218 initFolders();
219
220 // folder change
221 $( document ).on( 'change', '#media-attachment-rl-folders-filters', function() {
222 $( '#rl_folders_upload_files' ).val( $( this ).val() );
223 } );
224 } else {
225 var active_nodes = [],
226 plugins = ['sort', 'dnd'];
227
228 // detect active library mode
229 active_mode = ( $( 'body' ).hasClass( 'rl-folders-upload-grid-mode' ) ? 'grid' : 'list' );
230
231 // add media folders container
232 if ( active_mode === 'list' ) {
233 // add tree
234 $( '#posts-filter' ).before( rlFoldersArgs.template );
235
236 // add spinner
237 $( '.filter-items .actions' ).append( '<span class="spinner"></span>' );
238
239 // initialize draggable
240 draggable( 'list' );
241 // grid
242 } else {
243 // add tree
244 $( '#wp-media-grid .error' ).after( rlFoldersArgs.template );
245
246 initFolders();
247 }
248
249 // activate wholerow plugin if needed
250 if ( rlFoldersArgs.wholerow === '1' ) {
251 plugins.push( 'wholerow' );
252 }
253
254 // initialize jstree
255 $( '#rl-folders-tree' ).jstree( {
256 'core': {
257 'check_callback': function( operation, node, node_parent, node_position, more ) {
258 // prevent moving folders to 'all files' folder
259 return ! ( operation === 'move_node' && node_parent.parent === '#' && node_parent.a_attr['data-term_id'] === 'all' );
260 },
261 'multiple': false,
262 'expand_selected_onload': false,
263 'worker': false,
264 'animation': 150
265 },
266 'dnd': {
267 'is_draggable': function( object ) {
268 // prevent moving main folders
269 return ( object[0].parent !== '#' );
270 }
271 },
272 'sort': function( a, b ) {
273 // do not sort main and root nodes
274 if ( a === 'j1_1' )
275 return -1;
276 else
277 return this.get_text( a ).toLowerCase() > this.get_text( b ).toLowerCase() ? 1 : -1;
278 },
279 'plugins': plugins
280 } );
281
282 // apply theme
283 $( '#rl-folders-tree' ).jstree( 'set_theme', rlFoldersArgs.theme );
284
285 // handle folder click
286 $( document ).on( 'click', '.jstree-anchor', click_node );
287
288 // add new folder
289 $( document ).on( 'click', '.rl-folders-add-new-folder', function() {
290 // get current node
291 var parent_node = $( '#rl-folders-tree' ).jstree().get_selected().toString();
292
293 // create new node
294 var new_node = $( '#rl-folders-tree' ).jstree( 'create_node', parent_node, rlFoldersArgs.new_folder, 'inside', function() {}, true );
295
296 // deselect old node
297 $( '#rl-folders-tree' ).jstree( 'deselect_node', parent_node );
298
299 if ( active_mode === 'list' ) {
300 // disable redirect in select_node
301 disable_redirect = true;
302 }
303
304 // select new node
305 $( '#rl-folders-tree' ).jstree( 'select_node', new_node, true, true );
306
307 // open old node
308 $( '#rl-folders-tree' ).jstree( 'open_node', parent_node, function() {
309 var link = $( '#' + new_node + '_anchor' ),
310 content = link.html().match( '<i(?:.+)?/i>' )[0],
311 tree = $( '#rl-folders-tree' ).jstree( true ).get_json( '#', { 'flat': true } );
312
313 // unbind event
314 $( document ).off( 'click', '.jstree-anchor' );
315
316 // disable all nodes
317 $.each( tree, function( key, value ) {
318 if ( value.state.selected == false ) {
319 $( '#rl-folders-tree' ).jstree( 'disable_node', value.id );
320 }
321 } );
322
323 // hide icons
324 $( '.rl-folders-add-new-folder' ).hide();
325
326 // show icons
327 $( '.rl-folders-save-new-folder, .rl-folders-cancel-new-folder' ).show();
328
329 // disable icons
330 $( '.rl-folders-rename-folder, .rl-folders-delete-folder, .rl-folders-expand-folder, .rl-folders-collapse-folder' ).addClass( 'disabled-link' );
331
332 // hide node, show input
333 link.hide().after( '<span id="' + parent_node + '_span">' + content + '<input id="rl-folders-enter-new-folder" type="text" value="' + rlFoldersArgs.new_folder + '" placeholder="" data-term_id="' + parseInt( link.data( 'term_id' ) ) + '" data-nof="0" /></span>' );
334
335 // select text inside input
336 $( '#rl-folders-enter-new-folder' ).trigger( 'select' );
337
338 $( '#rl-folders-enter-new-folder' ).on( 'keyup', function( e ) {
339 // enter button
340 if ( e.which === 13 ) {
341 save_node( true, parseInt( $( '#' + parent_node + '_anchor' ).data( 'term_id' ) ) );
342 // escape button
343 } else if ( e.which === 27 ) {
344 restore_node( true, true );
345 }
346 } );
347 }, $( '#rl-folders-tree' ).jstree().settings.core.animation );
348
349 return false;
350 } );
351
352 // rename folder
353 $( document ).on( 'click', '.rl-folders-rename-folder', function() {
354 var node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString(),
355 link = $( '#' + node_id + '_anchor' ),
356 term_id = link.data( 'term_id' );
357
358 // prevent renaming main folders ('root' and 'all files')
359 if ( term_id === 'all' || term_id === 0 ) {
360 return false;
361 }
362
363 var content = link.html().match( '(<i(?:.+)?/i>)(.+)' ),
364 split = content[2].split( ' ' ),
365 nof = split.pop().match( /\d+/ )[0],
366 name = split.join( ' ' ),
367 tree = $( '#rl-folders-tree' ).jstree( true ).get_json( '#', { 'flat': true } );
368
369 // unbind event
370 $( document ).off( 'click', '.jstree-anchor' );
371
372 // disable all nodes
373 $.each( tree, function( key, value ) {
374 if ( value.state.selected == false ) {
375 $( '#rl-folders-tree' ).jstree( 'disable_node', value.id );
376 }
377 } );
378
379 // hide icons
380 $( '.rl-folders-rename-folder' ).hide();
381
382 // show icons
383 $( '.rl-folders-save-folder, .rl-folders-cancel-folder' ).show();
384
385 // disable icons
386 $( '.rl-folders-add-new-folder, .rl-folders-delete-folder, .rl-folders-expand-folder, .rl-folders-collapse-folder' ).addClass( 'disabled-link' );
387
388 // hide node, show input
389 link.hide().after( '<span id="' + node_id + '_span">' + content[1] + '<input id="rl-folders-enter-folder" type="text" value="' + name + '" placeholder="' + name + '" data-term_id="' + parseInt( term_id ) + '" data-nof="' + nof + '" /></span>' );
390
391 // select text inside input
392 $( '#rl-folders-enter-folder' ).trigger( 'select' );
393
394 $( '#rl-folders-enter-folder' ).on( 'keyup', function( e ) {
395 // enter button
396 if ( e.which === 13 ) {
397 save_node( false, 0 );
398 // escape button
399 } else if ( e.which === 27 ) {
400 restore_node( false, false );
401 }
402 } );
403
404 return false;
405 } );
406
407 // save folder
408 $( document ).on( 'click', '.rl-folders-save-folder', function() {
409 save_node( false, 0 );
410
411 return false;
412 } );
413
414 // save new folder
415 $( document ).on( 'click', '.rl-folders-save-new-folder', function() {
416 save_node( true, parseInt( $( '#' + $( '#rl-folders-tree' ).jstree().get_selected().toString() + '_anchor' ).data( 'term_id' ) ) );
417
418 return false;
419 } );
420
421 // cancel renaming folder
422 $( document ).on( 'click', '.rl-folders-cancel-folder', function() {
423 restore_node( false, false );
424
425 return false;
426 } );
427
428 // cancel adding new folder
429 $( document ).on( 'click', '.rl-folders-cancel-new-folder', function() {
430 restore_node( true, true );
431
432 return false;
433 } );
434
435 // delete folder
436 $( document ).on( 'click', '.rl-folders-delete-folder', function() {
437 if ( ! $( this ).hasClass( 'disabled-link' ) && confirm( rlFoldersArgs.remove_children === '1' ? rlFoldersArgs.delete_terms : rlFoldersArgs.delete_term ) ) {
438 // show spinner
439 toggle_spinner( true );
440
441 var node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString(),
442 term_id = parseInt( $( '#' + node_id + '_anchor' ).data( 'term_id' ) );
443
444 // delete term with children using ajax
445 $.post( ajaxurl, {
446 action: 'rl-folders-delete-term',
447 term_id: term_id,
448 children: rlFoldersArgs.remove_children,
449 nonce: rlFoldersArgs.nonce
450 } ).done( function( response ) {
451 try {
452 if ( response.success ) {
453 // get parent node
454 var parent = $( '#rl-folders-tree' ).jstree( 'get_parent', node_id );
455
456 // update upload select
457 update_upload_select( $( response.data ).find( 'option' ), '' );
458
459 // remove children?
460 if ( rlFoldersArgs.remove_children === '0' && ! $( '#rl-folders-tree' ).jstree( 'is_leaf', node_id ) ) {
461 // open removing node
462 $( '#rl-folders-tree' ).jstree( 'open_node', node_id, function() {
463 // move every child to a new parent
464 $( '#rl-folders-tree' ).jstree( 'get_children_dom', node_id ).each( function( i, el ) {
465 move_node( $( el ).attr( 'id' ), parent );
466 } );
467 }, $( '#rl-folders-tree' ).jstree().settings.core.animation );
468 }
469
470 // delete node
471 $( '#rl-folders-tree' ).jstree( 'delete_node', node_id );
472
473 // select parent node
474 $( '#rl-folders-tree' ).jstree( 'select_node', parent );
475
476 // force to update view
477 $( '#media-attachment-rl-folders-filters' ).val( $( '#' + parent + '_anchor' ).data( 'term_id' ) ).trigger( 'change' );
478
479 refresh_scrollbars();
480 } else {
481 //@TODO
482 }
483 } catch( e ) {
484 //@TODO
485 }
486
487 // hide spinner
488 toggle_spinner( false );
489 } ).fail( function() {
490 // hide spinner
491 toggle_spinner( false );
492 } );
493 }
494
495 return false;
496 } );
497
498 // expand folder
499 $( document ).on( 'click', '.rl-folders-expand-folder', function() {
500 if ( ! $( this ).hasClass( 'disabled-link' ) ) {
501 $( '#rl-folders-tree' ).jstree( 'open_all', $( '#rl-folders-tree' ).jstree().get_selected(), $( '#rl-folders-tree' ).jstree().settings.core.animation );
502 }
503
504 return false;
505 } );
506
507 // collapse folder
508 $( document ).on( 'click', '.rl-folders-collapse-folder', function() {
509 if ( ! $( this ).hasClass( 'disabled-link' ) ) {
510 $( '#rl-folders-tree' ).jstree( 'close_all', $( '#rl-folders-tree' ).jstree().get_selected(), $( '#rl-folders-tree' ).jstree().settings.core.animation );
511 }
512
513 return false;
514 } );
515
516 // select folder event handler
517 $( '#rl-folders-tree' ).on( 'select_node.jstree', function() {
518 // get node id
519 var node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString();
520
521 // list mode?
522 if ( active_mode === 'list' ) {
523 if ( disable_redirect ) {
524 disable_redirect = false;
525 } else {
526 window.location.replace( $( '#' + node_id + '_anchor' ).attr( 'href' ) );
527 }
528
529 return;
530 } else {
531 // update mode links
532 update_mode_link( 'grid' );
533 update_mode_link( 'list' );
534 }
535
536 // get term id of selected node
537 var term_id = $( '#' + node_id + '_anchor' ).data( 'term_id' );
538
539 // select term id in dropdown
540 $( '#rl_folders_upload_files' ).val( term_id === 'all' ? 0 : term_id );
541
542 // update term_id in uploader parameters
543 rl_folder_id = parseInt( term_id );
544
545 if ( isNaN( rl_folder_id ) )
546 rl_folder_id = 0;
547
548 // enable/disable icons for folders
549 if ( term_id === 'all' )
550 $( '.rl-folders-add-new-folder, .rl-folders-rename-folder, .rl-folders-delete-folder' ).addClass( 'disabled-link' );
551 else if ( term_id === 0 ) {
552 $( '.rl-folders-rename-folder, .rl-folders-delete-folder' ).addClass( 'disabled-link' );
553 $( '.rl-folders-add-new-folder' ).removeClass( 'disabled-link' );
554 } else
555 $( '.rl-folders-add-new-folder, .rl-folders-rename-folder, .rl-folders-delete-folder' ).removeClass( 'disabled-link' );
556
557 // enable/disable icons for non-empty folders
558 if ( $( '#rl-folders-tree' ).jstree( 'is_leaf', node_id ) )
559 $( '.rl-folders-expand-folder, .rl-folders-collapse-folder' ).addClass( 'disabled-link' );
560 else
561 $( '.rl-folders-expand-folder, .rl-folders-collapse-folder' ).removeClass( 'disabled-link' );
562 } );
563
564 // rename node event
565 $( '#rl-folders-tree' ).on( 'rename_node.jstree', function( event, tree ) {
566 // new node?
567 if ( event_data.create ) {
568 // set term id
569 tree.node.a_attr['data-term_id'] = event_data.response.term_id;
570
571 // set url
572 tree.node.a_attr.href = event_data.response.url;
573
574 // clear event data
575 event_data = {};
576 }
577 } );
578
579 // jstree is ready
580 $( '#rl-folders-tree' ).on( 'ready.jstree', function( e, data ) {
581 if ( active_mode === 'list' ) {
582 droppable( 'list' );
583 }
584
585 // initialize perfect scrollbar
586 rl_ps = new PerfectScrollbar( '#rl-folders-tree', {
587 wheelSpeed: 3,
588 wheelPropagation: true,
589 minScrollbarLength: 30
590 } );
591
592 // replace edit function to prevent using F2 key natively by jstree
593 $.jstree.core.prototype.edit = function( obj, default_text, callback ) {
594 $( '.rl-folders-rename-folder' ).trigger( 'click' );
595 };
596
597 // update mode links
598 update_mode_link( 'grid' );
599 update_mode_link( 'list' );
600 } );
601
602 // close all folders event
603 $( '#rl-folders-tree' ).on( 'close_all.jstree', function() {
604 refresh_scrollbars();
605 } );
606
607 // open all folders event
608 $( '#rl-folders-tree' ).on( 'open_all.jstree', function() {
609 refresh_scrollbars();
610 } );
611
612 // open folder event handler
613 $( '#rl-folders-tree' ).on( 'close_node.jstree', function() {
614 refresh_scrollbars();
615 } );
616
617 // open folder event handler
618 $( '#rl-folders-tree' ).on( 'open_node.jstree', function() {
619 refresh_scrollbars();
620
621 if ( active_mode === 'grid' ) {
622 // refresh tree elements to make children of selected node droppable
623 droppable( 'grid' );
624 }
625 } );
626
627 // after ajax complete
628 $( document ).on( 'ajaxComplete', function( event, xhr, object ) {
629 // check ajax action
630 var action = parse_str( 'action', object.data );
631
632 // attachments were moved
633 if ( action === 'rl-folders-move-attachments' ) {
634 // refresh droppable
635 droppable( active_mode );
636 // built-in query attachments
637 } else if ( action === 'query-attachments' ) {
638 // initialize droppable
639 droppable( 'grid' );
640
641 // initialize draggable
642 draggable( 'grid' );
643
644 // empty frame?
645 if ( grid_frame === null ) {
646 // store grid frame
647 grid_frame = wp.media.frame.content.get();
648
649 // set root as main folder for uploads
650 rl_folder_id = 0;
651 }
652 }
653 } );
654
655 // folder change
656 $( document ).on( 'change', '#media-attachment-rl-folders-filters', function() {
657 if ( active_mode === 'list' )
658 return;
659
660 var node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString();
661
662 // visiting node for the first time?
663 if ( typeof active_nodes[node_id] === 'undefined' )
664 active_nodes[node_id] = true;
665 else {
666 var term_id = $( this ).val();
667
668 // force ajax call
669 grid_frame.collection.props.set( 'force_update', + new Date() );
670
671 // make sure dropdown has valid term_id selected
672 $( this ).val( term_id );
673 }
674 } );
675
676 // change parent of the dragged folder
677 $( '#rl-folders-tree' ).on( 'move_node.jstree', function( e, object ) {
678 // prevent infinite loop
679 if ( move_node_failed ) {
680 move_node_failed = false;
681
682 return false;
683 }
684
685 // show spinner
686 toggle_spinner( true );
687
688 $.post( ajaxurl, {
689 action: 'rl-folders-move-term',
690 term_id: parseInt( object.node.a_attr['data-term_id'] ),
691 parent_id: parseInt( $( '#' + object.parent + '_anchor' ).data( 'term_id' ) ),
692 nonce: rlFoldersArgs.nonce
693 } ).done( function( response ) {
694 try {
695 if ( response.success ) {
696 // update upload select
697 update_upload_select( $( response.data ).find( 'option' ), '' );
698
699 // open parent node
700 $( '#rl-folders-tree' ).jstree( 'open_node', object.parent, '', $( '#rl-folders-tree' ).jstree().settings.core.animation );
701 } else {
702 move_node( object.node.id, object.old_parent, object.old_position );
703 }
704 } catch( e ) {
705 move_node( object.node.id, object.old_parent, object.old_position );
706 }
707
708 // hide spinner
709 toggle_spinner( false );
710 } ).fail( function() {
711 move_node( object.node.id, object.old_parent, object.old_position );
712
713 // hide spinner
714 toggle_spinner( false );
715 } );
716 } );
717
718 $( document ).on( 'click', '.select-mode-toggle-button', function() {
719 if ( grid_frame.controller.isModeActive( 'select' ) ) {
720 // refresh draggable
721 draggable( 'grid' );
722 } else {
723 // hide filters
724 $( '#media-attachment-rl-folders-filters' ).hide();
725 }
726 } );
727 }
728
729 // change uploading folder
730 $( document ).on( 'change', '#rl_folders_upload_files', function() {
731 // update term_id in uploader parameters
732 rl_folder_id = parseInt( $( this ).val() );
733
734 if ( isNaN( rl_folder_id ) )
735 rl_folder_id = 0;
736 } );
737
738 if ( rlFoldersArgs.page !== 'media' ) {
739 // press modal compat attachment left, right or escape key
740 $( document ).on( 'keydown', function( e ) {
741 if ( ( 'INPUT' === e.target.nodeName || 'TEXTAREA' === e.target.nodeName ) && ! ( e.target.readOnly || e.target.disabled ) )
742 return;
743
744 // escape key
745 if ( e.keyCode === 27 )
746 $( '.media-modal-close' ).trigger( 'click' );
747 } );
748 }
749 } );
750
751 // initialize select2 and it's events
752 function initSelect2() {
753 var select = $( '.rl-media-tag-select2' );
754
755 // skip initialization of select2
756 if ( select.length === 0 || select.hasClass( 'select2-hidden-accessible' ) )
757 return;
758
759 // init select2
760 select.select2( {
761 closeOnSelect: true,
762 multiple: true,
763 width: '100%',
764 minimumInputLength: 2,
765 dropdownCssClass: 'rl-media-tag-select2-dropdown',
766 ajax: {
767 delay: 250,
768 url: ajaxurl,
769 data: function( params ) {
770 return {
771 action: 'ajax-tag-search',
772 tax: 'rl_media_tag',
773 q: params.term
774 }
775 },
776 processResults: function( data ) {
777 var newdata = [];
778
779 // filter results
780 data = data.split( /[\r\n]+/ ).filter( Boolean );
781
782 // prepare select2 format
783 for ( i = 0; i < data.length; i++ ) {
784 newdata[i] = { id: data[i], text: data[i] };
785 }
786
787 return {
788 results: newdata
789 };
790 }
791 }
792 } );
793
794 // change select
795 select.on( 'change', function( e ) {
796 allow_modal_media_tag_saving = true;
797 } );
798
799 // select item
800 select.on( 'select2:select', function( e ) {
801 allow_modal_media_tag_saving = false;
802 } );
803
804 // unselect item
805 select.on( 'select2:unselect', function( e ) {
806 allow_modal_media_tag_saving = false;
807 } );
808 }
809
810 // update mode link (grid or list)
811 function update_mode_link( mode ) {
812 var selector = $( '.view-switch > a.view-' + mode ),
813 link = selector.prop( 'href' );
814
815 // get query string
816 var query = link.split( 'upload.php' )[1];
817
818 // parse query string
819 var string = parse_str( rlFoldersArgs.taxonomy, query );
820
821 // get term_id
822 var term = $( '#' + $( '#rl-folders-tree' ).jstree().get_selected().toString() + '_anchor' ).data( 'term_id' );
823
824 if ( mode === 'list' ) {
825 // 'all' on grid is 0 on list
826 if ( term === 'all' )
827 term = 0;
828 // -1 on list is 0 on grid
829 else if ( term === 0 )
830 term = -1;
831 }
832
833 // no 'taxonomy=term_id' in query?
834 if ( string === '' )
835 selector.prop( 'href', link + '&' + rlFoldersArgs.taxonomy + '=' + term );
836 // found pair so replace term_id with new one just in case it's invalid
837 else
838 selector.prop( 'href', link.replace( new RegExp( rlFoldersArgs.taxonomy + '=' + '(-?[0-9]+|all)', 'g' ), rlFoldersArgs.taxonomy + '=' + term ) );
839 }
840
841 // refresh perfect scrollbar
842 function refresh_scrollbars() {
843 setTimeout( function() {
844 rl_ps.update();
845 }, 200 );
846 }
847
848 // droppable (skip 'all files')
849 function droppable( mode ) {
850 // var node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString();
851 var node_id = $( '#rl-folders-tree' ).jstree( 'get_selected', false );
852
853 // is wholerow plugin active?
854 if ( rlFoldersArgs.wholerow === '1' ) {
855 var wholerow = $( 'div.jstree-wholerow.jstree-wholerow-clicked' );
856
857 // destroy only selected droppable node first if needed
858 if ( typeof wholerow.droppable( 'instance' ) !== 'undefined' )
859 wholerow.droppable( 'destroy' );
860
861 // droppable nodes selector, skip 'all files' and current folder
862 selector = $( '#rl-folders-tree .jstree-wholerow:not(:eq(0))' ).not( '#' + node_id + ' .jstree-wholerow-clicked' );
863 } else {
864 var anchor = $( '#' + node_id + '_anchor' );
865
866 // destroy only selected droppable node first if needed
867 if ( typeof anchor.droppable( 'instance' ) !== 'undefined' )
868 anchor.droppable( 'destroy' );
869
870 // droppable nodes selector, skip 'all files' and current folder
871 selector = $( '#rl-folders-tree li a.jstree-anchor:not(:eq(0),#' + node_id + '_anchor)' );
872 }
873
874 // list mode
875 if ( mode === 'list' ) {
876 selector.droppable( {
877 activeClass: 'rl-folders-state-active',
878 hoverClass: 'rl-folders-state-hover',
879 accept: '#the-list tr',
880 tolerance: 'pointer',
881 drop: function( event, ui ) {
882 var node = $( event.target ).closest( 'li' ).find( 'a.jstree-anchor' ),
883 old_node = $( '#' + $( '#rl-folders-tree' ).jstree().get_selected().toString() + '_anchor' ),
884 attachments = [],
885 ids = $( '#the-list .check-column input[type="checkbox"]:checked' ),
886 old_term_id = parseInt( old_node.data( 'term_id' ) ),
887 new_term_id = parseInt( node.data( 'term_id' ) );
888
889 if ( isNaN( old_term_id ) )
890 old_term_id = -1;
891
892 if ( isNaN( new_term_id ) )
893 new_term_id = -1;
894
895 toggle_spinner( true );
896
897 // dropped single unchecked attachment?
898 if ( ids.length === 0 )
899 attachments.push( ui.draggable.find( '.check-column input[type="checkbox"]' ).val() );
900 else {
901 ids.each( function( i, item ) {
902 attachments.push( parseInt( $( item ).val() ) );
903 } );
904 }
905
906 $.post( ajaxurl, {
907 action: 'rl-folders-move-attachments',
908 attachment_ids: attachments,
909 old_term_id: old_term_id,
910 new_term_id: new_term_id,
911 nonce: rlFoldersArgs.nonce
912 } ).done( function( response ) {
913 try {
914 if ( response.success ) {
915 // do not update 'all files' folder or remove attachments from there
916 if ( old_term_id !== -1 ) {
917 // remove attachments
918 for ( i = 0; i < response.data.attachments.success.length; i++ ) {
919 $( '#post-' + response.data.attachments.success[i] ).fadeOut( 'fast', function() {
920 $( this ).remove();
921
922 // display 'no media' text
923 if ( $( '#the-list tr' ).length === 0 )
924 $( '#the-list' ).append( rlFoldersArgs.no_media_items );
925 } );
926 }
927
928 // update old node number
929 update_node_number( old_node, response.data, false );
930 }
931
932 // update new node number
933 update_node_number( node, response.data, true );
934 }
935 } catch( e ) {
936 }
937
938 // hide spinner
939 toggle_spinner( false );
940 } ).fail( function() {
941 // hide spinner
942 toggle_spinner( false );
943 } );
944 }
945 } );
946 // grid mode
947 } else {
948 selector.droppable( {
949 activeClass: 'rl-folders-state-active',
950 hoverClass: 'rl-folders-state-hover',
951 accept: 'li.attachment',
952 tolerance: 'pointer',
953 drop: function( event, ui ) {
954 var node = $( event.target ).closest( 'li' ).find( 'a.jstree-anchor' ),
955 old_node = $( '#' + $( '#rl-folders-tree' ).jstree().get_selected().toString() + '_anchor' ),
956 term_id = old_node.data( 'term_id' ),
957 old_term_id = term_id === 'all' ? -1 : parseInt( term_id ),
958 attachments = [];
959
960 toggle_spinner( true );
961
962 // single attachment
963 if ( $( '.media-frame' ).hasClass( 'mode-edit' ) )
964 attachments.push( parseInt( ui.draggable.data( 'id' ) ) );
965 // selection of attachments
966 else {
967 $( 'ul.attachments > li.selected' ).each( function( i, item ) {
968 attachments.push( parseInt( $( item ).data( 'id' ) ) );
969 } );
970 }
971
972 $.post( ajaxurl, {
973 action: 'rl-folders-move-attachments',
974 attachment_ids: attachments,
975 old_term_id: old_term_id,
976 new_term_id: parseInt( node.data( 'term_id' ) ),
977 nonce: rlFoldersArgs.nonce
978 } ).done( function( response ) {
979 try {
980 if ( response.success ) {
981 // do not update 'all files' folder or remove attachments from there
982 if ( old_term_id !== -1 ) {
983 // remove attachments
984 for ( i = 0; i < response.data.attachments.success.length; i++ ) {
985 $( 'ul.attachments li[data-id="' + response.data.attachments.success[i] + '"]' ).fadeOut( 'fast', function() {
986 $( this ).remove();
987
988 // display 'no media' text
989 if ( $( 'ul.attachments li' ).length === 0 )
990 $( '.no-media' ).removeClass( 'hidden' );
991 } );
992 }
993
994 // update old node number
995 update_node_number( old_node, response.data, false );
996 }
997
998 // update new node number
999 update_node_number( node, response.data, true );
1000
1001 // deactivate select mode and activate edit mode
1002 grid_frame.controller.deactivateMode( 'select' ).activateMode( 'edit' );
1003 }
1004 } catch( e ) {
1005 }
1006
1007 // hide spinner
1008 toggle_spinner( false );
1009 } ).fail( function() {
1010 // hide spinner
1011 toggle_spinner( false );
1012 } );
1013 }
1014 } );
1015 }
1016 }
1017
1018 // draggable
1019 function draggable( mode ) {
1020 // grid mode
1021 if ( mode === 'grid' ) {
1022 var nof = 0;
1023
1024 $( '.media-frame-content ul.attachments li' ).draggable( {
1025 helper: function() {
1026 var attachments = 1;
1027
1028 // grid mode
1029 if ( active_mode === 'grid' ) {
1030 // single attachment
1031 if ( $( '.media-frame' ).hasClass( 'mode-edit' ) )
1032 attachments = 1;
1033 // selection of attachments
1034 else
1035 attachments = $( 'ul.attachments li.selected' ).length;
1036 // list mode
1037 } else
1038 attachments = $( '#the-list .check-column input[type="checkbox"]:checked' ).length;
1039
1040 // pass number of attachments to drag event
1041 nof = attachments;
1042
1043 return '<div class="rl-folders-dragged-item"><div class="dashicons dashicons-media-default"></div><span>' + attachments + '</span></div>';
1044 },
1045 drag: function() {
1046 if ( nof === 0 )
1047 return false;
1048 },
1049 appendTo: 'body',
1050 distance: 3,
1051 cursor: 'move',
1052 cursorAt: { top: 20, left: 20 },
1053 containment: '#wpwrap',
1054 revert: 'invalid',
1055 zIndex: 999
1056 } );
1057 // list mode
1058 } else {
1059 $( '#the-list tr' ).draggable( {
1060 helper: function() {
1061 var attachments = $( '#the-list .check-column input[type="checkbox"]:checked' ).length;
1062
1063 // dragging unchecked single attachment?
1064 if ( attachments === 0 )
1065 attachments = 1;
1066
1067 return '<div class="rl-folders-dragged-item"><div class="dashicons dashicons-media-default"></div><span>' + attachments + '</span></div>';
1068 },
1069 appendTo: 'body',
1070 distance: 3,
1071 cursor: 'move',
1072 cursorAt: { top: 20, left: 20 },
1073 containment: '#wpwrap',
1074 revert: 'invalid',
1075 zIndex: 999
1076 } );
1077 }
1078 }
1079
1080 // update number of attachments of specified node
1081 function update_node_number( node, data, add ) {
1082 var html = node.html().split( /(?:<i(?:.+)?\/i>)(.+)\s\((\d+)\)/ );
1083
1084 // rename node
1085 $( '#rl-folders-tree' ).jstree( 'rename_node', node.parent().attr( 'id' ), html[1] + ' (' + ( parseInt( html[2] ) + ( add ? data.attachments.success.length - data.attachments.duplicated.length : - data.attachments.success.length ) ) + ')' );
1086 }
1087
1088 // toggle spinner
1089 function toggle_spinner( show ) {
1090 if ( show ) {
1091 if ( active_mode === 'list' )
1092 $( '.filter-items .actions' ).find( '.spinner' ).addClass( 'is-active' );
1093 else
1094 $( '.media-toolbar-secondary' ).find( '.spinner' ).addClass( 'is-active' );
1095 } else {
1096 if ( active_mode === 'list' )
1097 $( '.filter-items .actions' ).find( '.spinner' ).removeClass( 'is-active' );
1098 else
1099 $( '.media-toolbar-secondary' ).find( '.spinner' ).removeClass( 'is-active' );
1100 }
1101 }
1102
1103 // move back node to old parent and position
1104 function move_node( node, parent, position ) {
1105 // set this to prevent infinite loop
1106 move_node_failed = true;
1107
1108 // move back node
1109 $( '#rl-folders-tree' ).jstree( 'move_node', node, parent, position );
1110 }
1111
1112 // cancel renaming/adding node
1113 function restore_node( new_node, cancel ) {
1114 var node_id = '#' + $( '#rl-folders-tree' ).jstree().get_selected().toString(),
1115 tree = $( '#rl-folders-tree' ).jstree( true ).get_json( '#', { 'flat': true } );
1116
1117 // show icon
1118 $( new_node ? '.rl-folders-add-new-folder' : '.rl-folders-rename-folder' ).show();
1119
1120 // hide icons
1121 $( new_node ? '.rl-folders-save-new-folder, .rl-folders-cancel-new-folder' : '.rl-folders-save-folder, .rl-folders-cancel-folder' ).hide();
1122
1123 // enable icons
1124 $( new_node ? '.rl-folders-rename-folder, .rl-folders-delete-folder' : '.rl-folders-add-new-folder, .rl-folders-delete-folder' ).removeClass( 'disabled-link' );
1125
1126 if ( new_node && cancel ) {
1127 // get parent node
1128 var parent = $( '#rl-folders-tree' ).jstree( 'get_parent', node_id );
1129
1130 // delete node
1131 $( '#rl-folders-tree' ).jstree( 'delete_node', node_id );
1132
1133 // disable redirect in select_node
1134 if ( active_mode === 'list' )
1135 disable_redirect = true;
1136
1137 // select parent node
1138 $( '#rl-folders-tree' ).jstree( 'select_node', parent );
1139 } else {
1140 // enable icons for non-empty nodes
1141 if ( ! $( '#rl-folders-tree' ).jstree( 'is_leaf', node_id ) )
1142 $( '.rl-folders-expand-folder, .rl-folders-collapse-folder' ).removeClass( 'disabled-link' );
1143
1144 // restore folder
1145 $( node_id + '_span' ).remove();
1146 $( node_id + '_anchor' ).show();
1147 }
1148
1149 // enable all nodes
1150 $.each( tree, function( key, value ) {
1151 $( '#rl-folders-tree' ).jstree( 'enable_node', value.id );
1152 } );
1153
1154 // refresh droppable nodes
1155 droppable( active_mode );
1156
1157 // rebind event
1158 $( document ).on( 'click', '.jstree-anchor', click_node );
1159 }
1160
1161 // save node with new name
1162 function save_node( new_node, parent_id ) {
1163 var input = $( new_node ? '#rl-folders-enter-new-folder' : '#rl-folders-enter-folder' );
1164 node_id = $( '#rl-folders-tree' ).jstree().get_selected().toString(),
1165 name = input.val().trim(),
1166 nof = input.data( 'nof' );
1167
1168 if ( ! new_node ) {
1169 var term_id = parseInt( input.data( 'term_id' ) );
1170
1171 if ( isNaN( term_id ) )
1172 term_id = 0;
1173 }
1174
1175 // empty or the same name?
1176 if ( name === '' || name === input.attr( 'placeholder' ) ) {
1177 restore_node( new_node, true );
1178
1179 return false;
1180 }
1181
1182 // show spinner
1183 toggle_spinner( true );
1184
1185 $.post( ajaxurl, new_node ? {
1186 action: 'rl-folders-add-term',
1187 parent_id: parent_id,
1188 name: name,
1189 nonce: rlFoldersArgs.nonce
1190 } : {
1191 action: 'rl-folders-rename-term',
1192 term_id: term_id,
1193 name: name,
1194 nonce: rlFoldersArgs.nonce
1195 } ).done( function( response ) {
1196 try {
1197 if ( response.success ) {
1198 if ( new_node ) {
1199 // add new folder to dropdown
1200 $( '#media-attachment-rl-folders-filters' ).append( '<option value="' + response.data.term_id + '">' + response.data.name + '</option>' );
1201
1202 if ( attachments_browser !== null ) {
1203 // update filters
1204 attachments_browser.toolbar.get( 'RLfoldersAttachmentFilters' ).filters[response.data.term_id] = {
1205 text: response.data.name,
1206 priority: last_priority + 1,
1207 props: {
1208 [rlFoldersArgs.taxonomy]: response.data.term_id,
1209 'force_update': 0,
1210 'include_children': false
1211 }
1212 };
1213 }
1214 } else {
1215 // rename node
1216 $( '#media-attachment-rl-folders-filters option[value="' + term_id + '"]' ).text( response.data.name );
1217 $( '#media-attachment-rl-folders-filters option[value="' + term_id + '"]' ).prop( 'selected', true );
1218 }
1219
1220 // pass data to rename_node event
1221 event_data = {
1222 response: response.data,
1223 create: new_node
1224 };
1225
1226 // rename node
1227 $( '#rl-folders-tree' ).jstree( 'rename_node', node_id, response.data.name + ' (' + nof + ')' );
1228
1229 // sort node
1230 $( '#rl-folders-tree' ).jstree( 'sort', node_id, false );
1231
1232 if ( new_node ) {
1233 // add term id and new url
1234 $( '#' + node_id + '_anchor' ).attr( 'data-term_id', response.data.term_id ).attr( 'href', response.data.url );
1235
1236 // force to update view
1237 $( '#media-attachment-rl-folders-filters' ).val( response.data.term_id ).trigger( 'change' );
1238
1239 if ( active_mode === 'list' )
1240 window.location.replace( response.data.url );
1241 }
1242
1243 // update upload select
1244 update_upload_select( $( response.data.select ).find( 'option' ), new_node ? response.data.term_id : term_id );
1245 }
1246
1247 restore_node( new_node, false );
1248 } catch( e ) {
1249 restore_node( new_node, true );
1250 }
1251
1252 // hide spinner
1253 toggle_spinner( false );
1254 } ).fail( function() {
1255 // hide spinner
1256 toggle_spinner( false );
1257
1258 restore_node( new_node, true );
1259 } );
1260 }
1261
1262 // update upload select
1263 function update_upload_select( options, selected ) {
1264 $( '#rl_folders_upload_files' ).empty().append( options ).val( selected );
1265 }
1266
1267 // click node handler
1268 function click_node() {
1269 $( '#media-attachment-rl-folders-filters' ).val( $( this ).data( 'term_id' ) ).trigger( 'change' );
1270 }
1271
1272 // parse query string
1273 function parse_str( name, str ) {
1274 var regex = new RegExp( '[?&]' + name.replace( /[\[\]]/g, '\\$&' ) + '(=([^&#]*)|&|#|$)' ),
1275 results = regex.exec( '&' + str );
1276
1277 return ( ! results || ! results[2] ? '' : decodeURIComponent( results[2].replace( /\+/g, ' ' ) ) );
1278 }
1279
1280 } )( jQuery );