Update formatting of JavaScript files

Change-Id: I7a18b7f76f7c0a064645f23974f1fe09dafc4ca2
This commit is contained in:
Siebrand Mazeland 2013-12-31 13:03:11 +01:00
parent 37e2ec1286
commit 2d121364d3
3 changed files with 485 additions and 489 deletions

View file

@ -4,33 +4,33 @@
* Needs some code de-dup with the full-page JS/CSS page editing. * Needs some code de-dup with the full-page JS/CSS page editing.
*/ */
$(function() { $( function () {
var $sources = $('.mw-geshi'); var $sources = $( '.mw-geshi' );
if ($sources.length > 0) { if ( $sources.length > 0 ) {
var setupEditor = function($div) { var setupEditor = function ( $div ) {
var $link = $('<a>') var $link = $( '<a>' )
.text(mediaWiki.msg('editsection')) .text( mediaWiki.msg( 'editsection' ) )
.attr('href', '#') .attr( 'href', '#' )
.attr('title', 'Edit this code section') .attr( 'title', 'Edit this code section' )
.click(function(event) { .click( function ( event ) {
openEditor($div); openEditor( $div );
event.preventDefault(); event.preventDefault();
}); } );
var $edit = $('<span>') var $edit = $( '<span>' )
.addClass('mw-editsection') .addClass( 'mw-editsection' )
.append('<span class="mw-editsection-bracket">[</span>') .append( '<span class="mw-editsection-bracket">[</span>' )
.append($link) .append( $link )
.append('<span class="mw-editsection-bracket">]</span>'); .append( '<span class="mw-editsection-bracket">]</span>' );
$div.prepend($edit); $div.prepend( $edit );
}; };
var openEditor = function($div) { var openEditor = function ( $div ) {
var $main = $div.find('div'), var $main = $div.find( 'div' ),
geshiLang = null, geshiLang = null,
matches = /(?:^| )source-([a-z0-9_-]+)/.exec($main.attr('class')); matches = /(?:^| )source-([a-z0-9_-]+)/.exec( $main.attr( 'class' ) );
if (matches) { if ( matches ) {
geshiLang = matches[1]; geshiLang = matches[1];
} }
mediaWiki.loader.using('ext.codeEditor.ace.modes', function() { mediaWiki.loader.using( 'ext.codeEditor.ace.modes', function () {
// @fixme de-duplicate // @fixme de-duplicate
var map = { var map = {
c: 'c_cpp', c: 'c_cpp',
@ -56,94 +56,92 @@ $(function() {
xml: 'xml' xml: 'xml'
}; };
// Disable some annoying commands // Disable some annoying commands
var canon = require('pilot/canon'); var canon = require( 'pilot/canon' );
canon.removeCommand('replace'); // ctrl+R canon.removeCommand( 'replace' ); // ctrl+R
canon.removeCommand('transposeletters'); // ctrl+T canon.removeCommand( 'transposeletters' ); // ctrl+T
canon.removeCommand('gotoline'); // ctrl+L canon.removeCommand( 'gotoline' ); // ctrl+L
var $container = $('<div>') var $container = $( '<div>' )
.attr('style', 'top: 32px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray') .attr( 'style', 'top: 32px; left: 0px; right: 0px; bottom: 0px; border: 1px solid gray' )
.text($main.text()); // quick hack :D .text( $main.text() ); // quick hack :D
var $label = $('<label>').text('Source language: '); var $label = $( '<label>' ).text( 'Source language: ' );
var $langDropDown = $('<select>'); var $langDropDown = $( '<select>' );
$.each(map, function(geshiLang, aceLang) { $.each( map, function ( geshiLang, aceLang ) {
var $opt = $('<option>') var $opt = $( '<option>' )
.text(geshiLang) .text( geshiLang )
.val(geshiLang) .val( geshiLang )
.appendTo($langDropDown); .appendTo( $langDropDown );
}); } );
$langDropDown $langDropDown
.val(geshiLang) .val( geshiLang )
.appendTo($label) .appendTo( $label )
.change(function(event) { .change( function ( event ) {
setLanguage($(this).val()); setLanguage( $( this ).val() );
}); } );
var $save = $('<button>') var $save = $( '<button>' )
.text(mediaWiki.msg('savearticle')) .text( mediaWiki.msg( 'savearticle' ) )
.click(function(event) { .click( function ( event ) {
// horrible hack ;) // horrible hack ;)
var src = codeEditor.getSession().getValue(); var src = codeEditor.getSession().getValue();
var tag = '<source lang="' + geshiLang + '">' + src + '</source>'; var tag = '<source lang="' + geshiLang + '">' + src + '</source>';
$.ajax(wgScriptPath + '/api' + wgScriptExtension, { $.ajax( wgScriptPath + '/api' + wgScriptExtension, {
data: { data: {
action: 'parse', action: 'parse',
text: tag, text: tag,
format: 'json' format: 'json'
}, },
type: 'POST', type: 'POST',
success: function(data, xhr) { success: function ( data, xhr ) {
var $html = $(data.parse.text['*']); var $html = $( data.parse.text['*'] );
$div.replaceWith($html); $div.replaceWith( $html );
setupEditor($html); setupEditor( $html );
closeEditor(); closeEditor();
event.preventDefault(); event.preventDefault();
} }
}); } );
}); } );
var $cancel = $('<button>') var $cancel = $( '<button>' )
.text('Close').click(function(event) { .text( 'Close' ).click( function ( event ) {
$xcontainer.remove(); $xcontainer.remove();
$div.css('display', 'block'); $div.css( 'display', 'block' );
event.preventDefault(); event.preventDefault();
}); } );
var $controls = $('<div>') var $controls = $( '<div>' )
.append($label) .append( $label )
.append($save) .append( $save )
.append($cancel); .append( $cancel );
var $xcontainer = $('<div style="position: relative"></div>') var $xcontainer = $( '<div style="position: relative"></div>' )
.append($controls) .append( $controls )
.append($container); .append( $container );
$xcontainer.width($main.width()) $xcontainer.width( $main.width() )
.height($main.height() * 1.1 + 64 + 32); .height( $main.height() * 1.1 + 64 + 32 );
$div.css('display', 'none'); $div.css( 'display', 'none' );
$xcontainer.insertAfter($div); $xcontainer.insertAfter( $div );
var codeEditor = ace.edit($container[0]); var codeEditor = ace.edit( $container[0] );
var setLanguage = function(lang) { var setLanguage = function ( lang ) {
geshiLang = lang; geshiLang = lang;
var aceLang = map[geshiLang]; var aceLang = map[geshiLang];
codeEditor.getSession().setMode(new (require("ace/mode/" + aceLang).Mode)); codeEditor.getSession().setMode( new (require( "ace/mode/" + aceLang ).Mode) );
}; };
setLanguage(geshiLang); setLanguage( geshiLang );
var closeEditor = function() { var closeEditor = function () {
$xcontainer.remove(); $xcontainer.remove();
$div.css('display', 'block'); $div.css( 'display', 'block' );
}; };
}); } );
}; };
$sources.each(function(i, div) { $sources.each( function ( i, div ) {
var $div = $(div); var $div = $( div );
setupEditor($div); setupEditor( $div );
}); } );
} }
}); } );

View file

@ -37,7 +37,7 @@
* JavaScript for WikiEditor Table of Contents * JavaScript for WikiEditor Table of Contents
*/ */
$( document ).ready( function() { $( document ).ready( function () {
var $wpTextbox1 = $( '#wpTextbox1' ); var $wpTextbox1 = $( '#wpTextbox1' );
// Code is supposed to be always LTR. See bug 39364. // Code is supposed to be always LTR. See bug 39364.
@ -46,8 +46,8 @@ $( document ).ready( function() {
// Add code editor module // Add code editor module
$wpTextbox1.wikiEditor( 'addModule', 'codeEditor' ); $wpTextbox1.wikiEditor( 'addModule', 'codeEditor' );
} ); } );
$( window ).load( function() { $( window ).load( function () {
// If there is a fragment giving a line number, scroll to the relevant location // If there is a fragment giving a line number, scroll to the relevant location
// Wait for the load event since it doesn't scroll properly on ready // Wait for the load event since it doesn't scroll properly on ready
$( '#wpTextbox1' ).data('wikiEditor-context').fn.codeEditorMonitorFragment(); $( '#wpTextbox1' ).data( 'wikiEditor-context' ).fn.codeEditorMonitorFragment();
} ); } );

View file

@ -1,95 +1,92 @@
/* Ace syntax-highlighting code editor extension for wikiEditor */ /* Ace syntax-highlighting code editor extension for wikiEditor */
( function( $ ) { (function ( $ ) {
$.wikiEditor.modules.codeEditor = {
$.wikiEditor.modules.codeEditor = { /**
/**
* Core Requirements * Core Requirements
*/ */
'req': [ 'codeEditor' ], 'req': [ 'codeEditor' ],
/** /**
* Configuration * Configuration
*/ */
cfg: { cfg: {
// //
}, },
/** /**
* API accessible functions * API accessible functions
*/ */
api: { api: {
// //
}, },
/** /**
* Event handlers * Event handlers
*/ */
evt: { evt: {
// //
}, },
/** /**
* Internally used functions * Internally used functions
*/ */
fn: { fn: {
} }
}; };
$.wikiEditor.extensions.codeEditor = function( context ) { $.wikiEditor.extensions.codeEditor = function ( context ) {
/*
/*
* Event Handlers * Event Handlers
* *
* These act as filters returning false if the event should be ignored or returning true if it should be passed * These act as filters returning false if the event should be ignored or returning true if it should be passed
* on to all modules. This is also where we can attach some extra information to the events. * on to all modules. This is also where we can attach some extra information to the events.
*/ */
context.evt = $.extend( context.evt, { context.evt = $.extend( context.evt, {
/** /**
* Filters change events, which occur when the user interacts with the contents of the iframe. The goal of this * Filters change events, which occur when the user interacts with the contents of the iframe. The goal of this
* function is to both classify the scope of changes as 'division' or 'character' and to prevent further * function is to both classify the scope of changes as 'division' or 'character' and to prevent further
* processing of events which did not actually change the content of the iframe. * processing of events which did not actually change the content of the iframe.
*/ */
'keydown': function( event ) { 'keydown': function ( event ) {
}, },
'change': function( event ) { 'change': function ( event ) {
}, },
'delayedChange': function( event ) { 'delayedChange': function ( event ) {
}, },
'cut': function( event ) { 'cut': function ( event ) {
}, },
'paste': function( event ) { 'paste': function ( event ) {
}, },
'ready': function( event ) { 'ready': function ( event ) {
}, },
'codeEditorSubmit': function( event ) { 'codeEditorSubmit': function ( event ) {
context.$textarea.val( context.$textarea.textSelection( 'getContents' ) ); context.$textarea.val( context.$textarea.textSelection( 'getContents' ) );
} }
} ); } );
var cookieEnabled = $.cookie('wikiEditor-' + context.instance + '-codeEditor-enabled'); var cookieEnabled = $.cookie( 'wikiEditor-' + context.instance + '-codeEditor-enabled' );
context.codeEditorActive = (cookieEnabled !== '0'); context.codeEditorActive = (cookieEnabled !== '0');
/** /**
* Internally used functions * Internally used functions
*/ */
context.fn = $.extend( context.fn, { context.fn = $.extend( context.fn, {
'codeEditorToolbarIcon': function() { 'codeEditorToolbarIcon': function () {
// When loaded as a gadget, one may need to override the wiki's own assets path. // When loaded as a gadget, one may need to override the wiki's own assets path.
var iconPath = mw.config.get('wgCodeEditorAssetsPath', mw.config.get('wgExtensionAssetsPath')) + '/CodeEditor/images/'; var iconPath = mw.config.get( 'wgCodeEditorAssetsPath', mw.config.get( 'wgExtensionAssetsPath' ) ) + '/CodeEditor/images/';
return iconPath + (context.codeEditorActive ? 'code-selected.png' : 'code.png'); return iconPath + (context.codeEditorActive ? 'code-selected.png' : 'code.png');
}, },
'setupCodeEditorToolbar': function() { 'setupCodeEditorToolbar': function () {
// Drop out some formatting that isn't relevant on these pages... // Drop out some formatting that isn't relevant on these pages...
context.api.removeFromToolbar(context, { context.api.removeFromToolbar( context, {
'section': 'main', 'section': 'main',
'group': 'format', 'group': 'format',
'tool': 'bold' 'tool': 'bold'
}); } );
context.api.removeFromToolbar(context, { context.api.removeFromToolbar( context, {
'section': 'main', 'section': 'main',
'group': 'format', 'group': 'format',
'tool': 'italic' 'tool': 'italic'
}); } );
var callback = function( context ) { var callback = function ( context ) {
context.codeEditorActive = !context.codeEditorActive; context.codeEditorActive = !context.codeEditorActive;
$.cookie( $.cookie(
'wikiEditor-' + context.instance + '-codeEditor-enabled', 'wikiEditor-' + context.instance + '-codeEditor-enabled',
@ -98,7 +95,7 @@ context.fn = $.extend( context.fn, {
); );
context.fn.toggleCodeEditorToolbar(); context.fn.toggleCodeEditorToolbar();
if (context.codeEditorActive) { if ( context.codeEditorActive ) {
// set it back up! // set it back up!
context.fn.setupCodeEditor(); context.fn.setupCodeEditor();
} else { } else {
@ -121,48 +118,48 @@ context.fn = $.extend( context.fn, {
} }
} ); } );
}, },
'toggleCodeEditorToolbar': function() { 'toggleCodeEditorToolbar': function () {
var target = 'img.tool[rel=codeEditor]'; var target = 'img.tool[rel=codeEditor]';
var $img = context.modules.toolbar.$toolbar.find( target ); var $img = context.modules.toolbar.$toolbar.find( target );
$img.attr('src', context.fn.codeEditorToolbarIcon()); $img.attr( 'src', context.fn.codeEditorToolbarIcon() );
}, },
/** /**
* Sets up the iframe in place of the textarea to allow more advanced operations * Sets up the iframe in place of the textarea to allow more advanced operations
*/ */
'setupCodeEditor': function() { 'setupCodeEditor': function () {
var box = context.$textarea; var box = context.$textarea;
var lang = mw.config.get("wgCodeEditorCurrentLanguage"); var lang = mw.config.get( "wgCodeEditorCurrentLanguage" );
if (lang) { if ( lang ) {
// Ace doesn't like replacing a textarea directly. // Ace doesn't like replacing a textarea directly.
// We'll stub this out to sit on top of it... // We'll stub this out to sit on top of it...
// line-height is needed to compensate for oddity in WikiEditor extension, which zeroes the line-height on a parent container // line-height is needed to compensate for oddity in WikiEditor extension, which zeroes the line-height on a parent container
var container = context.$codeEditorContainer = $('<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); var container = context.$codeEditorContainer = $( '<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 );
var editdiv = container.find('.editor'); var editdiv = container.find( '.editor' );
box.css('display', 'none'); box.css( 'display', 'none' );
container.width(box.width()) container.width( box.width() )
.height(box.height()); .height( box.height() );
editdiv.text(box.val()); editdiv.text( box.val() );
context.codeEditor = ace.edit(editdiv[0]); context.codeEditor = ace.edit( editdiv[0] );
// Disable some annoying commands // Disable some annoying commands
context.codeEditor.commands.removeCommand('replace'); // ctrl+R context.codeEditor.commands.removeCommand( 'replace' ); // ctrl+R
context.codeEditor.commands.removeCommand('transposeletters'); // ctrl+T context.codeEditor.commands.removeCommand( 'transposeletters' ); // ctrl+T
context.codeEditor.commands.removeCommand('gotoline'); // ctrl+L context.codeEditor.commands.removeCommand( 'gotoline' ); // ctrl+L
// fakeout for bug 29328 // fakeout for bug 29328
context.$iframe = [ context.$iframe = [
{ {
contentWindow: { contentWindow: {
focus: function() { focus: function () {
context.codeEditor.focus(); context.codeEditor.focus();
} }
} }
} }
]; ];
box.closest('form').submit( context.evt.codeEditorSubmit ); box.closest( 'form' ).submit( context.evt.codeEditorSubmit );
var session = context.codeEditor.getSession(); var session = context.codeEditor.getSession();
// Use proper tabs // Use proper tabs
@ -182,24 +179,24 @@ context.fn = $.extend( context.fn, {
// Disable code-linting in the background using JavaScript WebWorkers. // Disable code-linting in the background using JavaScript WebWorkers.
// Currently broken due to require() / ResourceLoader mismatch. // Currently broken due to require() / ResourceLoader mismatch.
session.setUseWorker(false); session.setUseWorker( false );
session.setMode(new (require("ace/mode/" + lang).Mode)); session.setMode( new (require( "ace/mode/" + lang ).Mode) );
// Force the box to resize horizontally to match in future :D // Force the box to resize horizontally to match in future :D
var resize = function() { var resize = function () {
container.width(box.width()); container.width( box.width() );
}; };
$(window).resize(resize); $( window ).resize( resize );
// Use jquery.ui.resizable so user can make the box taller too // Use jquery.ui.resizable so user can make the box taller too
container.resizable({ container.resizable( {
handles: 's', handles: 's',
minHeight: box.height(), minHeight: box.height(),
resize: function() { resize: function () {
context.codeEditor.resize(); context.codeEditor.resize();
} }
}); } );
var summary = $('#wpSummary'); var summary = $( '#wpSummary' );
// Let modules know we're ready to start working with the content // Let modules know we're ready to start working with the content
context.fn.trigger( 'ready' ); context.fn.trigger( 'ready' );
} }
@ -209,16 +206,16 @@ context.fn = $.extend( context.fn, {
* Turn off the code editor view and return to the plain textarea. * Turn off the code editor view and return to the plain textarea.
* May be needed by some folks with funky browsers, or just to compare. * May be needed by some folks with funky browsers, or just to compare.
*/ */
'disableCodeEditor': function() { 'disableCodeEditor': function () {
// Kills it! // Kills it!
context.$textarea.closest('form').unbind('submit', context.evt.codeEditorSubmit ); context.$textarea.closest( 'form' ).unbind( 'submit', context.evt.codeEditorSubmit );
if ( mw.hook ) { if ( mw.hook ) {
mw.hook( 'LivePreviewPrepare' ).remove( context.evt.codeEditorSubmit ); mw.hook( 'LivePreviewPrepare' ).remove( context.evt.codeEditorSubmit );
} }
$( mw ).unbind( 'LivePreviewPrepare', context.evt.codeEditorSubmit ); // deprecated $( mw ).unbind( 'LivePreviewPrepare', context.evt.codeEditorSubmit ); // deprecated
// Save contents // Save contents
context.$textarea.val(context.fn.getContents()); context.$textarea.val( context.fn.getContents() );
// @todo fetch cursor, scroll position // @todo fetch cursor, scroll position
@ -238,7 +235,7 @@ context.fn = $.extend( context.fn, {
* Start monitoring the fragment of the current window for hash change * Start monitoring the fragment of the current window for hash change
* events. If the hash is already set, handle it as a new event. * events. If the hash is already set, handle it as a new event.
*/ */
'codeEditorMonitorFragment': function() { 'codeEditorMonitorFragment': function () {
function onHashChange() { function onHashChange() {
var regexp = /#mw-ce-l(\d+)/; var regexp = /#mw-ce-l(\d+)/;
var result = regexp.exec( window.location.hash ); var result = regexp.exec( window.location.hash );
@ -252,62 +249,63 @@ context.fn = $.extend( context.fn, {
// Scroll up a bit to give some context // Scroll up a bit to give some context
context.codeEditor.scrollToRow( line - 4 ); context.codeEditor.scrollToRow( line - 4 );
} }
onHashChange(); onHashChange();
$( window ).bind( 'hashchange', onHashChange ); $( window ).bind( 'hashchange', onHashChange );
} }
}); } );
/** /**
* Override the base functions in a way that lets * Override the base functions in a way that lets
* us fall back to the originals when we turn off. * us fall back to the originals when we turn off.
*/ */
var saveAndExtend = function( base, extended ) { var saveAndExtend = function ( base, extended ) {
var saved = {}; var saved = {};
// $.map doesn't handle objects in jQuery < 1.6; need this for compat with MW 1.17 // $.map doesn't handle objects in jQuery < 1.6; need this for compat with MW 1.17
var map = function( obj, callback ) { var map = function ( obj, callback ) {
for (var key in extended ) { for ( var key in extended ) {
if ( obj.hasOwnProperty( key ) ) { if ( obj.hasOwnProperty( key ) ) {
callback( obj[key], key ); callback( obj[key], key );
} }
} }
}; };
map( extended, function( func, name ) { map( extended, function ( func, name ) {
if ( name in base ) { if ( name in base ) {
var orig = base[name]; var orig = base[name];
base[name] = function() { base[name] = function () {
if (context.codeEditorActive) { if ( context.codeEditorActive ) {
return func.apply(this, arguments); return func.apply( this, arguments );
} else if (orig) { } else if ( orig ) {
return orig.apply(this, arguments); return orig.apply( this, arguments );
} else { } else {
throw new Error('CodeEditor: no original function to call for ' + name); throw new Error( 'CodeEditor: no original function to call for ' + name );
} }
}; };
} else { } else {
base[name] = func; base[name] = func;
} }
}); } );
}; };
saveAndExtend( context.fn, { saveAndExtend( context.fn, {
'saveCursorAndScrollTop': function() { 'saveCursorAndScrollTop': function () {
// Stub out textarea behavior // Stub out textarea behavior
return; return;
}, },
'restoreCursorAndScrollTop': function() { 'restoreCursorAndScrollTop': function () {
// Stub out textarea behavior // Stub out textarea behavior
return; return;
}, },
'saveSelection': function() { 'saveSelection': function () {
mw.log('codeEditor stub function saveSelection called'); mw.log( 'codeEditor stub function saveSelection called' );
}, },
'restoreSelection': function() { 'restoreSelection': function () {
mw.log('codeEditor stub function restoreSelection called'); mw.log( 'codeEditor stub function restoreSelection called' );
}, },
/* Needed for search/replace */ /* Needed for search/replace */
'getContents': function() { 'getContents': function () {
return context.codeEditor.getSession().getValue(); return context.codeEditor.getSession().getValue();
}, },
@ -316,15 +314,15 @@ saveAndExtend( context.fn, {
* equivilant functionality to the otherwise textarea-based functionality. * equivilant functionality to the otherwise textarea-based functionality.
*/ */
'getElementAtCursor': function() { 'getElementAtCursor': function () {
mw.log('codeEditor stub function getElementAtCursor called'); mw.log( 'codeEditor stub function getElementAtCursor called' );
}, },
/** /**
* Gets the currently selected text in the content * Gets the currently selected text in the content
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
*/ */
'getSelection': function() { 'getSelection': function () {
return context.codeEditor.getCopyText(); return context.codeEditor.getCopyText();
}, },
/** /**
@ -332,7 +330,7 @@ saveAndExtend( context.fn, {
* selection is empty. * selection is empty.
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
*/ */
'encapsulateSelection': function( options ) { 'encapsulateSelection': function ( options ) {
// Does not yet handle 'ownline', 'splitlines' option // Does not yet handle 'ownline', 'splitlines' option
var sel = context.codeEditor.getSelection(); var sel = context.codeEditor.getSelection();
var range = sel.getRange(); var range = sel.getRange();
@ -352,7 +350,7 @@ saveAndExtend( context.fn, {
// May esplode if anything has newlines, be warned. :) // May esplode if anything has newlines, be warned. :)
range.setStart( range.start.row, range.start.column + options.pre.length ); range.setStart( range.start.row, range.start.column + options.pre.length );
range.setEnd( range.start.row, range.start.column + selText.length ); range.setEnd( range.start.row, range.start.column + selText.length );
sel.setSelectionRange(range); sel.setSelectionRange( range );
} }
return context.$textarea; return context.$textarea;
}, },
@ -360,8 +358,8 @@ saveAndExtend( context.fn, {
* Gets the position (in resolution of bytes not nessecarily characters) in a textarea * Gets the position (in resolution of bytes not nessecarily characters) in a textarea
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
*/ */
'getCaretPosition': function( options ) { 'getCaretPosition': function ( options ) {
mw.log('codeEditor stub function getCaretPosition called'); mw.log( 'codeEditor stub function getCaretPosition called' );
}, },
/** /**
* Sets the selection of the content * Sets the selection of the content
@ -372,16 +370,16 @@ saveAndExtend( context.fn, {
* @param startContainer Element in iframe to start selection in. If not set, start is a character offset * @param startContainer Element in iframe to start selection in. If not set, start is a character offset
* @param endContainer Element in iframe to end selection in. If not set, end is a character offset * @param endContainer Element in iframe to end selection in. If not set, end is a character offset
*/ */
'setSelection': function( options ) { 'setSelection': function ( options ) {
// Ace stores positions for ranges as row/column pairs. // Ace stores positions for ranges as row/column pairs.
// To convert from character offsets, we'll need to iterate through the document // To convert from character offsets, we'll need to iterate through the document
var doc = context.codeEditor.getSession().getDocument(); var doc = context.codeEditor.getSession().getDocument();
var lines = doc.getAllLines(); var lines = doc.getAllLines();
var offsetToPos = function( offset ) { var offsetToPos = function ( offset ) {
var row = 0, col = 0; var row = 0, col = 0;
var pos = 0; var pos = 0;
while ( row < lines.length && pos + lines[row].length < offset) { while ( row < lines.length && pos + lines[row].length < offset ) {
pos += lines[row].length; pos += lines[row].length;
pos++; // for the newline pos++; // for the newline
row++; row++;
@ -403,8 +401,8 @@ saveAndExtend( context.fn, {
* Scroll a textarea to the current cursor position. You can set the cursor position with setSelection() * Scroll a textarea to the current cursor position. You can set the cursor position with setSelection()
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead * DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
*/ */
'scrollToCaretPosition': function( options ) { 'scrollToCaretPosition': function ( options ) {
mw.log('codeEditor stub function scrollToCaretPosition called'); mw.log( 'codeEditor stub function scrollToCaretPosition called' );
return context.$textarea; return context.$textarea;
}, },
/** /**
@ -414,16 +412,16 @@ saveAndExtend( context.fn, {
* @param $element jQuery object containing an element in the iframe * @param $element jQuery object containing an element in the iframe
* @param force If true, scroll the element even if it's already visible * @param force If true, scroll the element even if it's already visible
*/ */
'scrollToTop': function( $element, force ) { 'scrollToTop': function ( $element, force ) {
mw.log('codeEditor stub function scrollToTop called'); mw.log( 'codeEditor stub function scrollToTop called' );
} }
} ); } );
/* Setup the editor */ /* Setup the editor */
context.fn.setupCodeEditorToolbar(); context.fn.setupCodeEditorToolbar();
if (context.codeEditorActive) { if ( context.codeEditorActive ) {
context.fn.setupCodeEditor(); context.fn.setupCodeEditor();
} }
}; };
} )( jQuery ); })( jQuery );