inserting local css file with firefox extension - javascript

I am building a firefox extension and need to insert some elements and css into the doc.
I tried following How can a Firefox extension inject a local css file into a webpage? and Inserting CSS with a Firefox Extension, but had no luck.
I know am missing some silly point but I cant really make out what it is,and would really appreciate if some one can point it out to me.
Heres my chrome.manifest:
content helloworld content/
overlay chrome://browser/content/browser.xul chrome://helloworld/content/overlay.xul
locale helloworld en-US locale/en-US/
skin helloworld classic/1.0 skin/
And my overlay.js:
var fileref = gBrowser.contentDocument.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", "resource://helloworld/skin/global.css");
gBrowser.contentDocument.getElementsByTagName("head")[0].appendChild(fileref);
I even tried this inside my overlay.js
var sss = Components.classes["#mozilla.org/content/style-sheet-service;1"]
.getService(Components.interfaces.nsIStyleSheetService);
var ios = Components.classes["#mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = ios.newURI(url, null, null);
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
No luck again.
What am I missing? I seriously can't figure out.
Tried using the console,shows nothing
When I copy and paste my href "chrome://helloworld/skin/global.css", I can see my css file in the browser.

You should set the javascript.options.showInConsole, restart, then check the Error Console.
The nsIStyleSheetService snippet should be the simplest to get working.
What's the url in it? The other snippets/comments you posted contradict each other -- the chrome.manifest and your comment "When I copy and paste my href ..., I can see my css file in the browser" imply you're using chrome://helloworld/skin/global.css, but your other snippet shows you use a resource:// URL, which is a different beast.
How do you determine the snippet is not working? Could you have your stylesheet wrong? Did you try something simple like * {color:red !important;} as your CSS?
P.S. If you use nsIStyleSheetService, please note the comment on MDC about taking care not to register the same sheet multiple times.
Also note that when using nsIStyleSheetService you should be careful not to make your styles apply to the pages you didn't intend to modify. #-moz-document can be very useful for that.

I'm not sure if this will solve your problem, but you should listen for load events in all tabs changing your overlay.js to something like:
window.addEventListener('load', function () {
gBrowser.addEventListener('DOMContentLoaded', function (event) {
if (event.originalTarget.nodeName == '#document' &&
event.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)
{
var document = event.originalTarget;
// Your css injection here
}
}, false),
true);

Forget the overlay.js file and the overlay.xul file, you don't need it. Use the style instruction for chrome.manifest instead, like so:
style chrome://browser/content/browser.xul resource://helloworld/skin/global.css
No js req'd

Related

How to remove and add js file completely dynamicaly after page load by jquery?

In my project ,I have to load JS and CSS file dynamically after the page load.
By using below code I am able to add and remove the js file But after adding the new file by removing the previous one,then the previous file is not shown in the header but when I run the code both js file code is executed.I don't known how to remove the file completely ,Can some body help me.
For that the code is.
In the the view page header:-
<link rel="stylesheet" id="videoCss" />
<script id="videojs"></script>
Jquery for Dynamically load JS and CSS file:-
function addRemoveJsCssFile(filename, filetype)
{
var fileref='';
if (filetype == "js") { //if filename is a external JavaScript file
document.getElementById("videojs").remove();
fileref=document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", filename);
fileref.setAttribute("id", "videojs");
}
else if (filetype == "css") { //if filename is an external CSS file
document.getElementById("videoCss").remove();
fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
fileref.setAttribute("id", "videoCss");
}
if (typeof fileref != "undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
In this function we have to pass the file location and type of file i.e css or js to add file dynamically.Thank you.
I don't know if I've understood your issue, but let me try to explain:
if the original script is in head section, it will be executed immediately, because Javascript is a procedural language, so there's nothing that you can do in a script placed "later": scripts defined earlier are executed earlier so, maybe your problem is when you call your function, it's simply too late to stop the videojs execution.
On the other side with scripts defined before, you can't see script tags defined later.. or better, you could if you're deferring, but in a deferred situation you'll be fighting again with the same issue, the videojs script would be always executed (it would be always too late or too early, because your statements executes or before, or after, there isn't a third way).
Of course you can load a script before just to set a global object that could say to videojs "stop, don't proceed with your stuff!" but obviously you shall edit videojs code either, with a wrapper "if" that asks that object the permission to proceed, and I don't think that's the response you're looking for.
But the question is: what's executed in that javascript videojs, an event binder that starts on load? Or in another event? Or is just a sequence of statements that are executed - sorry for the wordplay - sequentially?
In the first and second case there's something that you can do before: if video.js starts when an event is triggered, you can stop that function to be executed, operating before that trigger: you must delete the event subscription. To unbind the event, you must know how the first script operates and what event it subscribes in order to unbind it.
Here is how to execute script before jQuery ready event (but it's valid also for native javascript events, so I think that might be helpful):
running jQuery code before the dom is ready
This answer is useful even for every document events, not only for the load or "jQuery ready".
But, even if it's possible to remove the bind "vanishing" every videojs script effects, it's not a clean job, because
Overall, videojs has been executed
This will work only with videojs and at least it may work only with hardcoded scripts that uses the same event to start, but not for all hardcoded scripts
So, what I suggest for your purpose, it's to manage load and unload of scripts entirely with this manager, don't hardcode them in HTML.
PS: Have you ever heard about require.js?
If not, take a look here
Instead of deleting whole element, and than creating new one, maybe try just to change the 'src' attribute in existing element?
now
document.getElementById("videojs").remove();
fileref=document.createElement('script');
fileref.setAttribute("type", "text/javascript");
fileref.setAttribute("src", filename);
fileref.setAttribute("id", "videojs");
suggest
document.getElementById("videojs").setAttribute("src", filename);
You can use $.getScript() to dynamically load js file.
Try this
$('#scriptid').remove(); //remove it first and then add the new one
var script = document.createElement('script');
script.src = something;
document.head.appendChild(script); //Add element to head tag
OR
$("<style type='text/css' href=''></style>").appendTo("head");
$("<script type='text/javascript' src=''></script>").appendTo("head");

My Javascript is supposed to load one CSS on click, but loads both at the same time

When I launch my page, the css is totally messed up because my js is supposed to dynamically load css on click (mobile or standard website css). Currently, it just loads them both. Here's the code:
function loadjscssfile(filename, filetype)
{
if (filetype=="css")
{
var fileref = document.createElement("link");
fileref.rel= "stylesheet";
fileref.type = "text/css";
fileref.href = filename;
document.getElementsByTagName("head")[0].appendChild(fileref)
}
}
loadjscssfile("HCSS.css", "css")
I have two links on the site. One loads the mobile css, the other loads the standard website css. I have it linked like this:
load hcss
<br/>
load mobile
What you are after is swapping css files, not just loading a new one. In jquery it would probabaly look something like this (code not tested):
function swapCssFiles(fileToLoad, fileToUnload) {
$('head link[href="'+fileToUnload'"]') // select the tag with css to unload
.attr('href', fileToLoad); // swap the href attribute with the file to load
}
This is off course possible with 'pure' javascript, but I'm to much a jQuery addict to tell you how. If you see how easy the syntax is, you can probably tell why.
Your links would look something like this:
load hcss
I hope this is helpfull.
Note however that this is not the way I would approach this. If you want to target mobile devices with specific css, I would use mediaqueries to detect screensize, and not javascript.

random quote from array in external javascript not displaying onload

I'm a javascript beginner, and I'm trying to figure out why this code works when written in the head, but not when it's being referenced from an external file.
in the head of my html document, I'm referencing the javascript file "quote.js" as follows.
<script type="text/javascript" language="JavaScript" src="/js/quote.js"> </script>
the contents of quote.js are as follows
var textarray = [
"Be Good.",
"Our future depends powerfully on how well we understand the cosmos.",
"Bottomless wonders spring from simple rules... repeated without end.",
"All our science, measured against reality, is primitive and childlike — and yet, it is the most precious thing we have.",
"To use violence is to already be defeated."
];
function RndText() {
var rannum= Math.floor(Math.random()*textarray.length);
document.getElementById('ShowText').innerHTML=textarray[rannum];
}
window.onload = function() { RndText(); }
finally, the div I'm replacing in the body is as follows...
<div id = "ShowText"></div>
it's probably a stupid mistake, but I've been trying to track it down for a while now, and I'm missing something. When I write the contents of quote.js in my html head, it works fine. Any ideas? Thanks in advance.
If the code works in the head, but not when included, it's likely to be a problem with the path to the script. Double check that /js/quote.js is an appropriate location. It may need to be js/quote.js, you you may have a typo. In browsers like FireFox and Chrome, if you view the source code of your page you can click on the path to files like this and it loads the included file or shows you an error if the file is not found.
If you can share a link to the page, I can tell you with more certainty exactly what the problem is.
Also, you don't have to the language attribute if you're using XHTML, but that's not causing the problem.
Perhaps the code is running before the DOM is ready
Instead of onload use the event DOMContentLoaded
document.addEventListener('DOMContentLoaded', function () {
//code here
}, false);

Setting an image source via Javascript unreliable in Internet Explorer

I am simply trying to change the SRC attribute of an image via javascript like so:
document.getElementById('fooImage').src = img;
Where img is a variable that has a link to the file.
In all other browsers (Chrome, Firefox, Safari) this works. In IE (7+) this also works too sometimes.
Using IE's built-in developer tools, I can see that the image's SRC tag is set. Is there something else in the locals window that could help me debug why the image doesn't actually show on screen?
I've also tried using jQuery to do this and same outcome:
$("#fooImage").attr("src", img);
An ideas?
In debugging this I would hard code it first...
document.getElementById('fooImage').src = "myimage.png";
I've used the following in my website and it works like this...
var imgCounter = document.getElementById('formtimer');
imgCounter.src = "graphics/odometers/1.png";
Some other things to check:
Make sure your ID= tag is not in the <DIV section but inside the <IMG section... for example <div class="style1"><img src="yourpicture" id="someid">. If `id='someid' is in the div tag then you can't change the picture / the picture won't show up.
are you using window.onload?, body onload? the proper way to use the first is..
window.onload = function () { YourFunctionHere(); };
Try a different test image. I had issues in the past with showing png's, I changed it to a gif or jpg and it worked. I don't understand how that was "way back" but it doesn't seem to be an issue anymore but hey... something to try.
try a full url
using https?
try sticking the image somewhere else in your program and see what happens.
try adding this to your HTML (put your website in place of mine - lookup BASE href on google for more info)
<BASE href="http://perrycs/" />
Make sure the image isn't hidden behind a layer (I know it works in some browsers)
tell us the website so we can check it out and get more info to help you in debugging this, seeing context (surrounding code) helps...
Given that it works in other browsers, searching on this topic it seems that often the problem is how IE caches images (ref. Epascarello's comment). Your code is the same as what I have - it works fine except in IE10.
I too, faced this conundrum. Then discovered that it works in 'Page Inspector', so after some digging discovered that (in Internet Explorer) by going to Tools.Internet Options.Advanced
uncheck the 'Disable script debugging (Internet Explorer)' and the one below it.
I found that with IE9 after changing an image.src with
var strVar="C:Users/x/Desktop/caution.png"
image.src=strVar
and calling an alert(image.src) I would get something like this n the alertbox:
file:///C:Users/x/Desktop/"C:Users/x/Desktop/caution.png"
So I tried
image.src=strVar.replace(/\"/g,"")
to remove qoutemarks
and it worked!
alert(image.src)
file:///C:Users/x/Desktop/caution.png

Dynamically changing stylesheet path not working in IE and Firefox

I have the following file:
<html>
<head>
<title></title>
<link rel="css" type="text/css" href="/empty.css" title="css" />
<script type="text/javascript" src="/Prototype"></script>
<script type="text/javascript">
function load_content()
{
var d = new Date();
new Ajax.PeriodicalUpdater('content', '/DOC?'+d.getTime(),
{
method: 'post',
frequency: 5,
onSuccess: function(transport) {
for(i=0; (a = document.getElementsByTagName('link')[i]); i++)
{
if(a.getAttribute('rel') == 'css' && a.getAttribute("type") == 'text/css')
{
a.href = '/CSS?'+d.getTime();
}
}
}
});
}
</script>
</head>
<body>
<div id="content"></div>
<script type="text/javascript">
load_content();
</script>
</body>
</html>
Note: Ignore the d.getTime() calls...these are just to get around an issue with IE not loading a new page from an AJAX call because it's caching scheme is too aggressive.
Basically, when it reloads the file at /DOC, it is supposed to be setting the current stylesheet to the file at /CSS... both DOC and CSS and constantly changing.
What's weird is that in Chrome it works great. DOC loads up in the "content" div and the stylesheet gets set to CSS and that css is applied to the page. I can change with CSS page and withing 5 seconds, when the page is refreshed, the CSS will be refreshed as well.
But in IE and Firefox, the HTML will load and I can see that the href attribute of the stylesheet link IS getting changed to "/CSS + getTime()" but, while the HTML loads, the css is never applied to the page. I can even change the content of DOC and it updates, but the css is never even applied. It just stays a style-free page.
Does Firefox and IE not support changing the style sheet reference in this way?
Is there a better way to do this?
Rather than changing the sheet in a single link, try using alternate style sheets. See this link on using alternate style sheets:
http://www.alistapart.com/articles/alternate/
The best way to include files via javascript is to insert a new dom element.
var a = document.createElement('link');
a.href="inset.css";
a.rel="stylesheet";
document.getElementsByTagName("head")[0].appendChild(a);
However, obviously the problem you're going to run into though is that firefox and ie will not repaint the canvas once the document is finished loading (and you're using ajax). The way you get around that is by taking the contents of the stylesheets and including them in a style element. This sample code will change the color on the page dynamically.
function onLoadFunction() {
var a = document.createElement('style');
a.appendChild(document.createTextNode('body {color: blue;}'));
document.getElementsByTagName("body")[0].appendChild(a);
}
When you load a new sheet, just destroy the css inside the style element and replace it.
maybe this will help you ...
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
It looks like you are simply reloading the existing page every time. Why not just use the refresh tag in your header to force the document to reload each time and put in the CSS and content server-side. A lot simpler and it works even with javascript disabled.
<meta http-equiv="refresh" content="5;url=http://example.com/DOC" />
It might be a caching issue. If you do a hard refresh (Ctrl+R in FF, Ctrl+F5 in IE) does it display the style properly? If that does fix it, you may want to look at removing the Last-Modified header from the CSS file or adding a cache control header telling the browser not to cache it.

Categories

Resources