зеркало из https://github.com/mozilla/gecko-dev.git
Bug 673037 - Allow selecting text in frames. r=mfinkle
This commit is contained in:
Родитель
5ce917a794
Коммит
9896e0a8cf
|
@ -1332,6 +1332,7 @@ TouchEventHandler.init();
|
|||
var SelectionHandler = {
|
||||
cache: {},
|
||||
selectedText: "",
|
||||
contentWindow: null,
|
||||
|
||||
init: function() {
|
||||
addMessageListener("Browser:SelectionStart", this);
|
||||
|
@ -1348,13 +1349,34 @@ var SelectionHandler = {
|
|||
case "Browser:SelectionStart": {
|
||||
this.selectedText = "";
|
||||
|
||||
// if this is an iframe, dig down to find the document that was clicked
|
||||
let x = json.x;
|
||||
let y = json.y;
|
||||
let offsetX = 0;
|
||||
let offsetY = 0;
|
||||
let elem = utils.elementFromPoint(x, y, true, false);
|
||||
while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) {
|
||||
// adjust client coordinates' origin to be top left of iframe viewport
|
||||
let rect = elem.getBoundingClientRect();
|
||||
scrollOffset = ContentScroll.getScrollOffset(elem.ownerDocument.defaultView);
|
||||
offsetX += rect.left;
|
||||
x -= rect.left;
|
||||
|
||||
offsetY += rect.top + scrollOffset.y;
|
||||
y -= rect.top + scrollOffset.y;
|
||||
utils = elem.contentDocument.defaultView.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
elem = utils.elementFromPoint(x, y, true, false);
|
||||
}
|
||||
let contentWindow = elem.ownerDocument.defaultView;
|
||||
let currentDocShell = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
|
||||
|
||||
// Position the caret using a fake mouse click
|
||||
utils.sendMouseEventToWindow("mousedown", json.x - scrollOffset.x, json.y - scrollOffset.y, 0, 1, 0, true);
|
||||
utils.sendMouseEventToWindow("mouseup", json.x - scrollOffset.x, json.y - scrollOffset.y, 0, 1, 0, true);
|
||||
utils.sendMouseEventToWindow("mousedown", x - scrollOffset.x, y - scrollOffset.y, 0, 1, 0, true);
|
||||
utils.sendMouseEventToWindow("mouseup", x - scrollOffset.x, y - scrollOffset.y, 0, 1, 0, true);
|
||||
|
||||
// Select the word nearest the caret
|
||||
try {
|
||||
let selcon = docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
|
||||
let selcon = currentDocShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsISelectionDisplay).QueryInterface(Ci.nsISelectionController);
|
||||
selcon.wordMove(false, false);
|
||||
selcon.wordMove(true, true);
|
||||
} catch(e) {
|
||||
|
@ -1363,7 +1385,7 @@ var SelectionHandler = {
|
|||
}
|
||||
|
||||
// Find the selected text rect and send it back so the handles can position correctly
|
||||
let selection = content.getSelection();
|
||||
let selection = contentWindow.getSelection();
|
||||
if (selection.rangeCount == 0)
|
||||
return;
|
||||
|
||||
|
@ -1384,13 +1406,14 @@ var SelectionHandler = {
|
|||
let rects = range.getClientRects();
|
||||
for (let i=0; i<rects.length; i++) {
|
||||
if (i == 0) {
|
||||
this.cache.start.x = rects[i].left + scrollOffset.x;
|
||||
this.cache.start.y = rects[i].bottom + scrollOffset.y;
|
||||
this.cache.start.x = rects[i].left + offsetX;
|
||||
this.cache.start.y = rects[i].bottom + offsetY;
|
||||
}
|
||||
this.cache.end.x = rects[i].right + scrollOffset.x;
|
||||
this.cache.end.y = rects[i].bottom + scrollOffset.y;
|
||||
this.cache.end.x = rects[i].right + offsetX;
|
||||
this.cache.end.y = rects[i].bottom + offsetY;
|
||||
}
|
||||
|
||||
this.contentWindow = contentWindow;
|
||||
sendAsyncMessage("Browser:SelectionRange", this.cache);
|
||||
break;
|
||||
}
|
||||
|
@ -1398,7 +1421,9 @@ var SelectionHandler = {
|
|||
case "Browser:SelectionEnd": {
|
||||
try {
|
||||
// The selection might already be gone
|
||||
content.getSelection().collapseToStart();
|
||||
if (this.contentWindow)
|
||||
this.contentWindow.getSelection().collapseToStart();
|
||||
this.contentWindow = null;
|
||||
} catch(e) {}
|
||||
|
||||
if (this.selectedText.length) {
|
||||
|
@ -1412,6 +1437,8 @@ var SelectionHandler = {
|
|||
}
|
||||
|
||||
case "Browser:SelectionMove":
|
||||
if (!this.contentWindow)
|
||||
return;
|
||||
// Hack to avoid setting focus in a textbox [Bugs 654352 & 667243]
|
||||
let elemUnder = elementFromPoint(json.x - scrollOffset.x, json.y - scrollOffset.y);
|
||||
if (elemUnder && elemUnder instanceof Ci.nsIDOMHTMLInputElement || elemUnder instanceof Ci.nsIDOMHTMLTextAreaElement)
|
||||
|
@ -1433,7 +1460,7 @@ var SelectionHandler = {
|
|||
}
|
||||
|
||||
// Cache the selected text since the selection might be gone by the time we get the "end" message
|
||||
this.selectedText = content.getSelection().toString().trim();
|
||||
this.selectedText = this.contentWindow.getSelection().toString().trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче