views:

45

answers:

2

I have an application that passes any selected body text to a text-2-speech server (via ajax) when a "Say It" button in the parent window is clicked; the selected text is in an iframe.

The selection works on Firefox 3.6 and IE 8, but not Safari 5 (have not tried any others; thats our supported browser list). In Safari, whenever the button to perform the function is clicked, any selected text is lost.

I've tried adding this to the mouseup for the presentation iframe, found as a solution for losing selected text within a control,but it doesn't work for selected text in the body of the document:

$("#the_presentation").mouseup(function(e){

  e.preventDefault();

});

The function that catches the selected text is this:

function getSelectedText(){
//Grab selected text
var _txt = '';
var _selection = null;

if(window.getSelection){
  _txt = window.getSelection().toString();
}
else if(document.getSelection){ //deprecated in ff
  _txt = document.getSelection()+'';
}
else if(document.selection){
  _selection = document.selection.createRange();
  if(_selection != null && _selection.text )
  {
    _txt = _selection.text;
  }
}

  return _txt;
}

Thanks for any insight you can provide!

*edit: I forgot to mention only happens on Mac safari - windows safari does not have the problem.

+1  A: 

Why not call getSelectedText() upon any change in selection of text and store it until the button is clicked.

In jQuery, this would look something like the following:

$(function(){
    var currentSelectedText = '';

    $(document.body).bind('keyup mouseup mousedown', function(){
        currentSelectedText = getSelectedText(); //your function from above
    });

    $('#the_form').submit(function(){
        makeAjaxCallForSpeech(currentSelectedText);
    });
});

(Note: From your question, I wasn't sure what was going on with the iFrames. So this solution doesn't involve the iFrame setup you mentioned. You'll have to adopt it for your specific needs.)

Adam
Great idea! I don't like doing it, feels a little like a hack, but it works and doesn't break any other behavior... Thanks!
Tim Everson
Glad I could help. :)
Adam
It feels like a hack because it *is* a hack :)
Tim Down
A: 

If you're using an <input> element of type button, try making it unselectable to prevent it destroying the selection when clicked. You can do this using CSS in most browsers and using the unselectable attribute in IE. I don't know if the following will work because I don't have Safari on a Mac to hand.

<style type="text/css">
*.unselectable {
   -moz-user-select: none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}
</style>

<input type="button" class="unselectable" unselectable="on" 
    onclick="alert(getSelectedText())">
Tim Down
Thanks, this is a cleaner solution, but it didn't work - really hoped it would because the mac safari selection is lost after the button click, and a remaining annoyance to the user.
Tim Everson
OK. I wasn't 100% confident. I'm sure I have managed this before though, so I'll have a little play.
Tim Down