diff --git a/editors/ace.inc b/editors/ace.inc new file mode 100644 index 0000000..10a9aad --- /dev/null +++ b/editors/ace.inc @@ -0,0 +1,247 @@ + '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) { + $groups = wysiwyg_ace_themes_rich(); + $themes = array(); + foreach ($groups as $group) { + $themes = array_merge($themes, array_keys($group)); + } + return $themes; +} + +/** + * Returns a rich list of available themes. + * + * @return array + * An array of available themes suitable for Form API select element options. + */ +function wysiwyg_ace_themes_rich() { + return array( + 'Bright' => array( + 'chrome' => t('Chrome'), + 'clouds' => t('Clouds'), + 'crimson_editor' => t('Crimson Editor'), + 'dawn' => t('Dawn'), + 'dreamweaver' => t('Dreamweaver'), + 'eclipse' => t('Eclipse'), + 'github' => t('GitHub'), + 'solarized_light' => t('Solarized Light'), + 'textmate' => t('TextMate'), + 'tomorrow' => t('Tomorrow'), + 'xcode' => t('XCode'), + ), + 'Dark' => array( + 'ambiance' => t('Ambiance'), + 'clouds_midnight' => t('Clouds Midnight'), + 'cobalt' => t('Cobalt'), + 'idle_fingers' => t('idleFingers'), + 'kr_theme' => t('krTheme'), + 'merbivore' => t('Merbivore'), + 'merbivore_soft' => t('Merbivore Soft'), + 'mono_industrial' => t('Mono Industrial'), + 'monokai' => t('Monokai'), + 'pastel_on_dark' => t('Pastel on Dark'), + 'solarized_dark' => t('Solarized Dark'), + 'twilight' => t('Twilight'), + 'tomorrow_night' => t('Tomorrow Night'), + 'tomorrow_night_blue' => t('Tomorrow Night Blue'), + 'tomorrow_night_bright' => t('Tomorrow Night Bright'), + 'tomorrow_night_eighties' => t('Tomorrow Night 80s'), + 'vibrant_ink' => t('Vibrant Ink'), + ), + ); +} + +/** + * Settings callback for wysiwyg_ace_editor(). + */ +function wysiwyg_ace_settings($editor, $config, $theme) { + $settings = array( + 'mode' => 'ace/mode/' . ((!empty($config['mode'])) ? $config['mode'] : 'html'), + 'tab_size' => (!empty($config['tab_size'])) ? (int) $config['tab_size'] : 2, + 'theme' => 'ace/theme/' . $theme, + ); + 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']['#access'] = FALSE; + $form['output']['#access'] = FALSE; + $form['css']['#access'] = FALSE; + $form['basic']['language']['#access'] = FALSE; + + $profile = $form_state['wysiwyg_profile']; + + $form['basic']['theme'] = array( + '#type' => 'select', + '#title' => t('Theme'), + '#options' => wysiwyg_ace_themes_rich(), + '#default_value' => $profile->settings['theme'], + ); + $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', + ); + $form['basic']['tab_size'] = array( + '#type' => 'select', + '#title' => t('Tab size'), + '#options' => drupal_map_assoc(array(2, 4, 6, 8)), + '#default_value' => (!empty($profile->settings['tab_size'])) ? $profile->settings['tab_size'] : 2, + ); +} + +/** + * Returns a list of available language modes. + * + * @return array + * An array suitable for Form API select element options. + */ +function wysiwyg_ace_modes() { + return array( + 'asciidoc' => t('AsciiDoc'), + 'c9search' => t('C9Search'), + 'c_cpp' => t('C/C++'), + 'clojure' => t('Clojure'), + 'coffee' => t('CoffeeScript'), + '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('OpenSCAD'), + 'scala' => t('Scala'), + 'scss' => t('SCSS'), + 'sh' => t('SH'), + 'sql' => t('SQL'), + 'svg' => t('SVG'), + 'tcl' => t('Tcl'), + 'text' => t('Text'), + 'textile' => t('Textile'), + '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' => t('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'), + 'use_soft_tabs' => t('Use soft tabs'), + 'use_wrap_mode' => t('Use word wrap mode'), + ), + 'internal' => TRUE, + ), + ); +} 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..975cacb --- /dev/null +++ b/editors/js/ace.js @@ -0,0 +1,47 @@ +(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 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')); + editor.getSession().setTabSize(settings.tab_size); + editor.getSession().setUseSoftTabs(settings.hasOwnProperty('use_soft_tabs')); + editor.getSession().setUseWrapMode(settings.hasOwnProperty('use_wrap_mode')); + // 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);