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.
4
5import urllib2
6
7from telemetry.core import tab
8from telemetry.core import util
9from telemetry.core.backends.chrome import inspector_backend_list
10
11
12class TabListBackend(inspector_backend_list.InspectorBackendList):
13  """A dynamic sequence of tab.Tabs in UI order."""
14
15  def __init__(self, browser_backend):
16    super(TabListBackend, self).__init__(browser_backend,
17                                         backend_wrapper=tab.Tab)
18
19  def New(self, timeout):
20    assert self._browser_backend.supports_tab_control
21    self._browser_backend.Request('new', timeout=timeout)
22    return self[-1]
23
24  def CloseTab(self, debugger_url, timeout=None):
25    assert self._browser_backend.supports_tab_control
26    tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url)
27    # TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms.
28    # For now, just create a new tab before closing the last tab.
29    if len(self) <= 1:
30      self.New(timeout)
31    try:
32      response = self._browser_backend.Request('close/%s' % tab_id,
33                                               timeout=timeout,
34                                               throw_network_exception=True)
35    except urllib2.HTTPError:
36      raise Exception('Unable to close tab, tab id not found: %s' % tab_id)
37    assert response == 'Target is closing'
38    util.WaitFor(lambda: tab_id not in self, timeout=5)
39
40  def ActivateTab(self, debugger_url, timeout=None):
41    assert self._browser_backend.supports_tab_control
42    tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url)
43    assert tab_id in self
44    try:
45      response = self._browser_backend.Request('activate/%s' % tab_id,
46                                               timeout=timeout,
47                                               throw_network_exception=True)
48    except urllib2.HTTPError:
49      raise Exception('Unable to activate tab, tab id not found: %s' % tab_id)
50    assert response == 'Target activated'
51
52  def GetTabUrl(self, debugger_url):
53    tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url)
54    tab_info = self.GetContextInfo(tab_id)
55    assert tab_info is not None
56    return tab_info['url']
57
58  def Get(self, index, ret):
59    """Returns self[index] if it exists, or ret if index is out of bounds."""
60    if len(self) <= index:
61      return ret
62    return self[index]
63
64  def ShouldIncludeContext(self, context):
65    if 'type' in context:
66      return context['type'] == 'page'
67    # TODO: For compatibility with Chrome before r177683.
68    # This check is not completely correct, see crbug.com/190592.
69    return not context['url'].startswith('chrome-extension://')
70