One of the last tasks with this styling — or at least we reckoned it was with styling — was addressing a peculiar flashing effect that occurred whenever particular modules were loaded. Upon closer scrutiny we realised something was triggering all the background colours and all the button skins to be redrawn — very perceptively — when some modules were first displayed.
On the off chance someone else is puzzling over this problem and cannot find any documentation on the matter, I lay down my findings here.
After systematically breaking down and comparing components that were being added at runtime (as children of the loaded modules) I found mx.controls.ButtonBar to be the common culprit. If this wasn't loaded, the flashing didn't happen.
I then systematically broke down the ButtonBar component and found that the problem was indeed relating to styling: witness the following code.
The above snippet was extracted from the overridden setter function moduleFactory (line 497 of ButtonBar.as) and shows a comparison being made between the merged ButtonBar's borderSkin and the global borderSkin styles. In Flex 4 this equality comparison always returns false the first time it is encountered, causing a style to be set, and somehow manages to affect the global style; in the Flex 3 SDK this code doesn't exist.
var typeSelector:CSSStyleDeclaration = styleManager.getMergedStyleDeclaration("mx.controls.ButtonBar");
if (typeSelector)
{
var borderSkin:* =
styleManager.getMergedStyleDeclaration("global").getStyle("borderSkin");
if (typeSelector.getStyle("borderSkin") !== borderSkin)
{
// Setting a merged style is not supported so get a local style.
typeSelector = styleManager.getStyleDeclaration("mx.controls.ButtonBar");
// Our style manager may not have a local definition of the
// button bar style so add a local one so we can modify it.
if (!typeSelector)
{
var selector:CSSSelector = new CSSSelector("mx.controls.ButtonBar", null, null);
typeSelector = new CSSStyleDeclaration(selector, styleManager);
}
typeSelector.setStyle("borderSkin", borderSkin);
}
}
There is no way to forcefully assign a borderSkin to the component, since the class defines the style as excluded, and — in our framework anyway — the component fails to inherit the style by this point from the halo theme's global style.
As any good workaround ever is, the solution was simple.
I added a child ButtonBar to the top-level application. Since by itself it's invisible and sizeless in the halo theme, adding <mx:buttonbar/> somewhere discreetly was fairly inoffensive.
Debugging the code again, we find that the borderSkin comparison still fails, but it doesn't matter since the application defines the style before first rendering; and any subsequent appearance of the component from within a module or anywhere else in the application inherits directly, and properly, from this definition.
Now the two components we needed to load — RichTextEditor and TabNavigator — in our modules are loaded and displayed without changing any application styles, hence no confounded flashing.