Bug 940952 - Support repositioning selection markers when browser scale changes, and get selection while zoomed working. r=mbrubeck

This commit is contained in:
Jim Mathies 2013-11-26 14:14:40 -06:00
parent 31164cf6fa
commit a5986cea6a
3 changed files with 79 additions and 27 deletions

View File

@ -95,6 +95,15 @@
* @param aIgnoreScale ignore current scale factor.
* @return { x: converted x coordinate, y: converted y coordinate }
*
* rectClientToBrowser
* Convert a client Rect() in device pixels to page-relative
* coordinates in CSS pixels.
*
* @param aRect - client Rect to convert.
* @param aIgnoreScroll ignore root frame scroll.
* @param aIgnoreScale ignore current scale factor.
* @return converted Rect()
*
* ctobx, ctoby
* Convert individual x and y coordinates.
*
@ -172,6 +181,39 @@
</body>
</method>
<method name="rectClientToBrowser">
<parameter name="aClientRect"/>
<parameter name="aIgnoreScroll"/>
<parameter name="aIgnoreScale"/>
<body>
<![CDATA[
let ignoreScroll = aIgnoreScroll || false;
let ignoreScale = aIgnoreScale || false;
let scrollX = 0;
let scrollY = 0;
if (!ignoreScroll) {
let scroll = this.getRootView().getPosition();
scrollX = scroll.x;
scrollY = scroll.y;
}
let scale = 1;
if (!ignoreScale) {
scale = this.scale;
}
let bcr = this.getBoundingClientRect();
return new Rect(
(aClientRect.x + scrollX - bcr.left) / scale,
(aClientRect.y + scrollY - bcr.top) / scale,
aClientRect.width / scale,
aClientRect.height / scale
);
]]>
</body>
</method>
<method name="ctobx">
<parameter name="aX"/>
<parameter name="aIgnoreScroll"/>
@ -597,6 +639,18 @@
<field name="_frameLoader">null</field>
<field name="_contentViewManager">null</field>
<!--
* Returns the current content viewport bounds in browser coordinates
* taking into account zoom and scroll.
*
* @return Rect()
-->
<property name="contentViewportBounds">
<getter><![CDATA[
return this.rectClientToBrowser(this.getBoundingClientRect());
]]></getter>
</property>
<!-- Dimensions of content window -->
<field name="_contentWindowWidth">0</field>
<field name="_contentWindowHeight">0</field>

View File

@ -806,13 +806,31 @@ var SelectionHelperUI = {
_showMonocles: function _showMonocles(aSelection) {
if (!aSelection) {
this.caretMark.show();
if (this._checkMonocleVisibility(this.caretMark.xPos, this.caretMark.yPos)) {
this.caretMark.show();
}
} else {
this.endMark.show();
this.startMark.show();
if (this._checkMonocleVisibility(this.endMark.xPos, this.endMark.yPos)) {
this.endMark.show();
}
if (this._checkMonocleVisibility(this.startMark.xPos, this.startMark.yPos)) {
this.startMark.show();
}
}
},
_checkMonocleVisibility: function(aX, aY) {
let viewport = Browser.selectedBrowser.contentViewportBounds;
aX = this._msgTarget.ctobx(aX);
aY = this._msgTarget.ctoby(aY);
if (aX < viewport.x || aY < viewport.y ||
aX > (viewport.x + viewport.width) ||
aY > (viewport.y + viewport.height)) {
return false;
}
return true;
},
/*
* Event handlers for document events
*/
@ -914,16 +932,6 @@ var SelectionHelperUI = {
this._shutdown();
},
_checkMonocleVisibility: function(aX, aY) {
if (aX < 0 || aY < 0 ||
aX > ContentAreaObserver.viewableWidth ||
aY > ContentAreaObserver.viewableHeight) {
this.closeEditSession(true);
return false;
}
return true;
},
/*
* Message handlers
*/
@ -938,33 +946,25 @@ var SelectionHelperUI = {
if (json.updateStart) {
let x = this._msgTarget.btocx(json.start.xPos, true);
let y = this._msgTarget.btocx(json.start.yPos, true);
if (!this._checkMonocleVisibility(x, y)) {
return;
}
this.startMark.position(x, y);
}
if (json.updateEnd) {
let x = this._msgTarget.btocx(json.end.xPos, true);
let y = this._msgTarget.btocx(json.end.yPos, true);
if (!this._checkMonocleVisibility(x, y)) {
return;
}
this.endMark.position(x, y);
}
if (json.updateCaret) {
let x = this._msgTarget.btocx(json.caret.xPos, true);
let y = this._msgTarget.btocx(json.caret.yPos, true);
if (!this._checkMonocleVisibility(x, y)) {
return;
}
// If selectionRangeFound is set SelectionHelper found a range we can
// attach to. If not, there's no text in the control, and hence no caret
// position information we can use.
haveSelectionRect = json.selectionRangeFound;
if (json.selectionRangeFound) {
this.caretMark.position(x, y);
this.caretMark.show();
this._showMonocles(false);
}
}
@ -980,7 +980,7 @@ var SelectionHelperUI = {
this._targetElementRect =
this._msgTarget.rectBrowserToClient(json.element, true);
// Ifd this is the end of a selection move show the appropriate
// If this is the end of a selection move show the appropriate
// monocle images. src=(start, update, end, caret)
if (json.src == "start" || json.src == "end") {
this._showMonocles(true);

View File

@ -1631,7 +1631,5 @@ MetroWidget::Observe(nsISupports *subject, const char *topic, const PRUnichar *d
ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId);
APZController::sAPZC->UpdateZoomConstraints(guid, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f));
}
else {
return NS_OK;
}
return NS_OK;
}