From 51589757b8e92472a4fe98be82d589b7101e1ab8 Mon Sep 17 00:00:00 2001 From: Travis Carden Date: Fri, 13 Jan 2012 17:07:09 -0600 Subject: [PATCH] Added CodeMirror support. --- editors/codemirror.inc | 148 ++++++++++++++++++++++++++++++++++++++++++++ editors/css/codemirror.css | 7 ++ editors/js/codemirror.js | 37 +++++++++++ 3 files changed, 192 insertions(+), 0 deletions(-) create mode 100644 editors/codemirror.inc create mode 100644 editors/css/codemirror.css create mode 100644 editors/js/codemirror.js diff --git a/editors/codemirror.inc b/editors/codemirror.inc new file mode 100644 index 0000000..002b762 --- /dev/null +++ b/editors/codemirror.inc @@ -0,0 +1,148 @@ + 'CodeMirror', + 'vendor url' => 'http://codemirror.net', + 'download url' => 'http://codemirror.net', + 'library path' => wysiwyg_get_path('codemirror'), + 'libraries' => array( + '' => array( + 'title' => 'CodeMirror', + 'files' => array( + 'lib/codemirror.js', + ), + ), + ), + 'version callback' => 'wysiwyg_codemirror_version', + 'settings callback' => 'wysiwyg_codemirror_settings', + 'plugin callback' => 'wysiwyg_codemirror_plugins', + 'load callback' => 'wysiwyg_codemirror_load', + 'versions' => array( + '2' => array( + 'js files' => array('codemirror.js'), + 'css files' => array('codemirror.css'), + ), + ), + ); + return $editor; +} + +/** + * Detect editor version. + * + * @param $editor + * An array containing editor properties as returned from hook_editor(). + * + * @return + * The installed editor version. + */ +function wysiwyg_codemirror_version($editor) { + $fp = $editor['library path'] . '/README.md'; + if (!file_exists($fp)) { + return; + } + $fp = fopen($fp, 'r'); + $line = fgets($fp); + if (preg_match('@([0-9\.]+)$@', $line, $version)) { + fclose($fp); + return $version[1]; + } + fclose($fp); +} + +/** + * Perform additional actions upon loading this editor. + * + * @param $editor + * A processed hook_editor() array of editor properties. + * @param $library + * The internal library name (array key) to use. + */ +function wysiwyg_codemirror_load($editor, $library) { + // @TODO: Make themes and modes into editor settings + drupal_add_css($editor['library path'] . '/lib/codemirror.css'); + drupal_add_css($editor['library path'] . '/theme/default.css'); + + drupal_add_js($editor['library path'] . '/lib/codemirror.js'); + drupal_add_js($editor['library path'] . '/mode/clike/clike.js'); + drupal_add_js($editor['library path'] . '/mode/css/css.js'); + drupal_add_js($editor['library path'] . '/mode/diff/diff.js'); + drupal_add_js($editor['library path'] . '/mode/haskell/haskell.js'); + drupal_add_js($editor['library path'] . '/mode/htmlmixed/htmlmixed.js'); + drupal_add_js($editor['library path'] . '/mode/javascript/javascript.js'); + drupal_add_js($editor['library path'] . '/mode/php/php.js'); + drupal_add_js($editor['library path'] . '/mode/stex/stex.js'); + drupal_add_js($editor['library path'] . '/mode/xml/xml.js'); +} + +/** + * Return runtime editor settings for a given wysiwyg profile. + * + * @param $editor + * A processed hook_editor() array of editor properties. + * @param $config + * An array containing wysiwyg editor profile settings. + * @param $theme + * The name of a theme/GUI/skin to use. + * + * @return + * A settings array to be populated in + * Drupal.settings.wysiwyg.configs.{editor} + */ +function wysiwyg_codemirror_settings($editor, $config, $theme) { + /* Defaults */ + $settings = array( + 'mode' => 'application/x-httpd-php', + 'indentUnit' => 2, + 'indentWithTabs' => FALSE, + 'tabMode' => 'shift', + 'enterMode' => 'indent', + 'electricChars' => FALSE, + 'lineNumbers' => FALSE, + 'gutter' => FALSE, + 'readOnly' => FALSE, + 'matchBrackets' => FALSE + ); + + $all_settings = array_keys($settings); + + if (is_array($config['buttons']['default'])) { + foreach ($config['buttons']['default'] as $key => $value) { + if ($value) { + if (in_array($key, $all_settings)) { + $settings[$key] = ($value != 0); + } + } + } + } + + return $settings; +} + +/** + * Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin(). + */ +function wysiwyg_codemirror_plugins($editor) { + return array( + 'default' => array( + 'buttons' => array( + 'lineNumbers' => t('Line Numbers'), + 'matchBrackets' => t('Match Brackets'), + 'electricChars' => t('Electric Characters'), + 'indentWithTabs' => t('Indent With Tabs'), + 'gutter' => t('Gutter'), + 'matchBrackets' => t('Match Brackets') + ) + ), + 'internal' => TRUE, + ); +} diff --git a/editors/css/codemirror.css b/editors/css/codemirror.css new file mode 100644 index 0000000..6dae03e --- /dev/null +++ b/editors/css/codemirror.css @@ -0,0 +1,7 @@ + +/** + * CodeMirror + */ +.CodeMirror { + border: 1px solid #ddd +} diff --git a/editors/js/codemirror.js b/editors/js/codemirror.js new file mode 100644 index 0000000..1c7098e --- /dev/null +++ b/editors/js/codemirror.js @@ -0,0 +1,37 @@ +(function($) { + +/* Maintain a list of active editors on the page */ +var instances = new Object; + +/** + * Attach this editor to a target element. + * + * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook. + */ +Drupal.wysiwyg.editor.attach.codemirror = function(context, params, settings) { + var textArea = document.getElementById(params.field); + if (textArea) { + instances[params.field] = CodeMirror.fromTextArea(textArea, settings); + } + + if (params.resizable) { + jQuery('.CodeMirror-scroll').css({ + // @TODO: Get these from editor settings + //'height' : 'auto', + 'overflow-y' : 'hidden', + 'overflow-x' : 'auto' + }); + } +}; + +/** + * Detach a single or all editors. + * + * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook. + */ +Drupal.wysiwyg.editor.detach.codemirror = function(context, params) { + instances[params.field].toTextArea(); + delete instances[params.field]; +}; + +})(jQuery); -- 1.7.4.1