From fc8d1c535cbc59ef351711837de2a86ff52a4664 Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Tue, 21 May 2013 14:16:50 -0400 Subject: [PATCH] Bug 872355 - Always use nested virtual cursors, when available. r=yzen --- accessible/src/jsat/AccessFu.jsm | 15 ++++++++-- accessible/src/jsat/EventManager.jsm | 2 +- accessible/src/jsat/TraversalRules.jsm | 6 ++-- accessible/src/jsat/Utils.jsm | 41 +++++++++++++------------- accessible/src/jsat/content-script.js | 17 +++++++---- 5 files changed, 50 insertions(+), 31 deletions(-) diff --git a/accessible/src/jsat/AccessFu.jsm b/accessible/src/jsat/AccessFu.jsm index 625c64608f7..ac34c236b30 100644 --- a/accessible/src/jsat/AccessFu.jsm +++ b/accessible/src/jsat/AccessFu.jsm @@ -479,9 +479,20 @@ var Output = { aJsonBounds.right - aJsonBounds.left, aJsonBounds.bottom - aJsonBounds.top); let vp = Utils.getViewport(Utils.win) || { zoom: 1.0, offsetY: 0 }; - let browserOffset = aBrowser.getBoundingClientRect(); + let root = Utils.win; + let offset = { left: -root.mozInnerScreenX, top: -root.mozInnerScreenY }; + let scale = 1 / Utils.getPixelsPerCSSPixel(Utils.win); - return bounds.translate(browserOffset.left, browserOffset.top). + if (!aBrowser.contentWindow) { + // OOP browser, add offset of browser. + // The offset of the browser element in relation to its parent window. + let clientRect = aBrowser.getBoundingClientRect(); + let win = aBrowser.ownerDocument.defaultView; + offset.left += clientRect.left + win.mozInnerScreenX; + offset.top += clientRect.top + win.mozInnerScreenY; + } + + return bounds.scale(scale, scale).translate(offset.left, offset.top). scale(vp.zoom, vp.zoom).expandToIntegers(); } }; diff --git a/accessible/src/jsat/EventManager.jsm b/accessible/src/jsat/EventManager.jsm index 7d0446104b4..1cee5f4681e 100644 --- a/accessible/src/jsat/EventManager.jsm +++ b/accessible/src/jsat/EventManager.jsm @@ -138,7 +138,7 @@ this.EventManager.prototype = { case Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED: { let pivot = aEvent.accessible. - QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor; + QueryInterface(Ci.nsIAccessibleDocument).virtualCursor; let position = pivot.position; if (position.role == Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME) break; diff --git a/accessible/src/jsat/TraversalRules.jsm b/accessible/src/jsat/TraversalRules.jsm index 756cfe31a86..f9ce59d1bb3 100644 --- a/accessible/src/jsat/TraversalRules.jsm +++ b/accessible/src/jsat/TraversalRules.jsm @@ -31,9 +31,9 @@ BaseTraversalRule.prototype = { match: function BaseTraversalRule_match(aAccessible) { if (aAccessible.role == Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME) { - return (aAccessible.childCount) ? - Ci.nsIAccessibleTraversalRule.FILTER_IGNORE : - Ci.nsIAccessibleTraversalRule.FILTER_MATCH; + return (Utils.getMessageManager(aAccessible.DOMNode)) ? + Ci.nsIAccessibleTraversalRule.FILTER_MATCH : + Ci.nsIAccessibleTraversalRule.FILTER_IGNORE; } if (this._matchFunc) diff --git a/accessible/src/jsat/Utils.jsm b/accessible/src/jsat/Utils.jsm index cab406d4c7e..8fd2ac0375b 100644 --- a/accessible/src/jsat/Utils.jsm +++ b/accessible/src/jsat/Utils.jsm @@ -131,15 +131,27 @@ this.Utils = { let document = this.CurrentContentDoc; if (document) { - let remoteframes = document.querySelectorAll('iframe[remote=true]'); + let remoteframes = document.querySelectorAll('iframe'); + + for (let i = 0; i < remoteframes.length; ++i) { + let mm = this.getMessageManager(remoteframes[i]); + if (mm) { + messageManagers.push(mm); + } + } - for (let i = 0; i < remoteframes.length; ++i) - messageManagers.push(this.getMessageManager(remoteframes[i])); } return messageManagers; }, + get isContentProcess() { + delete this.isContentProcess; + this.isContentProcess = + Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT; + return this.isContentProcess; + }, + getMessageManager: function getMessageManager(aBrowser) { try { return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner). @@ -173,15 +185,12 @@ this.Utils = { let doc = (aDocument instanceof Ci.nsIAccessible) ? aDocument : this.AccRetrieval.getAccessibleFor(aDocument); - while (doc) { - try { - return doc.QueryInterface(Ci.nsIAccessibleCursorable).virtualCursor; - } catch (x) { - doc = doc.parentDocument; - } - } + return doc.QueryInterface(Ci.nsIAccessibleDocument).virtualCursor; + }, - return null; + getPixelsPerCSSPixel: function getPixelsPerCSSPixel(aWindow) { + return aWindow.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils).screenPixelsPerCSSPixel; } }; @@ -402,15 +411,7 @@ PivotContext.prototype = { this._accessible.getBounds(objX, objY, objW, objH); - // XXX: OOP content provides a screen offset of 0, while in-process provides a real - // offset. Removing the offset and using content-relative coords normalizes this. - let docX = {}, docY = {}; - let docRoot = this._accessible.rootDocument. - QueryInterface(Ci.nsIAccessible); - docRoot.getBounds(docX, docY, {}, {}); - - this._bounds = new Rect(objX.value, objY.value, objW.value, objH.value). - translate(-docX.value, -docY.value); + this._bounds = new Rect(objX.value, objY.value, objW.value, objH.value); } return this._bounds.clone(); diff --git a/accessible/src/jsat/content-script.js b/accessible/src/jsat/content-script.js index a7d7373f912..f67748f40ae 100644 --- a/accessible/src/jsat/content-script.js +++ b/accessible/src/jsat/content-script.js @@ -59,7 +59,12 @@ function virtualCursorControl(aMessage) { } break; case 'moveToPoint': - moved = vc.moveToPoint(rule, details.x, details.y, true); + if (!this._ppcp) { + this._ppcp = Utils.getPixelsPerCSSPixel(content); + } + moved = vc.moveToPoint(rule, + details.x * this._ppcp, details.y * this._ppcp, + true); break; case 'whereIsIt': if (!forwardMessage(vc, aMessage)) { @@ -97,10 +102,12 @@ function forwardMessage(aVirtualCursor, aMessage) { let mm = Utils.getMessageManager(acc.DOMNode); mm.addMessageListener(aMessage.name, virtualCursorControl); aMessage.json.origin = 'parent'; - // XXX: OOP content's screen offset is 0, - // so we remove the real screen offset here. - aMessage.json.x -= content.mozInnerScreenX; - aMessage.json.y -= content.mozInnerScreenY; + if (Utils.isContentProcess) { + // XXX: OOP content's screen offset is 0, + // so we remove the real screen offset here. + aMessage.json.x -= content.mozInnerScreenX; + aMessage.json.y -= content.mozInnerScreenY; + } mm.sendAsyncMessage(aMessage.name, aMessage.json); return true; }