Skip to content

Commit

Permalink
fix(RTL): Use feature detection to determine RTL
Browse files Browse the repository at this point in the history
Rather than relying on browser detection to determine how scrollLeft will
be defined when an element is RTL, use the method from this library:
https://github.com/othree/jquery.rtl-scroll-type which creates a temporary
element to see how scrollLeft turns out.

Fixes #1689
  • Loading branch information
c0bra committed Mar 11, 2015
1 parent 220d7b9 commit fbb3631
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 59 deletions.
4 changes: 2 additions & 2 deletions src/js/core/directives/ui-grid-render-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
// Horizontal scroll
if (args.x && $scope.bindScrollHorizontal) {
containerCtrl.prevScrollArgs = args;
var newScrollLeft = args.getNewScrollLeft(colContainer,containerCtrl.viewport);
var newScrollLeft = args.getNewScrollLeft(colContainer, containerCtrl.viewport);

// Make the current horizontal scroll position available in the $scope
$scope.newScrollLeft = newScrollLeft;
Expand All @@ -112,7 +112,7 @@

// Scroll came from somewhere else, so the viewport must be positioned
if (args.source !== ScrollEvent.Sources.ViewPortScroll) {
containerCtrl.viewport[0].scrollLeft = newScrollLeft;
containerCtrl.viewport[0].scrollLeft = gridUtil.denormalizeScrollLeft(containerCtrl.viewport, newScrollLeft);
}

containerCtrl.prevScrollLeft = newScrollLeft;
Expand Down
111 changes: 54 additions & 57 deletions src/js/core/services/ui-grid-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,34 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
return 'unknown';
};

// Borrowed from https://github.com/othree/jquery.rtl-scroll-type
// Determine the scroll "type" this browser is using for RTL
s.rtlScrollType = function rtlScrollType() {
if (rtlScrollType.type) {
return rtlScrollType.type;
}

var definer = angular.element('<div dir="rtl" style="font-size: 14px; width: 1px; height: 1px; position: absolute; top: -1000px; overflow: scroll">A</div>')[0],
type = 'reverse';

document.body.appendChild(definer);

if (definer.scrollLeft > 0) {
type = 'default';
}
else {
definer.scrollLeft = 1;
if (definer.scrollLeft === 0) {
type = 'negative';
}
}

definer.remove();
rtlScrollType.type = type;

return type;
};

/**
* @ngdoc method
* @name normalizeScrollLeft
Expand All @@ -896,37 +924,22 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
element = element[0];
}

var browser = s.detectBrowser();

var scrollLeft = element.scrollLeft;

var dir = s.getStyles(element)['direction'];

// IE stays normal in RTL
if (browser === 'ie') {
return scrollLeft;
}
// Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
else if (browser === 'chrome') {
if (dir === 'rtl') {
// Get the max scroll for the element
var maxScrollLeft = element.scrollWidth - element.clientWidth;

// Subtract the current scroll amount from the max scroll
return maxScrollLeft - scrollLeft;
var dir = s.getStyles(element).direction;

if (dir === 'rtl') {
switch (s.rtlScrollType()) {
case 'default':
return element.scrollWidth - scrollLeft - element.clientWidth;
case 'negative':
return scrollLeft + element.scrollWidth - element.clientWidth;
case 'reverse':
return scrollLeft;
}
else {
return scrollLeft;
}
}
// Firefox goes negative!
else if (browser === 'firefox') {
return Math.abs(scrollLeft);
}
else {
// TODO(c0bra): Handle other browsers? Android? iOS? Opera?
return scrollLeft;
}

return scrollLeft;
};

/**
Expand All @@ -947,40 +960,24 @@ module.service('gridUtil', ['$log', '$window', '$document', '$http', '$templateC
element = element[0];
}

var browser = s.detectBrowser();
var dir = s.getStyles(element).direction;

var dir = s.getStyles(element)['direction'];
if (dir === 'rtl') {
switch (s.rtlScrollType()) {
case 'default':
// Get the max scroll for the element
var maxScrollLeft = element.scrollWidth - element.clientWidth;

// IE stays normal in RTL
if (browser === 'ie') {
return scrollLeft;
}
// Chrome doesn't alter the scrollLeft value. So with RTL on a 400px-wide grid, the right-most position will still be 400 and the left-most will still be 0;
else if (browser === 'chrome') {
if (dir === 'rtl') {
// Get the max scroll for the element
var maxScrollLeft = element.scrollWidth - element.clientWidth;

// Subtract the current scroll amount from the max scroll
return maxScrollLeft - scrollLeft;
}
else {
return scrollLeft;
// Subtract the current scroll amount from the max scroll
return maxScrollLeft - scrollLeft;
case 'negative':
return scrollLeft * -1;
case 'reverse':
return scrollLeft;
}
}
// Firefox goes negative!
else if (browser === 'firefox') {
if (dir === 'rtl') {
return scrollLeft * -1;
}
else {
return scrollLeft;
}
}
else {
// TODO(c0bra): Handle other browsers? Android? iOS? Opera?
return scrollLeft;
}

return scrollLeft;
};

/**
Expand Down

0 comments on commit fbb3631

Please sign in to comment.