capture selected text when extension button is clicked

6,821 views
Skip to first unread message

phil swenson

unread,
Feb 9, 2012, 7:22:57 PM2/9/12
to Chromium-extensions
I have an extension where I want to capture the selected text when the
extension button is clicked.

My code works some of the time, but often it doesn't. I think I don't
understand the lifecycle of an extension and what happens when you
click the extension button.

Here is my code:

$(document).ready(function() {
console.log("doc ready");
selectedTextPaste();
});

function selectedTextPaste() {
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: "getSelection"},
function(response) {
// if no selected text, paste in the url
var text;
if (response.data == "") {
text = tab.url;
} else {
text = response.data;
}
$('#selected_text').text(text);
});
});
};


any thoughts on where I'm going wrong?

thanks!

Mohamed Mansour

unread,
Feb 9, 2012, 7:31:26 PM2/9/12
to phil swenson, Chromium-extensions
Hi Phil,

Couple of years ago I answered a similar question on StackOverflow:

From the code you pasted, your not showing the content script which implements the getSelected Messaging API. 

Kind regards,
Mohamed Mansour
http://mohamedmansour.com/+



--
You received this message because you are subscribed to the Google Groups "Chromium-extensions" group.
To post to this group, send email to chromium-...@chromium.org.
To unsubscribe from this group, send email to chromium-extens...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-extensions/?hl=en.


arthur

unread,
Feb 10, 2012, 4:21:58 PM2/10/12
to Mohamed Mansour, phil swenson, Chromium-extensions
FYI. With my limited experience, Chrome Extension content script can't
get selection from iframe (e.g. Gmail/Gdoc)

http://code.google.com/p/chromium/issues/detail?id=65636

http://groups.google.com/a/chromium.org/group/chromium-extensions/browse_thread/thread/a955986561a861c0?hl=en#

I didn't get much input and didn't test newer versions of Chrome after that.

Arthur

On 09/02/2012 7:31 PM, Mohamed Mansour wrote:
> Hi Phil,
>
> Couple of years ago I answered a similar question on StackOverflow:
> http://stackoverflow.com/questions/2626859/chrome-extension-how-to-capture-selected-text-and-send-to-a-web-service
>
>
> From the code you pasted, your not showing the content script which
> implements the getSelected Messaging API.
>
> Kind regards,
> Mohamed Mansour
> http://mohamedmansour.com/+
>
>
> On Thu, Feb 9, 2012 at 7:22 PM, phil swenson <phil.s...@gmail.com
> <mailto:phil.s...@gmail.com>> wrote:
>
> I have an extension where I want to capture the selected text when the
> extension button is clicked.
>
> My code works some of the time, but often it doesn't. I think I don't
> understand the lifecycle of an extension and what happens when you
> click the extension button.
>
> Here is my code:
>
> $(document).ready(function() {
> console.log("doc ready");
> selectedTextPaste();
> });
>
> function selectedTextPaste() {
> chrome.tabs.getSelected(null,
> function(tab) {
>

> chrome.tabs.sendRequest(tab.id <http://tab.id>, {method:


> "getSelection"},
> function(response) {
> // if no selected
> text, paste in the url
> var text;
> if (response.data ==
> "") {
> text = tab.url;
> } else {
> text =
> response.data;
> }
>
> $('#selected_text').text(text);
> });
> });
> };
>
>
> any thoughts on where I'm going wrong?
>
> thanks!
>
> --
> You received this message because you are subscribed to the Google
> Groups "Chromium-extensions" group.
> To post to this group, send email to
> chromium-...@chromium.org

> <mailto:chromium-...@chromium.org>.


> To unsubscribe from this group, send email to
> chromium-extens...@chromium.org

> <mailto:chromium-extensions%2Bunsu...@chromium.org>.

phil swenson

unread,
Feb 10, 2012, 4:50:21 PM2/10/12
to Mohamed Mansour, Chromium-extensions
Thanks Mohamed. I am resurrecting my old extension from 2 years ago,
that's why the redundant question.

I do have the suggested code in my content_script.js. Here is is:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == "getSelection")
sendResponse({data: window.getSelection().toString()});
else
sendResponse({});
});

