<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js">Ext.define('Ext.rtl.dom.Element_scroll', {
|
override: 'Ext.dom.Element',
|
|
rtlGetScroll: function() {
|
var me = this,
|
dom = me.dom,
|
doc = document,
|
body = doc.body,
|
scroll = me.getScroll(),
|
// The left value returned from getScroll() may be a negative number. In rtl
|
// mode left should always be reported as a positive number of pixels from the
|
// right, so use the absolute value of left.
|
left = Math.abs(scroll.left),
|
isDocOrBody = (dom === doc || dom === body);
|
|
if (isDocOrBody ? (3 & me._rtlDocScrollFlag) : (me._rtlScrollFlag === 1)) {
|
// If the browser reports scrollLeft as the number of pixels from left
|
// (same as ltr) we need to convert it to a rtl position by subtracting it
|
// from scrollWidth
|
if (isDocOrBody) {
|
dom = body;
|
}
|
|
left = dom.scrollWidth - left -
|
(isDocOrBody ? Ext.Element.getViewportWidth() : dom.clientWidth);
|
}
|
scroll.left = left;
|
|
return scroll;
|
},
|
|
rtlGetScrollLeft: function() {
|
return this.rtlGetScroll().left;
|
},
|
|
rtlSetScrollLeft: function(left){
|
var me = this;
|
|
me.dom.scrollLeft = me.rtlNormalizeScrollLeft(left);
|
return me;
|
},
|
|
rtlScrollTo: function(side, value, animate) {
|
if (side === 'left') {
|
value = this.rtlNormalizeScrollLeft(value);
|
}
|
|
return this.scrollTo(side, value, animate);
|
},
|
|
rtlScrollBy: function(deltaX, deltaY, animate) {
|
var me = this,
|
dom = me.dom,
|
left, maxScroll;
|
|
// Extract args if deltas were passed as an Array.
|
if (deltaX.length) {
|
animate = deltaY;
|
deltaY = deltaX[1];
|
deltaX = deltaX[0];
|
} else if (typeof deltaX != 'number') { // or an object
|
animate = deltaY;
|
deltaY = deltaX.y;
|
deltaX = deltaX.x;
|
}
|
|
if (deltaX) {
|
left = me.rtlNormalizeScrollLeft(
|
me.constrainScrollLeft(me.rtlGetScrollLeft() + deltaX)
|
);
|
|
me.scrollTo('left', left, animate);
|
}
|
if (deltaY) {
|
me.scrollTo('top', me.constrainScrollTop(dom.scrollTop + deltaY), animate);
|
}
|
|
return me;
|
},
|
|
rtlScroll: function(direction, distance, animate) {
|
if (!this.isScrollable()) {
|
return false;
|
}
|
var me = this,
|
side = direction === 'r' || direction === 'l' ? 'left' : 'top',
|
scrolled = false,
|
currentScroll, constrainedScroll;
|
|
if (direction === 'r') {
|
distance = -distance;
|
}
|
|
if (side === 'left') {
|
currentScroll = me.rtlGetScrollLeft();
|
constrainedScroll = me.constrainScrollLeft(currentScroll + distance);
|
} else {
|
currentScroll = me.dom.scrollTop;
|
constrainedScroll = me.constrainScrollTop(currentScroll + distance);
|
}
|
|
if (constrainedScroll !== currentScroll) {
|
this.rtlScrollTo(side, constrainedScroll, animate);
|
scrolled = true;
|
}
|
|
return scrolled;
|
},
|
|
rtlNormalizeScrollLeft: function(left){
|
var dom = this.dom,
|
flag = this._rtlScrollFlag;
|
|
if (flag === 0) {
|
left = -left;
|
} else if (flag === 1) {
|
left = dom.scrollWidth - left - dom.clientWidth;
|
}
|
return left;
|
}
|
|
}, function() {
|
var Element = this;
|
|
/*
|
* Sets a _rtlScrollFlag property on the Element class prototype indicating how the
|
* browser reports scrollLeft on overflowing rtl elements. This method cannot be used
|
* reliably on the documentElement or document.body because the behavior of these
|
* elements can be different from other elements in some browsers.
|
*
|
* 0: offset from right (negative number) - firefox
|
* 1: offset from left (positive number) - IE6, IE7, IE6 - IE9 quirks, and Webkit
|
* 2: offset from right (positive number) - IE8 - IE10 & IE10 quirks
|
*/
|
function cacheRtlScrollFlag() {
|
var el = Ext.getBody().createChild({
|
tag: 'div',
|
style: 'direction:rtl;position:absolute;overflow:auto;height:100px;width:100px;',
|
children: [{
|
tag: 'div',
|
style: 'height:30px;width:150px;'
|
}]
|
}),
|
dom = el.dom,
|
flag = 2;
|
|
if (dom.scrollLeft === 50) {
|
flag = 1;
|
} else {
|
dom.scrollLeft = -1;
|
if (dom.scrollLeft) {
|
flag = 0;
|
}
|
}
|
|
el.remove();
|
Element.prototype._rtlScrollFlag = flag;
|
}
|
|
/*
|
* scrollLeft on the document/body is reported differently from ordinary
|
* overflowing elements in many browsers (see getRtlScrollFlag).There are 2
|
* separate things we have to detect:
|
* 1. The element that overflows - when the document overflows some browsers
|
* set scrollLeft on the document body (webkit and IE quirks), while other
|
* browsers set scrollLeft on the documentElement (all other supported browsers
|
* at the time of this writing).
|
* 2. The scrollLeft of the overflowing document/body can be one of the
|
* following:
|
* a. number of pixels offset from right expressed as a negative number
|
* (Webkit, Firefox)
|
* b. number of pixels offset from right expressed as a positive number
|
* (IE8 - IE10 strict mode, and IE10 quirks mode.
|
* c. number of pixels offset from left expressed as a positive number
|
* (IE6 - IE9 quirks mode, and IE6/IE7 strict mode.
|
*
|
* The following logic feture detects the handling of scrollLeft and sets the
|
* _rtlDocScrollFlag property on this class' prototype as a bit flag which has
|
* the following values:
|
*
|
* 0 - docEl, negative right
|
* 1 - docEl, positive left
|
* 2 - docEl, positive right
|
* 4 - body, negative right
|
* 5 - body, positive left
|
*/
|
function cacheRtlDocScrollFlag() {
|
var doc = document,
|
docEl = doc.documentElement,
|
body = doc.body,
|
// flag defaults to body, negative right (webkit) so no detection needed
|
// is needed for this scenario
|
flag = 4,
|
bodyStyle = body.style,
|
// save the direction property so we can set it back when we are done.
|
direction = bodyStyle.direction,
|
el = Ext.getBody().createChild(
|
'<div style="height:20000px;width:20000px;"></div>'
|
),
|
dom = el.dom,
|
ltrRight, rtlRight
|
|
bodyStyle.direction = 'ltr';
|
ltrRight = dom.getBoundingClientRect().right;
|
|
bodyStyle.direction = 'rtl';
|
rtlRight = dom.getBoundingClientRect().right;
|
|
// when the body has vertical overflow some browser continue to show the
|
// vertical scrollbar on the right side of the page even in rtl mode.
|
Element.prototype._rtlBodyScrollbarOnRight = (ltrRight === rtlRight);
|
|
// First, check if scrollLeft is a non-zero value on the documentElement or
|
// body. This means scrollLeft is a positive number offset from the left.
|
if (docEl.scrollLeft > 0) {
|
// IE6/7 strict
|
flag = 1;
|
} else if (body.scrollLeft > 0) {
|
// IE6 - IE9 quirks
|
flag = 5;
|
} else {
|
// The next step is to attempt to set scrollLeft values, This allows us to
|
// test for non-zero values to see if the value was valid (scrollLeft
|
// resets to 0 when a non-valid value is set).
|
// attempt to set the documentElement's scrollLeft to a negative number
|
docEl.scrollLeft = -1;
|
if (docEl.scrollLeft) {
|
// it worked! we were able to set a negative scroll left on the
|
// documentElement (firefox)
|
flag = 0;
|
} else {
|
// attempt to set the documentElement's scrollLeft to a positive number
|
docEl.scrollLeft = 1;
|
if (docEl.scrollLeft) {
|
// success setting scroll left to a positive number on
|
// documentElement (IE8 strict, IE9 strict, and IE10 quirks)
|
flag = 2;
|
}
|
}
|
}
|
|
el.remove();
|
if (!direction) {
|
// if direction is an empty string, we set it back to "ltr", because once
|
// the direction style on the body element is changed to "rtl" in webkit,
|
// it becomes permanent, even after it is set back to "", unless it is first
|
// explicitly set back to "ltr"
|
bodyStyle.direction = 'ltr';
|
// read the scroll width before setting the direction back to "".
|
// This forces webkit to update its computed direction style to ltr
|
body.scrollWidth;
|
}
|
// set direction back to its original value
|
bodyStyle.direction = direction;
|
Element.prototype._rtlDocScrollFlag = flag;
|
}
|
|
Ext.on({
|
ready: function() {
|
// This function attaches to onReady with a priority of 1000 so that we can
|
// detect how the browser reports scrollLeft by manipulating the document/body
|
// before any components have been rendered to the page.
|
cacheRtlDocScrollFlag();
|
cacheRtlScrollFlag();
|
},
|
single: true,
|
priority: 1001
|
});
|
});
|
</pre>
|
</body>
|
</html>
|