Question

Basically I made a bookmarklet, and I'd like it to run when a certain wildcarded URL is opened. For some reasons it won't simply run as javascript in a chrome extension, and I'm tired of trying.

What I think could work is to make an extension that has a content_script for the specified page(s) (which allows a wildcard via match), and somehow make it do the same thing that would be done if the user clicked the bookmarklet in the bookmarks bar.

However, I do not know how to make this.

One thing to note is that I need it to access the page's global scope, i.e., break out of the extension sandbox (which is possible, and has been confirmed to be possible by design in the Chromium bug tracker).

So the question again is: how, from an content_script, do I "load the bookmarklet" (in other words, how to convert a bookmarklet to a Google Chrome extension). I have it in plain javascript too, if that could be of use.

This is the bookmarklet, in case somebody wants to test with it. It's meant to be used at my.deviantart.com/messages/* (but you need an account and messages in your inbox, to see the effect hover on top of a link to a "deviation", and it will show a tooltip with a thumbnail of it).

(Edit: Here's an extension attempt, posted in an answer's comments)

Was it helpful?

Solution

You can make cross domain calls from a content script if you put a url in the permissions part of your manifest...
http://code.google.com/chrome/extensions/xhr.html

What it seemed to be choking on was the callback that you put in the request url and thats not needed so I took it out.
Here's a working version of your code....
Manifest

{
  "name": "dA Tooltip Thumbnail",
  "version": "1.0.0",
  "description": "What the name says.",
  "permissions": [
    "http://backend.deviantart.com/*"
  ],
  "icons": {
    "48" : "sample-48.png",
    "128" : "sample-128.png"
  },
  "content_scripts": [
    {
      "matches": ["http://my.deviantart.com/messages/*"],
      "js" : ["jquery-1.7.1.min.js","contentscript.js"]
    }
  ]
}

ContentScript

$(".mcb-title a:first-child").each(function() {
    var b=$(this).attr("href");
    null!=b.match(/https?:\/\/fav\.me\/.*|https?:\/\/.*\.deviantart\.com\/art.*/)&&"true"!=$(this).attr("da-message-preview-attached")&&$.getJSON("http://backend.deviantart.com/oembed?url="+encodeURIComponent(b),$.proxy(function(b) {
        $(this).addClass("da-message-preview").attr("rel",b.thumbnail_url).attr("da-message-preview-attached","true");
        $(this).hover(function(a) {
            window.daMessagePreviewTitle=this.title;
            this.title="";
            $("body").append('<p id="da-message-preview"><img src="'+this.rel+'"/></p>');
            $("#da-message-preview").css( {top:a.pageY-10+"px",left:a.pageX+30+"px",position:"absolute",border:"1px solid #666",background:"#EEE",padding:"5px",display:"none","-webkit-border-radius":"6px","-moz-border-radius":"6px","border-radius":"6px","-webkit-box-shadow":"0px 2px 8px #000","-moz-box-shadow":"0px 2px 8px #000","box-shadow":"0px 2px 8px #000","z-index":"123456"}).fadeIn("fast")
        },function() {
            $("#da-message-preview").remove()
        });
        $(this).mousemove(function(a) {
            $("#da-message-preview").css("top",a.pageY-10+"px").css("left",a.pageX+30+"px")
        })
    },this))

});  

The only error I noticed after the changes was it tries to get a url that gets a 404...
http://backend.deviantart.com/oembed?url=http%3A%2F%2Fnews.deviantart.com%2Farticle%2F143885%2F
...small error, Ill leave it up to you to get rid of that one ;).
OH, and I took out the timer stuff, is that really needed? Wont you be going to a different url when you click on a gallery?...because if you do then the content script will get reinjected (you may need to add more matches for that tho, didnt really look).

OTHER TIPS

I think what you're looking for is Message Passing:

http://code.google.com/chrome/extensions/messaging.html

With it you can pass events from your content_script to your background script. Within the background page you'll have all the Chrome Extension capabilities at your disposal.

There is almost no work required in converting from a bookmarklet to a Chrome extension (provided the bookmarklet only accessess DOM elements - a criterion with which your extension appears to comply). Simply paste the JavaScript into your extension's content_script.js.

Note, though, that your bookmarklet uses jQuery. You'll have to embed that in your content script, as well. See here for how to do that.

One other note. You don't need to exploit some sort of bug in order to "break out" of the extension; by design, Chrome extensions are allowed access to DOM elements of the page, but nothing else inside of the JavaScript namespace. In other words, if the page has loaded some super secret variables into var bob = 'My secret!!!1', your extension could not access bob and read its value. On the other hand, if bob's value were loaded into a span tag, your extension could find that tag and read it, since it is part of the DOM.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top