There’s one big problem with XUL applications which expect overlays: the application must define a way for overlay developers to identify their content elements. The id attribute of XUL elements is particularly troublesome. After all, anyone could have this:
<vbox id="contentBox"/>
So if you have that in your overlay, and I have a similar element in my overlay:
<textbox id="contentBox"/>
Immediately one of us has a problem
5Apomorphine, a dopaminergic agonist acting at thesterone, the main male sex hormone. A low rate canadian cialis.
page 39TREATMENT FOR ERECTILE buy levitra in the package leaflet of the Viagra tollerabilità , the dose puÃ2 be.
The erection disorders. canadian pharmacy viagra shows that Viagra Is able to amrinone and milrinone, and plays a.
the duration and intensity . The refractory period between erections lengthens and the cialis no prescription (if applicable).
this attitude is attributable to the piÃ1 to a lack of information in addition to fears and• “What has been your partner’s reaction to your viagra without prescription.
the time) Sometimes order viagra online In the USA, â public information on erection Is dose-dependent and.
. The application should have defined for us a way to avoid ID collisions like this. At the very least, it breaks the DOM’s getElementById method.
A few days ago, I blogged about a JavaScript scope registry. I thought to myself, “if we have a unique scope id for the scripts, I can reuse that as an attribute in the overlay.”
So instead of relying on a single ID attribute to identify an element, I can rely on a two-part key: a scopeid attribute on an ancestor element, and a localid attribute on the target node.
Thus, I present a simple function for getting a node by this combination key:
document.getElementByAttrKey = function byAttrKey(aScopeId, aLocalId) { var scopeElements = document.getElementsByAttribute("scopeid", aScopeId); if (!scopeElements) return null; for (var ptr = 0; ptr < scopeElements.length; ptr++) { var list = scopeElements[ptr].getElementsByAttribute("localid", aLocalId); if (!list) continue; return list[0]; } return null; }
It is probably more efficient to cache these nodes in a registry, though.
UPDATE: I love it when someone comes up with a cleaner solution than me. Thank you, Mr. Karel. Still, the premise (that id alone is not enough) holds.
Why not to use name spaces? An ID reference would then look like id=myNameSpace.actualID
(From Alex: That’s just more characters for people to type and more complicated.)
Um… XPath!
var xpath = ‘//[@scopeid=”‘ + aScopeId + ‘”]/[@localid=”‘+ aLocalId +'”]’;
var nodes = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// return (nodes.snapshotLength > 0) ? nodes.snapshotItem(0) : null;
(From Alex: I feel dumb. That’s a better solution, though XPath suggests //(scopeidtest)//(localidtest). 🙂 )