Looking to dynamically alter a CSS rule set through JavaScript within a Firefox Add-on using XUL, SDK or WebExtensions techniques. Specifically targeting support for Firefox versions 29.0b1 through 49.0a1.
The main issue I want to address is modifying the following elements:
file.xul:
(contains this line at the beginning)
<?xml-stylesheet href="chrome://{GUID}/skin/text.css" type="text/css"?>
text.css:
(relevant class in the file)
.myTextClass {
max-width: 800px;
}
code:
// Make changes to the class selector rule set by adding another rule,
// such as font-family: DejaVu Sans Mono
// Later on, based on user input, update or remove this font from the class
This task may overlap with #20927075, which lacked satisfactory solutions. However, my focus also includes utilizing SDK or WebExtensions techniques to ensure the desired functionality can be implemented within an existing XUL-based add-on using newer APIs.
I aim to create a basic "font selector" UI feature that applies a new font to the class. The CSS rule set currently defines one class with one rule, to which I want to add another rule and reflect these changes in the add-on's interface.
Here are some options I've considered, but find them all somewhat cumbersome:
1) Utilize document.getElementById and manually set the style
attribute. This works well for the demo area.
2) Similar to option 1, but use getElementByClassName. This method doesn't actually use a class, it finds nodes using a class and then updates each element's attribute, either style or class. This approach feels sluggish. While I could create a large CSS file with a class for every possible font and change the class attribute, this seems impractical compared to updating the style attribute directly.
3) Consider the style sheet service, although I am uncertain of its longevity given that it may be XPCOM-based and not part of Services.jsm. It appears to only load or unload entire style sheets, instead of allowing precise modifications to individual rules within a class definition.
4) jQuery is an option, but not preferable due to overhead concerns for a small add-on. Additionally, compatibility within XUL interface code is unknown.
5) Explore document.styleSheets which seems promising but falls short in terms of achieving the desired result (unless there is a misunderstanding on my part). Everything appears to be read-only, further complicating matters.
6) Resort to manual manipulation of entire style sheets via document.getElementsByTagName('head'), effectively overriding an entire CSS sheet rather than impacting a specific rule within a class.
If no better alternative exists, I might have to opt for option 2 above. Nevertheless, I was hoping for a solution that allows precise control over CSS from within a XUL document using JavaScript.
In attempting to understand how to accomplish this, I tested the following snippet:
for ( i = 0; i < document.styleSheets.length; i++ ) {
styleSheet = document.styleSheets[ i ];
console.log( 'style sheet: ' + i + ' ' + styleSheet.href );
if ( styleSheet.href === 'chrome://{GUID}/skin/text.css' ) {
for ( j = 0; j < styleSheet.cssRules.length; j++ ) {
styleRule = styleSheet.cssRules[ j ];
console.log( 'style sheet: ' + i + ' ' + 'styleRule: ' + styleRule.cssText );
}
}
}
Upon executing this code (placed in file.js
referenced from a file.xul
<script>
tag), I observed log outputs similar to the following (in Firefox 29.0b1):
"style sheet: 0 chrome://git-addonbar/skin/addonbar.css" file.js:189
09:49:47.101 "style sheet: 1 chrome://browser/content/browser.css" file.js:189
09:49:47.101 "style sheet: 2 chrome://browser/content/places/places.css" file.js:189
09:49:47.101 "style sheet: 3 chrome://browser/skin/devtools/common.css" file.js:189
09:49:47.101 "style sheet: 4 chrome://browser/skin/customizableui/panelUIOverlay.css" file.js:189
09:49:47.101 "style sheet: 5 chrome://browser/skin/browser.css" file.js:189
09:49:47.101 "style sheet: 6 chrome://browser/skin/browser-lightweightTheme.css" file.js:189
09:49:47.101 "style sheet: 7 chrome://global/skin/global.css" file.js:189
09:49:47.101 "style sheet: 8 chrome://{GUID}/skin/text.css" file.js:189
09:49:47.102 "style sheet: 8 styleRule: .myTextClass { max-width: 800px; }" file.js:194
09:49:47.102 "style sheet: 9 null" file.js:189