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