(linkMatched, userMightOverType)
| 694 | // not contain the matched link, and may or may not have the focus. The resulting four cases are |
| 695 | // accounted for here by selectively pushing the appropriate HintCoordinator.onExit handlers. |
| 696 | activateLink(linkMatched, userMightOverType) { |
| 697 | let clickEl; |
| 698 | if (userMightOverType == null) { |
| 699 | userMightOverType = false; |
| 700 | } |
| 701 | this.removeHintMarkers(); |
| 702 | |
| 703 | if (linkMatched.isLocalMarker()) { |
| 704 | const localHint = linkMatched.localHint; |
| 705 | clickEl = localHint.element; |
| 706 | HintCoordinator.onExit.push((isSuccess) => { |
| 707 | if (isSuccess) { |
| 708 | if (localHint.reason === "Frame.") { |
| 709 | return Utils.nextTick(() => focusThisFrame({ highlight: true })); |
| 710 | } else if (localHint.reason === "Scroll.") { |
| 711 | // Tell the scroller that this is the activated element. |
| 712 | return handlerStack.bubbleEvent(Utils.isFirefox() ? "click" : "DOMActivate", { |
| 713 | target: clickEl, |
| 714 | }); |
| 715 | } else if (localHint.reason === "Open.") { |
| 716 | return clickEl.open = !clickEl.open; |
| 717 | } else if (DomUtils.isSelectable(clickEl)) { |
| 718 | globalThis.focus(); |
| 719 | return DomUtils.simulateSelect(clickEl); |
| 720 | } else { |
| 721 | const clickActivator = (modifiers) => (link) => DomUtils.simulateClick(link, modifiers); |
| 722 | const linkActivator = this.mode.linkActivator != null |
| 723 | ? this.mode.linkActivator |
| 724 | : clickActivator(this.mode.clickModifiers); |
| 725 | // Note(gdh1995): Here we should allow special elements to get focus, |
| 726 | // <select>: latest Chrome refuses `mousedown` event, and we can only focus it to let |
| 727 | // user press space to activate the popup menu |
| 728 | // <object> & <embed>: for Flash games which have their own key event handlers since we |
| 729 | // have been able to blur them by pressing `Escape` |
| 730 | if (["input", "select", "object", "embed"].includes(clickEl.nodeName.toLowerCase())) { |
| 731 | clickEl.focus(); |
| 732 | } |
| 733 | HintCoordinator.lastClickedElementRef = new WeakRef(clickEl); |
| 734 | return linkActivator(clickEl); |
| 735 | } |
| 736 | } |
| 737 | }); |
| 738 | } |
| 739 | |
| 740 | // If flash elements are created, then this function can be used later to remove them. |
| 741 | let removeFlashElements = function () {}; |
| 742 | if (linkMatched.isLocalMarker()) { |
| 743 | const { top: viewportTop, left: viewportLeft } = DomUtils.getViewportTopLeft(); |
| 744 | const flashElements = Array.from(clickEl.getClientRects()).map((rect) => |
| 745 | DomUtils.addFlashRect(Rect.translate(rect, viewportLeft, viewportTop)) |
| 746 | ); |
| 747 | removeFlashElements = () => flashElements.map((flashEl) => DomUtils.removeElement(flashEl)); |
| 748 | } |
| 749 | |
| 750 | // If we're using a keyboard blocker, then the frame with the focus sends the "exit" message, |
| 751 | // otherwise the frame containing the matched link does. |
| 752 | if (userMightOverType) { |
| 753 | HintCoordinator.onExit.push(removeFlashElements); |
no test coverage detected