зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1077574 - Add current and total counts to Find-in-page, r=wesj
This commit is contained in:
Родитель
f05da90fab
Коммит
178bbc9e00
|
@ -5,6 +5,8 @@
|
||||||
package org.mozilla.gecko;
|
package org.mozilla.gecko;
|
||||||
|
|
||||||
import org.mozilla.gecko.util.GeckoEventListener;
|
import org.mozilla.gecko.util.GeckoEventListener;
|
||||||
|
import org.mozilla.gecko.util.GeckoRequest;
|
||||||
|
import org.mozilla.gecko.util.NativeJSObject;
|
||||||
import org.mozilla.gecko.util.ThreadUtils;
|
import org.mozilla.gecko.util.ThreadUtils;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -19,12 +21,14 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener {
|
public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener {
|
||||||
private static final String REQUEST_ID = "FindInPageBar";
|
private static final String REQUEST_ID = "FindInPageBar";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private CustomEditText mFindText;
|
private CustomEditText mFindText;
|
||||||
|
private TextView mStatusText;
|
||||||
private boolean mInflated;
|
private boolean mInflated;
|
||||||
|
|
||||||
public FindInPageBar(Context context, AttributeSet attrs) {
|
public FindInPageBar(Context context, AttributeSet attrs) {
|
||||||
|
@ -58,6 +62,8 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mStatusText = (TextView) content.findViewById(R.id.find_status);
|
||||||
|
|
||||||
mInflated = true;
|
mInflated = true;
|
||||||
EventDispatcher.getInstance().registerGeckoThreadListener(this, "TextSelection:Data");
|
EventDispatcher.getInstance().registerGeckoThreadListener(this, "TextSelection:Data");
|
||||||
}
|
}
|
||||||
|
@ -71,6 +77,7 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||||
|
|
||||||
// handleMessage() receives response message and determines initial state of softInput
|
// handleMessage() receives response message and determines initial state of softInput
|
||||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("TextSelection:Get", REQUEST_ID));
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("TextSelection:Get", REQUEST_ID));
|
||||||
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Opened", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
@ -95,7 +102,7 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Find", s.toString()));
|
sendRequestToFinderHelper("FindInPage:Find", s.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,13 +122,13 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||||
final int viewId = v.getId();
|
final int viewId = v.getId();
|
||||||
|
|
||||||
if (viewId == R.id.find_prev) {
|
if (viewId == R.id.find_prev) {
|
||||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Prev", mFindText.getText().toString()));
|
sendRequestToFinderHelper("FindInPage:Prev", mFindText.getText().toString());
|
||||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewId == R.id.find_next) {
|
if (viewId == R.id.find_next) {
|
||||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Next", mFindText.getText().toString()));
|
sendRequestToFinderHelper("FindInPage:Next", mFindText.getText().toString());
|
||||||
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -170,4 +177,28 @@ public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnC
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request find operation, and update matchCount results (current count and total).
|
||||||
|
*/
|
||||||
|
private void sendRequestToFinderHelper(String request, String searchString) {
|
||||||
|
GeckoAppShell.sendRequestToGecko(new GeckoRequest(request, searchString) {
|
||||||
|
@Override
|
||||||
|
public void onResponse(NativeJSObject nativeJSObject) {
|
||||||
|
final int total = nativeJSObject.optInt("total", 0);
|
||||||
|
final int current = nativeJSObject.optInt("current", 0);
|
||||||
|
|
||||||
|
final Boolean statusVisibility = (total > 0);
|
||||||
|
final String statusText = current + "/" + total;
|
||||||
|
|
||||||
|
ThreadUtils.postToUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mStatusText.setVisibility(statusVisibility ? View.VISIBLE : View.GONE);
|
||||||
|
mStatusText.setText(statusText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,34 +6,44 @@
|
||||||
android:layout_width="0dip"
|
android:layout_width="0dip"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1.0"
|
android:layout_weight="1.0"
|
||||||
android:layout_marginLeft="5dip"
|
android:layout_marginLeft="@dimen/find_in_page_text_margin_left"
|
||||||
android:layout_marginRight="5dip"
|
android:layout_marginRight="@dimen/find_in_page_text_margin_right"
|
||||||
android:contentDescription="@string/find_text"
|
android:contentDescription="@string/find_text"
|
||||||
android:background="@drawable/url_bar_entry"
|
android:background="@drawable/url_bar_entry"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:textColor="#000000"
|
android:textColor="#000000"
|
||||||
android:textCursorDrawable="@null"
|
android:textCursorDrawable="@null"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:paddingLeft="15dip"
|
android:paddingLeft="@dimen/find_in_page_text_padding_left"
|
||||||
android:paddingRight="15dip"
|
android:paddingRight="@dimen/find_in_page_text_padding_right"
|
||||||
android:textColorHighlight="@color/url_bar_text_highlight"
|
android:textColorHighlight="@color/url_bar_text_highlight"
|
||||||
android:imeOptions="actionSearch"
|
android:imeOptions="actionSearch"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:gravity="center_vertical|left"/>
|
android:gravity="center_vertical|left"/>
|
||||||
|
|
||||||
|
<TextView android:id="@+id/find_status"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginRight="@dimen/find_in_page_status_margin_right"
|
||||||
|
android:textColor="@color/find_status_default"
|
||||||
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/find_prev"
|
<ImageButton android:id="@+id/find_prev"
|
||||||
style="@style/FindBar.ImageButton"
|
style="@style/FindBar.ImageButton"
|
||||||
android:contentDescription="@string/find_prev"
|
android:contentDescription="@string/find_prev"
|
||||||
|
android:layout_marginTop="@dimen/find_in_page_control_margin_top"
|
||||||
android:src="@drawable/find_prev"/>
|
android:src="@drawable/find_prev"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/find_next"
|
<ImageButton android:id="@+id/find_next"
|
||||||
style="@style/FindBar.ImageButton"
|
style="@style/FindBar.ImageButton"
|
||||||
android:contentDescription="@string/find_next"
|
android:contentDescription="@string/find_next"
|
||||||
|
android:layout_marginTop="@dimen/find_in_page_control_margin_top"
|
||||||
android:src="@drawable/find_next"/>
|
android:src="@drawable/find_next"/>
|
||||||
|
|
||||||
<ImageButton android:id="@+id/find_close"
|
<ImageButton android:id="@+id/find_close"
|
||||||
style="@style/FindBar.ImageButton"
|
style="@style/FindBar.ImageButton"
|
||||||
android:contentDescription="@string/find_close"
|
android:contentDescription="@string/find_close"
|
||||||
|
android:layout_marginTop="@dimen/find_in_page_control_margin_top"
|
||||||
android:src="@drawable/find_close"/>
|
android:src="@drawable/find_close"/>
|
||||||
|
|
||||||
</merge>
|
</merge>
|
||||||
|
|
|
@ -137,4 +137,8 @@
|
||||||
<color name="toast_button_background">#00000000</color>
|
<color name="toast_button_background">#00000000</color>
|
||||||
<color name="toast_button_pressed">#DD2C3136</color>
|
<color name="toast_button_pressed">#DD2C3136</color>
|
||||||
<color name="toast_button_text">#FFFFFFFF</color>
|
<color name="toast_button_text">#FFFFFFFF</color>
|
||||||
|
|
||||||
|
<!-- Colour used for Find-In-Page dialog -->
|
||||||
|
<color name="find_status_default">#AFB1B3</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -144,4 +144,13 @@
|
||||||
<dimen name="arrow_popup_arrow_width">40dip</dimen>
|
<dimen name="arrow_popup_arrow_width">40dip</dimen>
|
||||||
<dimen name="arrow_popup_arrow_height">12dip</dimen>
|
<dimen name="arrow_popup_arrow_height">12dip</dimen>
|
||||||
<dimen name="arrow_popup_arrow_offset">8dp</dimen>
|
<dimen name="arrow_popup_arrow_offset">8dp</dimen>
|
||||||
|
|
||||||
|
<!-- Find-In-Page dialog dimensions. -->
|
||||||
|
<dimen name="find_in_page_text_margin_left">5dip</dimen>
|
||||||
|
<dimen name="find_in_page_text_margin_right">12dip</dimen>
|
||||||
|
<dimen name="find_in_page_text_padding_left">10dip</dimen>
|
||||||
|
<dimen name="find_in_page_text_padding_right">10dip</dimen>
|
||||||
|
<dimen name="find_in_page_status_margin_right">5dip</dimen>
|
||||||
|
<dimen name="find_in_page_control_margin_top">2dip</dimen>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -8,35 +8,100 @@ var FindHelper = {
|
||||||
_targetTab: null,
|
_targetTab: null,
|
||||||
_initialViewport: null,
|
_initialViewport: null,
|
||||||
_viewportChanged: false,
|
_viewportChanged: false,
|
||||||
|
_matchesCountResult: null,
|
||||||
|
|
||||||
observe: function(aMessage, aTopic, aData) {
|
observe: function(aMessage, aTopic, aData) {
|
||||||
switch(aTopic) {
|
switch(aTopic) {
|
||||||
case "FindInPage:Find":
|
case "FindInPage:Opened": {
|
||||||
this.doFind(aData);
|
this._findOpened();
|
||||||
|
this._init();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "FindInPage:Prev":
|
case "Tab:Selected": {
|
||||||
this.findAgain(aData, true);
|
// Allow for page switching.
|
||||||
|
this._uninit();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "FindInPage:Next":
|
|
||||||
this.findAgain(aData, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "Tab:Selected":
|
|
||||||
case "FindInPage:Closed":
|
case "FindInPage:Closed":
|
||||||
this.findClosed();
|
this._uninit();
|
||||||
|
this._findClosed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_findOpened: function() {
|
||||||
|
Messaging.addListener((data) => {
|
||||||
|
this.doFind(data);
|
||||||
|
return this._getMatchesCountResult(data);
|
||||||
|
}, "FindInPage:Find");
|
||||||
|
|
||||||
|
Messaging.addListener((data) => {
|
||||||
|
this.findAgain(data, false);
|
||||||
|
return this._getMatchesCountResult(data);
|
||||||
|
}, "FindInPage:Next");
|
||||||
|
|
||||||
|
Messaging.addListener((data) => {
|
||||||
|
this.findAgain(data, true);
|
||||||
|
return this._getMatchesCountResult(data);
|
||||||
|
}, "FindInPage:Prev");
|
||||||
|
},
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
// If there's no find in progress, start one.
|
||||||
|
if (this._finder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._targetTab = BrowserApp.selectedTab;
|
||||||
|
this._finder = this._targetTab.browser.finder;
|
||||||
|
this._finder.addResultListener(this);
|
||||||
|
this._initialViewport = JSON.stringify(this._targetTab.getViewport());
|
||||||
|
this._viewportChanged = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_uninit: function() {
|
||||||
|
// If there's no find in progress, there's nothing to clean up.
|
||||||
|
if (!this._finder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._finder.removeSelection();
|
||||||
|
this._finder.removeResultListener(this);
|
||||||
|
this._finder = null;
|
||||||
|
this._targetTab = null;
|
||||||
|
this._initialViewport = null;
|
||||||
|
this._viewportChanged = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_findClosed: function() {
|
||||||
|
Messaging.removeListener("FindInPage:Find");
|
||||||
|
Messaging.removeListener("FindInPage:Next");
|
||||||
|
Messaging.removeListener("FindInPage:Prev");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request, wait for, and return the current matchesCount results for a string.
|
||||||
|
*/
|
||||||
|
_getMatchesCountResult: function(findString) {
|
||||||
|
// Sync call to Finder, results available immediately.
|
||||||
|
this._matchesCountResult = null;
|
||||||
|
this._finder.requestMatchesCount(findString);
|
||||||
|
|
||||||
|
return this._matchesCountResult;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pass along the count results to FindInPageBar for display.
|
||||||
|
*/
|
||||||
|
onMatchesCountResult: function(result) {
|
||||||
|
this._matchesCountResult = result;
|
||||||
|
},
|
||||||
|
|
||||||
doFind: function(aSearchString) {
|
doFind: function(aSearchString) {
|
||||||
if (!this._finder) {
|
if (!this._finder) {
|
||||||
this._targetTab = BrowserApp.selectedTab;
|
this._init();
|
||||||
this._finder = this._targetTab.browser.finder;
|
|
||||||
this._finder.addResultListener(this);
|
|
||||||
this._initialViewport = JSON.stringify(this._targetTab.getViewport());
|
|
||||||
this._viewportChanged = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._finder.fastFind(aSearchString, false);
|
this._finder.fastFind(aSearchString, false);
|
||||||
|
@ -52,19 +117,6 @@ var FindHelper = {
|
||||||
this._finder.findAgain(aFindBackwards, false, false);
|
this._finder.findAgain(aFindBackwards, false, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
findClosed: function() {
|
|
||||||
// If there's no find in progress, there's nothing to clean up
|
|
||||||
if (!this._finder)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._finder.removeSelection();
|
|
||||||
this._finder.removeResultListener(this);
|
|
||||||
this._finder = null;
|
|
||||||
this._targetTab = null;
|
|
||||||
this._initialViewport = null;
|
|
||||||
this._viewportChanged = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
onFindResult: function(aData) {
|
onFindResult: function(aData) {
|
||||||
if (aData.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
|
if (aData.result == Ci.nsITypeAheadFind.FIND_NOTFOUND) {
|
||||||
if (this._viewportChanged) {
|
if (this._viewportChanged) {
|
||||||
|
|
|
@ -127,7 +127,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "SharedPreferences",
|
||||||
#endif
|
#endif
|
||||||
["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
|
["MemoryObserver", ["memory-pressure", "Memory:Dump"], "chrome://browser/content/MemoryObserver.js"],
|
||||||
["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
|
["ConsoleAPI", ["console-api-log-event"], "chrome://browser/content/ConsoleAPI.js"],
|
||||||
["FindHelper", ["FindInPage:Find", "FindInPage:Prev", "FindInPage:Next", "FindInPage:Closed", "Tab:Selected"], "chrome://browser/content/FindHelper.js"],
|
["FindHelper", ["FindInPage:Opened", "FindInPage:Closed", "Tab:Selected"], "chrome://browser/content/FindHelper.js"],
|
||||||
["PermissionsHelper", ["Permissions:Get", "Permissions:Clear"], "chrome://browser/content/PermissionsHelper.js"],
|
["PermissionsHelper", ["Permissions:Get", "Permissions:Clear"], "chrome://browser/content/PermissionsHelper.js"],
|
||||||
["FeedHandler", ["Feeds:Subscribe"], "chrome://browser/content/FeedHandler.js"],
|
["FeedHandler", ["Feeds:Subscribe"], "chrome://browser/content/FeedHandler.js"],
|
||||||
["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"],
|
["Feedback", ["Feedback:Show"], "chrome://browser/content/Feedback.js"],
|
||||||
|
|
Загрузка…
Ссылка в новой задаче