cs-cloning.js
9 years ago
cs-cloning.min.js
9 years ago
cs-visibility.js
9 years ago
cs-visibility.min.js
9 years ago
cs.js
9 years ago
cs.min.js
9 years ago
cs-cloning.js
319 lines
| 1 | /*! Custom Sidebars - v3.0.7.1 |
| 2 | * https://premium.wpmudev.org/project/custom-sidebars-pro/ |
| 3 | * Copyright (c) 2017; * Licensed GPLv2+ */ |
| 4 | /*global jQuery:false */ |
| 5 | /*global window:false */ |
| 6 | /*global document:false */ |
| 7 | /*global wp:false */ |
| 8 | /*global wpmUi:false */ |
| 9 | |
| 10 | jQuery(function init_cloning() { |
| 11 | var $doc = jQuery( document ), |
| 12 | $all = jQuery( '#widgets-right' ), |
| 13 | is_cloning = false; |
| 14 | |
| 15 | /** |
| 16 | * Moves the "Clone" button next to the save button. |
| 17 | */ |
| 18 | var init_widget = function init_widget( ev, el ) { |
| 19 | var $widget = jQuery( el ).closest( '.widget' ), |
| 20 | $btn = $widget.find( '.csb-clone-button' ), |
| 21 | $target = $widget.find( '.widget-control-actions .widget-control-save' ), |
| 22 | $spinner = $widget.find( '.widget-control-actions .spinner' ), |
| 23 | $btn_save = $widget.find( '.widget-control-save' ); |
| 24 | |
| 25 | if ( $widget.data( '_csb_cloning' ) ) { |
| 26 | return; |
| 27 | } |
| 28 | |
| 29 | $spinner.insertBefore( $target ).css({ 'float': 'left' }); |
| 30 | $btn.insertBefore( $target ).click( clone_widget ); |
| 31 | $btn_save.click( prepare_update_group ); |
| 32 | |
| 33 | $widget.data( '_csb_cloning', true ); |
| 34 | }; |
| 35 | |
| 36 | /** |
| 37 | * Updates the group-counter when a widget is added. |
| 38 | */ |
| 39 | var update_group_counter = function update_group_counter( ev, el ) { |
| 40 | // We do NOT want to change the group-id when we clone a widget... |
| 41 | if ( is_cloning ) { return false; } |
| 42 | |
| 43 | var $widget = jQuery( el ).closest( '.widget' ), |
| 44 | $widget_group = $widget.find( 'input.csb-clone-group' ), |
| 45 | group_id = parseInt( $widget_group.val() ), |
| 46 | check = null; |
| 47 | |
| 48 | do { |
| 49 | check = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ); |
| 50 | if ( ! check.length || ( 1 === check.length && check[0] === $widget_group[0] ) ) { |
| 51 | break; |
| 52 | } else { |
| 53 | group_id += 1; |
| 54 | } |
| 55 | } |
| 56 | while ( true ); |
| 57 | |
| 58 | $widget_group.val( group_id ); |
| 59 | update_template_groups(); |
| 60 | }; |
| 61 | |
| 62 | /** |
| 63 | * Updates all group_id values for the widget-templates to the next free id. |
| 64 | */ |
| 65 | var update_template_groups = function update_template_groups() { |
| 66 | var $groups = jQuery( '#widgets-left input.csb-clone-group' ), |
| 67 | next_id = parseInt( $groups.first().val() ); |
| 68 | |
| 69 | while ( $all.find( 'input.csb-clone-group[value="' + next_id + '"]' ).length ) { |
| 70 | next_id += 1; |
| 71 | } |
| 72 | |
| 73 | $groups.val( next_id ); |
| 74 | }; |
| 75 | |
| 76 | /** |
| 77 | * Viually highlights all widgets of the same group. |
| 78 | */ |
| 79 | var mark_group = function mark_group( ev ) { |
| 80 | var $widget = jQuery( this ).closest( '.widget' ), |
| 81 | group_id = $widget.find( 'input.csb-clone-group' ).val(), |
| 82 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ); |
| 83 | |
| 84 | if ( isNaN( group_id ) || group_id < 1 ) { |
| 85 | return; |
| 86 | } |
| 87 | |
| 88 | $members.addClass('csb-marker'); |
| 89 | $widget.removeClass('csb-marker'); |
| 90 | }; |
| 91 | |
| 92 | /** |
| 93 | * Removes the visual highlighting of group widgets. |
| 94 | */ |
| 95 | var unmark_group = function unmark_group( ev ) { |
| 96 | var $marked = jQuery( '.widget.csb-marker' ); |
| 97 | $marked.removeClass('csb-marker'); |
| 98 | }; |
| 99 | |
| 100 | /** |
| 101 | * Adds icons to all widgets that are inside a group. |
| 102 | */ |
| 103 | var init_group_icons = function init_group_icons() { |
| 104 | var $groups = $all.find( 'input.csb-clone-group' ); |
| 105 | |
| 106 | $groups.each(function() { |
| 107 | var group_id = jQuery( this ).val(), |
| 108 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ), |
| 109 | $titles = $members.find( '.widget-title h4, .widget-title h3' ), |
| 110 | action = 'add'; |
| 111 | |
| 112 | if ( isNaN( group_id ) || group_id < 1 ) { |
| 113 | action = 'remove'; |
| 114 | } |
| 115 | if ( $members.length < 2 ) { |
| 116 | action = 'remove'; |
| 117 | } |
| 118 | |
| 119 | // Always remove the icons from the group. |
| 120 | $titles.removeClass( 'csb-group group-active' ) |
| 121 | .find( '.btn-clone-group' ).remove(); |
| 122 | $members.removeAttr( 'data-csb-icon' ); |
| 123 | |
| 124 | // If action is "add" then we add the icons again. |
| 125 | if ( action === 'add' ) { |
| 126 | $titles.addClass( 'csb-group group-active' ) |
| 127 | .prepend( '<i class="dashicons dashicons-admin-links btn-clone-group"></i> ' ); |
| 128 | $titles.find( '.btn-clone-group' ) |
| 129 | .hover( mark_group, unmark_group ) |
| 130 | .click( toggle_group ); |
| 131 | } |
| 132 | }); |
| 133 | }; |
| 134 | |
| 135 | /** |
| 136 | * Remove widget from group/assign to group again (only works until widget |
| 137 | * was saved.) |
| 138 | */ |
| 139 | var toggle_group = function toggle_group( ev ) { |
| 140 | var $widget = jQuery( this ).closest( '.widget' ), |
| 141 | $title = $widget.find( '.widget-title h4' ), |
| 142 | $icon = $title.find( '.btn-clone-group' ), |
| 143 | $group = $widget.find( 'input.csb-clone-group' ); |
| 144 | |
| 145 | ev.preventDefault(); |
| 146 | ev.stopPropagation(); |
| 147 | if ( $title.hasClass( 'group-active' ) ) { |
| 148 | $title.removeClass( 'group-active' ); |
| 149 | $icon.removeClass('dashicons-admin-links').addClass('dashicons-editor-unlink'); |
| 150 | $group.data( 'group', $group.val() ); |
| 151 | $group.val( 0 ); |
| 152 | unmark_group(); |
| 153 | } else { |
| 154 | $title.addClass( 'group-active' ); |
| 155 | $icon.addClass('dashicons-admin-links').removeClass('dashicons-editor-unlink'); |
| 156 | $group.val( $group.data( 'group' ) ); |
| 157 | mark_group.call( this, [ev] ); |
| 158 | } |
| 159 | return false; |
| 160 | }; |
| 161 | |
| 162 | /** |
| 163 | * Clones the widget: |
| 164 | * Add a new widget using default WordPress JS API and then update all the |
| 165 | * input values of the new widget to match the original widget. |
| 166 | */ |
| 167 | var clone_widget = function clone_widget( ev ) { |
| 168 | var $widget = jQuery( this ).closest( '.widget' ), |
| 169 | $available = jQuery( '#widgets-left' ), |
| 170 | $chooser = jQuery( '.widgets-chooser' ), |
| 171 | $content = jQuery( '#wpbody-content' ); |
| 172 | |
| 173 | ev.preventDefault(); |
| 174 | is_cloning = true; |
| 175 | |
| 176 | // 1. If the current widget is new then first save the current widget |
| 177 | var state = $widget.find( 'input.csb-clone-state' ).val(); |
| 178 | if ( 'new' === state ) { |
| 179 | window.wpWidgets.save( $widget, 0, 0, 0 ); |
| 180 | } |
| 181 | |
| 182 | // 2. Close any open chooser |
| 183 | window.wpWidgets.clearWidgetSelection(); |
| 184 | $chooser.slideUp( 200, function() { |
| 185 | $chooser.hide(); |
| 186 | $content.append( this ); |
| 187 | }); |
| 188 | |
| 189 | // 3. Find the "widget-in-question". |
| 190 | var class_name = $widget.find('input.id_base').val(), |
| 191 | $base = $available.find('input.id_base[value="' + class_name + '"]'), |
| 192 | $in_question = $base.closest( '.widget' ); |
| 193 | $in_question.addClass( 'widget-in-question' ); |
| 194 | |
| 195 | // 4. Provide data about the origin widget. |
| 196 | var group_id = $widget.find( 'input.csb-clone-group' ).val(), |
| 197 | $contr = $in_question.find( '.widget-control-actions' ), |
| 198 | $group = $in_question.find( 'input.csb-clone-group' ), |
| 199 | $state = $in_question.find( 'input.csb-clone-state' ); |
| 200 | $group.val( group_id ); |
| 201 | $state.val( 'empty' ); |
| 202 | |
| 203 | // 5. Select the current sidebar in the chooser. |
| 204 | var $sidebar = $widget.closest( '.widgets-sortables' ), |
| 205 | sb_id = $sidebar.attr( 'id' ); |
| 206 | $chooser.find ( '.widgets-chooser-selected' ).removeClass( 'widgets-chooser-selected' ); |
| 207 | $chooser.find( 'li' ).each( function() { |
| 208 | var $li = jQuery( this ); |
| 209 | if ( sb_id === $li.data('sidebarId') ) { |
| 210 | $li.addClass( 'widgets-chooser-selected' ).focus(); |
| 211 | } |
| 212 | }); |
| 213 | |
| 214 | // 6. Add the new widget to the sidebar. |
| 215 | // This will directly trigger the ajax command to save the widget. |
| 216 | window.wpWidgets.addWidget( $chooser ); |
| 217 | |
| 218 | // 7. Remove the custom elements and information again. |
| 219 | window.wpWidgets.clearWidgetSelection(); |
| 220 | update_template_groups(); |
| 221 | |
| 222 | is_cloning = false; |
| 223 | |
| 224 | return false; |
| 225 | }; |
| 226 | |
| 227 | /** |
| 228 | * Saves the specified widget if the clone-state is "empty". |
| 229 | */ |
| 230 | var populate_widget = function populate_widget( $widget ) { |
| 231 | var $state = $widget.find( 'input.csb-clone-state' ); |
| 232 | |
| 233 | if ( $state.val() === 'empty' ) { |
| 234 | $widget.addClass( 'wpmui-loading' ); |
| 235 | window.wpWidgets.save( $widget, 0, 1, 0 ); |
| 236 | } |
| 237 | }; |
| 238 | |
| 239 | /** |
| 240 | * Update all widgets belonging to the same group. |
| 241 | */ |
| 242 | var prepare_update_group = function prepare_update_group( ev ) { |
| 243 | var $widget = jQuery( this ).closest( '.widget' ), |
| 244 | group_id = $widget.find( 'input.csb-clone-group' ).val(), |
| 245 | $members = $all.find( 'input.csb-clone-group[value="' + group_id + '"]' ).closest( '.widget' ).not( $widget ); |
| 246 | |
| 247 | $members.each(function() { |
| 248 | var $item = jQuery( this ), |
| 249 | $state = $item.find( 'input.csb-clone-state' ); |
| 250 | |
| 251 | $item.addClass('wpmui-loading').attr( 'data-reload', true ); |
| 252 | }); |
| 253 | }; |
| 254 | |
| 255 | /** |
| 256 | * Update all widgets belonging to the same group. |
| 257 | */ |
| 258 | var update_group_widgets = function update_group_widgets( el ) { |
| 259 | var $widgets = $all.find( '.widget[data-reload]' ); |
| 260 | |
| 261 | $widgets.each(function() { |
| 262 | var $item = jQuery( this ), |
| 263 | $state = $item.find( 'input.csb-clone-state' ); |
| 264 | |
| 265 | $state.val( 'empty' ); |
| 266 | $item.removeAttr( 'data-reload' ); |
| 267 | window.wpWidgets.save( $item, 0, 0, 0 ); |
| 268 | }); |
| 269 | }; |
| 270 | |
| 271 | /** |
| 272 | * Global ajax observer reacts to all ajax responses. We need this to find |
| 273 | * out when a new widget is saved for the first time. |
| 274 | */ |
| 275 | var ajax_observer = function ajax_observer( ev, xhr, opt, resp ) { |
| 276 | var data = ( 'string' === typeof opt.data ? opt.data : '' ), |
| 277 | find_action = data.match( /^.*&action=([^&]+).*$/ ), |
| 278 | find_widget = data.match( /^.*&widget-id=([^&]+).*$/ ), |
| 279 | action = (find_action && find_action.length === 2 ? find_action[1] : ''), |
| 280 | widget = (find_widget && find_widget.length === 2 ? find_widget[1] : ''); |
| 281 | |
| 282 | if ( ! widget.length ) { |
| 283 | return; |
| 284 | } |
| 285 | |
| 286 | var $base = jQuery( '.widget input.widget-id[value="' + widget + '"]' ), |
| 287 | $widget = $base.closest( '.widget' ); |
| 288 | |
| 289 | switch ( action ) { |
| 290 | case 'save-widget': |
| 291 | $widget.removeClass( 'wpmui-loading' ); |
| 292 | if ( ! resp.length ) { |
| 293 | // Populate widget with data from group, if required. |
| 294 | populate_widget( $widget ); |
| 295 | } else if ( resp.match( /^deleted:/ ) ) { |
| 296 | // Widget was deleted and is removed with animation. |
| 297 | window.setTimeout( init_group_icons, 400 ); |
| 298 | } else { |
| 299 | // Existing widget was updated. |
| 300 | init_group_icons(); |
| 301 | update_group_widgets( $widget ); |
| 302 | } |
| 303 | break; |
| 304 | |
| 305 | default: |
| 306 | // Unrelated ajax event. |
| 307 | } |
| 308 | }; |
| 309 | |
| 310 | |
| 311 | $all.find( '.widget' ).each( init_widget ); |
| 312 | $doc.on( 'widget-added', init_widget ); |
| 313 | $doc.on( 'widget-added', update_group_counter ); |
| 314 | $doc.ajaxSuccess( ajax_observer ); |
| 315 | |
| 316 | init_group_icons(); |
| 317 | update_template_groups(); |
| 318 | }); |
| 319 |