0

I want to create a Chrome extension with a browser action onClicked which provides the same functionality as the following bookmark:

javascript:(function(){if(!window.page2rss_bookmark_urlr)window.page2rss_bookmark_urlr=function(ur){if(ur.error)alert(ur.error);if(ur.page&&ur.page.page)location.href=ur.page.page};var r=document.getElementById('urlFormRequest');if(r)r.parentNode.removeChild(r);r=document.createElement('script');r.id='urlFormRequest';r.type='text/javascript';r.src='http://page2rss.com/api/page?url='+encodeURIComponent(location.href)+'&callback=page2rss_bookmark_urlr';document.body.appendChild(r);})();

However, I struggle to correctly translate the javascript code of the bookmark into the logic of a Chrome extension. I thought the best to is to to put the exact code of the bookmark into a separate script create_feed_url.js and execute it in background.js. My background.js:

chrome.browserAction.onClicked.addListener(function(tab) {
    // Run the bookmark code
    chrome.tabs.executeScript(null, {file: "create_feed_url.js"});

    // Open a new tab for a valid url resulting from create_feed_url.js
    var feed_url = "http://page2rss.com/page?url=" + tab.url;
    chrome.tabs.create({"url": feed_url});

Yet the code in create_feed_url.js somewhat runs not sucessfully. There is no feed URL generated, resulting in a non existing value for feed_url.

My questions:

  1. Could you please help me to find out why I cannot just put the code of the bookmark into create_feed_url.js and run it?

  2. Is this approach of executeScript recommendable in my case or is there a better way translating a bookmark into an extension?

orschiro
  • 19,847
  • 19
  • 64
  • 95
  • Did you know that content scripts do *not* run in the context of the page? See https://developer.chrome.com/extensions/content_scripts.html#execution-environment. – Rob W Aug 08 '13 at 20:17
  • Thanks Rob. I was not aware of that. Then probably my solution of having all of the code logic in `background.js` is not too bad. – orschiro Aug 09 '13 at 05:52
  • Your current solution is sub-optimal, because background pages consume memory even when unused. In general all bookmarklets are easily convertable to content scripts. See [Building a Chrome Extension - Inject code in a page using a Content script](http://stackoverflow.com/questions/9515704/building-a-chrome-extension-inject-code-in-a-page-using-a-content-script/9517879#9517879) – Rob W Aug 09 '13 at 08:36

2 Answers2

0

I solved it with a workaround calling the URL that generates the new feed in a new tab before closing it and finally jumping to the tab with the final RSS feed URL. This solution does not require create_feed_url.js but relies completely on background.js:

chrome.browserAction.onClicked.addListener(function(tab) {
    // Original bookmark JS code
    //(function(){if(!window.page2rss_bookmark_urlr)window.page2rss_bookmark_urlr=function(ur){if(ur.error)alert(ur.error);if(ur.page&&ur.page.page)location.href=ur.page.page};var r=document.getElementById('urlFormRequest');if(r)r.parentNode.removeChild(r);r=document.createElement('script');r.id='urlFormRequest';r.type='text/javascript';r.src='http://page2rss.com/api/page?url='+encodeURIComponent(location.href)+'&callback=page2rss_bookmark_urlr';document.body.appendChild(r);})();

    var create_feed_url = "http://page2rss.com/api/page?url=" + encodeURIComponent(tab.url); //+ "&callback=page2rss_bookmark_urlr" 
    var feed_url = "http://page2rss.com/page?url=" + tab.url;

    chrome.tabs.create({"url": create_feed_url, active: false}, function(tab) {
        chrome.browserAction.setBadgeText({text: 'wait'});
        setTimeout(function() { 
            chrome.tabs.remove(tab.id, function(tab) {
                chrome.browserAction.setBadgeText({text: ''});
            }); 

        }, 5000);
    });

    setTimeout(function() { 
        chrome.tabs.create({"url": feed_url, active: true}, function(tab) {
            chrome.tabs.onUpdated.addListener(function( tabId , info ) {
                if ( info.status == "complete" ) {
                    chrome.browserAction.setBadgeText({text: 'done', tabId: tabId});
                }
            });
        }); }
    , 1000);    
});
orschiro
  • 19,847
  • 19
  • 64
  • 95
0

Based on Rob's comment above of using a content script approach I tried to implement it. However, clicking on the browser icon does not trigger the content script create_feed_url.js through content_script.js. I tried to debug the code but neither the Developer Tools nor the inspect element tool show any error.

background.js:

chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.tabs.executeScript(null, {file: "content_script.js"});
});

content_script.js:

var s = document.createElement('script');
s.src = chrome.extension.getURL("create_feed_url.js");
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

create_feed_url.js:

(function(){if(!window.page2rss_bookmark_urlr)window.page2rss_bookmark_urlr=function(ur){if(ur.error)alert(ur.error);if(ur.page&&ur.page.page)location.href=ur.page.page};var r=document.getElementById('urlFormRequest');if(r)r.parentNode.removeChild(r);r=document.createElement('script');r.id='urlFormRequest';r.type='text/javascript';r.src='//page2rss.com/api/page?url='+encodeURIComponent(location.href)+'&callback=page2rss_bookmark_urlr';document.body.appendChild(r);})();

manifest.json:

{
  "permissions": [
    "tabs", "http://*/*", "https://*/*"
  ],
  "background" : {
    "scripts": ["background.js"],
    "persistent": false
  },
  "web_accessible_resources": ["create_feed_url.js"],
  "browser_action" :
  {
    "default_icon" : "rss-19.png",
    "default_title" : "Create RSS feed for this page"
  },
  "manifest_version": 2
}
orschiro
  • 19,847
  • 19
  • 64
  • 95
  • Change `document.createElement('create_feed_url');` to `document.createElement('script');`, and remove the `"content_scripts"` entry from your manifest file (otherwise the bookmarklet is always activated, even when the button is not clicked. – Rob W Aug 11 '13 at 10:32
  • Thanks Rob. This works well for http sites but not for https sides. They prevent the bookmarklet code from being executed. Example: `[blocked] The page at https://bbs.archlinux.de/viewtopic.php?id=24576 ran insecure content from http://page2rss.com/api/page?url=https%3A%2F%2Fbbs.archlinux.de%2Fviewtopic.php%3Fid%3D24576&callback=page2rss_bookmark_urlr.` – orschiro Aug 11 '13 at 11:51
  • I managed to resolve that by changing the URL of the bookmarklet from `https://` to just `//`. – orschiro Aug 11 '13 at 13:45