1

I try to use jQuery and jQuery-UI in my Chrome extension. I try to create in the content script dialog window each time new tab is created but I keep getting:

Property '$' of object [object Window] is not a function 

I guess I'm doing something wrong loading the scripts. Here's what I have:

{
"name":"Sample",
"description":"This is a sample",
"manifest_version":2,
"version":"2",
"background":{
    "scripts":["background.js"]
},
"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery-1.8.3.min.js","jquery-ui.js","client.js","myscript.js"]
      "run_at":"document_end",
      "all_frames": true
    }
  ],
"web_accessible_resources": [
    "client.js","jquery-1.8.3.min.js","jquery-ui.js"
  ],
"permissions": [ 
        "unlimitedStorage",
        "http://*/",
        "<all_urls>",
        "tabs"
   ]
}


myscript.js ( the content script ):

var ss = document.createElement('script');
ss.type = "text/javascript";
ss.src = chrome.extension.getURL('jquery-1.8.3.min.js');
ss.onload = function() {
    ss.parentNode.removeChild(ss);
     console.log("jquery-1.8.3.min.js loaded");

};

var ss_ui = document.createElement('script');
ss_ui.type = "text/javascript";
ss_ui.src = chrome.extension.getURL('jquery-ui.js');
ss_ui.onload = function() {
    ss_ui.parentNode.removeChild(ss_ui);
    console.log("jquery-ui.js loaded");
};


var s = document.createElement('script');
s.type = "text/javascript";
s.src = chrome.extension.getURL('client.js');
s.onload = function() {
    s.parentNode.removeChild(s);
    console.log("client.js loaded");
};

        try{

            (document.head||document.documentElement).appendChild(ss);
            (document.head||document.documentElement).appendChild(ss_ui);
            (document.head||document.documentElement).appendChild(s);

        }catch(e){
          console.log("exception in appendChild");
        }  



client.js ( where I create the dialog )

       try{
        console.log("Starting to create tabel");

        var layerNode= document.createElement('div');
            layerNode.setAttribute('id','dialog');
            layerNode.setAttribute('title','Basic dialog');
        var pNode= document.createElement('p');
            pNode.innerHTML = "This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.";

        layerNode.appendChild(pNode);
        document.body.appendChild(layerNode);


        jq162 = jQuery.noConflict(true);
(function($){
    $(document).ready(function() {
       $("#dialog" ).dialog();
    });
})(jq162);

        }
        catch(e){
          console.log("script in page exception in appendChild"+e);
          //alert(e);
        }  

when I see in the console to see the order of prints im getting :

Starting to create tabel client.js:2
script in page exception in appendChildTypeError: Cannot call method 'dialog' of null client.js:26
client.js loaded chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/myscript.js:24
jquery-1.8.3.min.js loaded chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/myscript.js:6
jquery-ui.js loaded   

What am I doing wrong here?

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
user63898
  • 29,839
  • 85
  • 272
  • 514
  • When will you include `script.js`? –  Dec 02 '12 at 13:56
  • sorry its client.js ( update the question ) – user63898 Dec 02 '12 at 13:59
  • Have you checked to see if jquery's `$` is defined properly in `myscript.js`? –  Dec 02 '12 at 14:04
  • use `console.log` inside `ss.onload` callback. –  Dec 03 '12 at 06:01
  • you can also move all your code after line `var ss_ui =... ` inside `ss.onload`. maybe jquery.js is not loaded completely when you are including `client.js`. –  Dec 03 '12 at 06:03
  • or try to include `client.js` directly in `manifest.json`, instead of `myscript.js`. something like this `"js": ["jquery.min.js","jquery-ui.js","client.js"]` –  Dec 03 '12 at 06:07
  • ok i did all of what you suggested and still noting .. its not working . very strange, also update the question – user63898 Dec 03 '12 at 07:39

2 Answers2

5

Usual disclaimer, I don't really do jQuery... but I saw an obvious problem with your code and so gave it a shot...

Get rid of client.js, its no longer needed after you added the files it injects to the content script part of the manifest. After you added them to the manifest Chrome will now inject them for you. Once you do this it starts to half work.

After that I noticed that the dialog came up but had no graphics / styling so you need to add the css file to the content script part of the manifest to get injected. Now there's some style, but the console was saying it couldn't get at the graphic files needed for the style.

I'm not sure what the best way is to reference a graphic file that's contained in the extensions directory from a css file so I just turned all the graphics into dataurl's and put them in the css file. You can use a tool like this one...

