Files
torebki-fabiola.pl/wp-content/plugins/html-editor-syntax-highlighter/html-editor-syntax-highlighter.php
2026-03-05 13:07:40 +01:00

571 lines
18 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Plugin Name: HTML Editor Syntax Highlighter
* Description: Add syntax highlighting to the all WordPress code editors using Codemirror.js
* Author: James Bradford
* Author URI: http://bradford.digital/
* Author: Petr Mukhortov
* Author URI: http://mukhortov.com/
* Version: 2.4.4
*
* @package HESH_plugin
**/
// Check for required PHP version
if ( version_compare( PHP_VERSION, '5.2.17', '<' ) ) {
exit( sprintf( 'Foo requires PHP 5.2.17 or higher. Youre still on %s.', PHP_VERSION ) );
}
if ( preg_match( '#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'] ) ) {
die('You are not allowed to call this page directly.');
}
define( 'HESH_LIBS', plugins_url( '/', __FILE__ ) );
class Wp_Html_Editor_Syntax_Highlighter {
public function __construct () {
add_action( 'admin_init', array(&$this, 'hesh_set_options') );
add_action( 'wp_ajax_'.$this->formProcessName, array(&$this, 'hesh_options_form_process'));
// Load only on certain pages
if (
!strstr($_SERVER['SCRIPT_NAME'], 'post.php') &&
!strstr($_SERVER['SCRIPT_NAME'], 'post-new.php') &&
!strstr($_SERVER['SCRIPT_NAME'], 'editor.php')
) return;
add_action( 'admin_enqueue_scripts', array(&$this, 'hesh_admin_enqueue_scripts' ) );
add_action( 'admin_footer', array(&$this, 'hesh_output_form') );
// add_action( 'admin_notices', array(&$this, 'display_survey_notice' ));
}
// Enqueued scripts and styles for hesh.js
public function hesh_admin_enqueue_scripts () {
// get the plugin version number for cache busting purposes
$plugData = get_plugin_data( __FILE__ ); // need this temporary var to support versions of php < 5.4
$ver = $plugData['Version'];
// load minified version if not a localhost dev account
// $min = strpos(home_url(), 'localhost') ? '' : '.min' ; // no more...
wp_enqueue_script( 'jquery');
// dequeue the native WP code-editor and codemirror
if (wp_script_is( 'code-editor', 'enqueued' )) wp_dequeue_script( 'code-editor' );
if (wp_style_is( 'code-editor', 'enqueued' )) wp_dequeue_style( 'code-editor' );
// if (wp_script_is( 'wp-codemirror', 'enqueued' )) wp_dequeue_script( 'wp-codemirror' );
// if (wp_style_is( 'wp-codemirror', 'enqueued' )) wp_dequeue_style( 'wp-codemirror' );
// enqueue hesh scripts
wp_enqueue_script( 'heshJs', HESH_LIBS.'hesh.js', array('jquery', 'editor'), $ver, true );
wp_enqueue_style( 'heshCss', HESH_LIBS.'hesh.css', false, $ver );
// this shows up in js as window.heshOptions
$heshOptions = array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
// 'nonce' => wp_create_nonce( $this->formProcessName ) // TODO: use this instead of the hidden field?
);
// place all the userPreferences into the heshOptions object
foreach ($this->userPreferences as $id => $value) {
$heshOptions[$id] = $value['current'];
// error_log( $id . ': ' . $heshOptions[$id] . ' type: ' . gettype($heshOptions[$id]) ); // for debug
}
wp_localize_script(
'heshJs', // for hesh.js
'heshOptions', // the object name, shows up in js as window.heshOptions
$heshOptions // the php object to translate to js
);
}
private $surveyLink = 'https://goo.gl/forms/xvaHgd7sZEbBbFAL2';
private $formProcessName = 'hesh_options_form';
private $nonceSecretCode = 'secret-code';
private $prefix = 'hesh_';
private $userPreferences = array(); // added to the primary bar
public function hesh_set_options() {
$this->userPreferences = array(
// HIDDEN OPTIONS // added in the primary settings bar
'surveyNoticeDismissedB' => array(
'title' => 'UX Survey Notice Dismissed',
'type' => 'hidden',
// 'current' => false, // reset for debug
'current' => get_user_meta( get_current_user_id(), $this->prefix.'surveyNoticeDismissedB' , true),
'default' => false,
'set' => 'hidden',
),
// PRIMARY OPTIONS // added in the primary settings bar
'theme' => array(
'title' => 'Theme',
'type' => 'select',
'options' => $this->cssThemes,
'current' => get_user_meta( get_current_user_id(), $this->prefix.'theme' , true),
'default' => 'wordpress',
'set' => 'primary',
),
'tabSize' => array(
'title' => 'Indent',
'type' => 'select',
'options' => range(1,6),
'current' => get_user_meta( get_current_user_id(), $this->prefix.'tabSize' , true),
'default' => 4,
'set' => 'primary',
),
'lineWrapping'=> array(
'title' => 'Line Wrap',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'lineWrapping' , true),
'default' => true,
'set' => 'primary',
),
'lineNumbers'=> array(
'title' => 'Numbering',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'lineNumbers' , true),
'default' => true,
'set' => 'primary',
),
'fontSize'=> array(
'title' => 'Font Size',
'type' => 'select',
'options' => range(8,20),
'current' => get_user_meta( get_current_user_id(), $this->prefix.'fontSize' , true),
'default' => 13,
'set' => 'primary',
),
'lineHeight'=> array(
'title' => 'Line Height',
'type' => 'select',
'options' => range(1,2,0.25),
'current' => get_user_meta( get_current_user_id(), $this->prefix.'lineHeight' , true),
'default' => 1.5,
'set' => 'primary',
),
// ADVANCED OPTIONS // added to the advanced dropdown
'matchBrackets'=> array(
'title' => 'Match Brackets',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'matchBrackets' , true),
'default' => false,
'set' => 'advanced',
'description' => 'highlight matching bracket pairs next to cursor',
),
'matchTags'=> array(
'title' => 'Match Tags',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'matchTags' , true),
'default' => false,
'set' => 'advanced',
'description' => 'highlight matching html tag pairs (not shortcodes)',
),
'highlightSelectionMatches'=> array(
'title' => 'Highlight Selection Matches',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'highlightSelectionMatches' , true),
'default' => false,
'set' => 'advanced',
'description' => 'highlight all instances of a currently selected word',
),
'autoCloseTags'=> array(
'title' => 'Auto Close Tags',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'autoCloseTags' , true),
'default' => false,
'set' => 'advanced',
'description' => 'auto-close HTML tags when <code>></code> or <code>/</code> is typed',
),
'autoCloseBrackets'=> array(
'title' => 'Auto Close Brackets',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'autoCloseBrackets' , true),
'default' => false,
'set' => 'advanced',
'description' => 'auto-close brackets and quotes when typed',
),
'foldGutter'=> array(
'title' => 'Code Folding',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'foldGutter' , true),
'default' => false,
'set' => 'advanced',
// 'description' => 'fold HTML code (not shortcodes)',
),
'scrollbarStyle'=> array(
'title' => 'Show Scrollbars',
'type' => 'checkbox',
'current' => get_user_meta( get_current_user_id(), $this->prefix.'scrollbarStyle' , true),
'default' => false,
'set' => 'advanced',
),
'keyMap'=> array(
'title' => 'Key Mapping',
'type' => 'radio',
'options' => array('default', 'sublime', 'vim', 'emacs'),
'current' => get_user_meta( get_current_user_id(), $this->prefix.'keyMap' , true),
'default' => 'default',
'set' => 'advanced',
),
);
// Initialize all the hesh option fields as default if they don't exist yet
foreach ($this->userPreferences as $id => $value) {
if (!isset($value['current']) || trim($value['current'])==='')
update_user_meta( get_current_user_id(), $this->prefix.$id, $value['default']);
// error_log( $id . ': ' . $value['current'] . ': ' . isset($value['current']) ); // for debug
}
}
public function hesh_options_form_process() {
if (empty($_POST) || !wp_verify_nonce($_POST[$this->nonceSecretCode], $this->formProcessName)) {
error_log('The nonce did not verify.');
wp_die();
} else {
foreach ($this->userPreferences as $id => $value) {
$setting = $_POST[$id];
if ($setting === 'true') $setting = true;
if ($setting === 'false') $setting = false;
if (is_numeric($setting)) $setting = floatval($setting);
// error_log( $id . ': ' . $setting . ' type: ' . gettype($setting) ); // for debug
update_user_meta( get_current_user_id(), $this->prefix.$id, $setting);
}
}
}
private function hesh_output_option($id, $config) {
switch ($config['type']){
case 'select':
$this->hesh_output_primary_select($id, $config);
break;
case 'checkbox':
$this->hesh_output_primary_toggle($id, $config);
break;
}
}
private function hesh_output_primary_toggle($id, $config) {
extract($config);
?>
<label
class="CodeMirror-settings__button button button-small"
for="<?php echo $id; ?>"
>
<?php echo $title; ?>
<input type="hidden" value="false" name="<?php echo $id; ?>" />
<input
name="<?php echo $id; ?>"
id="<?php echo $id; ?>"
type="checkbox"
value="true"
class="CodeMirror-settings__option"
<?php if ($current) echo 'checked'; ?>
/>
</label>
<?php
}
private function hesh_output_primary_select($id, $config) {
extract($config);
?>
<label
class="CodeMirror-settings__button CodeMirror-settings__button--select button button-small"
for="<?php echo $id; ?>"
>
<?php echo $title; ?>
<select
id="<?php echo $id; ?>"
name="<?php echo $id; ?>"
class="CodeMirror-settings__option"
>
<?php foreach ($options as $option): ?>
<option
value="<?php echo $option; ?>"
<?php if ($current == $option) echo 'selected';?>
>
<?php echo ucfirst($option); ?>
</option>
<?php endforeach; ?>
</select>
</label>
<?php
}
private function hesh_output_fieldset($title=false) {
if ($title): ?>
<tr>
<th scope="row">
<?php echo $title; ?>
</th>
<td><fieldset>
<?php else: ?>
</fieldset></td>
</tr>
<?php endif;
}
private function hesh_output_checkbox($id, $config) {
extract($config);
?>
<label
for="<?php echo $id; ?>"
>
<input type="hidden" value="false" name="<?php echo $id; ?>" />
<input
name="<?php echo $id; ?>"
id="<?php echo $id; ?>"
type="checkbox"
value="true"
class="CodeMirror-settings__option"
<?php if ($current) echo 'checked'; ?>
/>
<?php echo $title; ?>
<?php if (isset($description)): ?>
<small
class="description CodeMirror-settings-advanced__description"
id="<?php echo $id; ?>-description"
>
<?php echo $description; ?>
</small>
<?php endif; ?>
</label>
<br/>
<?php
}
private function hesh_output_radio($id, $config) {
extract($config);
$this->hesh_output_fieldset('Key Bindings');
foreach ($options as $option):
?>
<label>
<input
type="radio"
id="<?php echo $id; ?>"
name="<?php echo $id; ?>"
value="<?php echo $option; ?>"
class="CodeMirror-settings__option"
<?php if ($current == $option) echo 'checked'; ?>
/>
<span>
<?php echo ucfirst($option); ?>
</span>
</label><br/>
<?php
endforeach;
$this->hesh_output_fieldset();
}
private function hesh_output_hidden($id, $config) {
extract($config);
?>
<input
type="hidden"
id="<?php echo $id; ?>"
name="<?php echo $id; ?>"
value="<?php echo $current; ?>"
class="CodeMirror-settings__option"
/>
<?php
}
public function hesh_output_form() {
// ob_start();
?>
<div class="CodeMirror-settings closed" id="CodeMirror-settings" style="display:none;">
<form
action="<?php echo admin_url('admin-ajax.php');?>"
method="post"
class="CodeMirror-settings__wrapper"
id="CodeMirror-settings__form"
>
<header class="CodeMirror-settings__header CodeMirror-settings__docked">
<?php
foreach ($this->userPreferences as $id => $value) {
if ( $value['set'] === 'primary' )
$this->hesh_output_option($id,$value);
if ( $value['set'] === 'hidden' )
$this->hesh_output_hidden($id,$value);
}
?>
<a
class="CodeMirror-settings__toggle-advanced"
id="CodeMirror-settings__toggle-advanced"
></a>
</header>
<div class="form CodeMirror-settings__body">
<?php wp_nonce_field($this->formProcessName,$this->nonceSecretCode);?>
<input name="action" value="hesh_options_form" type="hidden">
<table class="form-table"><tbody>
<tr><td class="CodeMirror-settings__heading" colspan="2">
<h1>
Advanced Options
</h1>
<?php /*
<!-- <small>These features are experimental and may have bugs</small> -->
<!-- <small>
<strong>HELP!</strong>
Please consider taking a short <a href="<?php echo $this->surveyLink; ?>" target="_blank" >User Experience Survey</a>
to provide feedback that will help shape the new version 3.0 of this plugin.
</small> -->
*/ ?>
</td></tr>
<?php
$this->hesh_output_fieldset('Highlighting');
$this->hesh_output_checkbox('matchBrackets',$this->userPreferences['matchBrackets']);
$this->hesh_output_checkbox('matchTags',$this->userPreferences['matchTags']);
$this->hesh_output_checkbox('highlightSelectionMatches',$this->userPreferences['highlightSelectionMatches']);
$this->hesh_output_fieldset();
$this->hesh_output_fieldset('Auto Completion');
$this->hesh_output_checkbox('autoCloseTags',$this->userPreferences['autoCloseTags']);
$this->hesh_output_checkbox('autoCloseBrackets',$this->userPreferences['autoCloseBrackets']);
$this->hesh_output_fieldset();
$this->hesh_output_fieldset('Editor Tools');
$this->hesh_output_checkbox('foldGutter',$this->userPreferences['foldGutter']);
$this->hesh_output_checkbox('scrollbarStyle',$this->userPreferences['scrollbarStyle']);
$this->hesh_output_fieldset();
$this->hesh_output_radio('keyMap',$this->userPreferences['keyMap']);
?>
</tbody></table>
</div>
<footer class="CodeMirror-settings__footer CodeMirror-settings__docked">
<p class="CodeMirror-settings__foot-content CodeMirror-settings__feedback">
<small>
<?php /* Provide a href="<?php echo $this->surveyLink; ?>" target="_blank" >feedback</a>, */ ?>
Leave a
<a href="https://wordpress.org/support/plugin/html-editor-syntax-highlighter/reviews/#new-post" target="_blank">review</a>,
fork on
<a href="https://github.com/mukhortov/HESH-WordPress-Plugin/" target="_blank">Github</a>,
or submit a
<a href="https://github.com/mukhortov/HESH-WordPress-Plugin/issues/new" target="_blank">bug report or enhancement request</a>.
</small>
</p>
<p class="CodeMirror-settings__foot-content CodeMirror-settings__credits">
<small>
Created by
<a href="http://www.bradford.digital" target="_blank">James Bradford</a>
&amp;
<a href="http://www.mukhortov.com/" target="_blank">Petr Mukhortov</a>.
</small>
</p>
</footer>
</form>
<div class="CodeMirror-settings__toggle" id="CodeMirror-settings__toggle"></div>
</div>
<?php
// return ob_get_clean();
}
/* // not currently being used
public function display_survey_notice() {
if ( $this->userPreferences['surveyNoticeDismissedB']['current'] ) return;
// https://codex.wordpress.org/Plugin_API/Action_Reference/admin_notices
?>
<div class="notice notice-info is-dismissible notice-hesh">
<p>
<strong style="font-size:1.5em;">Please Take A Short Syntax Highlighter UX Survey</strong>
<br/>
A new version of the HTML Editor Syntax Highlighter Is Coming!
Please take this 5 minute user experience survey, and share your opinion to help shape new features in the v3.0 update.
A survey link is also available in the <em>Advanced Options</em>.
<br/><br/>
<a href="<?php echo $this->surveyLink; ?>" target="_blank" class="button button-primary">Take the UX Survey</a>
</p>
</div>
<?php
} */
// to get a list of theme names: `cd node_modules/codemirror/theme/` then run `ls > css-themes.txt`
private $cssThemes = array(
'none', // special
'wordpress', // custom
'default', // special
// node_modules/codemirror/theme/
'3024-day', // SUCKS
'3024-night', //??
'abbott',
'abcdef',
'ambiance-mobile',// BROKEN
'ambiance',
'ayu-dark',
'ayu-mirage',
'base16-dark',
'base16-light',
'bespin',
'blackboard',
'cobalt',
'codepen', // custom
'colorforth',
'darcula',
'dracula',
'duotone-dark',
'duotone-light',
'eclipse',
'elegant',
'erlang-dark',
'gruvbox-dark',
'github', // from npm
'hopscotch',
'icecoder',
'idea',
'isotope',
'juejin',
'lesser-dark',
'liquibyte',
'lucario',
'material-darker',
'material-ocean',
'material-palenight',
'material',
'mbo',
'mdn-like',
'midnight',
'monokai',
'moxer',
'neat', // SUCKS
'neo',
'night',
'nord',
'oceanic-next',
'panda-syntax',
'paraiso-dark',
'paraiso-light',
'pastel-on-dark',
'railscasts',
'rubyblue',
'seti',
'shadowfox',
'solarized',
'ssms', // SUCKS
'the-matrix',
'tomorrow-night-bright',
'tomorrow-night-eighties',
'ttcn',
'twilight',
'vibrant-ink',
'xq-dark',
'xq-light', // SUCKS, that yellow...
'yeti',
'yonce',
'zenburn'
);
}
if ( is_admin() ) {
$hesh = new Wp_Html_Editor_Syntax_Highlighter();
}
?>