1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- 2 * This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 package org.mozilla.geckoview; 7 8 import android.util.Pair; 9 import androidx.annotation.AnyThread; 10 import androidx.annotation.NonNull; 11 import androidx.annotation.Nullable; 12 import java.util.Arrays; 13 import java.util.List; 14 import org.mozilla.gecko.EventDispatcher; 15 import org.mozilla.gecko.util.GeckoBundle; 16 import org.mozilla.geckoview.GeckoSession.FinderDisplayFlags; 17 import org.mozilla.geckoview.GeckoSession.FinderFindFlags; 18 import org.mozilla.geckoview.GeckoSession.FinderResult; 19 20 /** 21 * {@code SessionFinder} instances returned by {@link GeckoSession#getFinder()} performs 22 * find-in-page operations. 23 */ 24 @AnyThread 25 public final class SessionFinder { 26 private static final String LOGTAG = "GeckoSessionFinder"; 27 28 private static final List<Pair<Integer, String>> sFlagNames = 29 Arrays.asList( 30 new Pair<>(GeckoSession.FINDER_FIND_BACKWARDS, "backwards"), 31 new Pair<>(GeckoSession.FINDER_FIND_LINKS_ONLY, "linksOnly"), 32 new Pair<>(GeckoSession.FINDER_FIND_MATCH_CASE, "matchCase"), 33 new Pair<>(GeckoSession.FINDER_FIND_WHOLE_WORD, "wholeWord")); 34 addFlagsToBundle( @inderFindFlags final int flags, @NonNull final GeckoBundle bundle)35 private static void addFlagsToBundle( 36 @FinderFindFlags final int flags, @NonNull final GeckoBundle bundle) { 37 for (final Pair<Integer, String> name : sFlagNames) { 38 if ((flags & name.first) != 0) { 39 bundle.putBoolean(name.second, true); 40 } 41 } 42 } 43 getFlagsFromBundle(@ullable final GeckoBundle bundle)44 /* package */ static int getFlagsFromBundle(@Nullable final GeckoBundle bundle) { 45 if (bundle == null) { 46 return 0; 47 } 48 49 int flags = 0; 50 for (final Pair<Integer, String> name : sFlagNames) { 51 if (bundle.getBoolean(name.second)) { 52 flags |= name.first; 53 } 54 } 55 return flags; 56 } 57 58 private final EventDispatcher mDispatcher; 59 @FinderDisplayFlags private int mDisplayFlags; 60 SessionFinder(@onNull final EventDispatcher dispatcher)61 /* package */ SessionFinder(@NonNull final EventDispatcher dispatcher) { 62 mDispatcher = dispatcher; 63 setDisplayFlags(0); 64 } 65 66 /** 67 * Find and select a string on the current page, starting from the current selection or the start 68 * of the page if there is no selection. Optionally return results related to the search in a 69 * {@link FinderResult} object. If {@code searchString} is null, search is performed using the 70 * previous search string. 71 * 72 * @param searchString String to search, or null to find again using the previous string. 73 * @param flags Flags for performing the search; either 0 or a combination of {@link 74 * GeckoSession#FINDER_FIND_BACKWARDS FINDER_FIND_*} constants. 75 * @return Result of the search operation as a {@link GeckoResult} object. 76 * @see #clear 77 * @see #setDisplayFlags 78 */ 79 @NonNull find( @ullable final String searchString, @FinderFindFlags final int flags)80 public GeckoResult<FinderResult> find( 81 @Nullable final String searchString, @FinderFindFlags final int flags) { 82 final GeckoBundle bundle = new GeckoBundle(sFlagNames.size() + 1); 83 bundle.putString("searchString", searchString); 84 addFlagsToBundle(flags, bundle); 85 86 return mDispatcher 87 .queryBundle("GeckoView:FindInPage", bundle) 88 .map(response -> new FinderResult(response)); 89 } 90 91 /** 92 * Clear any highlighted find-in-page matches. 93 * 94 * @see #find 95 * @see #setDisplayFlags 96 */ clear()97 public void clear() { 98 mDispatcher.dispatch("GeckoView:ClearMatches", null); 99 } 100 101 /** 102 * Return flags for displaying find-in-page matches. 103 * 104 * @return Display flags as a combination of {@link GeckoSession#FINDER_DISPLAY_HIGHLIGHT_ALL 105 * FINDER_DISPLAY_*} constants. 106 * @see #setDisplayFlags 107 * @see #find 108 */ 109 @FinderDisplayFlags getDisplayFlags()110 public int getDisplayFlags() { 111 return mDisplayFlags; 112 } 113 114 /** 115 * Set flags for displaying find-in-page matches. 116 * 117 * @param flags Display flags as a combination of {@link GeckoSession#FINDER_DISPLAY_HIGHLIGHT_ALL 118 * FINDER_DISPLAY_*} constants. 119 * @see #getDisplayFlags 120 * @see #find 121 */ setDisplayFlags(@inderDisplayFlags final int flags)122 public void setDisplayFlags(@FinderDisplayFlags final int flags) { 123 mDisplayFlags = flags; 124 125 final GeckoBundle bundle = new GeckoBundle(3); 126 bundle.putBoolean("highlightAll", (flags & GeckoSession.FINDER_DISPLAY_HIGHLIGHT_ALL) != 0); 127 bundle.putBoolean("dimPage", (flags & GeckoSession.FINDER_DISPLAY_DIM_PAGE) != 0); 128 bundle.putBoolean("drawOutline", (flags & GeckoSession.FINDER_DISPLAY_DRAW_LINK_OUTLINE) != 0); 129 mDispatcher.dispatch("GeckoView:DisplayMatches", bundle); 130 } 131 } 132