You don't need to QI when you get `nsINode` (or some its subclasses), `nsPIDOMWindowInner`, `nsPIDOMWindowOuter` or `nsPIWindowRoot` from `EventTarget`

47 views
Skip to first unread message

Masayuki Nakano

unread,
Nov 8, 2021, 6:02:24 AM11/8/21
to dev-pl...@mozilla.org

Hello, I added some static `FromEventTarget` helper methods like `FromNode`. This allows you to avoid to QI from `EventTarget` pointers.

For example, when you need to get `Element` pointer from `EventTarget` pointer, previous you needed to do:

namespace mozilla::dom {

void Foo(EventTarget* aEventTarget) {
  nsCOMPtr<Element> element = do_QueryInterface(aEventTarget);
  if (!element) {
    return;
  }
  ...
}

}  // namespace mozilla::dom

Now, you can write this as:

namespace mozilla::dom {

void Foo(EventTarget* aEventTarget) {
  Element* element = Element::FromEventTargetOrNull(aEventTarget);
  if (!element) {
    return;
  }
  ...
}

}  // namespace mozilla::dom

`nsINode::FromEventTarget()`, `nsPIDOMWindowInner::FromEventTarget()`, `nsPIDOMWindowOuter::FromEventTarget()` and `nsPIWindowRoot::FromEventTarget()` resolve this with one virtual call so that they are never slower than `do_QueryInterface`.

Subclasses of `nsINode` helpers (e.g., `nsIContent::FromEventTarget()`, `Element::FromEventTarget()`, etc) resolve this with two virtual calls. I guess that this is faster than `do_QueryInterface` in most cases since IID comparison is not cheap and most concrete classes of `nsINode` have a lot of interfaces.

`FromEventTarget` and `FromEventTargetOrNull` helpers for subclasses of `nsINode` are declared and defined by `NS_IMPL_FROMNODE_HELPER` macro automatically. So all classes which have `FromNode` and `FromNodeOrNull` have the new helper methods too.

Finally, like `dom::Element` and `dom::Text`, there are similar utility methods in `dom::EventTarget` now.

-- 
Masayuki Nakano <masa...@d-toybox.com>
Working on DOM, Events, editor and IME handling for Gecko
Reply all
Reply to author
Forward
0 new messages