Use Javascript to get selected text in Mobile Safari
Asked Answered
R

3

13

So I'm working on a bookmarklet where it would be ideal for me to grab the content selected by the user using the "loop". Both window.getSelection and document.getSelection are functions that I can call, however, they always return an empty string.

I believe the problem is that when you tap on the bookmark icon in Mobile Safari, the selection is released. For example, if you select some text, tap the "+", bookmark or other tab, the selection is unselected even if you cancel.

Any thoughts on if it is possible to get at this data at all? Or is this pretty much impossible?

Resistant answered 29/6, 2010 at 3:33 Comment(2)
Are you sure that window.getSelection() returns empty string, and not DOMSelection? I do not have access to Mobile Safari, but in webkit this function returns DOMSelection even if there is nothing selected on the page.Sulphurbottom
see also #1936632Henson
M
1

I think you would have to have the bookmarklet insert some content into the page that would operate on the selection. You might add a button to the top or bottom of the page, and when clicked it would act on the current selection. It could then clean up the added content or leave it there.

Monition answered 29/6, 2010 at 4:18 Comment(2)
This is one of the solutions I thought about after posting this question. My concern with this solution is that I can not think of a good way to position the added "button" so that it will be easily selectable. Mobile Safari doesn't support the "position: fixed" CSS property. Also it adds more steps: 1) Activate bookmark 2) Select text 3) Locate and activate added content of bookmark vs. 1) Select text 2) Activate bookmark Thank you for your suggestion.Resistant
You might want to take a loom at the bookmarklet from amplify.com - they do exactly what is proposed here and the button follows the scroll actions.Yonina
I
1

The contents of the "loop" are not exposed to javascript in the mobile browser, period. So this is impossible (I am assuming that you are working in the full browser, not in the browser window created when you launch a "saved to home page" icon)

Ingle answered 3/8, 2010 at 15:44 Comment(1)
Your post is a comment and not an answer. Use the comments when you are asking a question and not posting a solution. Otherwise its not helpful.Appleby
I
-1

I have a fairly simple idea.

var latestSelection = "";
while (true)
{
    var tmp;
    if ((tmp = document.getSelection()) != "")
        latestSelection = tmp;
}

This way you would always have the latest selection in the latestSelection variable. Of course it would be expensive to have a loop run like this all the time. So you will probably want to play around with listeners or at least timers.

Hope this helps.

Update: Don't use the above code as is.

Here is how you would write the same thing in objective-c:

- (void) updateSelection
{
    NSString * tmp = [webView stringByEvaluatingJavaScriptFromString:@"document.getSelection()"];
    if (![tmp isEqualToString:@""])
        latestSelection = tmp;
}

You could have a timer execute updateSelection every x time units. If you find some good notification that let's you know that the user has interacted with the webview, you could use that to update latestSelection.

Insolvable answered 13/8, 2010 at 12:32 Comment(5)
I think this would lock the UI thread, though changing to use setInterval() or setTimeout() wouldn't, ;)Gillie
Can anyone explain why this answer was down voted? I do explain that you should use timers or listeners, so that you don't lock the UI-thread. Also if you don't want to write it in Javascript, you could easily write the same thing in Objective-C. The code was just explaining an idea. I was not suggesting that you would actually use that code.Insolvable
I don't see why it was down voted. Looks useful to me. I just up-voted it. Any idea what sort of listeners to use? Timers would run the risk of missing changes to the selection that occur between the last timer tick and when you execute the bookmarklet.Heard
The problem is, it is assumed that the code is to be used. And doing so would crash the browser. If you want to present a concept, then just write an explanation of how it would work, and if you need to use code to explain it, then add a disclaimer saying that the code is untested or not for actual use. Also, this question was asking for a solution for a bookmarklet, so JavaScript is required (cannot be written in objective c), and having a 'latest selection' is not possible as the bookmarklet code is not run until it is clicked. So... that's why this answer was downvoted.Mcmullan
And it wouldn't work even if it did not lock the browser, because for the bookmarklet to take the selection, that code would need to run before the bookmarklet was executed.Yonina

© 2022 - 2024 — McMap. All rights reserved.