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