From bf675819244ed82c601bd2b04e0e175960a373d7 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Thu, 4 Aug 2011 22:33:59 +0000 Subject: [PATCH] CodeEditor ext: Add an experimental demo (off by default) mode to edit SyntaxHighlight_GeSHi sections inline using Ace editor Not ready for prime-time. :) Doesn't actually save pages (just updates the live view), and seems to have problems when invoked multiple times. Not all GeSHi languages are supported. Colors of course are different. Set $wgCodeEditorGeshiIntegration = true to enable; adds a 'section edit link' on source bits. --- CodeEditor.hooks.php | 8 ++ CodeEditor.php | 38 ++++++++ modules/ext.codeEditor.geshi.js | 148 ++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 modules/ext.codeEditor.geshi.js diff --git a/CodeEditor.hooks.php b/CodeEditor.hooks.php index a033f42d..c3e69179 100644 --- a/CodeEditor.hooks.php +++ b/CodeEditor.hooks.php @@ -8,4 +8,12 @@ class CodeEditorHooks { } return true; } + + public static function onBeforePageDisplay( $out, $skin ) { + global $wgCodeEditorGeshiIntegration; + if ( $wgCodeEditorGeshiIntegration ) { + $out->addModules( 'ext.codeEditor.geshi' ); + } + return true; + } } diff --git a/CodeEditor.php b/CodeEditor.php index 29792b91..1af0368d 100644 --- a/CodeEditor.php +++ b/CodeEditor.php @@ -23,6 +23,7 @@ $wgAutoloadClasses['CodeEditorHooks'] = $dir . '/CodeEditor.hooks.php'; $wgExtensionMessagesFiles['CodeEditor'] = $dir . '/CodeEditor.i18n.php'; $wgHooks['EditPage::showEditForm:initial'][] = 'CodeEditorHooks::editPageShowEditFormInitial'; +$wgHooks['BeforePageDisplay'][] = 'CodeEditorHooks::onBeforePageDisplay'; $tpl = array( 'localBasePath' => dirname( __FILE__ ) . '/modules', @@ -51,9 +52,46 @@ $wgResourceModules['jquery.codeEditor'] = array( // Minimal bundling of a couple bits of Ace $wgResourceModules['ext.codeEditor.ace'] = array( + 'group' => 'ext.codeEditor.ace', 'scripts' => array( 'ace/ace-uncompressed.js', 'ace/mode-javascript.js', 'ace/mode-css.js', ), ) + $tpl; + +// Extra highlighting modes to match some availabel GeSHi highlighting languages +$wgResourceModules['ext.codeEditor.ace.modes'] = array( + 'group' => 'ext.codeEditor.ace', + 'scripts' => array( + 'ace/mode-c_cpp.js', + 'ace/mode-clojure.js', + 'ace/mode-csharp.js', + 'ace/mode-coffee.js', + 'ace/mode-groovy.js', + 'ace/mode-html.js', + 'ace/mode-java.js', + 'ace/mode-ocaml.js', + 'ace/mode-perl.js', + 'ace/mode-php.js', + 'ace/mode-python.js', + 'ace/mode-ruby.js', + 'ace/mode-scala.js', + ), + 'dependencies' => 'ext.codeEditor.ace', +) + $tpl; + +// Helper to add inline [edit] links to sections +$wgResourceModules['ext.codeEditor.geshi'] = array( + 'scripts' => array( + 'ext.codeEditor.geshi.js' + ), + 'messages' => array( + 'editsection', + 'editsection-brackets', + 'savearticle' + ) +) + $tpl; + +// Experimental feature; not ready yet. +$wgCodeEditorGeshiIntegration = false; diff --git a/modules/ext.codeEditor.geshi.js b/modules/ext.codeEditor.geshi.js new file mode 100644 index 00000000..331cb7df --- /dev/null +++ b/modules/ext.codeEditor.geshi.js @@ -0,0 +1,148 @@ +/** + * This is experimental and does not yet actually save anything back. + * Has to be manually enabled. + * Needs some code de-dup with the full-page JS/CSS page editing. + */ + +$(function() { + var $sources = $('.mw-geshi'); + if ($sources.length > 0) { + var setupEditor = function($div) { + var $link = $('') + .text(mediaWiki.msg('editsection')) + .attr('href', '#') + .attr('title', 'Edit this code section') + .click(function(event) { + openEditor($div) + event.preventDefault(); + }); + var $edit = $('') + .css('float', 'right') + .append('[') + .append($link) + .append(']'); // @fixme use the editsection-brackets msg + $div.prepend($edit); + }; + var openEditor = function($div) { + var $main = $div.find('div'), + geshiLang = null, + matches = /(?:^| )source-([a-z0-9_-]+)/.exec($main.attr('class')); + if (matches) { + geshiLang = matches[1]; + } + mediaWiki.loader.using('ext.codeEditor.ace.modes', function() { + // @fixme de-duplicate + var map = { + c: 'c_cpp', + cpp: 'c_cpp', + clojure: 'clojure', + csharp: 'csharp', + css: 'css', + coffeescript: 'coffee', + groovy: 'groovy', + html4strict: 'html', + html5: 'html', + java: 'java', + java5: 'java', + javascript: 'javascript', + jquery: 'javascript', + ocaml: 'ocaml', + perl: 'perl', + php: 'php', + python: 'python', + ruby: 'ruby', + scala: 'scala', + xml: 'xml' + }; + + + // Disable some annoying commands + var canon = require('pilot/canon'); + canon.removeCommand('replace'); // ctrl+R + canon.removeCommand('transposeletters'); // ctrl+T + canon.removeCommand('gotoline'); // ctrl+L + + var $container = $('
') + .attr('style', 'top: 32px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray') + .text($main.text()); // quick hack :D + + var $label = $('