(function($) { var sprintf, __; if (!window['wordfenceAdmin']) { //To compile for checking: java -jar /usr/local/bin/closure.jar --js=admin.js --js_output_file=test.js window['wordfenceAdmin'] = { isSmallScreen: false, loading16: '
', loadingCount: 0, dbCheckTables: [], dbCheckCount_ok: 0, dbCheckCount_skipped: 0, dbCheckCount_errors: 0, issues: [], ignoreData: false, iconErrorMsgs: [], scanIDLoaded: 0, colorboxQueue: [], mode: '', visibleIssuesPanel: 'new', preFirstScanMsgsLoaded: false, newestActivityTime: 0, //must be 0 to force loading of all initially elementGeneratorIter: 1, reloadConfigPage: false, nonce: false, liveTrafficUpdatePending: false, activityLogUpdatePending: false, lastALogCtime: 0, lastIssueUpdateTime: 0, activityQueue: [], totalActAdded: 0, maxActivityLogItems: 1000, scanReqAnimation: false, debugOn: false, blockedCountriesPending: [], ownCountry: "", schedStartHour: false, currentPointer: false, countryMap: false, countryCodesToSave: "", performanceScale: 3, performanceMinWidth: 20, _windowHasFocus: true, serverTimestampOffset: 0, serverMicrotime: 0, wfLiveTraffic: null, loadingBlockedIPs: false, scanRunning: false, basePageName: '', pendingChanges: {}, scanStalled: false, siteCleaningIssueTypes: ['file', 'checkGSB', 'checkSpamIP', 'commentBadURL', 'knownfile', 'optionBadURL', 'postBadTitle', 'postBadURL', 'spamvertizeCheck', 'suspiciousAdminUsers'], //Screen sizes SCREEN_XS: 'xs', SCREEN_SM: 'sm', SCREEN_MD: 'md', SCREEN_LG: 'lg', init: function() { this.isSmallScreen = window.matchMedia("only screen and (max-width: 500px)").matches; this.nonce = WordfenceAdminVars.firstNonce; this.debugOn = WordfenceAdminVars.debugOn == '1' ? true : false; this.scanRunning = WordfenceAdminVars.scanRunning == '1' ? true : false; this.basePageName = document.title; var startTicker = false; var self = this; $(window).on('blur', function() { self._windowHasFocus = false; }).on('focus', function() { self._windowHasFocus = true; }).focus(); $('.do-show').click(function() { var $this = $(this); $this.hide(); $($this.data('selector')).show(); return false; }); $('.downloadLogFile').each(function() { $(this).attr('href', WordfenceAdminVars.ajaxURL + '?action=wordfence_downloadLogFile&nonce=' + WFAD.nonce + '&logfile=' + encodeURIComponent($(this).data('logfile'))); }); $('#doSendEmail').click(function() { var ticket = $('#_ticketnumber').val(); if (ticket === null || typeof ticket === "undefined" || ticket.length == 0) { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Error"), __("Please include your support ticket number or forum username.")); return; } WFAD.ajax('wordfence_sendDiagnostic', {email: $('#_email').val(), ticket: ticket}, function(res) { if (res.result) { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Email Diagnostic Report"), __("Diagnostic report has been sent successfully.")); } else { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Error"), __("There was an error while sending the email.")); } }); }); $('#exportDiagnostics').click(function() { self.showLoading(); var diagnosticsExportWindow = window.open(WordfenceAdminVars.ajaxURL + '?action=wordfence_exportDiagnostics&nonce=' + WFAD.nonce); diagnosticsExportWindow.onbeforeunload = function() { self.removeLoading(); }; return false; }); $('#sendByEmail').click(function() { $('#sendByEmailForm').removeClass('hidden'); $(this).hide(); }); $('#expandAllDiagnostics').click(function() { $('#wf-diagnostics').find('.wf-block').each(function() { var el = $(this); if (!el.hasClass('wf-active')) { el.find('.wf-block-header').trigger('click'); } }) }); $(window).bind("scroll", function() { $(this).scrollTop() > 200 ? $(".wf-scrollTop").fadeIn() : $(".wf-scrollTop").fadeOut() }); $(".wf-scrollTop").click(function(e) { return e.stopPropagation(), $("body,html").animate({ scrollTop: 0 }, 800), !1; }); var tabs = jQuery('.wf-page-tabs').find('.wf-tab a'); if (tabs.length > 0) { tabs.click(function() { jQuery('.wf-page-tabs').find('.wf-tab').removeClass('wf-active').find('a').attr('aria-selected', 'false'); jQuery('.wf-tab-content').removeClass('wf-active'); var tab = jQuery(this).closest('.wf-tab'); tab.addClass('wf-active'); tab.find('a').attr('aria-selected', 'true'); var content = jQuery('#' + tab.data('target')); content.addClass('wf-active'); document.title = tab.data('pageTitle') + " \u2039 " + self.basePageName; self.sectionInit(); $(window).trigger('wfTabChange', [tab.data('target')]); }); if (window.location.hash) { var hashes = WFAD.parseHashes(); var hash = hashes[hashes.length - 1]; for (var i = 0; i < tabs.length; i++) { if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) { jQuery(tabs[i]).trigger('click'); } } } else { jQuery(tabs[0]).trigger('click'); } jQuery(window).on('hashchange', function () { var hashes = WFAD.parseHashes(); var hash = hashes[hashes.length - 1]; for (var i = 0; i < tabs.length; i++) { if (hash == jQuery(tabs[i]).closest('.wf-tab').data('target')) { jQuery(tabs[i]).trigger('click'); } } }); } else { this.sectionInit(); } if (this.mode) { jQuery(document).bind('cbox_closed', function() { self.colorboxIsOpen = false; self.colorboxServiceQueue(); }); } if ($('.wf-options-controls-spacer').length) { //The WP code doesn't move update nags and we need to $('.update-nag, #update-nag').insertAfter($('.wf-options-controls-spacer')); } $('.wf-block-header-action-disclosure').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).closest('.wf-block-header').trigger('click'); } }); $(this).closest('.wf-block-header').css('cursor', 'pointer'); $(this).closest('.wf-block-header').on('click', function(e) { // Let links in the header work. if (e.target && e.target.nodeName === 'A' && e.target.href) { return; } e.preventDefault(); e.stopPropagation(); if ($(this).closest('.wf-block').hasClass('wf-disabled')) { return; } var isActive = $(this).closest('.wf-block').hasClass('wf-active'); if (isActive) { //$(this).closest('.wf-block').removeClass('wf-active'); $(this).closest('.wf-block').find('.wf-block-content').slideUp({ always: function() { $(this).closest('.wf-block').removeClass('wf-active'); $(this).attr('aria-checked', 'false'); } }); } else { //$(this).closest('.wf-block').addClass('wf-active'); $(this).closest('.wf-block').find('.wf-block-content').slideDown({ always: function() { $(this).closest('.wf-block').addClass('wf-active'); $(this).attr('aria-checked', 'true'); } }); } WFAD.ajax('wordfence_saveDisclosureState', {name: $(this).closest('.wf-block').data('persistenceKey'), state: !isActive}, function() {}, function() {}, true); }); }); //On/Off Option $('.wf-option.wf-option-toggled .wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var optionElement = $(this).closest('.wf-option'); if (optionElement.hasClass('wf-option-premium') || optionElement.hasClass('wf-disabled')) { return; } var option = optionElement.data('option'); var value = false; var isActive = $(this).hasClass('wf-checked'); if (isActive) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); value = optionElement.data('disabledValue'); } else { $(this).addClass('wf-checked').attr('aria-checked', 'true'); value = optionElement.data('enabledValue'); } var originalValue = optionElement.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); $(this).parent().find('.wf-option-title').on('click', function(e) { var links = $(this).find('a'); var buffer = 10; for (var i = 0; i < links.length; i++) { var t = $(links[i]).offset().top; var l = $(links[i]).offset().left; var b = t + $(links[i]).height(); var r = l + $(links[i]).width(); if (e.pageX > l - buffer && e.pageX < r + buffer && e.pageY > t - buffer && e.pageY < b + buffer) { return; } } $(this).parent().find('.wf-option-checkbox').trigger('click'); }).css('cursor', 'pointer'); }); //On/Off Boolean Switch Option $('.wf-option.wf-option-toggled-boolean-switch .wf-boolean-switch').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); $(this).find('.wf-boolean-switch-handle').trigger('click'); }); $(this).find('.wf-boolean-switch-handle').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var optionElement = $(this).closest('.wf-option'); if (optionElement.hasClass('wf-option-premium') || optionElement.hasClass('wf-disabled')) { return; } var switchElement = $(this).closest('.wf-boolean-switch'); var option = optionElement.data('option'); var value = false; var isActive = switchElement.hasClass('wf-active'); if (isActive) { switchElement.removeClass('wf-active').attr('aria-checked', 'false'); value = optionElement.data('disabledValue'); } else { switchElement.addClass('wf-active').attr('aria-checked', 'true'); value = optionElement.data('enabledValue'); } var originalValue = optionElement.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); $(this).parent().find('.wf-option-title').on('click', function(e) { var links = $(this).find('a'); var buffer = 10; for (var i = 0; i < links.length; i++) { var t = $(links[i]).offset().top; var l = $(links[i]).offset().left; var b = t + $(links[i]).height(); var r = l + $(links[i]).width(); if (e.pageX > l - buffer && e.pageX < r + buffer && e.pageY > t - buffer && e.pageY < b + buffer) { return; } } $(this).parent().find('.wf-boolean-switch-handle').trigger('click'); }).css('cursor', 'pointer'); }); //On/Off Segmented Option $('.wf-option.wf-option-toggled-segmented [type=radio]').each(function() { $(this).on('click', function(e) { var optionElement = $(this).closest('.wf-option'); if (optionElement.hasClass('wf-option-premium') || optionElement.hasClass('wf-disabled')) { return; } var option = optionElement.data('option'); var value = this.value; var originalValue = optionElement.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); }); //On/Off Multiple Option $('.wf-option.wf-option-toggled-multiple .wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var optionElement = $(this).closest('.wf-option'); if (optionElement.hasClass('wf-option-premium') || optionElement.hasClass('wf-disabled')) { return; } var checkboxElement = $(this).closest('ul'); var option = checkboxElement.data('option'); var value = false; var isActive = $(this).hasClass('wf-checked'); if (isActive) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); value = checkboxElement.data('disabledValue'); } else { $(this).addClass('wf-checked').attr('aria-checked', 'true'); value = checkboxElement.data('enabledValue'); } var originalValue = checkboxElement.data('originalValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); }); //On/Off Option with menu and Option with menu $('.wf-option.wf-option-toggled-select .wf-option-checkbox').each(function() { $(this).on('keydown', function(e) { if (e.keyCode == 32) { e.preventDefault(); e.stopPropagation(); $(this).trigger('click'); } }); $(this).on('click', function(e) { e.preventDefault(); e.stopPropagation(); var optionElement = $(this).closest('.wf-option'); if (optionElement.hasClass('wf-option-premium') || optionElement.hasClass('wf-disabled')) { return; } var selectElement = optionElement.find('.wf-option-select select'); var option = optionElement.data('toggleOption'); var value = false; var isActive = $(this).hasClass('wf-checked'); if (isActive) { $(this).removeClass('wf-checked').attr('aria-checked', 'false'); selectElement.attr('disabled', true); value = optionElement.data('disabledToggleValue'); } else { $(this).addClass('wf-checked').attr('aria-checked', 'true'); selectElement.attr('disabled', false); value = optionElement.data('enabledToggleValue'); } var originalValue = optionElement.data('originalToggleValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); $(this).parent().find('.wf-option-title').on('click', function(e) { var links = $(this).find('a'); var buffer = 10; for (var i = 0; i < links.length; i++) { var t = $(links[i]).offset().top; var l = $(links[i]).offset().left; var b = t + $(links[i]).height(); var r = l + $(links[i]).width(); if (e.pageX > l - buffer && e.pageX < r + buffer && e.pageY > t - buffer && e.pageY < b + buffer) { return; } } $(this).closest('.wf-option').find('.wf-option-checkbox').trigger('click'); }).css('cursor', 'pointer'); }); $('.wf-option.wf-option-toggled-select > .wf-option-content > ul > li.wf-option-select select, .wf-option.wf-option-select > .wf-option-content > ul > li.wf-option-select select, .wf-option.wf-option-select > li.wf-option-select select').each(function() { if (!$.fn.wfselect2) { return; } var width = WFAD.isSmallScreen ? '200px' : 'resolve'; if ($(this).data('preferredWidth')) { width = $(this).data('preferredWidth'); } $(this).wfselect2({ minimumResultsForSearch: -1, width: width }).on('change', function () { var optionElement = $(this).closest('.wf-option'); var option = optionElement.data('selectOption'); var value = $(this).val(); var originalValue = optionElement.data('originalSelectValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }); }).triggerHandler('change'); //Text field option $('.wf-option.wf-option-text > .wf-option-content > ul > li.wf-option-text input').on('change paste keyup', function() { var e = this; setTimeout(function() { var optionElement = $(e).closest('.wf-option'); var option = optionElement.data('textOption'); if (typeof option !== 'undefined') { var value = $(e).val(); var originalValue = optionElement.data('originalTextValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); } }, 4); }); //Text area option $('.wf-option.wf-option-textarea > .wf-option-content > ul > li.wf-option-textarea textarea').on('change paste keyup', function() { var e = this; setTimeout(function() { var optionElement = $(e).closest('.wf-option'); var option = optionElement.data('textOption'); var value = $(e).val(); var originalValue = optionElement.data('originalTextValue'); if (originalValue == value) { delete WFAD.pendingChanges[option]; } else { WFAD.pendingChanges[option] = value; } $(optionElement).trigger('change', [false]); WFAD.updatePendingChanges(); }, 4); }); //Value entry token option if ($.fn.wfselect2) { $('.wf-option.wf-option-token select').wfselect2({ tags: true, tokenSeparators: [','], width: 'element', minimumResultsForSearch: -1, selectOnClose: true, matcher: function(params, data) { return null; } }).on('wfselect2:unselect', function(e){ jQuery(e.params.data.element).remove(); }).on('wfselect2:opening wfselect2:close', function(e){ $('body').toggleClass('wf-select2-suppress-dropdown', e.type == 'wfselect2:opening'); }).on('change', function () { var optionElement = $(this).closest('.wf-option'); var option = optionElement.data('tokenOption'); var value = $(this).val(); if (!(value instanceof Array)) { value = []; } var selected = $(this).find('option:selected'); var tagsElement = optionElement.find('.wf-option-token-tags'); var list = $('" + body + "
", settings]); this.colorboxServiceQueue(); }, colorboxModalHTML: function(width, heading, body, settings) { if (typeof settings === 'undefined') { settings = {}; } var prompt = $.tmpl(WordfenceAdminVars.modalHTMLTemplate, {title: heading, message: body}); var promptHTML = $("").append(prompt).html(); var callback = settings.onComplete; settings.overlayClose = false; settings.closeButton = false; settings.className = 'wf-modal'; settings.onComplete = function() { $('#wf-generic-modal-close').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.colorboxClose(); }); typeof callback === 'function' && callback(); }; this.colorboxHTML(width, promptHTML, settings) }, colorboxModal: function(width, heading, body, settings) { if (typeof settings === 'undefined') { settings = {}; } var prompt = $.tmpl(WordfenceAdminVars.modalTemplate, {title: heading, message: body}); var promptHTML = $("").append(prompt).html(); var callback = settings.onComplete; settings.overlayClose = false; settings.closeButton = false; settings.className = 'wf-modal'; settings.onComplete = function() { $('#wf-generic-modal-close').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.colorboxClose(); }); typeof callback === 'function' && callback(); }; this.colorboxHTML(width, promptHTML, settings) }, colorboxError: function(errorMsg, isTokenError) { var callback = false; if (isTokenError) { if (WFAD.tokenErrorShowing) { return; } callback = function() { setTimeout(function() { WFAD.tokenErrorShowing = false; }, 30000); }; WFAD.tokenErrorShowing = true; } var prompt = $.tmpl(WordfenceAdminVars.tokenInvalidTemplate, {title: __('An error occurred'), message: errorMsg}); var promptHTML = $("").append(prompt).html(); var settings = {}; settings.overlayClose = false; settings.closeButton = false; settings.className = 'wf-modal'; settings.onComplete = function() { $('#wf-token-invalid-modal-reload').on('click', function(e) { e.preventDefault(); e.stopPropagation(); window.location.reload(true); }); typeof callback === 'function' && callback(); }; WFAD.colorboxHTML((WFAD.isSmallScreen ? '300px' : '400px'), promptHTML, settings); }, colorboxHTML: function(width, html, settings) { if (typeof settings === 'undefined') { settings = {}; } this.colorboxQueue.push([width, html, settings]); this.colorboxServiceQueue(); }, colorboxServiceQueue: function() { if (this.colorboxIsOpen) { return; } if (this.colorboxQueue.length < 1) { return; } var elem = this.colorboxQueue.shift(); this.colorboxOpen(elem[0], elem[1], elem[2]); }, colorboxOpen: function(width, html, settings) { var self = this; this.colorboxIsOpen = true; jQuery.extend(settings, { width: width, html: html, onClosed: function() { self.colorboxClose(); } }); jQuery.wfcolorbox(settings); }, colorboxClose: function() { this.colorboxIsOpen = false; jQuery.wfcolorbox.close(); }, bulkOperationConfirmed: function(op) { WFAD.colorboxClose(); this.ajax('wordfence_bulkOperation', { op: op }, function(res) { if (res.ok) { for (var i = 0; i < res.idsRemoved.length; i++) { $('.wf-issue[data-issue-id="' + res.idsRemoved[i] + '"]').remove(); } WFAD.updateIssueCounts(res.issueCounts); WFAD.repositionSiteCleaningCallout(); WFAD.updateBulkButtons(); setTimeout(function() { WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), res.bulkHeading, res.bulkBody); }, 500); } }); }, deleteFile: function(issueID, force, callback) { this.ajax('wordfence_deleteFile', { issueID: issueID, forceDelete: force }, function(res) { if (res.needsCredentials) { document.location.href = res.redirect; } else { typeof callback === 'function' && callback(res); } }); }, promptToRepairFile: function(issueID, file) { if (window.localStorage) { var sudoExpiration = window.localStorage.getItem('wf-repair-file-sudo'); if (sudoExpiration && parseInt(sudoExpiration, 10) > new Date().getTime()) { this.repairFile(issueID); return; } } WFAD.colorboxModalHTML((WFAD.isSmallScreen ? '300px' : '400px'), __("Download Backup File"), __('Please make a backup of this file before proceeding. If you need to restore this backup file, you can copy it to the following path from your site\'s root:') + '' + file + '
' + '' + '' + '
' + '' ); }, promptToRepairFileDone: function(issueID, dontPromptAgain) { if (dontPromptAgain) { if (window.localStorage) { window.localStorage.setItem('wf-repair-file-sudo', (new Date().getTime() + 86400000)); } } this.repairFile(issueID); }, repairFile: function(issueID) { var self = this; self.colorboxClose(); this.restoreFile(issueID, function(res) { if (res.ok) { var issueElement = $('.wf-issue[data-issue-id=' + parseInt(issueID, 10) + ']'); issueElement.remove(); self.updateIssueCounts(res.issueCounts); self.repositionSiteCleaningCallout(); self.updateBulkButtons(); self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success restoring file"), sprintf(__("The file %s was successfully restored."), res.file)); } else if (res.errorMsg) { self.colorboxError(res.errorMsg, res.tokenInvalid); } }); }, deleteDatabaseOption: function(issueID) { var self = this; this.ajax('wordfence_deleteDatabaseOption', { issueID: issueID }, function(res) { self.doneDeleteDatabaseOption(res); }); }, doneDeleteDatabaseOption: function(res) { var cb = false; var self = this; if (res.ok) { this.loadIssues(function() { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success removing option"), sprintf(__("The option %s was successfully removed."), res.option_name)); }); } else if (res.cerrorMsg) { this.loadIssues(function() { WFAD.colorboxError(res.cerrorMsg, res.tokenInvalid); }); } }, useRecommendedHowGetIPs: function(issueID) { var self = this; this.ajax('wordfence_misconfiguredHowGetIPsChoice', { issueID: issueID, choice: 'yes' }, function(res) { if (res.ok) { jQuery('#wordfenceMisconfiguredHowGetIPsNotice').fadeOut(); self.loadIssues(function() { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Success updating option"), __("The 'How does Wordfence get IPs' option was successfully updated to the recommended value.")); }); } else if (res.cerrorMsg) { self.loadIssues(function() { WFAD.colorboxError(res.cerrorMsg, res.tokenInvalid); }); } }); }, fixFPD: function(issueID) { var self = this; var title = __("Full Path Disclosure"); issueID = parseInt(issueID); this.ajax('wordfence_checkHtaccess', {}, function(res) { if (res.ok) { self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), title, __('We are about to change your .htaccess file. Please make a backup of this file before proceeding.') + '" + __('No activity to report yet. Please complete your first scan.') + "
"); } }); }, emailActivityLog: function() { this.colorboxModalHTML((this.isSmallScreen ? '300px' : '400px'), __('Email Wordfence Activity Log'), __("Enter the email address you would like to send the Wordfence activity log to. Note that the activity log may contain thousands of lines of data. This log is usually only sent to a member of the Wordfence support team. It also contains your PHP configuration from the phpinfo() function for diagnostic data.") + "" + sprintf(__("Use one of these %s codes to log in if you lose access to your authenticator device. Codes are 16 characters long, plus optional spaces. Each one may be used only once."), res.recoveryCodes.length) + "
" + __("This will be shown only once. Keep these codes somewhere safe.") + "
"; self.colorboxModalHTML((self.isSmallScreen ? '300px' : '440px'), __("Authentication Code"), message, {onComplete: function() { jQuery('#wfTwoFactorQRCodeTable').qrcode({text: totpURL, width: (self.isSmallScreen ? 175 : 256), height: (self.isSmallScreen ? 175 : 256)}); jQuery('#wfTwoFactorDownload').on('click', function(e) { e.preventDefault(); e.stopPropagation(); saveAs(new Blob([recoveryCodeFileContents], {type: "text/plain;charset=" + document.characterSet}), self.htmlEscape(res.homeurl) + "_" + self.htmlEscape(res.username) + "_recoverycodes.txt"); }); }}); } else { if (res.recoveryCodes.length > 0) { var message = "" + sprintf(__("Use one of these %s codes to log in if you are unable to access your phone. Codes are 16 characters long, plus optional spaces. Each one may be used only once."), res.recoveryCodes.length) + "
" + __("This will be shown only once. Keep these codes somewhere safe.") + "
"; self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __("Recovery Codes"), message, {onComplete: function() { jQuery('#wfTwoFactorDownload').on('click', function(e) { e.preventDefault(); e.stopPropagation(); saveAs(new Blob([recoveryCodeFileContents], {type: "text/plain;charset=" + document.characterSet}), self.htmlEscape(res.homeurl) + "_" + self.htmlEscape(res.username) + "_recoverycodes.txt"); }); }}); } } var updatedTwoFac = jQuery('#wfTwoFacUserTmpl').tmpl({users: [res]}); jQuery('#twoFactorUser-none').remove(); jQuery('#wfTwoFacUsers > table > tbody:last-child').append(updatedTwoFac.find('tbody > tr')); } }); }, twoFacActivate: function(userID, code) { var self = this; this.ajax('wordfence_twoFacActivate', { userID: userID, code: code }, function(res) { if (res.ok) { var updatedTwoFac = jQuery('#wfTwoFacUserTmpl').tmpl({users: [res]}); updatedTwoFac.find('tbody > tr').each(function(index, element) { jQuery('#' + jQuery(element).attr('id')).replaceWith(element); }); self.twoFacStatus(__('Cellphone Sign-in activated for user.')); } }); }, delTwoFac: function(userID) { this.ajax('wordfence_twoFacDel', { userID: userID }, function(res) { if (res.ok) { jQuery('#twoFactorUser-' + res.userID).fadeOut(function() { jQuery(this).remove(); if (jQuery('#wfTwoFacUsers > table > tbody:last-child').children().length == 0) { jQuery('#wfTwoFacUsers').html(jQuery('#wfTwoFacUserTmpl').tmpl({users: []})); } }); } }); }, loadTwoFactor: function() { this.ajax('wordfence_loadTwoFactor', {}, function(res) { jQuery('#wfTwoFacUsers').html(jQuery('#wfTwoFacUserTmpl').tmpl(res)); }); }, getQueryParam: function(name) { name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); var regexS = "[\\?&]" + name + "=([^]*)"; var regex = new RegExp(regexS); var results = regex.exec(window.location.search); if (results == null) { return ""; } else { return decodeURIComponent(results[1].replace(/\+/g, " ")); } }, inet_aton: function(dot) { var d = dot.split('.'); return ((((((+d[0]) * 256) + (+d[1])) * 256) + (+d[2])) * 256) + (+d[3]); }, inet_ntoa: function(num) { var d = num % 256; for (var i = 3; i > 0; i--) { num = Math.floor(num / 256); d = num % 256 + '.' + d; } return d; }, inet_pton: function(a) { // discuss at: http://phpjs.org/functions/inet_pton/ // original by: Theriault // example 1: inet_pton('::'); // returns 1: '\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0' // example 2: inet_pton('127.0.0.1'); // returns 2: '\x7F\x00\x00\x01' var r, m, x, i, j, f = String.fromCharCode; m = a.match(/^(?:\d{1,3}(?:\.|$)){4}/); // IPv4 if (m) { m = m[0].split('.'); m = f(m[0]) + f(m[1]) + f(m[2]) + f(m[3]); // Return if 4 bytes, otherwise false. return m.length === 4 ? m : false; } r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/i; m = a.match(r); // IPv6 if (m) { if (a == '::') { return "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; } var colonCount = a.split(':').length - 1; var doubleColonPos = a.indexOf('::'); if (doubleColonPos > -1) { var expansionLength = ((doubleColonPos == 0 || doubleColonPos == a.length - 2) ? 9 : 8) - colonCount; var expansion = ''; for (i = 0; i < expansionLength; i++) { expansion += ':0000'; } a = a.replace('::', expansion + ':'); a = a.replace(/(?:^\:|\:$)/, '', a); } var ipGroups = a.split(':'); var ipBin = ''; for (i = 0; i < ipGroups.length; i++) { var group = ipGroups[i]; if (group.length > 4) { return false; } group = ("0000" + group).slice(-4); var b1 = parseInt(group.slice(0, 2), 16); var b2 = parseInt(group.slice(-2), 16); if (isNaN(b1) || isNaN(b2)) { return false; } ipBin += f(b1) + f(b2); } return ipBin.length == 16 ? ipBin : false; } return false; // Invalid IP. }, inet_ntop: function(a) { // discuss at: http://phpjs.org/functions/inet_ntop/ // original by: Theriault // example 1: inet_ntop('\x7F\x00\x00\x01'); // returns 1: '127.0.0.1' // example 2: inet_ntop('\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1'); // returns 2: '::1' var i = 0, m = '', c = []; a += ''; if (a.length === 4) { // IPv4 return [ a.charCodeAt(0), a.charCodeAt(1), a.charCodeAt(2), a.charCodeAt(3)].join('.'); } else if (a.length === 16) { // IPv6 for (i = 0; i < 16; i++) { c.push(((a.charCodeAt(i++) << 8) + a.charCodeAt(i)) .toString(16)); } return c.join(':') .replace(/((^|:)0(?=:|$))+:?/g, function(t) { m = (t.length > m.length) ? t : m; return t; }) .replace(m || ' ', '::'); } else { // Invalid length return false; } }, deleteAdminUser: function(issueID) { var self = this; this.ajax('wordfence_deleteAdminUser', { issueID: issueID }, function(res) { if (res.ok) { self.loadIssues(function() { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Successfully deleted admin"), sprintf(__("The admin user %s was successfully deleted."), res.user_login)); }); } else if (res.errorMsg) { self.loadIssues(function() { WFAD.colorboxError(res.errorMsg, res.tokenInvalid); }); } }); }, revokeAdminUser: function(issueID) { var self = this; this.ajax('wordfence_revokeAdminUser', { issueID: issueID }, function(res) { if (res.ok) { self.loadIssues(function() { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __("Successfully revoked admin"), sprintf(__("All capabilties of admin user %s were successfully revoked."), res.user_login)); }); } else if (res.errorMsg) { self.loadIssues(function() { WFAD.colorboxError(res.errorMsg, res.tokenInvalid); }); } }); }, windowHasFocus: function() { if (typeof document.hasFocus === 'function') { return document.hasFocus(); } // Older versions of Opera return this._windowHasFocus; }, htmlEscape: function(html) { return String(html) .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') .replace(//g, '>'); }, permanentlyBlockAllIPs: function(type) { var self = this; this.ajax('wordfence_permanentlyBlockAllIPs', { type: type }, function(res) { $('#wfTabs').find('.wfTab1').eq(0).trigger('click'); }); }, showTimestamp: function(timestamp, serverTime, format) { serverTime = serverTime === undefined ? new Date().getTime() / 1000 : serverTime; format = format === undefined ? '${dateTime} (${timeAgo} ago)' : format; var date = new Date(timestamp * 1000); return jQuery.tmpl(format, { dateTime: date.toLocaleDateString() + ' ' + date.toLocaleTimeString(), timeAgo: this.makeTimeAgo(serverTime - timestamp) }); }, updateTimeAgo: function() { var self = this; jQuery('.wfTimeAgo-timestamp').each(function(idx, elem) { var el = jQuery(elem); var testEl = el; if (typeof jQuery === "function" && testEl instanceof jQuery) { testEl = testEl[0]; } var rect = testEl.getBoundingClientRect(); if (!(rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth))) { return; } var timestamp = el.data('wfctime'); if (!timestamp) { timestamp = el.attr('data-timestamp'); } var serverTime = self.serverMicrotime; var format = el.data('wfformat'); if (!format) { format = el.attr('data-format'); } el.html(self.showTimestamp(timestamp, serverTime, format)); }); }, wafData: { whitelistedURLParams: [] }, restoreWAFData: { whitelistedURLParams: [] }, wafWhitelistedBulkChangeEnabled: function(enabled) { $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox.wf-checked').each(function() { $(this).closest('tr').find('.wf-whitelist-item-enabled.wf-option-checkbox').each(function() { if (($(this).hasClass('wf-checked') && !enabled) || (!$(this).hasClass('wf-checked') && enabled)) { var tr = $(this).closest('tr'); if (tr.is(':visible')) { WFAD.wafWhitelistedChangeEnabled(tr.data('key'), enabled); } } }); }) }, wafWhitelistedChangeEnabled: function(key, enabled) { $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-key="' + key + '"]').each(function() { var adding = !!$(this).data('adding'); if (adding) { WFAD.pendingChanges['whitelistedURLParams']['add'][key]['data']['disabled'] = !enabled ? 1 : 0; } else { if (!(WFAD.pendingChanges['whitelistedURLParams'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams'] = {}; } if (!(WFAD.pendingChanges['whitelistedURLParams']['enabled'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams']['enabled'] = {}; } WFAD.pendingChanges['whitelistedURLParams']['enabled'][key] = !!enabled ? 1 : 0; } $(this).find('.wf-whitelist-item-enabled.wf-option-checkbox').toggleClass('wf-checked', !!enabled); }); }, wafWhitelistedBulkDelete: function() { $('.wf-whitelist-table-bulk-checkbox.wf-option-checkbox.wf-checked').each(function() { $(this).closest('tr').find('.wf-whitelist-item-enabled.wf-option-checkbox').each(function() { var tr = $(this).closest('tr'); if (tr.is(':visible')) { WFAD.wafWhitelistedDelete(tr.data('key')); } }); }); }, wafWhitelistedDelete: function(key) { $('#waf-whitelisted-urls-wrapper .whitelist-table > tbody > tr[data-key="' + key + '"]').each(function() { var adding = !!$(this).data('adding'); if (adding) { delete WFAD.pendingChanges['whitelistedURLParams']['add'][key]; } else { if (!(WFAD.pendingChanges['whitelistedURLParams'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams'] = {}; } if (!(WFAD.pendingChanges['whitelistedURLParams']['delete'] instanceof Object)) { WFAD.pendingChanges['whitelistedURLParams']['delete'] = {}; } WFAD.pendingChanges['whitelistedURLParams']['delete'][key] = 1; } for (var i = 0; i < WFAD.wafData.whitelistedURLParams.length; i++) { var testKey = WFAD.wafData.whitelistedURLParams[i].path + '|' + WFAD.wafData.whitelistedURLParams[i].paramKey; if (testKey == key) { WFAD.wafData.whitelistedURLParams.splice(i, 1); break; } } }); }, wafConfigPageRender: function() { WFAD.wafData.ruleCount = 0; if (WFAD.wafData.rules) { WFAD.wafData.ruleCount = Object.keys(WFAD.wafData.rules).length; } var whitelistedIPsEl = $('#waf-whitelisted-urls-tmpl').tmpl(WFAD.wafData); $('#waf-whitelisted-urls-wrapper').html(whitelistedIPsEl); var rulesEl = $('#waf-rules-tmpl').tmpl(WFAD.wafData); $('#waf-rules-wrapper').html(rulesEl); $('#waf-show-all-rules-button').on('click', function(e) { e.preventDefault(); e.stopPropagation(); $('#waf-rules-wrapper').addClass('wf-show-all'); }); if (WFAD.wafData['rulesLastUpdated']) { var date = new Date(WFAD.wafData['rulesLastUpdated'] * 1000); WFAD.renderWAFRulesLastUpdated(date); } $(window).trigger('wordfenceWAFConfigPageRender'); }, renderWAFRulesLastUpdated: function(date) { var dateString = date.toString(); if (date.toLocaleString) { dateString = date.toLocaleString(); } $('#waf-rules-last-updated').text(sprintf(__('Last Updated: %s'), dateString)) .css({ 'opacity': 0 }) .animate({ 'opacity': 1 }, 500); }, renderWAFRulesNextUpdate: function(date) { var dateString = date.toString(); if (date.toLocaleString) { dateString = date.toLocaleString(); } $('#waf-rules-next-update').text(sprintf(__('Next Update Check: %s'), dateString)) .css({ 'opacity': 0 }) .animate({ 'opacity': 1 }, 500); }, wafUpdateRules: function(onSuccess) { var self = this; this.ajax('wordfence_updateWAFRules', {}, function(res) { self.wafData = res; self.restoreWAFData.rules = res.rules; self.restoreWAFData.rulesLastUpdated = res.rulesLastUpdated; self.wafConfigPageRender(); if (self.wafData['updated']) { if (!self.wafData['isPaid']) { self.colorboxModalHTML((self.isSmallScreen ? '300px' : '400px'), __('Rules Updated'), __('Your rules have been updated successfully. You are currently using the free version of Wordfence. Upgrade to Wordfence premium to have your rules updated automatically as new threats emerge. Click here to purchase a premium license. Note: Your rules will still update every 30 days as a free user.')); } else { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rules Updated'), __('Your rules have been updated successfully.')); } } else { if (self.wafData['failure'] == 'ratelimit') { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Your website has reached the maximum number of rule update requests. Please try again later.')); } else if (self.wafData['failure'] == 'unreachable') { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Please verify your website can reach the Wordfence servers.')); } else { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Rule Update Failed'), __('No rules were updated. Please verify you have permissions to write to the /wp-content/wflogs directory.')); } } if (typeof onSuccess === 'function') { return onSuccess.apply(this, arguments); } }); }, dateFormat: function(date) { if (date instanceof Date) { if (date.toLocaleString) { return date.toLocaleString(); } return date.toString(); } return date; }, confirmWAFConfigureAutoPrepend: function() { var self = this; this.ajax('wordfence_wafConfigureAutoPrepend', {}, function(res) { self.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('.htaccess Updated'), __("Your .htaccess has been updated successfully. Please verify your site is functioning normally.")); }); }, updatePendingChanges: function() { $(window).off('beforeunload', WFAD._unsavedOptionsHandler); if (Object.keys(WFAD.pendingChanges).length) { $('#wf-cancel-changes').removeClass('wf-disabled'); $('#wf-save-changes').removeClass('wf-disabled'); $(window).on('beforeunload', WFAD._unsavedOptionsHandler); } else { $('#wf-cancel-changes').addClass('wf-disabled'); $('#wf-save-changes').addClass('wf-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 = e || window.event; if (e) { e.returnValue = message; //IE and Firefox } return message; //Others }, setOption: function(key, value, successCallback, failureCallback) { var changes = {}; changes[key] = value; this.ajax('wordfence_saveOptions', {changes: JSON.stringify(changes), page: WFAD.getParameterByName('page')}, function(res) { if (res.success) { typeof successCallback == 'function' && successCallback(res); } else { WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Saving Option'), res.error); typeof failureCallback == 'function' && failureCallback(res); } }); }, saveOptions: function(successCallback, failureCallback) { if (!Object.keys(WFAD.pendingChanges).length) { return; } var self = this; this.ajax('wordfence_saveOptions', {changes: JSON.stringify(WFAD.pendingChanges), page: WFAD.getParameterByName('page')}, function(res) { if (res.success) { typeof successCallback == 'function' && successCallback(res); } else { WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Saving Options'), res.error); typeof failureCallback == 'function' && failureCallback } }); }, enableAllOptionsPage: function() { this.ajax('wordfence_enableAllOptionsPage', {}, function(res) { if (res.redirect) { window.location.href = res.redirect; } else { WFAD.colorboxModal((self.isSmallScreen ? '300px' : '400px'), __('Error Enabling All Options Page'), res.error); } }); }, getParameterByName: function(name, url) { if (!url) url = window.location.href; name = name.replace(/[\[\]]/g, "\\$&"); var regex = new RegExp("[?&]" + name + "(=([^]*)|&|#|$)"), results = regex.exec(url); if (!results) return null; if (!results[2]) return ''; return decodeURIComponent(results[2].replace(/\+/g, " ")); }, base64_decode: function(s) { var e = {}, i, b = 0, c, x, l = 0, a, r = '', w = String.fromCharCode, L = s.length; var A = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; for (i = 0; i < 64; i++) { e[A.charAt(i)] = i; } for (x = 0; x < L; x++) { c = e[s.charAt(x)]; b = (b << 6) + c; l += 6; while (l >= 8) { ((a = (b >>> (l -= 8)) & 0xff) || (x < (L - 2))) && (r += w(a)); } } return r; }, base64_encode: function (input) { var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var output = ""; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; while (i < input.length) { chr1 = input.charCodeAt(i++); chr2 = input.charCodeAt(i++); chr3 = input.charCodeAt(i++); enc1 = chr1 >> 2; enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64; } else if (isNaN(chr3)) { enc4 = 64; } output = output + chars.charAt(enc1) + chars.charAt(enc2) + chars.charAt(enc3) + chars.charAt(enc4); } return output; } }; window['WFAD'] = window['wordfenceAdmin']; setInterval(function() { WFAD.updateTimeAgo(); }, 1000); } __ = window.wfi18n.__; sprintf = window.wfi18n.sprintf; jQuery(function() { wordfenceAdmin.init(); jQuery(window).on('focus', function() { if (jQuery('body').hasClass('wordfenceLiveActivityPaused')) { jQuery('body').removeClass('wordfenceLiveActivityPaused'); } }); }); $(function() { $('#wf-mobile-controls').on('click', function(e) { e.preventDefault(); e.stopPropagation(); $.wfMobileMenu({ menuItems: [ {title: __('Save Changes'), primary: true, disabled: $('#wf-save-changes').hasClass('wf-disabled'), action: function() { $('#wf-save-changes').trigger('click'); }}, {title: __('Cancel Changes'), primary: false, disabled: $('#wf-cancel-changes').hasClass('wf-disabled'), action: function() { $('#wf-cancel-changes').trigger('click'); }}, {title: __('Restore Defaults'), primary: false, disabled: $('#wf-restore-defaults').hasClass('wf-disabled'), action: function() { $('#wf-restore-defaults').trigger('click'); }} ] }); }); $('#wf-restore-defaults').on('click', function(e) { e.preventDefault(); e.stopPropagation(); var restoreDefaultsSection = $(this).data('restoreDefaultsSection'); var prompt = $('#wfTmpl_restoreDefaultsPrompt').tmpl(); var promptHTML = $("").append(prompt).html(); WFAD.colorboxHTML((WFAD.isSmallScreen ? '300px' : '400px'), promptHTML, {overlayClose: false, closeButton: false, className: 'wf-modal', onComplete: function() { $('#wf-restore-defaults-prompt-cancel').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.colorboxClose(); }); $('#wf-restore-defaults-prompt-confirm').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.ajax('wordfence_restoreDefaults', {section: restoreDefaultsSection}, function(res) { if (res.success) { window.location.reload(true); } else { WFAD.colorboxClose(); WFAD.colorboxModal((WFAD.isSmallScreen ? '300px' : '400px'), __('Error Restoring Defaults'), res.error); } }); }); }}); }); $('#wf-save-changes').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.saveOptions(function(res) { WFAD.pendingChanges = {}; WFAD.updatePendingChanges(); if (res.redirect) { window.location.href = res.redirect; } else { window.location.reload(true); } }); }); $('#wf-cancel-changes').on('click', function(e) { e.preventDefault(); e.stopPropagation(); WFAD.pendingChanges = {}; WFAD.updatePendingChanges(); //On/Off options $('.wf-option.wf-option-toggled').each(function() { var enabledValue = $(this).data('enabledValue'); var disabledValue = $(this).data('disabledValue'); var originalValue = $(this).data('originalValue'); if (enabledValue == originalValue) { $(this).find('.wf-option-checkbox').addClass('wf-checked').attr('aria-checked', 'true'); } else { $(this).find('.wf-option-checkbox').removeClass('wf-checked').attr('aria-checked', 'false'); } $(this).trigger('change', [true]); }); $('.wf-option-toggled-boolean-switch').each(function() { var enabledValue = $(this).data('enabledValue'); var disabledValue = $(this).data('disabledValue'); var originalValue = $(this).data('originalValue'); if (enabledValue == originalValue) { $(this).find('.wf-boolean-switch').addClass('wf-active').attr('aria-checked', 'true'); } else { $(this).find('.wf-boolean-switch').removeClass('wf-active').attr('aria-checked', 'false'); } $(this).trigger('change', [true]); }); $('.wf-option.wf-option-toggled-segmented').each(function() { var originalValue = $(this).data('originalValue'); $(this).find('[type=radio]').each(function() { if (this.value == originalValue) { this.checked = true; return false; } }); $(this).trigger('change', [true]); }); //On/Off multiple options $('.wf-option.wf-option-toggled-multiple').each(function() { $(this).find('.wf-option-checkboxes > ul').each(function() { var enabledValue = $(this).data('enabledValue'); var disabledValue = $(this).data('disabledValue'); var originalValue = $(this).data('originalValue'); if (enabledValue == originalValue) { $(this).find('.wf-option-checkbox').addClass('wf-checked').attr('aria-checked', 'true'); } else { $(this).find('.wf-option-checkbox').removeClass('wf-checked').attr('aria-checked', 'false'); } }); $(this).trigger('change', [true]); }); //On/Off options with menu $('.wf-option.wf-option-toggled-select').each(function() { var selectElement = $(this).find('.wf-option-select select'); var enabledToggleValue = $(this).data('enabledToggleValue'); var disabledToggleValue = $(this).data('disabledToggleValue'); var originalToggleValue = $(this).data('originalToggleValue'); if (enabledToggleValue == originalToggleValue) { $(this).find('.wf-option-checkbox').addClass('wf-checked').attr('aria-checked', 'true'); selectElement.attr('disabled', false); } else { $(this).find('.wf-option-checkbox').removeClass('wf-checked').attr('aria-checked', 'false'); selectElement.attr('disabled', true); } var originalSelectValue = $(this).data('originalSelectValue'); $(this).find('.wf-option-select select').val(originalSelectValue).trigger('change'); $(this).trigger('change', [true]); }); //Menu options $('.wf-option.wf-option-select').each(function() { var originalSelectValue = $(this).data('originalSelectValue'); $(this).find('.wf-option-select select').val(originalSelectValue).trigger('change'); $(this).trigger('change', [true]); }); //Text options $('.wf-option.wf-option-text').each(function() { var originalTextValue = $(this).data('originalTextValue'); if (typeof originalTextValue !== 'undefined') { $(this).find('.wf-option-text input').val(originalTextValue); } $(this).trigger('change', [true]); }); //Text area options $('.wf-option.wf-option-textarea').each(function() { var originalTextValue = $(this).data('originalTextValue'); $(this).find('.wf-option-textarea textarea').val(originalTextValue); $(this).trigger('change', [true]); }); //Token options $('.wf-option.wf-option-token').each(function() { var originalTokenValue = $(this).data('originalTokenValue'); $(this).find('select').val(originalTokenValue).trigger('change'); $(this).trigger('change', [true]); }); //Switch options $('.wf-option.wf-option-switch').each(function() { var originalValue = $(this).data('originalValue'); $(this).find('.wf-switch > li').each(function() { $(this).toggleClass('wf-active', originalValue == $(this).data('optionValue')).attr('aria-checked', originalValue == $(this).data('optionValue') ? 'true' : 'false'); }); $(this).trigger('change', [true]); }); //Other options $(window).trigger('wfOptionsReset'); }); var select2s = $('.wf-select2'); if (select2s.length && $.fn.wfselect2) { select2s.wfselect2({ minimumResultsForSearch: 5 }); } if ($.fn.tooltip) { $('.wf-status-circular').each(function() { var circle = $(this); var tmplID = 'tooltip-' + this.id + '-tmpl'; var circleTmpl = $('#' + tmplID); if (circleTmpl.length) { circle.tooltip({ tooltipClass: "wf-circle-tooltip", position: { my: "left-40 bottom", at: "center top", using: function(obj, info) { var el = $(this); el.removeClass('wf-tooltip-vertical-top wf-tooltip-vertical-bottom ' + 'wf-tooltip-horizontal-left wf-tooltip-horizontal-right') .addClass('wf-tooltip-vertical-' + info.vertical) .addClass('wf-tooltip-horizontal-' + info.horizontal); $(this).css({ left: obj.left + 'px', top: obj.top + 'px' }); } }, items: this, close: function (event, ui) { ui.tooltip.hover( function () { $(this).stop(true).fadeTo(400, 1); }, function () { $(this).fadeOut("400", function () { $(this).remove(); }) }); }, content: function() { var circleClone = $(this).clone(); circleClone.find('svg, .wf-status-circular-text').css('opacity', 1.0); var circleHTML = $(circleClone).html(); return circleTmpl.tmpl({ statusCircle: circleHTML }); } }) // .tooltip('open'); } }); } }); })(jQuery); //wfCircularProgress jQuery.fn.wfCircularProgress = function(options) { var __ = window.wfi18n.__; var sprintf = window.wfi18n.sprintf; jQuery(this).each(function() { var creationOptions; try { creationOptions = JSON.parse(jQuery(this).data('wfCircularProgressOptions')); } catch (e) { /* Ignore */ } if (typeof creationOptions !== 'object') { creationOptions = {}; } var opts = jQuery.extend({}, jQuery.fn.wfCircularProgress.defaults, creationOptions, options); var center = Math.floor(opts.diameter / 2); var insetRadius = center - opts.strokeWidth * 2; var circumference = 2 * insetRadius * Math.PI; var finalOffset = -(circumference * (1 - opts.endPercent)); var initialOffset = -(circumference); var terminatorRadius = Math.floor(opts.strokeWidth * 1.5); var terminatorDiameter = 2 * terminatorRadius; var finalTerminatorX = center - insetRadius * Math.cos(Math.PI * 2 * (opts.endPercent - 0.25)); var finalTerminatorY = center + insetRadius * Math.sin(Math.PI * 2 * (opts.endPercent - 0.25)); var initialTerminatorX = center - insetRadius * Math.cos(Math.PI * 2 * (opts.startPercent - 0.25)); var initialTerminatorY = center + insetRadius * Math.sin(Math.PI * 2 * (opts.startPercent - 0.25)); var terminatorSVG = "m 0,-" + terminatorRadius + " a " + terminatorRadius + "," + terminatorRadius + " 0 1 1 0," + terminatorDiameter + " a " + terminatorRadius + "," + terminatorRadius + " 0 1 1 0,-" + terminatorDiameter; jQuery(this).data('wfCircularProgressOptions', JSON.stringify(opts)); jQuery(this).css('width', opts.diameter + 'px'); jQuery(this).css('height', opts.diameter + 'px'); var svg = jQuery(this).find('svg'); if (svg.length == 0) { svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); jQuery(this).append(svg); } var inactivePath = jQuery(this).find('.wf-status-circular-inactive-path'); if (inactivePath.length == 0) { inactivePath = document.createElementNS("http://www.w3.org/2000/svg", "path"); jQuery(inactivePath).addClass('wf-status-circular-inactive-path'); jQuery(svg).append(inactivePath); } var activePath = jQuery(this).find('.wf-status-circular-active-path'); if (activePath.length == 0) { activePath = document.createElementNS("http://www.w3.org/2000/svg", "path"); jQuery(activePath).addClass('wf-status-circular-active-path'); jQuery(svg).append(activePath); } var terminator = jQuery(this).find('.wf-status-circular-terminator'); if (terminator.length == 0) { terminator = document.createElementNS("http://www.w3.org/2000/svg", "path"); jQuery(terminator).addClass('wf-status-circular-terminator'); jQuery(svg).append(terminator); } var text = jQuery(this).find('.wf-status-circular-text'); if (text.length == 0) { text = jQuery(''); jQuery(this).append(text); } var pendingOverlay = jQuery(this).find('.wf-status-overlay-text'); if (pendingOverlay.length == 0) { pendingOverlay = jQuery(''); jQuery(this).append(pendingOverlay); } jQuery(svg).attr('viewBox', '0 0 ' + opts.diameter + ' ' + opts.diameter); jQuery(svg).css('display', 'block'); jQuery(svg).css('width', opts.diameter + 'px'); jQuery(svg).css('height', opts.diameter + 'px'); jQuery(inactivePath).attr('d', 'M ' + center + ',' + center + ' m 0,-' + insetRadius + ' a ' + insetRadius + ',' +insetRadius + ' 0 1 1 0,' + (2 * insetRadius) + ' a ' + insetRadius + ',' + insetRadius + ' 0 1 1 0,-' + (2 * insetRadius)); jQuery(inactivePath).attr('stroke', opts.inactiveColor); jQuery(inactivePath).attr('stroke-width', opts.strokeWidth); jQuery(inactivePath).attr('fill-opacity', 0); jQuery(activePath).attr('d', 'M ' + center + ',' + center + ' m 0,-' + insetRadius + ' a ' + insetRadius + ',' + insetRadius + ' 0 1 1 0,' + (2 * insetRadius) + ' a ' + insetRadius + ',' + insetRadius + ' 0 1 1 0,-' + (2 * insetRadius)); jQuery(activePath).attr('stroke', opts.color); jQuery(activePath).attr('stroke-width', opts.strokeWidth); jQuery(activePath).attr('stroke-dasharray', circumference + ',' + circumference); jQuery(activePath).attr('stroke-dashoffset', initialOffset); jQuery(activePath).attr('fill-opacity', 0); jQuery(terminator).attr('d', 'M ' + initialTerminatorX + ',' + initialTerminatorY + ' ' + terminatorSVG); jQuery(terminator).attr('stroke', opts.color); jQuery(terminator).attr('stroke-width', opts.strokeWidth); jQuery(terminator).attr('fill', '#ffffff'); jQuery(pendingOverlay).html(opts.pendingMessage); jQuery(pendingOverlay).animate({ opacity: opts.pendingOverlay ? 1.0 : 0.0, }, { duration: 500, step: function(value) { var opacity = 1.0 - (value * 0.8); jQuery(svg).css('opacity', opacity); jQuery(text).css('opacity', opacity); }, complete: function() { jQuery(svg).css('opacity', opts.pendingOverlay ? 0.2 : 1.0); jQuery(text).css('opacity', opts.pendingOverlay ? 0.2 : 1.0); } }); jQuery(activePath).animate({ "stroke-dashoffset": finalOffset + 'px' }, { duration: 500, step: function(value) { var percentage = 1 + value / circumference; var x = center - insetRadius * Math.cos(Math.PI * 2 * (percentage - 0.25)); var y = center + insetRadius * Math.sin(Math.PI * 2 * (percentage - 0.25)); jQuery(terminator).attr('d', 'M ' + x + ',' + y + ' ' + terminatorSVG); text.html(Math.round(percentage * 100) + '%'); }, complete: function() { text.html(Math.round(opts.endPercent * 100) + '%'); } }); }); }; (function() { var __ = window.wfi18n.__; var sprintf = window.wfi18n.sprintf; jQuery.fn.wfCircularProgress.defaults = { startPercent: 0, endPercent: 1, color: '#16bc9b', inactiveColor: '#ececec', strokeWidth: 3, diameter: 100, pendingOverlay: false, pendingMessage: __('Note: Status will update when changes are saved'), }; })(); //wfDrawer (function ($, document, window) { var __ = window.wfi18n.__; var sprintf = window.wfi18n.sprintf; var defaults = { width: '600px', clickOverlayDismiss: false, content: false, onComplete: false, }; var publicMethod = $.fn['wfDrawer'] = $['wfDrawer'] = function (options) { var opts = $.extend({}, defaults, options); var overlay = $('').css('opacity', 0); if (opts.clickOverlayDismiss) { overlay.on('click', function(e) { e.preventDefault(); e.stopPropagation(); $.wfDrawer.close(); }); } $('body').append(overlay); var drawer = $('').css('width', opts.width).css('right', '-' + opts.width); if (opts.content) { drawer.append(opts.content); } $('body').append(drawer); overlay.animate({ "opacity": 1 }); drawer.animate({ "right": '0px' }, { complete: function() { typeof opts.onComplete === 'function' && opts.onComplete(); } }); }; publicMethod.close = function() { var overlay = $('.wf-drawer-overlay'); overlay.animate({ "opacity": 0 }, { complete: function() { overlay.remove(); } }); var drawer = $('.wf-drawer'); drawer.animate({ "right": '-' + drawer.css('width') }, { complete: function() { drawer.remove(); } }); }; }(jQuery, document, window)); //wfMobileMenu (function ($, document, window) { var __ = window.wfi18n.__; var sprintf = window.wfi18n.sprintf; var defaults = { width: '280px', clickOverlayDismiss: true, menuItems: [], onDismiss: false, }; var publicMethod = $.fn['wfMobileMenu'] = $['wfMobileMenu'] = function (options) { var opts = $.extend({}, defaults, options); var overlay = $('').css('opacity', 0); if (opts.clickOverlayDismiss) { overlay.on('click', function(e) { e.preventDefault(); e.stopPropagation(); typeof opts.onDismiss === 'function' && opts.onDismiss(false); $.wfMobileMenu.close(); }); } $('body').append(overlay); var menu = $(' ').css('width', opts.width).css('bottom', '-9999px'); var itemsWrapper = menu.find('.wf-mobile-menu-items'); for (var i = 0; i < opts.menuItems.length; i++) { var button = $('