why won't my rule apply

Discuss application theming and theme development.
Post Reply
User avatar
mcdavis
Posts: 3195
Joined: December 9th, 2005, 5:51 am

why won't my rule apply

Post by mcdavis »

I'm trying to work with CTR in NNL. Aris has some code (CSS probably; most of his stylesheets are applied with JS, but I couldn't find any JS touching this more directly than that) that removes padding from #identity-box. So I need to put it back on, and that's not working.

I have this rule in Stylish. It's the one not working. I can see in DOM Inspector that it's matching, it's just not winning.

Code: Select all

/* He sets padding on #identity-box; we reassert ours. 
 * His rule has selector:
 *
 *     #main-window:not([defaultfxtheme="true"]) #notification-popup-box[hidden] + * { ... }
 *
 * which has specificity 220, and we must exceed that.
 *
 * Unfortunately, even though our rule matches and is seen in DOM Inspector,
 * our padding still doesn't apply.
 */
#urlbar-wrapper > #urlbar #identity-box {
  padding: 0 5px !important;
  -moz-padding-start: 5px !important;
  -moz-padding-end: 5px !important;
}


Stylish claims https://github.com/JasonBarnabe/stylish ... age-styles its styles are applied as AUTHOR_SHEET unless you include the comment /* AGENT_SHEET */ in your sheet, which I'm not, so presumably my code is applied as AUTHOR_SHEET.

CTR's competing rule is this one, defined in back-forwardextra.css. The first half of that rule is the part that matches #identity-box.

Code: Select all

   #main-window:not([defaultfxtheme="true"]) #notification-popup-box[hidden] + *,
   #main-window:not([defaultfxtheme="true"]) #notification-popup-box + .notification-anchor-icon {
     -moz-padding-start: 0px !important;
     transition: none !important;
   }


As best I can tell, this rule is applied as follows.

1. CTR chrome.manifest overlays browser.xul with overlay.xul
2. overlay.xul includes overlay.js.
3. Based on settings, overlay.js applies one or more of the following CSS files:
- chrome://classic_theme_restorer/content/css/back-forward.css
- chrome://classic_theme_restorer/content/css/mode_icons_and_text.css
- chrome://classic_theme_restorer/content/css/mode_icons_and_text2.css
- chrome://classic_theme_restorer/content/css/mode_txtonly.css
4. Each of those four @imports chrome://ctraddon_os_special/skin/back-forwardextra.css
5. CTR chrome.manifest makes chrome://ctraddon_os_special/skin/ point to one of several os-specific versions of the file.
6. I'm on Vista, so this resolves to content/css/winaero/back-forwardextra.css
7. This file contains CTR's rule shown above.

CTR's overlay.js applies the CSS file in a function called manageCSS(). You can see the stylesheet is being applied as an AGENT_SHEET.

Code: Select all

    // Apply or remove the style sheet files
    function manageCSS(file) {

        const sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
        const ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

        let uri = ios.newURI("chrome://classic_theme_restorer/content/css/" + file,null,null);

        try{
            if (enable) {
                if (!sss.sheetRegistered(uri,sss.AGENT_SHEET))
                    sss.loadAndRegisterSheet(uri,sss.AGENT_SHEET);
            } else {
                if (sss.sheetRegistered(uri,sss.AGENT_SHEET))
                    sss.unregisterSheet(uri,sss.AGENT_SHEET);
            }
        }catch(e){}
    }


So that makes me think we have two competing rules, both with !important, CTR's from an AGENT_SHEET source and mine in Stylish from an AUTHOR_SHEET source.

According to W3C's CSS2 spec http://www.w3.org/TR/2011/REC-CSS2-2011 ... ml#cascade:

Code: Select all

To find the value for an element/property combination, user agents must apply the following sorting order:

    Find all declarations that apply to the element and property in question, for the target media type. Declarations apply if the associated selector matches the element in question and the target medium matches the media list on all @media rules containing the declaration and on all links on the path through which the style sheet was reached.
    Sort according to importance (normal or important) and origin (author, user, or user agent). In ascending order of precedence:
        user agent declarations
        user normal declarations
        author normal declarations
        author important declarations
        user important declarations
    Sort rules with the same importance and origin by specificity of selector: more specific selectors will override more general ones. Pseudo-elements and pseudo-classes are counted as normal elements and classes, respectively.
    Finally, sort by order specified: if two declarations have the same weight, origin and specificity, the latter specified wins. Declarations in imported style sheets are considered to be before any declarations in the style sheet itself.


I take that to mean my author rule has higher precedence that his user agent rule, and my property settings should win.

Obviously I'm wrong. What am I missing/forgetting?

