]> git.proxmox.com Git - extjs.git/blob - extjs/classic/classic/src/rtl/Component.js
add extjs 6.0.1 sources
[extjs.git] / extjs / classic / classic / src / rtl / Component.js
1 /**
2 * This override adds RTL support and the `rtl` config option to AbstactComponent.
3 */
4 Ext.define('Ext.rtl.Component', {
5 override: 'Ext.Component',
6
7 /**
8 * @cfg {Boolean} rtl
9 * True to layout this component and its descendants in "rtl" (right-to-left) mode.
10 * Can be explicitly set to false to override a true value inherited from an ancestor.
11 */
12
13 applyScrollable: function(scrollable, oldScrollable) {
14 var ret = this.callParent([scrollable, oldScrollable]);
15
16 if (ret && this.getInherited().rtl) {
17 ret.setRtl(true);
18 }
19
20 return ret;
21 },
22
23 convertPositionSpec: function(posSpec) {
24 // Since anchoring is done based on page level coordinates, we need to invert
25 // left and right in the position spec when the direction of the compoent being
26 // aligned is not the same as the direction of the viewport/body
27 if ((Ext.rootInheritedState.rtl || false) !== (this.getInherited().rtl || false)) {
28 posSpec = posSpec.replace(/l/g, 'tmp').replace(/r/g, 'l').replace(/tmp/g, 'r');
29 }
30 return posSpec;
31 },
32
33 getAnchorToXY: function(el, anchor, local, mySize) {
34 var doc = document,
35 pos, scroll, extraX, extraY;
36
37 if (el.dom === doc.body || el.dom === doc) {
38 // anchor the element using the same coordinate system as the viewport or body
39 scroll = Ext.rootInheritedState.rtl ? el.rtlGetScroll() : el.getScroll();
40 extraX = scroll.left;
41 extraY = scroll.top;
42 } else {
43 pos = el.getXY();
44 extraX = local ? 0 : pos[0];
45 extraY = local ? 0 : pos[1];
46 }
47
48 return el.calculateAnchorXY(anchor, extraX, extraY, mySize);
49 },
50
51 getBorderPadding: function() {
52 var borderPadding = this.el.getBorderPadding(),
53 xBegin;
54
55 if (this.isParentRtl()) {
56 xBegin = borderPadding.xBegin;
57 borderPadding.xBegin = borderPadding.xEnd;
58 borderPadding.xEnd = xBegin;
59 }
60
61 return borderPadding;
62 },
63
64 getLocalX: function() {
65 return this.isLocalRtl() ? this.el.rtlGetLocalX() : this.el.getLocalX();
66 },
67
68 getLocalXY: function() {
69 return this.isLocalRtl() ? this.el.rtlGetLocalXY() : this.el.getLocalXY();
70 },
71
72 unitizeBox: function(box) {
73 if (this.getInherited().rtl) {
74 return Ext.dom.Element.rtlUnitizeBox(box);
75 } else {
76 return this.callParent(arguments);
77 }
78 },
79
80 initInheritedState: function (inheritedState) {
81 this.callParent(arguments);
82
83 var rtl = this.rtl;
84
85 if (rtl !== undefined) {
86 // unlike the other hierarchical properties which should always
87 // be inherited from the hierarchy unless true, rtl should only
88 // be inherited if undefined, that is if this component instance
89 // does not have rtl specified as true or false.
90 inheritedState.rtl = rtl;
91 }
92 },
93
94 /**
95 * Returns true if this component's local coordinate system is rtl. For normal
96 * components this equates to the value of isParentRtl(). Floaters are a bit different
97 * because a floater's element can be a childNode of something other than its
98 * parent component's element. For floaters we have to read the dom to see if the
99 * component's element's parentNode has a css direction value of "rtl".
100 * @return {Boolean}
101 * @private
102 */
103 isLocalRtl: function() {
104 var me = this,
105 rtl, offsetParent;
106
107 if (me.floating) {
108 if (me._isOffsetParentRtl === undefined) {
109
110 // position:fixed elements do not report an offsetParent, so fall back to parentNode
111 offsetParent = this.el.dom.offsetParent || this.el.dom.parentNode;
112 if (offsetParent) {
113 me._isOffsetParentRtl =
114 Ext.fly(offsetParent, '_isLocalRtl').isStyle('direction', 'rtl');
115 }
116 }
117 rtl = !!me._isOffsetParentRtl;
118 } else {
119 rtl = this.isParentRtl();
120 }
121
122 return rtl;
123 },
124
125 /**
126 * Returns true if this component's parent container is rtl. Used by rtl positioning
127 * methods to determine if the component should be positioned using a right-to-left
128 * coordinate system.
129 * @return {Boolean}
130 * @private
131 */
132 isParentRtl: function() {
133 var me = this,
134 inheritedState = me.getInherited(),
135 isRtl = false,
136 myRtl;
137
138 if (inheritedState.hasOwnProperty('rtl')) {
139 // Temporarily remove this component's rtl property so we can see what the rtl
140 // value is on the prototype. A component is only rtl positioned if it is
141 // inside of an rtl coordinate system (if one of it's ancestors is rtl). We
142 // can't just use ownerCt/floatParent inheritedState, because components may
143 // not have a container, but might still be part of a rtl coordinate system by
144 // virtue of the Viewport. These components will inherit the correct rtl
145 // value from the prototype because all hierarchy states inherit from
146 // Ext.rootInheritedState
147 myRtl = inheritedState.rtl;
148 delete inheritedState.rtl;
149 }
150
151 if (inheritedState.rtl) {
152 isRtl = true;
153 }
154
155 if (myRtl !== undefined) {
156 // restore this component's original inheritedState rtl property
157 inheritedState.rtl = myRtl;
158 }
159
160 return isRtl;
161 },
162
163 setLocalX: function(x) {
164 return this.isLocalRtl() ? this.el.rtlSetLocalX(x) : this.el.setLocalX(x);
165 },
166
167 setLocalXY: function(x, y) {
168 return this.isLocalRtl() ? this.el.rtlSetLocalXY(x, y) : this.el.setLocalXY(x, y);
169 },
170
171 isOppositeRootDirection: function(){
172 return !this.getInherited().rtl !== !Ext.rootInheritedState.rtl; // jshint ignore:line
173 },
174
175 privates: {
176 initStyles: function(){
177 if (this.getInherited().rtl) {
178 this.horizontalPosProp = 'right';
179 }
180 this.callParent(arguments);
181 },
182
183 parseBox: function(box) {
184 if (this.getInherited().rtl) {
185 return Ext.dom.Element.rtlParseBox(box);
186 } else {
187 return this.callParent(arguments);
188 }
189 }
190 }
191 }, function() {
192 Ext.onInternalReady(function() {
193 // If the document or body has "direction:rtl" then we set the rtl flag in the
194 // root hierarchy state so that the page-level coordinate system will be
195 // right-based (similar to using a Viewport with "rtl: true").
196 if ((Ext.fly(document.documentElement).isStyle('direction', 'rtl')) ||
197 (Ext.getBody().isStyle('direction', 'rtl'))) {
198 Ext.rootInheritedState.rtl = true;
199 }
200 });
201 });
202