Commit d7557a57 authored by joki%netscape.com's avatar joki%netscape.com
Browse files

Adding accesskey support. Bug 959.

parent fbfcb9d9
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -78,8 +78,8 @@ public:
  NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) = 0;

  // Access Key Registration
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, PRUint32 aKey) = 0;
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame) = 0;
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey) = 0;
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey) = 0;

  NS_IMETHOD SetCursor(PRInt32 aCursor, nsIWidget* aWidget, PRBool aLockCursor) = 0;

+84 −10
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ nsEventStateManager::nsEventStateManager()
  mLastWindowToHaveFocus = nsnull;
  mFirstBlurEvent = nsnull;
  mFirstFocusEvent = nsnull;
  mAccessKeys = nsnull;
  NS_INIT_REFCNT();
  
  ++mInstanceCount;
@@ -171,6 +172,10 @@ nsEventStateManager::~nsEventStateManager()
    NS_IF_RELEASE(gLastFocusedDocument);
  }

  if (mAccessKeys) {
    delete mAccessKeys;
  }

  if (!m_haveShutdown) {
    Shutdown();

@@ -584,6 +589,39 @@ nsEventStateManager::PreHandleEvent(nsIPresContext* aPresContext,
    break;
    
  case NS_KEY_PRESS:
    {
      nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
      //This is to prevent keyboard scrolling while alt modifier in use.
      if (keyEvent->isAlt) {
        //Alt key is down, we may need to do an accesskey
        if (mAccessKeys) {
          //Someone registered an accesskey.  Find and activate it.
          nsVoidKey key((void*)keyEvent->charCode);
          if (mAccessKeys->Exists(&key)) {
            nsCOMPtr<nsIContent> content = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));

            //Its hard to say what HTML4 wants us to do in all cases.  So for now we'll settle for
            //A) Set focus
            ChangeFocus(content, nsnull, PR_TRUE);

            //B) Click on it.
            nsEventStatus status = nsEventStatus_eIgnore;
            nsMouseEvent event;
            event.eventStructType = NS_GUI_EVENT;
            event.message = NS_MOUSE_LEFT_CLICK;
            event.isShift = PR_FALSE;
            event.isControl = PR_FALSE;
            event.isAlt = PR_FALSE;
            event.isMeta = PR_FALSE;
            event.clickCount = 0;
            event.widget = nsnull;
            content->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);

            *aStatus = nsEventStatus_eConsumeNoDefault;
          }
        }
      }
    }
  case NS_KEY_DOWN:
  case NS_KEY_UP:
  case NS_MOUSE_SCROLL:
@@ -2328,23 +2366,59 @@ nsEventStateManager::SetFocusedContent(nsIContent* aContent)
// Access Key Registration
//-------------------------------------------
NS_IMETHODIMP
nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, PRUint32 aKey)
nsEventStateManager::RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey)
{
#ifdef DEBUG_rods
  printf("Obj: %p Registered %d [%c]accesskey\n", aFrame, aKey, (char)aKey);
#endif
  if (!mAccessKeys) {
    mAccessKeys = new nsSupportsHashtable();
    if (!mAccessKeys) {
      return NS_ERROR_FAILURE;
    }
  }

  nsCOMPtr<nsIContent> content;
  if (!aContent) {
    aFrame->GetContent(getter_AddRefs(content));
  }
  else {
    content = aContent;
  }

  if (content) {
    nsVoidKey key((void*)aKey);

    nsIContent* oldContent = NS_STATIC_CAST(nsIContent*, mAccessKeys->Put(&key, content));
    NS_IF_RELEASE(oldContent);
  }

  return NS_OK;
}

NS_IMETHODIMP
nsEventStateManager::UnregisterAccessKey(nsIFrame * aFrame)
nsEventStateManager::UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey)
{
#ifdef DEBUG_rods
  printf("Obj: %p Unregistered accesskey\n", aFrame);
#endif
  if (!mAccessKeys) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<nsIContent> content;
  if (!aContent) {
    aFrame->GetContent(getter_AddRefs(content));
  }
  else {
    content = aContent;
  }
  if (content) {
    nsVoidKey key((void*)aKey);

    nsCOMPtr<nsIContent> oldContent = getter_AddRefs(NS_STATIC_CAST(nsIContent*, mAccessKeys->Get(&key)));
    if (oldContent != content) {
      return NS_OK;
    }
    mAccessKeys->Remove(&key);
  }
  return NS_OK;
}

// This function MAY CHANGE the PresContext that you pass into it.  It
// will be changed to the PresContext for the main document.  If the
// new PresContext differs from the one you passed in, you should
+6 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "nsIPref.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsHashTable.h"

class nsIDocument;
class nsIScrollableView;
@@ -93,8 +94,8 @@ public:
  NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) { mConsumeFocusEvents = aDoConsume; return NS_OK; }

  // Access Key Registration
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, PRUint32 aKey);
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame);
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey);
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey);

  NS_IMETHOD SetCursor(PRInt32 aCursor, nsIWidget* aWidget, PRBool aLockCursor);

@@ -182,6 +183,9 @@ protected:
  PRUint32 mMClickCount;
  PRUint32 mRClickCount;

  //Hashtable for accesskey support
  nsSupportsHashtable *mAccessKeys;

  static PRUint32 mInstanceCount;

  // For mousewheel preferences handling
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "nsIFrameManager.h"
#include "nsIPresShell.h"
#include "nsIDocument.h"
#include "nsIHTMLAttributes.h"

// XXX suppress

+2 −2
Original line number Diff line number Diff line
@@ -78,8 +78,8 @@ public:
  NS_IMETHOD ConsumeFocusEvents(PRBool aDoConsume) = 0;

  // Access Key Registration
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, PRUint32 aKey) = 0;
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame) = 0;
  NS_IMETHOD RegisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey) = 0;
  NS_IMETHOD UnregisterAccessKey(nsIFrame * aFrame, nsIContent* aContent, PRUint32 aKey) = 0;

  NS_IMETHOD SetCursor(PRInt32 aCursor, nsIWidget* aWidget, PRBool aLockCursor) = 0;

Loading