зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1023418 - (p0) Auto-selecting a phone number does not stop at element breaks, r=mfinkle
This commit is contained in:
Родитель
c1f48dce0b
Коммит
7449ef9663
|
@ -4,6 +4,9 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
// Define elements that bound phone number containers.
|
||||
const PHONE_NUMBER_CONTAINERS = "td,div";
|
||||
|
||||
var SelectionHandler = {
|
||||
HANDLE_TYPE_START: "START",
|
||||
HANDLE_TYPE_MIDDLE: "MIDDLE",
|
||||
|
@ -317,42 +320,6 @@ var SelectionHandler = {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (this._isPhoneNumber(selection.toString())) {
|
||||
let anchorNode = selection.anchorNode;
|
||||
let anchorOffset = selection.anchorOffset;
|
||||
let focusNode = null;
|
||||
let focusOffset = null;
|
||||
while (this._isPhoneNumber(selection.toString().trim())) {
|
||||
focusNode = selection.focusNode;
|
||||
focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", "forward", "word");
|
||||
// if we hit the end of the text on the page, we can't advance the selection
|
||||
if (focusNode == selection.focusNode && focusOffset == selection.focusOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// reverse selection
|
||||
selection.collapse(focusNode, focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
|
||||
anchorNode = focusNode;
|
||||
anchorOffset = focusOffset
|
||||
|
||||
while (this._isPhoneNumber(selection.toString().trim())) {
|
||||
focusNode = selection.focusNode;
|
||||
focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", "backward", "word");
|
||||
// if we hit the end of the text on the page, we can't advance the selection
|
||||
if (focusNode == selection.focusNode && focusOffset == selection.focusOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
selection.collapse(focusNode, focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
}
|
||||
|
||||
// Add a listener to end the selection if it's removed programatically
|
||||
selection.QueryInterface(Ci.nsISelectionPrivate).addSelectionListener(this);
|
||||
this._activeType = this.TYPE_SELECTION;
|
||||
|
@ -389,7 +356,16 @@ var SelectionHandler = {
|
|||
if (aOptions.mode == this.SELECT_AT_POINT) {
|
||||
// Clear any ranges selected outside SelectionHandler, by code such as Find-In-Page.
|
||||
this._contentWindow.getSelection().removeAllRanges();
|
||||
return this._domWinUtils.selectAtPoint(aOptions.x, aOptions.y, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
|
||||
if (!this._domWinUtils.selectAtPoint(aOptions.x, aOptions.y, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Perform additional phone-number "smart selection".
|
||||
if (this._isPhoneNumber(this._getSelection().toString())) {
|
||||
this._selectSmartPhoneNumber();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aOptions.mode != this.SELECT_ALL) {
|
||||
|
@ -429,6 +405,71 @@ var SelectionHandler = {
|
|||
return true;
|
||||
},
|
||||
|
||||
/*
|
||||
* Called to expand a selection that appears to represent a phone number. This enhances the basic
|
||||
* SELECT_WORDNOSPACE logic employed in performSelection() in response to long-tap / selecting text.
|
||||
*/
|
||||
_selectSmartPhoneNumber: function() {
|
||||
this._extendPhoneNumberSelection("forward");
|
||||
this._reversePhoneNumberSelectionDir();
|
||||
|
||||
this._extendPhoneNumberSelection("backward");
|
||||
this._reversePhoneNumberSelectionDir();
|
||||
},
|
||||
|
||||
/*
|
||||
* Extend the current phone number selection in the requested direction.
|
||||
*/
|
||||
_extendPhoneNumberSelection: function(direction) {
|
||||
let selection = this._getSelection();
|
||||
|
||||
// Extend the phone number selection until we find a boundry.
|
||||
while (true) {
|
||||
// Save current focus position, and extend the selection.
|
||||
let focusNode = selection.focusNode;
|
||||
let focusOffset = selection.focusOffset;
|
||||
selection.modify("extend", direction, "character");
|
||||
|
||||
// If the selection doesn't change, (can't extend further), we're done.
|
||||
if (selection.focusNode == focusNode && selection.focusOffset == focusOffset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't extend past a valid phone number.
|
||||
if (!this._isPhoneNumber(selection.toString().trim())) {
|
||||
// Backout the undesired selection extend, and we're done.
|
||||
selection.collapse(selection.anchorNode, selection.anchorOffset);
|
||||
selection.extend(focusNode, focusOffset);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't extend the selection into a new container.
|
||||
if (selection.focusNode != focusNode) {
|
||||
let nextContainer = (selection.focusNode instanceof Text) ?
|
||||
selection.focusNode.parentNode : selection.focusNode;
|
||||
if (nextContainer.mozMatchesSelector &&
|
||||
nextContainer.mozMatchesSelector(PHONE_NUMBER_CONTAINERS)) {
|
||||
// Backout the undesired selection extend, and we're done.
|
||||
selection.collapse(selection.anchorNode, selection.anchorOffset);
|
||||
selection.extend(focusNode, focusOffset);
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Reverse the the selection direction, swapping anchorNode <-+-> focusNode.
|
||||
*/
|
||||
_reversePhoneNumberSelectionDir: function(direction) {
|
||||
let selection = this._getSelection();
|
||||
|
||||
let anchorNode = selection.anchorNode;
|
||||
let anchorOffset = selection.anchorOffset;
|
||||
selection.collapse(selection.focusNode, selection.focusOffset);
|
||||
selection.extend(anchorNode, anchorOffset);
|
||||
},
|
||||
|
||||
/* Return true if the current selection (given by aPositions) is near to where the coordinates passed in */
|
||||
_selectionNearClick: function(aX, aY, aPositions) {
|
||||
let distance = 0;
|
||||
|
|
Загрузка…
Ссылка в новой задаче