[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Plugin 5 * @subpackage Editors.codemirror 6 * 7 * @copyright (C) 2009 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 10 * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace 11 */ 12 13 use Joomla\CMS\Layout\LayoutHelper; 14 use Joomla\CMS\Plugin\CMSPlugin; 15 use Joomla\CMS\Plugin\PluginHelper; 16 use Joomla\Event\Event; 17 18 // phpcs:disable PSR1.Files.SideEffects 19 \defined('_JEXEC') or die; 20 // phpcs:enable PSR1.Files.SideEffects 21 22 /** 23 * CodeMirror Editor Plugin. 24 * 25 * @since 1.6 26 */ 27 class PlgEditorCodemirror extends CMSPlugin 28 { 29 /** 30 * Affects constructor behavior. If true, language files will be loaded automatically. 31 * 32 * @var boolean 33 * @since 3.1.4 34 */ 35 protected $autoloadLanguage = true; 36 37 /** 38 * Mapping of syntax to CodeMirror modes. 39 * 40 * @var array 41 */ 42 protected $modeAlias = array(); 43 44 /** 45 * Base path for editor assets. 46 * 47 * @var string 48 * 49 * @since 4.0.0 50 */ 51 protected $basePath = 'media/vendor/codemirror/'; 52 53 /** 54 * Base path for editor modes. 55 * 56 * @var string 57 * 58 * @since 4.0.0 59 */ 60 protected $modePath = 'media/vendor/codemirror/mode/%N/%N'; 61 62 /** 63 * Application object. 64 * 65 * @var \Joomla\CMS\Application\CMSApplication 66 * @since 4.0.0 67 */ 68 protected $app; 69 70 /** 71 * Initialises the Editor. 72 * 73 * @return void 74 */ 75 public function onInit() 76 { 77 static $done = false; 78 79 // Do this only once. 80 if ($done) { 81 return; 82 } 83 84 $done = true; 85 86 // Most likely need this later 87 $doc = $this->app->getDocument(); 88 89 // Codemirror shall have its own group of plugins to modify and extend its behavior 90 PluginHelper::importPlugin('editors_codemirror'); 91 92 // At this point, params can be modified by a plugin before going to the layout renderer. 93 $this->app->triggerEvent('onCodeMirrorBeforeInit', array(&$this->params, &$this->basePath, &$this->modePath)); 94 95 $displayData = (object) array('params' => $this->params); 96 $font = $this->params->get('fontFamily', '0'); 97 $fontInfo = $this->getFontInfo($font); 98 99 if (isset($fontInfo)) { 100 if (isset($fontInfo->url)) { 101 $doc->addStyleSheet($fontInfo->url); 102 } 103 104 if (isset($fontInfo->css)) { 105 $displayData->fontFamily = $fontInfo->css . '!important'; 106 } 107 } 108 109 // We need to do output buffering here because layouts may actually 'echo' things which we do not want. 110 ob_start(); 111 LayoutHelper::render('editors.codemirror.styles', $displayData, __DIR__ . '/layouts'); 112 ob_end_clean(); 113 114 $this->app->triggerEvent('onCodeMirrorAfterInit', array(&$this->params, &$this->basePath, &$this->modePath)); 115 } 116 117 /** 118 * Display the editor area. 119 * 120 * @param string $name The control name. 121 * @param string $content The contents of the text area. 122 * @param string $width The width of the text area (px or %). 123 * @param string $height The height of the text area (px or %). 124 * @param int $col The number of columns for the textarea. 125 * @param int $row The number of rows for the textarea. 126 * @param boolean $buttons True and the editor buttons will be displayed. 127 * @param string $id An optional ID for the textarea (note: since 1.6). If not supplied the name is used. 128 * @param string $asset Not used. 129 * @param object $author Not used. 130 * @param array $params Associative array of editor parameters. 131 * 132 * @return string HTML 133 */ 134 public function onDisplay( 135 $name, 136 $content, 137 $width, 138 $height, 139 $col, 140 $row, 141 $buttons = true, 142 $id = null, 143 $asset = null, 144 $author = null, 145 $params = array() 146 ) { 147 // True if a CodeMirror already has autofocus. Prevent multiple autofocuses. 148 static $autofocused; 149 150 $id = empty($id) ? $name : $id; 151 152 // Must pass the field id to the buttons in this editor. 153 $buttons = $this->displayButtons($id, $buttons, $asset, $author); 154 155 // Only add "px" to width and height if they are not given as a percentage. 156 $width .= is_numeric($width) ? 'px' : ''; 157 $height .= is_numeric($height) ? 'px' : ''; 158 159 // Options for the CodeMirror constructor. 160 $options = new stdClass(); 161 $keyMapUrl = ''; 162 163 // Is field readonly? 164 if (!empty($params['readonly'])) { 165 $options->readOnly = 'nocursor'; 166 } 167 168 // Should we focus on the editor on load? 169 if (!$autofocused) { 170 $options->autofocus = isset($params['autofocus']) ? (bool) $params['autofocus'] : false; 171 $autofocused = $options->autofocus; 172 } 173 // Set autorefresh to true - fixes issue when editor is not loaded in a focused tab 174 $options->autoRefresh = true; 175 176 $options->lineWrapping = (bool) $this->params->get('lineWrapping', 1); 177 178 // Add styling to the active line. 179 $options->styleActiveLine = (bool) $this->params->get('activeLine', 1); 180 181 // Do we highlight selection matches? 182 if ($this->params->get('selectionMatches', 1)) { 183 $options->highlightSelectionMatches = array( 184 'showToken' => true, 185 'annotateScrollbar' => true, 186 ); 187 } 188 189 // Do we use line numbering? 190 if ($options->lineNumbers = (bool) $this->params->get('lineNumbers', 1)) { 191 $options->gutters[] = 'CodeMirror-linenumbers'; 192 } 193 194 // Do we use code folding? 195 if ($options->foldGutter = (bool) $this->params->get('codeFolding', 1)) { 196 $options->gutters[] = 'CodeMirror-foldgutter'; 197 } 198 199 // Do we use a marker gutter? 200 if ($options->markerGutter = (bool) $this->params->get('markerGutter', $this->params->get('marker-gutter', 1))) { 201 $options->gutters[] = 'CodeMirror-markergutter'; 202 } 203 204 // Load the syntax mode. 205 $syntax = !empty($params['syntax']) 206 ? $params['syntax'] 207 : $this->params->get('syntax', 'html'); 208 $options->mode = $this->modeAlias[$syntax] ?? $syntax; 209 210 // Load the theme if specified. 211 if ($theme = $this->params->get('theme')) { 212 $options->theme = $theme; 213 214 $this->app->getDocument()->getWebAssetManager() 215 ->registerAndUseStyle('codemirror.theme', $this->basePath . 'theme/' . $theme . '.css'); 216 } 217 218 // Special options for tagged modes (xml/html). 219 if (in_array($options->mode, array('xml', 'html', 'php'))) { 220 // Autogenerate closing tags (html/xml only). 221 $options->autoCloseTags = (bool) $this->params->get('autoCloseTags', 1); 222 223 // Highlight the matching tag when the cursor is in a tag (html/xml only). 224 $options->matchTags = (bool) $this->params->get('matchTags', 1); 225 } 226 227 // Special options for non-tagged modes. 228 if (!in_array($options->mode, array('xml', 'html'))) { 229 // Autogenerate closing brackets. 230 $options->autoCloseBrackets = (bool) $this->params->get('autoCloseBrackets', 1); 231 232 // Highlight the matching bracket. 233 $options->matchBrackets = (bool) $this->params->get('matchBrackets', 1); 234 } 235 236 $options->scrollbarStyle = $this->params->get('scrollbarStyle', 'native'); 237 238 // KeyMap settings. 239 $options->keyMap = $this->params->get('keyMap', false); 240 241 // Support for older settings. 242 if ($options->keyMap === false) { 243 $options->keyMap = $this->params->get('vimKeyBinding', 0) ? 'vim' : 'default'; 244 } 245 246 if ($options->keyMap !== 'default') { 247 $keyMapUrl = $this->basePath . 'keymap/' . $options->keyMap . '.min.js'; 248 } 249 250 $options->keyMapUrl = $keyMapUrl; 251 252 $displayData = (object) array( 253 'options' => $options, 254 'params' => $this->params, 255 'name' => $name, 256 'id' => $id, 257 'cols' => $col, 258 'rows' => $row, 259 'content' => $content, 260 'buttons' => $buttons, 261 'basePath' => $this->basePath, 262 'modePath' => $this->modePath, 263 ); 264 265 // At this point, displayData can be modified by a plugin before going to the layout renderer. 266 $results = $this->app->triggerEvent('onCodeMirrorBeforeDisplay', array(&$displayData)); 267 268 $results[] = LayoutHelper::render('editors.codemirror.element', $displayData, __DIR__ . '/layouts'); 269 270 foreach ($this->app->triggerEvent('onCodeMirrorAfterDisplay', array(&$displayData)) as $result) { 271 $results[] = $result; 272 } 273 274 return implode("\n", $results); 275 } 276 277 /** 278 * Displays the editor buttons. 279 * 280 * @param string $name Button name. 281 * @param mixed $buttons [array with button objects | boolean true to display buttons] 282 * @param mixed $asset Unused. 283 * @param mixed $author Unused. 284 * 285 * @return string|void 286 */ 287 protected function displayButtons($name, $buttons, $asset, $author) 288 { 289 if (is_array($buttons) || (is_bool($buttons) && $buttons)) { 290 $buttonsEvent = new Event( 291 'getButtons', 292 [ 293 'editor' => $name, 294 'buttons' => $buttons, 295 ] 296 ); 297 298 $buttonsResult = $this->getDispatcher()->dispatch('getButtons', $buttonsEvent); 299 $buttons = $buttonsResult['result']; 300 301 return LayoutHelper::render('joomla.editors.buttons', $buttons); 302 } 303 } 304 305 /** 306 * Gets font info from the json data file 307 * 308 * @param string $font A key from the $fonts array. 309 * 310 * @return object 311 */ 312 protected function getFontInfo($font) 313 { 314 static $fonts; 315 316 if (!$fonts) { 317 $fonts = json_decode(file_get_contents(__DIR__ . '/fonts.json'), true); 318 } 319 320 return isset($fonts[$font]) ? (object) $fonts[$font] : null; 321 } 322 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |