XBL documents can use a <stylesheet> element to specify additional stylesheets that get applied to bindings. This is probably needed to render the browser chrome properly, as well as a few odd XBL-implemented content features like video controls. This is implemented by code to attach the binding manager to the style set in nsCSSFrameConstructor::ConstructRootFrame, and then additional logic (currently in nsStyleSet::AppendAllXBLStyleSheets) to get the stylesheet from the bindings.
Cameron, can you take this?
Per discussion this afternoon, ting-yu is going to work on this. Cameron can probably provide guidance. We should make this machinery general enough to also support <stylesheet scoped>, which will solve two issues at once.
Note that in bug 1328509, jryans is going to need to add some machinery to the traversal to track whether any ancestor satisfies a particular predicate (in the case of bug 1328509, whether the ancestor or self is a link element). We should be able to use the same machinery to track whether an ancestor element has a scoped stylesheet.
Let's start with supporting XBL style sheets and leave <style scoped> as a followup, which will need a bit more complication. Looks like there are three main aspects to supporting XBL style sheets: 1. Making sure that we create the right kinds of StyleSheet object in nsXBLProtoypeResources. There is one nsBindingManager per document, and the nsBindingManager is constructed with a document argument, so we should be able to pass down the StyleBackendType to use down to nsXBLResourceLoader::LoadResources, which is where the style sheets are actually loaded. We don't need separate storage for ServoStyleSheets and GeckoStyleSheets. 2. Adding a new member to nsXBLPrototypeResources to represent the result of cascading all the style sheets for that particular XBL binding, like the existing nsCSSRuleProcessor object is used for Gecko. At the point where all the style sheets have finished loading, in nsXBLResourceLoader::StyleSheetLoaded, instead of calling GatherRuleProcessor on the nsXBLPrototypeResources, we can call some new method which would call into a Servo FFI function that takes a list of the StyleSheet objects and returns (1) a Rust SelectorMap object, and (2) a FnvHashMap<PseudoElement, SelectorMap> object, which together represent the result of the casacde, just like nsCSSRuleProcessor, for that XBL binding's style sheets. (We might want a new Rust type that bundles those two things together.) Then, in push_applicable_declarations, we call into a new Gecko FFI function to ask the nsBindingManager to return all of the SelectorsMaps/FnvHashMaps that apply to the element, and we can do that just before the Author level. This FFI function will search for the bindings just like the mBindingManager->WalkRules call in nsStyleSet::FileRules does. We might be able to use the NODE_MAY_BE_IN_BINDING_MNGR Node bit to do a quick check on whether we need to call into the nsBindingManager (since it would be good to avoid doing this for every element in the document, I guess). 3. We also need to make push_applicable_declarations skip applying any Author level style sheets to content that is in an XBL shadow tree. I'm not sure if that means we can just extend the existing "is NAC" check to an "is anonymous content" check. You could investigate how, in nsStyleSet::FileRules, the mBindingManager->WalkRules returns the "cutOffInheritance" outparam. We don't need to worry about tracking what XBL style scopes we have during the traversal, since the nsBindingManager itself will ensure that we only return SelectorMaps for an element if it's within that binding's scope. (But we will need to worry about this later, for HTML <style scoped> support.) bz, as someone more familiar with XBL guts than me, does this sound reasonable?
> We also need to make push_applicable_declarations skip applying any Author level style > sheets to content that is in an XBL shadow tree. Not quite. You need to skip applying author level style if the element's binding (or rather its most-derived binding with anon content) has inheritstyle="false" on the <xbl:binding> element, or if that's true for anything up its GetBindingParent() chain. At least if I'm reading the code correctly. The rest of this sounds reasonable. You can in fact check NODE_MAY_BE_IN_BINDING_MNGR to avoid doing any of the XBL-related stuff here.