First follow up question:

if I have code like this in my background.html:

chrome.browserAction.onClicked.addListener(function(tab) {
console.log("HEY, browser icon pressed!")
});
$(document).ready(function() {
console.log("ready!");
}

What should I expect when I click the extension button (I guess it's
called the "Action button")?

What I see is "ready!" and never the "HEY, browser icon pressed!"

This is not what I expect based on reading the info you pointed me to.

Mohamed Mansour

unread,
Feb 10, 2012, 6:57:34 PM2/10/12
to phil swenson, Chromium-extensions
The reason why you don't see "HEY" is probably because you have defined the popup.html in your manifest. You can't have "both" defined, you can either use that event listener or a popup.html defined.

The first step is to get your "HEY" to work, in your manifest, make sure you just have:

 "browser_action": {
   "default_title": "Selected Text",
   "default_icon": "icon.png"
 },

Then add that event listener that you stated in your background page, then reload extension and test it out. To verify it is working, you have to visit your extension page (chrome://extensions) , and then locate that loaded extension and hit the "background.html" page.

Kind regards,
Mohamed Mansour

phil swenson

unread,
Feb 11, 2012, 6:23:48 PM2/11/12
to Mohamed Mansour, Chromium-extensions
I'm having quite a tough time with this.

First there is a misunderstanding… I shouldn't have told you "background.html"

What I meant was "popup.html"

I'll be more clear: I want an extension that when the action button
is clicked will capture selected text and populate a text area with
the text. If there is no selected text I want the current browser
URL. What I have works, but it fails often.

I found an extension (GrabText) that behaves very much like my
extension with regard to selecting the text (works for some pages,
fails often): https://chrome.google.com/webstore/detail/pmkkkpcojlkfgkgoiilkgfkeaiaocehb
The code in Grab Text looks very much like what you suggest. There
are many pages it fails on such as http://cnn.com .

I found an extension (View Selection Source) that works every time,
but doesn't do exactly what I want as it returns the HTML for the
selected text instead of just the text:
https://chrome.google.com/webstore/detail/fbhgckgfljgjkkfngcoeajbgndkeoaaj

The approachView Selection Source is very different from what you
suggest. The code is just:

popup.html:

chrome.tabs.executeScript(null, {file:"script.js"});

chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
document.getElementById("txtar").innerText=request.viewsource;

and in script.js it's

var selection = window.getSelection();
var range = selection.getRangeAt(0);
if (range) {
var div = document.createElement('div');
div.appendChild(range.cloneContents());
vs=div.innerHTML;
}

chrome.extension.sendRequest({viewsource: vs}, function(response) {
console.log(response.farewell);
});

I tried grabbing this code and adapting for my purposes to return text
not HTML. Unfortunately, the code in the content script (script.js)
is difficult to debug as console.log doesn't seem to do anything. So
haven't gotten it where I need it yet. It just returns HTML for me
instead of the plain text.

Any thoughts on this?

thanks
phil

Mohamed Mansour

unread,
Feb 11, 2012, 7:23:51 PM2/11/12
to phil swenson, Chromium-extensions
Hi Phil,

From the GitHub answer I wrote (I still had the source two years ago), I loaded it up in Chrome and it does what you want. The Gist is here:  https://gist.github.com/1805261 

Regarding your code, the reason why it is returning HTML is because you are extracting the innerHTML instead of innnerText.

Change your:

    vs=div.innerHTML;

to:

    vs=div.innerText; 


Kind regards,
Mohamed Mansour

Devin

unread,
Feb 11, 2012, 10:54:43 PM2/11/12
to Chromium-extensions
Yeah, Mohamed is on track, now on your chrome.browserAction.onClicked
listener, you'll want to send a message to the current/active tab.

If you want to get into iframes, this is totally possible and I've
done it before. The way I'm thinking that will work best for you is to
inject a small piece of JS as a content_script to all_frames. Then in
this JS file, have it check if it is inside an iframe or is being
injected in a regular tab. You may need to append a script to the dom
to actually detect this. I tried looking my old code but couldn't find
it. If you are in a frame, add some code that uses postMessage to the
top frame. You can even json encode/decode code to execute in either
frame. You can learn more about the postMessage api here:
https://developer.mozilla.org/en/DOM/window.postMessage

To detect what text is selected, you'll want to use the onselectstart
event.

document.body.onselectstart = function (e) {
  e.textContent; //the text that was selected ... supposedly. It's not
100% accurate.
  e.wholeText; //all of the text in this text node
}

There is also the onselect event, but when I was highlighting text in
a p element on a page, the event never triggered for me.

You will probably want to combine this with mousedown, mousemove, and
mouseup events.

There are probably other onselect__ events, but I didn't see them when
I did dir(document.body) in the console.



On Feb 11, 4:23 pm, Mohamed Mansour <m...@chromium.org> wrote:
> Hi Phil,
>
> From the GitHub answer I wrote (I still had the source two years ago), I
> loaded it up in Chrome and it does what you want. The Gist is here:https://gist.github.com/1805261
>
> Regarding your code, the reason why it is returning HTML is because you are
> extracting the innerHTML instead of innnerText.
>
> Change your:
>
>     vs=div.innerHTML;
>
> to:
>
>     vs=div.innerText;
>
> Kind regards,
> Mohamed Mansour
>
> On Sat, Feb 11, 2012 at 6:23 PM, phil swenson <phil.swen...@gmail.com>wrote:
>
>
>
>
>
>
>
> > I'm having quite a tough time with this.
>
> > First there is a misunderstanding… I shouldn't have told you
> > "background.html"
>
> > What I meant was "popup.html"
>
> > I'll be more clear:  I want an extension that when the action button
> > is clicked will capture selected text and populate a text area with
> > the text.  If there is no selected text I want the current browser
> > URL.  What I have works, but it fails often.
>
> > I found an extension (GrabText)  that behaves very much like my
> > extension with regard to selecting the text (works for some pages,
> > fails often):
> >https://chrome.google.com/webstore/detail/pmkkkpcojlkfgkgoiilkgfkeaia...
> >  The code in Grab Text looks very much like what you suggest.  There
> > are many pages it fails on such ashttp://cnn.com.
>
> > I found an extension (View Selection Source) that works every time,
> > but doesn't do exactly what I want as it returns the HTML for the
> > selected text instead of just the text:
> >https://chrome.google.com/webstore/detail/fbhgckgfljgjkkfngcoeajbgndk...
> > > On Fri, Feb 10, 2012 at 4:50 PM, phil swenson <phil.swen...@gmail.com>
> >http://stackoverflow.com/questions/2626859/chrome-extension-how-to-ca...
>
> > >> > From the code you pasted, your not showing the content script which
> > >> > implements the getSelected Messaging API.
>
> > >> > Kind regards,
> > >> > Mohamed Mansour
> > >> >http://mohamedmansour.com/+
>
> > >> > On Thu, Feb 9, 2012 at 7:22 PM, phil swenson <phil.swen...@gmail.com>
> > chromium-extensi...@chromium.org.
> > >> >> To unsubscribe from this group, send email to
> > >> >> chromium-extensions+unsubscr...@chromium.org.

phil swenson

unread,
Feb 12, 2012, 12:57:47 PM2/12/12
to Mohamed Mansour, Chromium-extensions
Mohamed,

your github extension does exactly what I described my code as doing.
I downloaded your extension and tried it out. When I got to some
sites (like http://news.ycombinator.com) it works great. Others, it
simply doesn't work (http://cnn.com). I select some random text on
CNN's page and hit your button - nothing happens.

On the other hand, the code I referenced from this extension (View
Selected Source)
https://chrome.google.com/webstore/detail/fbhgckgfljgjkkfngcoeajbgndkeoaaj
works on all sites that don't use iframes.

I am curious, can you duplicate the problem? I'm on a mac w/ chrome
v17.0.963.46

Do you see any advantages of your approach vs the one in the View
Selected Source Extension?

phil swenson

unread,
Feb 11, 2012, 7:30:26 PM2/11/12
to Mohamed Mansour, Chromium-extensions
haha, I figured this out almost simultaneous to your email. This does work!

Thanks!

Reply all
Reply to author
Forward
0 new messages