Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Attributes
nsUICommandCollector Class Reference

#include <nsUICommandCollector.h>

Inheritance diagram for nsUICommandCollector:
Inheritance graph
[legend]
Collaboration diagram for nsUICommandCollector:
Collaboration graph
[legend]

List of all members.

Classes

struct  EventHandler

Public Member Functions

 nsUICommandCollector ()
nsresult GetEventTargets (nsIDOMEvent *event, nsString &targetId, nsString &targetAnonId) const
void GetEventKeyId (nsIDOMEvent *event, nsString &keyId) const
nsresult GetEventWindow (nsIDOMEvent *event, PRUint32 *window) const
void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.
void handleEvent (in nsIDOMEvent event)
 This method is called whenever an event occurs of the type for which the EventListener interface was registered.
void onAttach ()
 Notification that this collector should be enabled.
void onDetach ()
 Notification that this collector is no longer enabled.
void onNewLog ()
 Notification that the MetricsService is starting a new event log.

Static Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
NS_DECL_NSIDOMEVENTLISTENER
static
NS_DECL_NSIMETRICSCOLLECTOR
PLDHashOperator PR_CALLBACK 
AddCommandEventListener (const nsIDOMWindow *key, PRUint32 windowID, void *userArg)
static PLDHashOperator PR_CALLBACK RemoveCommandEventListener (const nsIDOMWindow *key, PRUint32 windowID, void *userArg)

Private Member Functions

 ~nsUICommandCollector ()
void AddEventListeners (nsIDOMEventTarget *window)
void RemoveEventListeners (nsIDOMEventTarget *window)
nsresult HandleCommandEvent (nsIDOMEvent *event)
nsresult HandleTabMoveEvent (nsIDOMEvent *event)
nsresult LogBookmarkInfo (const nsString &id, nsIMetricsEventItem *parentItem)
nsresult SetHashedValue (nsIWritablePropertyBag2 *properties, const nsString &propertyName, const nsString &propertyValue) const

Static Private Attributes

static const EventHandler kEvents []

Detailed Description

Definition at line 52 of file nsUICommandCollector.h.


Constructor & Destructor Documentation

Definition at line 103 of file nsUICommandCollector.cpp.

{
}

Definition at line 107 of file nsUICommandCollector.cpp.

{
}

Member Function Documentation

NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER NS_DECL_NSIDOMEVENTLISTENER static NS_DECL_NSIMETRICSCOLLECTOR PLDHashOperator PR_CALLBACK nsUICommandCollector::AddCommandEventListener ( const nsIDOMWindow key,
PRUint32  windowID,
void userArg 
) [static]

Definition at line 424 of file nsUICommandCollector.cpp.

{
  for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kEvents); ++i) {
    // Attach a capturing event listener to the window.
    // Use capturing instead of bubbling so that we still record
    // the event even if propagation is canceled for some reason.

    // Using NS_LITERAL_STRING in const data is not allowed, so convert here.
    // This is not performance-sensitive.
    nsresult rv;
    rv = window->AddEventListener(NS_ConvertASCIItoUTF16(kEvents[i].event),
                                  this, PR_TRUE);
    if (NS_FAILED(rv)) {
      MS_LOG(("Couldn't add event listener %s", kEvents[i]));
    }
  }
}

Here is the caller graph for this function:

Definition at line 374 of file nsUICommandCollector.cpp.

