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