Commit b9dbf07a authored by alain's avatar alain 🐙
Browse files

update plugins

parent fa69e04f
/***************************************
Tabs on the settings page
***************************************/
.wrap.ws-ame-too-many-tabs .ws-ame-nav-tab-list {
&.nav-tab-wrapper {
border-bottom-color: transparent;
}
.nav-tab {
border-bottom: 1px solid #c3c4c7;
margin-bottom: 10px;
margin-top: 0;
}
}
/* Spacing between the page heading and the tab list.
Normally, this is handled by .nav-tab styles, but WordPress changes the margins at smaller screen sizes
and the tabs end up without a left margin. Let's put that margin on the heading instead and remove it
from the first tab. */
#ws_ame_editor_heading {
margin-right: 0.305em;
}
.ws-ame-nav-tab-list {
a.nav-tab:first-of-type {
margin-left: 0;
}
}
/* When in "too many tabs" mode, there's too much space between the bottom of the tab list and the rest
of the page. I haven't found a good way to change the margins of just the last row, so here's a partial fix. */
.ws-ame-too-many-tabs #ws_actor_selector {
margin-top: 0;
}
\ No newline at end of file
......@@ -51,7 +51,8 @@ hr.ws-submenu-separator {
}
/* No colored bar/marker when hovering over a separator. */
#adminmenu li.ws-submenu-separator-wrap a:hover {
#adminmenu li.ws-submenu-separator-wrap a:hover,
#adminmenu li.ws-submenu-separator-wrap a:focus {
box-shadow: none;
}
......@@ -118,25 +119,3 @@ hr.ws-submenu-separator {
opacity: 1;
filter: alpha(opacity=100);
}
/*
* Third level menus.
*/
#adminmenu .ame-deep-submenu {
}
#adminmenu li.menu-top.opensub .ame-deep-submenu {
top: -1000em;
}
#adminmenu .wp-submenu li.opensub > ul.ame-deep-submenu {
top: -1px;
}
.folded #adminmenu li.opensub > ul.ame-deep-submenu,
.folded #adminmenu .wp-has-current-submenu.opensub > ul.ame-deep-submenu,
.no-js.folded #adminmenu .ame-has-deep-submenu:hover > ul.ame-deep-submenu {
top: 0;
left: 160px;
}
\ No newline at end of file
......@@ -740,7 +740,7 @@ a.ws_button.ws_button_disabled:hover {
width: 5px;
}
#ws_toggle_toolbar {
#ws_toggle_toolbar, .ws_toggle_toolbar_button {
margin-right: 0;
}
......@@ -1968,6 +1968,10 @@ $userSelectionPanelPadding: 10px;
vertical-align: bottom;
}
.ws_tooltip_trigger.ame-warning-tooltip {
color: orange;
}
.ws_wide_tooltip {
max-width: 450px;
}
......@@ -2257,3 +2261,5 @@ span.description {
}
@import "test-access-screen";
@import "main-tabs";
\ No newline at end of file
......@@ -61,7 +61,9 @@ class wsMenuEditorExtras {
//and is slightly faster than adding a separate filter for each feature.
add_filter('custom_admin_menu', array($this, 'apply_admin_menu_filters'));
add_filter('custom_admin_submenu', array($this, 'apply_admin_menu_filters'), 10, 2);
add_filter('admin_menu_editor-menu_merged', array($this, 'on_menu_merged'), 10, 1);
add_action('admin_menu_editor-menu_merged', array($this, 'on_menu_merged'), 10, 1);
add_action('admin_menu_editor-menu_built', array($this, 'on_menu_built'), 10, 2);
//Add some extra shortcodes of our own
$shortcode_callback = array($this, 'handle_shortcode');
......@@ -822,6 +824,23 @@ class wsMenuEditorExtras {
</form>
</div>
<div id="ws_ame_deep_nesting_dialog" title="Three Level Menu" style="display: none;">
<div class="ws_dialog_panel">
<strong style="font-size: larger;">Enable three level menus?</strong><br>
<em>Example: Menu &rarr; Submenu &rarr; Another Submenu</em>
<p>
This is an experimental feature! WordPress usually only supports two levels of admin menus.
Additional levels might not work correctly in some browsers
and might be incompatible with some plugins and themes.
</p>
</div>
<div class="ws_dialog_buttons">
<a class="button-primary" id="ame_allow_deep_nesting" href="#">Enable Experimental Feature</a>
<input type="button" name="cancel" class="button" value="Cancel" id="ame_reject_deep_nesting">
</div>
</div>
<script type="text/javascript">
/** @namespace wsEditorData */
wsEditorData.wsMenuEditorPro = true;
......@@ -946,7 +965,7 @@ wsEditorData.importMenuNonce = "<?php echo esc_js(wp_create_nonce('import_custom
//Add Pro version buttons to the menu editor toolbar.
add_filter('admin_menu_editor-toolbar_icons', array($this, 'add_toolbar_icons'), 10, 2);
add_action('admin_menu_editor-toolbar_row_2', array($this, 'output_toolbar2_buttons'), 10, 1);
add_action('admin_menu_editor-register_toolbar_buttons', array($this, 'register_toolbar_buttons'), 10, 2);
//Handle menu download requests
if ( $action == 'download_menu' ){
......@@ -1126,24 +1145,49 @@ wsEditorData.importMenuNonce = "<?php echo esc_js(wp_create_nonce('import_custom
return $icons;
}
public function output_toolbar2_buttons($icons) {
?>
<div class="ws_separator">&nbsp;</div>
<a id='ws_toggle_all_menus' class='ws_button' href='javascript:void(0)'
title='Toggle all menus for the selected role'
><img src='<?php echo $icons['toggle-all']; ?>' alt="Toggle all" /></a>
<a id='ws_reset_actor_permissions' class='ws_button' href='javascript:void(0)'
title='Reset all permissions for the selected role or user'
><img src='<?php echo esc_attr($icons['reset-permissions']); ?>' alt="Reset permissions" /></a>
/**
* @param ameOrderedMap $firstRow
* @param ameOrderedMap $secondRow
*/
public function register_toolbar_buttons($firstRow, $secondRow) {
$hideButtonExtraTooltip = 'When "All" is selected, this will hide the menu from everyone except the current user'
. (is_multisite() ? ' and Super Admin' : '') . '.';
<a id='ws_copy_role_permissions' class='ws_button' href='javascript:void(0)'
title='Copy all menu permissions from one role to another'
><img src='<?php echo $icons['copy-permissions']; ?>' alt="Copy permissions" /></a>
$firstRow->insertAllAfter(
'new-separator',
array(
'new-heading' => array(
'title' => 'New heading',
'topLevelOnly' => true,
),
'pro-separator-1' => null,
'deny' => array(
'title' => "Hide and prevent access. \n" . $hideButtonExtraTooltip,
'alt' => 'Hide',
'iconName' => 'hide-and-deny',
),
)
);
<div class="ws_separator">&nbsp;</div>
<?php
$secondRow->addAll(array(
'pro-separator-2' => null,
'toggle-all' => array(
'title' => 'Toggle all menus for the selected role',
'alt' => 'Toggle all',
'topLevelOnly' => true,
),
'reset-permissions' => array(
'title' => 'Reset all permissions for the selected role or user',
'alt' => 'Reset permissions',
'topLevelOnly' => true,
),
'copy-permissions' => array(
'title' => 'Copy all menu permissions from one role to another',
'alt' => 'Copy permissions',
'topLevelOnly' => true,
),
'pro-separator-3' => null,
));
}
public function register_extra_scripts() {
......@@ -1879,6 +1923,20 @@ wsEditorData.importMenuNonce = "<?php echo esc_js(wp_create_nonce('import_custom
$allowed_user_id = $this->wp_menu_editor->get_plugin_option('plugins_page_allowed_user_id');
if ( get_current_user_id() != $allowed_user_id ) {
unset($plugins[$this->wp_menu_editor->plugin_basename]);
//Also hide the Branding and Toolbar Editor add-ons.
if ( defined('AME_BRANDING_ADD_ON_FILE') ) {
$brandingAddon = plugin_basename(constant('AME_BRANDING_ADD_ON_FILE'));
if ( $brandingAddon ) {
unset($plugins[$brandingAddon]);
}
}
if ( defined('WS_ADMIN_BAR_EDITOR_FILE') ) {
$toolbarAddon = plugin_basename(constant('WS_ADMIN_BAR_EDITOR_FILE'));
if ( $toolbarAddon ) {
unset($plugins[$toolbarAddon]);
}
}
}
return $plugins;
}
......@@ -1950,6 +2008,46 @@ wsEditorData.importMenuNonce = "<?php echo esc_js(wp_create_nonce('import_custom
);
}
/**
* @param array $customMenu
* @param WPMenuEditor $menuEditor
* @noinspection PhpUnusedParameterInspection The unused $customMenu param is part of the hook signature.
*/
public function on_menu_built($customMenu = array(), $menuEditor = null) {
if ( !$menuEditor ) {
return;
}
if ( $menuEditor->is_custom_menu_deep() ) {
if ( did_action('admin_enqueue_scripts') ) {
$this->enqueue_third_level_script();
} else {
add_action('admin_enqueue_scripts', array($this, 'enqueue_third_level_script'));
}
add_action('in_admin_header', array($this, 'output_menu_ready_trigger'));
}
}
public function enqueue_third_level_script() {
//Third level menu support.
wp_enqueue_auto_versioned_script(
'ame-third-level-menus',
plugins_url('/extras/third-level-menus.js', __FILE__),
array('jquery', 'hoverIntent')
);
}
public function output_menu_ready_trigger() {
?>
<script type="text/javascript">
if (jQuery && document && (jQuery('#adminmenu').length > 0)) {
jQuery(document).trigger('adminMenuEditor:menuDomReady');
}
</script>
<?php
}
/**
* Generate CSS rules for menu items that have user-defined colors.
*
......@@ -2138,6 +2236,12 @@ wsEditorData.importMenuNonce = "<?php echo esc_js(wp_create_nonce('import_custom
$this->enqueue_menu_color_style();
$this->enqueue_fontawesome();
wp_enqueue_auto_versioned_style(
'ame-pro-admin-styles',
plugins_url('extras/pro-admin-styles.css', __FILE__),
array()
);
$is_helper_needed = true;
$helper_data = array();
......
......@@ -4,7 +4,7 @@ jQuery(function($) {
$submitButton = $importForm.find(':submit');
//Enable the "next" button when the user selects a file.
$importFile.change(function () {
$importFile.on('change', function () {
$submitButton.prop('disabled', !$importFile.val());
});
......
......@@ -178,6 +178,8 @@ class wsAmeImportExportFeature {
}
}
//todo: Consider adding some buffer space at the end to avoid truncation when other plugins add superfluous whitespace.
$data = $this->export_data();
$data['settings'] = array_intersect_key($data['settings'], $enabledOptions);
$json = json_encode($data);
......
......@@ -185,7 +185,7 @@ ko.bindingHandlers.ameColorPicker = {
if (newValue === '') {
//Programmatically click the "Clear" button. It's not elegant, but I haven't found
//a way to do this using the Iris API.
jQuery(element).closest('.wp-picker-input-wrap').find('.wp-picker-clear').click();
jQuery(element).closest('.wp-picker-input-wrap').find('.wp-picker-clear').trigger('click');
}
else {
jQuery(element).iris('color', newValue);
......
......@@ -231,7 +231,7 @@ ko.bindingHandlers.ameColorPicker = {
if (newValue === '') {
//Programmatically click the "Clear" button. It's not elegant, but I haven't found
//a way to do this using the Iris API.
jQuery(element).closest('.wp-picker-input-wrap').find('.wp-picker-clear').click();
jQuery(element).closest('.wp-picker-input-wrap').find('.wp-picker-clear').trigger('click');
} else {
jQuery(element).iris('color', newValue);
}
......
'use strict';
jQuery(function ($) {
const menuEditorNode = $('#ws_menu_editor');
$(document).on('filterMenuFields.adminMenuEditor', function (event, knownMenuFields, baseField) {
var scrollCheckboxField = $.extend({}, baseField, {
caption: 'Hide the frame scrollbar',
......@@ -48,7 +50,9 @@ jQuery(function ($) {
});
//The "Reset permissions" toolbar button.
$('#ws_reset_actor_permissions').on('click', function (event) {
menuEditorNode.on(
'adminMenuEditor:action-reset-permissions',
function (event) {
event.preventDefault();
var selectedActor = AmeEditorApi.actorSelectorWidget.selectedActor;
......@@ -97,12 +101,19 @@ jQuery(function ($) {
AmeEditorApi.updateParentAccessUi(containerNode);
}
});
});
}
);
//"New heading" toolbar button.
let headingCount = 0;
$('#ws_new_heading').on('click', function (event) {
event.preventDefault();
menuEditorNode.on(
'adminMenuEditor:action-new-heading',
/**
* @param event
* @param {JQuery|null} selectedItem
* @param {AmeEditorColumn} column
*/
function (event, selectedItem, column) {
headingCount++;
//The new menu starts out rather bare
......@@ -119,8 +130,54 @@ jQuery(function ($) {
items: []
});
AmeEditorApi.insertMenu(menu);
column.outputItem(menu, selectedItem);
$(document).trigger('adminMenuEditor:newHeadingCreated');
}
);
//Three level menu confirmation dialog.
let $deepNestingDialog;
function initNestingDialog() {
if ($deepNestingDialog) {
return;
}
$deepNestingDialog = $('#ws_ame_deep_nesting_dialog');
$deepNestingDialog.dialog({
autoOpen: false,
closeText: ' ',
draggable: false,
modal: true,
minHeight: 300,
minWidth: 400
});
}
menuEditorNode.on(
'adminMenuEditor:queryDeepNesting',
/**
* @param event
* @param {Array} queue
*/
function(event, queue) {
let isEnabled = $.Deferred();
queue.push(isEnabled);
initNestingDialog();
$deepNestingDialog.dialog('open');
$deepNestingDialog.find('#ame_allow_deep_nesting').one('click', function() {
isEnabled.resolve();
$deepNestingDialog.dialog('close');
return false;
});
$deepNestingDialog.find('#ame_reject_deep_nesting').one('click', function() {
isEnabled.reject();
$deepNestingDialog.dialog('close');
return false;
});
}
);
});
\ No newline at end of file
......@@ -214,6 +214,11 @@ class ameMenuHeadingStyler {
['&.ame-collapsible-heading a'],
['cursor' => 'pointer']
),
//Remove the colored bar from item unless the heading is clickable.
$this->makeCssRule(
['&:not(.ame-collapsible-heading) a'],
['box-shadow' => 'none']
),
];
//Some rules might be empty if we have no custom settings for their properties,
......
......@@ -374,7 +374,6 @@ class ameWidgetCollection {
'Cannot decompress dashboard widget data. This site may be missing the Zlib extension.'
);
}
/** @noinspection PhpComposerExtensionStubsInspection */
$data = gzuncompress($data);
}
......
......@@ -24,7 +24,7 @@ class ameWidgetEditor extends ameModule implements ameExportableModule {
return;
}
add_action('wp_dashboard_setup', array($this, 'setupDashboard'), 200);
add_action('wp_dashboard_setup', array($this, 'setupDashboard'), 20000);
add_action('admin_menu_editor-header', array($this, 'handleFormSubmission'), 10, 2);
......@@ -107,7 +107,7 @@ class ameWidgetEditor extends ameModule implements ameExportableModule {
plugins_url('dashboard-widget-editor.js', __FILE__),
array(
'ame-lodash', 'ame-dashboard-widget', 'knockout', 'ame-actor-selector',
'ame-jquery-form', 'jquery-ui-dialog', 'jquery-json', 'ame-ko-extensions',
'ame-jquery-form', 'jquery-ui-dialog', 'ame-ko-extensions',
)
);
......
......@@ -125,7 +125,7 @@ var AmeDashboardWidgetEditor = /** @class */ (function () {
AmeDashboardWidgetEditor.prototype.saveChanges = function () {
var settings = this.getCurrentSettings();
//Set the hidden form fields.
this.widgetData(jQuery.toJSON(settings));
this.widgetData(JSON.stringify(settings));
this.widgetDataLength(this.widgetData().length);
//Submit the form.
return true;
......@@ -158,7 +158,7 @@ var AmeDashboardWidgetEditor = /** @class */ (function () {
var _this = this;
//Temporarily disable the export button to prevent accidental repeated clicks.
this.isExportButtonEnabled(false);
this.widgetData(jQuery.toJSON(this.getCurrentSettings()));
this.widgetData(JSON.stringify(this.getCurrentSettings()));
//Re-enable the export button after a few seconds.
window.setTimeout(function () {
_this.isExportButtonEnabled(true);
......@@ -246,7 +246,7 @@ var AmeDashboardWidgetEditor = /** @class */ (function () {
handleUnexpectedImportError(xhr, errorMessage);
}
});
this.importDialog.find('#ame-cancel-widget-import').click(function () {
this.importDialog.find('#ame-cancel-widget-import').on('click', function () {
_this.importDialog.dialog('close');
});
};
......
......@@ -190,7 +190,7 @@ class AmeDashboardWidgetEditor {
let settings = this.getCurrentSettings();
//Set the hidden form fields.
this.widgetData(jQuery.toJSON(settings));
this.widgetData(JSON.stringify(settings));
this.widgetDataLength(this.widgetData().length);
//Submit the form.
......@@ -229,7 +229,7 @@ class AmeDashboardWidgetEditor {
//Temporarily disable the export button to prevent accidental repeated clicks.
this.isExportButtonEnabled(false);
this.widgetData(jQuery.toJSON(this.getCurrentSettings()));
this.widgetData(JSON.stringify(this.getCurrentSettings()));
//Re-enable the export button after a few seconds.
window.setTimeout(() => {
......@@ -334,7 +334,7 @@ class AmeDashboardWidgetEditor {
}
});
this.importDialog.find('#ame-cancel-widget-import').click(() => {
this.importDialog.find('#ame-cancel-widget-import').on('click', () => {
this.importDialog.dialog('close');
});
}
......
......@@ -10,6 +10,8 @@ var __extends = (this && this.__extends) || (function () {
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
......
......@@ -62,6 +62,13 @@ class ameMetaBoxCollection {
continue;
}
//Skip boxes that have an invalid ID. The ID must be a string.
//This is a workaround for plugins that set the ID to null or another unsupported value.
//Example: "Amazon Simple Affiliate (ASA2)", version 1.15.3.
if (!is_string($metaBox['id'])) {
continue;
}
$properties = array_merge(
array(
'context' => $context,
......
......@@ -20,6 +20,8 @@ class ameMetaBoxEditor extends ameModule implements ameExportableModule {
private $shouldRefreshMetaBoxes = false;
private $hiddenBoxCache = array();
private $areSettingsCorrupted = false;
public function __construct($menuEditor) {
parent::__construct($menuEditor);
......@@ -84,7 +86,7 @@ class ameMetaBoxEditor extends ameModule implements ameExportableModule {
global $wp_meta_boxes;
$currentScreen = get_current_screen();
if ( empty($currentScreen) ) {
if ( empty($currentScreen) || $this->areSettingsCorrupted ) {
return;
}
......@@ -143,7 +145,7 @@ class ameMetaBoxEditor extends ameModule implements ameExportableModule {
* @return array
*/
public function filterDefaultHiddenBoxes($hidden, $screen) {