author | Jim Mathies <jmathies@mozilla.com> |
Wed, 27 Feb 2013 10:27:47 -0600 | |
changeset 123179 | a2c6dda9543e8f693629c6bbc32f203169d75336 |
parent 123178 | 026f901ab4177471f7c37f6f71552dc58ecd0e64 |
child 123180 | 33dd2de9984f47821ff359ad1a9159d33409cd35 |
push id | 24373 |
push user | ryanvm@gmail.com |
push date | Thu, 28 Feb 2013 01:36:21 +0000 |
treeherder | mozilla-central@8cb9d6981978 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mbrubeck |
bugs | 832957 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/metro/base/content/bindings/selectionoverlay.xml +++ b/browser/metro/base/content/bindings/selectionoverlay.xml @@ -14,21 +14,23 @@ <xul:toolbarbutton id="selectionhandle-end" label="^" left="100" top="10" hidden="false"/> </xul:stack> </html:div> </content> <implementation implements="nsIDOMEventListener"> <constructor> <![CDATA[ + this._selectionOverlay.addEventListener('contextmenu', this); ]]> </constructor> <destructor> <![CDATA[ + this._selectionOverlay.removeEventListener('contextmenu', this); ]]> </destructor> <field name="_selectionOverlay" readonly="true">document.getAnonymousElementByAttribute(this, "anonid", "selection-overlay-inner").parentNode;</field> <field name="_selectionDebugOverlay" readonly="true">document.getAnonymousElementByAttribute(this, "anonid", "selection-overlay-debug");</field> <property name="enabled"> <setter> @@ -82,16 +84,41 @@ <method name="shutdown"> <body> <![CDATA[ this.enabled = false; ]]> </body> </method> + <method name="_onContextMenu"> + <parameter name="aEvent"/> + <body> + <![CDATA[ + // forward this over. frame script will treat this like + // a bubbling contextmenu event. + Browser.selectedTab.browser.messageManager.sendAsyncMessage("Browser:InvokeContextAtPoint", { + xPos: aEvent.clientX, yPos: aEvent.clientY }); + ]]> + </body> + </method> + + <method name="handleEvent"> + <parameter name="aEvent"/> + <body> + <![CDATA[ + switch (aEvent.type) { + case 'contextmenu': + this._onContextMenu(aEvent); + break; + } + ]]> + </body> + </method> + <method name="addDebugRect"> <parameter name="aLeft"/> <parameter name="aTop"/> <parameter name="aRight"/> <parameter name="aBottom"/> <parameter name="aColor"/> <parameter name="aFill"/> <parameter name="aId"/>
--- a/browser/metro/base/content/contenthandlers/Content.js +++ b/browser/metro/base/content/contenthandlers/Content.js @@ -162,42 +162,48 @@ const ElementTouchHelper = { }; /* * Global functions */ /* - * elementFromPoint + * elementFromPoint - find the closes element at a point. searches + * sub-frames. * - * @param x,y Browser coordinates - * @return Element at position, null if no active browser or no element found + * @param aX, aY browser coordinates + * @return + * element - element at the position, or null if no active browser or + * element was found. + * frameX - x position within the subframe element was found. aX if no + * sub-frame was found. + * frameY - y position within the subframe element was found. aY if no + * sub-frame was found. */ -function elementFromPoint(x, y) { +function elementFromPoint(aX, aY) { // browser's elementFromPoint expect browser-relative client coordinates. // subtract browser's scroll values to adjust let cwu = Util.getWindowUtils(content); - let elem = ElementTouchHelper.getClosest(cwu, x, y); + let elem = ElementTouchHelper.getClosest(cwu, aX, aY); // step through layers of IFRAMEs and FRAMES to find innermost element while (elem && (elem instanceof HTMLIFrameElement || elem instanceof HTMLFrameElement)) { // adjust client coordinates' origin to be top left of iframe viewport let rect = elem.getBoundingClientRect(); - x -= rect.left; - y -= rect.top; + aX -= rect.left; + aY -= rect.top; let windowUtils = elem.contentDocument .defaultView .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); - elem = ElementTouchHelper.getClosest(windowUtils, x, y); + elem = ElementTouchHelper.getClosest(windowUtils, aX, aY); } - - return elem; + return { element: elem, frameX: aX, frameY: aY }; } /* * getBoundingContentRect * * @param aElement * @return Bounding content rect adjusted for scroll and frame offsets. */ @@ -395,34 +401,34 @@ let Content = { /****************************************************** * generic input handlers * * regardless of whether the input was received via * message manager or sent directly via dispatch. */ _genericMouseDown: function _genericMouseDown(x, y) { - let element = elementFromPoint(x, y); + let { element } = elementFromPoint(x, y); if (!element) return; // There is no need to have a feedback for disabled element let isDisabled = element instanceof HTMLOptionElement ? (element.disabled || element.parentNode.disabled) : element.disabled; if (isDisabled) return; // Set the target element to active this._doTapHighlight(element); }, _genericMouseClick: function _genericMouseClick(aEvent) { ContextMenuHandler.reset(); - let element = elementFromPoint(aEvent.clientX, aEvent.clientY); + let { element: element } = elementFromPoint(aEvent.clientX, aEvent.clientY); if (!element) return; // Only show autocomplete after the item is clicked if (!this.lastClickElement || this.lastClickElement != element) { this.lastClickElement = element; if (aEvent.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE && !(element instanceof HTMLSelectElement)) {
--- a/browser/metro/base/content/contenthandlers/ContextMenuHandler.js +++ b/browser/metro/base/content/contenthandlers/ContextMenuHandler.js @@ -86,18 +86,19 @@ var ContextMenuHandler = { }, /* * Handler for selection overlay context menu events. */ _onContextAtPoint: function _onContextCommand(aMessage) { // we need to find popupNode as if the context menu were // invoked on underlying content. - let elem = elementFromPoint(aMessage.json.xPos, aMessage.json.yPos); - this._processPopupNode(elem, aMessage.json.xPos, aMessage.json.yPos, + let { element, frameX, frameY } = + elementFromPoint(aMessage.json.xPos, aMessage.json.yPos); + this._processPopupNode(element, frameX, frameY, Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH); }, /****************************************************** * Event handlers */ reset: function ch_reset() { @@ -166,30 +167,39 @@ var ContextMenuHandler = { while (element && element.ownerDocument && element.ownerDocument.defaultView != content) { element = element.ownerDocument.defaultView.frameElement; let rect = element.getBoundingClientRect(); offsetX += rect.left; offsetY += rect.top; } - return { offsetX: offsetX, offsetY: offsetY }; + let win = null; + if (element == aPopupNode) + win = content; + else + win = element.contentDocument.defaultView; + return { targetWindow: win, offsetX: offsetX, offsetY: offsetY }; }, /* * _processPopupNode - Generate and send a Content:ContextMenu message * to browser detailing the underlying content types at this.popupNode. * Note the event we receive targets the sub frame (if there is one) of * the page. */ _processPopupNode: function _processPopupNode(aPopupNode, aX, aY, aInputSrc) { if (!aPopupNode) return; - let { offsetX: offsetX, offsetY: offsetY } = + + let { targetWindow: targetWindow, + offsetX: offsetX, + offsetY: offsetY } = this._translateToTopLevelWindow(aPopupNode); + let popupNode = this.popupNode = aPopupNode; let imageUrl = ""; let state = { types: [], label: "", linkURL: "", linkTitle: "", @@ -293,19 +303,19 @@ var ContextMenuHandler = { elem = elem.parentNode; } // Over arching text tests if (isText) { // If this is text and has a selection, we want to bring // up the copy option on the context menu. - if (content && content.getSelection() && - content.getSelection().toString().length > 0) { - state.string = content.getSelection().toString(); + let selection = targetWindow.getSelection(); + if (selection && selection.toString().length > 0) { + state.string = targetWindow.getSelection().toString(); state.types.push("copy"); state.types.push("selected-text"); } else { // Add general content text if this isn't anything specific if (state.types.indexOf("image") == -1 && state.types.indexOf("media") == -1 && state.types.indexOf("video") == -1 && state.types.indexOf("link") == -1 &&