diff --git a/editors/ace.inc b/editors/ace.inc new file mode 100644 index 0000000..4ce7b8e --- /dev/null +++ b/editors/ace.inc @@ -0,0 +1,239 @@ + 'Ace (Ajax.org Cloud9 Editor)', + 'vendor url' => 'http://ace.ajax.org/', + 'download url' => 'https://github.com/ajaxorg/ace-builds/', + 'library path' => wysiwyg_get_path('ace'), + 'libraries' => array( + 'src-min-noconflict' => array( + 'title' => 'Minified, no conflict', + 'files' => array( + 'src-min-noconflict/ace.js' => array('preprocess' => FALSE), + ), + ), + 'src-noconflict' => array( + 'title' => 'No conflict', + 'files' => array( + 'src-noconflict/ace.js' => array('preprocess' => FALSE), + ), + ), + 'src-min' => array( + 'title' => 'Minified', + 'files' => array( + 'src-min/ace.js' => array('preprocess' => FALSE), + ), + ), + 'src' => array( + 'title' => 'Source', + 'files' => array( + 'src/ace.js' => array('preprocess' => FALSE), + ), + ), + ), + 'version callback' => 'wysiwyg_ace_version', + 'themes callback' => 'wysiwyg_ace_themes', + 'settings form callback' => 'wysiwyg_ace_settings_form', + 'settings callback' => 'wysiwyg_ace_settings', + 'plugin callback' => 'wysiwyg_ace_plugins', + 'versions' => array( + '0.2.0' => array( + 'js files' => array('ace.js'), + 'css files' => array('ace.css'), + ), + ), + ); + return $editor; +} + +/** + * Version callback for wysiwyg_ace_editor(). + */ +function wysiwyg_ace_version($editor) { + // @todo Detect this for real (perhaps from ChangeLog.txt) rather than + // hardcoding it. + return '0.2.0'; +} + +/** + * Themes callback for wysiwyg_ace_editor(). + */ +function wysiwyg_ace_themes($editor, $profile) { + return array( + 'ambiance', + 'chrome', + 'clouds', + 'clouds_midnight', + 'cobalt', + 'crimson_editor', + 'dawn', + 'dreamweaver', + 'eclipse', + 'github', + 'idle_fingers', + 'kr', + 'merbivore', + 'merbivore_soft', + 'mono_industrial', + 'monokai', + 'pastel_on_dark', + 'solarized_dark', + 'solarized_light', + 'textmate', + 'tomorrow', + 'tomorrow_night', + 'tomorrow_night_blue', + 'tomorrow_night_bright', + 'tomorrow_night_eighties', + 'twilight', + 'vibrant_ink', + 'xcode', + ); +} + +/** + * Settings callback for wysiwyg_ace_editor(). + */ +function wysiwyg_ace_settings($editor, $config, $theme) { + $settings = array( + 'theme' => 'ace/theme/' . $theme, + 'mode' => 'ace/mode/' . ((!empty($config['mode'])) ? $config['mode'] : 'html'), + ); + if (!empty($config['buttons']['default'])) { + foreach ($config['buttons']['default'] as $setting => $value) { + $settings[$setting] = $value; + } + } + return $settings; +} + +/** + * Settings form callback for wysiwyg_ace_editor(). + */ +function wysiwyg_ace_settings_form(&$form, &$form_state) { + // These settings don't make sense for ACE. + $form['appearance']['toolbar_loc']['#access'] = FALSE; + $form['appearance']['toolbar_align']['#access'] = FALSE; + $form['appearance']['path_loc']['#access'] = FALSE; + $form['appearance']['resizing']['#access'] = FALSE; + $form['output']['#access'] = FALSE; + $form['css']['#access'] = FALSE; + + $profile = $form_state['wysiwyg_profile']; + $themes = wysiwyg_ace_themes($form_state['wysiwyg']['editor'], $profile); + + $form['basic']['theme'] = array( + '#type' => 'select', + '#title' => t('Theme'), + '#options' => drupal_map_assoc($themes, '_wysiwyg_ace_make_friendly_name'), + '#default_value' => $profile->settings['theme'], + ); + $form['basic']['language']['#weight'] = 5; + $form['basic']['mode'] = array( + '#type' => 'select', + '#title' => t('Language mode'), + '#description' => t('This determines the syntax highlighting scheme and autocompletion behavior'), + '#options' => wysiwyg_ace_modes(), + '#default_value' => (!empty($profile->settings['mode'])) ? $profile->settings['mode'] : 'html', + ); +} + +/** + * Returns a list of available language modes. + * + * This is not a hook implementation. + */ +function wysiwyg_ace_modes() { + return array( + 'asciidoc' => t('AsciiDoc'), + 'c9search' => t('C9 Search'), + 'c_cpp' => t('C CPP'), + 'clojure' => t('Closure'), + 'coffee' => t('Coffee'), + 'coldfusion' => t('ColdFusion'), + 'csharp' => t('C#'), + 'css' => t('CSS'), + 'diff' => t('Diff'), + 'glsl' => t('GLSL'), + 'golang' => t('Go'), + 'groovy' => t('Groovy'), + 'haxe' => t('Haxe'), + 'html' => t('HTML'), + 'jade' => t('Jade'), + 'java' => t('Java'), + 'javascript' => t('JavaScript'), + 'json' => t('JSON'), + 'jsp' => t('JSP'), + 'jsx' => t('JSX'), + 'latex' => t('LaTeX'), + 'less' => t('LESS'), + 'liquid' => t('Liquid'), + 'lua' => t('Lua'), + 'luapage' => t('LuaPage'), + 'markdown' => t('Markdown'), + 'ocaml' => t('OCaml'), + 'perl' => t('Perl'), + 'pgsql' => t('pgSQL'), + 'php' => t('PHP'), + 'powershell' => t('PowerShell'), + 'python' => t('Python'), + 'ruby' => t('Ruby'), + 'scad' => t('SCAD'), + 'scala' => t('Scala'), + 'scss' => t('SCSS'), + 'sh' => t('SH'), + 'sql' => t('SQL'), + 'svg' => t('SVG'), + 'tcl' => t('TCL'), + 'textile' => t('Textile'), + 'text' => t('Text'), + 'typescript' => t('TypeScript'), + 'xml' => t('XML'), + 'xquery' => t('XQuery'), + 'yaml' => t('YAML'), + ); +} + +/** + * Implements hook_INCLUDE_plugins(). + */ +function wysiwyg_ace_plugins($editor) { + return array( + 'default' => array( + 'buttons' => array( + 'highlight_active_line' => ('Highlight active line'), + 'highlight_selected_word' => t('Highlight selected word'), + 'show_fold_widgets' => t('Show fold widgets'), + 'show_invisibles' => t('Show invisible characters'), + 'show_print_margin' => t('Show print margin'), + ), + 'internal' => TRUE, + ), + ); +} + +/** + * Make a friendly name from a machine name. For use with drupal_map_assoc(). + * + * Replaces underscores (_) with spaces ( ) and capitalizes words. + * + * @param string $name + * The machine name to be transformed. + * + * @return string + * The resulting friendly name. + */ +function _wysiwyg_ace_make_friendly_name($name) { + $name = str_replace('_', ' ', $name); + $name = ucwords($name); + return $name; +} diff --git a/editors/css/ace.css b/editors/css/ace.css new file mode 100644 index 0000000..012dc4c --- /dev/null +++ b/editors/css/ace.css @@ -0,0 +1,10 @@ +.wysiwyg-ace-wrapper { + position: relative; +} +.ace_editor { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; +} diff --git a/editors/js/ace.js b/editors/js/ace.js new file mode 100644 index 0000000..40993d4 --- /dev/null +++ b/editors/js/ace.js @@ -0,0 +1,46 @@ +(function ($) { +"use strict"; + +Drupal.wysiwyg.editor.instances = []; + +/** + * Attach this editor to a target element. + */ +Drupal.wysiwyg.editor.attach.ace = function (context, params, settings) { + var textarea = $('#' + params.field) + // Give the incipient editor a wrapper to expand to. + .wrap('
') + // Create a DIV to target. + .after('
'); + // Attach the editor. + var editor = Drupal.wysiwyg.editor.instances[params.field] = ace.edit(params.field + '-ace'); + // Apply hardcoded settings. + editor.getSession().setTabSize(2); + // Apply user configured settings. + editor.setTheme(settings.theme); + editor.getSession().setMode(settings.mode); + editor.setHighlightActiveLine(settings.hasOwnProperty('highlight_active_line')); + editor.setHighlightSelectedWord(settings.hasOwnProperty('highlight_selected_word')); + editor.setShowFoldWidgets(settings.hasOwnProperty('show_fold_widgets')); + editor.setShowInvisibles(settings.hasOwnProperty('show_invisibles')); + editor.setShowPrintMargin(settings.hasOwnProperty('show_print_margin')); + // Populate the editor from the TEXTAREA. + editor.getSession().setValue(textarea.val()); +}; + +/** + * Detach an editor. + */ +Drupal.wysiwyg.editor.detach.ace = function (context, params, trigger) { + if (params !== undefined) { + var editor = Drupal.wysiwyg.editor.instances[params.field]; + var textarea = $('#' + params.field); + // Save the contents back to the textarea. + textarea.val(editor.getSession().getValue()); + // Destroy the editor. + $('#' + params.field).unwrap('
'); + $('#' + params.field + '-ace').remove(); + } +}; + +})(jQuery);