77 lines
2.7 KiB
PHP
77 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace Reservair\Forms;
|
|
|
|
/**
|
|
* Wraps WordPress' bundled CodeMirror (wp_enqueue_code_editor) as a drop-in
|
|
* replacement for a <textarea>.
|
|
*
|
|
* The textarea stays the source of truth: CodeMirror mirrors its content back
|
|
* on every edit, so any form serialization that reads the textarea's value
|
|
* keeps working unchanged. When the user has turned syntax highlighting off in
|
|
* their profile, this degrades to the plain textarea.
|
|
*/
|
|
class RsvCodeEditor
|
|
{
|
|
/**
|
|
* Renders a code-editor-backed <textarea> and arranges for it to be
|
|
* upgraded to CodeMirror on the page.
|
|
*
|
|
* @param array{name?:string,value?:string,mode?:string,rows?:int,class?:string} $args
|
|
* mode is a MIME type understood by wp_enqueue_code_editor, e.g.
|
|
* 'text/html' or 'text/css'.
|
|
*/
|
|
public static function render(string $id, array $args = []): string
|
|
{
|
|
$name = $args['name'] ?? $id;
|
|
$value = $args['value'] ?? '';
|
|
$mode = $args['mode'] ?? 'text/html';
|
|
$rows = $args['rows'] ?? 8;
|
|
$class = $args['class'] ?? 'large-text code';
|
|
|
|
$textarea = '<textarea id="' . esc_attr($id) . '" name="' . esc_attr($name) . '"'
|
|
. ' rows="' . $rows . '" class="' . esc_attr($class) . '">'
|
|
. esc_textarea($value)
|
|
. '</textarea>';
|
|
|
|
$settings = wp_enqueue_code_editor(['type' => $mode]);
|
|
|
|
// Syntax highlighting disabled in the user's profile — keep it plain.
|
|
if ($settings === false) {
|
|
return $textarea;
|
|
}
|
|
|
|
self::schedule_init($id, $settings);
|
|
|
|
return $textarea;
|
|
}
|
|
|
|
/**
|
|
* Initializes CodeMirror on $id after the code editor script loads, and
|
|
* keeps the underlying textarea in sync — including dispatching `input` so
|
|
* listeners (live previews, change tracking) still fire while typing.
|
|
*
|
|
* @param array<array-key,mixed> $settings As returned by wp_enqueue_code_editor.
|
|
*/
|
|
private static function schedule_init(string $id, array $settings): void
|
|
{
|
|
$id_json = wp_json_encode($id);
|
|
$settings_json = wp_json_encode($settings);
|
|
if ($id_json === false || $settings_json === false) {
|
|
return;
|
|
}
|
|
|
|
$script = '(function(){'
|
|
. 'var ta=document.getElementById(' . $id_json . ');'
|
|
. 'if(!ta||!window.wp||!wp.codeEditor)return;'
|
|
. 'var ed=wp.codeEditor.initialize(ta,' . $settings_json . ');'
|
|
. 'ed.codemirror.on("change",function(cm){'
|
|
. 'cm.save();'
|
|
. 'ta.dispatchEvent(new Event("input",{bubbles:true}));'
|
|
. '});'
|
|
. '})();';
|
|
|
|
wp_add_inline_script('code-editor', $script);
|
|
}
|
|
}
|