Possibilities:
1 - It's been a long time since CSS2, and it doesn't work that way any more.
2 - Stylish documentation is wrong and it isn't actually creating AUTHOR_SHEETs.
3 - In its SQLite db, Stylish is confused about whether my sheet is AUTHOR_SHEET or AGENT_SHEET.
4 - Somewhere in CTR, Aris is setting padding directly on the element with JS el.padding = 0, and I overlooked this.
5 - The fact that CTR's sheet is applied later makes it ordered after other sheets and gives it higher precedence somehow.
6 - I'm confused in thinking that when W3C CSS2 talks about agent sheets, it's talking about the same thing as a stylesheet applied in JS as an AGENT_SHEET. Maybe when they say agent sheet they mean "rules that come with the user agent, built into it", and those are really two different things? But then wouldn't any second meaning need a separate place in the precedence order given by the W3C, which is missing, which means they accidentally left it out, which is unlikely?
Last edited by mcdavis on January 18th, 2015, 8:40 am, edited 1 time in total.
Theme Development is Radical Participation.
NNL Beta Builds for Current and Up-coming Firefox
Dear User: Your Help is Needed
User avatar
silverwind
Posts: 35
Joined: June 3rd, 2012, 5:07 am
Contact:

Re: why won't my rule apply

Post by silverwind »

Specificity issues like this are always a pain. In Stylish, I learned to always use the /* AGENT_SHEET */ comment to overrule anything in the UI or shadow DOM like checkboxes and other built-in styles. Let's see:

Code: Select all

#urlbar-wrapper > #urlbar #identity-box
This looks to be a specificity of 3-0-0. (3 IDs)

Code: Select all

#main-window:not([defaultfxtheme="true"]) #notification-popup-box + .notification-anchor-icon
This is 2-1-1 if I'm correct. (2 IDs, 1 class, 1 attribute)

Based on that alone, your style should win. Does AGENT_SHEET not help in your case? Maybe hack in a few ancestors of #urlbar-wrapper?
User avatar
mcdavis
Posts: 3195
Joined: December 9th, 2005, 5:51 am

Re: why won't my rule apply

Post by mcdavis »

silverwind wrote:In Stylish, I learned to always use the /* AGENT_SHEET */ comment to overrule anything in the UI or shadow DOM like checkboxes and other built-in styles.


I did try setting /* AGENT_SHEET */ like you said, but unfortunately that got me nothing.

I was vague about the part of the rule that matches, it was actually the other part, the #main-window:not([defaultfxtheme="true"]) #notification-popup-box[hidden] + *, part. I score that as 2-2-1 (assuming * counts as 1, and that classes and attributes each count as 10). So yeah, 3-0-0 should beat that.

EDIT: Not that it matters here, but I just checked and * (the universal element selector) counts as zero, so that should be scored as 2-2-0.
Last edited by mcdavis on January 18th, 2015, 7:04 am, edited 1 time in total.
Theme Development is Radical Participation.
NNL Beta Builds for Current and Up-coming Firefox
Dear User: Your Help is Needed
User avatar
silverwind
Posts: 35
Joined: June 3rd, 2012, 5:07 am
Contact:

Re: why won't my rule apply

Post by silverwind »

Out of curiosity: Does it work when you put it directly in the theme as opposed to a user style?
User avatar
mcdavis
Posts: 3195
Joined: December 9th, 2005, 5:51 am

Re: why won't my rule apply

Post by mcdavis »

silverwind wrote:Out of curiosity: Does it work when you put it directly in the theme as opposed to a user style?


Good thought :D but I did try that and no go. Darn it.
Theme Development is Radical Participation.
NNL Beta Builds for Current and Up-coming Firefox
Dear User: Your Help is Needed
User avatar
silverwind
Posts: 35
Joined: June 3rd, 2012, 5:07 am
Contact:

Re: why won't my rule apply

Post by silverwind »

Maybe there's another style you're missing? I'm not sure if you could get the DevTools to work on XUL parts, but I sometimes try to get clues from "Computed Styles".

Also relevant: https://bugzilla.mozilla.org/show_bug.cgi?id=936768
User avatar
mcdavis
Posts: 3195
Joined: December 9th, 2005, 5:51 am

Re: why won't my rule apply

Post by mcdavis »

At this point my guess is that the problem is that I've been using CSS2's cascading principles but I should be using the ones from CSS3 ("CSS Cascading and Inheritance Level 3") instead. It's the end of my day so I'll confirm that later but that fits all the evidence so far. There are big changes in the way CSS3 deals with rules having origin in an agent sheet which I must be the last person on the planet to find out about. Thanks Aris (who sent me a very helpful PM) and silverwind for the help.
Theme Development is Radical Participation.
NNL Beta Builds for Current and Up-coming Firefox
Dear User: Your Help is Needed
Post Reply