http://dataurl.net/#dataurlmaker

...to get that done.

Now we have a nice looking dialog.

manifest.json

{
"name":"JQuery UI Dialog",
"description":"https://stackoverflow.com/questions/13669762/chrome-extention-using-jquery-in-content-script-resolve-error-when-creating-dial",
"manifest_version":2,
"version":"2",
"content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["jquery-1.8.3.min.js","jquery-ui.js","client.js"],
      "run_at":"document_end",
      "all_frames": true,
      "css":["jquery-ui-base64.css"]
    }
  ],
"web_accessible_resources": [
    "client.js","jquery-1.8.3.min.js","jquery-ui.js"
  ],
"permissions": [ 
        "unlimitedStorage",
        "http://*/",
        "<all_urls>",
        "tabs"
   ]
}

jquery-ui-base64.css
https://gist.github.com/4193693
Thought it might be a little to big to put here.

client.js

try {
  console.log("Starting to create tabel");

  var layerNode = document.createElement('div');
  layerNode.setAttribute('id', 'dialog');
  layerNode.setAttribute('title', 'Basic dialog');
  var pNode = document.createElement('p');
  pNode.innerHTML = "This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.";

  layerNode.appendChild(pNode);
  document.body.appendChild(layerNode);


  jq162 = jQuery.noConflict(true);
  (function($) {
    $(document).ready(function() {
      $("#dialog").dialog();
    });
  })(jq162);



} catch(e) {
  console.log("script in page exception in appendChild" + e);
  //alert(e);
}

EDIT
Using chromes i18n support we can change the urls for the images in the css so they point to the files in our extension.
https://stackoverflow.com/a/8864212/189093
So this...
url(images/ui-bg_flat_0_aaaaaa_40x100.png)
...becomes...
url(chrome-extension://__MSG_@@extension_id__/images/ui-bg_flat_0_aaaaaa_40x100.png)
and the path isnt relative anymore and the __MSG_@@extension_id__ gets replaced with the id of your extension.
Also, all the images used this way need to be declared in the web_accessible_resources part of your mainfest.
So, that part in your manifest ends up looking like this (notice I took out the three you had there, they dont need to be included anymore as their injected by the extension now)...

"web_accessible_resources": [
    "images/ui-bg_flat_75_ffffff_40x100.png","images/ui-icons_222222_256x240.png","images/ui-bg_highlight-soft_75_cccccc_1x100.png"
  ]

..Ive only included the files I needed to get my test working, you may need to add more. Check the console on the page the script is running and it will tell you what files you need to add.
Here's a link to the same css file used in my test with the urls updated to work this way...
https://gist.github.com/4195616

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
PAEz
  • 8,366
  • 2
  • 34
  • 27
  • do you know why even if i add the images dir with the css png's it still dont show me them ? do i need to enable them in the json ? im getting this kind of warnings: GET http://archan937.github.com/templayed.js/images/ui-icons_454545_256x240.png 404 (Not Found) chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/jquery-1.8.3.min.js:2 v.event.fix chrome-extension://mmoccjinakdjcmhjdjghhjnihbfkkgkp/jquery-1.8.3.min.js:2 v.event.dispatch chrome-e even if the ui-icons_454545_256x240.png in the ext dir in images dir – user63898 Dec 03 '12 at 14:03
  • Yep. Notice the url in the get warning? The relative paths in the css get resolved against the url of the page their inserted into. Their was a way to deal with this in css, but I couldnt rememeber what it was at the time. But Ive looked it up and Ill update the answer showing you how to do that. – PAEz Dec 03 '12 at 14:58
  • 1
    @user63898 OK, updated. Hope that all works out for you. Sorry about the brief explanation but Im tired as hell. – PAEz Dec 03 '12 at 15:14
  • Hi can you please take alook at this question , i getting errors but every thing is working fine : http://stackoverflow.com/questions/13718669/chrom-ext-and-jquery-resources-must-be-listed-in-the-web-accessible-resources-ma – user63898 Dec 05 '12 at 08:01
  • 1
    @user63898 Yep. Check the comments to Sudarshan's answer. – PAEz Dec 05 '12 at 11:54
0

When you call jQuery.noConflict then $ variable will not be defined.

But in script.js you are calling $(document) right after noConflict. I think you forgot a line (function($ after calling noConflict.

You have to change your code to something like this:

jq162 = jQuery.noConflict(true);
(function($){
    $(document).ready(function() {
       $("#dialog" ).dialog();
    });
})(jq162);