Bug 972574 - Monocles not matching selection after double tap in URL text field, r=jimm, azasypkin

This commit is contained in:
Mark Capella 2014-03-04 09:39:48 -05:00
parent a4d19fe1a8
commit 8af11e03f8
3 changed files with 101 additions and 14 deletions

View File

@ -8,11 +8,8 @@
let Ci = Components.interfaces;
const kCaretMode = 1;
const kSelectionMode = 2;
var ChromeSelectionHandler = {
_mode: kSelectionMode,
_mode: this._SELECTION_MODE,
/*************************************************
* Messaging wrapper
@ -33,6 +30,10 @@ var ChromeSelectionHandler = {
* General selection start method for both caret and selection mode.
*/
_onSelectionAttach: function _onSelectionAttach(aJson) {
// Clear previous ChromeSelectionHandler state.
this._deactivate();
// Initialize ChromeSelectionHandler state.
this._domWinUtils = Util.getWindowUtils(window);
this._contentWindow = window;
this._targetElement = aJson.target;
@ -54,11 +55,14 @@ var ChromeSelectionHandler = {
return;
}
// Add a listener to respond to programmatic selection changes.
selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
if (!selection.isCollapsed) {
this._mode = kSelectionMode;
this._mode = this._SELECTION_MODE;
this._updateSelectionUI("start", true, true);
} else {
this._mode = kCaretMode;
this._mode = this._CARET_MODE;
this._updateSelectionUI("caret", false, false, true);
}
@ -156,9 +160,9 @@ var ChromeSelectionHandler = {
return;
}
this._updateSelectionUI("update",
this._mode == kSelectionMode,
this._mode == kSelectionMode,
this._mode == kCaretMode);
this._mode == this._SELECTION_MODE,
this._mode == this._SELECTION_MODE,
this._mode == this._CARET_MODE);
},
/*
@ -188,7 +192,7 @@ var ChromeSelectionHandler = {
// We bail if things get out of sync here implying we missed a message.
this._selectionMoveActive = true;
this._mode = kSelectionMode;
this._mode = this._SELECTION_MODE;
// Update the position of the selection marker that is *not*
// being dragged.
@ -266,7 +270,7 @@ var ChromeSelectionHandler = {
/*
* _clearSelection
*
* Clear existing selection if it exists and reset our internla state.
* Clear existing selection if it exists and reset our internal state.
*/
_clearSelection: function _clearSelection() {
let selection = this._getSelection();
@ -278,9 +282,30 @@ var ChromeSelectionHandler = {
/*
* _closeSelection
*
* Shuts SelectionHandler down.
* Shuts ChromeSelectionHandler and SelectionHelperUI down.
*/
_closeSelection: function _closeSelection() {
this._deactivate();
this.sendAsync("Content:HandlerShutdown", {});
},
/*
* _deactivate
*
* Resets ChromeSelectionHandler state, previously initialized in
* general selection start-method |_onSelectionAttach()|.
*/
_deactivate: function _deactivate() {
// Remove our selection notification listener.
let selection = this._getSelection();
if (selection) {
try {
selection.QueryInterface(Ci.nsISelectionPrivate).removeSelectionListener(this);
} catch(e) {
// Fail safe during multiple _deactivate() calls.
}
}
this._clearTimers();
this._cache = null;
this._contentWindow = null;
@ -291,7 +316,7 @@ var ChromeSelectionHandler = {
this._selectionMoveActive = false;
this._domWinUtils = null;
this._targetIsEditable = false;
this.sendAsync("Content:HandlerShutdown", {});
this._mode = null;
},
get hasSelection() {

View File

@ -53,6 +53,9 @@ dump("### SelectionPrototype.js loaded\n");
var SelectionPrototype = function() { }
SelectionPrototype.prototype = {
_CARET_MODE: 1, // Single monocle mode (Collapsed caret).
_SELECTION_MODE: 2, // Double monocle mode (Selection w/Text).
_debugEvents: false,
_cache: {},
_targetElement: null,
@ -169,6 +172,28 @@ SelectionPrototype.prototype = {
this._debugEvents = aMsg.dumpEvents;
},
/*
* Selection Changed notification listener. This allows us to respond to selection changes
* introduced programmatically by Gecko events, target-page support code, etc.
*/
notifySelectionChanged: function notifySelectionChanged(aDocument, aSelection, aReason) {
// Ignore user generated selectionChange notifications during monocle/marker movement.
if ((typeof SelectionHelperUI != "undefined") && SelectionHelperUI.hasActiveDrag) {
return;
}
// Ignore selectionChange notifications, unless reason is mouseup, or unknown.
if (!(aReason & Ci.nsISelectionListener.MOUSEUP_REASON) &&
(aReason != Ci.nsISelectionListener.NO_REASON)) {
return;
}
// If in selection mode, and we have a selection, update it.
if (this._mode == this._SELECTION_MODE && !aSelection.isCollapsed) {
this._updateSelectionUI("update", true, true);
}
},
/*************************************************
* Selection api
*/

View File

@ -232,7 +232,7 @@ gTests.push({
gTests.push({
desc: "Bug 957646 - Selection monocles sometimes don't display when tapping" +
" text ion the nav bar.",
" text in the nav bar.",
run: function() {
yield showNavBar();
@ -250,6 +250,43 @@ gTests.push({
}
});
gTests.push({
desc: "Bug 972574 - Monocles not matching selection after double tap" +
" in URL text field.",
run: function() {
yield showNavBar();
let MARGIN_OF_ERROR = 15;
let EST_URLTEXT_WIDTH = 125;
let edit = document.getElementById("urlbar-edit");
edit.value = "http://www.wikipedia.org/";
// Determine a tap point centered on URL.
let editRectangle = edit.getBoundingClientRect();
let midX = editRectangle.left + Math.ceil(EST_URLTEXT_WIDTH / 2);
let midY = editRectangle.top + Math.ceil(editRectangle.height / 2);
// Tap inside the input for fluffing to take effect.
sendTap(window, midX, midY);
// Double-tap inside the input to selectALL.
sendDoubleTap(window, midX, midY);
// Check for start/end monocles positioned within accepted margins.
checkMonoclePositionRange("start",
Math.ceil(editRectangle.left - MARGIN_OF_ERROR),
Math.ceil(editRectangle.left + MARGIN_OF_ERROR),
Math.ceil(editRectangle.top + editRectangle.height - MARGIN_OF_ERROR),
Math.ceil(editRectangle.top + editRectangle.height + MARGIN_OF_ERROR));
checkMonoclePositionRange("end",
Math.ceil(editRectangle.left + EST_URLTEXT_WIDTH - MARGIN_OF_ERROR),
Math.ceil(editRectangle.left + EST_URLTEXT_WIDTH + MARGIN_OF_ERROR),
Math.ceil(editRectangle.top + editRectangle.height - MARGIN_OF_ERROR),
Math.ceil(editRectangle.top + editRectangle.height + MARGIN_OF_ERROR));
}
});
gTests.push({
desc: "Bug 972428 - grippers not appearing under the URL field when adding " +
"text.",