r89810 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89809‎ | r89810 | r89811 >
Date:01:11, 10 June 2011
Author:brion
Status:deferred
Tags:
Comment:
Partway through integrating CodeEditor more closely with WikiEditor. Special character insertions now work! Bold, link etc will insert their sample text, which is less useful but hey.
Modified paths:
  • /trunk/extensions/CodeEditor/CodeEditor.php (modified) (history)
  • /trunk/extensions/CodeEditor/modules/ext.codeEditor.js (modified) (history)
  • /trunk/extensions/CodeEditor/modules/jquery.codeEditor.js (added) (history)

Diff [purge]

Index: trunk/extensions/CodeEditor/CodeEditor.php
@@ -27,13 +27,21 @@
2828 $tpl = array(
2929 'localBasePath' => dirname( __FILE__ ) . '/modules',
3030 'remoteExtPath' => 'CodeEditor/modules',
31 - 'group' => 'ext.codeEditor',
 31+ 'group' => 'ext.wikiEditor',
3232 );
3333
3434 $wgResourceModules['ext.codeEditor'] = array(
3535 'scripts' => 'ext.codeEditor.js',
3636 'dependencies' => array(
3737 'ext.wikiEditor',
 38+ 'jquery.codeEditor'
 39+ ),
 40+) + $tpl;
 41+
 42+$wgResourceModules['jquery.codeEditor'] = array(
 43+ 'scripts' => 'jquery.codeEditor.js',
 44+ 'dependencies' => array(
 45+ 'jquery.wikiEditor',
3846 'ext.codeEditor.ace',
3947 ),
4048 ) + $tpl;
Index: trunk/extensions/CodeEditor/modules/jquery.codeEditor.js
@@ -0,0 +1,207 @@
 2+/* Ace syntax-highlighting code editor extension for wikiEditor */
 3+
 4+( function( $ ) {
 5+
 6+$.wikiEditor.modules.codeEditor = {
 7+
 8+/**
 9+ * Core Requirements
 10+ */
 11+'req': [ 'codeEditor' ],
 12+/**
 13+ * Configuration
 14+ */
 15+cfg: {
 16+ //
 17+},
 18+/**
 19+ * API accessible functions
 20+ */
 21+api: {
 22+ //
 23+},
 24+/**
 25+ * Event handlers
 26+ */
 27+evt: {
 28+ //
 29+},
 30+/**
 31+ * Internally used functions
 32+ */
 33+fn: {
 34+}
 35+
 36+};
 37+
 38+$.wikiEditor.extensions.codeEditor = function( context ) {
 39+
 40+/*
 41+ * Event Handlers
 42+ *
 43+ * These act as filters returning false if the event should be ignored or returning true if it should be passed
 44+ * on to all modules. This is also where we can attach some extra information to the events.
 45+ */
 46+context.evt = $.extend( context.evt, {
 47+ /**
 48+ * Filters change events, which occur when the user interacts with the contents of the iframe. The goal of this
 49+ * function is to both classify the scope of changes as 'division' or 'character' and to prevent further
 50+ * processing of events which did not actually change the content of the iframe.
 51+ */
 52+ 'keydown': function( event ) {
 53+ },
 54+ 'change': function( event ) {
 55+ },
 56+ 'delayedChange': function( event ) {
 57+ },
 58+ 'cut': function( event ) {
 59+ },
 60+ 'paste': function( event ) {
 61+ },
 62+ 'ready': function( event ) {
 63+ }
 64+} );
 65+
 66+/**
 67+ * Internally used functions
 68+ */
 69+context.fn = $.extend( context.fn, {
 70+ 'saveCursorAndScrollTop': function() {
 71+ // Stub out textarea behavior
 72+ return;
 73+ },
 74+ 'restoreCursorAndScrollTop': function() {
 75+ // Stub out textarea behavior
 76+ return;
 77+ },
 78+ 'saveSelection': function() {
 79+ },
 80+ 'restoreSelection': function() {
 81+ },
 82+ /**
 83+ * Sets up the iframe in place of the textarea to allow more advanced operations
 84+ */
 85+ 'setupCodeEditor': function() {
 86+ var box = context.$textarea;
 87+
 88+ var matches = /\.(js|css)$/.exec(wgTitle);
 89+ if (matches && (wgNamespaceNumber == 2 /* User: */ || wgNamespaceNumber == 8 /* MediaWiki: */)) {
 90+ var ext = matches[1];
 91+ var map = {js: 'javascript', css: 'css'};
 92+ var lang = map[ext];
 93+
 94+ // Ace doesn't like replacing a textarea directly.
 95+ // We'll stub this out to sit on top of it...
 96+ // line-height is needed to compensate for oddity in WikiEditor extension, which zeroes the line-height on a parent container
 97+ var container = $('<div style="position: relative"><div class="editor" style="line-height: 1.5em; top: 0px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray"></div></div>').insertAfter(box);
 98+ var editdiv = container.find('.editor');
 99+
 100+ box.css('display', 'none');
 101+ container.width(box.width())
 102+ .height(box.height());
 103+
 104+ editdiv.text(box.val());
 105+ context.codeEditor = ace.edit(editdiv[0]);
 106+
 107+ // fakeout for bug 29328
 108+ context.$iframe = [
 109+ {
 110+ contentWindow: {
 111+ focus: function() {
 112+ context.codeEditor.focus();
 113+ }
 114+ }
 115+ }
 116+ ];
 117+ box.closest('form').submit(function(event) {
 118+ box.val(context.codeEditor.getSession().getValue());
 119+ });
 120+ context.codeEditor.getSession().setMode(new (require("ace/mode/" + lang).Mode));
 121+
 122+ // Force the box to resize horizontally to match in future :D
 123+ var resize = function() {
 124+ container.width(box.width());
 125+ };
 126+ $(window).resize(resize);
 127+ // Use jquery.ui.resizable so user can make the box taller too
 128+ container.resizable({
 129+ handles: 's',
 130+ minHeight: box.height(),
 131+ resize: function() {
 132+ context.codeEditor.resize();
 133+ }
 134+ });
 135+
 136+ var summary = $('#wpSummary');
 137+ if (summary.val() == '') {
 138+ summary.val('/* using [[mw:CodeEditor|CodeEditor]] */ ');
 139+ }
 140+ // Let modules know we're ready to start working with the content
 141+ context.fn.trigger( 'ready' );
 142+ }
 143+ },
 144+
 145+ /*
 146+ * Compatibility with the $.textSelection jQuery plug-in. When the iframe is in use, these functions provide
 147+ * equivilant functionality to the otherwise textarea-based functionality.
 148+ */
 149+
 150+ 'getElementAtCursor': function() {
 151+ },
 152+
 153+ /**
 154+ * Gets the currently selected text in the content
 155+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 156+ */
 157+ 'getSelection': function() {
 158+ return context.$codeEditor.getSelectionRange();
 159+ },
 160+ /**
 161+ * Inserts text at the begining and end of a text selection, optionally inserting text at the caret when
 162+ * selection is empty.
 163+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 164+ */
 165+ 'encapsulateSelection': function( options ) {
 166+ // Hack! Handle actual selection logic.
 167+ var text = options.pre + options.peri + options.post;
 168+ context.codeEditor.insert( text );
 169+ },
 170+ /**
 171+ * Gets the position (in resolution of bytes not nessecarily characters) in a textarea
 172+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 173+ */
 174+ 'getCaretPosition': function( options ) {
 175+ },
 176+ /**
 177+ * Sets the selection of the content
 178+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 179+ *
 180+ * @param start Character offset of selection start
 181+ * @param end Character offset of selection end
 182+ * @param startContainer Element in iframe to start selection in. If not set, start is a character offset
 183+ * @param endContainer Element in iframe to end selection in. If not set, end is a character offset
 184+ */
 185+ 'setSelection': function( options ) {
 186+ },
 187+ /**
 188+ * Scroll a textarea to the current cursor position. You can set the cursor position with setSelection()
 189+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 190+ */
 191+ 'scrollToCaretPosition': function( options ) {
 192+ //context.fn.scrollToTop( context.fn.getElementAtCursor(), true );
 193+ },
 194+ /**
 195+ * Scroll an element to the top of the iframe
 196+ * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
 197+ *
 198+ * @param $element jQuery object containing an element in the iframe
 199+ * @param force If true, scroll the element even if it's already visible
 200+ */
 201+ 'scrollToTop': function( $element, force ) {
 202+ }
 203+} );
 204+
 205+/* Setup the editor */
 206+context.fn.setupCodeEditor();
 207+
 208+} } )( jQuery );
