mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CodeEditor
synced 2024-11-27 16:40:07 +00:00
Update formatting of JavaScript files
Change-Id: I7a18b7f76f7c0a064645f23974f1fe09dafc4ca2
This commit is contained in:
parent
37e2ec1286
commit
2d121364d3
|
@ -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',
|
||||||
|
@ -55,95 +55,93 @@ $(function() {
|
||||||
scala: 'scala',
|
scala: 'scala',
|
||||||
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 );
|
||||||
});
|
} );
|
||||||
}
|
}
|
||||||
});
|
} );
|
||||||
|
|
|
@ -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();
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1,429 +1,427 @@
|
||||||
/* Ace syntax-highlighting code editor extension for wikiEditor */
|
/* Ace syntax-highlighting code editor extension for wikiEditor */
|
||||||
|
|
||||||
( function( $ ) {
|
(function ( $ ) {
|
||||||
|
$.wikiEditor.modules.codeEditor = {
|
||||||
|
/**
|
||||||
|
* Core Requirements
|
||||||
|
*/
|
||||||
|
'req': [ 'codeEditor' ],
|
||||||
|
/**
|
||||||
|
* Configuration
|
||||||
|
*/
|
||||||
|
cfg: {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* API accessible functions
|
||||||
|
*/
|
||||||
|
api: {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Event handlers
|
||||||
|
*/
|
||||||
|
evt: {
|
||||||
|
//
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Internally used functions
|
||||||
|
*/
|
||||||
|
fn: {
|
||||||
|
}
|
||||||
|
|
||||||
$.wikiEditor.modules.codeEditor = {
|
};
|
||||||
|
|
||||||
/**
|
$.wikiEditor.extensions.codeEditor = function ( context ) {
|
||||||
* Core Requirements
|
/*
|
||||||
*/
|
* Event Handlers
|
||||||
'req': [ 'codeEditor' ],
|
*
|
||||||
/**
|
* These act as filters returning false if the event should be ignored or returning true if it should be passed
|
||||||
* Configuration
|
* on to all modules. This is also where we can attach some extra information to the events.
|
||||||
*/
|
*/
|
||||||
cfg: {
|
context.evt = $.extend( context.evt, {
|
||||||
//
|
/**
|
||||||
},
|
* 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
|
||||||
* API accessible functions
|
* processing of events which did not actually change the content of the iframe.
|
||||||
*/
|
*/
|
||||||
api: {
|
'keydown': function ( event ) {
|
||||||
//
|
},
|
||||||
},
|
'change': function ( event ) {
|
||||||
/**
|
},
|
||||||
* Event handlers
|
'delayedChange': function ( event ) {
|
||||||
*/
|
},
|
||||||
evt: {
|
'cut': function ( event ) {
|
||||||
//
|
},
|
||||||
},
|
'paste': function ( event ) {
|
||||||
/**
|
},
|
||||||
* Internally used functions
|
'ready': function ( event ) {
|
||||||
*/
|
},
|
||||||
fn: {
|
'codeEditorSubmit': function ( event ) {
|
||||||
}
|
context.$textarea.val( context.$textarea.textSelection( 'getContents' ) );
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
$.wikiEditor.extensions.codeEditor = function( context ) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Event Handlers
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
context.evt = $.extend( context.evt, {
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* processing of events which did not actually change the content of the iframe.
|
|
||||||
*/
|
|
||||||
'keydown': function( event ) {
|
|
||||||
},
|
|
||||||
'change': function( event ) {
|
|
||||||
},
|
|
||||||
'delayedChange': function( event ) {
|
|
||||||
},
|
|
||||||
'cut': function( event ) {
|
|
||||||
},
|
|
||||||
'paste': function( event ) {
|
|
||||||
},
|
|
||||||
'ready': function( event ) {
|
|
||||||
},
|
|
||||||
'codeEditorSubmit': function( event ) {
|
|
||||||
context.$textarea.val( context.$textarea.textSelection( 'getContents' ) );
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
var cookieEnabled = $.cookie('wikiEditor-' + context.instance + '-codeEditor-enabled');
|
|
||||||
context.codeEditorActive = (cookieEnabled !== '0');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internally used functions
|
|
||||||
*/
|
|
||||||
context.fn = $.extend( context.fn, {
|
|
||||||
'codeEditorToolbarIcon': function() {
|
|
||||||
// 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/';
|
|
||||||
return iconPath + (context.codeEditorActive ? 'code-selected.png' : 'code.png');
|
|
||||||
},
|
|
||||||
'setupCodeEditorToolbar': function() {
|
|
||||||
// Drop out some formatting that isn't relevant on these pages...
|
|
||||||
context.api.removeFromToolbar(context, {
|
|
||||||
'section': 'main',
|
|
||||||
'group': 'format',
|
|
||||||
'tool': 'bold'
|
|
||||||
});
|
|
||||||
context.api.removeFromToolbar(context, {
|
|
||||||
'section': 'main',
|
|
||||||
'group': 'format',
|
|
||||||
'tool': 'italic'
|
|
||||||
});
|
|
||||||
var callback = function( context ) {
|
|
||||||
context.codeEditorActive = !context.codeEditorActive;
|
|
||||||
$.cookie(
|
|
||||||
'wikiEditor-' + context.instance + '-codeEditor-enabled',
|
|
||||||
context.codeEditorActive ? 1 : 0,
|
|
||||||
{ expires: 30, path: '/' }
|
|
||||||
);
|
|
||||||
context.fn.toggleCodeEditorToolbar();
|
|
||||||
|
|
||||||
if (context.codeEditorActive) {
|
|
||||||
// set it back up!
|
|
||||||
context.fn.setupCodeEditor();
|
|
||||||
} else {
|
|
||||||
context.fn.disableCodeEditor();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
context.api.addToToolbar( context, {
|
|
||||||
'section': 'main',
|
|
||||||
'group': 'format',
|
|
||||||
'tools': {
|
|
||||||
'codeEditor': {
|
|
||||||
'labelMsg': 'codeeditor-toolbar-toggle',
|
|
||||||
'type': 'button',
|
|
||||||
'icon': context.fn.codeEditorToolbarIcon(),
|
|
||||||
'action': {
|
|
||||||
'type': 'callback',
|
|
||||||
'execute': callback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
},
|
|
||||||
'toggleCodeEditorToolbar': function() {
|
|
||||||
var target = 'img.tool[rel=codeEditor]';
|
|
||||||
var $img = context.modules.toolbar.$toolbar.find( target );
|
|
||||||
$img.attr('src', context.fn.codeEditorToolbarIcon());
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Sets up the iframe in place of the textarea to allow more advanced operations
|
|
||||||
*/
|
|
||||||
'setupCodeEditor': function() {
|
|
||||||
var box = context.$textarea;
|
|
||||||
|
|
||||||
var lang = mw.config.get("wgCodeEditorCurrentLanguage");
|
var cookieEnabled = $.cookie( 'wikiEditor-' + context.instance + '-codeEditor-enabled' );
|
||||||
if (lang) {
|
context.codeEditorActive = (cookieEnabled !== '0');
|
||||||
// Ace doesn't like replacing a textarea directly.
|
|
||||||
// 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
|
|
||||||
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');
|
|
||||||
|
|
||||||
box.css('display', 'none');
|
/**
|
||||||
container.width(box.width())
|
* Internally used functions
|
||||||
.height(box.height());
|
*/
|
||||||
|
context.fn = $.extend( context.fn, {
|
||||||
|
'codeEditorToolbarIcon': function () {
|
||||||
|
// 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/';
|
||||||
|
return iconPath + (context.codeEditorActive ? 'code-selected.png' : 'code.png');
|
||||||
|
},
|
||||||
|
'setupCodeEditorToolbar': function () {
|
||||||
|
// Drop out some formatting that isn't relevant on these pages...
|
||||||
|
context.api.removeFromToolbar( context, {
|
||||||
|
'section': 'main',
|
||||||
|
'group': 'format',
|
||||||
|
'tool': 'bold'
|
||||||
|
} );
|
||||||
|
context.api.removeFromToolbar( context, {
|
||||||
|
'section': 'main',
|
||||||
|
'group': 'format',
|
||||||
|
'tool': 'italic'
|
||||||
|
} );
|
||||||
|
var callback = function ( context ) {
|
||||||
|
context.codeEditorActive = !context.codeEditorActive;
|
||||||
|
$.cookie(
|
||||||
|
'wikiEditor-' + context.instance + '-codeEditor-enabled',
|
||||||
|
context.codeEditorActive ? 1 : 0,
|
||||||
|
{ expires: 30, path: '/' }
|
||||||
|
);
|
||||||
|
context.fn.toggleCodeEditorToolbar();
|
||||||
|
|
||||||
editdiv.text(box.val());
|
if ( context.codeEditorActive ) {
|
||||||
context.codeEditor = ace.edit(editdiv[0]);
|
// set it back up!
|
||||||
|
context.fn.setupCodeEditor();
|
||||||
// Disable some annoying commands
|
} else {
|
||||||
context.codeEditor.commands.removeCommand('replace'); // ctrl+R
|
context.fn.disableCodeEditor();
|
||||||
context.codeEditor.commands.removeCommand('transposeletters'); // ctrl+T
|
}
|
||||||
context.codeEditor.commands.removeCommand('gotoline'); // ctrl+L
|
};
|
||||||
|
context.api.addToToolbar( context, {
|
||||||
// fakeout for bug 29328
|
'section': 'main',
|
||||||
context.$iframe = [
|
'group': 'format',
|
||||||
{
|
'tools': {
|
||||||
contentWindow: {
|
'codeEditor': {
|
||||||
focus: function() {
|
'labelMsg': 'codeeditor-toolbar-toggle',
|
||||||
context.codeEditor.focus();
|
'type': 'button',
|
||||||
|
'icon': context.fn.codeEditorToolbarIcon(),
|
||||||
|
'action': {
|
||||||
|
'type': 'callback',
|
||||||
|
'execute': callback
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} );
|
||||||
|
},
|
||||||
|
'toggleCodeEditorToolbar': function () {
|
||||||
|
var target = 'img.tool[rel=codeEditor]';
|
||||||
|
var $img = context.modules.toolbar.$toolbar.find( target );
|
||||||
|
$img.attr( 'src', context.fn.codeEditorToolbarIcon() );
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Sets up the iframe in place of the textarea to allow more advanced operations
|
||||||
|
*/
|
||||||
|
'setupCodeEditor': function () {
|
||||||
|
var box = context.$textarea;
|
||||||
|
|
||||||
|
var lang = mw.config.get( "wgCodeEditorCurrentLanguage" );
|
||||||
|
if ( lang ) {
|
||||||
|
// Ace doesn't like replacing a textarea directly.
|
||||||
|
// 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
|
||||||
|
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' );
|
||||||
|
|
||||||
|
box.css( 'display', 'none' );
|
||||||
|
container.width( box.width() )
|
||||||
|
.height( box.height() );
|
||||||
|
|
||||||
|
editdiv.text( box.val() );
|
||||||
|
context.codeEditor = ace.edit( editdiv[0] );
|
||||||
|
|
||||||
|
// Disable some annoying commands
|
||||||
|
context.codeEditor.commands.removeCommand( 'replace' ); // ctrl+R
|
||||||
|
context.codeEditor.commands.removeCommand( 'transposeletters' ); // ctrl+T
|
||||||
|
context.codeEditor.commands.removeCommand( 'gotoline' ); // ctrl+L
|
||||||
|
|
||||||
|
// fakeout for bug 29328
|
||||||
|
context.$iframe = [
|
||||||
|
{
|
||||||
|
contentWindow: {
|
||||||
|
focus: function () {
|
||||||
|
context.codeEditor.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
box.closest( 'form' ).submit( context.evt.codeEditorSubmit );
|
||||||
|
var session = context.codeEditor.getSession();
|
||||||
|
|
||||||
|
// Use proper tabs
|
||||||
|
session.setUseSoftTabs( false );
|
||||||
|
|
||||||
|
// Bug 47235: Update text field for LivePreview
|
||||||
|
if ( mw.hook ) {
|
||||||
|
// New style hook
|
||||||
|
mw.hook( 'LivePreviewPrepare' ).add( context.evt.codeEditorSubmit );
|
||||||
|
|
||||||
|
mw.hook( 'codeEditor.configure' ).fire( session );
|
||||||
|
}
|
||||||
|
// Old, deprecated style for backwards compat
|
||||||
|
// Do this even if mw.hook exists, because the caller wasn't
|
||||||
|
// updated right away to actually use the new style.
|
||||||
|
$( mw ).bind( 'LivePreviewPrepare', context.evt.codeEditorSubmit );
|
||||||
|
|
||||||
|
// Disable code-linting in the background using JavaScript WebWorkers.
|
||||||
|
// Currently broken due to require() / ResourceLoader mismatch.
|
||||||
|
session.setUseWorker( false );
|
||||||
|
session.setMode( new (require( "ace/mode/" + lang ).Mode) );
|
||||||
|
|
||||||
|
// Force the box to resize horizontally to match in future :D
|
||||||
|
var resize = function () {
|
||||||
|
container.width( box.width() );
|
||||||
|
};
|
||||||
|
$( window ).resize( resize );
|
||||||
|
// Use jquery.ui.resizable so user can make the box taller too
|
||||||
|
container.resizable( {
|
||||||
|
handles: 's',
|
||||||
|
minHeight: box.height(),
|
||||||
|
resize: function () {
|
||||||
|
context.codeEditor.resize();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
var summary = $( '#wpSummary' );
|
||||||
|
// Let modules know we're ready to start working with the content
|
||||||
|
context.fn.trigger( 'ready' );
|
||||||
}
|
}
|
||||||
];
|
},
|
||||||
box.closest('form').submit( context.evt.codeEditorSubmit );
|
|
||||||
var session = context.codeEditor.getSession();
|
|
||||||
|
|
||||||
// Use proper tabs
|
/**
|
||||||
session.setUseSoftTabs( false );
|
* 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.
|
||||||
|
*/
|
||||||
|
'disableCodeEditor': function () {
|
||||||
|
// Kills it!
|
||||||
|
context.$textarea.closest( 'form' ).unbind( 'submit', context.evt.codeEditorSubmit );
|
||||||
|
if ( mw.hook ) {
|
||||||
|
mw.hook( 'LivePreviewPrepare' ).remove( context.evt.codeEditorSubmit );
|
||||||
|
}
|
||||||
|
$( mw ).unbind( 'LivePreviewPrepare', context.evt.codeEditorSubmit ); // deprecated
|
||||||
|
|
||||||
// Bug 47235: Update text field for LivePreview
|
// Save contents
|
||||||
if ( mw.hook ) {
|
context.$textarea.val( context.fn.getContents() );
|
||||||
// New style hook
|
|
||||||
mw.hook( 'LivePreviewPrepare' ).add( context.evt.codeEditorSubmit );
|
|
||||||
|
|
||||||
mw.hook( 'codeEditor.configure' ).fire( session );
|
// @todo fetch cursor, scroll position
|
||||||
|
|
||||||
|
// Drop the fancy editor widget...
|
||||||
|
context.$codeEditorContainer.remove();
|
||||||
|
context.$codeEditorContainer = undefined;
|
||||||
|
context.$iframe = undefined;
|
||||||
|
context.codeEditor = undefined;
|
||||||
|
|
||||||
|
// Restore textarea
|
||||||
|
context.$textarea.show();
|
||||||
|
|
||||||
|
// @todo restore cursor, scroll position
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start monitoring the fragment of the current window for hash change
|
||||||
|
* events. If the hash is already set, handle it as a new event.
|
||||||
|
*/
|
||||||
|
'codeEditorMonitorFragment': function () {
|
||||||
|
function onHashChange() {
|
||||||
|
var regexp = /#mw-ce-l(\d+)/;
|
||||||
|
var result = regexp.exec( window.location.hash );
|
||||||
|
if ( result === null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line numbers in CodeEditor are zero-based
|
||||||
|
var line = parseInt( result[1] );
|
||||||
|
context.codeEditor.navigateTo( line - 1, 0 );
|
||||||
|
// Scroll up a bit to give some context
|
||||||
|
context.codeEditor.scrollToRow( line - 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
onHashChange();
|
||||||
|
$( window ).bind( 'hashchange', onHashChange );
|
||||||
}
|
}
|
||||||
// Old, deprecated style for backwards compat
|
|
||||||
// Do this even if mw.hook exists, because the caller wasn't
|
|
||||||
// updated right away to actually use the new style.
|
|
||||||
$( mw ).bind( 'LivePreviewPrepare', context.evt.codeEditorSubmit );
|
|
||||||
|
|
||||||
// Disable code-linting in the background using JavaScript WebWorkers.
|
} );
|
||||||
// Currently broken due to require() / ResourceLoader mismatch.
|
|
||||||
session.setUseWorker(false);
|
|
||||||
session.setMode(new (require("ace/mode/" + lang).Mode));
|
|
||||||
|
|
||||||
// Force the box to resize horizontally to match in future :D
|
/**
|
||||||
var resize = function() {
|
* Override the base functions in a way that lets
|
||||||
container.width(box.width());
|
* us fall back to the originals when we turn off.
|
||||||
|
*/
|
||||||
|
var saveAndExtend = function ( base, extended ) {
|
||||||
|
var saved = {};
|
||||||
|
// $.map doesn't handle objects in jQuery < 1.6; need this for compat with MW 1.17
|
||||||
|
var map = function ( obj, callback ) {
|
||||||
|
for ( var key in extended ) {
|
||||||
|
if ( obj.hasOwnProperty( key ) ) {
|
||||||
|
callback( obj[key], key );
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
$(window).resize(resize);
|
map( extended, function ( func, name ) {
|
||||||
// Use jquery.ui.resizable so user can make the box taller too
|
if ( name in base ) {
|
||||||
container.resizable({
|
var orig = base[name];
|
||||||
handles: 's',
|
base[name] = function () {
|
||||||
minHeight: box.height(),
|
if ( context.codeEditorActive ) {
|
||||||
resize: function() {
|
return func.apply( this, arguments );
|
||||||
context.codeEditor.resize();
|
} else if ( orig ) {
|
||||||
}
|
return orig.apply( this, arguments );
|
||||||
});
|
} else {
|
||||||
|
throw new Error( 'CodeEditor: no original function to call for ' + name );
|
||||||
var summary = $('#wpSummary');
|
}
|
||||||
// Let modules know we're ready to start working with the content
|
};
|
||||||
context.fn.trigger( 'ready' );
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
'disableCodeEditor': function() {
|
|
||||||
// Kills it!
|
|
||||||
context.$textarea.closest('form').unbind('submit', context.evt.codeEditorSubmit );
|
|
||||||
if ( mw.hook ) {
|
|
||||||
mw.hook( 'LivePreviewPrepare' ).remove( context.evt.codeEditorSubmit );
|
|
||||||
}
|
|
||||||
$( mw ).unbind( 'LivePreviewPrepare', context.evt.codeEditorSubmit ); // deprecated
|
|
||||||
|
|
||||||
// Save contents
|
|
||||||
context.$textarea.val(context.fn.getContents());
|
|
||||||
|
|
||||||
// @todo fetch cursor, scroll position
|
|
||||||
|
|
||||||
// Drop the fancy editor widget...
|
|
||||||
context.$codeEditorContainer.remove();
|
|
||||||
context.$codeEditorContainer = undefined;
|
|
||||||
context.$iframe = undefined;
|
|
||||||
context.codeEditor = undefined;
|
|
||||||
|
|
||||||
// Restore textarea
|
|
||||||
context.$textarea.show();
|
|
||||||
|
|
||||||
// @todo restore cursor, scroll position
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start monitoring the fragment of the current window for hash change
|
|
||||||
* events. If the hash is already set, handle it as a new event.
|
|
||||||
*/
|
|
||||||
'codeEditorMonitorFragment': function() {
|
|
||||||
function onHashChange() {
|
|
||||||
var regexp = /#mw-ce-l(\d+)/;
|
|
||||||
var result = regexp.exec( window.location.hash );
|
|
||||||
if ( result === null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Line numbers in CodeEditor are zero-based
|
|
||||||
var line = parseInt( result[1] );
|
|
||||||
context.codeEditor.navigateTo( line - 1, 0 );
|
|
||||||
// Scroll up a bit to give some context
|
|
||||||
context.codeEditor.scrollToRow( line - 4 );
|
|
||||||
}
|
|
||||||
onHashChange();
|
|
||||||
$( window ).bind( 'hashchange', onHashChange );
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the base functions in a way that lets
|
|
||||||
* us fall back to the originals when we turn off.
|
|
||||||
*/
|
|
||||||
var saveAndExtend = function( base, extended ) {
|
|
||||||
var saved = {};
|
|
||||||
// $.map doesn't handle objects in jQuery < 1.6; need this for compat with MW 1.17
|
|
||||||
var map = function( obj, callback ) {
|
|
||||||
for (var key in extended ) {
|
|
||||||
if ( obj.hasOwnProperty( key ) ) {
|
|
||||||
callback( obj[key], key );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
map( extended, function( func, name ) {
|
|
||||||
if ( name in base ) {
|
|
||||||
var orig = base[name];
|
|
||||||
base[name] = function() {
|
|
||||||
if (context.codeEditorActive) {
|
|
||||||
return func.apply(this, arguments);
|
|
||||||
} else if (orig) {
|
|
||||||
return orig.apply(this, arguments);
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('CodeEditor: no original function to call for ' + name);
|
base[name] = func;
|
||||||
}
|
}
|
||||||
};
|
} );
|
||||||
} else {
|
|
||||||
base[name] = func;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
saveAndExtend( context.fn, {
|
|
||||||
'saveCursorAndScrollTop': function() {
|
|
||||||
// Stub out textarea behavior
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
'restoreCursorAndScrollTop': function() {
|
|
||||||
// Stub out textarea behavior
|
|
||||||
return;
|
|
||||||
},
|
|
||||||
'saveSelection': function() {
|
|
||||||
mw.log('codeEditor stub function saveSelection called');
|
|
||||||
},
|
|
||||||
'restoreSelection': function() {
|
|
||||||
mw.log('codeEditor stub function restoreSelection called');
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Needed for search/replace */
|
|
||||||
'getContents': function() {
|
|
||||||
return context.codeEditor.getSession().getValue();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compatibility with the $.textSelection jQuery plug-in. When the iframe is in use, these functions provide
|
|
||||||
* equivilant functionality to the otherwise textarea-based functionality.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'getElementAtCursor': function() {
|
|
||||||
mw.log('codeEditor stub function getElementAtCursor called');
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently selected text in the content
|
|
||||||
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
|
||||||
*/
|
|
||||||
'getSelection': function() {
|
|
||||||
return context.codeEditor.getCopyText();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Inserts text at the begining and end of a text selection, optionally inserting text at the caret when
|
|
||||||
* selection is empty.
|
|
||||||
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
|
||||||
*/
|
|
||||||
'encapsulateSelection': function( options ) {
|
|
||||||
// Does not yet handle 'ownline', 'splitlines' option
|
|
||||||
var sel = context.codeEditor.getSelection();
|
|
||||||
var range = sel.getRange();
|
|
||||||
var selText = context.fn.getSelection();
|
|
||||||
var isSample = false;
|
|
||||||
if ( !selText ) {
|
|
||||||
selText = options.peri;
|
|
||||||
isSample = true;
|
|
||||||
} else if ( options.replace ) {
|
|
||||||
selText = options.peri;
|
|
||||||
}
|
|
||||||
var text = options.pre;
|
|
||||||
text += selText;
|
|
||||||
text += options.post;
|
|
||||||
context.codeEditor.insert( text );
|
|
||||||
if ( isSample && options.selectPeri && !options.splitlines ) {
|
|
||||||
// May esplode if anything has newlines, be warned. :)
|
|
||||||
range.setStart( range.start.row, range.start.column + options.pre.length );
|
|
||||||
range.setEnd( range.start.row, range.start.column + selText.length );
|
|
||||||
sel.setSelectionRange(range);
|
|
||||||
}
|
|
||||||
return context.$textarea;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Gets the position (in resolution of bytes not nessecarily characters) in a textarea
|
|
||||||
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
|
||||||
*/
|
|
||||||
'getCaretPosition': function( options ) {
|
|
||||||
mw.log('codeEditor stub function getCaretPosition called');
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Sets the selection of the content
|
|
||||||
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
|
||||||
*
|
|
||||||
* @param start Character offset of selection start
|
|
||||||
* @param end Character offset of selection end
|
|
||||||
* @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
|
|
||||||
*/
|
|
||||||
'setSelection': function( options ) {
|
|
||||||
// Ace stores positions for ranges as row/column pairs.
|
|
||||||
// To convert from character offsets, we'll need to iterate through the document
|
|
||||||
var doc = context.codeEditor.getSession().getDocument();
|
|
||||||
var lines = doc.getAllLines();
|
|
||||||
|
|
||||||
var offsetToPos = function( offset ) {
|
|
||||||
var row = 0, col = 0;
|
|
||||||
var pos = 0;
|
|
||||||
while ( row < lines.length && pos + lines[row].length < offset) {
|
|
||||||
pos += lines[row].length;
|
|
||||||
pos++; // for the newline
|
|
||||||
row++;
|
|
||||||
}
|
|
||||||
col = offset - pos;
|
|
||||||
return {row: row, column: col};
|
|
||||||
};
|
};
|
||||||
var start = offsetToPos( options.start ),
|
|
||||||
end = offsetToPos( options.end );
|
|
||||||
|
|
||||||
var sel = context.codeEditor.getSelection();
|
saveAndExtend( context.fn, {
|
||||||
var range = sel.getRange();
|
'saveCursorAndScrollTop': function () {
|
||||||
range.setStart( start.row, start.column );
|
// Stub out textarea behavior
|
||||||
range.setEnd( end.row, end.column );
|
return;
|
||||||
sel.setSelectionRange( range );
|
},
|
||||||
return context.$textarea;
|
'restoreCursorAndScrollTop': function () {
|
||||||
},
|
// Stub out textarea behavior
|
||||||
/**
|
return;
|
||||||
* 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
|
'saveSelection': function () {
|
||||||
*/
|
mw.log( 'codeEditor stub function saveSelection called' );
|
||||||
'scrollToCaretPosition': function( options ) {
|
},
|
||||||
mw.log('codeEditor stub function scrollToCaretPosition called');
|
'restoreSelection': function () {
|
||||||
return context.$textarea;
|
mw.log( 'codeEditor stub function restoreSelection called' );
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Scroll an element to the top of the iframe
|
|
||||||
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
|
||||||
*
|
|
||||||
* @param $element jQuery object containing an element in the iframe
|
|
||||||
* @param force If true, scroll the element even if it's already visible
|
|
||||||
*/
|
|
||||||
'scrollToTop': function( $element, force ) {
|
|
||||||
mw.log('codeEditor stub function scrollToTop called');
|
|
||||||
}
|
|
||||||
} );
|
|
||||||
|
|
||||||
/* Setup the editor */
|
/* Needed for search/replace */
|
||||||
context.fn.setupCodeEditorToolbar();
|
'getContents': function () {
|
||||||
if (context.codeEditorActive) {
|
return context.codeEditor.getSession().getValue();
|
||||||
context.fn.setupCodeEditor();
|
},
|
||||||
}
|
|
||||||
|
|
||||||
};
|
/**
|
||||||
} )( jQuery );
|
* Compatibility with the $.textSelection jQuery plug-in. When the iframe is in use, these functions provide
|
||||||
|
* equivilant functionality to the otherwise textarea-based functionality.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'getElementAtCursor': function () {
|
||||||
|
mw.log( 'codeEditor stub function getElementAtCursor called' );
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the currently selected text in the content
|
||||||
|
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
||||||
|
*/
|
||||||
|
'getSelection': function () {
|
||||||
|
return context.codeEditor.getCopyText();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Inserts text at the begining and end of a text selection, optionally inserting text at the caret when
|
||||||
|
* selection is empty.
|
||||||
|
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
||||||
|
*/
|
||||||
|
'encapsulateSelection': function ( options ) {
|
||||||
|
// Does not yet handle 'ownline', 'splitlines' option
|
||||||
|
var sel = context.codeEditor.getSelection();
|
||||||
|
var range = sel.getRange();
|
||||||
|
var selText = context.fn.getSelection();
|
||||||
|
var isSample = false;
|
||||||
|
if ( !selText ) {
|
||||||
|
selText = options.peri;
|
||||||
|
isSample = true;
|
||||||
|
} else if ( options.replace ) {
|
||||||
|
selText = options.peri;
|
||||||
|
}
|
||||||
|
var text = options.pre;
|
||||||
|
text += selText;
|
||||||
|
text += options.post;
|
||||||
|
context.codeEditor.insert( text );
|
||||||
|
if ( isSample && options.selectPeri && !options.splitlines ) {
|
||||||
|
// May esplode if anything has newlines, be warned. :)
|
||||||
|
range.setStart( range.start.row, range.start.column + options.pre.length );
|
||||||
|
range.setEnd( range.start.row, range.start.column + selText.length );
|
||||||
|
sel.setSelectionRange( range );
|
||||||
|
}
|
||||||
|
return context.$textarea;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Gets the position (in resolution of bytes not nessecarily characters) in a textarea
|
||||||
|
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
||||||
|
*/
|
||||||
|
'getCaretPosition': function ( options ) {
|
||||||
|
mw.log( 'codeEditor stub function getCaretPosition called' );
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Sets the selection of the content
|
||||||
|
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
||||||
|
*
|
||||||
|
* @param start Character offset of selection start
|
||||||
|
* @param end Character offset of selection end
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
'setSelection': function ( options ) {
|
||||||
|
// Ace stores positions for ranges as row/column pairs.
|
||||||
|
// To convert from character offsets, we'll need to iterate through the document
|
||||||
|
var doc = context.codeEditor.getSession().getDocument();
|
||||||
|
var lines = doc.getAllLines();
|
||||||
|
|
||||||
|
var offsetToPos = function ( offset ) {
|
||||||
|
var row = 0, col = 0;
|
||||||
|
var pos = 0;
|
||||||
|
while ( row < lines.length && pos + lines[row].length < offset ) {
|
||||||
|
pos += lines[row].length;
|
||||||
|
pos++; // for the newline
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
col = offset - pos;
|
||||||
|
return {row: row, column: col};
|
||||||
|
};
|
||||||
|
var start = offsetToPos( options.start ),
|
||||||
|
end = offsetToPos( options.end );
|
||||||
|
|
||||||
|
var sel = context.codeEditor.getSelection();
|
||||||
|
var range = sel.getRange();
|
||||||
|
range.setStart( start.row, start.column );
|
||||||
|
range.setEnd( end.row, end.column );
|
||||||
|
sel.setSelectionRange( range );
|
||||||
|
return context.$textarea;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
'scrollToCaretPosition': function ( options ) {
|
||||||
|
mw.log( 'codeEditor stub function scrollToCaretPosition called' );
|
||||||
|
return context.$textarea;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Scroll an element to the top of the iframe
|
||||||
|
* DO NOT CALL THIS DIRECTLY, use $.textSelection( 'functionname', options ) instead
|
||||||
|
*
|
||||||
|
* @param $element jQuery object containing an element in the iframe
|
||||||
|
* @param force If true, scroll the element even if it's already visible
|
||||||
|
*/
|
||||||
|
'scrollToTop': function ( $element, force ) {
|
||||||
|
mw.log( 'codeEditor stub function scrollToTop called' );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
/* Setup the editor */
|
||||||
|
context.fn.setupCodeEditorToolbar();
|
||||||
|
if ( context.codeEditorActive ) {
|
||||||
|
context.fn.setupCodeEditor();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
})( jQuery );
|
||||||
|
|
Loading…
Reference in a new issue