mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 652168: Add thumb for input box. [r=mfinkle]
--HG-- extra : rebase_source : 9cd553fedb4e58a6dee437ed0360b6ba5df56c54
This commit is contained in:
parent
3cc53fe881
commit
cdf1677e14
@ -1679,6 +1679,7 @@ abstract public class GeckoApp
|
||||
mPromptService = new PromptService();
|
||||
|
||||
mTextSelection = new TextSelection((TextSelectionHandle) findViewById(R.id.start_handle),
|
||||
(TextSelectionHandle) findViewById(R.id.middle_handle),
|
||||
(TextSelectionHandle) findViewById(R.id.end_handle),
|
||||
GeckoAppShell.getEventDispatcher());
|
||||
|
||||
|
@ -505,6 +505,7 @@ RES_DRAWABLE_BASE = \
|
||||
res/drawable/bookmarkdefaults_favicon_support.png \
|
||||
res/drawable/bookmarkdefaults_favicon_addons.png \
|
||||
res/drawable/handle_end.png \
|
||||
res/drawable/handle_middle.png \
|
||||
res/drawable/handle_start.png \
|
||||
$(addprefix res/drawable-mdpi/,$(notdir $(SYNC_RES_DRAWABLE_MDPI))) \
|
||||
$(NULL)
|
||||
@ -571,6 +572,7 @@ RES_DRAWABLE_HDPI = \
|
||||
res/drawable-hdpi/validation_arrow_inverted.png \
|
||||
res/drawable-hdpi/validation_bg.9.png \
|
||||
res/drawable-hdpi/handle_end.png \
|
||||
res/drawable-hdpi/handle_middle.png \
|
||||
res/drawable-hdpi/handle_start.png \
|
||||
$(addprefix res/drawable-hdpi/,$(notdir $(SYNC_RES_DRAWABLE_HDPI))) \
|
||||
$(NULL)
|
||||
@ -631,6 +633,7 @@ RES_DRAWABLE_XHDPI = \
|
||||
res/drawable-xhdpi/validation_arrow_inverted.png \
|
||||
res/drawable-xhdpi/validation_bg.9.png \
|
||||
res/drawable-xhdpi/handle_end.png \
|
||||
res/drawable-xhdpi/handle_middle.png \
|
||||
res/drawable-xhdpi/handle_start.png \
|
||||
$(NULL)
|
||||
|
||||
|
@ -11,6 +11,7 @@ import org.mozilla.gecko.util.EventDispatcher;
|
||||
import org.mozilla.gecko.util.FloatUtils;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.util.Log;
|
||||
@ -20,6 +21,7 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
private static final String LOGTAG = "GeckoTextSelection";
|
||||
|
||||
private final TextSelectionHandle mStartHandle;
|
||||
private final TextSelectionHandle mMiddleHandle;
|
||||
private final TextSelectionHandle mEndHandle;
|
||||
private final EventDispatcher mEventDispatcher;
|
||||
|
||||
@ -27,14 +29,17 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
private float mViewTop;
|
||||
private float mViewZoom;
|
||||
|
||||
TextSelection(TextSelectionHandle startHandle, TextSelectionHandle endHandle,
|
||||
TextSelection(TextSelectionHandle startHandle,
|
||||
TextSelectionHandle middleHandle,
|
||||
TextSelectionHandle endHandle,
|
||||
EventDispatcher eventDispatcher) {
|
||||
mStartHandle = startHandle;
|
||||
mMiddleHandle = middleHandle;
|
||||
mEndHandle = endHandle;
|
||||
mEventDispatcher = eventDispatcher;
|
||||
|
||||
// Only register listeners if we have valid start/end handles
|
||||
if (mStartHandle == null || mEndHandle == null) {
|
||||
// Only register listeners if we have valid start/middle/end handles
|
||||
if (mStartHandle == null || mMiddleHandle == null || mEndHandle == null) {
|
||||
Log.e(LOGTAG, "Failed to initialize text selection because at least one handle is null");
|
||||
} else {
|
||||
registerEventListener("TextSelection:ShowHandles");
|
||||
@ -52,42 +57,73 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
try {
|
||||
if (event.equals("TextSelection:ShowHandles")) {
|
||||
final JSONArray handles = message.getJSONArray("handles");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mStartHandle.setVisibility(View.VISIBLE);
|
||||
mEndHandle.setVisibility(View.VISIBLE);
|
||||
try {
|
||||
for (int i=0; i < handles.length(); i++) {
|
||||
String handle = handles.getString(i);
|
||||
|
||||
mViewLeft = 0.0f;
|
||||
mViewTop = 0.0f;
|
||||
mViewZoom = 0.0f;
|
||||
LayerView layerView = GeckoApp.mAppContext.getLayerView();
|
||||
if (layerView != null) {
|
||||
layerView.addLayer(TextSelection.this);
|
||||
}
|
||||
if (handle.equals("START"))
|
||||
mStartHandle.setVisibility(View.VISIBLE);
|
||||
else if (handle.equals("MIDDLE"))
|
||||
mMiddleHandle.setVisibility(View.VISIBLE);
|
||||
else
|
||||
mEndHandle.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mViewLeft = 0.0f;
|
||||
mViewTop = 0.0f;
|
||||
mViewZoom = 0.0f;
|
||||
LayerView layerView = GeckoApp.mAppContext.getLayerView();
|
||||
if (layerView != null) {
|
||||
layerView.addLayer(TextSelection.this);
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
} else if (event.equals("TextSelection:HideHandles")) {
|
||||
final JSONArray handles = message.getJSONArray("handles");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
LayerView layerView = GeckoApp.mAppContext.getLayerView();
|
||||
if (layerView != null) {
|
||||
layerView.removeLayer(TextSelection.this);
|
||||
}
|
||||
try {
|
||||
LayerView layerView = GeckoApp.mAppContext.getLayerView();
|
||||
if (layerView != null) {
|
||||
layerView.removeLayer(TextSelection.this);
|
||||
}
|
||||
|
||||
mStartHandle.setVisibility(View.GONE);
|
||||
mEndHandle.setVisibility(View.GONE);
|
||||
for (int i=0; i < handles.length(); i++) {
|
||||
String handle = handles.getString(i);
|
||||
if (handle.equals("START"))
|
||||
mStartHandle.setVisibility(View.GONE);
|
||||
else if (handle.equals("MIDDLE"))
|
||||
mMiddleHandle.setVisibility(View.GONE);
|
||||
else
|
||||
mEndHandle.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
});
|
||||
} else if (event.equals("TextSelection:PositionHandles")) {
|
||||
final int startLeft = message.getInt("startLeft");
|
||||
final int startTop = message.getInt("startTop");
|
||||
final int endLeft = message.getInt("endLeft");
|
||||
final int endTop = message.getInt("endTop");
|
||||
|
||||
final JSONArray positions = message.getJSONArray("positions");
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mStartHandle.positionFromGecko(startLeft, startTop);
|
||||
mEndHandle.positionFromGecko(endLeft, endTop);
|
||||
try {
|
||||
for (int i=0; i < positions.length(); i++) {
|
||||
JSONObject position = positions.getJSONObject(i);
|
||||
String handle = position.getString("handle");
|
||||
int left = position.getInt("left");
|
||||
int top = position.getInt("top");
|
||||
|
||||
if (handle.equals("START"))
|
||||
mStartHandle.positionFromGecko(left, top);
|
||||
else if (handle.equals("MIDDLE"))
|
||||
mMiddleHandle.positionFromGecko(left, top);
|
||||
else
|
||||
mEndHandle.positionFromGecko(left, top);
|
||||
}
|
||||
} catch (Exception e) { }
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -113,6 +149,7 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
GeckoApp.mAppContext.mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mStartHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
mMiddleHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
mEndHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
}
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ import android.widget.RelativeLayout;
|
||||
class TextSelectionHandle extends ImageView implements View.OnTouchListener {
|
||||
private static final String LOGTAG = "GeckoTextSelectionHandle";
|
||||
|
||||
private enum HandleType { START, END };
|
||||
private enum HandleType { START, MIDDLE, END };
|
||||
|
||||
private final HandleType mHandleType;
|
||||
private final int mWidth;
|
||||
@ -42,8 +42,16 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener {
|
||||
setOnTouchListener(this);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextSelectionHandle);
|
||||
String handleType = a.getString(R.styleable.TextSelectionHandle_handleType);
|
||||
mHandleType = handleType.equals("START") ? HandleType.START : HandleType.END;
|
||||
int handleType = a.getInt(R.styleable.TextSelectionHandle_handleType, 0x01);
|
||||
|
||||
if (handleType == 0x01)
|
||||
mHandleType = HandleType.START;
|
||||
else if (handleType == 0x02)
|
||||
mHandleType = HandleType.MIDDLE;
|
||||
else
|
||||
mHandleType = HandleType.END;
|
||||
|
||||
mGeckoPoint = new PointF(0.0f, 0.0f);
|
||||
|
||||
mWidth = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_width);
|
||||
mHeight = getResources().getDimensionPixelSize(R.dimen.text_selection_handle_height);
|
||||
@ -89,7 +97,14 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener {
|
||||
return;
|
||||
}
|
||||
// Send x coordinate on the right side of the start handle, left side of the end handle.
|
||||
float left = (float) mLeft + (mHandleType.equals(HandleType.START) ? mWidth - mShadow : mShadow);
|
||||
float left = (float) mLeft;
|
||||
if (mHandleType.equals(HandleType.START))
|
||||
left += mWidth - mShadow;
|
||||
else if (mHandleType.equals(HandleType.MIDDLE))
|
||||
left += (float) ((mWidth - mShadow) / 2);
|
||||
else
|
||||
left += mShadow;
|
||||
|
||||
PointF geckoPoint = new PointF(left, (float) mTop);
|
||||
geckoPoint = layerView.convertViewPointToLayerPoint(geckoPoint);
|
||||
|
||||
@ -122,7 +137,14 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener {
|
||||
PointF viewPoint = new PointF((mGeckoPoint.x * zoom) - x,
|
||||
(mGeckoPoint.y * zoom) - y);
|
||||
|
||||
mLeft = Math.round(viewPoint.x) - (mHandleType.equals(HandleType.START) ? mWidth - mShadow : mShadow);
|
||||
mLeft = Math.round(viewPoint.x);
|
||||
if (mHandleType.equals(HandleType.START))
|
||||
mLeft -= mWidth - mShadow;
|
||||
else if (mHandleType.equals(HandleType.MIDDLE))
|
||||
mLeft -= (float) ((mWidth - mShadow) / 2);
|
||||
else
|
||||
mLeft -= mShadow;
|
||||
|
||||
mTop = Math.round(viewPoint.y);
|
||||
|
||||
setLayoutPosition();
|
||||
|
BIN
mobile/android/base/resources/drawable-hdpi/handle_middle.png
Normal file
BIN
mobile/android/base/resources/drawable-hdpi/handle_middle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
mobile/android/base/resources/drawable-xhdpi/handle_middle.png
Normal file
BIN
mobile/android/base/resources/drawable-xhdpi/handle_middle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
BIN
mobile/android/base/resources/drawable/handle_middle.png
Normal file
BIN
mobile/android/base/resources/drawable/handle_middle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -12,12 +12,19 @@
|
||||
android:layout_height="@dimen/text_selection_handle_height"
|
||||
android:src="@drawable/handle_start"
|
||||
android:visibility="gone"
|
||||
gecko:handleType="START"/>
|
||||
gecko:handleType="start"/>
|
||||
|
||||
<org.mozilla.gecko.TextSelectionHandle android:id="@+id/middle_handle"
|
||||
android:layout_width="@dimen/text_selection_handle_width"
|
||||
android:layout_height="@dimen/text_selection_handle_height"
|
||||
android:src="@drawable/handle_middle"
|
||||
android:visibility="gone"
|
||||
gecko:handleType="middle"/>
|
||||
|
||||
<org.mozilla.gecko.TextSelectionHandle android:id="@+id/end_handle"
|
||||
android:layout_width="@dimen/text_selection_handle_width"
|
||||
android:layout_height="@dimen/text_selection_handle_height"
|
||||
android:src="@drawable/handle_end"
|
||||
android:visibility="gone"
|
||||
gecko:handleType="END"/>
|
||||
gecko:handleType="end"/>
|
||||
</merge>
|
||||
|
@ -50,7 +50,11 @@
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="TextSelectionHandle">
|
||||
<attr name="handleType" format="string"/>
|
||||
<attr name="handleType">
|
||||
<flag name="start" value="0x01" />
|
||||
<flag name="middle" value="0x02" />
|
||||
<flag name="end" value="0x03" />
|
||||
</attr>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
@ -1629,12 +1629,17 @@ var NativeWindow = {
|
||||
|
||||
var SelectionHandler = {
|
||||
HANDLE_TYPE_START: "START",
|
||||
HANDLE_TYPE_MIDDLE: "MIDDLE",
|
||||
HANDLE_TYPE_END: "END",
|
||||
|
||||
TYPE_NONE: 0,
|
||||
TYPE_CURSOR: 1,
|
||||
TYPE_SELECTION: 2,
|
||||
|
||||
// Keeps track of data about the dimensions of the selection. Coordinates
|
||||
// stored here are relative to the _view window.
|
||||
cache: null,
|
||||
_active: false,
|
||||
_activeType: this.TYPE_NONE,
|
||||
|
||||
// The window that holds the selection (can be a sub-frame)
|
||||
get _view() {
|
||||
@ -1684,62 +1689,78 @@ var SelectionHandler = {
|
||||
},
|
||||
|
||||
observe: function sh_observe(aSubject, aTopic, aData) {
|
||||
if (!this._active)
|
||||
return;
|
||||
|
||||
switch (aTopic) {
|
||||
case "Gesture:SingleTap": {
|
||||
let data = JSON.parse(aData);
|
||||
this.endSelection(data.x, data.y);
|
||||
if (this._activeType == this.TYPE_SELECTION) {
|
||||
let data = JSON.parse(aData);
|
||||
this.endSelection(data.x, data.y);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "Tab:Selected":
|
||||
case "Window:Resize": {
|
||||
// Knowing when the page is done drawing is hard, so let's just cancel
|
||||
// the selection when the window changes. We should fix this later.
|
||||
this.endSelection();
|
||||
if (this._activeType == this.TYPE_SELECTION) {
|
||||
// Knowing when the page is done drawing is hard, so let's just cancel
|
||||
// the selection when the window changes. We should fix this later.
|
||||
this.endSelection();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "after-viewport-change": {
|
||||
// Update the cache after the viewport changes (e.g. panning, zooming).
|
||||
this.updateCacheForSelection();
|
||||
if (this._activeType == this.TYPE_SELECTION) {
|
||||
// Update the cache after the viewport changes (e.g. panning, zooming).
|
||||
this.updateCacheForSelection();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TextSelection:Move": {
|
||||
let data = JSON.parse(aData);
|
||||
this.moveSelection(data.handleType == this.HANDLE_TYPE_START, data.x, data.y);
|
||||
if (this._activeType == this.TYPE_SELECTION)
|
||||
this.moveSelection(data.handleType == this.HANDLE_TYPE_START, data.x, data.y);
|
||||
else if (this._activeType == this.TYPE_CURSOR)
|
||||
this._sendMouseEvents(data.x, data.y);
|
||||
break;
|
||||
}
|
||||
case "TextSelection:Position": {
|
||||
let data = JSON.parse(aData);
|
||||
if (this._activeType == this.TYPE_SELECTION) {
|
||||
let data = JSON.parse(aData);
|
||||
|
||||
// Reverse the handles if necessary.
|
||||
let selectionReversed = this.updateCacheForSelection(data.handleType == this.HANDLE_TYPE_START);
|
||||
if (selectionReversed) {
|
||||
// Re-send mouse events to update the selection corresponding to the new handles.
|
||||
if (this._isRTL) {
|
||||
this._sendMouseEvents(this.cache.end.x, this.cache.end.y, false);
|
||||
this._sendMouseEvents(this.cache.start.x, this.cache.start.y, true);
|
||||
} else {
|
||||
this._sendMouseEvents(this.cache.start.x, this.cache.start.y, false);
|
||||
this._sendMouseEvents(this.cache.end.x, this.cache.end.y, true);
|
||||
// Reverse the handles if necessary.
|
||||
let selectionReversed = this.updateCacheForSelection(data.handleType == this.HANDLE_TYPE_START);
|
||||
if (selectionReversed) {
|
||||
// Re-send mouse events to update the selection corresponding to the new handles.
|
||||
if (this._isRTL) {
|
||||
this._sendMouseEvents(this.cache.end.x, this.cache.end.y, false);
|
||||
this._sendMouseEvents(this.cache.start.x, this.cache.start.y, true);
|
||||
} else {
|
||||
this._sendMouseEvents(this.cache.start.x, this.cache.start.y, false);
|
||||
this._sendMouseEvents(this.cache.end.x, this.cache.end.y, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Position the handles to align with the edges of the selection.
|
||||
this.positionHandles();
|
||||
// Position the handles to align with the edges of the selection.
|
||||
this.positionHandles();
|
||||
} else if (this._activeType == this.TYPE_CURSOR) {
|
||||
this.positionHandles();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function sh_handleEvent(aEvent) {
|
||||
if (!this._active)
|
||||
return;
|
||||
|
||||
switch (aEvent.type) {
|
||||
case "pagehide":
|
||||
this.endSelection();
|
||||
if (this._activeType == this.TYPE_SELECTION)
|
||||
this.endSelection();
|
||||
else
|
||||
this.hideThumb();
|
||||
break;
|
||||
|
||||
case "keydown":
|
||||
case "blur":
|
||||
if (this._activeType == this.TYPE_CURSOR)
|
||||
this.hideThumb();
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -1777,8 +1798,12 @@ var SelectionHandler = {
|
||||
// aX/aY are in top-level window browser coordinates
|
||||
startSelection: function sh_startSelection(aElement, aX, aY) {
|
||||
// Clear out any existing selection
|
||||
if (this._active)
|
||||
if (this._activeType == this.TYPE_SELECTION) {
|
||||
this.endSelection();
|
||||
} else if (this._activeType == this.TYPE_CURSOR) {
|
||||
// Hide the cursor handles.
|
||||
this.hideThumb();
|
||||
}
|
||||
|
||||
// Get the element's view
|
||||
this._view = aElement.ownerDocument.defaultView;
|
||||
@ -1827,8 +1852,15 @@ var SelectionHandler = {
|
||||
this.cache = { start: {}, end: {}};
|
||||
this.updateCacheForSelection();
|
||||
|
||||
this.showHandles();
|
||||
this._active = true;
|
||||
this._activeType = this.TYPE_SELECTION;
|
||||
this.positionHandles();
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:ShowHandles",
|
||||
handles: [this.HANDLE_TYPE_START, this.HANDLE_TYPE_END]
|
||||
}
|
||||
});
|
||||
|
||||
if (aElement instanceof Ci.nsIDOMNSEditableElement)
|
||||
aElement.focus();
|
||||
@ -1854,11 +1886,11 @@ var SelectionHandler = {
|
||||
|
||||
// Used by the contextmenu "matches" functions in ClipboardHelper
|
||||
shouldShowContextMenu: function sh_shouldShowContextMenu(aX, aY) {
|
||||
return this._active && this._pointInSelection(aX, aY);
|
||||
return (this._activeType == this.TYPE_SELECTION) && this._pointInSelection(aX, aY);
|
||||
},
|
||||
|
||||
selectAll: function sh_selectAll(aElement, aX, aY) {
|
||||
if (!this._active)
|
||||
if (this._activeType != this.TYPE_SELECTION)
|
||||
this.startSelection(aElement, aX, aY);
|
||||
|
||||
let selectionController = this.getSelectionController();
|
||||
@ -1906,11 +1938,17 @@ var SelectionHandler = {
|
||||
|
||||
// aX/aY are in top-level window browser coordinates
|
||||
endSelection: function sh_endSelection(aX, aY) {
|
||||
if (!this._active)
|
||||
if (this._activeType != this.TYPE_SELECTION)
|
||||
return "";
|
||||
|
||||
this._activeType = this.TYPE_NONE;
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:HideHandles",
|
||||
handles: [this.HANDLE_TYPE_START, this.HANDLE_TYPE_END]
|
||||
}
|
||||
});
|
||||
|
||||
this._active = false;
|
||||
this.hideHandles();
|
||||
|
||||
let selectedText = "";
|
||||
let pointInSelection = false;
|
||||
@ -1947,6 +1985,9 @@ var SelectionHandler = {
|
||||
|
||||
_cleanUp: function sh_cleanUp() {
|
||||
this._view.removeEventListener("pagehide", this, false);
|
||||
this._view.removeEventListener("keydown", this, false);
|
||||
this._view.removeEventListener("blur", this, true);
|
||||
this._activeType = this.TYPE_NONE;
|
||||
this._view = null;
|
||||
this._target = null;
|
||||
this._isRTL = false;
|
||||
@ -2000,6 +2041,41 @@ var SelectionHandler = {
|
||||
return selectionReversed;
|
||||
},
|
||||
|
||||
showThumb: function sh_showThumb(aElement) {
|
||||
if (!aElement)
|
||||
return;
|
||||
|
||||
// Get the element's view
|
||||
this._view = aElement.ownerDocument.defaultView;
|
||||
this._target = aElement;
|
||||
|
||||
this._view.addEventListener("pagehide", this, false);
|
||||
this._view.addEventListener("keydown", this, false);
|
||||
this._view.addEventListener("blur", this, true);
|
||||
|
||||
this._activeType = this.TYPE_CURSOR;
|
||||
this.positionHandles();
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:ShowHandles",
|
||||
handles: [this.HANDLE_TYPE_MIDDLE]
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
hideThumb: function sh_hideThumb() {
|
||||
this._activeType = this.TYPE_NONE;
|
||||
this._cleanUp();
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:HideHandles",
|
||||
handles: [this.HANDLE_TYPE_MIDDLE]
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
positionHandles: function sh_positionHandles() {
|
||||
// Translate coordinates to account for selections in sub-frames. We can't cache
|
||||
// this because the top-level page may have scrolled since selection started.
|
||||
@ -2007,37 +2083,30 @@ var SelectionHandler = {
|
||||
let scrollX = {}, scrollY = {};
|
||||
this._view.top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).getScrollXY(false, scrollX, scrollY);
|
||||
|
||||
let positions = null;
|
||||
if (this._activeType == this.TYPE_CURSOR) {
|
||||
let cursor = this._cwu.sendQueryContentEvent(this._cwu.QUERY_CARET_RECT, this._target.selectionEnd, 0, 0, 0);
|
||||
positions = [ { handle: this.HANDLE_TYPE_MIDDLE,
|
||||
left: cursor.left + offset.x + scrollX.value,
|
||||
top: cursor.top + cursor.height + offset.y + scrollY.value } ];
|
||||
} else {
|
||||
positions = [ { handle: this.HANDLE_TYPE_START,
|
||||
left: this.cache.start.x + offset.x + scrollX.value,
|
||||
top: this.cache.start.y + offset.y + scrollY.value },
|
||||
{ handle: this.HANDLE_TYPE_END,
|
||||
left: this.cache.end.x + offset.x + scrollX.value,
|
||||
top: this.cache.end.y + offset.y + scrollY.value } ];
|
||||
}
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:PositionHandles",
|
||||
startLeft: this.cache.start.x + offset.x + scrollX.value,
|
||||
startTop: this.cache.start.y + offset.y + scrollY.value,
|
||||
endLeft: this.cache.end.x + offset.x + scrollX.value,
|
||||
endTop: this.cache.end.y + offset.y + scrollY.value
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
showHandles: function sh_showHandles() {
|
||||
this.positionHandles();
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:ShowHandles"
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
hideHandles: function sh_hideHandles() {
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "TextSelection:HideHandles"
|
||||
positions: positions
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var UserAgent = {
|
||||
DESKTOP_UA: null,
|
||||
|
||||
@ -3607,6 +3676,10 @@ var BrowserEventHandler = {
|
||||
this._sendMouseEvent("mousemove", element, data.x, data.y);
|
||||
this._sendMouseEvent("mousedown", element, data.x, data.y);
|
||||
this._sendMouseEvent("mouseup", element, data.x, data.y);
|
||||
|
||||
// See if its a input element
|
||||
if ((element instanceof HTMLInputElement && element.mozIsTextField(false)) || (element instanceof HTMLTextAreaElement))
|
||||
SelectionHandler.showThumb(element);
|
||||
|
||||
if (isClickable)
|
||||
Haptic.performSimpleAction(Haptic.LongPress);
|
||||
|
Loading…
Reference in New Issue
Block a user