: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
var originalSelectValue = $(this).data('originalSelectValue');
$(this).find('.wfls-option-select select').val(originalSelectValue).trigger('change');
$(this).trigger('change', [true]);
$('.wfls-option.wfls-option-text').each(function() {
var originalTextValue = $(this).data('originalTextValue');
if (typeof originalTextValue !== 'undefined') {
$(this).find('.wfls-option-text input').val(originalTextValue);
$(this).trigger('change', [true]);
$('.wfls-option.wfls-option-textarea').each(function() {
var originalTextValue = $(this).data('originalTextValue');
$(this).find('.wfls-option-textarea textarea').val(originalTextValue);
$(this).trigger('change', [true]);
$('.wfls-option.wfls-option-token').each(function() {
var originalTokenValue = $(this).data('originalTokenValue');
$(this).find('select').val(originalTokenValue).trigger('change');
$(this).trigger('change', [true]);
$('.wfls-option.wfls-option-switch').each(function() {
var originalValue = $(this).data('originalValue');
$(this).find('.wfls-switch > li').each(function() {
$(this).toggleClass('wfls-active', originalValue == $(this).data('optionValue')).attr('aria-checked', originalValue == $(this).data('optionValue') ? 'true' : 'false');
$(this).trigger('change', [true]);
$(window).trigger('wflsOptionsReset');
WFLS.pendingChanges = {};
WFLS.updatePendingChanges();
updatePendingChanges: function() {
$(window).off('beforeunload', WFLS._unsavedOptionsHandler);
if (Object.keys(WFLS.pendingChanges).length) {
$('#wfls-cancel-changes').removeClass('wfls-disabled');
$('#wfls-save-changes').removeClass('wfls-disabled');
$(window).on('beforeunload', WFLS._unsavedOptionsHandler);
$('#wfls-cancel-changes').addClass('wfls-disabled');
$('#wfls-save-changes').addClass('wfls-disabled');
_unsavedOptionsHandler: function(e) {
var message = __("You have unsaved changes to your options. If you leave this page, those changes will be lost."); //Only shows on older browsers, newer browsers don't allow message customization
e.returnValue = message; //IE and Firefox
setOptions: function(options, successCallback, failureCallback) {
if (!Object.keys(options).length) {
this.ajax('wordfence_ls_save_options', {changes: JSON.stringify(options)}, function(res) {
typeof successCallback == 'function' && successCallback(res);
if (res.hasOwnProperty('html') && res.html) {
WFLS.panelModalHTML((WFLS.screenSize(500) ? '300px' : '400px'), 'Error Saving Options', res.error);
WFLS.panelModal((WFLS.screenSize(500) ? '300px' : '400px'), 'Error Saving Options', res.error);
typeof failureCallback == 'function' && failureCallback
saveOptions: function(successCallback, failureCallback) {
this.setOptions(WFLS.pendingChanges, successCallback, failureCallback);
updateIPPreview: function(value, successCallback) {
this.ajax('wordfence_ls_update_ip_preview', value, function(response) {
successCallback(response);
* Sends a WP AJAX call, automatically adding our nonce.
* @param string|array|object payload
* @param function successCallback
* @param function failureCallback
ajax: function(action, payload, successCallback, failureCallback) {
if (typeof(payload) == 'string') {
if (payload.length > 0) {
payload += 'action=' + action + '&nonce=' + WFLSVars.nonce;
else if (typeof(payload) == 'object' && payload instanceof Array) {
// jQuery serialized form data
else if (typeof(payload) == 'object') {
payload['action'] = action;
payload['nonce'] = WFLSVars.nonce;
success: function(json) {
typeof successCallback == 'function' && successCallback(json);
typeof failureCallback == 'function' && failureCallback();
* Displays a generic panel.
* @param @param string width A width string in the format '100px'
panel: function(width, heading, body, settings) {
if (typeof settings === 'undefined') {
WFLS.panelQueue.push([width, "<h3>" + heading + "</h3><p>" + body + "</p>", settings]);
WFLS._panelServiceQueue();
* Displays a modal panel with fixed HTML content.
* @param @param string width A width string in the format '100px'
panelModalHTML: function(width, heading, body, settings) {
if (typeof settings === 'undefined') {
var prompt = $.tmpl(WFLSVars.modalHTMLTemplate, {title: heading, message: body});
var promptHTML = $("<div />").append(prompt).html();
var callback = settings.onComplete;
settings.overlayClose = false;
settings.closeButton = false;
settings.className = 'wfls-modal';
settings.onComplete = function() {
$('#wfls-generic-modal-close').on('click', function(e) {
typeof callback === 'function' && callback();
WFLS.panelHTML(width, promptHTML, settings)
* Displays a modal panel, automatically escaping the content.
* @param @param string width A width string in the format '100px'
panelModal: function(width, heading, body, settings) {
if (typeof settings === 'undefined') {
width = WFLS.screenSize(500) ? '300px' : '400px';
var includeDefaultButtons = typeof settings.includeDefaultButtons === 'undefined' ? false : settings.includeDefaultButtons;
var prompt = $.tmpl(WFLSVars[includeDefaultButtons ? 'modalTemplate' : 'modalNoButtonsTemplate'], {title: heading, message: body});
if (typeof settings.additional_buttons !== 'undefined') {
var buttonSection = prompt.find('.wfls-modal-footer > ul');
for(index in settings.additional_buttons) {
var buttonSettings = settings.additional_buttons[index];
var button = $('<button>').text(buttonSettings.label)
.addClass('wfls-btn wfls-btn-callout-subtle wfls-additional-button')
.attr('id', buttonSettings.id);
var buttonType = typeof buttonSettings.type === 'undefined' ? 'default' : buttonSettings.type;
button.addClass('wfls-btn-' + buttonType);
buttonSection.prepend($("<li>").addClass('wfls-padding-add-left-small').append(button));
var promptHTML = $("<div />").append(prompt).html();
var callback = settings.onComplete;
settings.overlayClose = false;
settings.closeButton = false;
settings.className = 'wfls-modal';
settings.onComplete = function() {
$('#wfls-generic-modal-close').on('click', function(e) {
typeof callback === 'function' && callback();
WFLS.panelHTML(width, promptHTML, settings)
* Displays a modal with the given title and message text.
* @param string title the modal title
* @param string message the message (this will be treated as text, not HTML)
* @param array buttons the buttons to include in the modal footer
* Each item in the array should be an object with the following properties:
* - label: The button text
* - id: An ID for the button
* - type: The type of button for styling purposes - i.e. default, primary (default: 'default')
displayModalMessage: function(title, message, buttons, settings) {
if (typeof settings !== 'object')
var width = typeof settings.width === 'undefined' ? null : settings.width;
settings.includeDefaultButtons = false;
settings.additional_buttons = buttons;
WFLS.panelModal(width, title, message, settings);
* Displays a modal panel with the error formatting.
* @param bool isTokenError Whether or not this error is an expired nonce error.
panelError: function(errorMsg, isTokenError) {
if (WFLS.tokenErrorShowing) {
WFLS.tokenErrorShowing = false;
WFLS.tokenErrorShowing = true;
var prompt = $.tmpl(WFLSVars.tokenInvalidTemplate, {title: 'An error occurred', message: errorMsg});
var promptHTML = $("<div />").append(prompt).html();
settings.overlayClose = false;
settings.closeButton = false;
settings.className = 'wfls-modal';
settings.onComplete = function() {
$('#wfls-token-invalid-modal-reload').on('click', function(e) {
window.location.reload(true);
typeof callback === 'function' && callback();
WFLS.panelHTML((WFLS.screenSize(500) ? '300px' : '400px'), promptHTML, settings);
* Displays a panel with fixed HTML content.
* @param string width A width string in the format '100px'
panelHTML: function(width, html, settings) {
if (typeof settings === 'undefined') {
WFLS.panelQueue.push([width, html, settings]);
WFLS._panelServiceQueue();
* Displays the next panel in the queue.
_panelServiceQueue: function() {
if (WFLS.panelQueue.length < 1) {
var elem = WFLS.panelQueue.shift();
WFLS._panelOpen(elem[0], elem[1], elem[2]);
* Does the actual function call to display the panel.
* @param string width A width string in the format '100px'
_panelOpen: function(width, html, settings) {
$.wflscolorbox(settings);
* Closes the current panel.
WFLS.panelIsOpen = false;
if (WFLS.panelQueue.length < 1) {
WFLS._panelServiceQueue();
* Parses and returns the hash portion of a URL, working around user agents that URL-encode the # character.
parseHashes: function() {
var hashes = window.location.hash.replace('%23', '#');
var splitHashes = hashes.split('#');
for (var i = 0; i < splitHashes.length; i++) {
if (splitHashes[i].length > 0) {
result.push(splitHashes[i]);
* Returns whether or not the screen size is within the size given. This may be a numerical value
* or one of the WFLS_SCREEN_ constants.
screenSize: function(size) {
return window.matchMedia("only screen and (max-width: 767px)").matches;
return window.matchMedia("only screen and (max-width: 991px)").matches;
return window.matchMedia("only screen and (max-width: 1199px)").matches;
return window.matchMedia("only screen and (max-width: 32767px)").matches;
var parsed = parseInt(size);
return window.matchMedia("only screen and (max-width: " + parsed + "px)").matches;
$.fn.crossfade = function(incoming, duration, complete) {
duration = duration || 400;
complete = complete || function() { };
return this.each(function() {
$(this).fadeOut(duration, function() {
$(incoming).fadeIn(duration, complete);
/*! @source https://github.com/eligrey/FileSaver.js/blob/master/dist/FileSaver.min.js */
(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)});