No i'm pretty darn sure it's a bug, and it's even present in the demo over at http://codepress.sourceforge.net/index.php . So far I'm encountering it on Firefox 3.0, Firefox 3.0.1 /Windows XP, Ubuntu 8.04.
What setup are you on that has a working TAB-indent then?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Matt, I'm amazed your works, yes what setup are you using? I have Mac OS Tiger, Fedora 8, Windows XP, all with FF3, and no tabs in codepress.
The bug summary is that it was an accessibility issue, and Mozilla decided to change the default behaviour for tabs to switch to the next page element and allow developers of inline editors to alter the behaviour, rather than relying on them to build in accessibility features (such as escape key gets you out of editor, or whatever). It's been re-opened however since lots of feathers have been ruffled, no idea about what they're going to do though.
I'm a major fan of codepress, but this is making my CMS somewhat unusable :( I *hate* indenting with spaces, and I usually forget anyway, hit tab and end up typing in nothing... so now I ssh in and use nano instead, which gives you some idea of how annoying it is.
So we need a key listener on the parent window, to pass the TAB event through to the codepress window (right?). I tried passing ctrl+s events back to the parent for saving documents and gave up after a couple of hours (my JS isn't too good when there's more than one window), so don't think I'm qualified, though I'll have a go at this in a minute... meantime, if anyone comes up with a fix, please do paste it in here, alternatively email me and I'll stick it up on a blog somewhere and put a link in at bugzilla - clancyhood[at]gmail
Regards all :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
When I was still working with Codepress (I since started writing my own, as I needed more flexibility), I came up with a semi-solution for this problem. It was actually to fix the behaviour in IE, but it also works in Firefox 3.
The idea was that since the basic Codepress package had a few useful functions missing, I created an 'extend_codepress' function that adds the functions without modifying Codepress itself, so that updates could be done easily.
Within this 'extend_codepress' function, I had the TAB correction, and so I cut out the meaningful bits to present here. I hope I have not cut out anything important! One other thing, in order for things to work in IE also, I use selection objects. However, under IE, these are lost as soon as the editor looses focus. To get around this, and since all functions were to be called from a menu outside the editor, I used the mouseout event. If your code uses keyboard shortcuts as well, you should investigate whether the mouseout event has to be called manually before...
So, enough words, here is the code, I hope it can be useful for someone!
var global_ie_selection; // IE hack, as it tends to loose focus!
/* SO in order to use, you would need to call extend_codepress( [handle of the editor] )
You also need to replace all instances of "Codepress_editor_handle" and "Editor" to that handle*/
Hope this helps!
F.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if (!CodePress.snippets(evt)) {
var range = window.getSelection().getRangeAt(0);
var newTextNode = document.createTextNode('\t');
range.insertNode(newTextNode);
range.setStartAfter(newTextNode)
}
evt.preventDefault(); // prevent the tab key from being added
goto snippets : function(evt) {
first line of the function add
var workWasDone = false;
then add the second line that follows after the if statement, which is the first line here:
if(snippets[i].input == trigger) {
workWasDone = true;
finally the last line of this function is:
return workWasDone;
Now when you hit tab, it will make a tab and everyone claps their hands.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
your code is useful but need to be updated, because
when you highlighnt multiple line TAB doesn't work and also shift + tab is not supported, is it possible to update the code for gecko ?
thnak you for your great help !
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Has anyone figured out a fix or workaround for this?
With the release of Firefox 3, tab-indenting no longer works :/
Vebjorn,
I'm using Firefox 3 and the tabs are working. It may be something else in your installation?
Matt
Hi Matt!
No i'm pretty darn sure it's a bug, and it's even present in the demo over at http://codepress.sourceforge.net/index.php . So far I'm encountering it on Firefox 3.0, Firefox 3.0.1 /Windows XP, Ubuntu 8.04.
What setup are you on that has a working TAB-indent then?
Yup, it sure is a bug, though it was at NOFIX for a while: https://bugzilla.mozilla.org/show_bug.cgi?id=426690
Matt, I'm amazed your works, yes what setup are you using? I have Mac OS Tiger, Fedora 8, Windows XP, all with FF3, and no tabs in codepress.
The bug summary is that it was an accessibility issue, and Mozilla decided to change the default behaviour for tabs to switch to the next page element and allow developers of inline editors to alter the behaviour, rather than relying on them to build in accessibility features (such as escape key gets you out of editor, or whatever). It's been re-opened however since lots of feathers have been ruffled, no idea about what they're going to do though.
I'm a major fan of codepress, but this is making my CMS somewhat unusable :( I *hate* indenting with spaces, and I usually forget anyway, hit tab and end up typing in nothing... so now I ssh in and use nano instead, which gives you some idea of how annoying it is.
So we need a key listener on the parent window, to pass the TAB event through to the codepress window (right?). I tried passing ctrl+s events back to the parent for saving documents and gave up after a couple of hours (my JS isn't too good when there's more than one window), so don't think I'm qualified, though I'll have a go at this in a minute... meantime, if anyone comes up with a fix, please do paste it in here, alternatively email me and I'll stick it up on a blog somewhere and put a link in at bugzilla - clancyhood[at]gmail
Regards all :)
Hello,
When I was still working with Codepress (I since started writing my own, as I needed more flexibility), I came up with a semi-solution for this problem. It was actually to fix the behaviour in IE, but it also works in Firefox 3.
The idea was that since the basic Codepress package had a few useful functions missing, I created an 'extend_codepress' function that adds the functions without modifying Codepress itself, so that updates could be done easily.
Within this 'extend_codepress' function, I had the TAB correction, and so I cut out the meaningful bits to present here. I hope I have not cut out anything important! One other thing, in order for things to work in IE also, I use selection objects. However, under IE, these are lost as soon as the editor looses focus. To get around this, and since all functions were to be called from a menu outside the editor, I used the mouseout event. If your code uses keyboard shortcuts as well, you should investigate whether the mouseout event has to be called manually before...
So, enough words, here is the code, I hope it can be useful for someone!
var global_ie_selection; // IE hack, as it tends to loose focus!
function extend_codepress(self)
{
// IE HACK...
if(!window.selection && self.contentWindow.document.selection) {
self.onmouseout = function(){global_ie_selection = self.contentWindow.document.selection.createRange();};
}
self.contentWindow.document.onkeydown = global_keyhandler;
document.onkeydown = global_keyhandler;
self.insertText = function(txt) {
if(!self.contentWindow.document.selection) {
self.contentWindow.document.execCommand("inserthtml", null, txt);
self.focus();
self.editor.syntaxHighlight('code_insertion');
}
else { // for IE ...
if(!global_ie_selection) global_ie_selection = self.contentWindow.document.selection.createRange();
self.focus();
txt = txt.replace(/\n/gi,'<P>');
txt = txt.replace(/<BR>/gi,'<P>');
// I forget the reason why spaces are necessary in IE... try maybe with a standard tab?
txt = txt.replace(/\t/gi,' ');
global_ie_selection.pasteHTML(txt);
global_ie_selection.select();
self.editor.syntaxHighlight('code_insertion');
self.onmouseout();
}
}
}
function global_keyhandler(evt)
{
evt = evt || window.event;
var charCode = evt.keyCode;
var fromChar = String.fromCharCode(charCode);
if(fromChar == '\t') {
if(evt.preventDefault) evt.preventDefault(); // Gecko and Others
evt.returnValue = false; // IE
/*Codepress_editor_handle*/.insertCode('\t');
return false;
}
// Add other shortcuts here!
return true;
}
/* SO in order to use, you would need to call extend_codepress( [handle of the editor] )
You also need to replace all instances of "Codepress_editor_handle" and "Editor" to that handle*/
Hope this helps!
F.
Wow! Thanks Franchie, I will certainly try this out. You're a star x
Here what i did on gecko.js, replace keyHandler function by mine:
// treat key bindings
keyHandler : function(evt) {
keyCode = evt.keyCode;
charCode = evt.charCode;
fromChar = String.fromCharCode(charCode);
if(! (evt.ctrlKey || evt.metaKey || evt.shiftKey) && keyCode == 9) {
if(evt.preventDefault) evt.preventDefault(); // Gecko and Others
evt.returnValue = false; // IE
var code = '';
code = window.getSelection().getRangeAt(0).toString();
CodePress.insertCode('\t'+code);
CodePress.snippets(evt);
}
else if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && charCode!=90) { // shortcuts = ctrl||appleKey+shift+key!=z(undo)
CodePress.shortcuts(charCode?charCode:keyCode);
}
else if( (completeEndingChars.indexOf('|'+fromChar+'|')!= -1 || completeChars.indexOf('|'+fromChar+'|')!=-1) && CodePress.autocomplete) { // auto complete
if(!CodePress.completeEnding(fromChar))
CodePress.complete(fromChar);
}
else if(chars.indexOf('|'+charCode+'|')!=-1||keyCode==13) { // syntax highlighting
top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
}
else if(keyCode==9 || evt.tabKey) { // snippets activation (tab)
CodePress.snippets(evt);
evt.preventDefault();
}
else if(keyCode==46||keyCode==8) { // save to history when delete or backspace pressed
CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;
}
else if((charCode==122||charCode==121||charCode==90) && evt.ctrlKey) { // undo and redo
(charCode==121||evt.shiftKey) ? CodePress.actions.redo() : CodePress.actions.undo();
evt.preventDefault();
}
else if(charCode==118 && evt.ctrlKey) { // handle paste
top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
}
else if(charCode==99 && evt.ctrlKey) { // handle cut
//alert(window.getSelection().getRangeAt(0).toString().replace(/\t/g,'FFF'));
}
},
Or maybe, try this:
It makes indent and outdent. This let Firefox to autoindent lines too.
keyHandler : function(evt) {
keyCode = evt.keyCode;
charCode = evt.charCode;
fromChar = String.fromCharCode(charCode);
if(! (evt.ctrlKey || evt.metaKey) && keyCode == 9) {
if(evt.preventDefault) evt.preventDefault(); // Gecko and Others
evt.returnValue = false; // IE
window.document.execCommand((evt.shiftKey ? "outdent" : "indent"),false,false);
}
if((evt.ctrlKey || evt.metaKey) && evt.shiftKey && charCode!=90) { // shortcuts = ctrl||appleKey+shift+key!=z(undo)
CodePress.shortcuts(charCode?charCode:keyCode);
}
else if( (completeEndingChars.indexOf('|'+fromChar+'|')!= -1 || completeChars.indexOf('|'+fromChar+'|')!=-1) && CodePress.autocomplete) { // auto complete
if(!CodePress.completeEnding(fromChar))
CodePress.complete(fromChar);
}
else if(chars.indexOf('|'+charCode+'|')!=-1||keyCode==13) { // syntax highlighting
top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
}
else if(keyCode==9 || evt.tabKey) { // snippets activation (tab)
CodePress.snippets(evt);
evt.preventDefault();
}
else if(keyCode==46||keyCode==8 ||keyCode == 9) { // save to history when delete or backspace pressed
CodePress.actions.history[CodePress.actions.next()] = editor.innerHTML;
}
else if((charCode==122||charCode==121||charCode==90) && evt.ctrlKey) { // undo and redo
(charCode==121||evt.shiftKey) ? CodePress.actions.redo() : CodePress.actions.undo();
evt.preventDefault();
}
else if(charCode==118 && evt.ctrlKey) { // handle paste
top.setTimeout(function(){CodePress.syntaxHighlight('generic');},100);
}
else if(charCode==99 && evt.ctrlKey) { // handle cut
//alert(window.getSelection().getRangeAt(0).toString().replace(/\t/g,'FFF'));
}
},
Finnaly... i did this:
keyHandler : function(evt) {
keyCode = evt.keyCode;
charCode = evt.charCode;
fromChar = String.fromCharCode(charCode);
if(! (evt.ctrlKey || evt.metaKey) && keyCode == 9) {
if(evt.preventDefault) evt.preventDefault(); // Gecko and Others
evt.returnValue = false; // IE
var content = window.getSelection().getRangeAt(0);
var div = document.createElement('div');
div.appendChild(content.cloneContents());
if(!evt.shiftKey){
content = div.innerHTML.replace(/<br>/gi,'\n\t');
content = content.replace(/\u2009/g,'');
content = content.replace(/<.*?>/g,'');
content = content.replace(/</g,'<');
content = content.replace(/>/g,'>');
content = content.replace(/&/gi,'&');
CodePress.insertCode('\t'+content);
}
else {
content = div.innerHTML.replace(/<br>/gi,'\n');
content = content.replace(/^\t/g,'');
content = content.replace(/\n\t/g,'\n');
content = content.replace(/\u2009/g,'');
content = content.replace(/<.*?>/g,'');
content = content.replace(/</g,'<');
content = content.replace(/>/g,'>');
content = content.replace(/&/gi,'&');
CodePress.insertCode(content);
}
CodePress.syntaxHighlight('generic');
}
....
If you are talking about making tabs work when you hit tab (i recently fixed this)
It's very easy.
open engines/gecko.js
goto keyhandler : function
goto else if(keyCode==9 || evt.tabKey) { // snippets activation (tab)
replace this if block with:
if (!CodePress.snippets(evt)) {
var range = window.getSelection().getRangeAt(0);
var newTextNode = document.createTextNode('\t');
range.insertNode(newTextNode);
range.setStartAfter(newTextNode)
}
evt.preventDefault(); // prevent the tab key from being added
goto snippets : function(evt) {
first line of the function add
var workWasDone = false;
then add the second line that follows after the if statement, which is the first line here:
if(snippets[i].input == trigger) {
workWasDone = true;
finally the last line of this function is:
return workWasDone;
Now when you hit tab, it will make a tab and everyone claps their hands.
Hi,
your code is useful but need to be updated, because
when you highlighnt multiple line TAB doesn't work and also shift + tab is not supported, is it possible to update the code for gecko ?
thnak you for your great help !
well its actual the same as brad laney (2up By: brad laney (digitalpacman) - 2008-10-31 20:49)
but I think is it a little easier:
simply replace the snippets function with:
var snippets = Language.snippets;
var trigger = this.getLastWord();
var tab = true;
for (var i=0; i<snippets.length; i++) {
if(snippets[i].input == trigger) {
tab = false;
var content = snippets[i].output.replace(/</g,'<');
content = content.replace(/>/g,'>');
if(content.indexOf('$0')<0) content += cc;
else content = content.replace(/\$0/,cc);
content = content.replace(/\n/g,'<br>');
var pattern = new RegExp(trigger+cc,'gi');
evt.preventDefault(); // prevent the tab key from being added
this.syntaxHighlight('snippets',pattern,content);
}
}
if(tab){
var range = window.getSelection().getRangeAt(0);
var newTextNode = document.createTextNode('\t');
range.insertNode(newTextNode);
range.setStartAfter(newTextNode)
evt.preventDefault(); // prevent the normal tab action
}