2012-05-30 13:26:13 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
2013-07-28 13:36:47 -07:00
|
|
|
import org.mozilla.gecko.util.GeckoEventListener;
|
|
|
|
import org.mozilla.gecko.util.ThreadUtils;
|
|
|
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
2012-05-30 13:26:13 -07:00
|
|
|
import android.content.Context;
|
|
|
|
import android.text.Editable;
|
2013-07-28 13:36:47 -07:00
|
|
|
import android.text.TextUtils;
|
2012-05-30 13:26:13 -07:00
|
|
|
import android.text.TextWatcher;
|
|
|
|
import android.util.AttributeSet;
|
2012-07-11 16:04:49 -07:00
|
|
|
import android.view.KeyEvent;
|
2012-05-30 13:26:13 -07:00
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.View;
|
2012-07-11 16:06:25 -07:00
|
|
|
import android.view.inputmethod.InputMethodManager;
|
2012-06-13 16:21:17 -07:00
|
|
|
import android.widget.LinearLayout;
|
2012-05-30 13:26:13 -07:00
|
|
|
|
2013-07-28 13:36:47 -07:00
|
|
|
public class FindInPageBar extends LinearLayout implements TextWatcher, View.OnClickListener, GeckoEventListener {
|
|
|
|
private static final String REQUEST_ID = "FindInPageBar";
|
2012-05-30 13:26:13 -07:00
|
|
|
|
|
|
|
private final Context mContext;
|
2012-07-11 16:04:49 -07:00
|
|
|
private CustomEditText mFindText;
|
2012-05-30 13:26:13 -07:00
|
|
|
private boolean mInflated = false;
|
|
|
|
|
|
|
|
public FindInPageBar(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
mContext = context;
|
|
|
|
setFocusable(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void inflateContent() {
|
|
|
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
|
|
|
View content = inflater.inflate(R.layout.find_in_page_content, this);
|
|
|
|
|
|
|
|
content.findViewById(R.id.find_prev).setOnClickListener(this);
|
|
|
|
content.findViewById(R.id.find_next).setOnClickListener(this);
|
|
|
|
content.findViewById(R.id.find_close).setOnClickListener(this);
|
|
|
|
|
2012-09-25 13:43:55 -07:00
|
|
|
// Capture clicks on the rest of the view to prevent them from
|
|
|
|
// leaking into other views positioned below.
|
|
|
|
content.setOnClickListener(this);
|
|
|
|
|
2012-07-11 16:04:49 -07:00
|
|
|
mFindText = (CustomEditText) content.findViewById(R.id.find_text);
|
2012-05-30 13:26:13 -07:00
|
|
|
mFindText.addTextChangedListener(this);
|
2012-07-11 16:04:49 -07:00
|
|
|
mFindText.setOnKeyPreImeListener(new CustomEditText.OnKeyPreImeListener() {
|
2013-02-26 21:48:00 -08:00
|
|
|
@Override
|
2012-07-11 16:04:49 -07:00
|
|
|
public boolean onKeyPreIme(View v, int keyCode, KeyEvent event) {
|
|
|
|
if (keyCode == KeyEvent.KEYCODE_BACK) {
|
|
|
|
hide();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2012-05-30 13:26:13 -07:00
|
|
|
|
|
|
|
mInflated = true;
|
2014-05-02 11:34:40 -07:00
|
|
|
EventDispatcher.getInstance().registerGeckoThreadListener(this, "TextSelection:Data");
|
2012-05-30 13:26:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public void show() {
|
|
|
|
if (!mInflated)
|
|
|
|
inflateContent();
|
|
|
|
|
2012-07-11 16:06:25 -07:00
|
|
|
setVisibility(VISIBLE);
|
2012-05-30 13:26:13 -07:00
|
|
|
mFindText.requestFocus();
|
2012-07-11 16:06:25 -07:00
|
|
|
|
2013-07-28 13:36:47 -07:00
|
|
|
// handleMessage() receives response message and determines initial state of softInput
|
2013-08-06 13:58:41 -07:00
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("TextSelection:Get", REQUEST_ID));
|
2012-05-30 13:26:13 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
public void hide() {
|
2012-07-11 16:06:25 -07:00
|
|
|
setVisibility(GONE);
|
|
|
|
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
2012-05-30 13:26:13 -07:00
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Closed", null));
|
|
|
|
}
|
|
|
|
|
2012-07-11 16:06:25 -07:00
|
|
|
private InputMethodManager getInputMethodManager(View view) {
|
|
|
|
Context context = view.getContext();
|
|
|
|
return (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
|
|
}
|
|
|
|
|
2013-07-28 13:36:47 -07:00
|
|
|
public void onDestroy() {
|
2014-04-04 09:33:51 -07:00
|
|
|
if (!mInflated) {
|
|
|
|
return;
|
|
|
|
}
|
2014-05-02 11:34:40 -07:00
|
|
|
EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "TextSelection:Data");
|
2013-07-28 13:36:47 -07:00
|
|
|
}
|
|
|
|
|
2012-05-30 13:26:13 -07:00
|
|
|
// TextWatcher implementation
|
|
|
|
|
2013-02-26 21:48:00 -08:00
|
|
|
@Override
|
2012-05-30 13:26:13 -07:00
|
|
|
public void afterTextChanged(Editable s) {
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Find", s.toString()));
|
|
|
|
}
|
|
|
|
|
2013-02-26 21:48:00 -08:00
|
|
|
@Override
|
2012-05-30 13:26:13 -07:00
|
|
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
2013-02-26 21:48:00 -08:00
|
|
|
@Override
|
2012-05-30 13:26:13 -07:00
|
|
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
|
|
|
// View.OnClickListener implementation
|
|
|
|
|
2013-02-26 21:48:00 -08:00
|
|
|
@Override
|
2012-05-30 13:26:13 -07:00
|
|
|
public void onClick(View v) {
|
2013-08-13 16:44:00 -07:00
|
|
|
final int viewId = v.getId();
|
|
|
|
|
|
|
|
if (viewId == R.id.find_prev) {
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Prev", mFindText.getText().toString()));
|
|
|
|
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewId == R.id.find_next) {
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FindInPage:Next", mFindText.getText().toString()));
|
|
|
|
getInputMethodManager(mFindText).hideSoftInputFromWindow(mFindText.getWindowToken(), 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (viewId == R.id.find_close) {
|
|
|
|
hide();
|
2012-05-30 13:26:13 -07:00
|
|
|
}
|
|
|
|
}
|
2013-07-28 13:36:47 -07:00
|
|
|
|
|
|
|
// GeckoEventListener implementation
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void handleMessage(String event, JSONObject message) {
|
2013-08-06 13:58:41 -07:00
|
|
|
if (!event.equals("TextSelection:Data") || !REQUEST_ID.equals(message.optString("requestId"))) {
|
2013-07-28 13:36:47 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final String text = message.optString("text");
|
|
|
|
|
|
|
|
// Populate an initial find string, virtual keyboard not required.
|
|
|
|
if (!TextUtils.isEmpty(text)) {
|
|
|
|
// Populate initial selection
|
|
|
|
ThreadUtils.postToUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
mFindText.setText(text);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the virtual keyboard.
|
|
|
|
if (mFindText.hasWindowFocus()) {
|
|
|
|
getInputMethodManager(mFindText).showSoftInput(mFindText, 0);
|
|
|
|
} else {
|
|
|
|
// showSoftInput won't work until after the window is focused.
|
|
|
|
mFindText.setOnWindowFocusChangeListener(new CustomEditText.OnWindowFocusChangeListener() {
|
|
|
|
@Override
|
|
|
|
public void onWindowFocusChanged(boolean hasFocus) {
|
|
|
|
if (!hasFocus)
|
|
|
|
return;
|
|
|
|
|
|
|
|
mFindText.setOnWindowFocusChangeListener(null);
|
|
|
|
getInputMethodManager(mFindText).showSoftInput(mFindText, 0);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2012-05-30 13:26:13 -07:00
|
|
|
}
|