I am building a firefox addon through the Mozilla Addon Builder https://builder.addons.mozilla.org
I'm starting really basic, I figure it doesn't get any more simple than changing google.com to red. I made the css change the body, html, and divs and added important, so I could be sure that if the stylesheet displays, it will change the background red, and will overwrite the current css.
However, when I activate it (through the testing button which installs the addon), nothing happens. The CSS is not injected into the page.
Here is what the extension looks like:
Here is the code:
main.js
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "*.google.com/*",
contentStyleFile: data.url("data/style.css")
});
style.css
html, body, div {
background: red !important;
}
I also tried using the following urls, all which did not work either:
http://google.com/*
https://google.com/*
http://www.google.com/*
https://www.google.com/*
http://google.com/
https://google.com/
http://www.google.com/
https://www.google.com/
I also tried changing the following locations to style.css, which did not make any difference either:
style.css
data/style.css
../data/style.css
I also tried removing the sdk/ from the data and pagemod variables, but that did not work either.
Why is it not working and how can I fix it?
Match patterns contain only one *.
The pattern "*.google.com" matches all the Google url's in your list. Match pattern can also be a regular expression. You can match http://google.ie and all the other google.*'s with
pageMod.PageMod({
include: /.*\/(\/\w*\.)?google\.[A-Za-z]{2,3}\/.*/,
contentStyleFile: data.url("style.css")
});
Related
I have a component A that should dynamically change the font size of some of it's contents. I currently use CSS variables to do that and the component will contribute some CSS String containing these CSS variables:
public void renderHead(IHeaderResponse response) {
String fontCss = // dynamically fetch CSS cariables
response.render(CssHeaderItem.forCSS(fontCss, "font-css"));
}
On the same page I have the possibility to change these font sizes using an AJAX update within another component B. This will add the component A to the AjaxRequestTarget, which will cause the renderHead method to be executed with updated values for the font CSS variables.
However, I don't see an updated font size in my browser as the old CSS variables still seem to be present. How can I enforce the new CSS to overwrite the old one?
So far I found 2 solutions, that seem like dirty workarounds to me:
Add the whole page to the AjaxRequestTarget, so the whole page will be refreshed.
Add JavaScript to the AJAX update to remove the old styling with:
var allStyles = document.getElementsByTagName("style");
for (var style of allStyles) {
if (style.getAttribute("id").includes("font-css")) {
style.remove();
}
}
Is there a cleaner solution to this problem?
You found the problem with workaround 2.
response.render(CssHeaderItem.forCSS(fontCss, "font-css"));
adds <style id="font-css"> ... </style> to the page. Later when the Ajax response contributes the new content the JavaScript logic finds that there is an HTML element with id font-css and assumes that there is nothing to do.
A simple solution is to use dynamic id, e.g. by using UUID in #renderHead().
Another solution is to make this <style> a proper Wicket Component, a Label, that could be added to the AjaxRequestTarget with an updated Model when needed.
I was looking for a solution to automatic generation of the VuePress sidebar and found this module which was recommended in this tutorial - solution2
I'm trying to get it working as described however the sidebar displays the actual folder path to the html rather than just the name as can be seen below, i've tried a different folder structure, adding and removing MD files but i cannot get the sidebar to display correctly. Would anyone know how I can fix this / what i've done wrong?
Config.js:
const getConfig = require("vuepress-bar");
module.exports = {
title: 'Hello VuePress',
description: 'Just playing around',
themeConfig: {
...getConfig(`${__dirname}/..`)
}
}
Sidebar result :
I fixed this by adding the correct front matter to my MD files, title and permalink
I want to prevent JavaScript redirects in Firefox for one domain (youtube.com), and I was wondering whether there's a plugin that will do it. I'm trying to use NoScript, and I'd like to allow scripts globally because I don't want to disable most JavaScript, but this seems to just allow JavaScript redirects. Is there a way for me to just disable JavaScript redirects (or ideally, display a prompt)?
The only other way I can think of doing it is to write my own extension that messes around with window.onbeforeunload and window.unload, but ideally I'd like to use an existing addon.
var {utils: Cu, classes: Cc, instances: Ci, results: Cr} = Components
Cu.import('resource://gre/modules/Services.jsm');
var myobserve = function(aSubject, aTopic, aData) {
var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
if (httpChannel.loadFlags & Ci.nsIHttpChannel.LOAD_REPLACE) {
//its a redirect, lets block it
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
}
}
I use the presence of flags to test for redirect. Here are some notes i took on flags awhile back, im not totally sure of how accurate these notes are:
if has LOAD_DOCUMENT_URI it usually also has LOAD_INITIAL_DOCUMENT_URI if its top window, but on view source we just see LOAD_DOCUMENT_URI. If frame we just see LOAD_DOCUMENT_URI. js css files etc (i think just some imgs fire http modify, not sure, maybe all but not if cached) come in with LOAD_CLASSIFY_URI or no flags (0)
note however, that if there is a redirect, you will get the LOAD_DOC_URI and the LOAD_INIT_DOC_URI on initial and then on consequent redirects until final redirect. All redirects have LOAD_REPLACE flag tho
note: i think all imgs throw http-on-modify but cahced images dont. images can also have LOAD_REPLACE flag
Of course to start observing:
Services.obs.addObserver(myobserve, 'http-on-modify-request', false);
and to stop:
Services.obs.removeObserver(myobserve, 'http-on-modify-request', false);
How to get all the images, after decoding if possible, on a webpage through XPCOM ?
The image might be specified in HTML as a background url in some CSS property, inside img tag, or in any form that a web developer might have included.
I tried looking into imgIContainer, imgIDecodeObserver and many other interfaces. Although there is a way through which we can provide image URI to Mozilla so that it loads the image, decodes it and returns imgIContainer. But I couldn't find anyway to get all images in current webpage.
This has to be done in either Java or Javascript.
Any suggestions?
#Wladimir - Thanks for your help.
I want all the images including CSS constructs (background images). So now I am listening to events from nsIWebProgressListener.
onStateChange: function(webProgress, request, stateFlags, status) {
if ((~stateFlags & (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_STOP)) == 0) {
var imgReq = request.QueryInterface(CI.imgIRequest);
if (imgReq)
var img = imgReq.image;
}
}
The problem is that request.QueryInterface(CI.imgIRequest) throws exception for all NON-image requests. Although those exceptions can be ignored by putting code inside try-catch block, but I'd prefer to do things cleanly.
Is there any condition that can be checked to know whether request is for image or not?
There is existing code that you can look at. The Page Info dialog has a Media tab that successfully shows most images on the page. The important function is grabAll() in pageInfo.js, it is called for each element (via a TreeWalker). As you can see, there is no generic way to get the image, this function rather uses window.getComputedStyle() to extract the values of a bunch of the CSS properties for this element: background-image, border-image, list-style-image, cursor. It will also look for <img>, <svg:image>, <link> (favicon), <input>, <button>, <object> and <embed> tags. It doesn't manage to recognize everything however, e.g. these CSS constructs will not be recognized:
.foo:before
{
content: url(image.png);
}
.foo:hover
{
background-image: url(image.png);
}
Still, this is probably as far as you can get - unless you want to look at the requests made by the web page as it loads.
Edit: If you look at the requests as they are performed (via a web progress listener), you can do the following:
if (request instanceof CI.imgIRequest)
var img = request.URI.spec;
Note that request.image won't help you much, almost all methods of imgIContainer are only accessible from native code.
I've developed a Firefox extension for displaying explanations for some unusual words. My problem is that my tooltip get's modified by other stylesheets of the current page. So on some pages my stylesheet looks fine and on some it's totally messed up. Is there a way to limit my stylesheet to my tooltip notes so that stylesheets from the webpage wouldn't affect mine?
I'm loading my stylesheet that way:
initTooltipStyle: function(on) {
var sss = Cc["#mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var uri = makeURI("resource://tooltip/tooltip.css");
if (sss.sheetRegistered(uri, sss.USER_SHEET))
sss.unregisterSheet(uri, sss.USER_SHEET);
if (on)
sss.loadAndRegisterSheet(uri, sss.USER_SHEET);
},
I have experienced this problem. Most of the time the style property which you didn't applied to your element will be easily overriden by webpages. For instance, if you didn't declare margin for your div element and webpage has declared div{margin:0;} your element will also inherit it. Try adding reset.css to your elemets(http://meyerweb.com/eric/tools/css/reset/).
Then try adding your elements into the root elemnt of the page instead of body. document.documentElement.appendChild(). These techniques helped me.
Hope that helps!