Fail nicely with a malformed language definition, play by Crockford's rules
This commit is contained in:
@@ -107,11 +107,12 @@
|
||||
* Used by the definitions in langs/ to register language definitions.
|
||||
*/
|
||||
$.GollumEditor.defineLanguage = function( language_name, languageObject ) {
|
||||
if ( typeof languageObject == 'object' )
|
||||
if ( typeof languageObject == 'object' ) {
|
||||
LanguageDefinition.define( language_name, languageObject );
|
||||
else
|
||||
debug('GollumEditor.defineLanguage: definition for ' + language_name
|
||||
+ ' is not an object');
|
||||
} else {
|
||||
debug('GollumEditor.defineLanguage: definition for ' + language_name +
|
||||
' is not an object');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -123,8 +124,8 @@
|
||||
* @return void
|
||||
*/
|
||||
var debug = function(m) {
|
||||
if ( ActiveOptions.Debug
|
||||
&& typeof console != 'undefined' ) {
|
||||
if ( ActiveOptions.Debug &&
|
||||
typeof console != 'undefined' ) {
|
||||
console.log( m );
|
||||
}
|
||||
};
|
||||
@@ -164,15 +165,19 @@
|
||||
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, {} );
|
||||
return;
|
||||
}
|
||||
|
||||
// update features that rely on the language definition
|
||||
if ( EditorHas.functionBar() )
|
||||
if ( EditorHas.functionBar() ) {
|
||||
FunctionBar.refresh();
|
||||
}
|
||||
|
||||
if ( LanguageDefinition.isValid() && EditorHas.formatSelector() )
|
||||
if ( LanguageDefinition.isValid() && EditorHas.formatSelector() ) {
|
||||
FormatSelector.updateSelected();
|
||||
}
|
||||
|
||||
} );
|
||||
} else {
|
||||
@@ -236,11 +241,14 @@
|
||||
* @return boolean
|
||||
*/
|
||||
isLoadedFor: function( markup_name ) {
|
||||
if ( LanguageDefinition._LOADED_LANGS.length == 0 ) return false;
|
||||
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;
|
||||
if ( LanguageDefinition._LOADED_LANGS[i] == markup_name ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@@ -406,8 +414,9 @@
|
||||
$(this).click( FunctionBar.evtFunctionButtonClick );
|
||||
$(this).removeClass('disabled');
|
||||
}
|
||||
else if ( $(this).attr('id') != 'function-help' )
|
||||
else if ( $(this).attr('id') != 'function-help' ) {
|
||||
$(this).addClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
// show bar as active
|
||||
@@ -458,7 +467,7 @@
|
||||
// execute a replacement function if one exists
|
||||
if ( definitionObject.exec &&
|
||||
typeof definitionObject.exec == 'function' ) {
|
||||
definitionObject.exec ( txt, selText, $('#gollum-editor-body') );
|
||||
definitionObject.exec( txt, selText, $('#gollum-editor-body') );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -487,11 +496,11 @@
|
||||
// remove any excess backreferences from the replace string
|
||||
rt = rt.replace( /\$[\d]/g, '' );
|
||||
repText = rt;
|
||||
} else if ( repText == '' ) {
|
||||
} else if ( repText === '' ) {
|
||||
debug('Search string is empty');
|
||||
|
||||
// find position of $1 - this is where we will place the cursor
|
||||
var cursor = rt.indexOf('$1');
|
||||
cursor = rt.indexOf('$1');
|
||||
|
||||
// we have an empty string, so just remove backreferences
|
||||
repText = rt.replace( /\$[\d]/g, '' );
|
||||
@@ -513,9 +522,10 @@
|
||||
repText += definitionObject.append;
|
||||
}
|
||||
|
||||
if ( repText )
|
||||
if ( repText ) {
|
||||
FunctionBar.replaceFieldSelection( $('#gollum-editor-body'),
|
||||
repText, reselect, cursor );
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@@ -536,22 +546,25 @@
|
||||
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;
|
||||
debug('IE: start position is currently ' + s);
|
||||
for ( var i=0; i < s; i++ )
|
||||
if ( el.value.charAt(i).match(/\r/) )
|
||||
++lb;
|
||||
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');
|
||||
@@ -560,10 +573,12 @@
|
||||
}
|
||||
|
||||
var e = end;
|
||||
for ( var i=0; i < e; i++ )
|
||||
if ( el.value.charAt(i).match(/\r/) )
|
||||
++lb;
|
||||
|
||||
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;
|
||||
@@ -592,8 +607,8 @@
|
||||
if ( $field.length ) {
|
||||
selPos = FunctionBar.getFieldSelectionPosition( $field );
|
||||
selStr = $field.val().substring( selPos.start, selPos.end );
|
||||
debug('Selected: ' + selStr + ' (' + selPos.start + ', '
|
||||
+ selPos.end + ')');
|
||||
debug('Selected: ' + selStr + ' (' + selPos.start + ', ' +
|
||||
selPos.end + ')');
|
||||
return selStr;
|
||||
}
|
||||
return false;
|
||||
@@ -609,8 +624,9 @@
|
||||
if ( LanguageDefinition.isValid() ) {
|
||||
$('#gollum-editor-function-bar a.function-button').unbind('click');
|
||||
FunctionBar.activate();
|
||||
if ( Help )
|
||||
if ( Help ) {
|
||||
Help.setActiveHelp( LanguageDefinition.getActiveLanguage() );
|
||||
}
|
||||
} else {
|
||||
debug('Language definition is invalid.');
|
||||
if ( FunctionBar.isShown() ) {
|
||||
@@ -639,7 +655,7 @@
|
||||
var fullStr = $field.val();
|
||||
var selectNew = true;
|
||||
if ( reselect === false) {
|
||||
var selectNew = false;
|
||||
selectNew = false;
|
||||
}
|
||||
|
||||
var scrollTop = null;
|
||||
@@ -819,12 +835,14 @@
|
||||
|
||||
// go go inefficient algorithm
|
||||
for ( var i=0; i < helpData.length; i++ ) {
|
||||
if ( typeof helpData[i] != 'object' ) break;
|
||||
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 ) {
|
||||
if ( i === 0 ) {
|
||||
// select on first run
|
||||
$newLi.children('a').addClass('selected');
|
||||
}
|
||||
@@ -851,7 +869,9 @@
|
||||
$('#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;
|
||||
if ( typeof subData.content[i] != 'object' ) {
|
||||
break;
|
||||
}
|
||||
|
||||
var $subLi = $('<li><a href="#" rel="' + index + ':' + i + '">' +
|
||||
subData.content[i].menuName + '</a></li>');
|
||||
@@ -986,8 +1006,8 @@
|
||||
*/
|
||||
evtHelpButtonClick: function( e ) {
|
||||
e.preventDefault();
|
||||
if ( Help.isShown() ) Help.hide();
|
||||
else Help.show();
|
||||
if ( Help.isShown() ) { Help.hide(); }
|
||||
else { Help.show(); }
|
||||
},
|
||||
|
||||
|
||||
@@ -1003,7 +1023,7 @@
|
||||
evtParentMenuClick: function( e ) {
|
||||
e.preventDefault();
|
||||
// short circuit if we've selected this already
|
||||
if ( $(this).hasClass('selected') ) return;
|
||||
if ( $(this).hasClass('selected') ) { return; }
|
||||
|
||||
// populate from help data for this
|
||||
var helpIndex = $(this).attr('rel');
|
||||
@@ -1026,7 +1046,7 @@
|
||||
*/
|
||||
evtSubMenuClick: function( e ) {
|
||||
e.preventDefault();
|
||||
if ( $(this).hasClass('selected') ) return;
|
||||
if ( $(this).hasClass('selected') ) { return; }
|
||||
|
||||
// split index rel data
|
||||
var rawIndex = $(this).attr('rel').split(':');
|
||||
@@ -1044,7 +1064,7 @@
|
||||
$.GollumEditor.Dialog = $.GollumDialog;
|
||||
$.GollumEditor.replaceSelection = function( repText ) {
|
||||
FunctionBar.replaceFieldSelection( $('#gollum-editor-body'), repText );
|
||||
}
|
||||
};
|
||||
|
||||
// Placeholder exists as its own thing now
|
||||
$.GollumEditor.Placeholder = $.GollumPlaceholder;
|
||||
|
||||
Reference in New Issue
Block a user