void KeyboardEvent::GetInitDict(KeyboardEventInit& aParam) { GetKey(aParam.mKey); GetCode(aParam.mCode); aParam.mLocation = Location(); aParam.mRepeat = Repeat(); aParam.mIsComposing = IsComposing(); // legacy attributes aParam.mKeyCode = KeyCode(); aParam.mCharCode = CharCode(); aParam.mWhich = Which(); // modifiers from EventModifierInit aParam.mCtrlKey = CtrlKey(); aParam.mShiftKey = ShiftKey(); aParam.mAltKey = AltKey(); aParam.mMetaKey = MetaKey(); WidgetKeyboardEvent* internalEvent = mEvent->AsKeyboardEvent(); aParam.mModifierAltGraph = internalEvent->IsAltGraph(); aParam.mModifierCapsLock = internalEvent->IsCapsLocked(); aParam.mModifierFn = internalEvent->IsFn(); aParam.mModifierFnLock = internalEvent->IsFnLocked(); aParam.mModifierNumLock = internalEvent->IsNumLocked(); aParam.mModifierOS = internalEvent->IsOS(); aParam.mModifierScrollLock = internalEvent->IsScrollLocked(); aParam.mModifierSymbol = internalEvent->IsSymbol(); aParam.mModifierSymbolLock = internalEvent->IsSymbolLocked(); // EventInit aParam.mBubbles = internalEvent->mFlags.mBubbles; aParam.mCancelable = internalEvent->mFlags.mCancelable; }
bool nsXBLKeyEventHandler::ExecuteMatchedHandlers( nsIDOMKeyEvent* aKeyEvent, uint32_t aCharCode, const IgnoreModifierState& aIgnoreModifierState) { WidgetEvent* event = aKeyEvent->GetInternalNSEvent(); nsCOMPtr<EventTarget> target = aKeyEvent->InternalDOMEvent()->GetCurrentTarget(); bool executed = false; for (uint32_t i = 0; i < mProtoHandlers.Length(); ++i) { nsXBLPrototypeHandler* handler = mProtoHandlers[i]; bool hasAllowUntrustedAttr = handler->HasAllowUntrustedAttr(); if ((event->mFlags.mIsTrusted || (hasAllowUntrustedAttr && handler->AllowUntrustedEvents()) || (!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingContentXBLScope)) && handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreModifierState)) { handler->ExecuteHandler(target, aKeyEvent); executed = true; } } #ifdef XP_WIN // Windows native applications ignore Windows-Logo key state when checking // shortcut keys even if the key is pressed. Therefore, if there is no // shortcut key which exactly matches current modifier state, we should // retry to look for a shortcut key without the Windows-Logo key press. if (!executed && !aIgnoreModifierState.mOS) { WidgetKeyboardEvent* keyEvent = event->AsKeyboardEvent(); if (keyEvent && keyEvent->IsOS()) { IgnoreModifierState ignoreModifierState(aIgnoreModifierState); ignoreModifierState.mOS = true; return ExecuteMatchedHandlers(aKeyEvent, aCharCode, ignoreModifierState); } } #endif return executed; }
bool nsXBLWindowKeyHandler::WalkHandlersAndExecute( nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, nsXBLPrototypeHandler* aHandler, uint32_t aCharCode, const IgnoreModifierState& aIgnoreModifierState, bool aExecute, bool* aOutReservedForChrome) { nsresult rv; // Try all of the handlers until we find one that matches the event. for (nsXBLPrototypeHandler *currHandler = aHandler; currHandler; currHandler = currHandler->GetNextHandler()) { bool stopped = aKeyEvent->AsEvent()->IsDispatchStopped(); if (stopped) { // The event is finished, don't execute any more handlers return false; } if (!EventMatched(currHandler, aEventType, aKeyEvent, aCharCode, aIgnoreModifierState)) { continue; // try the next one } // Before executing this handler, check that it's not disabled, // and that it has something to do (oncommand of the <key> or its // <command> is non-empty). nsCOMPtr<nsIContent> elt = currHandler->GetHandlerElement(); nsCOMPtr<Element> commandElt; // See if we're in a XUL doc. nsCOMPtr<Element> el = GetElement(); if (el && elt) { // We are. Obtain our command attribute. nsAutoString command; elt->GetAttr(kNameSpaceID_None, nsGkAtoms::command, command); if (!command.IsEmpty()) { // Locate the command element in question. Note that we // know "elt" is in a doc if we're dealing with it here. NS_ASSERTION(elt->IsInDoc(), "elt must be in document"); nsIDocument *doc = elt->GetCurrentDoc(); if (doc) commandElt = do_QueryInterface(doc->GetElementById(command)); if (!commandElt) { NS_ERROR("A XUL <key> is observing a command that doesn't exist. Unable to execute key binding!"); continue; } } } if (!commandElt) { commandElt = do_QueryInterface(elt); } if (commandElt) { nsAutoString value; commandElt->GetAttribute(NS_LITERAL_STRING("disabled"), value); if (value.EqualsLiteral("true")) { continue; // this handler is disabled, try the next one } // Check that there is an oncommand handler commandElt->GetAttribute(NS_LITERAL_STRING("oncommand"), value); if (value.IsEmpty()) { continue; // nothing to do } if (aOutReservedForChrome) { // The caller wants to know if this is a reserved command commandElt->GetAttribute(NS_LITERAL_STRING("reserved"), value); *aOutReservedForChrome = value.EqualsLiteral("true"); } } nsCOMPtr<EventTarget> piTarget; nsCOMPtr<Element> element = GetElement(); if (element) { piTarget = commandElt; } else { piTarget = mTarget; } if (!aExecute) { return true; } rv = currHandler->ExecuteHandler(piTarget, aKeyEvent->AsEvent()); if (NS_SUCCEEDED(rv)) { return true; } } #ifdef XP_WIN // Windows native applications ignore Windows-Logo key state when checking // shortcut keys even if the key is pressed. Therefore, if there is no // shortcut key which exactly matches current modifier state, we should // retry to look for a shortcut key without the Windows-Logo key press. if (!aIgnoreModifierState.mOS) { WidgetKeyboardEvent* keyEvent = aKeyEvent->AsEvent()->GetInternalNSEvent()->AsKeyboardEvent(); if (keyEvent && keyEvent->IsOS()) { IgnoreModifierState ignoreModifierState(aIgnoreModifierState); ignoreModifierState.mOS = true; return WalkHandlersAndExecute(aKeyEvent, aEventType, aHandler, aCharCode, ignoreModifierState, aExecute); } } #endif return false; }
bool nsXBLWindowKeyHandler::WalkHandlersAndExecute( nsIDOMKeyEvent* aKeyEvent, nsIAtom* aEventType, nsXBLPrototypeHandler* aFirstHandler, uint32_t aCharCode, const IgnoreModifierState& aIgnoreModifierState, bool aExecute, bool* aOutReservedForChrome) { // Try all of the handlers until we find one that matches the event. for (nsXBLPrototypeHandler* handler = aFirstHandler; handler; handler = handler->GetNextHandler()) { bool stopped = aKeyEvent->AsEvent()->IsDispatchStopped(); if (stopped) { // The event is finished, don't execute any more handlers return false; } if (aExecute) { // If it's executing matched handlers, the event type should exactly be // matched. if (!handler->EventTypeEquals(aEventType)) { continue; } } else { if (handler->EventTypeEquals(nsGkAtoms::keypress)) { // If the handler is a keypress event handler, we also need to check // if coming keydown event is a preceding event of reserved key // combination because if default action of a keydown event is // prevented, following keypress event won't be fired. However, if // following keypress event is reserved, we shouldn't allow web // contents to prevent the default of the preceding keydown event. if (aEventType != nsGkAtoms::keydown && aEventType != nsGkAtoms::keypress) { continue; } } else if (!handler->EventTypeEquals(aEventType)) { // Otherwise, aEventType should exactly be matched. continue; } } // Check if the keyboard event *may* execute the handler. if (!handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreModifierState)) { continue; // try the next one } // Before executing this handler, check that it's not disabled, // and that it has something to do (oncommand of the <key> or its // <command> is non-empty). nsCOMPtr<Element> commandElement; if (!GetElementForHandler(handler, getter_AddRefs(commandElement))) { continue; } bool isReserved = false; if (commandElement) { if (!IsExecutableElement(commandElement)) { continue; } isReserved = commandElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::reserved, nsGkAtoms::_true, eCaseMatters); if (aOutReservedForChrome) { *aOutReservedForChrome = isReserved; } } if (!aExecute) { if (handler->EventTypeEquals(aEventType)) { return true; } // If the command is reserved and the event is keydown, check also if // the handler is for keypress because if following keypress event is // reserved, we shouldn't dispatch the event into web contents. if (isReserved && aEventType == nsGkAtoms::keydown && handler->EventTypeEquals(nsGkAtoms::keypress)) { return true; } // Otherwise, we've not found a handler for the event yet. continue; } nsCOMPtr<EventTarget> target; nsCOMPtr<Element> chromeHandlerElement = GetElement(); if (chromeHandlerElement) { // XXX commandElement may be nullptr... target = commandElement; } else { target = mTarget; } // XXX Do we execute only one handler even if the handler neither stops // propagation nor prevents default of the event? nsresult rv = handler->ExecuteHandler(target, aKeyEvent->AsEvent()); if (NS_SUCCEEDED(rv)) { return true; } } #ifdef XP_WIN // Windows native applications ignore Windows-Logo key state when checking // shortcut keys even if the key is pressed. Therefore, if there is no // shortcut key which exactly matches current modifier state, we should // retry to look for a shortcut key without the Windows-Logo key press. if (!aIgnoreModifierState.mOS) { WidgetKeyboardEvent* keyEvent = aKeyEvent->AsEvent()->WidgetEventPtr()->AsKeyboardEvent(); if (keyEvent && keyEvent->IsOS()) { IgnoreModifierState ignoreModifierState(aIgnoreModifierState); ignoreModifierState.mOS = true; return WalkHandlersAndExecute(aKeyEvent, aEventType, aFirstHandler, aCharCode, ignoreModifierState, aExecute); } } #endif return false; }