{
  // The source event will give us the original event in the case where a new
  // event was dispatched due to a command= attribute.
  nsCOMPtr<nsIDOMXULCommandEvent> commandEvent = do_QueryInterface(event);
  if (!commandEvent) {
    // nsIDOMXULCommandEvent is only in Gecko 1.8.1+
    return;
  }

  nsCOMPtr<nsIDOMEvent> sourceEvent;
  commandEvent->GetSourceEvent(getter_AddRefs(sourceEvent));
  if (!sourceEvent) {
    return;
  }

  nsCOMPtr<nsIDOMEventTarget> sourceEventTarget;
  sourceEvent->GetTarget(getter_AddRefs(sourceEventTarget));
  nsCOMPtr<nsIDOMElement> sourceElement = do_QueryInterface(sourceEventTarget);
  if (!sourceElement) {
    return;
  }

  nsString namespaceURI, localName;
  sourceElement->GetNamespaceURI(namespaceURI);
  sourceElement->GetLocalName(localName);
  if (namespaceURI.Equals(NS_LITERAL_STRING("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul")) &&
      localName.Equals(NS_LITERAL_STRING("key"))) {
    sourceElement->GetAttribute(NS_LITERAL_STRING("id"), keyId);
    MS_LOG(("Key Id: %s", NS_ConvertUTF16toUTF8(keyId).get()));
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsUICommandCollector::GetEventTargets ( nsIDOMEvent event,
nsString targetId,
nsString targetAnonId 
) const

Definition at line 302 of file nsUICommandCollector.cpp.

{
  // This code deals with both anonymous and explicit (non-anonymous) content.
  //
  // For explicit content, we just return the id of the event target in
  // targetId, and leave targetAnonId empty.  If there is no id, then
  // we return failure.
  //
  // For anonymous content, we return the id of the event target (after
  // retargeting), in targetId.  We return the anonid of the event's
  // originalTarget in targetAnonId, so that XBL child elements can be
  // distinguished.  If there is no anonid, then we return failure.
  // Note that the originalTarget is set after text node retargting, but
  // before any XBL retargeting.
  //
  // We assume that if the originalTarget has no id, we're dealing with
  // anonymous content (this isn't always true, but it's good enough for what
  // this code does).

  nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(event);
  NS_ENSURE_STATE(nsEvent);

  nsCOMPtr<nsIDOMEventTarget> originalTarget;
  nsEvent->GetOriginalTarget(getter_AddRefs(originalTarget));
  NS_ENSURE_STATE(originalTarget);

  nsString origElementId;
  nsCOMPtr<nsIDOMElement> origElement(do_QueryInterface(originalTarget));
  if (origElement) {
    origElement->GetAttribute(NS_LITERAL_STRING("id"), origElementId);
    origElement->GetAttribute(NS_LITERAL_STRING("anonid"), targetAnonId);
  }

  nsCOMPtr<nsIDOMEventTarget> target;
  event->GetTarget(getter_AddRefs(target));
  NS_ENSURE_STATE(target);

  nsCOMPtr<nsIDOMElement> targetElement(do_QueryInterface(target));
  if (targetElement) {
    targetElement->GetAttribute(NS_LITERAL_STRING("id"), targetId);
  }

  MS_LOG(("Original Target Id: %s, Original Target Anonid: %s, Target Id: %s",
          NS_ConvertUTF16toUTF8(origElementId).get(),
          NS_ConvertUTF16toUTF8(targetAnonId).get(),
          NS_ConvertUTF16toUTF8(targetId).get()));

  if (targetId.IsEmpty()) {
    // There's nothing useful to log in this case -- even if we have an anonid,
    // it's not possible to determine its position in the document.
    MS_LOG(("Warning: skipping logging because of empty target ID"));
    return NS_ERROR_FAILURE;
  }

  if (origElementId.IsEmpty()) {
    // We're dealing with anonymous content, so don't continue if we didn't
    // find an anonid.
    if (targetAnonId.IsEmpty()) {
      MS_LOG(("Warning: skipping logging because of empty anonid"));
      return NS_ERROR_FAILURE;
    }
  } else {
    // We're dealing with normal explicit content, so don't return an anonid.
    targetAnonId.SetLength(0);
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 408 of file nsUICommandCollector.cpp.

{
  nsCOMPtr<nsIDOMEventTarget> target;
  event->GetTarget(getter_AddRefs(target));
  nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(target);
  if (!targetNode) {
    MS_LOG(("Warning: couldn't get window id because target is not a node"));
    return NS_ERROR_FAILURE;
  }

  *window = nsMetricsUtils::FindWindowForNode(targetNode);
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 203 of file nsUICommandCollector.cpp.

{
  PRUint32 window;
  if (NS_FAILED(GetEventWindow(event, &window))) {
    return NS_OK;
  }

  nsString targetId, targetAnonId;
  if (NS_FAILED(GetEventTargets(event, targetId, targetAnonId))) {
    return NS_OK;
  }
  NS_ASSERTION(!targetId.IsEmpty(), "can't have an empty target id");

  nsString keyId;
  GetEventKeyId(event, keyId);

  // Fill a property bag with what we want to log
  nsCOMPtr<nsIWritablePropertyBag2> properties;
  nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
  NS_ENSURE_STATE(properties);

  nsresult rv;
  rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
                                        NS_LITERAL_STRING("command"));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = SetHashedValue(properties, NS_LITERAL_STRING("targetidhash"), targetId);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!targetAnonId.IsEmpty()) {
    rv = SetHashedValue(properties, NS_LITERAL_STRING("targetanonidhash"),
                        targetAnonId);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  if (!keyId.IsEmpty()) {
    rv = SetHashedValue(properties, NS_LITERAL_STRING("keyidhash"), keyId);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  nsMetricsService *ms = nsMetricsService::get();
  NS_ENSURE_STATE(ms);

  nsCOMPtr<nsIMetricsEventItem> item;
  ms->CreateEventItem(NS_LITERAL_STRING("uielement"), getter_AddRefs(item));
  NS_ENSURE_STATE(item);
  item->SetProperties(properties);

  // Capture extra bookmark state onto the event if the target is a bookmark.
  rv = LogBookmarkInfo(targetId, item);
  NS_ENSURE_SUCCESS(rv, rv);

  // Actually log it
  rv = ms->LogEvent(item);
  NS_ENSURE_SUCCESS(rv, rv);

  MS_LOG(("Successfully logged UI Event"));
  return NS_OK;
}

Here is the call graph for this function:

This method is called whenever an event occurs of the type for which the EventListener interface was registered.

Parameters:
evtThe Event contains contextual information about the event. It also contains the stopPropagation and preventDefault methods which are used in determining the event's flow and default action.

Definition at line 266 of file nsUICommandCollector.cpp.

{
  PRUint32 window;
  if (NS_FAILED(GetEventWindow(event, &window))) {
    return NS_OK;
  }

  // Fill a property bag with what we want to log
  nsCOMPtr<nsIWritablePropertyBag2> properties;
  nsMetricsUtils::NewPropertyBag(getter_AddRefs(properties));
  NS_ENSURE_STATE(properties);

  nsresult rv;
  rv = properties->SetPropertyAsUint32(NS_LITERAL_STRING("window"), window);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = properties->SetPropertyAsAString(NS_LITERAL_STRING("action"),
                                        NS_LITERAL_STRING("comand"));
  NS_ENSURE_SUCCESS(rv, rv);

  // TabMove events just have a dummy target id of "TabMove_Event".
  rv = SetHashedValue(properties, NS_LITERAL_STRING("targetidhash"),
                      NS_LITERAL_STRING("TabMove_Event"));
  NS_ENSURE_SUCCESS(rv, rv);

  nsMetricsService *ms = nsMetricsService::get();
  NS_ENSURE_STATE(ms);

  rv = ms->LogEvent(NS_LITERAL_STRING("uielement"), properties);
  NS_ENSURE_SUCCESS(rv, rv);

  MS_LOG(("Successfully logged UI Event"));
  return NS_OK;
}

Here is the call graph for this function:

Definition at line 473 of file nsUICommandCollector.cpp.

{
#ifdef MOZ_PLACES
  // TODO: write me!
  return NS_OK;

#else

  // First check whether this is an anonymous RDF id.
  // If it's not, we know it's not a bookmark id at all.
  if (!StringHead(id, strlen("rdf:")).Equals(NS_LITERAL_STRING("rdf:"))) {
    return NS_OK;
  }

  nsCOMPtr<nsIRDFService> rdfSvc =
    do_GetService("@mozilla.org/rdf/rdf-service;1");
  NS_ENSURE_STATE(rdfSvc);

  nsCOMPtr<nsIRDFResource> targetResource;
  rdfSvc->GetUnicodeResource(id, getter_AddRefs(targetResource));
  NS_ENSURE_STATE(targetResource);

  nsCOMPtr<nsIWritablePropertyBag2> bmProps;
  nsMetricsUtils::NewPropertyBag(getter_AddRefs(bmProps));
  NS_ENSURE_STATE(bmProps);

  nsCOMPtr<nsIBookmarksService> bmSvc =
    do_GetService(NS_BOOKMARKS_SERVICE_CONTRACTID);
  NS_ENSURE_STATE(bmSvc);

  nsCOMPtr<nsIArray> parentChain;
  bmSvc->GetParentChain(targetResource, getter_AddRefs(parentChain));
  NS_ENSURE_STATE(parentChain);

  PRUint32 depth = 0;
  parentChain->GetLength(&depth);
  bmProps->SetPropertyAsInt32(NS_LITERAL_STRING("depth"), depth);
  if (depth == 0) {
    // Hm, an event on the bookmarks root?  Not much to log in this case.
    return NS_OK;
  }

  nsCOMPtr<nsIRDFDataSource> bmDS =
    do_GetService(NS_BOOKMARKS_DATASOURCE_CONTRACTID);
  NS_ENSURE_STATE(bmDS);

  // Find the bookmark's position in its parent folder.
  // do_QueryElementAt() isn't a frozen export :-(
  nsCOMPtr<nsIRDFResource> parent;
  parentChain->QueryElementAt(depth - 1, NS_GET_IID(nsIRDFResource),
                              getter_AddRefs(parent));
  NS_ENSURE_STATE(parent);

  nsCOMPtr<nsIRDFContainer> container =
    do_CreateInstance("@mozilla.org/rdf/container;1");
  NS_ENSURE_STATE(container);

  nsresult rv = container->Init(bmDS, parent);
  NS_ENSURE_SUCCESS(rv, rv);

  PRInt32 pos;
  rv = container->IndexOf(targetResource, &pos);
  NS_ENSURE_SUCCESS(rv, rv);
  if (pos == -1) {
    MS_LOG(("Bookmark not contained in its parent?"));
  } else {
    bmProps->SetPropertyAsInt32(NS_LITERAL_STRING("pos"), pos);
  }

  // Determine whether the bookmark is under the toolbar folder
  PRBool isToolbarBM = PR_FALSE;
  nsCOMPtr<nsIRDFResource> toolbarFolder;
  bmSvc->GetBookmarksToolbarFolder(getter_AddRefs(toolbarFolder));
  if (toolbarFolder) {
    // Since the user can designate any folder as the toolbar folder,
    // we must walk the entire parent chain looking for it.
    for (PRUint32 i = 0; i < depth; ++i) {
      nsCOMPtr<nsIRDFResource> item;
      parentChain->QueryElementAt(i, NS_GET_IID(nsIRDFResource),
                                  getter_AddRefs(item));
      if (toolbarFolder == item) {
        isToolbarBM = PR_TRUE;
        break;
      }
    }
  }
  bmProps->SetPropertyAsBool(NS_LITERAL_STRING("toolbar"), isToolbarBM);

  return nsMetricsUtils::AddChildItem(parentItem,
                                      NS_LITERAL_STRING("bookmark"), bmProps);
#endif  // MOZ_PLACES
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.

Notification that this collector should be enabled.

The collector should register itself for observer and event notifications as necessary.

Notification that this collector is no longer enabled.

The collector should unregister itself from observer and event notifications so that the object can be freed.

Notification that the MetricsService is starting a new event log.

This happens after any onDetach() notifications that result from parsing the new configuration.

Definition at line 87 of file nsUICommandCollector.cpp.

{
  nsCOMPtr<nsIDOMEventTarget> windowTarget =
    do_QueryInterface(NS_CONST_CAST(nsIDOMWindow *, key));
  if (!windowTarget) {
    MS_LOG(("Error casting domeventtarget"));
    return PL_DHASH_NEXT;
  }

  nsUICommandCollector* collector = NS_STATIC_CAST(nsUICommandCollector*,
                                                   userArg);
  collector->RemoveEventListeners(windowTarget);
  return PL_DHASH_NEXT;
}

Here is the call graph for this function:

Definition at line 443 of file nsUICommandCollector.cpp.

{
  for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(kEvents); ++i) {
    // Using NS_LITERAL_STRING in const data is not allowed, so convert here.
    // This is not performance-sensitive.
    nsresult rv;
    rv = window->RemoveEventListener(NS_ConvertASCIItoUTF16(kEvents[i].event),
                                     this, PR_TRUE);
    if (NS_FAILED(rv)) {
      MS_LOG(("Couldn't remove event listener %s", kEvents[i]));
    }
  }
}

Here is the caller graph for this function:

nsresult nsUICommandCollector::SetHashedValue ( nsIWritablePropertyBag2 properties,
const nsString propertyName,
const nsString propertyValue 
) const [private]

Definition at line 458 of file nsUICommandCollector.cpp.

{
  nsMetricsService *ms = nsMetricsService::get();
  NS_ENSURE_STATE(ms);

  nsCString hashedValue;
  nsresult rv = ms->HashUTF16(propertyValue, hashedValue);
  NS_ENSURE_SUCCESS(rv, rv);

  return properties->SetPropertyAsACString(propertyName, hashedValue);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Initial value:

Definition at line 92 of file nsUICommandCollector.h.


The documentation for this class was generated from the following files: