]> git.proxmox.com Git - extjs.git/blame - extjs/modern/modern/src/viewport/Android.js
add extjs 6.0.1 sources
[extjs.git] / extjs / modern / modern / src / viewport / Android.js
CommitLineData
6527f429
DM
1/**\r
2 * @private\r
3 * Android version of viewport.\r
4 */\r
5Ext.define('Ext.viewport.Android', {\r
6 extend: 'Ext.viewport.Default',\r
7\r
8 config: {\r
9 translatable: {\r
10 translationMethod: 'csstransform'\r
11 }\r
12 },\r
13\r
14 constructor: function() {\r
15 this.callParent(arguments);\r
16\r
17 this.on({\r
18 orientationchange: 'hideKeyboardIfNeeded',\r
19 scope: this,\r
20 // run our handler before user code\r
21 priority: 1001\r
22 });\r
23\r
24\r
25 // Viewport is initialized before event system, we need to wait until the application is ready before\r
26 // we add the resize listener. Otherwise it will only fire if another resize listener is added later.\r
27 var me = this;\r
28 Ext.onReady(function() { Ext.getBody().on('resize', me.onResize, me);});\r
29 },\r
30\r
31 getWindowWidth: function () {\r
32 return this.element.getWidth();\r
33\r
34 },\r
35\r
36 getWindowHeight: function () {\r
37 return this.element.getHeight();\r
38 },\r
39\r
40 getDummyInput: function() {\r
41 var input = this.dummyInput,\r
42 focusedElement = this.focusedElement,\r
43 box = Ext.fly(focusedElement).getBox();\r
44\r
45 if (!input) {\r
46 this.dummyInput = input = document.createElement('input');\r
47 input.style.position = 'absolute';\r
48 input.style.opacity = '0';\r
49 input.style.pointerEvents = 'none';\r
50 document.body.appendChild(input);\r
51 }\r
52\r
53 input.style.left = box.left + 'px';\r
54 input.style.top = box.top + 'px';\r
55 input.style.display = '';\r
56\r
57 return input;\r
58 },\r
59\r
60 doBlurInput: function(e) {\r
61 var target = e.target,\r
62 focusedElement = this.focusedElement,\r
63 dummy;\r
64\r
65 if (focusedElement && !this.isInputRegex.test(target.tagName)) {\r
66 dummy = this.getDummyInput();\r
67 delete this.focusedElement;\r
68 dummy.focus();\r
69\r
70 Ext.defer(function() {\r
71 dummy.style.display = 'none';\r
72 }, 100);\r
73 }\r
74 },\r
75\r
76 hideKeyboardIfNeeded: function() {\r
77 var focusedElement = this.focusedElement;\r
78\r
79 if (focusedElement) {\r
80 delete this.focusedElement;\r
81\r
82 if (Ext.os.version.lt('4')) {\r
83 focusedElement.style.display = 'none';\r
84 }\r
85 else {\r
86 focusedElement.blur();\r
87 }\r
88\r
89 Ext.defer(function() {\r
90 focusedElement.style.display = '';\r
91 }, 1000);\r
92 }\r
93 },\r
94\r
95 doFireOrientationChangeEvent: function() {\r
96 this.orientationChanging = true;\r
97\r
98 this.waitUntil(function() {\r
99 return this.getWindowOuterHeight() !== this.windowOuterHeight;\r
100 }, function() {\r
101 this.windowOuterHeight = this.getWindowOuterHeight();\r
102 this.updateSize();\r
103 this.orientationChanging = false;\r
104\r
105 }, function() {\r
106 //<debug>\r
107 Ext.Logger.error("Timeout waiting for viewport's outerHeight to change before firing orientationchange", this);\r
108 //</debug>\r
109 });\r
110\r
111 return this;\r
112 },\r
113\r
114 determineOrientation: function() {\r
115 return (this.getWindowHeight() >= this.getWindowWidth()) ? this.PORTRAIT : this.LANDSCAPE;\r
116 },\r
117\r
118 getActualWindowOuterHeight: function() {\r
119 return Math.round(this.getWindowOuterHeight() / window.devicePixelRatio);\r
120 },\r
121\r
122 maximize: function() {\r
123 var stretchHeights = this.stretchHeights,\r
124 orientation = this.orientation,\r
125 height;\r
126\r
127 height = stretchHeights[orientation];\r
128\r
129 if (!height) {\r
130 stretchHeights[orientation] = height = this.getActualWindowOuterHeight();\r
131 }\r
132\r
133 if (!this.addressBarHeight) {\r
134 this.addressBarHeight = height - this.getWindowHeight();\r
135 }\r
136\r
137 this.setHeight(height);\r
138\r
139 var isHeightMaximized = Ext.Function.bind(this.isHeightMaximized, this, [height]);\r
140\r
141 this.scrollToTop();\r
142 this.waitUntil(isHeightMaximized, this.fireMaximizeEvent, this.fireMaximizeEvent);\r
143 },\r
144\r
145 isHeightMaximized: function(height) {\r
146 this.scrollToTop();\r
147 return this.getWindowHeight() === height;\r
148 },\r
149\r
150 supportsOrientation: function () {\r
151 return false;\r
152 },\r
153\r
154 onResize: function () {\r
155 this.waitUntil(function () {\r
156 var oldWidth = this.windowWidth,\r
157 oldHeight = this.windowHeight,\r
158 width = this.getWindowWidth(),\r
159 height = this.getWindowHeight(),\r
160 currentOrientation = this.getOrientation(),\r
161 newOrientation = this.determineOrientation();\r
162\r
163 return ((oldWidth !== width && oldHeight !== height) && currentOrientation !== newOrientation);\r
164 }, function () {\r
165 var currentOrientation = this.getOrientation(),\r
166 newOrientation = this.determineOrientation();\r
167\r
168 this.fireOrientationChangeEvent(newOrientation, currentOrientation);\r
169 }, Ext.emptyFn, 250);\r
170 },\r
171\r
172 doPreventZooming: function (e) {\r
173 // Don't prevent right mouse event\r
174 if ('button' in e && e.button !== 0) {\r
175 return;\r
176 }\r
177\r
178 var target = e.target;\r
179\r
180 if (target && target.nodeType === 1 && !this.isInputRegex.test(target.tagName) && !this.focusedElement) {\r
181 e.preventDefault();\r
182 }\r
183 }\r
184\r
185}, function() {\r
186 if (!Ext.os.is.Android) {\r
187 return;\r
188 }\r
189\r
190 var version = Ext.os.version,\r
191 userAgent = Ext.browser.userAgent,\r
192 // These Android devices have a nasty bug which causes JavaScript timers to be completely frozen\r
193 // when the browser's viewport is being panned.\r
194 isBuggy = /(htc|desire|incredible|ADR6300)/i.test(userAgent) && version.lt('2.3');\r
195\r
196 if (isBuggy) {\r
197 this.override({\r
198 constructor: function(config) {\r
199 if (!config) {\r
200 config = {};\r
201 }\r
202\r
203 config.autoMaximize = false;\r
204\r
205 this.watchDogTick = Ext.Function.bind(this.watchDogTick, this);\r
206\r
207 Ext.interval(this.watchDogTick, 1000);\r
208\r
209 return this.callParent([config]);\r
210 },\r
211\r
212 watchDogTick: function() {\r
213 this.watchDogLastTick = Ext.Date.now();\r
214 },\r
215\r
216 doPreventPanning: function() {\r
217 var now = Ext.Date.now(),\r
218 lastTick = this.watchDogLastTick,\r
219 deltaTime = now - lastTick;\r
220\r
221 // Timers are frozen\r
222 if (deltaTime >= 2000) {\r
223 return;\r
224 }\r
225\r
226 return this.callParent(arguments);\r
227 },\r
228\r
229 doPreventZooming: function() {\r
230 var now = Ext.Date.now(),\r
231 lastTick = this.watchDogLastTick,\r
232 deltaTime = now - lastTick;\r
233\r
234 // Timers are frozen\r
235 if (deltaTime >= 2000) {\r
236 return;\r
237 }\r
238\r
239 return this.callParent(arguments);\r
240 }\r
241 });\r
242 }\r
243\r
244 if (version.match('2')) {\r
245 this.override({\r
246 onReady: function() {\r
247 this.addWindowListener('resize', Ext.Function.bind(this.onWindowResize, this));\r
248\r
249 this.callParent(arguments);\r
250 },\r
251\r
252 scrollToTop: function() {\r
253 document.body.scrollTop = 100;\r
254 },\r
255\r
256 onWindowResize: function() {\r
257 var oldWidth = this.windowWidth,\r
258 oldHeight = this.windowHeight,\r
259 width = this.getWindowWidth(),\r
260 height = this.getWindowHeight();\r
261\r
262 if (this.getAutoMaximize() && !this.isMaximizing && !this.orientationChanging\r
263 && window.scrollY === 0\r
264 && oldWidth === width\r
265 && height < oldHeight\r
266 && ((height >= oldHeight - this.addressBarHeight) || !this.focusedElement)) {\r
267 this.scrollToTop();\r
268 }\r
269 }\r
270 });\r
271 }\r
272 else if (version.gtEq('3.1')) {\r
273 this.override({\r
274 isHeightMaximized: function(height) {\r
275 this.scrollToTop();\r
276 return this.getWindowHeight() === height - 1;\r
277 }\r
278 });\r
279 }\r
280 else if (version.match('3')) {\r
281 this.override({\r
282 isHeightMaximized: function() {\r
283 this.scrollToTop();\r
284 return true;\r
285 }\r
286 })\r
287 }\r
288\r
289 if (version.gtEq('4')) {\r
290 this.override({\r
291 doBlurInput: Ext.emptyFn\r
292 });\r
293 }\r
294});\r