1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4import os
5
6from telemetry.internal.actions import page_action
7
8
9class PinchAction(page_action.PageAction):
10  def __init__(self, selector=None, text=None, element_function=None,
11               left_anchor_ratio=0.5, top_anchor_ratio=0.5,
12               scale_factor=None, speed_in_pixels_per_second=800,
13               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
14    super(PinchAction, self).__init__()
15    self._selector = selector
16    self._text = text
17    self._element_function = element_function
18    self._left_anchor_ratio = left_anchor_ratio
19    self._top_anchor_ratio = top_anchor_ratio
20    self._scale_factor = scale_factor
21    self._speed = speed_in_pixels_per_second
22    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
23                                      synthetic_gesture_source)
24
25    if (self._selector is None and self._text is None and
26        self._element_function is None):
27      self._element_function = 'document.body'
28
29  def WillRunAction(self, tab):
30    for js_file in ['gesture_common.js', 'pinch.js']:
31      with open(os.path.join(os.path.dirname(__file__), js_file)) as f:
32        js = f.read()
33        tab.ExecuteJavaScript(js)
34
35    # Fail if browser doesn't support synthetic pinch gestures.
36    if not tab.EvaluateJavaScript('window.__PinchAction_SupportedByBrowser()'):
37      raise page_action.PageActionNotSupported(
38          'Synthetic pinch not supported for this browser')
39
40    done_callback = 'function() { window.__pinchActionDone = true; }'
41    tab.ExecuteJavaScript("""
42        window.__pinchActionDone = false;
43        window.__pinchAction = new __PinchAction(%s);"""
44        % done_callback)
45
46  @staticmethod
47  def _GetDefaultScaleFactorForPage(tab):
48    current_scale_factor = tab.EvaluateJavaScript(
49        'window.outerWidth / window.innerWidth')
50    return 3.0 / current_scale_factor
51
52  def RunAction(self, tab):
53    scale_factor = (self._scale_factor if self._scale_factor else
54                    PinchAction._GetDefaultScaleFactorForPage(tab))
55    code = '''
56        function(element, info) {
57          if (!element) {
58            throw Error('Cannot find element: ' + info);
59          }
60          window.__pinchAction.start({
61            element: element,
62            left_anchor_ratio: %s,
63            top_anchor_ratio: %s,
64            scale_factor: %s,
65            speed: %s
66          });
67        }''' % (self._left_anchor_ratio,
68                self._top_anchor_ratio,
69                scale_factor,
70                self._speed)
71    page_action.EvaluateCallbackWithElement(
72        tab, code, selector=self._selector, text=self._text,
73        element_function=self._element_function)
74    tab.WaitForJavaScriptExpression('window.__pinchActionDone', 60)
75