Property changes on: trunk/extensions/CodeEditor/modules/jquery.codeEditor.js
___________________________________________________________________
Added: svn:eol-style
1209 + native
Index: trunk/extensions/CodeEditor/modules/ext.codeEditor.js
@@ -35,56 +35,11 @@
3636 * - ctrl+R, ctrl+L, ctrl+T are taken over by the editor, which is SUPER annoying
3737 * https://github.com/ajaxorg/ace/issues/210
3838 */
39 -(function(mw, $) {
40 - // This should point to a checkout of Ace source.
41 - var editorBase = mw.config.get('wgExtensionAssetsPath') + '/CodeEditor/modules/ace/';
 39+/*
 40+ * JavaScript for WikiEditor Table of Contents
 41+ */
4242
43 - $(function() {
44 - var box = $('#wpTextbox1');
45 - if (box.length > 0) {
46 - var matches = /\.(js|css)$/.exec(wgTitle);
47 - if (matches && (wgNamespaceNumber == 2 /* User: */ || wgNamespaceNumber == 8 /* MediaWiki: */)) {
48 - var ext = matches[1];
49 - var map = {js: 'javascript', css: 'css'};
50 - var lang = map[ext];
51 -
52 - // Ace doesn't like replacing a textarea directly.
53 - // We'll stub this out to sit on top of it...
54 - // line-height is needed to compensate for oddity in WikiEditor extension, which zeroes the line-height on a parent container
55 - var container = $('<div style="position: relative"><div class="editor" style="line-height: 1.5em; top: 0px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray"></div></div>').insertAfter(box);
56 - var editdiv = container.find('.editor');
57 -
58 - box.css('display', 'none');
59 - container.width(box.width())
60 - .height(box.height());
61 -
62 - editdiv.text(box.val());
63 - var editor = ace.edit(editdiv[0]);
64 - box.closest('form').submit(function(event) {
65 - box.val(editor.getSession().getValue());
66 - });
67 - editor.getSession().setMode(new (require("ace/mode/" + lang).Mode));
68 -
69 - // Force the box to resize horizontally to match in future :D
70 - var resize = function() {
71 - container.width(box.width());
72 - };
73 - $(window).resize(resize);
74 - // Use jquery.ui.resizable so user can make the box taller too
75 - container.resizable({
76 - handles: 's',
77 - minHeight: box.height(),
78 - resize: function() {
79 - editor.resize();
80 - }
81 - });
82 -
83 - var summary = $('#wpSummary');
84 - if (summary.val() == '') {
85 - summary.val('/* using [[mw:CodeEditor|CodeEditor]] */ ');
86 - }
87 - }
88 - }
89 - });
90 -
91 -})(mediaWiki, jQuery);
 43+$( document ).ready( function() {
 44+ // Add code editor module
 45+ $( '#wpTextbox1' ).wikiEditor( 'addModule', 'codeEditor' );
 46+} );

Status & tagging log