Esanders has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/160579

Change subject: Remove getSelection*Client* methods
......................................................................

Remove getSelection*Client* methods

Maintaining two versions for one optimisation is too much work.

Change-Id: I92fdcc24c6114e5e02d5bc5b227b1660d2429e52
---
M src/ce/ve.ce.Surface.js
M src/ui/ve.ui.DesktopContext.js
M src/ui/ve.ui.Toolbar.js
M tests/ce/ve.ce.Surface.test.js
4 files changed, 75 insertions(+), 106 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/79/160579/1

diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index dd26b76..04faf41 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -317,27 +317,18 @@
 };
 
 /**
- * Get the inline coordinates of the selection range relative to the viewport.
+ * Get the inline coordinates of the selection range relative to the surface.
  *
- * Returned coordinates are client coordinates (i.e. relative to the viewport).
- * For coordinates relative to the surface, use 
#getSelectionInlineRelativeRects
+ * Returned coordinates are relative to the surface.
  *
  * @method
  * @returns {Object|null} Start and end selection rectangles
  */
-ve.ce.Surface.prototype.getSelectionInlineClientRects = function () {
-       var inlineRects, nativeRange, surfaceRect, boundingRect, rtl, x, 
collapsedRect;
+ve.ce.Surface.prototype.getSelectionInlineRects = function () {
+       var inlineRects, nativeRange, surfaceRect, focusNodeRect, rtl, x, 
collapsedRect;
+
        if ( this.focusedNode ) {
-               inlineRects = this.focusedNode.getInlineRects();
-               surfaceRect = this.getSurface().getBoundingClientRect();
-               if ( !inlineRects || !surfaceRect ) {
-                       return null;
-               }
-               // Convert surface relative coords to client coords
-               return {
-                       start: ve.translateRect( inlineRects.start, 
surfaceRect.left, surfaceRect.top ),
-                       end: ve.translateRect( inlineRects.end, 
surfaceRect.left, surfaceRect.top )
-               };
+               return this.focusedNode.getInlineRects();
        }
 
        nativeRange = this.getNativeRange();
@@ -349,29 +340,29 @@
        // * in Firefox on page load when the address bar is still focused
        // * in empty paragraphs
        try {
-               return ve.getStartAndEndRects( nativeRange.getClientRects() );
+               inlineRects = ve.getStartAndEndRects( 
nativeRange.getClientRects() );
        } catch ( e ) {
                // When possible, pretend the cursor is the left/right border 
of the node
                // (depending on directionality) as a fallback.
                if ( this.nativeSelection.focusNode && 
this.nativeSelection.focusNode.nodeType === Node.ELEMENT_NODE ) {
                        // We would use getBoundingClientRect(), but in iOS7 
that's relative to the
                        // document rather than to the viewport
-                       boundingRect = 
this.nativeSelection.focusNode.getClientRects()[0];
-                       if ( !boundingRect ) {
+                       focusNodeRect = 
this.nativeSelection.focusNode.getClientRects()[0];
+                       if ( !focusNodeRect ) {
                                // FF can return null when focusNode is 
invisible
                                return null;
                        }
                        rtl = this.getModel().getDocument().getDir() === 'rtl';
-                       x = rtl ? boundingRect.right : boundingRect.left;
+                       x = rtl ? focusNodeRect.right : focusNodeRect.left;
                        collapsedRect = {
-                               top: boundingRect.top,
-                               bottom: boundingRect.bottom,
+                               top: focusNodeRect.top,
+                               bottom: focusNodeRect.bottom,
                                left: x,
                                right: x,
                                width: 0,
-                               height: boundingRect.height
+                               height: focusNodeRect.height
                        };
-                       return {
+                       inlineRects = {
                                start: collapsedRect,
                                end: collapsedRect
                        };
@@ -379,75 +370,7 @@
                        return null;
                }
        }
-};
 
-/**
- * Get the bounding coordinates of the selection relative to the viewport.
- *
- * Returned coordinates are client coordinates (i.e. relative to the viewport).
- * For coordinates relative to the surface, use 
#getSelectionBoundingRelativeRect
- *
- * @method
- * @returns {Object|null} Selection rectangle, with keys top, bottom, left, 
right, width, height
- */
-ve.ce.Surface.prototype.getSelectionBoundingClientRect = function () {
-       var inlineRects, boundingRect, surfaceRect, nativeRange;
-
-       if ( this.focusedNode ) {
-               boundingRect = this.focusedNode.getBoundingRect();
-               surfaceRect = this.getSurface().getBoundingClientRect();
-               if ( !boundingRect || !surfaceRect ) {
-                       return;
-               }
-               // Convert surface relative coords to client coords
-               return ve.translateRect( boundingRect, surfaceRect.left, 
surfaceRect.top );
-       }
-
-       // We can't do anything if there's no selection
-       if ( this.nativeSelection.rangeCount === 0 ) {
-               return null;
-       }
-
-       nativeRange = this.getNativeRange();
-       if ( !nativeRange ) {
-               return null;
-       }
-
-       try {
-               inlineRects = nativeRange.getClientRects();
-               // Try the zeroth inline rect first as Chrome sometimes returns 
a rectangle
-               // full of zeros for getBoundingClientRect when the cursor is 
collapsed.
-               // We could test for this failure and fall back to inline[0], 
except for the
-               // fact that the bounding rect is 1px bigger than inline[0], so 
cursoring across
-               // a link causes a verticle wobble as it alternately breaks and 
unbreaks.
-               // See 
https://code.google.com/p/chromium/issues/detail?id=238976
-               if ( inlineRects.length === 1 ) {
-                       return inlineRects[0];
-               }
-               return nativeRange.getBoundingClientRect();
-       } catch ( e ) {
-               return null;
-       }
-};
-
-/**
- * Get the inline coordinates of the selection range relative to the surface.
- *
- * Returned coordinates are relative to the surface. For client coordinates,
- * use #getSelectionInlineClientRects.
- *
- * @method
- * @returns {Object|null} Start and end selection rectangles
- */
-ve.ce.Surface.prototype.getSelectionInlineRelativeRects = function () {
-       var inlineRects, surfaceRect;
-
-       if ( this.focusedNode ) {
-               // We can optimize the focusedNode case as we already have the 
relative coordinates
-               return this.focusedNode.getInlineRects();
-       }
-
-       inlineRects = this.getSelectionInlineClientRects();
        surfaceRect = this.getSurface().getBoundingClientRect();
        if ( !inlineRects || !surfaceRect ) {
                return null;
@@ -461,20 +384,23 @@
 /**
  * Get the coordinates of the selection anchor relative to the surface.
  *
- * Returned coordinates are relative to the surface. For client coordinates,
- * use #getSelectionBoundingClientRect.
+ * Returned coordinates are relative to the surface.
  *
  * @method
  * @returns {Object|null} Selection rectangle, with keys top, bottom, left, 
right, width, height
  */
-ve.ce.Surface.prototype.getSelectionBoundingRelativeRect = function () {
-       var boundingRect, surfaceRect;
+ve.ce.Surface.prototype.getSelectionBoundingRect = function () {
+       var nativeRange, boundingRect, surfaceRect;
        if ( this.focusedNode ) {
-               // We can optimize the focusedNode case as we already have the 
relative coordinates
                return this.focusedNode.getBoundingRect();
        }
 
-       boundingRect = this.getSelectionBoundingClientRect();
+       nativeRange = this.getNativeRange();
+       if ( !nativeRange ) {
+               return null;
+       }
+
+       boundingRect = this.getNativeRangeBoundingClientRect( nativeRange );
        surfaceRect = this.getSurface().getBoundingClientRect();
        if ( !boundingRect || !surfaceRect ) {
                return null;
@@ -2467,6 +2393,44 @@
 };
 
 /**
+ * Get bounding client rect of a native range
+ *
+ * Works around some browser bugs in Range#getBoundingClientRect
+ *
+ * @param {Range} nativeRange Native range to get the bounding client rect of
+ * @return {ClientRect|null} Client rectangle of the native selection, or null 
if there was a problem
+ */
+ve.ce.Surface.prototype.getNativeRangeBoundingClientRect = function ( 
nativeRange ) {
+       var inlineRects;
+
+       if ( !nativeRange ) {
+               return null;
+       }
+
+       try {
+               inlineRects = nativeRange.getClientRects();
+               if ( inlineRects.length === 0 ) {
+                       // If there are no inline rects return null, otherwise 
we'll fall through to
+                       // getBoundingClientRect, which in Chrome becomes 
[0,0,0,0].
+                       return null;
+               } else if ( inlineRects.length === 1 ) {
+                       // Try the zeroth inline rect first as Chrome sometimes 
returns a rectangle
+                       // full of zeros for getBoundingClientRect when the 
cursor is collapsed.
+                       // We could test for this failure and fall back to 
inline[0], except for the
+                       // fact that the bounding rect is 1px bigger than 
inline[0], so cursoring across
+                       // a link causes a verticle wobble as it alternately 
breaks and unbreaks.
+                       // See 
https://code.google.com/p/chromium/issues/detail?id=238976
+                       return inlineRects[0];
+               } else {
+                       // After two browser bugs it's finally safe to try the 
bounding rect.
+                       return nativeRange.getBoundingClientRect();
+               }
+       } catch ( e ) {
+               return null;
+       }
+};
+
+/**
  * Append passed highlights to highlight container.
  *
  * @method
diff --git a/src/ui/ve.ui.DesktopContext.js b/src/ui/ve.ui.DesktopContext.js
index 06ec337..9787bba 100644
--- a/src/ui/ve.ui.DesktopContext.js
+++ b/src/ui/ve.ui.DesktopContext.js
@@ -182,7 +182,7 @@
                rtl = this.surface.getModel().getDocument().getDir() === 'rtl',
                surface = this.surface.getView(),
                focusedNode = surface.getFocusedNode(),
-               boundingRect = surface.getSelectionBoundingRelativeRect();
+               boundingRect = surface.getSelectionBoundingRect();
 
        $container = this.inspector ? this.inspector.$frame : 
this.menu.$element;
 
@@ -209,7 +209,7 @@
                }
        } else {
                // The selection is text or an inline focused node
-               inlineRects = surface.getSelectionInlineRelativeRects();
+               inlineRects = surface.getSelectionInlineRects();
                if ( inlineRects && boundingRect ) {
                        middle = ( boundingRect.left + boundingRect.right ) / 2;
                        if (
@@ -229,7 +229,7 @@
                                };
                        }
                }
-               // If !inlineRects, the surface apparently isn't selected, so 
getSelectionBoundingRelativeRect()
+               // If !inlineRects, the surface apparently isn't selected, so 
getSelectionBoundingRect()
                // returned null. This shouldn't happen because the context is 
only supposed to be
                // displayed in response to a selection, but for some reason 
this does happen when opening
                // an inspector without changing the selection.
diff --git a/src/ui/ve.ui.Toolbar.js b/src/ui/ve.ui.Toolbar.js
index 04f2616..a0e44c0 100644
--- a/src/ui/ve.ui.Toolbar.js
+++ b/src/ui/ve.ui.Toolbar.js
@@ -140,13 +140,20 @@
  * FIXME: this code should be in a target class or something
  */
 ve.ui.Toolbar.prototype.onSurfaceViewKeyUp = function () {
-       var clientRect, barHeight, scrollTo, obscured;
+       var surfaceView, nativeRange, clientRect, barHeight, scrollTo, obscured;
 
        if ( !this.floating ) {
                return;
        }
 
-       clientRect = 
this.getSurface().getView().getSelectionBoundingClientRect();
+       surfaceView = this.getSurface().getView();
+
+       nativeRange = surfaceView.getNativeRange();
+       if ( !nativeRange ) {
+               return null;
+       }
+
+       clientRect = surfaceView.getNativeRangeBoundingClientRect( nativeRange 
);
        if ( !clientRect ) {
                return;
        }
diff --git a/tests/ce/ve.ce.Surface.test.js b/tests/ce/ve.ce.Surface.test.js
index 4cd7aa7..c0ee222 100644
--- a/tests/ce/ve.ce.Surface.test.js
+++ b/tests/ce/ve.ce.Surface.test.js
@@ -1088,10 +1088,8 @@
 // TODO: ve.ce.Surface#getDocument
 // TODO: ve.ce.Surface#getFocusedNode
 // TODO: ve.ce.Surface#isRenderingLocked
-// TODO: ve.ce.Surface#getSelectionBoundingClientRect
-// TODO: ve.ce.Surface#getSelectionBoundingRelativeRect
-// TODO: ve.ce.Surface#getSelectionInlineClientRects
-// TODO: ve.ce.Surface#getSelectionInlineRelativeRects
+// TODO: ve.ce.Surface#getSelectionBoundingRect
+// TODO: ve.ce.Surface#getSelectionInlineRects
 
 /* Methods without return values */
 // TODO: ve.ce.Surface#initialize

-- 
To view, visit https://gerrit.wikimedia.org/r/160579
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I92fdcc24c6114e5e02d5bc5b227b1660d2429e52
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to