Skip to content

Add admin-created custom cheats #3

Description

@acodebeard

Goal

Allow site administrators to create custom CheatJS cheats from the WordPress admin. Each custom cheat should have a name, recorded key sequence, custom CSS, and custom JavaScript.

Decisions

  • Custom cheats are stored separately from built-in presets in cheatjs_settings['custom_cheats'].
  • Custom CSS/JS is powerful and should only be editable by users with unfiltered_html.
  • Users with manage_options can manage the CheatJS settings page, but users without unfiltered_html should not be able to create or modify custom CSS/JS. Existing custom code should be preserved if such a user saves other settings.
  • Custom CSS/JS editors should use WordPress's built-in code editor UI when available.
  • If wp_enqueue_code_editor() returns false, the admin fields remain normal textareas and still save correctly.

Data Model

Each custom cheat stores:

[
    'id'       => 'generated-stable-id',
    'enabled'  => true,
    'name'     => 'Custom Cheat Name',
    'sequence' => [ 'c', 'u', 's', 't', 'o', 'm' ],
    'css'      => 'body.cheatjs-custom-generated-stable-id { ... }',
    'js'       => 'return function cleanup() { ... };',
]

IDs should be stable after creation so saved sequences and body classes do not change. Use a sanitized submitted ID when present; otherwise generate a new unique ID during sanitization.

Frontend Behavior

When a custom cheat is activated:

  • Add cheatjs-custom-{id} to document.body.
  • Inject the custom CSS into a <style> element owned by that active cheat.
  • Execute the custom JS.
  • Provide the custom JS with a small API object containing the cheat ID, body class, document, and window.
  • If the custom JS returns a function, store it as the cleanup callback.

When a custom cheat is toggled off, Stop is clicked, or the controller is destroyed:

  • Remove the custom body class.
  • Remove the injected <style> element.
  • Call the cleanup callback if one was returned.
  • Catch JS runtime errors so one bad custom cheat does not break the detector.

Admin UI

Add a new Custom Cheats section below built-in presets.

Each custom cheat card needs:

  • Enabled checkbox.
  • Cheat name input.
  • Key sequence recorder using the existing Record/Clear/Done behavior.
  • CSS editor textarea.
  • JS editor textarea.
  • Remove button.

Add an Add custom cheat button that creates a blank custom cheat card client-side. The new card should be compatible with the existing key recorder controller.

For code editor fields:

  • Enqueue the WordPress code editor in CheatJS_Admin::enqueue_assets().
  • Call wp_enqueue_code_editor( [ 'type' => 'text/css' ] ) for CSS settings.
  • Call wp_enqueue_code_editor( [ 'type' => 'application/javascript' ] ) for JS settings.
  • Pass editor settings into assets/js/cheatjs-admin.js.
  • Initialize each editor with wp.codeEditor.initialize(...) when available.
  • Fall back to normal textareas if syntax highlighting is disabled or unavailable.

Implementation Tasks

  • Extend CheatJS_Settings::get_defaults() to include custom_cheats.
  • Add sanitizer coverage for custom cheat IDs, enabled state, name, sequence, CSS, and JS.
  • Preserve existing custom CSS/JS when a user lacks unfiltered_html.
  • Add CheatJS_Settings::get_active_custom_cheats() or equivalent shared active-cheat assembly.
  • Extend CheatJS_Frontend::get_runtime_config() to include enabled custom cheats.
  • Update assets/js/cheatjs.js to activate/deactivate custom CSS and JS with cleanup support.
  • Update CheatJS_Admin::render_page() to render the custom cheat section.
  • Update assets/js/cheatjs-admin.js to add/remove custom cheat cards and initialize WordPress code editors.
  • Update assets/css/cheatjs-admin.css for custom cheat fields and code editor layout.
  • Update README to replace the old “no custom JS/CSS” statement with the new permission model.

Tests

  • PHP settings test: defaults include an empty custom_cheats list.
  • PHP settings test: valid custom cheats are normalized and invalid empty entries are dropped.
  • PHP settings test: unknown/bad sequence values are removed or fall back safely.
  • PHP settings test: users without unfiltered_html cannot overwrite stored CSS/JS.
  • PHP frontend test: enabled custom cheats appear in runtime config with CSS/JS fields.
  • PHP frontend test: disabled custom cheats do not appear in runtime config.
  • PHP admin test: custom cheat controls render with stable input names.
  • JS runtime test: custom CSS is injected on activation and removed on deactivation.
  • JS runtime test: custom JS executes on activation and cleanup runs on deactivation/Stop/destroy.
  • JS admin test: Add custom cheat creates a card with name, sequence, CSS, JS, and remove controls.
  • JS admin test: WordPress code editor initialization is called when available and skipped cleanly when unavailable.

Acceptance Criteria

  • An admin can add a custom cheat, name it, record a sequence, enter CSS, enter JS, save, and trigger it on the frontend.
  • The custom cheat can be disabled without deleting it.
  • The custom cheat can be removed from settings.
  • Custom CSS and JS only run while that custom cheat is active.
  • Stop cheating cleans up custom CSS, body class, and JS cleanup callbacks.
  • Built-in presets continue to work unchanged.
  • Tests do not lock down custom user CSS/JS content beyond the required lifecycle and permission behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions