Community
Participate
Working Groups
I started to investigate what would be necessary to hook in a custom element provider. Although I can see my custom provider is picked up by CSSEngineImpl, it's never actually used. Tracing through AbstractCSSEngine#getElement(Object) lines 844 - 849 seems incorrect: if (element instanceof Element) elt = (Element) element; else if (elementProvider != null) { elt = elementProvider.getElement(element, this); } else if (elementProvider == null) { Object tmp = widgetsMap.get(element.getClass().getName()); if (tmp == null) { Class parent = element.getClass(); do { parent = parent.getSuperclass(); tmp = widgetsMap.get(parent.getName()); } while (tmp == null && parent != Object.class); } //found && parentClass != ElementAdapter.class // line 844 elementProvider = (IElementProvider) tmp; // PROBLEM // Looks like this can be NULL see bug 338756 if( elementProvider != null ) { elt = elementProvider.getElement(element, this); } } This code causes the first matching element provider found to become *the* only element provider consulted. I think it should instead be: if(tmp != null && tmp instanceof IElementProvider) { elt = ((IElementProvider)tmp).getElement(element, this); } This has the expected effect.
This fix will have a performance impact when we enable dynamic pseudo classes (bug 362532).
Brian, did you add an extension point for your element provider? (org.eclipse.e4.css.core.elementProvider - take a look at the plugin.xml for org.eclipse.e4.ui.css.swt)
Created attachment 206794 [details] demo app with custom element provider for Link (In reply to comment #2) > Brian, did you add an extension point for your element provider? > (org.eclipse.e4.css.core.elementProvider - take a look at the plugin.xml for > org.eclipse.e4.ui.css.swt) Yes, I did. With the fix I describe above, my custom element provider is correctly instantiated and picked up. I've attached the test app here. It is the RCP Mail example with an attempt to add an element for Links, ostensibly to add support for a new property "link-color" (which depends on bug 130444). If you look at the code above for AbstractCSSEngine#getElement(Object), which is called for every widget during the traversal, you'll see that if elementProvider == null, it causes elementProvider to be set to 'tmp'. Subsequent calls will always use that elementProvider. The first call will usually be for a Shell, which is mapped to SWTElementProvider, and thus the SWTElementProvider will be used for all subsequent widgets, regardless of whether they provide a different provider. It just happens to work as we only provide a single element provider anyways, SWTElementProvider.
Fix and tests committed to master http://git.eclipse.org/c/platform/eclipse.platform.ui.git/commit/?id=667bfe7fa9091c9748141820e2fccb053ebc6685
Verified with demo app in I20120123-2200