=== Maestro: The Inline Admin Menu Editor ===
Contributors: dpknauss
Donate link: https://www.paypal.com/paypalme/DanKnauss
Tags: admin menu, menu editor, admin, dashboard, icons
Requires at least: 6.4
Tested up to: 7.0
Stable tag: 1.0.0
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

In-place editing of the WordPress admin menu: rename, reorder, swap icons, and hide items per role — edited on the menu itself.

== Description ==

Toggle "Edit Menu" from the admin bar and the admin menu becomes editable in
place:

* **Rename** any top-level or submenu item (click the label).
* **Reorder** items by dragging (top-level and within each submenu).
* **Swap icons** on top-level items (submenus carry no icon). The picker offers
  dashicons and bundled Bootstrap Icons, with search; any of WordPress's four
  native icon forms is accepted (dashicon, "none", base64 image data-URI, or an
  image URL).
* **Hide** items from chosen roles. Custom roles registered by other plugins
  ([User Role Editor](https://wordpress.org/plugins/user-role-editor/),
  [Members](https://wordpress.org/plugins/members/), etc.) appear automatically.
* **Reset** a single item to its default, or reset everything at once.

Changes are **global** — one configuration applies to everyone — and are stored
as a sparse delta layered over the menu WordPress builds each load.

= Important: visibility is cosmetic, not access control =

Hiding a menu item only declutters the menu. The underlying admin page still
loads for anyone who knows or types its URL, because a page's own registered
**capability** is the true lock. This plugin operates on the menu (presentation),
which is a different plane from authorization.

If you need to actually *prevent* access, pair this with a capability manager:

* **[User Role Editor](https://wordpress.org/plugins/user-role-editor/)** —
  simplest way to edit what a role can do.
* **[PublishPress Capabilities](https://wordpress.org/plugins/capability-manager-enhanced/)** —
  menu-aware; its Pro tier can block admin pages by URL.

The `maestro_capability` filter lets such a plugin hand editing rights to a custom
capability instead of the default `manage_options`.

= Localization =

Maestro uses the `maestro-menu-editor` text domain. PHP strings use
WordPress translation helpers, and editor labels are passed to JavaScript in a
localized payload so the UI can be translated. The plugin ships a translation
template plus starter language packs for Spanish (`es_ES`), German (`de_DE`),
Japanese (`ja`), French (`fr_FR`), Portuguese (Brazil) (`pt_BR`), and Italian
(`it_IT`). WordPress.org language packs can still override and extend the
bundled catalogs; native-speaker and WordPress Polyglots review is welcome.

== How to use ==

= Enter edit mode =

After activation, choose **Edit Menu** from the admin bar. The admin menu stays
expanded while editing so items are visible and stable. Choose **Exit Menu
Editing** when done; any pending autosave is completed before the page reloads.

= Select an item =

Click a top-level or submenu item to select it. Keyboard users can focus a menu
item and press Enter or Space. The shared controls panel opens for the selected
item.

= Rename =

Edit the selected item's label in the controls panel. Press Enter to commit the
label or Escape to restore the previous label. Changes autosave after a short
pause.

= Reorder =

Drag menu rows to reorder them. Top-level items reorder among top-level items;
submenu items reorder within their current parent. Moving items between
top-level and submenu positions is deferred to a later version.

= Icons =

Select a top-level item and open the icon picker. Choose a Dashicon, bundled
Bootstrap Icon, "No icon", or a valid WordPress icon value. Submenu items do not
have separate WordPress admin menu icons, so the icon control appears only for
top-level items.

= Role visibility =

Open the visibility control and check the roles that should not see the selected
item in the admin menu. These settings are global for each role and are cosmetic
only; they do not block the underlying page URL.

= Reset =

Use **Reset this item** to remove one item's customizations, or **Reset all** to
delete the saved configuration and return to the menu generated by WordPress and
active plugins.

== Architecture (for developers) ==

* `Config` — reads/writes/sanitizes a single option (`maestro_config`) holding only
  the deltas. Reset = delete the option; the natural menu returns automatically.
* `Replay` — on a late `admin_menu` pass, applies rename/icon/visibility to the
  `$menu`/`$submenu` globals and reorders submenus. Top-level order uses the
  core `custom_menu_order` + `menu_order` filters. Resilient to missing slugs
  (orphans are skipped) and new items (appended at the end).
* `Rest` — `maestro/v1/config` (GET/POST/DELETE), capability-gated, `X-WP-Nonce`.
* The editor JS is driven by a localized model (with DOM ids), not DOM scraping,
  and diffs against captured pristine defaults so the stored config stays sparse.
* Localized editor labels are passed from PHP to JavaScript in `maestroData.i18n`;
  the runtime zip includes the bundled POT template and starter catalogs.
* WordPress.org listing graphics live in the repository's `.wordpress-org/`
  directory: `icon.svg`, `icon-128x128.png`, `icon-256x256.png`,
  `banner-772x250.png`, `banner-1544x500.png`, and `screenshot-1.png` through
  `screenshot-4.png`.

== Screenshots ==

1. Edit mode with the Posts menu item selected and the shared controls panel open.
2. Searchable icon picker with Dashicons and Bootstrap Icons tabs.
3. Per-role visibility picker for hiding a menu item from selected roles.
4. A renamed menu item saved through debounced autosave.

== Known limits / deferred to v2 ==

* **Reparenting** (moving an item between top-level and submenu) is not included.
  It requires hand-splicing the globals plus `parent_file`/`submenu_file`
  highlighting fixes — a known minefield, parked deliberately.
* **Separators** are preserved in place but not yet add/move/delete-able; their
  generated slugs (`separator1`…) have no stable identity to key against.
* **Renaming** an item drops any core-appended count badge (e.g. pending
  comments) from that label, since the badge lives inside the title string.
* **Keyboard reordering** is not included in v1. Keyboard users can select
  items, rename them, change icons, change visibility, and reset items, but
  drag reordering is mouse/touch-only until v2 move controls are added.
* Submenu sort relies on items registering by the late `admin_menu` pass; a
  plugin that registers submenus on an unusually late hook may not be captured.

== Credits ==

Bundled [Bootstrap Icons](https://icons.getbootstrap.com/) are © The Bootstrap
Authors, licensed under the MIT License. They are recoloured to the WordPress
menu grey and embedded as data-URIs; see `bin/generate-bootstrap-icons.mjs`.

== Changelog ==

= 1.0.0 =
* Initial release: rename, reorder, per-role visibility, reset.
* Icons: accepts all four native WordPress forms (dashicon, none, base64 image
  data-URI, image URL); picker bundles dashicons + curated Bootstrap Icons with
  search, keyboard accessibility, and mobile-sized touch targets.
* Editor: click-to-select with a shared panel, debounced single-flight autosave,
  and folded-mode neutralization.
