| 1 |
jQuery(function($){ |
| 2 |
$.fn.wpjam_each = function(cb){ |
| 3 |
return this.each((i, el) => cb($(el), i)); |
| 4 |
}; |
| 5 |
|
| 6 |
$.fn.wpjam_on = function(name, selector, callback, options){ |
| 7 |
let cb = !_.isFunction(callback) && $.fn[callback] ? (e, ...args) => $(e.currentTarget)[callback](e, ...args) : callback; |
| 8 |
|
| 9 |
let {type, wait=300, ...data} = options || {}; |
| 10 |
|
| 11 |
if(type == 'throttle'){ |
| 12 |
cb = _.throttle(cb, wait); |
| 13 |
}else if(type == 'debounce' || ['submit', 'change', 'click'].includes(name)){ |
| 14 |
cb = _.debounce(cb, wait, true); |
| 15 |
} |
| 16 |
|
| 17 |
return this.on(name+'.wpjam', (!selector || selector === 'body') ? null : selector, data, cb); |
| 18 |
}; |
| 19 |
|
| 20 |
$.fn.wpjam_init = function(){ |
| 21 |
let filter = this.is('body') ? ':not(form *)' : ''; |
| 22 |
let rules = $.fn.wpjam_init.rules = $.fn.wpjam_init.rules || [ |
| 23 |
[null, '[data-indeterminate]', $el => $el.prop('indeterminate', true).removeAttr('data-indeterminate')] |
| 24 |
]; |
| 25 |
|
| 26 |
filter && _.each(Object.keys($.fn), handle => { |
| 27 |
if(handle.startsWith('wpjam_') && _.every(rules, (r) => r[0] !== handle)){ |
| 28 |
let {selector, events} = $.fn[handle]; |
| 29 |
|
| 30 |
rules.push([handle, selector]); |
| 31 |
|
| 32 |
_.each(events, event => $('body').wpjam_on(event.name, event.selector || selector, handle, event)); |
| 33 |
} |
| 34 |
}); |
| 35 |
|
| 36 |
_.each(rules, ([handle, sel, cb])=> sel && this.find(sel.split(',').map(s => s.trim()+filter).join(',')).wpjam_each($el => cb ? cb($el) : $el[handle]())); |
| 37 |
|
| 38 |
filter && this.find('form').wpjam_each($el => $el.data('initialized') || $el.data('initialized', true).wpjam_init()); |
| 39 |
|
| 40 |
return this; |
| 41 |
}; |
| 42 |
|
| 43 |
$.fn.wpjam_highlight = function(type){ |
| 44 |
if(type){ |
| 45 |
this.attr('data-highlight', type); |
| 46 |
|
| 47 |
return type == 'delete' ? this : this.hide().fadeIn(1000); |
| 48 |
} |
| 49 |
|
| 50 |
return this.removeAttr('data-highlight'); |
| 51 |
}; |
| 52 |
|
| 53 |
$.fn.wpjam_remove = function(cb){ |
| 54 |
return this.fadeOut(400, ()=> this.remove() && cb && cb()); |
| 55 |
}; |
| 56 |
|
| 57 |
$.fn.wpjam_control = function(){ |
| 58 |
let $field = !this.data('type') && this.is(':checkbox, :radio') ? this.closest('.wpjam-choice') : []; |
| 59 |
|
| 60 |
return $field[0] ? $field : this; |
| 61 |
}; |
| 62 |
|
| 63 |
$.fn.wpjam_field = function(){ |
| 64 |
let {type, key, value, button_text: btn, multiple: mu, ...data} = this.data(); |
| 65 |
|
| 66 |
let id = this.attr('id'); |
| 67 |
let name = this.attr('name')+(mu ? '[]' : ''); |
| 68 |
let $wrap; |
| 69 |
|
| 70 |
if(type == 'color'){ |
| 71 |
$wrap = this.attr('type', 'text').addClass('expandable').val(value).wpColorPicker().closest('.wp-picker-container'); |
| 72 |
|
| 73 |
$wrap.prepend($('<label>').append(['.before', '> button', '> span', '.after'].map(s => $wrap.find(s)))).append($wrap.next('.description')); |
| 74 |
|
| 75 |
btn && $wrap.find('.wp-color-result-text').text(btn); |
| 76 |
}else if(type == 'timestamp'){ |
| 77 |
if(value){ |
| 78 |
let pad2 = num => (num.toString().length < 2 ? '0' : '')+num; |
| 79 |
let date = new Date(+value*1000); |
| 80 |
|
| 81 |
this.val(date.getFullYear()+'-'+pad2(date.getMonth()+1)+'-'+pad2(date.getDate())+'T'+pad2(date.getHours())+':'+pad2(date.getMinutes())); |
| 82 |
} |
| 83 |
|
| 84 |
this.attr('type', 'datetime-local'); |
| 85 |
}else if(type == 'toggle'){ |
| 86 |
value && this.prop('checked', true); |
| 87 |
}else if(['img', 'image', 'file'].includes(type)){ |
| 88 |
if(!this.closest('.wpjam-'+type)[0]){ |
| 89 |
$wrap = this.wrap('<div class="wpjam-'+type+'">').parent(); |
| 90 |
|
| 91 |
if(!wpjam.upload_files){ |
| 92 |
this.prop('disabled', true); |
| 93 |
$wrap.addClass('disabled'); |
| 94 |
} |
| 95 |
|
| 96 |
this.after('<a class="add-media button"><span class="dashicons dashicons-admin-media"></span>'+btn+'</a>'); |
| 97 |
|
| 98 |
(type == 'img' ? this.parent() : this.next('a.button')).on('click.wpjam', (e)=> { |
| 99 |
$(e.target).is('.del-img') ? this.data('value', '').wpjam_field() : this.wpjam_media(value => this.data('value', value).wpjam_field()); |
| 100 |
}); |
| 101 |
} |
| 102 |
|
| 103 |
if(type == 'img'){ |
| 104 |
this.prevAll('img, a.del-img')[value ? 'remove' : 'wpjam_remove'](); |
| 105 |
this.val(value ? value.value : '').before(value ? '<img src="'+value.url+data.thumb_args+'" /><a class="del-img dashicons dashicons-no-alt"></a>' : ''); |
| 106 |
}else{ |
| 107 |
this.val(value); |
| 108 |
} |
| 109 |
}else if(type == 'uploader'){ |
| 110 |
$wrap = this.add(this.prev('.before')).add(this.next('.after')).wrapAll('<div class="wpjam-uploader">').parent(); |
| 111 |
|
| 112 |
this.before($('<label class="button">'+btn+'</label>').append($('<input type="file" accept="'+this.attr('accept')+'" hidden>').on('change', e => { |
| 113 |
e.target.files[0] && this.wpjam_upload(e.target.files[0]); |
| 114 |
e.target.value = ''; |
| 115 |
}))); |
| 116 |
|
| 117 |
data.drag_drop && $wrap.addClass('drag-drop').append([ |
| 118 |
'<p class="drag-drop-info">'+wp.i18n.__('Drop files to upload', 'default')+'</p>', |
| 119 |
$('<p class="drag-drop-buttons"></p>').append(this) |
| 120 |
]).on('dragover', e => { |
| 121 |
e.preventDefault(); |
| 122 |
$wrap.addClass('drag-over'); |
| 123 |
}).on('dragleave drop', e => { |
| 124 |
$wrap.removeClass('drag-over'); |
| 125 |
}).on('drop', e=> { |
| 126 |
e.preventDefault(); |
| 127 |
this.wpjam_upload(e.originalEvent.dataTransfer.files[0]); |
| 128 |
}); |
| 129 |
|
| 130 |
this.wpjam_label(); |
| 131 |
}else if(type == 'textarea'){ |
| 132 |
this.addClass('expandable'); |
| 133 |
}else if(type == 'editor'){ |
| 134 |
if(data.editor){ |
| 135 |
if(wp.editor){ |
| 136 |
wp.editor.remove(id); |
| 137 |
wp.editor.initialize(id, {...data.editor, mediaButtons: wpjam.upload_files}); |
| 138 |
|
| 139 |
this.attr({rows: 10, cols: 40}); |
| 140 |
}else{ |
| 141 |
console.log('请在页面加载 add_action(\'admin_footer\', \'wp_enqueue_editor\');'); |
| 142 |
} |
| 143 |
} |
| 144 |
}else if(type == 'cascade'){ |
| 145 |
let keys = ['data-data_type', 'data-query_args', 'data-filter_key']; |
| 146 |
let attr = _.object(keys, _.map(keys, k => this.attr(k))); |
| 147 |
|
| 148 |
this.addClass('wpjam-cascade').removeAttr(keys.join(' ')); |
| 149 |
|
| 150 |
_.each(data.options, (options, i)=> { |
| 151 |
let $select = $('<select>', {id: id+'_'+i, name: name+'[]'}).addClass('field-key-'+key+'_'+i).appendTo(this).wpjam_options(options); |
| 152 |
|
| 153 |
if(options.length){ |
| 154 |
value[i] && $select.val(value[i]); |
| 155 |
}else{ |
| 156 |
i > 0 && $select.addClass('hidden'); |
| 157 |
} |
| 158 |
|
| 159 |
i > 0 && $select.attr(attr).wpjam_show_if(key+'_'+(i-1), '!=', ''); |
| 160 |
}); |
| 161 |
}else if(['select', 'radio', 'checkbox'].includes(type)){ |
| 162 |
let options = data.options || []; |
| 163 |
|
| 164 |
if(data.custom){ |
| 165 |
let {title, by, key: ck, ...attr} = data.custom; |
| 166 |
|
| 167 |
let keys = options.flatMap(o => o.options ? o.options.map(c => String(c.value)) : [String(o.value)]); |
| 168 |
let diff = [].concat(value || []).filter(v => !keys.includes(String(v))); |
| 169 |
let $input = $('<input>').attr({...attr, name, required: 'required'}).addClass('field-key-'+ck).wpjam_show_if(key, by); |
| 170 |
|
| 171 |
this.wpjam_options([...options, {value: by, label: title}]); |
| 172 |
|
| 173 |
if(diff.length){ |
| 174 |
$input.val(diff[0]); |
| 175 |
|
| 176 |
value = mu ? [...[].concat(value).filter(v => keys.includes(String(v))), by] : by; |
| 177 |
} |
| 178 |
|
| 179 |
type === 'select' ? this.after([' ', $input]) : this.append($input); |
| 180 |
}else{ |
| 181 |
this.wpjam_options(options); |
| 182 |
} |
| 183 |
|
| 184 |
if(this.is('select')){ |
| 185 |
this.val(value != null && this.find(`option[value="${value}"]`)[0] ? value : this.find('option:first').val()); |
| 186 |
}else{ |
| 187 |
let $btn = type === 'select' && $('<button>', {type: 'button', text: data.show_option_all || '请选择'}).prop('popoverTargetElement', this[0]).insertBefore(this.attr('popover', 'auto').wrap('<div class="mu-select"></div>')); |
| 188 |
|
| 189 |
this.addClass('wpjam-choice direction-'+(data.direction || ($btn || data.sep ? 'column' : 'row'))); |
| 190 |
|
| 191 |
this.on('change.wpjam', 'input', (e)=> { |
| 192 |
let $el = $(e.target); |
| 193 |
|
| 194 |
$el.is(':checkbox') ? $el.trigger('validate.wpjam') : this.find('label').removeClass('checked'); |
| 195 |
|
| 196 |
$el.closest('label').toggleClass('checked', $el.is(':checked')); |
| 197 |
|
| 198 |
$btn && $btn.text(this.find('label.checked').toArray().map(el => $(el).text().trim()).join(', ') || data.show_option_all || '请选择'); |
| 199 |
}); |
| 200 |
|
| 201 |
this.find(':checkbox')[0] && this.attr('data-validation', true).on('validate.wpjam', (e)=> { |
| 202 |
let $el = $(e.target); |
| 203 |
|
| 204 |
this.find(':checkbox').toArray().forEach(el => el.setCustomValidity('')); |
| 205 |
|
| 206 |
_.each($el.is('input') ? [$el.is(':checked') ? 'max' : 'min'] : ['min', 'max'], type => { |
| 207 |
let v = this.wpjam_schema(type+'Items'); |
| 208 |
let [c, m] = type === 'max' ? ['>', '最多'] : ['<', '至少']; |
| 209 |
|
| 210 |
if(v && wpjam.compare(this.find(':checkbox:checked').length, c, v)){ |
| 211 |
let el = $el.is('input') ? $el[0] : this.find(':checkbox')[0]; |
| 212 |
|
| 213 |
return el.setCustomValidity(m+`选择${v}个`), el.reportValidity(), false; |
| 214 |
} |
| 215 |
}); |
| 216 |
}); |
| 217 |
|
| 218 |
this.attr('id', id+'_options').find([].concat(value === null ? [] : value).map(v => `input[value="${v}"]`).join(',')).trigger("click"); |
| 219 |
} |
| 220 |
}else{ |
| 221 |
this.is('.tiny-text, .small-text') && this.addClass('expandable'); |
| 222 |
} |
| 223 |
|
| 224 |
if($wrap){ |
| 225 |
let show_if = $wrap.find('[data-show_if]').attr('data-show_if'); |
| 226 |
|
| 227 |
show_if && $wrap.attr('data-show_if', show_if); |
| 228 |
|
| 229 |
$wrap.addClass(['disabled', 'readonly', 'hidden'].filter(v => this.hasClass(v))); |
| 230 |
} |
| 231 |
|
| 232 |
return this.removeAttr('data-value data-options data-custom'); |
| 233 |
}; |
| 234 |
|
| 235 |
$.fn.wpjam_field.selector = 'input[data-type], select[data-type], textarea[data-type], fieldset[data-type]'; |
| 236 |
|
| 237 |
$.fn.wpjam_options = function(options){ |
| 238 |
let $field = this.data('type') ? this : this.closest('[data-type]'); |
| 239 |
|
| 240 |
let {type, value, key, sep, multiple: mu} = $field.data(); |
| 241 |
|
| 242 |
let name = $field.attr('name')+(mu ? '[]' : ''); |
| 243 |
let select = $field.is('select') || type === 'cascade'; |
| 244 |
|
| 245 |
if(type === 'cascade'){ |
| 246 |
options = [{value: '', label: $field.data('show_option_all') || '请选择'}, ...options]; |
| 247 |
} |
| 248 |
|
| 249 |
return this.append(options.map((opt, i) => { |
| 250 |
if(opt.options){ |
| 251 |
let {options: go, data={}, ...attr} = opt; |
| 252 |
|
| 253 |
return select ? $('<optgroup>').attr(attr).wpjam_data(data).appendTo(this).wpjam_options(go) : ''; |
| 254 |
} |
| 255 |
|
| 256 |
let {label, alias, description, image, class: cls, data={}, ...attr} = opt; |
| 257 |
let $el = select ? $('<option>', attr) : $('<label>').addClass(cls); |
| 258 |
|
| 259 |
$el.wpjam_data(data); |
| 260 |
|
| 261 |
if(description){ |
| 262 |
let $desc = $field.next('p.description'); |
| 263 |
|
| 264 |
($desc[0] ? $desc : $('<p>').addClass('description').insertAfter($field)).append($('<span>').html(description).wpjam_show_if(key, opt.value)); |
| 265 |
} |
| 266 |
|
| 267 |
if(select){ |
| 268 |
return $el.val(value !== null && (alias || []).includes(String(value)) ? value : opt.value).text(label); |
| 269 |
} |
| 270 |
|
| 271 |
let $input = $('<input>').addClass('field-key-'+key).attr(attr).attr({ |
| 272 |
name, |
| 273 |
type: mu ? 'checkbox' : 'radio', |
| 274 |
id: $field.attr('id')+'_'+attr.value |
| 275 |
}); |
| 276 |
|
| 277 |
$el.attr('for', $input.attr('id')).append($input); |
| 278 |
|
| 279 |
image && $el.addClass('image-'+$input.attr('type')).append(([].concat(image)).slice(0, 2).map(src => $('<img>').attr({src, alt: label}))); |
| 280 |
|
| 281 |
return $el.append(label).after(select || i == options.length - 1 ? '' : sep); |
| 282 |
})); |
| 283 |
}; |
| 284 |
|
| 285 |
$.fn.wpjam_upload = function(file){ |
| 286 |
let {max_size, key: name, nonce} = this.data(); |
| 287 |
|
| 288 |
if(max_size && file.size > max_size){ |
| 289 |
return alert('文件大小不能� |
| 290 |
过 '+Math.round(max_size/1024/1024)+'MB'); |
| 291 |
} |
| 292 |
|
| 293 |
this.after('<div class="media-item"><div class="progress"><div class="percent">0%</div><div class="bar"></div></div></div>').prev('span').remove(); |
| 294 |
|
| 295 |
let data = new FormData(); |
| 296 |
let xhr = new XMLHttpRequest(); |
| 297 |
|
| 298 |
_.each(wpjam.with_page({ |
| 299 |
name, |
| 300 |
accept: this.attr('accept'), |
| 301 |
action: 'wpjam-upload', |
| 302 |
[name]: file, |
| 303 |
_ajax_nonce: nonce |
| 304 |
}), (v, k)=> data.append(k, v)); |
| 305 |
|
| 306 |
xhr.upload.onprogress = e => { |
| 307 |
let p = Math.round(e.loaded/e.total*100); |
| 308 |
|
| 309 |
this.next('.media-item').find('.bar').width(p*2).end().find('.percent').text(p+'%'); |
| 310 |
}; |
| 311 |
|
| 312 |
xhr.onload = ()=> { |
| 313 |
let res = JSON.parse(xhr.responseText); |
| 314 |
|
| 315 |
res.errcode ? alert(res.errmsg) : this.val(res.path).wpjam_label(); |
| 316 |
|
| 317 |
this.next('.media-item').remove(); |
| 318 |
}; |
| 319 |
|
| 320 |
xhr.open('POST', ajaxurl); |
| 321 |
xhr.send(data); |
| 322 |
} |
| 323 |
|
| 324 |
$.fn.wpjam_label = function(){ |
| 325 |
let $label = this.prev('span.query-label'); |
| 326 |
|
| 327 |
if($label[0]){ |
| 328 |
$label.next('input').val('').change().end().wpjam_remove(); |
| 329 |
}else{ |
| 330 |
let tag = this.hasClass('tag-input'); |
| 331 |
let label = this.data('label') || (this.data('type') === 'uploader' ? this.val().split('/').pop() : tag && this.val()); |
| 332 |
|
| 333 |
label && this.before($('<span>', {class:'query-label'}).append([ |
| 334 |
$('<span>', {class:'dashicons del-item'}).on('click', ()=> this.wpjam_label()), |
| 335 |
tag ? label : $('<span>', {class:'truncate-text', text: label}), |
| 336 |
]).addClass(!tag && this.data('class'))).removeData('label').removeAttr('data-label'); |
| 337 |
} |
| 338 |
}; |
| 339 |
|
| 340 |
$.fn.wpjam_show_if = function(...args){ |
| 341 |
if(args.length > 1){ |
| 342 |
return this.wpjam_data({show_if: _.object(['key', ...(args.length > 2 ? ['compare'] : []), 'value'], args)}); |
| 343 |
} |
| 344 |
|
| 345 |
let show_if = this.data('show_if'); |
| 346 |
|
| 347 |
if(!show_if){ |
| 348 |
return this; |
| 349 |
} |
| 350 |
|
| 351 |
if(!args.length){ |
| 352 |
let key = show_if.key; |
| 353 |
let sk = show_if.current?.includes('__') && show_if.current.split('__').slice(0,-1).concat(key).join('__'); |
| 354 |
let sib = sk && this.closest('form').find('.field-key-'+sk)[0]; |
| 355 |
let dep = sib || this.closest('form').find('.field-key-'+key)[0] || $('.field-key-'+key)[0] || $('#'+key)[0]; |
| 356 |
let $el = dep ? $(dep).wpjam_control() : ''; |
| 357 |
|
| 358 |
if(dep){ |
| 359 |
this.addClass('dep-on-'+($el.data('dep-id') || $el.attr('data-dep-id', 'dep-'+$.guid++).data('dep-id'))); |
| 360 |
|
| 361 |
if(sib){ |
| 362 |
this.data('show_if', {...show_if, key: sk}); |
| 363 |
}else{ |
| 364 |
sk && this.wpjam_show_if($el.wpjam_val()); |
| 365 |
} |
| 366 |
} |
| 367 |
|
| 368 |
return this; |
| 369 |
} |
| 370 |
|
| 371 |
let val = args[0]; |
| 372 |
let show = val === null ? false : wpjam.compare(val, show_if); |
| 373 |
|
| 374 |
this.add(this.nextUntil(':not(br, .after, p.description)')).add(this.prev('.before')).toggleClass('hidden', !show); |
| 375 |
|
| 376 |
if(this.is('option')){ |
| 377 |
this.prop('disabled', !show).is(':selected') && !show && this.closest('select').prop('selectedIndex', 0).wpjam_depend(); |
| 378 |
}else{ |
| 379 |
(this.is(':input') ? this : this.find(':input')).wpjam_each($el => { |
| 380 |
$el.closest('.disabled')[0] || $el.prop('disabled', !show); |
| 381 |
|
| 382 |
if($el.is(this) || $el.parent().is(this)){ |
| 383 |
let {filter_key: fk, query_args: qv} = $el.data() || {}; |
| 384 |
|
| 385 |
if(fk && qv && (!_.has(qv, fk) || (!$el.hasClass('hidden') && val !== null && qv[fk] !== val))){ |
| 386 |
$el.data('query_args', {...qv, [fk] : val ?? ''}); |
| 387 |
|
| 388 |
if(_.has(qv, fk)){ |
| 389 |
if($el.is('select')){ |
| 390 |
return $el.empty().wpjam_query().then(items => (items.length ? $el.wpjam_options(items) : $el.addClass('hidden')).wpjam_depend()); |
| 391 |
} |
| 392 |
|
| 393 |
$el.is('input') && $el.val('').wpjam_label(); |
| 394 |
} |
| 395 |
} |
| 396 |
} |
| 397 |
|
| 398 |
return $el.wpjam_depend(); |
| 399 |
}); |
| 400 |
} |
| 401 |
|
| 402 |
return this; |
| 403 |
}; |
| 404 |
|
| 405 |
$.fn.wpjam_show_if.selector = '[data-show_if]'; |
| 406 |
|
| 407 |
$.fn.wpjam_data_type = function(){ |
| 408 |
let $mu = this.closest('.mu-text'); |
| 409 |
let $hidden = !$mu[0] && this.data('filterable') && $('<input>',{type: 'hidden', name: this.attr('name'), value: this.val()}).insertAfter(this.removeAttr('name')); |
| 410 |
|
| 411 |
if(!this.hasClass('mix-tag')){ |
| 412 |
this.data('label') && ($hidden ? this.val(this.data('label')) : this.wpjam_label()); |
| 413 |
} |
| 414 |
|
| 415 |
return this.autocomplete({ |
| 416 |
minLength: 0, |
| 417 |
delay: 400, |
| 418 |
source: (request, response)=> { |
| 419 |
let items = this.data('items'); |
| 420 |
|
| 421 |
if(items){ |
| 422 |
let term = request.term.toLowerCase(); |
| 423 |
let exclude = $mu.wpjam_schema('uniqueItems') ? $mu.wpjam_val() : []; |
| 424 |
|
| 425 |
response(_.filter(items, item => { |
| 426 |
if(exclude.includes(item.value)){ |
| 427 |
return false; |
| 428 |
} |
| 429 |
|
| 430 |
return !term || item.label.toLowerCase().includes(term) || item.value.toLowerCase().includes(term); |
| 431 |
})); |
| 432 |
}else{ |
| 433 |
this.wpjam_query(request.term).then(items => response(items)); |
| 434 |
} |
| 435 |
}, |
| 436 |
search: (e, ui)=> { |
| 437 |
if(!this.val() && _.isMatch(e.originalEvent, {type: 'keydown', key: 'Backspace'})){ |
| 438 |
return false; |
| 439 |
} |
| 440 |
}, |
| 441 |
select: (e, ui)=> { |
| 442 |
if(this.hasClass('mix-tag')){ |
| 443 |
e.preventDefault(); |
| 444 |
this.wpjam_mix_tag('add', ui.item); |
| 445 |
|
| 446 |
return false; |
| 447 |
}else if($hidden){ |
| 448 |
this.val(ui.item.label); |
| 449 |
$hidden.val(ui.item.value); |
| 450 |
}else{ |
| 451 |
ui.item && this.val(ui.item.value).data('label', ui.item.label).wpjam_label(); |
| 452 |
} |
| 453 |
}, |
| 454 |
change: (e, ui)=> { |
| 455 |
this.trigger('change.wpjam'); |
| 456 |
} |
| 457 |
}).on('click', (e)=> { |
| 458 |
this.autocomplete('search'); |
| 459 |
}).on('keydown', (e)=> { |
| 460 |
!this.val() && e.key === 'Backspace' && this.autocomplete('close'); |
| 461 |
}).on('input', (e)=>{ |
| 462 |
$hidden && $hidden.val(this.val()); |
| 463 |
}); |
| 464 |
}; |
| 465 |
|
| 466 |
$.fn.wpjam_data_type.selector = 'input[data-data_type][data-query_args], input[data-items]'; |
| 467 |
|
| 468 |
$.fn.wpjam_depend = function(){ |
| 469 |
let $el = this.wpjam_control(); |
| 470 |
let val = $el.wpjam_val(); |
| 471 |
let id = $el.data('dep-id'); |
| 472 |
|
| 473 |
id && $('.dep-on-'+id).wpjam_each($el => $el.wpjam_show_if(val)); |
| 474 |
}; |
| 475 |
|
| 476 |
$.fn.wpjam_depend.selector = '[data-dep-id]'; |
| 477 |
$.fn.wpjam_depend.events = [{name: 'change', selector: ':input[data-dep-id], [data-dep-id] :input'}]; |
| 478 |
|
| 479 |
$.fn.wpjam_action = function(e){ |
| 480 |
let type = this.is('#wpjam_option') ? 'option' : (this.is('#wpjam_form, .wpjam-button') ? 'page' : 'list-table'); |
| 481 |
let data = this.data(); |
| 482 |
let $form, $ae, title; |
| 483 |
|
| 484 |
if(this.is('form')){ |
| 485 |
$ae = $(document.activeElement); |
| 486 |
$ae = $ae.is(':submit') ? $ae : this.find(':submit').first().focus(); |
| 487 |
$form = this; |
| 488 |
title = $ae.val(); |
| 489 |
|
| 490 |
if((type == 'option' && $ae.attr('name') === 'reset') ? !confirm('确定要'+title+'吗?') : !this.wpjam_validate()){ |
| 491 |
return false; |
| 492 |
} |
| 493 |
|
| 494 |
$ae.is('body') || $ae.after(wpjam.spinner); |
| 495 |
}else{ |
| 496 |
$form = this.closest('form'); |
| 497 |
title = data.page_title || this.attr('title') || data.title; |
| 498 |
|
| 499 |
if(data.confirm && (data.action == 'delete' ? !showNotice.warn() : !confirm('确定要'+title+'吗?'))){ |
| 500 |
return false; |
| 501 |
} |
| 502 |
} |
| 503 |
|
| 504 |
let indeterminate = $form.find('input[type="checkbox"]:indeterminate').toArray().map(cb => `${encodeURIComponent(cb.name)}=${encodeURIComponent(cb.value)}`).join('&'); |
| 505 |
|
| 506 |
return wpjam.action(type, { |
| 507 |
...(type === 'page' && {page_action: data.action}), |
| 508 |
...(type === 'list-table' && {list_action: data.action, ..._.pick(data, ['bulk', 'id', 'ids'])}), |
| 509 |
...($ae ? { |
| 510 |
action_type: 'submit', |
| 511 |
submit: $ae.attr('name'), |
| 512 |
data: $form.serialize(), |
| 513 |
defaults: data.data || {}, |
| 514 |
$ae |
| 515 |
} : { |
| 516 |
action_type: data.direct ? 'direct' : 'form', |
| 517 |
data: data.data || {}, |
| 518 |
form_data: $.param(wpjam.parse_params($form.serialize(), true)) |
| 519 |
}), |
| 520 |
page_title: title, |
| 521 |
_ajax_nonce: data.nonce, |
| 522 |
indeterminate |
| 523 |
}) && false; |
| 524 |
} |
| 525 |
|
| 526 |
$.fn.wpjam_action.events = [ |
| 527 |
{name: 'click', selector: '.wpjam-button, .list-table-action'}, |
| 528 |
{name: 'submit', selector: '#wpjam_form, #wpjam_option, #list_table_action_form'}, |
| 529 |
]; |
| 530 |
|
| 531 |
$.fn.wpjam_query = function(term){ |
| 532 |
let {data_type, query_args} = this.data(); |
| 533 |
|
| 534 |
if(term){ |
| 535 |
query_args.search = term; |
| 536 |
} |
| 537 |
|
| 538 |
let $mu = this.closest('.mu-text'); |
| 539 |
|
| 540 |
if($mu.wpjam_schema('uniqueItems')){ |
| 541 |
query_args.exclude = $mu.wpjam_val(); |
| 542 |
} |
| 543 |
|
| 544 |
return wpjam.post({ |
| 545 |
action: 'wpjam-query', |
| 546 |
_ajax_nonce: (this.is('select') ? this.parent() : this).data('query_nonce'), |
| 547 |
data_type, |
| 548 |
query_args |
| 549 |
}).then(data => data.errcode ? (data.errmsg && alert(data.errmsg), Promise.reject(data)) : data.items); |
| 550 |
} |
| 551 |
|
| 552 |
$.fn.wpjam_mix_tag = function(e, ...args){ |
| 553 |
let is_e = e ? _.isObject(e) : false; |
| 554 |
let action = is_e ? (e.data.action || e.type) : e; |
| 555 |
|
| 556 |
if(action){ |
| 557 |
if(action == 'keydown'){ |
| 558 |
if(e.key === 'Enter'){ |
| 559 |
e.preventDefault(); |
| 560 |
} |
| 561 |
} |
| 562 |
|
| 563 |
let $field, $editor, $hidden; |
| 564 |
|
| 565 |
if(this.hasClass('mix-tag-editor')){ |
| 566 |
$editor = this; |
| 567 |
$hidden = this.prev('input[type=hidden]'); |
| 568 |
$field = $hidden.prev('input'); |
| 569 |
}else{ |
| 570 |
$field = this; |
| 571 |
$hidden = this.next('input[type=hidden]'); |
| 572 |
$editor = $hidden.next('.mix-tag-editor'); |
| 573 |
} |
| 574 |
|
| 575 |
let sel = window.getSelection(); |
| 576 |
let range, node, word; |
| 577 |
|
| 578 |
if(sel.rangeCount){ |
| 579 |
range = sel.getRangeAt(0); |
| 580 |
node = range.startContainer; |
| 581 |
|
| 582 |
if(node){ |
| 583 |
if($editor[0].contains(node)){ |
| 584 |
$editor.data('range', range); |
| 585 |
}else{ |
| 586 |
range = $editor.data('range'); |
| 587 |
node = range ? range.startContainer : null; |
| 588 |
} |
| 589 |
} |
| 590 |
|
| 591 |
if(node && node.nodeType === Node.TEXT_NODE){ |
| 592 |
let sep = [...($field.data('sep') || []), ' ']; |
| 593 |
let i = range.startOffset - 1; |
| 594 |
|
| 595 |
while(i >= 0 && !sep.includes(node.textContent[i])){ |
| 596 |
i--; |
| 597 |
} |
| 598 |
|
| 599 |
word = node.textContent.substring(i + 1, range.startOffset).trim(); |
| 600 |
} |
| 601 |
} |
| 602 |
|
| 603 |
if(action == 'add'){ |
| 604 |
let $tag = $('<span class="query-label" contenteditable="false" data-value="'+args[0].value+'">'+args[0].label+'</span>'); |
| 605 |
let blank = document.createTextNode(' '); |
| 606 |
|
| 607 |
if(word){ |
| 608 |
range.setStart(node, range.startOffset - word.length); |
| 609 |
range.deleteContents(); |
| 610 |
} |
| 611 |
|
| 612 |
range.insertNode($tag[0]); |
| 613 |
range.setStartAfter($tag[0]); |
| 614 |
$tag.after(blank); |
| 615 |
range.setStartAfter(blank); |
| 616 |
range.collapse(true); |
| 617 |
|
| 618 |
$editor.trigger('focus'); |
| 619 |
|
| 620 |
sel.removeAllRanges(); |
| 621 |
sel.addRange(range); |
| 622 |
}else{ |
| 623 |
$field.autocomplete('option', 'position', {my: 'left top', at: 'left bottom', of: e}).autocomplete('option', 'classes', {'ui-autocomplete': 'mix-tag-autocomplete'}); |
| 624 |
$field.val(word).autocomplete('search', word); |
| 625 |
|
| 626 |
if(action == 'click'){ |
| 627 |
return false; |
| 628 |
} |
| 629 |
} |
| 630 |
|
| 631 |
let parts = []; |
| 632 |
|
| 633 |
$editor.contents().each(function(){ |
| 634 |
if(this.nodeType === Node.TEXT_NODE){ |
| 635 |
parts.push(this.textContent); |
| 636 |
}else if(this.nodeType === Node.ELEMENT_NODE && $(this).hasClass('query-label')){ |
| 637 |
parts.push($(this).data('value')); |
| 638 |
} |
| 639 |
}); |
| 640 |
|
| 641 |
return $hidden.val(parts.join(' ')); |
| 642 |
} |
| 643 |
|
| 644 |
this.css({position: 'absolute', left: '-9999px', width: '1px'}); |
| 645 |
|
| 646 |
let $hidden = $('<input>', {type: 'hidden', name: this.attr('name'), value: this.val()}).insertAfter(this.removeAttr('name')); |
| 647 |
let $editor = $('<div>', {class: 'mix-tag-editor', contenteditable: 'true'}).insertAfter($hidden); |
| 648 |
let value = this.data('value'); |
| 649 |
|
| 650 |
value && value.forEach(item => { |
| 651 |
if(typeof item === 'object'){ |
| 652 |
$('<span class="query-label" contenteditable="false" data-value="'+item.value+'">'+item.label+'</span>').appendTo($editor); |
| 653 |
}else{ |
| 654 |
$editor.append(document.createTextNode(item)); |
| 655 |
} |
| 656 |
}); |
| 657 |
|
| 658 |
return this; |
| 659 |
}; |
| 660 |
|
| 661 |
$.fn.wpjam_mix_tag.selector = 'input.mix-tag[data-items], input.mix-tag[data-data_type]'; |
| 662 |
$.fn.wpjam_mix_tag.events = [ |
| 663 |
{name: 'input', selector: '.mix-tag-editor'}, |
| 664 |
{name: 'click', selector: '.mix-tag-editor'}, |
| 665 |
{name: 'keydown', selector: '.mix-tag-editor'} |
| 666 |
]; |
| 667 |
|
| 668 |
$.fn.wpjam_mu = function(e, ...args){ |
| 669 |
let is_e = e ? _.isObject(e) : false; |
| 670 |
let action = is_e ? (e.data.action || e.type) : e; |
| 671 |
let $mu = this.closest('.mu'); |
| 672 |
let type = $mu.data('type').substring(3); |
| 673 |
|
| 674 |
if(action == 'new_item'){ |
| 675 |
if($mu.wpjam_mu('rest', true) <= 0){ |
| 676 |
is_e && e.type === 'autocompleteselect' && (args[0].item = ''); |
| 677 |
return false; |
| 678 |
} |
| 679 |
|
| 680 |
if(['img', 'image', 'file'].includes(type)){ |
| 681 |
$mu.wpjam_media(value => $mu.wpjam_mu('add_item', value)); |
| 682 |
}else{ |
| 683 |
let $items = $mu.children(); |
| 684 |
|
| 685 |
if($items.length >= 2 && !$items.eq(-2).wpjam_mu('validate')){ |
| 686 |
return false; |
| 687 |
} |
| 688 |
|
| 689 |
$mu.wpjam_mu('add_item'); |
| 690 |
} |
| 691 |
|
| 692 |
if($mu.wpjam_schema('uniqueItems')){ |
| 693 |
let value = $mu.wpjam_val(); |
| 694 |
|
| 695 |
if(value && _.uniq(value).length !== value.length){ |
| 696 |
alert('不� |
| 697 |
�许重复'); |
| 698 |
} |
| 699 |
} |
| 700 |
|
| 701 |
return is_e ? false : true; |
| 702 |
}else if(action == 'add_item'){ |
| 703 |
let $tmpl = $mu.children().last(); |
| 704 |
let $new = $tmpl.clone().find('.new-item, span.query-label').remove().end().insertBefore($tmpl); |
| 705 |
|
| 706 |
let {value, label, url} = _.isObject(args[0]) ? args[0] : {value: args[0]}; |
| 707 |
|
| 708 |
if(['img', 'image', 'file'].includes(type)){ |
| 709 |
type == 'img' && url && $new.prepend($('<img>', {src: url+$new.find('input').data('thumb_args'), 'data-preview':url})); |
| 710 |
|
| 711 |
$new.find('input').val(value); |
| 712 |
}else if(type == 'text'){ |
| 713 |
if(value){ |
| 714 |
$new.find(':input').val(value).data(label ? {label} : {}).wpjam_label(); |
| 715 |
}else{ |
| 716 |
$tmpl.find(':input').is(':visible') && $new.insertAfter($tmpl).find(':input').val('').after($tmpl.find('.new-item')); |
| 717 |
} |
| 718 |
}else if(type == 'fields'){ |
| 719 |
$new.wpjam_mu('template').prevAll().wpjam_each($el => $el.wpjam_mu('tag_label')); |
| 720 |
} |
| 721 |
|
| 722 |
_.isUndefined(value) && $new.wpjam_mu('focus'); |
| 723 |
|
| 724 |
$mu.wpjam_mu('rest'); |
| 725 |
|
| 726 |
return $new.wpjam_init(); |
| 727 |
}else if(action == 'del_item'){ |
| 728 |
return this.closest('.mu-item').wpjam_remove(()=> $mu.wpjam_mu('rest')), false; |
| 729 |
}else if(action == 'rest'){ |
| 730 |
let max = $mu.wpjam_schema('maxItems'); |
| 731 |
let rest = max ? (max - ($mu.children().length - (['img', 'fields', 'text'].includes(type) ? 1 : 0))) : 10000; |
| 732 |
|
| 733 |
max && $mu.attr('data-rest', rest); |
| 734 |
max && args[0] && rest <= 0 && alert('最多支持'+max+'个'); |
| 735 |
|
| 736 |
return rest; |
| 737 |
}else if(action == 'focus'){ |
| 738 |
return this.find(':input:visible').first().focus().select(); |
| 739 |
}else if(action == 'validate'){ |
| 740 |
return this.find(':input').toArray().every(el => el.checkValidity() || (el.reportValidity(), false)); |
| 741 |
}else if(action == 'keydown'){ |
| 742 |
let $item = this.closest('.mu-item'); |
| 743 |
|
| 744 |
if(type == 'text'){ |
| 745 |
if(this.hasClass('tag-input')){ |
| 746 |
let del = e.key === 'Backspace' && !this.val(); |
| 747 |
let timer = $mu.wpjam_timer(!del); |
| 748 |
|
| 749 |
del && (timer ? $item.prev().wpjam_mu('del_item') : $item.prev().fadeOut(300).fadeIn(200)); |
| 750 |
} |
| 751 |
|
| 752 |
if(e.key === 'Enter'){ |
| 753 |
if(this.val() && !this.data('data_type')){ |
| 754 |
if($mu.wpjam_mu('new_item')){ |
| 755 |
this.wpjam_label(); |
| 756 |
|
| 757 |
$(document.activeElement).closest('.mu-item').insertAfter($item).wpjam_mu('focus'); |
| 758 |
}else{ |
| 759 |
this.hasClass('tag-input') && this.val(''); |
| 760 |
} |
| 761 |
} |
| 762 |
|
| 763 |
return false; |
| 764 |
} |
| 765 |
}else{ |
| 766 |
if(e.key === 'Enter'){ |
| 767 |
let $inputs = $item.find(':input:visible'); |
| 768 |
let $next = $inputs.eq($inputs.index(this)+1); |
| 769 |
|
| 770 |
if($next[0]){ |
| 771 |
$next.focus().select(); |
| 772 |
}else if($mu.data('tag_label')){ |
| 773 |
if($item.is($mu.children().eq(-2))){ |
| 774 |
$mu.wpjam_mu('new_item'); |
| 775 |
}else{ |
| 776 |
$item.wpjam_mu('validate') && $item.wpjam_mu('tag_label'); |
| 777 |
} |
| 778 |
} |
| 779 |
|
| 780 |
return false; |
| 781 |
} |
| 782 |
} |
| 783 |
}else if(action == 'tag_label'){ |
| 784 |
let label = $mu.data('tag_label'); |
| 785 |
|
| 786 |
if(label && !this.has('template, span.tag-label')[0]){ |
| 787 |
let prefix = this.find(':input').first().attr('name'); |
| 788 |
|
| 789 |
prefix = prefix.endsWith('[]') ? prefix.slice(0, -2) : prefix; |
| 790 |
prefix = prefix.substring(0, prefix.lastIndexOf('[')); |
| 791 |
label = label.replace(/\${(.*?)}/g, (match, name) => { |
| 792 |
let $field = this.find('[name="'+prefix+'['+name+']"]'); |
| 793 |
|
| 794 |
return $field.is('select') ? $field.find('option:selected').text().trim() : $field.val(); |
| 795 |
}); |
| 796 |
|
| 797 |
$('<span class="tag-label">'+label+'</span>').append(this.find('.del-item').clone()).prependTo(this).on('dblclick', (e)=>$(e.target).remove()); |
| 798 |
} |
| 799 |
}else if(action == 'template'){ |
| 800 |
return this.find('template').replaceWith((_, html) => html.replace(/\$\{i\}/g, $mu.data('i', ($mu.data('i') || 0)+ 1).data('i'))).end(); |
| 801 |
} |
| 802 |
|
| 803 |
if(e){ |
| 804 |
return; |
| 805 |
} |
| 806 |
|
| 807 |
$mu.children().addClass('mu-item'); |
| 808 |
|
| 809 |
if(type == 'fields'){ |
| 810 |
$mu.children().not(':last-child').wpjam_each($el => $el.wpjam_mu('template').wpjam_init()); |
| 811 |
}else{ |
| 812 |
_.each($mu.data('value'), v => $mu.wpjam_mu('add_item', v)); |
| 813 |
} |
| 814 |
|
| 815 |
let sortable = $mu.removeAttr('data-value').is('.sortable') && !$mu.closest('.disabled, .readonly')[0]; |
| 816 |
|
| 817 |
if(type == 'text' && $mu.find('input.tag-input')[0]){ |
| 818 |
$mu.attr('data-validation', true).on('validate.wpjam', ()=> $mu.find('input:visible').val('')); |
| 819 |
}else{ |
| 820 |
let dir = $mu.data('direction') || (type == 'img' || $mu.data('tag_label') ? 'row' : 'column'); |
| 821 |
let row = dir == 'row'; |
| 822 |
|
| 823 |
$mu.addClass('direction-'+dir).find('> .mu-item').wpjam_each($el => $el.append([ |
| 824 |
$el.is(':last-child') && '<a class="new-item button">'+(type == 'img' ? '' : $mu.data('button_text'))+'</a>', |
| 825 |
'<a class="del-item '+(row ? 'dashicons dashicons-no-alt' : 'button')+'"></a>', |
| 826 |
sortable && type != 'img' && '<span class="move-item dashicons dashicons-menu"></span>', |
| 827 |
])); |
| 828 |
|
| 829 |
['text', 'fields'].includes(type) && row && $mu.wpjam_mu('rest') > 0 && $mu.wpjam_mu('add_item', ''); |
| 830 |
} |
| 831 |
|
| 832 |
sortable && $mu.sortable({cursor: 'move', items: '.mu-item:not(:last-child)'}); |
| 833 |
|
| 834 |
return this; |
| 835 |
}; |
| 836 |
|
| 837 |
$.fn.wpjam_mu.selector = '.mu'; |
| 838 |
$.fn.wpjam_mu.events = [ |
| 839 |
{name: 'autocompleteselect', selector: '.mu-text input', action: 'new_item'}, |
| 840 |
{name: 'click', selector: '.mu .new-item', action: 'new_item'}, |
| 841 |
{name: 'click', selector: '.mu .del-item', action: 'del_item'}, |
| 842 |
{name: 'keydown', selector: '.mu-text input, .mu-fields input, .mu-fields select'} |
| 843 |
]; |
| 844 |
|
| 845 |
$.fn.wpjam_validate = function(){ |
| 846 |
this[0].checkValidity() && this.find('[data-validation]').trigger('validate.wpjam'); |
| 847 |
|
| 848 |
if(!this[0].checkValidity()){ |
| 849 |
let $field = $(this.find('input:invalid')[0] || this.find(':invalid')[0]); |
| 850 |
let custom = $field.data('custom_validity'); |
| 851 |
|
| 852 |
custom && $field.one('input', ()=> $field[0].setCustomValidity(''))[0].setCustomValidity(custom); |
| 853 |
|
| 854 |
if(!$field.is(':visible')){ |
| 855 |
$field.closest('.tabs').wpjam_tabs('#'+$field.closest('.tab').attr('id')); |
| 856 |
$field.closest('[popover]')[0]?.showPopover(); |
| 857 |
} |
| 858 |
|
| 859 |
return this[0].reportValidity(); |
| 860 |
} |
| 861 |
|
| 862 |
return true; |
| 863 |
}; |
| 864 |
|
| 865 |
$.fn.wpjam_schema = function(key){ |
| 866 |
return (this.data('schema') || {})[key]; |
| 867 |
}; |
| 868 |
|
| 869 |
$.fn.wpjam_data = function(data){ |
| 870 |
_.each(data, (v, k)=> this.attr('data-'+k, _.isObject(v) ? JSON.stringify(v) : v)); |
| 871 |
|
| 872 |
return this; |
| 873 |
}; |
| 874 |
|
| 875 |
$.fn.wpjam_val = function(){ |
| 876 |
if(this.prop('disabled')){ |
| 877 |
return null; |
| 878 |
}else if(this.is('span')){ |
| 879 |
return this.data('value'); |
| 880 |
}else if(this.is('.mu-text')){ |
| 881 |
return this.find('input').toArray().map(el=> el.value).filter(v => v !== ''); |
| 882 |
}else if(this.is('.wpjam-choice')){ |
| 883 |
let val = this.find('input:checked').toArray().map(el => el.value); |
| 884 |
|
| 885 |
return this.find('input').is(':radio') ? (val.length ? val[0] : null) : val; |
| 886 |
}else if(this.is(':checkbox, :radio')){ |
| 887 |
let $field = this.wpjam_control(); |
| 888 |
|
| 889 |
return $field[0] !== this[0] ? $field.wpjam_val() : (this.is(':checked') ? this.val() : (this.is(':checkbox') ? 0 : null)); |
| 890 |
} |
| 891 |
|
| 892 |
return this.val(); |
| 893 |
}; |
| 894 |
|
| 895 |
$.fn.wpjam_timer = function(cancel){ |
| 896 |
let timer = this.data('timer'); |
| 897 |
|
| 898 |
if(cancel){ |
| 899 |
timer && timer.cancel(); |
| 900 |
|
| 901 |
return this.removeData('timer'); |
| 902 |
} |
| 903 |
|
| 904 |
if(timer){ |
| 905 |
return timer; |
| 906 |
} |
| 907 |
|
| 908 |
this.data('timer', _.debounce(()=> this.wpjam_timer(true), 2000)).data('timer')(); |
| 909 |
}; |
| 910 |
|
| 911 |
$.fn.wpjam_media = function(callback){ |
| 912 |
let {type, item_type, rest, button_text: btn} = this.data(); |
| 913 |
|
| 914 |
let mu = this.is('.mu'); |
| 915 |
type = type.substring(mu ? 3 : 0); |
| 916 |
|
| 917 |
if(this.hasClass('readonly')){ |
| 918 |
return; |
| 919 |
} |
| 920 |
|
| 921 |
let args = { |
| 922 |
...(wp.media.view.settings.post.id && {frame: 'post'}), |
| 923 |
id: 'uploader_'+this.prop('id'), |
| 924 |
multiple: mu, |
| 925 |
title: btn, |
| 926 |
library : {type : ['img', 'image'].includes(type) ? 'image' : item_type}, |
| 927 |
// button : {text: title} |
| 928 |
}; |
| 929 |
|
| 930 |
let frame = wp.media(args); |
| 931 |
|
| 932 |
frame.on('open', function(){ |
| 933 |
frame.$el.addClass('hide-menu'); |
| 934 |
|
| 935 |
mu && rest && frame.state().get('selection').on('update', function(){ |
| 936 |
if(this.length > rest){ |
| 937 |
this.reset(this.first(rest)); |
| 938 |
|
| 939 |
alert('最多可以选择'+rest+'个'); |
| 940 |
} |
| 941 |
}); |
| 942 |
}).on('insert select', function(){ |
| 943 |
frame.state().get('selection').map((attachment)=> { |
| 944 |
let data = attachment.toJSON(); |
| 945 |
let qs = $.param(_.pick(data, 'orientation', 'width', 'height')); |
| 946 |
let value = data.url+(qs ? '?'+qs : ''); |
| 947 |
|
| 948 |
callback && callback(type == 'img' ? {...data, value : item_type === 'url' ? value : data.id} : value); |
| 949 |
}); |
| 950 |
}).open(); |
| 951 |
}; |
| 952 |
|
| 953 |
$.fn.wpjam_lightbox = function(e){ |
| 954 |
$('dialog.wpjam-lightbox').remove(); |
| 955 |
|
| 956 |
let src = this.data('preview') || this.attr('href'); |
| 957 |
let rel = this.attr('rel'); |
| 958 |
let $btn = $('<button type="button" class="dashicons dashicons-no-alt del-icon"></button>'); |
| 959 |
let $modal = $('<dialog class="wpjam-lightbox"></dialog>').append([$btn.one('click', ()=> $modal.remove()), $('<img src="'+src+'">')]).appendTo($('body')); |
| 960 |
|
| 961 |
$modal[0].showModal(); |
| 962 |
|
| 963 |
let images = rel ? $(`[rel="${rel}"]`).toArray().map(el => $(el).data('preview') || el.href) : []; |
| 964 |
let length = images.length; |
| 965 |
|
| 966 |
if(length > 1){ |
| 967 |
let index = images.indexOf(src); |
| 968 |
|
| 969 |
$modal.wrapInner('<div>').prepend('<a rel="'+rel+'" data-preview="'+images.at(index - 1)+'" class="dashicons dashicons-arrow-left-alt2"></a>').append('<a rel="'+rel+'" data-preview="'+images.at((index + 1) % length)+'" class="dashicons dashicons-arrow-right-alt2"></a>') |
| 970 |
} |
| 971 |
|
| 972 |
return e ? false : this; |
| 973 |
} |
| 974 |
|
| 975 |
$.fn.wpjam_lightbox.events = [{name: 'click', selector: '[data-preview], a.lightbox'}]; |
| 976 |
|
| 977 |
$.fn.wpjam_tooltip = function(e){ |
| 978 |
let action = e?.type; |
| 979 |
let $tip = $('div.wpjam-tooltip'); |
| 980 |
|
| 981 |
if(action === 'mouseenter'){ |
| 982 |
($tip[0] ? $tip : $('<div popover="manual" class="wpjam-tooltip"></div>')).stop(true).fadeIn(100).html(this.is('.preview') ? '<img src="'+this.find('img:visible').attr('src')+'" />' : (this.data('description') || this.data('tooltip'))).appendTo(this)[0].showPopover(); |
| 983 |
}else if(action === 'mouseleave'){ |
| 984 |
$tip.fadeOut(300); |
| 985 |
}else{ |
| 986 |
this.is('[data-description]') && this.addClass('dashicons dashicons-editor-help'); |
| 987 |
} |
| 988 |
|
| 989 |
return this; |
| 990 |
}; |
| 991 |
|
| 992 |
$.fn.wpjam_tooltip.selector = '[data-tooltip], [data-description], .image-radio.preview'; |
| 993 |
$.fn.wpjam_tooltip.events = [{name: 'mouseenter'}, {name: 'mouseleave'}]; |
| 994 |
|
| 995 |
$.fn.wpjam_modal = function(e){ |
| 996 |
if(this.hasClass('notice-dismiss')){ |
| 997 |
return this.prev('.delete-notice').trigger('click'); |
| 998 |
} |
| 999 |
|
| 1000 |
let $modal = e ? $('#'+this.data('modal_id')) : this; |
| 1001 |
let $dialog = wpjam.dialog($modal.html(), $modal.data('title'), $modal.data('width')); |
| 1002 |
|
| 1003 |
e || $dialog.one('wpjam:dialog:closed', ()=> this.find('.delete-notice').trigger('click').end().remove()); |
| 1004 |
|
| 1005 |
return e ? false : this; |
| 1006 |
} |
| 1007 |
|
| 1008 |
$.fn.wpjam_modal.selector = '.notice-modal:first'; |
| 1009 |
$.fn.wpjam_modal.events = [{name: 'click', selector: '.show-modal, .is-dismissible .notice-dismiss'}]; |
| 1010 |
|
| 1011 |
$.fn.wpjam_chart = function(){ |
| 1012 |
let chart = this.data('chart'); |
| 1013 |
let {type, options} = _.isObject(chart) ? chart : {}; |
| 1014 |
|
| 1015 |
if(type && !_.isEmpty(options)){ |
| 1016 |
type == 'Donut' && this.height(Math.max(160, Math.min(240, this.next('table').height() || 240))).width(this.height()); |
| 1017 |
|
| 1018 |
['Line', 'Bar', 'Donut'].includes(type) && Morris[type]({...options, element: this.prop('id')}); |
| 1019 |
|
| 1020 |
this.removeAttr('data-chart'); |
| 1021 |
} |
| 1022 |
} |
| 1023 |
|
| 1024 |
$.fn.wpjam_chart.selector = '[data-chart]'; |
| 1025 |
|
| 1026 |
$.fn.wpjam_tabs = function(hash){ |
| 1027 |
hash = window.location.hash = hash || window.location.hash; |
| 1028 |
|
| 1029 |
this.find('.tab').hide().filter(hash || ':first').show(); |
| 1030 |
this.find('.nav-tab').removeClass('nav-tab-active').filter(hash ? '[href="'+hash+'"]' : ':first').addClass('nav-tab-active'); |
| 1031 |
}; |
| 1032 |
|
| 1033 |
$.fn.wpjam_place = function(content, replace, placement){ |
| 1034 |
let $content = $(content); |
| 1035 |
|
| 1036 |
this[{before: 'prevAll', after: 'nextAll'}[placement] || 'find'](replace).remove(); |
| 1037 |
this[placement || 'append']($content); |
| 1038 |
|
| 1039 |
return $content; |
| 1040 |
}; |
| 1041 |
|
| 1042 |
$.fn.wpjam_scroll = function(){ |
| 1043 |
let $modal = this.closest('dialog .content'); |
| 1044 |
|
| 1045 |
if($modal[0]){ |
| 1046 |
$modal.animate({scrollTop: this[0].offsetTop - 80}, 300); |
| 1047 |
}else if(this[0]){ |
| 1048 |
let top = this.offset().top; |
| 1049 |
let dis = $(window).height() * 0.4; |
| 1050 |
|
| 1051 |
(Math.abs(top - $(window).scrollTop()) > dis) && $('html, body').animate({scrollTop: top - dis}, 300); |
| 1052 |
} |
| 1053 |
|
| 1054 |
return this; |
| 1055 |
}; |
| 1056 |
|
| 1057 |
window.wpjam = { |
| 1058 |
...wpjam_page_setting, |
| 1059 |
spinner: '<span class="spinner is-active"></span>', |
| 1060 |
|
| 1061 |
init: function(){ |
| 1062 |
$.ajax = this.enhance($.ajax, (options) => { |
| 1063 |
let type = typeof options.data; |
| 1064 |
let data = type == 'string' ? this.parse_params(options.data) : (type == 'object' ? options.data : {}); |
| 1065 |
|
| 1066 |
if(data.action){ |
| 1067 |
if(data.action.startsWith('wpjam-')){ |
| 1068 |
data = this.with_page(data); |
| 1069 |
}else if(['fetch-list', 'inline-save-tax', 'get-comments', 'replyto-comment'].includes(data.action)){ |
| 1070 |
data.screen_id = this.screen_id; |
| 1071 |
options.data = type == 'string' ? $.param(data) : data; |
| 1072 |
} |
| 1073 |
} |
| 1074 |
}, 'before'); |
| 1075 |
|
| 1076 |
this.params = this.parse_params(window.location.search, true); |
| 1077 |
|
| 1078 |
this.page_title_action && $('.wp-heading-inline:visible').last().wpjam_place(this.page_title_action, 'a.page-title-action', 'after'); |
| 1079 |
|
| 1080 |
$('a[href*="/wp-admin/page="]').attr('href', (_, v)=> v.replace('/wp-admin/page=', 'admin/admin.php?page=')); |
| 1081 |
|
| 1082 |
_.each(this.query_url, pair => $('a[href="'+pair[0]+'"]').attr('href', pair[1])); |
| 1083 |
|
| 1084 |
$('body').on('click', 'input[type=submit]', e => $(document.activeElement).attr('id') || $(e.target).focus()); |
| 1085 |
|
| 1086 |
$(window).on('popstate', e => e.originalEvent.state?.params && this.load(e.originalEvent.state.params)); |
| 1087 |
$(window).on('hashchange load', ()=> $('.tabs').wpjam_each($el => $el.wpjam_tabs())); |
| 1088 |
|
| 1089 |
$(document).on('heartbeat-send', (e, data)=> this.query_data && $.extend(data, this.query_data)); |
| 1090 |
$(document).on('widget-updated', (e, widget)=> widget.wpjam_init()); |
| 1091 |
$(document).on('mousemove', (e)=> $('html').css({ |
| 1092 |
'--wpjam-left': (e.clientX+(e.clientX + 300 > window.innerWidth ? -305 : 5))+'px', |
| 1093 |
'--wpjam-top': (e.clientY+(e.clientY + 220 > window.innerHeight ? -225 : 5))+'px' |
| 1094 |
})); |
| 1095 |
|
| 1096 |
this.load(); |
| 1097 |
|
| 1098 |
$('body').wpjam_init(); |
| 1099 |
}, |
| 1100 |
|
| 1101 |
load: function(params){ |
| 1102 |
if(params){ |
| 1103 |
this.dialog('close'); |
| 1104 |
this.params = params; |
| 1105 |
} |
| 1106 |
|
| 1107 |
let args = {...this.params, action_type: 'form'}; |
| 1108 |
|
| 1109 |
if(list_table){ |
| 1110 |
if(!params){ |
| 1111 |
list_table.load(); |
| 1112 |
} |
| 1113 |
|
| 1114 |
if(args.list_action){ |
| 1115 |
return list_table.action(args); |
| 1116 |
} |
| 1117 |
|
| 1118 |
if(params){ |
| 1119 |
return list_table.query(params); |
| 1120 |
} |
| 1121 |
} |
| 1122 |
|
| 1123 |
if(args.page_action){ |
| 1124 |
return this.action('page', args); |
| 1125 |
} |
| 1126 |
|
| 1127 |
this.plugin_page && this.state('replace'); |
| 1128 |
}, |
| 1129 |
|
| 1130 |
state: function(action='push'){ |
| 1131 |
let url = new URL(this.admin_url); |
| 1132 |
|
| 1133 |
if(!_.isEmpty(this.params) || this.query_data){ |
| 1134 |
url.search = '?'+$.param(_.extend( |
| 1135 |
this.parse_params(url.search), |
| 1136 |
this.query_data, |
| 1137 |
_.omit(this.params, (v, k)=> v == null || (k == 'paged' && v <= 1)) |
| 1138 |
)); |
| 1139 |
} |
| 1140 |
|
| 1141 |
url = url.toString()+(window.location.hash || ''); |
| 1142 |
|
| 1143 |
$('input[name="_wp_http_referer"]').val(url); |
| 1144 |
|
| 1145 |
if(action != 'push' || window.location.href != url){ |
| 1146 |
window.history[(action == 'push' ? 'pushState' : 'replaceState')]({params: this.params}, null, url); |
| 1147 |
} |
| 1148 |
}, |
| 1149 |
|
| 1150 |
notice: function(notice, type){ |
| 1151 |
if(_.isObject(notice)){ |
| 1152 |
type = notice.type; |
| 1153 |
notice = notice.message; |
| 1154 |
} |
| 1155 |
|
| 1156 |
if(notice){ |
| 1157 |
let $dialog = this.dialog(); |
| 1158 |
let [$el, act] = $dialog[0] ? [$dialog.find('.content'), 'prepend'] : [$('.wp-header-end').last(), 'before']; |
| 1159 |
|
| 1160 |
$el.wpjam_place('<div class="notice notice-'+(type || 'success')+' is-replaceable is-dismissible"><p><strong>'+notice+'</strong></p></div>', '.notice.is-replaceable', act).wpjam_scroll(); |
| 1161 |
|
| 1162 |
$(document).trigger('wp-notice-added'); |
| 1163 |
} |
| 1164 |
}, |
| 1165 |
|
| 1166 |
dialog: function(...args){ |
| 1167 |
let id = 'wpjam_dialog'; |
| 1168 |
|
| 1169 |
if(!args.length){ |
| 1170 |
return $('#'+id+'[open]'); |
| 1171 |
} |
| 1172 |
|
| 1173 |
let $dialog = $('#'+id); |
| 1174 |
|
| 1175 |
if(args[0] === 'close'){ |
| 1176 |
return $dialog[0]?.close(); |
| 1177 |
} |
| 1178 |
|
| 1179 |
if(args[0] === 'show'){ |
| 1180 |
if($dialog[0] && !$dialog[0].open){ |
| 1181 |
$dialog[0].returnValue = ''; |
| 1182 |
$dialog[0].showModal(); |
| 1183 |
} |
| 1184 |
|
| 1185 |
return; |
| 1186 |
} |
| 1187 |
|
| 1188 |
let [data, ...rest] = args; |
| 1189 |
|
| 1190 |
data = _.isObject(data) ? data : {..._.object(['page_title', 'width'], rest), data}; |
| 1191 |
|
| 1192 |
if(!$dialog[0]){ |
| 1193 |
$dialog = $('<dialog id="'+id+'" class="wpjam-dialog"><div class="title"><h2></h2><button type="button" commandfor="'+id+'" command="close"></button></div><div class="content"></div></dialog>').appendTo('body'); |
| 1194 |
|
| 1195 |
this.dialog.observer = new MutationObserver(()=> $('body').hasClass('modal-open') ? $dialog[0].close('temp') : this.dialog('show')); |
| 1196 |
|
| 1197 |
this.dialog.observe = ()=> this.dialog.observer.observe(document.body, {attributes: true, attributeFilter: ['class']}); |
| 1198 |
|
| 1199 |
$dialog.on('close', ()=> { |
| 1200 |
if($dialog[0].returnValue != 'temp'){ |
| 1201 |
this.dialog.observer.disconnect(); |
| 1202 |
|
| 1203 |
$dialog.trigger('wpjam:dialog:closed'); |
| 1204 |
} |
| 1205 |
}).on('click', 'button[command="close"]', ()=> $dialog[0].close()); |
| 1206 |
} |
| 1207 |
|
| 1208 |
$dialog.css('width', (data.width || 700)+'px').find('h2').text(data.page_title || '').end().find('.content').html(data.form || data.data || ''); |
| 1209 |
|
| 1210 |
$dialog[0].showModal(); |
| 1211 |
this.dialog.observe(); |
| 1212 |
|
| 1213 |
$dialog.trigger('wpjam:dialog:opened'); |
| 1214 |
|
| 1215 |
return $dialog; |
| 1216 |
}, |
| 1217 |
|
| 1218 |
post: function(args){ |
| 1219 |
return $.ajax({ |
| 1220 |
url: ajaxurl, |
| 1221 |
method: 'POST', |
| 1222 |
data: args, |
| 1223 |
dataType: 'json', |
| 1224 |
headers: {'Accept': 'application/json'}, |
| 1225 |
error: function(xhr, status, error){} |
| 1226 |
}); |
| 1227 |
}, |
| 1228 |
|
| 1229 |
action: Object.assign(function(type, args){ |
| 1230 |
let action = this.action[type]; |
| 1231 |
|
| 1232 |
if(action?.before?.(args) === false){ |
| 1233 |
return false; |
| 1234 |
} |
| 1235 |
|
| 1236 |
if(args.state){ |
| 1237 |
_.extend(this.params, _.pick(args, args.state)); |
| 1238 |
|
| 1239 |
$('body').one('wpjam:dialog:closed', ()=> { |
| 1240 |
this.params = _.omit(this.params, args.state); |
| 1241 |
this.state(); |
| 1242 |
}); |
| 1243 |
} |
| 1244 |
|
| 1245 |
args.$ae && args.$ae.prop('disabled', true); |
| 1246 |
|
| 1247 |
$('.spinner.is-active')[0] || $('<div class="wpjam-loading"><img src="'+this.loading+'" /></div>').appendTo('body').show(); |
| 1248 |
|
| 1249 |
return this.post({..._.omit(args, ['$ae', 'state']), action: 'wpjam-'+type+'-action'}).then(data => { |
| 1250 |
args.$ae && args.$ae.prop('disabled', false); |
| 1251 |
|
| 1252 |
$('.spinner.is-active, .wpjam-loading').remove(); |
| 1253 |
|
| 1254 |
if(data.errcode){ |
| 1255 |
this.notice((args.page_title ? args.page_title+'失败:' : '')+(data.errmsg || ''), 'error'); |
| 1256 |
}else{ |
| 1257 |
data.params && _.extend(this.params, data.params); |
| 1258 |
|
| 1259 |
let $dialog = this.dialog(); |
| 1260 |
let dismiss = $dialog[0] && data.dismiss; |
| 1261 |
|
| 1262 |
if(data.type == 'form'){ |
| 1263 |
!data.form && !data.data && alert('服务端未返回表单数据'); |
| 1264 |
|
| 1265 |
this.dialog(data); |
| 1266 |
}else if(data.type == 'append'){ |
| 1267 |
if(!$dialog[0] && data.list_action){ |
| 1268 |
this.dialog(data); |
| 1269 |
}else{ |
| 1270 |
($dialog[0] ? $dialog.find('.content') : $('div.wrap')).wpjam_place($('<div class="card wrap-text">'+data.data+'</div>'), '.response.card').hide().fadeIn(400).wpjam_scroll(); |
| 1271 |
} |
| 1272 |
}else if(data.type == 'redirect'){ |
| 1273 |
$('body').one(dismiss ? 'wpjam:dialog:closed' : type+'_action_success', ()=> { |
| 1274 |
let url = data.url ? data.url.replace('admin/page=', 'admin/admin.php?page=') : (_.isObject(data.args) ? wpjam.admin_url+(wpjam.admin_url.includes('?') ? '&' : '?')+$.param(data.args) : null); |
| 1275 |
url ? window.open(url, data.target) : window.location.reload(); |
| 1276 |
}); |
| 1277 |
} |
| 1278 |
|
| 1279 |
action?.response?.(data, args); |
| 1280 |
|
| 1281 |
dismiss && $dialog[0].close(); |
| 1282 |
|
| 1283 |
this.state(); |
| 1284 |
|
| 1285 |
$('body').wpjam_init().trigger(type+'_action_success', data); |
| 1286 |
} |
| 1287 |
}); |
| 1288 |
}, { |
| 1289 |
page: { |
| 1290 |
before: function(args){ |
| 1291 |
if(args.action_type == 'form'){ |
| 1292 |
args.state = ['page_action', 'data']; |
| 1293 |
} |
| 1294 |
}, |
| 1295 |
|
| 1296 |
response: function(data, args){ |
| 1297 |
if(!['form', 'append', 'redirect'].includes(data.type)){ |
| 1298 |
data.args && setTimeout(()=> wpjam.action('page', {...args, data: data.args}), 400); |
| 1299 |
|
| 1300 |
args.action_type == 'submit' && data.form && $('#wpjam_form').html(data.form); |
| 1301 |
|
| 1302 |
wpjam.notice(data.notice || args.page_title+'成功'); |
| 1303 |
} |
| 1304 |
|
| 1305 |
data.page_action = args.page_action; |
| 1306 |
data.action_type = data.page_action_type = args.action_type; |
| 1307 |
} |
| 1308 |
}, |
| 1309 |
|
| 1310 |
option: { |
| 1311 |
response: function(data){ |
| 1312 |
data.type == 'save' && wpjam.notice(data.notice); |
| 1313 |
} |
| 1314 |
} |
| 1315 |
}), |
| 1316 |
|
| 1317 |
with_page: function(args){ |
| 1318 |
let left_key = args.action_type != 'query_items' && this.left_key; |
| 1319 |
|
| 1320 |
if(this.query_data || left_key){ |
| 1321 |
let type = args.data ? typeof args.data : 'string'; |
| 1322 |
let data = type == 'object' ? args.data : (args.data ? this.parse_params(args.data) : {}); |
| 1323 |
|
| 1324 |
_.each(this.query_data, (v, k)=> { |
| 1325 |
if(_.has(data, k)){ |
| 1326 |
this.query_data[k] = data[k]; |
| 1327 |
}else{ |
| 1328 |
data[k] = v; |
| 1329 |
} |
| 1330 |
}); |
| 1331 |
|
| 1332 |
if(left_key){ |
| 1333 |
data[left_key] = wpjam.params[left_key]; |
| 1334 |
} |
| 1335 |
|
| 1336 |
if(type == 'string'){ |
| 1337 |
args.data = $.param(data); |
| 1338 |
} |
| 1339 |
} |
| 1340 |
|
| 1341 |
return _.extend(args, _.pick(this, ['screen_id', 'plugin_page', 'current_tab', 'builtin_page', 'post_type', 'taxonomy'])); |
| 1342 |
}, |
| 1343 |
|
| 1344 |
parse_params: function(params, clean){ |
| 1345 |
if(_.isString(params)){ |
| 1346 |
let obj = {}; |
| 1347 |
params = params ? params.replace(/^\?|\+/g, ' ').trim() : ''; |
| 1348 |
|
| 1349 |
params && params.replace(/^\?|\+/g, ' ').trim().split('&').forEach(v => { |
| 1350 |
let param = v.split('='); |
| 1351 |
let key = decodeURIComponent(param[0]); |
| 1352 |
let val = param.length === 2 ? decodeURIComponent(param[1]) : ''; |
| 1353 |
let keys = key.split(']['); |
| 1354 |
|
| 1355 |
if(keys[0].includes('[') && _.last(keys).endsWith(']')){ |
| 1356 |
keys = keys.shift().split('[').concat(keys); |
| 1357 |
keys = [...keys.slice(0, -1), keys.pop().slice(0, -1)]; |
| 1358 |
|
| 1359 |
keys.reduce((cur, k, i)=> { |
| 1360 |
k = (k === '') ? cur.length : k; |
| 1361 |
cur[k] = keys.length - 1 > i ? (cur[k] || (isNaN(Number(keys[i + 1])) ? {} : [])) : val; |
| 1362 |
|
| 1363 |
return cur[k]; |
| 1364 |
}, obj); |
| 1365 |
}else{ |
| 1366 |
obj[key] = val; |
| 1367 |
} |
| 1368 |
}); |
| 1369 |
|
| 1370 |
params = obj; |
| 1371 |
} |
| 1372 |
|
| 1373 |
return clean ? _.omit(params, _.union( |
| 1374 |
['_wp_http_referer', '_wpnonce', 'action', 'action2'], |
| 1375 |
this.query_data ? Object.keys(this.query_data) : [], |
| 1376 |
this.builtin_page ? ['post_type', 'taxonomy'] : ['page', 'tab'] |
| 1377 |
)) : params; |
| 1378 |
}, |
| 1379 |
|
| 1380 |
compare: function(a, compare, b){ |
| 1381 |
let cmp = compare; |
| 1382 |
|
| 1383 |
if(_.isObject(compare)){ |
| 1384 |
b = compare.value; |
| 1385 |
cmp = compare.compare; |
| 1386 |
} |
| 1387 |
|
| 1388 |
if(_.isArray(a) || (_.isObject(compare) && compare.swap)){ |
| 1389 |
[a, b] = [b, a]; |
| 1390 |
} |
| 1391 |
|
| 1392 |
if(cmp){ |
| 1393 |
cmp = cmp.toUpperCase(); |
| 1394 |
|
| 1395 |
let antonym = { |
| 1396 |
'!=': '=', |
| 1397 |
'<=': '>', |
| 1398 |
'>=': '<', |
| 1399 |
'NOT IN': 'IN', |
| 1400 |
'NOT BETWEEN': 'BETWEEN' |
| 1401 |
}[cmp]; |
| 1402 |
|
| 1403 |
if(antonym){ |
| 1404 |
return !wpjam.compare(a, antonym, b); |
| 1405 |
} |
| 1406 |
}else{ |
| 1407 |
cmp = _.isArray(b) ? 'IN' : '='; |
| 1408 |
} |
| 1409 |
|
| 1410 |
if(cmp === 'IN' || cmp === 'BETWEEN'){ |
| 1411 |
b = _.isArray(b) ? b : b.split(/[\s,]+/); |
| 1412 |
|
| 1413 |
if(!_.isArray(a) && b.length === 1) { |
| 1414 |
return a == b[0]; |
| 1415 |
} |
| 1416 |
|
| 1417 |
b = b.map(String); |
| 1418 |
}else{ |
| 1419 |
b = _.isString(b) ? b.trim() : b; |
| 1420 |
} |
| 1421 |
|
| 1422 |
switch (cmp) { |
| 1423 |
case '=': return a == b; |
| 1424 |
case '>': return a > b; |
| 1425 |
case '<': return a < b; |
| 1426 |
case 'IN': return b.includes(a); |
| 1427 |
case 'BETWEEN': return a >= b[0] && a <= b[1]; |
| 1428 |
default: return false; |
| 1429 |
} |
| 1430 |
}, |
| 1431 |
|
| 1432 |
enhance: function(func, callback, when){ |
| 1433 |
return function(...args){ |
| 1434 |
when == 'before' && callback.apply(this, args); |
| 1435 |
|
| 1436 |
let result = func.call(this, ...args); |
| 1437 |
|
| 1438 |
when != 'before' && callback.apply(this, args); |
| 1439 |
|
| 1440 |
return result; |
| 1441 |
}; |
| 1442 |
}, |
| 1443 |
|
| 1444 |
delegate: function(selector, sub){ |
| 1445 |
let $sel = $(selector); |
| 1446 |
|
| 1447 |
_.each($._data($sel.get(0), 'events'), (list, type)=> { |
| 1448 |
_.each(list, (event)=> { |
| 1449 |
let sel = event?.selector; |
| 1450 |
|
| 1451 |
if(event?.handler && (!sel || !sub || sel == sub)){ |
| 1452 |
$('body').on(type, sel ? selector+' '+sel : selector, event.handler); |
| 1453 |
$sel.off(type, sel || event.handler, sel && event.handler); |
| 1454 |
} |
| 1455 |
}); |
| 1456 |
}); |
| 1457 |
} |
| 1458 |
}; |
| 1459 |
|
| 1460 |
window.list_table = wpjam.list_table && { |
| 1461 |
...wpjam.list_table, |
| 1462 |
$form: $('form:has(.wp-list-table)').attr('novalidate', 'novalidate'), |
| 1463 |
|
| 1464 |
load: function(data){ |
| 1465 |
data && data.setting && _.extend(list_table, data.setting); |
| 1466 |
|
| 1467 |
this.table(data); |
| 1468 |
this.views(data); |
| 1469 |
this.left(data); |
| 1470 |
|
| 1471 |
$('input[name="post_status"]').val(wpjam.params.post_status || 'all'); |
| 1472 |
|
| 1473 |
let $end = $('.wp-header-end').last(); |
| 1474 |
|
| 1475 |
this.subtitle && $end.wpjam_place('<span class="subtitle">'+this.subtitle+'</span>', 'span.subtitle', 'before'); |
| 1476 |
this.summary && $end.wpjam_place('<div class="summary">'+this.summary+'</div>', 'div.summary', 'after'); |
| 1477 |
|
| 1478 |
if(this.search){ |
| 1479 |
if(this.search.box){ |
| 1480 |
$('#list_table_form').wpjam_place(this.search.box, 'p.search-box', 'prepend'); |
| 1481 |
}else{ |
| 1482 |
$('p.search-box input[type="search"]').val(this.search.term); |
| 1483 |
} |
| 1484 |
|
| 1485 |
this.search.columns && $('p.search-box').wpjam_place(this.search.columns, '#search_columns', 'prepend'); |
| 1486 |
} |
| 1487 |
|
| 1488 |
if(wpjam.params.id && !wpjam.params.list_action && !wpjam.params.action){ |
| 1489 |
let id = wpjam.params.id; |
| 1490 |
|
| 1491 |
delete wpjam.params.id; |
| 1492 |
|
| 1493 |
this.get_row(id)[0] ? this.update_row(id) : this.query({id: id}); |
| 1494 |
} |
| 1495 |
|
| 1496 |
data ? $('body').trigger('list_table_load', data) : $(window).on('load', ()=> $('body').trigger('list_table_load', data)); |
| 1497 |
}, |
| 1498 |
|
| 1499 |
table: function(data){ |
| 1500 |
let $form = this.$form.attr('data-layout', this.layout).addClass('layout-'+this.layout); |
| 1501 |
|
| 1502 |
if(!data){ |
| 1503 |
_.each([ |
| 1504 |
['submit'], |
| 1505 |
['keydown', '.tablenav :input, .search-box :input'], |
| 1506 |
['change', '.tablenav [type="date"]'], |
| 1507 |
['click', '.list-table-filter, td a, th a, .pagination-links a, .prev-day, .next-day'] |
| 1508 |
], ([name, sel])=> $form.wpjam_on(name, sel, e => this.callback(e))); |
| 1509 |
|
| 1510 |
wpjam.action['list-table'] = this; |
| 1511 |
} |
| 1512 |
|
| 1513 |
if(data && (data.table || data.tablenav)){ |
| 1514 |
$form.find('input[name="_wpnonce"], input[name="_wp_http_referer"]').remove(); |
| 1515 |
|
| 1516 |
if(data.table){ |
| 1517 |
$form.wpjam_place(data.table, 'table, div.tablenav'); |
| 1518 |
}else{ |
| 1519 |
_.each(['top', 'bottom'], key => $form.find('div.tablenav.'+key).replaceWith(data.tablenav[key])); |
| 1520 |
} |
| 1521 |
} |
| 1522 |
|
| 1523 |
if(!data || data.table){ |
| 1524 |
let $table = $form.find('table.wp-list-table'); |
| 1525 |
let columns = {}; |
| 1526 |
this.$tbody = this.$form.find('#the-list'); |
| 1527 |
this.name = (this.$tbody.data('wp-lists') || ':post').split(':')[1]; |
| 1528 |
|
| 1529 |
$table.find('thead th i').wpjam_each($i => { |
| 1530 |
let $th = $i.closest('th'); |
| 1531 |
let col = 'column-'+$th.attr('id'); |
| 1532 |
let data = $i.appendTo($th).data(); |
| 1533 |
|
| 1534 |
data.nowrap && $('.'+col).addClass('nowrap'); |
| 1535 |
|
| 1536 |
columns[col] = {...data, left: $th.prevAll().toArray().reduce((sum, el) => sum += $(el).outerWidth(), 0)}; |
| 1537 |
}); |
| 1538 |
|
| 1539 |
sticky = _.some(columns, data => data.sticky); |
| 1540 |
|
| 1541 |
sticky && ($table.width() > $form.width()) && $table.addClass('sticky-columns'); |
| 1542 |
|
| 1543 |
this.columns = {...columns, 'check-column' : {check:true, sticky, left: 0}}; |
| 1544 |
|
| 1545 |
this.render($table); |
| 1546 |
} |
| 1547 |
|
| 1548 |
if(!data || data.table || data.tablenav){ |
| 1549 |
$form.removeData('initialized').wpjam_place($('<div class="actions overallactions"></div>').append(this.overall_actions), '.overallactions').insertBefore($('.tablenav.top').find('div.tablenav-pages, br.clear').first()); |
| 1550 |
|
| 1551 |
$form.find('.current-page').addClass('expandable').removeAttr('size').attr({type: 'number', min: 1, max: parseInt($form.find('span.total-pages').first().text())}); |
| 1552 |
} |
| 1553 |
}, |
| 1554 |
|
| 1555 |
views: function(data){ |
| 1556 |
let $views = $('ul.subsubsub'); |
| 1557 |
|
| 1558 |
if(data){ |
| 1559 |
if(!data.views){ |
| 1560 |
return; |
| 1561 |
} |
| 1562 |
|
| 1563 |
$views.empty().append($(data.views).html()); |
| 1564 |
|
| 1565 |
data.type != 'list' && $views.find('a').removeClass('current').end().find('li.'+this.view+' a').addClass('current'); |
| 1566 |
}else{ |
| 1567 |
$views.wpjam_on('click', 'a', e => this.callback(e)); |
| 1568 |
} |
| 1569 |
|
| 1570 |
this.view = $views.find('li:has(a.current)').attr('class'); |
| 1571 |
}, |
| 1572 |
|
| 1573 |
left: function(data){ |
| 1574 |
let $left = $('#col-left form').prop('novalidate', true); |
| 1575 |
let $paged = $left.find('input.current-page'); |
| 1576 |
|
| 1577 |
if(!$left[0]){ |
| 1578 |
return; |
| 1579 |
} |
| 1580 |
|
| 1581 |
if(data && data.currentTarget){ |
| 1582 |
let $el = $(data.currentTarget); |
| 1583 |
|
| 1584 |
if($el.is('[data-id]')){ |
| 1585 |
$left.find('.left-current').removeClass('left-current'); |
| 1586 |
|
| 1587 |
this.query({...wpjam.params, [wpjam.left_key]: $el.addClass('left-current').data('id')}); |
| 1588 |
}else{ |
| 1589 |
$paged.val($el.is('select.left-filter') ? 1 : parseInt($paged.val())+($el.is('.prev-page') ? -1 : ($el.is('.next-page') ? +1 : 0))); |
| 1590 |
|
| 1591 |
if(!$left.wpjam_validate()){ |
| 1592 |
return false; |
| 1593 |
} |
| 1594 |
|
| 1595 |
this.query(wpjam.parse_params($left.serialize(), true)); |
| 1596 |
} |
| 1597 |
|
| 1598 |
return false; |
| 1599 |
} |
| 1600 |
|
| 1601 |
if(data){ |
| 1602 |
if(!data.left){ |
| 1603 |
return; |
| 1604 |
} |
| 1605 |
|
| 1606 |
$left.removeData('initialized').html(data.left); |
| 1607 |
}else{ |
| 1608 |
_.each([ |
| 1609 |
['submit'], |
| 1610 |
['change', 'select'], |
| 1611 |
['click', '.prev-page, .next-page, [data-id]'], |
| 1612 |
], ([name, sel])=> $left.wpjam_on(name, sel, e => this.left(e))); |
| 1613 |
} |
| 1614 |
|
| 1615 |
let $items = $left.find('[data-id]'); |
| 1616 |
let paged = parseInt($paged.addClass('expandable').val()); |
| 1617 |
let key = wpjam.left_key = this.left_key; |
| 1618 |
|
| 1619 |
$left.find('a.prev-page').addClass('button').addClass(paged <= 1 && 'disabled'); |
| 1620 |
$left.find('a.next-page').addClass('button').addClass(paged >= parseInt($paged.attr('max')) && 'disabled'); |
| 1621 |
|
| 1622 |
$items[0] && $left.find('[data-id='+(wpjam.params[key] = wpjam.params[key] || $items.first().data('id'))+']').addClass('left-current'); |
| 1623 |
|
| 1624 |
this.$form.find('.sticky-columns').css('--left-height', $('#col-left table').height()+'px'); |
| 1625 |
|
| 1626 |
$('a.page-title-action').clone().toggleClass('page-title-action button').prependTo($('div.overallactions')); |
| 1627 |
}, |
| 1628 |
|
| 1629 |
render: function($el){ |
| 1630 |
$el.is('td, th') || _.each(this.columns, (column, sel)=> { |
| 1631 |
let {sticky, left, nowrap, description, ...data} = column; |
| 1632 |
let $col = $('.'+sel); |
| 1633 |
|
| 1634 |
sticky && $col.addClass('sticky-column').css('left', left); |
| 1635 |
nowrap && $col.addClass('nowrap'); |
| 1636 |
|
| 1637 |
if(_.isEmpty(data)){ |
| 1638 |
return; |
| 1639 |
} |
| 1640 |
|
| 1641 |
$col.wpjam_each($td => { |
| 1642 |
if(data.check){ |
| 1643 |
let $input = $td.find('input'); |
| 1644 |
|
| 1645 |
return $input[0] ? $input.attr('title', '选择'+($td.nextAll('.column-primary')[0].childNodes[0].textContent.trim() || $input.val())) : ($td.find('span')[0] || $td.append('<span class="dashicons dashicons-minus"></span>')); |
| 1646 |
} |
| 1647 |
|
| 1648 |
let value = $td.text(); |
| 1649 |
let number = Number(value); |
| 1650 |
|
| 1651 |
if(value === '' || isNaN(number)){ |
| 1652 |
return; |
| 1653 |
} |
| 1654 |
|
| 1655 |
_.some(data.conditional_styles, rule => wpjam.compare(number, rule) && $td.css(_.reduce({ |
| 1656 |
bold: {'font-weight': 'bold'}, |
| 1657 |
strikethrough: {'text-decoration': 'line-through'}, |
| 1658 |
color: '', |
| 1659 |
'background-color': '' |
| 1660 |
}, (acc, prop, key)=> rule[key] ? {...acc, ...(prop || _.pick(rule, key))} : acc, {}))); |
| 1661 |
|
| 1662 |
let {format, precision} = data; |
| 1663 |
|
| 1664 |
if(format || precision){ |
| 1665 |
if(format == '%'){ |
| 1666 |
number = parseFloat((number*100).toFixed(precision || 2))+'%'; |
| 1667 |
}else{ |
| 1668 |
number = precision ? parseFloat(number.toFixed(precision)) : number; |
| 1669 |
number = format == ',' ? number.toLocaleString() : number; |
| 1670 |
} |
| 1671 |
|
| 1672 |
$td.text(number).attr('value', value); |
| 1673 |
} |
| 1674 |
}); |
| 1675 |
}); |
| 1676 |
|
| 1677 |
$el.find('.items.sortable').add($el.is('table') && this.sortable && this.$tbody).wpjam_each($s => { |
| 1678 |
let tbody = $s.is('tbody'); |
| 1679 |
let handle = '.list-table-move-'+(tbody ? '' : 'item-')+'action'; |
| 1680 |
|
| 1681 |
$s.sortable({ |
| 1682 |
...(tbody ? {items: this.sortable.items, axis: 'y'} : {items: '> div.item'}), |
| 1683 |
handle, |
| 1684 |
cursor: 'move', |
| 1685 |
start: (e, ui)=> { |
| 1686 |
tbody && ui.placeholder.css({ |
| 1687 |
visibility: 'visible', |
| 1688 |
height: ui.helper.outerHeight()+'px', |
| 1689 |
width: ui.helper.outerWidth()+'px' |
| 1690 |
}); |
| 1691 |
}, |
| 1692 |
update: (e, ui)=> { |
| 1693 |
let $handle = ui.item.find(handle); |
| 1694 |
let parts = [$handle.data('data'), 'pos='+ui.item.prevAll().length, $s.sortable('serialize')].filter(Boolean); |
| 1695 |
|
| 1696 |
$handle.data('data', parts.join('&')).wpjam_action(); |
| 1697 |
} |
| 1698 |
}); |
| 1699 |
}); |
| 1700 |
|
| 1701 |
return this; |
| 1702 |
}, |
| 1703 |
|
| 1704 |
update_row: function(data, highlight=true){ |
| 1705 |
let $el = data; |
| 1706 |
|
| 1707 |
if(!(data instanceof $)){ |
| 1708 |
if(this.layout == 'calendar'){ |
| 1709 |
_.each(data.data, (item, date)=> this.update_row($('td#date_'+date).html(item))); |
| 1710 |
|
| 1711 |
return this; |
| 1712 |
} |
| 1713 |
|
| 1714 |
if(_.isObject(data) && data.bulk){ |
| 1715 |
_.each(data.data || data.ids, item => this.update_row(item)); |
| 1716 |
|
| 1717 |
return this; |
| 1718 |
} |
| 1719 |
|
| 1720 |
let id = data; |
| 1721 |
|
| 1722 |
if(_.isObject(data)){ |
| 1723 |
id = data.id; |
| 1724 |
|
| 1725 |
data.data && this.get_row(id).first().before(data.data).end().remove(); |
| 1726 |
} |
| 1727 |
|
| 1728 |
$el = this.get_row(id); |
| 1729 |
} |
| 1730 |
|
| 1731 |
highlight && $el.wpjam_highlight('add'); |
| 1732 |
|
| 1733 |
return this.render($el); |
| 1734 |
}, |
| 1735 |
|
| 1736 |
delete_row: function(id){ |
| 1737 |
this.get_row(id).wpjam_highlight('delete').wpjam_remove(()=> this.$tbody.find('> tr')[0] || this.$tbody.append('<tr class="no-items"><td colspan="'+this.$form.find('tr').children().length+'" class="colspanchange">'+_wpMediaViewsL10n.noItemsFound+'</td></tr>')); |
| 1738 |
}, |
| 1739 |
|
| 1740 |
get_row: function(id){ |
| 1741 |
id = typeof id == "string" ? id.replace(/(:|\.|\[|\]|,|=|@)/g, "\\$1") : id; |
| 1742 |
|
| 1743 |
return $('.tr-'+id)[0] ? $('.tr-'+id) : $('#'+this.name+'-'+id); |
| 1744 |
}, |
| 1745 |
|
| 1746 |
action: function(args){ |
| 1747 |
return wpjam.action('list-table', args); |
| 1748 |
}, |
| 1749 |
|
| 1750 |
query: function(params){ |
| 1751 |
$('.notice-dismiss').trigger('click.wp-dismiss-notice'); |
| 1752 |
|
| 1753 |
if(!params && !this.$form.wpjam_validate()){ |
| 1754 |
return false; |
| 1755 |
} |
| 1756 |
|
| 1757 |
wpjam.params = params ? _.omit(params, v => _.isNull(v)) : wpjam.parse_params(this.$form.serialize(), true); |
| 1758 |
|
| 1759 |
return this.action({action_type: 'query_items', data: $.param(wpjam.params)}); |
| 1760 |
}, |
| 1761 |
|
| 1762 |
callback: function(e){ |
| 1763 |
let $el = $(e.currentTarget); |
| 1764 |
|
| 1765 |
if(e.type == 'click'){ |
| 1766 |
if($el.hasClass('list-table-action')){ |
| 1767 |
return; |
| 1768 |
} |
| 1769 |
|
| 1770 |
if($el.is('.prev-day, .next-day')){ |
| 1771 |
let $date = $el.siblings('[name="date"]'); |
| 1772 |
let date = new Date($date.val()); |
| 1773 |
|
| 1774 |
date.setDate(date.getDate()+($el.hasClass('prev-day') ? -1 : 1)); |
| 1775 |
$date.val(date.toISOString().split('T')[0]); |
| 1776 |
|
| 1777 |
return this.query(), false; |
| 1778 |
} |
| 1779 |
|
| 1780 |
if($el.hasClass('list-table-filter')){ |
| 1781 |
return this.query($el.data('filter')), false; |
| 1782 |
} |
| 1783 |
|
| 1784 |
if(this.ajax === false){ |
| 1785 |
return; |
| 1786 |
} |
| 1787 |
|
| 1788 |
if($el.closest('td, th')[0] && (wpjam.plugin_page || !$el.attr('href').startsWith($('#adminmenu a.current').attr('href')))){ |
| 1789 |
return; |
| 1790 |
} |
| 1791 |
|
| 1792 |
let params = wpjam.parse_params(new URL($el.prop('href')).search); |
| 1793 |
|
| 1794 |
if(wpjam.builtin_page && (params.page || params.action)){ |
| 1795 |
return; |
| 1796 |
} |
| 1797 |
|
| 1798 |
return this.query($el.is('th a, .pagination-links a') ? { |
| 1799 |
...wpjam.params, |
| 1800 |
..._.omit(params, 'page'), |
| 1801 |
paged: params.paged || 1 |
| 1802 |
} : params), false; |
| 1803 |
}else if(e.type == 'submit'){ |
| 1804 |
let $ae = $(document.activeElement); |
| 1805 |
|
| 1806 |
if($ae.is('#doaction, #doaction2')){ |
| 1807 |
let $select = $ae.prev('select'); |
| 1808 |
let name = $select.val(); |
| 1809 |
let $ids = this.$tbody.find('.check-column input[type="checkbox"]:checked'); |
| 1810 |
let ba = this.bulk_actions?.[name]; |
| 1811 |
|
| 1812 |
if(ba && $ids[0]){ |
| 1813 |
return $select.data({ |
| 1814 |
...ba, |
| 1815 |
...(name == 'delete' && ba.bulk === true && {bulk: 2}), |
| 1816 |
ids: $ids.toArray().map(cb => cb.value) |
| 1817 |
}).wpjam_action(), false; |
| 1818 |
} |
| 1819 |
}else if($ae.is('[name=filter_action], #search-submit')){ |
| 1820 |
if(this.ajax !== false){ |
| 1821 |
return this.query(), false; |
| 1822 |
} |
| 1823 |
} |
| 1824 |
}else if(e.type == 'keydown'){ |
| 1825 |
if(e.key === 'Enter' && this.ajax !== false){ |
| 1826 |
if($el.is('#current-page-selector')){ |
| 1827 |
return this.query(_.extend(wpjam.params, {paged: parseInt($el.val())})), false; |
| 1828 |
}else if(!$el.closest('.mu-text, .mu-fields')[0]){ |
| 1829 |
let $submit = $el.closest(':has(:submit)').find(':submit'); |
| 1830 |
|
| 1831 |
if($submit[0]){ |
| 1832 |
return $submit.first().focus().trigger("click"), false; |
| 1833 |
} |
| 1834 |
} |
| 1835 |
} |
| 1836 |
}else if(e.type == 'change'){ |
| 1837 |
if($el.is('[name="date"]')){ |
| 1838 |
this.query(); |
| 1839 |
}else if($el.is('[name="end_date"]')){ |
| 1840 |
let dates = _.map(['start_date', 'end_date'], k => $('.tablenav [name="'+k+'"]').val()); |
| 1841 |
|
| 1842 |
dates[0] && dates[1] && dates[0] > dates[1] && wpjam.notice('开始日期不能大于结束日期', 'error'); |
| 1843 |
} |
| 1844 |
} |
| 1845 |
}, |
| 1846 |
|
| 1847 |
before: function(args){ |
| 1848 |
let state = ['list_action', 'id', 'data']; |
| 1849 |
|
| 1850 |
if(args.action_type == 'form'){ |
| 1851 |
if(!args.bulk){ |
| 1852 |
args.state = state; |
| 1853 |
} |
| 1854 |
}else{ |
| 1855 |
if(args.bulk && args.bulk == 2 && !args.id){ |
| 1856 |
wpjam.dialog('close'); |
| 1857 |
|
| 1858 |
return this.action({...args, id: args.ids.shift()}).then(()=> args.ids.length && setTimeout(()=> this.action(args), 400)) && false; |
| 1859 |
} |
| 1860 |
|
| 1861 |
args.params = _.omit(wpjam.params, state); |
| 1862 |
} |
| 1863 |
|
| 1864 |
if(this.$tbody.find('.check-column')[0]){ |
| 1865 |
_.reduce(((args.bulk && args.bulk != 2) ? args.ids : (args.id ? [args.id] : [])), ($r, i)=> $r.add(this.get_row(i)), $()).find('.check-column input').before(wpjam.spinner); |
| 1866 |
} |
| 1867 |
}, |
| 1868 |
|
| 1869 |
response: function(data, args){ |
| 1870 |
if(args.bulk){ |
| 1871 |
this.$form.find('thead, tfoot').find('.check-column input').prop('checked', false); |
| 1872 |
}else{ |
| 1873 |
this.$tbody.find('> tr').not(args.id ? this.get_row(args.id) : '').wpjam_highlight(); |
| 1874 |
} |
| 1875 |
|
| 1876 |
let $item = args.id && this.get_row(args.id).wpjam_scroll(); |
| 1877 |
let type = data.type; |
| 1878 |
|
| 1879 |
if(['up', 'down', 'move'].includes(type)){ |
| 1880 |
$item.wpjam_highlight('move'); |
| 1881 |
|
| 1882 |
if(type == 'up'){ |
| 1883 |
$item.insertBefore($item.prev()); |
| 1884 |
}else if(type == 'down'){ |
| 1885 |
$item.insertAfter($item.next()); |
| 1886 |
} |
| 1887 |
}else if(!['form', 'append', 'redirect'].includes(type)){ |
| 1888 |
data.args && setTimeout(()=> this.action({...args, data: data.args}), 400); |
| 1889 |
|
| 1890 |
type == 'list' && args.list_action == 'delete' && this.delete_row(args.id); |
| 1891 |
|
| 1892 |
this.load(data); |
| 1893 |
|
| 1894 |
if(type == 'items'){ |
| 1895 |
_.each(data.items, item => this.process(item, args)); |
| 1896 |
}else{ |
| 1897 |
this.process(data, args); |
| 1898 |
} |
| 1899 |
} |
| 1900 |
|
| 1901 |
data.next && _.extend(wpjam.params, {list_action: data.next}, _.pick(args, ['id', 'data'])); |
| 1902 |
|
| 1903 |
data.list_action = args.list_action; |
| 1904 |
data.action_type = data.list_action_type = args.action_type; |
| 1905 |
|
| 1906 |
return data; |
| 1907 |
}, |
| 1908 |
|
| 1909 |
process: function(data, args){ |
| 1910 |
let type = data.type; |
| 1911 |
let $dialog = wpjam.dialog(); |
| 1912 |
|
| 1913 |
if($dialog[0] || args.action_type != 'submit'){ |
| 1914 |
$dialog[0] && data.form && wpjam.dialog(data); |
| 1915 |
|
| 1916 |
wpjam.notice(data.notice); |
| 1917 |
} |
| 1918 |
|
| 1919 |
if(type == 'list'){ |
| 1920 |
$('html').scrollTop(0); |
| 1921 |
|
| 1922 |
((data.bulk && data.ids) || data.id) && this.update_row(data); |
| 1923 |
}else if(['add', 'duplicate'].includes(type)){ |
| 1924 |
let pos = (data.after || data.before); |
| 1925 |
let $pos = pos ? this.get_row(pos) : this.$tbody.find('> tr'); |
| 1926 |
let $row = $(data.data); |
| 1927 |
|
| 1928 |
if(data.after || data.last){ |
| 1929 |
$pos.last().after($row); |
| 1930 |
}else{ |
| 1931 |
$pos.first().before($row); |
| 1932 |
} |
| 1933 |
|
| 1934 |
this.update_row(data).$form.find('tr.no-items').remove(); |
| 1935 |
}else if(['add_item', 'edit_item', 'del_item', 'move_item'].includes(type)){ |
| 1936 |
let params = wpjam.parse_params(['add_item', 'edit_item'].includes(type) ? args.defaults : args.data); |
| 1937 |
let $items = (type == 'del_item' ? this : this.update_row(data, false)).get_row(data.id).find('[data-field="'+params._field+'"]'); |
| 1938 |
|
| 1939 |
if(type == 'add_item'){ |
| 1940 |
$items.find('[data-i]:last').wpjam_highlight('add'); |
| 1941 |
}else if(type == 'edit_item'){ |
| 1942 |
$items.find('[data-i="'+params.i+'"]').wpjam_highlight('update'); |
| 1943 |
}else if(type == 'move_item'){ |
| 1944 |
$items.find('[data-i="'+params.pos+'"]').wpjam_highlight('move'); |
| 1945 |
}else if(type == 'del_item'){ |
| 1946 |
$items.find('[data-i="'+params.i+'"]').wpjam_highlight('delete').wpjam_remove(); |
| 1947 |
} |
| 1948 |
}else if(type == 'delete'){ |
| 1949 |
_.each(data.bulk ? data.ids : [data.id], id => this.delete_row(id)); |
| 1950 |
}else{ |
| 1951 |
this.update_row(data); |
| 1952 |
} |
| 1953 |
} |
| 1954 |
}; |
| 1955 |
|
| 1956 |
wpjam.init(); |
| 1957 |
}); |
| 1958 |
|
| 1959 |
jQuery.widget('wpjam.iris', jQuery.a8c.iris, { |
| 1960 |
_create: function(){ |
| 1961 |
if(!Color.fn.fromHex6){ |
| 1962 |
Color.fn.fromHex6 = Color.fn.fromHex; |
| 1963 |
Color.fn.fromHex = function(color){ |
| 1964 |
color = color.replace(/^#|^0x/, ''); |
| 1965 |
|
| 1966 |
if(color.length === 8 && /^[0-9A-F]{8}$/i.test(color)){ |
| 1967 |
this.a(parseInt(color.substring(6), 16)/255); |
| 1968 |
|
| 1969 |
color = color.substring(0, 6); |
| 1970 |
} |
| 1971 |
|
| 1972 |
return this.fromHex6(color); |
| 1973 |
}; |
| 1974 |
|
| 1975 |
Color.fn.toString = function(){ |
| 1976 |
return this.error ? '' : '#'+(parseInt(this._color, 10).toString(16).padStart(6, '0'))+(this._alpha < 1 ? parseInt(255*this._alpha, 10).toString(16).padStart(2, '0') : ''); |
| 1977 |
}; |
| 1978 |
} |
| 1979 |
|
| 1980 |
this._super(); |
| 1981 |
}, |
| 1982 |
_change: function(){ |
| 1983 |
if(this.element.data('alpha-enabled')){ |
| 1984 |
this._inited || this.controls.strip.width(18).clone(false, false).find('> div').slider({ |
| 1985 |
orientation: 'vertical', |
| 1986 |
value: parseInt(this._color.a()*100), |
| 1987 |
slide: (e, ui)=> { |
| 1988 |
this._color.a(parseFloat(ui.value/100)); |
| 1989 |
this.active = 'strip'; |
| 1990 |
this._change(); |
| 1991 |
} |
| 1992 |
}).end().insertAfter(this.controls.strip); |
| 1993 |
|
| 1994 |
this.element.closest('.wp-picker-container').css('--color', this._color.toString() || '#FFFFFF80'); |
| 1995 |
} |
| 1996 |
|
| 1997 |
this._super(); |
| 1998 |
} |
| 1999 |
}); |