diff options
| -rw-r--r-- | background_scripts/main.coffee | 34 | ||||
| -rw-r--r-- | content_scripts/link_hints.coffee | 8 | ||||
| -rw-r--r-- | tests/dom_tests/dom_tests.coffee | 4 | 
3 files changed, 31 insertions, 15 deletions
| diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index 829b0abb..5c6e8e19 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -355,34 +355,44 @@ HintCoordinator =        # If there's no handler here, then the message is forwarded to all frames in the sender's tab.        @sendMessage request.messageType, tabId, request +  # Post a link-hints message to a particular frame's port. We catch errors in case the frame has gone away. +  postMessage: (tabId, frameId, messageType, port, request = {}) -> +    try +      port.postMessage extend request, {handler: "linkHintsMessage", messageType} +    catch +      @unregisterFrame tabId, frameId + +  # Post a link-hints message to all participating frames.    sendMessage: (messageType, tabId, request = {}) -> -    extend request, {handler: "linkHintsMessage", messageType}      for own frameId, port of @tabState[tabId].ports -      try -        port.postMessage request -      catch -        @unregisterFrame tabId, parseInt frameId +      @postMessage tabId, parseInt(frameId), messageType, port, request    prepareToActivateMode: (tabId, originatingFrameId, {modeIndex}) -> -    @tabState[tabId] = {frameIds: frameIdsForTab[tabId][..], hintDescriptors: [], originatingFrameId, modeIndex} +    @tabState[tabId] = {frameIds: frameIdsForTab[tabId][..], hintDescriptors: {}, originatingFrameId, modeIndex}      @tabState[tabId].ports = extend {}, portsForTab[tabId]      @sendMessage "getHintDescriptors", tabId, {modeIndex}    # Receive hint descriptors from all frames and activate link-hints mode when we have them all.    postHintDescriptors: (tabId, frameId, {hintDescriptors}) ->      if frameId in @tabState[tabId].frameIds -      @tabState[tabId].hintDescriptors.push hintDescriptors... +      @tabState[tabId].hintDescriptors[frameId] = hintDescriptors        @tabState[tabId].frameIds = @tabState[tabId].frameIds.filter (fId) -> fId != frameId        if @tabState[tabId].frameIds.length == 0 -        @sendMessage "activateMode", tabId, -          originatingFrameId: @tabState[tabId].originatingFrameId -          hintDescriptors: @tabState[tabId].hintDescriptors -          modeIndex: @tabState[tabId].modeIndex +        for own frameId, port of @tabState[tabId].ports +          if frameId of @tabState[tabId].hintDescriptors +            hintDescriptors = extend {}, @tabState[tabId].hintDescriptors +            # We do not send back the frame's own hint descriptors.  This is faster (approx. speedup 3/2) for +            # link-busy sites like reddit. +            delete hintDescriptors[frameId] +            @postMessage tabId, parseInt(frameId), "activateMode", port, +              originatingFrameId: @tabState[tabId].originatingFrameId +              hintDescriptors: hintDescriptors +              modeIndex: @tabState[tabId].modeIndex    # If an unregistering frame is participating in link-hints mode, then we need to tidy up after it.    unregisterFrame: (tabId, frameId) ->      delete @tabState[tabId]?.ports?[frameId] -    # We fake "postHintDescriptors" for an unregistering frame, if necessary. +    # We fake "postHintDescriptors" for an unregistering frame.      @postHintDescriptors tabId, frameId, hintDescriptors: [] if @tabState[tabId]?.frameIds  # Port handler mapping diff --git a/content_scripts/link_hints.coffee b/content_scripts/link_hints.coffee index 89875da0..c012edba 100644 --- a/content_scripts/link_hints.coffee +++ b/content_scripts/link_hints.coffee @@ -82,13 +82,17 @@ HintCoordinator =      DomUtils.documentReady => Settings.onLoaded =>        requireHref = availableModes[modeIndex] in [COPY_LINK_URL, OPEN_INCOGNITO]        @localHints = LocalHints.getLocalHints requireHref -      @sendMessage "postHintDescriptors", hintDescriptors: -        @localHints.map ({linkText}, localIndex) -> {frameId, localIndex, linkText} +      @localHintDescriptors = @localHints.map ({linkText}, localIndex) -> {frameId, localIndex, linkText} +      @sendMessage "postHintDescriptors", hintDescriptors: @localHintDescriptors    # We activate LinkHintsMode() in every frame and provide every frame with exactly the same hint descriptors.    # We also propagate the key state between frames.  Therefore, the hint-selection process proceeds in lock    # step in every frame, and @linkHintsMode is in the same state in every frame.    activateMode: ({hintDescriptors, modeIndex, originatingFrameId}) -> +    # We do not receive the frame's own hint descritors back from the background page.  Instead, we merge them +    # with the hint descriptors from other frames here. +    [hintDescriptors[frameId], @localHintDescriptors] = [@localHintDescriptors, null] +    hintDescriptors = [].concat (hintDescriptors[fId] for fId in (fId for own fId of hintDescriptors).sort())...      # Ensure that the document is ready and that the settings are loaded.      DomUtils.documentReady => Settings.onLoaded =>        @suppressKeyboardEvents.exit() if @suppressKeyboardEvents?.modeIsActive diff --git a/tests/dom_tests/dom_tests.coffee b/tests/dom_tests/dom_tests.coffee index 96d95902..75cc5da7 100644 --- a/tests/dom_tests/dom_tests.coffee +++ b/tests/dom_tests/dom_tests.coffee @@ -64,7 +64,9 @@ getHintMarkers = ->  stubSettings = (key, value) -> stub Settings.cache, key, JSON.stringify value  HintCoordinator.sendMessage = (name, request = {}) -> HintCoordinator[name]? request; request -activateLinkHintsMode = -> HintCoordinator.activateMode HintCoordinator.getHintDescriptors {modeIndex: 0} +activateLinkHintsMode = -> +  HintCoordinator.getHintDescriptors modeIndex: 0 +  HintCoordinator.activateMode hintDescriptors: {}, modeIndex: 0, originatingFrameId: frameId,  #  # Generate tests that are common to both default and filtered | 
