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
Tests
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.
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
cheatjs_settings['custom_cheats'].unfiltered_html.manage_optionscan manage the CheatJS settings page, but users withoutunfiltered_htmlshould not be able to create or modify custom CSS/JS. Existing custom code should be preserved if such a user saves other settings.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:
cheatjs-custom-{id}todocument.body.<style>element owned by that active cheat.document, andwindow.When a custom cheat is toggled off, Stop is clicked, or the controller is destroyed:
<style>element.Admin UI
Add a new
Custom Cheatssection below built-in presets.Each custom cheat card needs:
Add an
Add custom cheatbutton 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:
CheatJS_Admin::enqueue_assets().wp_enqueue_code_editor( [ 'type' => 'text/css' ] )for CSS settings.wp_enqueue_code_editor( [ 'type' => 'application/javascript' ] )for JS settings.assets/js/cheatjs-admin.js.wp.codeEditor.initialize(...)when available.Implementation Tasks
CheatJS_Settings::get_defaults()to includecustom_cheats.unfiltered_html.CheatJS_Settings::get_active_custom_cheats()or equivalent shared active-cheat assembly.CheatJS_Frontend::get_runtime_config()to include enabled custom cheats.assets/js/cheatjs.jsto activate/deactivate custom CSS and JS with cleanup support.CheatJS_Admin::render_page()to render the custom cheat section.assets/js/cheatjs-admin.jsto add/remove custom cheat cards and initialize WordPress code editors.assets/css/cheatjs-admin.cssfor custom cheat fields and code editor layout.Tests
custom_cheatslist.unfiltered_htmlcannot overwrite stored CSS/JS.Acceptance Criteria