XylotrechusZ
/**
* JS used for UI of WPMUDEV plugins.
*/
/*
* Initialize the Dashboard once the page is fully loaded.
*/
jQuery(function() {
// Small layout fix (changes the global background color).
jQuery("html").addClass("wpmud-html");
// Add event handlers to show overlay dialogs.
jQuery(".wpmud").on("click", "a[rel=dialog]", showDialog);
// Open any auto-show overlays.
jQuery("dialog.auto-show").first().each(showDialog);
// Select code content on click.
jQuery(".wpmud").on("click", "code, pre, .sel-all", selectOnClick);
// Disable the one-time-click buttons on first click.
jQuery(".wpmud").on("click", ".one-click", disableOnClick);
// Start animation when clicking on spinner-icons.
jQuery(".wpmud").on("click", ".has-spinner", spinOnClick);
// Make Ajax-submit buttons behave as Ajax-submit buttons.
jQuery(".wpmud").on("click", ".as-ajax", ajaxSubmitLink);
// Handle close buttons inside boxes.
jQuery(".wpmud").on("click", ".can-close .close", closeElement);
// Add a reload-page handler.
jQuery(".wpmud").on("click", ".reload-page", reloadPage);
// Initialize all tab-areas.
jQuery(".wpmud .tabs").each(function(){
WDP.wpmuTabs(this);
});
// Initialize all vertical tab-areas.
jQuery(".wpmud .vertical-tabs").each(function(){
WDP.wpmuVerticalTabs(this);
});
// Convert all select lists to fancy WPMU Select lists.
jQuery(".wpmud select").each(function(){
WDP.wpmuSelect(this);
});
// Convert all all search-fields to WPMU search areas.
jQuery(".wpmud input[type=search]").each(function(){
WDP.wpmuSearchfield(this);
});
// Check the page URL for special actions
checkLocalRoutes();
// Add new jQuery function jQuery().loading(true|false)
jQuery.fn.extend({
loading: function(state, message) {
if (undefined === state) { state = true; }
this.each(function() {
if (state) {
jQuery(this).addClass("loading");
} else {
jQuery(this).removeClass("loading");
}
});
if (state && message) {
jQuery(".wpmud-loading-info").remove();
message = "<p><span class='loading'></span> " + message + "</p>";
jQuery("<div></div>")
.addClass("wpmud-loading-info")
.appendTo("body")
.html(message);
} else if (!state) {
jQuery(".wpmud-loading-info").remove();
}
return this;
}
});
// When a rel=dialog element was clicked we find and open the target dialog.
function showDialog(ev) {
var el = jQuery(this);
var args = {};
if (el.data("width")) { args.width = el.data("width"); }
if (el.data("height")) { args.height = el.data("height"); }
if (el.data("class")) { args.class = el.data("class"); }
if (el.data("title")) { args.title = el.data("title"); }
if (el.is("dialog")) {
WDP.showOverlay("#" + el.attr("id"), args);
} else if (el.attr("href")) {
WDP.showOverlay(el.attr("href"), args);
}
return false;
}
// When a .reload-page item is clicked, we reload it!
function reloadPage(ev) {
if (ev && ev.preventDefault) { ev.preventDefault(); }
var btn = jQuery(ev.target),
scope = jQuery("#wpbody, .dev-overlay"),
elems = scope.find("button, .button, a[href], [tooltip]");
// Disable other elements on the page and start loading animation.
if (btn.closest(".box").length) {
btn.closest(".box").loading(true);
} else if (btn.find(".spin-on-click")) {
spinOnClick.call(btn, ev);
} else {
btn.loading(true);
}
elems.prop("disabled", true).addClass("disabled");
// Reload the page!
window.location.reload();
return false;
}
// Select all text inside the element.
function selectOnClick(ev) {
WDP.selectText(this);
}
// Disable the element on click.
function disableOnClick(ev) {
var form, el = jQuery(this);
window.setTimeout(function() {
el.prop("disabled", true).addClass("disabled").loading(true);
if (el.hasClass("button")) {
form = el.closest("form");
if ( form.length ) {
form.find(":input").prop("disabled", true).addClass("disabled");
form.prop("disabled", true).addClass("disabled");
}
}
}, 20);
}
// Start animating the element on click.
function spinOnClick(ev) {
var icon, el = jQuery(this);
if (el.hasClass("spin-on-click")) { icon = el; }
else { icon = el.find(".spin-on-click"); }
icon.addClass("spin");
}
// Submit a link as ajax request instead of refreshing the window.
function ajaxSubmitLink(ev) {
var el = jQuery(this),
url = el.attr("href");
if (! url) { return false; }
el.addClass("loading disabled").prop("disabled", true);
jQuery.post(url)
.always(function() {
el.removeClass("loading disabled").prop("disabled", false);
}).fail(function() {
WDP.showError({"message": false});
});
return false;
}
// Parses the hash-tag in the current address bar.
function checkLocalRoutes() {
var route = window.location.hash.substr(1),
parts = route.split("=");
WDP.localRoutes = {
"action": false,
"param": false
};
if (! route.length ) { return; }
WDP.localRoutes.action = parts[0];
if (parts.length > 1) {
WDP.localRoutes.param = parts[1];
}
}
// Closes an element (i.e. hides and removes it)
function closeElement() {
var box = jQuery(this).closest(".can-close");
box.css({height: box.outerHeight() });
box.addClass("animated collapse");
function removeElementBox() {
box.remove();
}
window.setTimeout(removeElementBox, 450);
}
});
/*
* Define Dashboard namespace with all the functions.
* WDP = WPMUDEV Dashboard Plugin
*/
window.WDP = window.WDP || {};
/**
* Display a modal overlay on the screen.
* Only one overlay can be displayed at once.
*
* The dialog source must be (or contain) an <dialog> element.
* Only the <dialog> element is parsed and displayed in the overlay.
*
* @since 4.0.0
* @param string dialogSource Either CSS class/ID, URL or HTML string.
* - ID must start with a hash '#'.
* - Class must start with a dot '.'.
* - URL contains '://' (absolute URL).
* - URL starts with slash '/' (relative URL).
* - Everything else is considered HTML string.
* @param array args Optional arguments, like callbacks
* @var callback onShow
* @var int width (only for iframes)
* @var int height (only for iframes)
* @var string class
* @var string title
*/
WDP.showOverlay = function(dialogSource, args) {
var retry = false;
if ('object' !== typeof args) { args = {}; }
args.onShow = args.onShow || false;
// 1.) fetch the dialog code from the appropriate source.
if ('#' === dialogSource[0] || '.' === dialogSource[0]) {
/*
* Type 1: CSS selector
* The page contains a <dialog> element that is instantly displayed.
*/
var dialog = jQuery('dialog' + dialogSource);
showTheDialog(dialog);
} else if (-1 !== dialogSource.indexOf('://') || '/' === dialogSource[0]) {
var type;
if ('/' === dialogSource[0]) { type = 'ajax'; }
else if (0 === dialogSource.indexOf(WDP.data.site_url)) { type = 'ajax'; }
else { type = 'iframe'; }
if ('ajax' === type) {
/*
* Type 2a: AJAX handler
* The URL is relative or starts with the WordPress site_url. The
* URL is called as ajax handler. Result can be either HTML code or
* a JSON object with attributes `obj.success` and `obj.data.html`
* In either case, the returned HTML needs to contain a <dialog> tag
*/
jQuery.get(
dialogSource,
'',
function(resp) {
var el;
if ('{' === resp[0]) { resp = jQuery.parseJSON(resp); }
if ('object' === typeof resp) {
if (resp && resp.success && resp.data.html) {
el = jQuery(resp.data.html);
}
} else {
el = jQuery(resp);
}
if (!el || !el.length) { return; }
if (el.is('dialog')) { showTheDialog(el); }
else { showTheDialog(el.find('dialog')); }
}
);
} else if ('iframe' === type) {
/*
* Type 2b: iframe container
* An external URL is loaded inside an iframe which is displayed
* inside the dialog. The external URL may return any content.
*/
var iframe = jQuery('<div><iframe class="fullsize"></iframe></div>');
iframe.find('iframe').attr('src', dialogSource);
if (args.width) { iframe.find('iframe').attr('width', args.width); }
if (args.height) { iframe.find('iframe').attr('height', args.height); }
showTheDialog(iframe);
}
} else {
/*
* Type 3: Plain HTML code
* The dialog source is plain HTML code that is parsed and displayed;
* the code needs to contain an <dialog> element.
*/
var el = jQuery(dialogSource);
if (el.is('dialog')) { showTheDialog(el); }
else { showTheDialog(el.find('dialog')); }
}
// 2.) Render the dialog.
function showTheDialog(dialog) {
if ( ! dialog.length ) { return; }
if ( ! WDP.prepareOverlay() ) {
if ( ! retry ) {
retry = true;
WDP.closeOverlay();
window.setTimeout(function() { showTheDialog(dialog); }, 610);
}
return;
}
if (! args.title) {
args.title = dialog.attr('title');
}
if (args.class) {
dialog.addClass(args.class);
}
WDP.overlay.box_title.find('h3').html(args.title);
WDP.overlay.box_content.html(dialog.html());
WDP.overlay.wrapper.addClass(dialog.attr('class'));
if (dialog.hasClass('no-close')) {
WDP.overlay.wrapper.addClass('no-close');
WDP.overlay.close.remove();
}
if (dialog.find('.title-action').length) {
WDP.overlay.box_content.find('.title-action').appendTo(WDP.overlay.box_title);
}
WDP.overlay.box_content.on('click', '.close', WDP.closeOverlay);
jQuery(window).on('resize', WDP.positionOverlay);
WDP.overlay.container.addClass('has-overlay');
WDP.overlay.wrapper.show();
WDP.overlay.box.addClass('bounce-in');
WDP.overlay.back.addClass('fade-in');
WDP.overlay.visible = true;
WDP.positionOverlay();
window.setTimeout(function(){
WDP.overlay.box.removeClass('bounce-in');
WDP.overlay.back.removeClass('fade-in');
}, 1000);
if ('function' === typeof args.onShow) { args.onShow(); }
}
return WDP;
};
/**
* Closes the current modal overlay again.
*
* @since 4.0.0
*/
WDP.closeOverlay = function() {
if ( WDP.prepareOverlay() ) { return WDP; }
WDP.overlay.container.removeClass('has-overlay');
WDP.overlay.box.addClass('bounce-out');
WDP.overlay.back.addClass('fade-out');
jQuery(window).off('resize', WDP.positionOverlay);
window.setTimeout(function() {
WDP.overlay.wrapper.hide()
}, 550);
window.setTimeout(function() {
WDP.overlay.wrapper.remove();
WDP.overlay.wrapper = null;
WDP.overlay.visible = false;
}, 600);
return WDP;
};
/**
* Updates the position of the overlay to keep it vertically centered on the
* screen.
*
* @since 4.0.0
*/
WDP.positionOverlay = function() {
var availHeight, needHeight, newOffset;
if ( WDP.prepareOverlay() ) { return WDP; }
availHeight = WDP.overlay.scroll.height();
needHeight = WDP.overlay.box.outerHeight();
newOffset = (availHeight - needHeight) / 2;
if ( newOffset < 20 ) { newOffset = 20; }
WDP.overlay.box.css({ marginTop: newOffset });
return WDP;
};
/**
* Creates all the DOM elements needed to display the overlay element.
*
* @since 4.0.0
* @return bool True if the modal is ready to be displayed.
*/
WDP.prepareOverlay = function() {
var offset = jQuery('#wpcontent').offset();
WDP.overlay = WDP.overlay || {};
if ( WDP.overlay.visible ) { return false; }
if ( ! WDP.overlay.wrapper ) {
WDP.overlay.container = jQuery('.wpmud-html');
WDP.overlay.wrapper = jQuery('<div class="dev-overlay"></div>');
WDP.overlay.back = jQuery('<div class="back"></div>');
WDP.overlay.scroll = jQuery('<div class="box-scroll"></div>');
WDP.overlay.box = jQuery('<div class="box"></div>');
WDP.overlay.box_title = jQuery('<div class="title"><h3></h3></div>');
WDP.overlay.box_content = jQuery('<div class="content"></div>');
WDP.overlay.close = jQuery('<div aria-hidden="true" class="close">×</div><button class="wpdui-sr-only"><span class="wpdui-sr-only">Close</span></button>');
WDP.overlay.back.appendTo(WDP.overlay.wrapper);
WDP.overlay.scroll.appendTo(WDP.overlay.wrapper);
WDP.overlay.box.appendTo(WDP.overlay.scroll);
WDP.overlay.box_title.appendTo(WDP.overlay.box);
WDP.overlay.box_content.appendTo(WDP.overlay.box);
WDP.overlay.close.appendTo(WDP.overlay.box_title);
WDP.overlay.wrapper.appendTo('body');
WDP.overlay.close.click(WDP.closeOverlay);
}
return true;
};
/**
* Select all text inside the HTML element. This can be a div/code/input/etc.
*
* @since 4.0.0
* @param object el The HTML element.
*/
WDP.selectText = function(el) {
var range, jq;
jq = jQuery( el );
el = jq[0];
if ( jq.is(':input') ) {
jq.focus().select();
} else if ( document.selection ) {
range = document.body.createTextRange();
range.moveToElementText(el);
range.select();
} else if ( window.getSelection ) {
range = document.createRange();
range.selectNode(el);
window.getSelection().addRange(range);
}
return WDP;
};
/**
* Initialize the functions of a tab-area
*
* @since 4.0.0
* @param object el The tab-area container element.
*/
WDP.wpmuTabs = function(el) {
var jq = jQuery(el).closest('.tabs');
if (! jq.length) { return; }
// Resize the tab-area after short delay.
function resizeArea() {
window.setTimeout(resizeAreaHandler, 20);
}
// Resize the tab area to match the current tab.
function resizeAreaHandler() {
var current = jq.find('.tab > input:checked').parent(),
content = current.find('.content');
jq.height(content.outerHeight() + current.outerHeight() - 6);
}
// Updates the URL hash to keep tab open during page refresh
function updateHash() {
var current = jq.find('.tab > input:checked');
if (current.attr('id').length) {
WDP.updateHash(current.attr('id'));
}
resizeArea();
}
// Open the tab that is specified in window URL hash
function switchTab() {
var curTab,
route = window.location.hash.replace( /[^\w-_]/g, '' );
if (route) {
curTab = jq.find('input#' + route);
if (curTab.length && ! curTab.prop('checked')) {
curTab.prop('checked', true);
scrollWindow();
}
}
}
// Scroll the window to top of the tab list.
function scrollWindow() {
resizeArea();
jQuery('html, body').scrollTop(
jq.offset().top
- parseInt( jQuery('html').css('paddingTop') )
- 20
);
}
// Constructor.
function init() {
jq.on('click', '.tab > input[type=radio]', updateHash);
jQuery(window).on('hashchange', switchTab);
resizeArea();
switchTab();
}
init();
return WDP;
};
/**
* Initialize the functions of a vertical tab-area
*
* @since 4.0.0
* @param object el The tab-area container element.
*/
WDP.wpmuVerticalTabs = function(el) {
var jq = jQuery(el).closest('.vertical-tabs'),
minHeight = 0;
if (! jq.length) { return; }
// Resize the tab-area after short delay.
function resizeArea() {
window.setTimeout(resizeAreaHandler, 20);
}
// Resize the tab area to match the current tab.
function resizeAreaHandler() {
var current = jq.find('.tab > input:checked').parent(),
content = current.find('.content'),
newHeight = content.outerHeight();
if (newHeight < minHeight) { newHeight = minHeight; }
content.css({'min-height': minHeight});
jq.height(newHeight);
}
// Find the height of the tab labels
function calcMinHeight() {
minHeight = 0;
jq.find('.tab > label:visible').each(function() {
minHeight += jQuery(this).outerHeight();
});
}
// Updates the URL hash to keep tab open during page refresh
function updateHash() {
var current = jq.find('.tab > input:checked');
if (current.attr('id').length) {
WDP.updateHash(current.attr('id'));
}
resizeArea();
}
// Open the tab that is specified in window URL hash
function switchTab() {
var curTab,
route = window.location.hash.replace( /[^\w-_]/g, '' );
if (route) {
curTab = jq.find('input#' + route);
if (curTab.length && ! curTab.prop('checked')) {
curTab.prop('checked', true);
scrollWindow();
}
}
}
// Scroll the window to top of the tab list.
function scrollWindow() {
resizeArea();
jQuery('html, body').scrollTop(
jq.offset().top
- parseInt( jQuery('html').css('paddingTop') )
- 20
);
}
// Constructor.
function init() {
jq.on('click', '.tab > input[type=radio]', updateHash);
jQuery(window).on('resize', calcMinHeight);
jQuery(window).on('hashchange', switchTab);
calcMinHeight();
resizeArea();
switchTab();
}
init();
return WDP;
};
/**
* Update a normal select list to a fancy WPMU DEV select list!
*
* @since 4.0.0
* @param object el The select element.
*/
WDP.wpmuSelect = function(el) {
var jq = jQuery(el),
wrap, handle, list, value, items;
if (! jq.is("select")) { return; }
if (jq.closest(".select-container").length || jq.data("select2") || jq.is(".none-wpmu") ) { return; }
// Add the DOM elements to style the select list.
function setupElement() {
jq.wrap("<div class='select-container'>");
jq.hide();
wrap = jq.parent();
handle = jQuery("<span class='dropdown-handle'><i aria-hidden='true' class='wdv-icon wdv-icon-reorder'></i></span>").prependTo(wrap);
list = jQuery("<div class='select-list-container'></div>").appendTo(wrap);
value = jQuery("<div class='list-value'> </div>").appendTo(list);
items = jQuery("<ul class='list-results'></ul>").appendTo(list);
wrap.addClass(jq.attr("class"));
}
// When changing selection using JS, you need to trigger a 'wpmu:change' event
// eg: jQuery('select').val('4').trigger('wpmu:change')
function handleSelectionChange() {
jq.on('wpmu:change',function(){
//We need to re-populateList to handle dynamic select options added via JS/ajax
populateList();
items.find("li").not('.optgroup-label').on("click", function onItemClick(ev) {
var opt = jQuery(ev.target);
selectItem(opt, false);
});
});
}
// Add all the options to the new DOM elements.
function populateList() {
items.empty();
if( jq.find("optgroup").length ){
jq.find("optgroup").each(function(){
var optgroup = jQuery(this),
optgroup_item;
optgroup_item = jQuery("<ul></ul>").appendTo(items);
$label = jQuery('<li class="optgroup-label"></li>').text( optgroup.prop('label') );
optgroup_item.html( $label );
optgroup_item.addClass('optgroup');
optgroup.find('option').each(function onPopulateLoop() {
var opt = jQuery(this),
item;
item = jQuery("<li></li>").appendTo(optgroup_item);
item.text(opt.text());
item.data("value", opt.val());
if (opt.val() == jq.val()) {
selectItem(item);
}
});
});
}else{
jq.find("option").each(function onPopulateLoop() {
var opt = jQuery(this),
item;
item = jQuery("<li></li>").appendTo(items);
item.text(opt.text());
item.data("value", opt.val());
if (opt.val() == jq.val()) {
selectItem(item, true);
}
});
}
}
// Toggle the dropdown state between open/closed.
function stateToggle() {
if( wrap.find("select").is(":disabled") ) return;
if (! wrap.hasClass("active")) {
stateOpen();
} else {
stateClose();
}
}
// Close the dropdown list.
function stateClose(item) {
if (!item) { item = wrap; }
item.removeClass("active");
item.closest("tr").removeClass("select-open");
}
// Open the dropdown list.
function stateOpen() {
jQuery(".select-container.active").each(function() {
stateClose(jQuery(this));
});
wrap.addClass("active");
wrap.closest("tr").addClass("select-open");
}
// Visually mark the specified option as "selected".
function selectItem(opt, is_init) {
is_init = typeof is_init === "undefined" ? false : is_init;
value.text(opt.text());
jQuery(".current", items).removeClass("current");
opt.addClass("current");
stateClose();
// Also update the select list value.
jq.val(opt.data("value"));
if( !is_init )
jq.trigger("change");
}
// Element constructor.
function init() {
var sel_id;
setupElement();
populateList();
handleSelectionChange();
items.find("li").not('.optgroup-label').on("click", function onItemClick(ev) {
var opt = jQuery(ev.target);
selectItem(opt, false);
});
handle.on("click", stateToggle);
value.on("click", stateToggle);
jq.on("focus", stateOpen);
jQuery(document).click(function onOutsideClick(ev) {
var jq = jQuery(ev.target),
sel_id;
if (jq.closest(".select-container").length) { return; }
if (jq.is("label") && jq.attr("for")) {
sel_id = jq.attr("for");
if (jQuery("select#" + sel_id).length) { return; }
}
stateClose();
});
sel_id = jq.attr("id");
if (sel_id) {
jQuery("label[for=" + sel_id + "]").on("click", stateOpen);
}
jq.addClass("wdev-styled");
}
init();
return WDP;
};
/**
* Initialize the search-areas.
*
* @since 4.0.0
* @param object el The search input element.
*/
WDP.wpmuSearchfield = function(el) {
var jq = jQuery(el),
tmrDelay = 0,
lastVal = '',
tmrHide = false,
hasResults = false,
search, wrap, inpbox, emptyMsg, emptybox, resbox, reslist, curitem;
if (! jq.is('input[type="search"]')) { return; }
// Add the DOM elements to style the select list.
function setupElement() {
var classes = jq.attr('class');
jq.prop('autocomplete', 'off');
jq.wrap('<div class="search-box">');
wrap = jq.parent();
if ( classes ) {
wrap.addClass(classes);
}
jq.wrap('<div class="input-box">');
inpbox = jq.parent();
inpbox.append('<i aria-hidden="true" class="search-icon dev-icon dev-icon-search"></i><button class="wpdui-sr-only search-icon"><span class="wpdui-sr-only">Search</span></button>');
curitem = jQuery('<div class="current-item"></div>');
curitem.appendTo(inpbox);
resbox = jQuery('<div class="search-results"></div>');
reslist = jQuery('<ul></ul>');
reslist.appendTo(resbox);
resbox.appendTo(wrap);
emptybox = jQuery('<div class="no-results"></div>');
emptybox.appendTo(wrap);
emptybox.hide();
}
// Start a timer on each keystroke. When the timer runs out a 'search' event
// is triggered.
function startDelay() {
clearDelay();
// Ignore if value did not change (i.e. cursor keys, shift, return, ...)
if (lastVal === jq.val()) { return; }
lastVal = jq.val();
tmrDelay = window.setTimeout(function() { jq.trigger('search'); }, 400);
}
// On key-DOWN we clear the timer.
function clearDelay() {
if (tmrDelay) {
window.clearTimeout(tmrDelay);
tmrDelay = 0;
}
}
// Toggle the progress state of the search box.
function doingProgress(state) {
if (state) {
wrap.addClass('progress');
} else {
wrap.removeClass('progress');
}
}
// Clear/Hide the search-results list.
function clearResults(clearFilter) {
reslist.empty();
curitem.hide();
jq.show();
hasResults = false;
resultsVisible(false);
if (clearFilter) {
if (search) {
jq.val(search);
} else {
jq.val('');
}
}
}
// Populate/Show the search-results list.
function showResults(items) {
clearResults(false);
if (! items || ! items.length) {
resultsVisible(true);
return;
}
for (var i = 0; i < items.length; i += 1) {
var li = jQuery('<li></li>'),
item = items[i];
if (! item.label) { continue; }
li.html('<span aria-hidden="true" class="item-label">' + item.label + '</span><a class="wpdui-sr-only item-label"><span class="wpdui-sr-only">' + item.label + '</span></a>');
if (item.thumb) {
li.prepend('<span aria-hidden="true" class="thumb" style="background-image:url(' + item.thumb + ')">');
}
if (item.id) {
li.attr('data-id', item.id);
li.addClass('item item-' + item.id);
}
reslist.append(li);
hasResults = true;
}
resultsVisible(true);
}
// Toggle visibility of the results.
function resultsVisible(state) {
emptybox.hide();
if (! hasResults) {
resbox.hide();
if (jq.val() && state) {
if (jq.data('no-empty-msg') || wrap.hasClass('progress')) {
emptybox.hide();
} else {
if (!emptyMsg || !emptyMsg.length) {
if (jq.data('empty-msg')) {
emptyMsg = jq.data('empty-msg');
} else {
emptyMsg = WDP.lang.empty_search;
}
emptybox.text(emptyMsg);
}
emptybox.show();
}
}
return;
}
if (state) {
if (tmrHide) {
window.clearTimeout(tmrHide);
tmrHide = false;
}
resbox.show();
} else {
tmrHide = window.setTimeout(function() {
resbox.hide();
tmrHide = false;
}, 300 );
}
}
// Visually select a single search item
function selectItem(item) {
var item_label, title;
if (item) {
title = '';
item_label = '';
if (item.find('.thumb').length) {
title += item.find('.thumb')[0].outerHTML;
}
if (item.find('.title').length) {
item_label = item.find('.title').text();
title += item.find('.title')[0].outerHTML;
} else {
item_label = item.find('.item-label').text();
title += item.find('.item-label').html();
}
curitem.html(title);
search = jq.val();
jq.hide();
curitem.show();
resbox.hide();
if (item.data('id')) {
jq.val(item.data('id'));
} else {
jq.val(item_label);
}
jq.trigger('item:select');
} else {
jq.val(search);
curitem.hide();
jq.show();
window.setTimeout(function(){jq.focus();}, 20);
jq.trigger('item:clear');
}
}
// Constructor.
function init() {
setupElement();
clearResults(true);
jq.on('keydown', clearDelay);
jq.on('keyup', startDelay);
jq.on('focus', function() { resultsVisible(true) } );
jq.on('blur', function() { resultsVisible(false) } );
jq.on('progress:start', function() { doingProgress(true); });
jq.on('progress:stop', function() { doingProgress(false); });
jq.on('results:clear', function() { clearResults(true); });
jq.on('results:show', function(ev, data) { showResults(data); });
wrap.on('click', '.search-results .item', function() { selectItem(jQuery(this)); });
curitem.on('click', function() { selectItem(false); });
wrap.on('click', '.search-icon', function() { jq.trigger('search'); jq.focus(); });
}
init();
return WDP;
};
/**
* Displays a message in the top of the window.
*
* @since 4.0.0
*/
WDP.showMessage = function(action) {
var me = this;
initDom();
// Options can also be passed in as object now :)
if (action instanceof Object) {
for (var key in action) {
if (!action.hasOwnProperty(key)) {continue;}
WDP.showMessage(key, action[key]);
}
return;
}
if (WDP.data._msg) {
me.msg = WDP.data._msg;
}
switch (action) {
case "type":
switch ( arguments[1] ) {
case "success":
case "ok":
case "green":
WDP.data._msg = me.msgSuccess;
break;
case "error":
case "err":
case "red":
WDP.data._msg = me.msgError;
break;
}
break;
case "message":
var text = arguments[1];
if (!text || !text.length) {
me.msg.find(".extra-text").html("").hide();
me.msg.find(".default-text").show();
} else {
me.msg.find(".extra-text").html(text).show();
me.msg.find(".default-text").hide();
}
break;
case "delay":
var new_delay = parseInt( arguments[1] );
if (!new_delay) {
me.delay = 0;
} else if (isNaN(new_delay) || new_delay < 2000) {
me.delay = 3000;
} else {
me.delay = new_delay;
}
break;
case "icon":
if (false === arguments[1] || 0 === arguments[1]) {
me.msg.find(".the-msg-icon").hide();
} else {
me.msg.find(".the-msg-icon").show();
}
break;
case "hide":
if (false === arguments[1] || 0 === arguments[1]) { break; }
hideMessage();
break;
case "show":
default:
if (false === arguments[1] || 0 === arguments[1]) { break; }
showMessage();
break;
}
// Dreate the DOM elements.
function initDom() {
if (WDP.data._message_dom_done) { return; }
WDP.data._message_dom_done = true;
if (! WDP.lang.default_msg_ok) {
WDP.lang.default_msg_ok = "Okay, we saved your changes!";
}
if (! WDP.lang.default_msg_err) {
WDP.lang.default_msg_err = "Oops, we could not do this...";
}
jQuery("body").append(
'<div class="update-notice ok" id="wdp-success" style="display:none">' +
'<span aria-hidden="true" class="the-msg-icon check-animation"></span>' +
'<p><span class="default-text">' + WDP.lang.default_msg_ok + '</span>' +
'<span class="extra-text" style="display:none"></span></p>' +
'<span aria-hidden="true" class="close">×</span><button class="wpdui-sr-only"><span class="wpdui-sr-only">Close</span></button>' +
'</div>'
)
jQuery("body").append(
'<div class="update-notice err" id="wdp-error" style="display:none">' +
'<i aria-hidden="true" class="the-msg-icon wdv-icon wdv-icon-warning-sign"></i>' +
'<p><span class="default-text">' + WDP.lang.default_msg_err + '</span>' +
'<span class="extra-text" style="display:none"></span></p>' +
'<span aria-hidden="true" class="close">×</span><button class="wpdui-sr-only"><span class="wpdui-sr-only">Close</span></button>' +
'</div>'
);
me.msgSuccess = jQuery("#wdp-success");
me.msgError = jQuery("#wdp-error");
me.msg = me.msgSuccess;
me.delay = 3000;
}
// Show current message.
function showMessage() {
var tmr = me.msg.data("tmr");
hideMessage();
if (tmr) {
window.setTimeout(WDP.showMessage, 20);
return;
}
me.msg.show();
me.msg.one("click", ".close", hideMessage);
// Hide the update notice box after a short time.
if (me.delay) {
tmr = window.setTimeout(function() {
me.msg.fadeOut();
me.msg.data("tmr", false);
}, me.delay);
me.msg.data("tmr", tmr);
me.msg.find(".close").hide();
} else {
me.msg.find(".close").show();
tmr = false;
me.msg.data("tmr", false);
}
}
// Hide all messages.
function hideMessage() {
var tmr;
// Success message.
tmr = me.msgSuccess.data("tmr");
if (tmr) {
window.clearTimeout(tmr);
me.msgSuccess.data("tmr", false);
}
me.msgSuccess.hide();
// Error message.
tmr = me.msgError.data("tmr");
if (tmr) {
window.clearTimeout(tmr);
me.msgError.data("tmr", false);
}
me.msgError.hide();
}
return WDP;
}
/**
* Displays the "Changes saved" message in the top of the window.
*
* @since 4.0.0
*/
WDP.showSuccess = function(message) {
var args = {
"type": "success",
"delay": 3000,
"icon": true,
"message": false,
"show": false
};
if (message instanceof Object) {
WDP.showMessage(args);
message.show = true;
WDP.showMessage(message);
} else if ("string" === typeof message) {
args.message = message;
WDP.showMessage(args);
}
return WDP;
};
/**
* Displays the "Did not work" message in the top of the window.
*
* @since 4.0.0
*/
WDP.showError = function(message) {
var args = {
"type": "error",
"delay": false,
"icon": true,
"message": false,
"show": true
};
if (message instanceof Object) {
WDP.showMessage(args);
message.show = true;
WDP.showMessage(message);
} else if ("string" === typeof message) {
args.message = message;
WDP.showMessage(args);
}
return WDP;
};
/**
* Updates the hash-value in the current windows URL without scrolling to the
* element.
*
* @since 4.0.3
*/
WDP.updateHash = function(newHash) {
newHash = newHash.replace( /^#/, '' );
var fx,
node = jQuery( '#' + newHash );
if (node.length) {
// Remove the ID value from the actual element.
node.attr('id', '');
// Create a dummy element at current position with the specific ID.
fx = jQuery('<div></div>')
.css({
position: 'absolute',
visibility: 'hidden',
top: jQuery(document).scrollTop() + 'px'
})
.attr('id', newHash)
.appendTo(document.body);
}
// Change hash value in the URL. Browser will scroll to _current position_.
document.location.hash = newHash;
// Undo the changes from first part.
if (node.length) {
fx.remove();
node.attr('id', newHash);
}
}
/**
* Create or replace a cookie via javascript.
*
* @since 4.1.0
*/
WDP.setCookie = function(name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 86400 * 1000));
expires = "; expires=" + date.toGMTString();
} else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
};
/**
* Return the value of a cookie.
*
* @since 4.1.0
*/
WDP.getCookie = function(cookieName) {
if (document.cookie.length > 0) {
offset = document.cookie.indexOf(cookieName + "=");
if (-1 != offset) {
offset = offset + cookieName.length + 1;
end = document.cookie.indexOf(";", offset);
if (end == -1) {
end = document.cookie.length;
}
return unescape(document.cookie.substring(offset, end));
}
}
return "";
};