blob: 5d82c03e34056390a568ef7b44f2d095693b0484 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* gollum.editor.js
* A jQuery plugin that creates the Gollum Editor.
*
* Usage:
* $.GollumEditor(); on DOM ready.
*/
(function($) {
// Editor options
var DefaultOptions = {
MarkupType: 'markdown',
EditorMode: 'code',
NewFile: false,
HasFunctionBar: true,
Debug: false,
NoDefinitionsFor: []
};
var ActiveOptions = {};
/**
* $.GollumEditor
*
* You don't need to do anything. Just run this on DOM ready.
*/
$.GollumEditor = function( IncomingOptions ) {
ActiveOptions = $.extend( DefaultOptions, IncomingOptions );
debug('GollumEditor loading');
if ( EditorHas.baseEditorMarkup() ) {
if ( EditorHas.titleDisplayed() ) {
$('#gollum-editor-title-field').addClass('active');
}
if ( EditorHas.editSummaryMarkup() ) {
$.GollumEditor.Placeholder.add($('#gollum-editor-edit-summary input'));
$('#gollum-editor form[name="gollum-editor"]').submit(function( e ) {
e.preventDefault();
$.GollumEditor.Placeholder.clearAll();
debug('submitting');
$(this).unbind('submit');
$(this).submit();
});
}
if ( EditorHas.collapsibleInputs() ) {
$('#gollum-editor .collapsed a.button, ' +
'#gollum-editor .expanded a.button').click(function( e ) {
e.preventDefault();
$(this).parent().toggleClass('expanded');
$(this).parent().toggleClass('collapsed');
});
}
if ( EditorHas.previewButton() ) {
var formAction =
$('#gollum-editor #gollum-editor-preview').click(function() {
// make a dummy form, submit to new target window
// get form fields
var oldAction = $('#gollum-editor form').attr('action');
var $form = $($('#gollum-editor form').get(0));
$form.attr('action', this.href || '/preview');
$form.attr('target', '_blank');
$form.submit();
$form.attr('action', oldAction);
$form.removeAttr('target');
return false;
});
}
// Initialize the function bar by loading proper definitions
if ( EditorHas.functionBar() ) {
var htmlSetMarkupLang =
$('#gollum-editor-body').attr('data-markup-lang');
if ( htmlSetMarkupLang ) {
ActiveOptions.MarkupType = htmlSetMarkupLang;
}
// load language definition
LanguageDefinition.setActiveLanguage( ActiveOptions.MarkupType );
if ( EditorHas.formatSelector() ) {
FormatSelector.init(
$('#gollum-editor-format-selector select') );
}
if ( EditorHas.help() ) {
$('#gollum-editor-help').hide();
$('#gollum-editor-help').removeClass('jaws');
}
}
// EditorHas.functionBar
}
// EditorHas.baseEditorMarkup
};
/**
* $.GollumEditor.defineLanguage
* Defines a set of language actions that Gollum can use.
* Used by the definitions in langs/ to register language definitions.
*/
$.GollumEditor.defineLanguage = function( language_name, languageObject ) {
if ( typeof languageObject == 'object' ) {
LanguageDefinition.define( language_name, languageObject );
} else {
debug('GollumEditor.defineLanguage: definition for ' + language_name +
' is not an object');
}
};
/**
* debug
* Prints debug information to console.log if debug output is enabled.
*
* @param mixed Whatever you want to dump to console.log
* @return void
*/
var debug = function(m) {
if ( ActiveOptions.Debug &&
typeof console != 'undefined' ) {
console.log( m );
}
};
/**
* LanguageDefinition
* Language definition file handler
* Loads language definition files as necessary.
*/
var LanguageDefinition = {
_ACTIVE_LANG: '',
_LOADED_LANGS: [],
_LANG: {},
/**
* Defines a language
*
* @param name string The name of the language
* @param name object The definition object
*/
define: function( name, definitionObject ) {
LanguageDefinition._ACTIVE_LANG = name;
LanguageDefinition._LOADED_LANGS.push( name );
if ( typeof $.GollumEditor.WikiLanguage == 'object' ) {
var definition = {};
$.extend(definition, $.GollumEditor.WikiLanguage, definitionObject);
LanguageDefinition._LANG[name] = definition;
} else {
LanguageDefinition._LANG[name] = definitionObject;
}
},
getActiveLanguage: function() {
return LanguageDefinition._ACTIVE_LANG;
},
setActiveLanguage: function( name ) {
if ( !LanguageDefinition.isLoadedFor(name) ) {
LanguageDefinition._ACTIVE_LANG = null;
LanguageDefinition.loadFor( name, function(x, t) {
if ( t != 'success' ) {
debug('Failed to load language definition for ' + name);
// well, fake it and turn everything off for this one
LanguageDefinition.define( name, {} );
}
// update features that rely on the language definition
if ( EditorHas.functionBar() ) {
FunctionBar.refresh();
}
if ( LanguageDefinition.isValid() && EditorHas.formatSelector() ) {
FormatSelector.updateSelected();
}
} );
} else {
LanguageDefinition._ACTIVE_LANG = name;
FunctionBar.refresh();
}
},
/**
* gets a definition object for a specified attribute
*
* @param string attr The specified attribute.
* @param string specified_lang The language to pull a definition for.
* @return object if exists, null otherwise
*/
getDefinitionFor: function( attr, specified_lang ) {
if ( !specified_lang ) {
specified_lang = LanguageDefinition._ACTIVE_LANG;
}
if ( LanguageDefinition.isLoadedFor(specified_lang) &&
LanguageDefinition._LANG[specified_lang][attr] &&
typeof LanguageDefinition._LANG[specified_lang][attr] == 'object' ) {
return LanguageDefinition._LANG[specified_lang][attr];
}
return null;
},
/**
* loadFor
* Asynchronously loads a definition file for the current markup.
* Definition files are necessary to use the code editor.
*
* @param string markup_name The markup name you want to load
* @return void
*/
loadFor: function( markup_name, on_complete ) {
// Keep us from hitting 404s on our site, check the definition blacklist
if ( ActiveOptions.NoDefinitionsFor.length ) {
for ( var i=0; i < ActiveOptions.NoDefinitionsFor.length; i++ ) {
if ( markup_name == ActiveOptions.NoDefinitionsFor[i] ) {
// we don't have this. get out.
if ( typeof on_complete == 'function' ) {
on_complete( null, 'error' );
return;
}
}
}
}
// attempt to load the definition for this language
var script_uri = '/javascript/editor/langs/' + markup_name + '.js';
$.ajax({
url: script_uri,
dataType: 'script',
complete: function( xhr, textStatus ) {
if ( typeof on_complete == 'function' ) {
on_complete( xhr, textStatus );
}
}
});
},
/**
* isLoadedFor
* Checks to see if a definition file has been loaded for the
* specified markup language.
*
* @param string markup_name The name of the markup.
* @return boolean
*/
isLoadedFor: function( markup_name ) {
if ( LanguageDefinition._LOADED_LANGS.length === 0 ) {
return false;
}
for ( var i=0; i < LanguageDefinition._LOADED_LANGS.length; i++ ) {
if ( LanguageDefinition._LOADED_LANGS[i] == markup_name ) {
return true;
}
}
return false;
},
isValid: function() {
return ( LanguageDefinition._ACTIVE_LANG &&
typeof LanguageDefinition._LANG[LanguageDefinition._ACTIVE_LANG] ==
'object' );
}
};
/**
* EditorHas
* Various conditionals to check what features of the Gollum Editor are
* active/operational.
*/
var EditorHas = {
/**
* EditorHas.baseEditorMarkup
* True if the basic editor form is in place.
*
* @return boolean
*/
baseEditorMarkup: function() {
return ( $('#gollum-editor').length &&
$('#gollum-editor-body').length );
},
/**
* EditorHas.collapsibleInputs
* True if the editor contains collapsible inputs for things like the
* sidebar or footer, false otherwise.
*
* @return boolean
*/
collapsibleInputs: function() {
return $('#gollum-editor .collapsed, #gollum-editor .expanded').length;
},
/**
* EditorHas.formatSelector
* True if the editor has a format selector (for switching between
* language types), false otherwise.
*
* @return boolean
*/
formatSelector: function() {
return $('#gollum-editor-format-selector select').length;
},
/**
* EditorHas.functionBar
* True if the Function Bar markup exists.
*
* @return boolean
*/
functionBar: function() {
return ( ActiveOptions.HasFunctionBar &&
$('#gollum-editor-function-bar').length );
},
/**
* EditorHas.ff4Environment
* True if in a Firefox 4.0 Beta environment.
*
* @return boolean
*/
ff4Environment: function() {
var ua = new RegExp(/Firefox\/4.0b/);
return ( ua.test( navigator.userAgent ) );
},
/**
* EditorHas.editSummaryMarkup
* True if the editor has a summary field (Gollum's commit message),
* false otherwise.
*
* @return boolean
*/
editSummaryMarkup: function() {
return ( $('input#gollum-editor-message-field').length > 0 );
},
/**
* EditorHas.help
* True if the editor contains the inline help sector, false otherwise.
*
* @return boolean
*/
help: function() {
return ( $('#gollum-editor #gollum-editor-help').length &&
$('#gollum-editor #function-help').length );
},
/**
* EditorHas.previewButton
* True if the editor has a preview button, false otherwise.
*
* @return boolean
*/
previewButton: function() {
return ( $('#gollum-editor #gollum-editor-preview').length );
},
/**
* EditorHas.titleDisplayed
* True if the editor is displaying a title field, false otherwise.
*
* @return boolean
*/
titleDisplayed: function() {
return ( ActiveOptions.NewFile );
}
};
/**
* FunctionBar
*
* Things the function bar does.
*/
var FunctionBar = {
isActive: false,
/**
* FunctionBar.activate
* Activates the function bar, attaching all click events
* and displaying the bar.
*
*/
activate: function() {
debug('Activating function bar');
// check these out
$('#gollum-editor-function-bar a.function-button').each(function() {
if ( LanguageDefinition.getDefinitionFor( $(this).attr('id') ) ) {
$(this).click( FunctionBar.evtFunctionButtonClick );
$(this).removeClass('disabled');
}
else if ( $(this).attr('id') != 'function-help' ) {
$(this).addClass('disabled');
}
});
// show bar as active
$('#gollum-editor-function-bar').addClass( 'active' );
FunctionBar.isActive = true;
},
deactivate: function() {
$('#gollum-editor-function-bar a.function-button').unbind('click');
$('#gollum-editor-function-bar').removeClass( 'active' );
FunctionBar.isActive = false;
},
/**
* FunctionBar.evtFunctionButtonClick
* Event handler for the function buttons. Traps the click and
* executes the proper language action.
*
* @param jQuery.Event jQuery event object.
*/
evtFunctionButtonClick: function(e) {
e.preventDefault();
var def = LanguageDefinition.getDefinitionFor( $(this).attr('id') );
if ( typeof def == 'object' ) {
FunctionBar.executeAction( def );
}
},
/**
* FunctionBar.executeAction
* Executes a language-specific defined action for a function button.
*
*/
executeAction: function( definitionObject ) {
// get the selected text from the textarea
var txt = $('#gollum-editor-body').val();
// hmm, I'm not sure this will work in a textarea
var selPos = FunctionBar
.getFieldSelectionPosition( $('#gollum-editor-body') );
var selText = FunctionBar.getFieldSelection( $('#gollum-editor-body') );
var repText = selText;
var reselect = true;
var cursor = null;
// execute a replacement function if one exists
if ( definitionObject.exec &&
typeof definitionObject.exec == 'function' ) {
definitionObject.exec( txt, selText, $('#gollum-editor-body') );
return;
}
// execute a search/replace if they exist
var searchExp = /([^\n]+)/gi;
if ( definitionObject.search &&
typeof definitionObject.search == 'object' ) {
debug('Replacing search Regex');
searchExp = null;
searchExp = new RegExp ( definitionObject.search );
debug( searchExp );
}
debug('repText is ' + '"' + repText + '"');
// replace text
if ( definitionObject.replace &&
typeof definitionObject.replace == 'string' ) {
debug('Running replacement - using ' + definitionObject.replace);
var rt = definitionObject.replace;
repText = repText.replace( searchExp, rt );
// remove backreferences
repText = repText.replace( /\$[\d]/g, '' );
if ( repText === '' ) {
debug('Search string is empty');
// find position of $1 - this is where we will place the cursor
cursor = rt.indexOf('$1');
// we have an empty string, so just remove backreferences
repText = rt.replace( /\$[\d]/g, '' );
// if the position of $1 doesn't exist, stick the cursor in
// the middle
if ( cursor == -1 ) {
cursor = Math.floor( rt.length / 2 );
}
}
}
// append if necessary
if ( definitionObject.append &&
typeof definitionObject.append == 'string' ) {
if ( repText == selText ) {
reselect = false;
}
repText += definitionObject.append;
}
if ( repText ) {
FunctionBar.replaceFieldSelection( $('#gollum-editor-body'),
repText, reselect, cursor );
}
},
/**
* getFieldSelectionPosition
* Retrieves the selection range for the textarea.
*
* @return object the .start and .end offsets in the string
*/
getFieldSelectionPosition: function( $field ) {
if ($field.length) {
var start = 0, end = 0;
var el = $field.get(0);
if (typeof el.selectionStart == "number" &&
typeof el.selectionEnd == "number") {
start = el.selectionStart;
end = el.selectionEnd;
} else {
var range = document.selection.createRange();
var stored_range = range.duplicate();
stored_range.moveToElementText( el );
stored_range.setEndPoint( 'EndToEnd', range );
start = stored_range.text.length - range.text.length;
end = start + range.text.length;
// so, uh, we're close, but we need to search for line breaks and
// adjust the start/end points accordingly since IE counts them as
// 2 characters in TextRange.
var s = start;
var lb = 0;
var i;
debug('IE: start position is currently ' + s);
for ( i=0; i < s; i++ ) {
if ( el.value.charAt(i).match(/\r/) ) {
++lb;
}
}
if ( lb ) {
debug('IE start: compensating for ' + lb + ' line breaks');
start = start - lb;
lb = 0;
}
var e = end;
for ( i=0; i < e; i++ ) {
if ( el.value.charAt(i).match(/\r/) ) {
++lb;
}
}
if ( lb ) {
debug('IE end: compensating for ' + lb + ' line breaks');
end = end - lb;
}
}
return {
start: start,
end: end
};
} // end if ($field.length)
},
/**
* getFieldSelection
* Returns the currently selected substring of the textarea.
*
* @param jQuery A jQuery object for the textarea.
* @return string Selected string.
*/
getFieldSelection: function( $field ) {
var selStr = '';
var selPos;
if ( $field.length ) {
selPos = FunctionBar.getFieldSelectionPosition( $field );
selStr = $field.val().substring( selPos.start, selPos.end );
debug('Selected: ' + selStr + ' (' + selPos.start + ', ' +
selPos.end + ')');
return selStr;
}
return false;
},
isShown: function() {
return ($('#gollum-editor-function-bar').is(':visible'));
},
refresh: function() {
if ( EditorHas.functionBar() ) {
debug('Refreshing function bar');
if ( LanguageDefinition.isValid() ) {
$('#gollum-editor-function-bar a.function-button').unbind('click');
FunctionBar.activate();
if ( Help ) {
Help.setActiveHelp( LanguageDefinition.getActiveLanguage() );
}
} else {
debug('Language definition is invalid.');
if ( FunctionBar.isShown() ) {
// deactivate the function bar; it's not gonna work now
FunctionBar.deactivate();
}
if ( Help.isShown() ) {
Help.hide();
}
}
}
},
/**
* replaceFieldSelection
* Replaces the currently selected substring of the textarea with
* a new string.
*
* @param jQuery A jQuery object for the textarea.
* @param string The string to replace the current selection with.
* @param boolean Reselect the new text range.
*/
replaceFieldSelection: function( $field, replaceText, reselect, cursorOffset ) {
var selPos = FunctionBar.getFieldSelectionPosition( $field );
var fullStr = $field.val();
var selectNew = true;
if ( reselect === false) {
selectNew = false;
}
var scrollTop = null;
if ( $field[0].scrollTop ) {
scrollTop = $field[0].scrollTop;
}
$field.val( fullStr.substring(0, selPos.start) + replaceText +
fullStr.substring(selPos.end) );
$field[0].focus();
if ( selectNew ) {
if ( $field[0].setSelectionRange ) {
if ( cursorOffset ) {
$field[0].setSelectionRange(
selPos.start + cursorOffset,
selPos.start + cursorOffset
);
} else {
$field[0].setSelectionRange( selPos.start,
selPos.start + replaceText.length );
}
} else if ( $field[0].createTextRange ) {
var range = $field[0].createTextRange();
range.collapse( true );
if ( cursorOffset ) {
range.moveEnd( selPos.start + cursorOffset );
range.moveStart( selPos.start + cursorOffset );
} else {
range.moveEnd( 'character', selPos.start + replaceText.length );
range.moveStart( 'character', selPos.start );
}
range.select();
}
}
if ( scrollTop ) {
// this jumps sometimes in FF
$field[0].scrollTop = scrollTop;
}
}
};
/**
* FormatSelector
*
* Functions relating to the format selector (if it exists)
*/
var FormatSelector = {
$_SELECTOR: null,
/**
* FormatSelector.evtChangeFormat
* Event handler for when a format has been changed by the format
* selector. Will automatically load a new language definition
* via JS if necessary.
*
* @return void
*/
evtChangeFormat: function( e ) {
var newMarkup = $(this).val();
LanguageDefinition.setActiveLanguage( newMarkup );
},
/**
* FormatSelector.init
* Initializes the format selector.
*
* @return void
*/
init: function( $sel ) {
debug('Initializing format selector');
// unbind events if init is being called twice for some reason
if ( FormatSelector.$_SELECTOR &&
typeof FormatSelector.$_SELECTOR == 'object' ) {
FormatSelector.$_SELECTOR.unbind( 'change' );
}
FormatSelector.$_SELECTOR = $sel;
// set format selector to the current language
FormatSelector.updateSelected();
FormatSelector.$_SELECTOR.change( FormatSelector.evtChangeFormat );
},
/**
* FormatSelector.update
*/
updateSelected: function() {
var currentLang = LanguageDefinition.getActiveLanguage();
FormatSelector.$_SELECTOR.val( currentLang );
}
};
/**
* Help
*
* Functions that manage the display and loading of inline help files.
*/
var Help = {
_ACTIVE_HELP: '',
_LOADED_HELP_LANGS: [],
_HELP: {},
/**
* Help.define
*
* Defines a new help context and enables the help function if it
* exists in the Gollum Function Bar.
*
* @param string name The name you're giving to this help context.
* Generally, this should match the language name.
* @param object definitionObject The definition object being loaded from a
* language / help definition file.
* @return void
*/
define: function( name, definitionObject ) {
if ( Help.isValidHelpFormat( definitionObject ) ) {
debug('help is a valid format');
Help._ACTIVE_HELP_LANG = name;
Help._LOADED_HELP_LANGS.push( name );
Help._HELP[name] = definitionObject;
if ( $("#function-help").length ) {
if ( $('#function-help').hasClass('disabled') ) {
$('#function-help').removeClass('disabled');
}
$('#function-help').unbind('click');
$('#function-help').click( Help.evtHelpButtonClick );
// generate help menus
Help.generateHelpMenuFor( name );
if ( $('#gollum-editor-help').length &&
typeof $('#gollum-editor-help').attr('data-autodisplay') !== 'undefined' &&
$('#gollum-editor-help').attr('data-autodisplay') === 'true' ) {
Help.show();
}
}
} else {
if ( $('#function-help').length ) {
$('#function-help').addClass('disabled');
}
}
},
/**
* Help.generateHelpMenuFor
* Generates the markup for the main help menu given a context name.
*
* @param string name The context name.
* @return void
*/
generateHelpMenuFor: function( name ) {
if ( !Help._HELP[name] ) {
debug('Help is not defined for ' + name.toString());
return false;
}
var helpData = Help._HELP[name];
// clear this shiz out
$('#gollum-editor-help-parent').html('');
$('#gollum-editor-help-list').html('');
$('#gollum-editor-help-content').html('');
// go go inefficient algorithm
for ( var i=0; i < helpData.length; i++ ) {
if ( typeof helpData[i] != 'object' ) {
break;
}
var $newLi = $('<li><a href="#" rel="' + i + '">' +
helpData[i].menuName + '</a></li>');
$('#gollum-editor-help-parent').append( $newLi );
if ( i === 0 ) {
// select on first run
$newLi.children('a').addClass('selected');
}
$newLi.children('a').click( Help.evtParentMenuClick );
}
// generate parent submenu on first run
Help.generateSubMenu( helpData[0], 0 );
$($('#gollum-editor-help-list li a').get(0)).click();
},
/**
* Help.generateSubMenu
* Generates the markup for the inline help sub-menu given the data
* object for the submenu and the array index to start at.
*
* @param object subData The data for the sub-menu.
* @param integer index The index clicked on (parent menu index).
* @return void
*/
generateSubMenu: function( subData, index ) {
$('#gollum-editor-help-list').html('');
$('#gollum-editor-help-content').html('');
for ( var i=0; i < subData.content.length; i++ ) {
if ( typeof subData.content[i] != 'object' ) {
break;
}
var $subLi = $('<li><a href="#" rel="' + index + ':' + i + '">' +
subData.content[i].menuName + '</a></li>');
$('#gollum-editor-help-list').append( $subLi );
$subLi.children('a').click( Help.evtSubMenuClick );
}
},
hide: function() {
if ( $.browser.msie ) {
$('#gollum-editor-help').css('display', 'none');
} else {
$('#gollum-editor-help').animate({
opacity: 0
}, 200, function() {
$('#gollum-editor-help')
.animate({ height: 'hide' }, 200);
});
}
},
show: function() {
if ( $.browser.msie ) {
// bypass effects for internet explorer, since it does weird crap
// to text antialiasing with opacity animations
$('#gollum-editor-help').css('display', 'block');
} else {
$('#gollum-editor-help').animate({
height: 'show'
}, 200, function() {
$('#gollum-editor-help')
.animate({ opacity: 1 }, 300);
});
}
},
/**
* Help.showHelpFor
* Displays the actual help content given the two menu indexes, which are
* rendered in the rel="" attributes of the help menus
*
* @param integer index1 parent index
* @param integer index2 submenu index
* @return void
*/
showHelpFor: function( index1, index2 ) {
var html =
Help._HELP[Help._ACTIVE_HELP_LANG][index1].content[index2].data;
$('#gollum-editor-help-content').html(html);
},
/**
* Help.isLoadedFor
* Returns true if help is loaded for a specific markup language,
* false otherwise.
*
* @param string name The name of the markup language.
* @return boolean
*/
isLoadedFor: function( name ) {
for ( var i=0; i < Help._LOADED_HELP_LANGS.length; i++ ) {
if ( name == Help._LOADED_HELP_LANGS[i] ) {
return true;
}
}
return false;
},
isShown: function() {
return ($('#gollum-editor-help').is(':visible'));
},
/**
* Help.isValidHelpFormat
* Does a quick check to make sure that the help definition isn't in a
* completely messed-up format.
*
* @param object (Array) helpArr The help definition array.
* @return boolean
*/
isValidHelpFormat: function( helpArr ) {
return ( typeof helpArr == 'object' &&
helpArr.length &&
typeof helpArr[0].menuName == 'string' &&
typeof helpArr[0].content == 'object' &&
helpArr[0].content.length );
},
/**
* Help.setActiveHelp
* Sets the active help definition to the one defined in the argument,
* re-rendering the help menu to match the new definition.
*
* @param string name The name of the help definition.
* @return void
*/
setActiveHelp: function( name ) {
if ( !Help.isLoadedFor( name ) ) {
if ( $('#function-help').length ) {
$('#function-help').addClass('disabled');
}
if ( Help.isShown() ) {
Help.hide();
}
} else {
Help._ACTIVE_HELP_LANG = name;
if ( $("#function-help").length ) {
if ( $('#function-help').hasClass('disabled') ) {
$('#function-help').removeClass('disabled');
}
$('#function-help').unbind('click');
$('#function-help').click( Help.evtHelpButtonClick );
Help.generateHelpMenuFor( name );
}
}
},
/**
* Help.evtHelpButtonClick
* Event handler for clicking the help button in the function bar.
*
* @param jQuery.Event e The jQuery event object.
* @return void
*/
evtHelpButtonClick: function( e ) {
e.preventDefault();
if ( Help.isShown() ) {
// turn off autodisplay if it's on
if ( $('#gollum-editor-help').length &&
$('#gollum-editor-help').attr('data-autodisplay') !== 'undefined' &&
$('#gollum-editor-help').attr('data-autodisplay') === 'true' ) {
$.post('/wiki/help?_method=delete');
$('#gollum-editor-help').attr('data-autodisplay', '');
}
Help.hide(); }
else { Help.show(); }
},
/**
* Help.evtParentMenuClick
* Event handler for clicking on an item in the parent menu. Automatically
* renders the submenu for the parent menu as well as the first result for
* the actual plain text.
*
* @param jQuery.Event e The jQuery event object.
* @return void
*/
evtParentMenuClick: function( e ) {
e.preventDefault();
// short circuit if we've selected this already
if ( $(this).hasClass('selected') ) { return; }
// populate from help data for this
var helpIndex = $(this).attr('rel');
var subData = Help._HELP[Help._ACTIVE_HELP_LANG][helpIndex];
$('#gollum-editor-help-parent li a').removeClass('selected');
$(this).addClass('selected');
Help.generateSubMenu( subData, helpIndex );
$($('#gollum-editor-help-list li a').get(0)).click();
},
/**
* Help.evtSubMenuClick
* Event handler for clicking an item in a help submenu. Renders the
* appropriate text for the submenu link.
*
* @param jQuery.Event e The jQuery event object.
* @return void
*/
evtSubMenuClick: function( e ) {
e.preventDefault();
if ( $(this).hasClass('selected') ) { return; }
// split index rel data
var rawIndex = $(this).attr('rel').split(':');
$('#gollum-editor-help-list li a').removeClass('selected');
$(this).addClass('selected');
Help.showHelpFor( rawIndex[0], rawIndex[1] );
}
};
// Publicly-accessible function to Help.define
$.GollumEditor.defineHelp = Help.define;
// Dialog exists as its own thing now
$.GollumEditor.Dialog = $.GollumDialog;
$.GollumEditor.replaceSelection = function( repText ) {
FunctionBar.replaceFieldSelection( $('#gollum-editor-body'), repText );
};
// Placeholder exists as its own thing now
$.GollumEditor.Placeholder = $.GollumPlaceholder;
})(jQuery);