From 2d5f1687c835c1ff01d61c68f2a84890a222e3f5 Mon Sep 17 00:00:00 2001 From: g1879 Date: Fri, 20 Oct 2023 17:15:36 +0800 Subject: [PATCH] =?UTF-8?q?new=5Ftab()=E6=94=B9=E5=9B=9E=E8=BF=94=E5=9B=9E?= =?UTF-8?q?tab=5Fid=EF=BC=9B=E5=A2=9E=E5=8A=A0tab.set.activate()=EF=BC=9BT?= =?UTF-8?q?ab=E5=AF=B9=E8=B1=A1=E8=83=BD=E8=8E=B7=E5=8F=96=E8=87=AA?= =?UTF-8?q?=E5=B7=B1=E7=9A=84=E7=AA=97=E5=8F=A3=E7=9F=A9=E5=BD=A2=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=EF=BC=9B=E4=BF=AE=E5=A4=8D=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E5=8C=96=E6=97=B6=E6=A8=A1=E6=8B=9F=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=B8=8D=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DrissionPage/_base/browser.py | 9 ++- DrissionPage/_base/browser.pyi | 2 +- DrissionPage/_pages/chromium_base.py | 1 + DrissionPage/_pages/chromium_page.py | 82 +-------------------------- DrissionPage/_pages/chromium_page.pyi | 44 ++------------ DrissionPage/_pages/chromium_tab.py | 6 +- DrissionPage/_pages/chromium_tab.pyi | 6 +- DrissionPage/_pages/web_page.py | 8 --- DrissionPage/_pages/web_page.pyi | 2 - DrissionPage/_units/setter.py | 4 ++ DrissionPage/_units/setter.pyi | 2 + DrissionPage/_units/tab_rect.py | 76 +++++++++++++++++++++++++ DrissionPage/_units/tab_rect.pyi | 42 ++++++++++++++ 13 files changed, 148 insertions(+), 136 deletions(-) create mode 100644 DrissionPage/_units/tab_rect.py create mode 100644 DrissionPage/_units/tab_rect.pyi diff --git a/DrissionPage/_base/browser.py b/DrissionPage/_base/browser.py index 126afab..e0ef55a 100644 --- a/DrissionPage/_base/browser.py +++ b/DrissionPage/_base/browser.py @@ -127,9 +127,12 @@ class Browser(object): """ self._driver.get(f'http://{self.address}/json/activate/{tab_id}') - def get_window_bounds(self): - """返回浏览器窗口位置和大小信息""" - return self.run_cdp('Browser.getWindowForTarget', targetId=self.id)['bounds'] + def get_window_bounds(self, tab_id=None): + """返回浏览器窗口位置和大小信息 + :param tab_id: 标签页id + :return: 窗口大小字典 + """ + return self.run_cdp('Browser.getWindowForTarget', targetId=tab_id or self.id)['bounds'] def quit(self): """关闭浏览器""" diff --git a/DrissionPage/_base/browser.pyi b/DrissionPage/_base/browser.pyi index 3a0b818..81bd82a 100644 --- a/DrissionPage/_base/browser.pyi +++ b/DrissionPage/_base/browser.pyi @@ -46,7 +46,7 @@ class Browser(object): def activate_tab(self, tab_id: str) -> None: ... - def get_window_bounds(self) -> dict: ... + def get_window_bounds(self, tab_id: str = None) -> dict: ... def connect_to_page(self) -> None: ... diff --git a/DrissionPage/_pages/chromium_base.py b/DrissionPage/_pages/chromium_base.py index e0259c4..c2c2267 100644 --- a/DrissionPage/_pages/chromium_base.py +++ b/DrissionPage/_pages/chromium_base.py @@ -105,6 +105,7 @@ class ChromiumBase(BasePage): self._driver.call_method('DOM.enable') self._driver.call_method('Page.enable') + self._driver.call_method('Emulation.setFocusEmulationEnabled', enabled=True) self._driver.set_listener('Page.frameStoppedLoading', self._onFrameStoppedLoading) self._driver.set_listener('Page.frameStartedLoading', self._onFrameStartedLoading) diff --git a/DrissionPage/_pages/chromium_page.py b/DrissionPage/_pages/chromium_page.py index 64ed600..cfe8855 100644 --- a/DrissionPage/_pages/chromium_page.py +++ b/DrissionPage/_pages/chromium_page.py @@ -15,6 +15,7 @@ from .._configs.chromium_options import ChromiumOptions from .._pages.chromium_base import ChromiumBase, Timeout from .._pages.chromium_tab import ChromiumTab from .._units.setter import ChromiumPageSetter +from .._units.tab_rect import ChromiumTabRect from .._units.waiter import ChromiumPageWaiter @@ -155,7 +156,7 @@ class ChromiumPage(ChromiumBase): """ return self._browser.find_tabs(title, url, tab_type, single) - def _new_tab(self, url=None, switch_to=False): + def new_tab(self, url=None, switch_to=False): """新建一个标签页,该标签页在最后面 :param url: 新标签页跳转到的网址 :param switch_to: 新建标签页后是否把焦点移过去 @@ -184,14 +185,6 @@ class ChromiumPage(ChromiumBase): return tid - def new_tab(self, url=None, switch_to=False): - """新建一个标签页,该标签页在最后面 - :param url: 新标签页跳转到的网址 - :param switch_to: 新建标签页后是否把焦点移过去 - :return: 新标签页对象 - """ - return ChromiumTab(self, self._new_tab(url, switch_to)) - def to_main_tab(self): """跳转到主标签页""" self.to_tab(self._main_tab) @@ -326,77 +319,6 @@ class ChromiumPage(ChromiumBase): self._driver.has_alert = True -class ChromiumTabRect(object): - def __init__(self, page): - self._page = page - - @property - def window_state(self): - """返回窗口状态:normal、fullscreen、maximized、 minimized""" - return self._get_browser_rect()['windowState'] - - @property - def browser_location(self): - """返回浏览器在屏幕上的坐标,左上角为(0, 0)""" - r = self._get_browser_rect() - if r['windowState'] in ('maximized', 'fullscreen'): - return 0, 0 - return r['left'] + 7, r['top'] - - @property - def page_location(self): - """返回页面左上角在屏幕中坐标,左上角为(0, 0)""" - w, h = self.viewport_location - r = self._get_page_rect()['layoutViewport'] - return w - r['pageX'], h - r['pageY'] - - @property - def viewport_location(self): - """返回视口在屏幕中坐标,左上角为(0, 0)""" - w_bl, h_bl = self.browser_location - w_bs, h_bs = self.browser_size - w_vs, h_vs = self.viewport_size_with_scrollbar - return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs - - @property - def browser_size(self): - """返回浏览器大小""" - r = self._get_browser_rect() - if r['windowState'] == 'fullscreen': - return r['width'], r['height'] - elif r['windowState'] == 'maximized': - return r['width'] - 16, r['height'] - 16 - else: - return r['width'] - 16, r['height'] - 7 - - @property - def page_size(self): - """返回页面总宽高,格式:(宽, 高)""" - r = self._get_page_rect()['contentSize'] - return r['width'], r['height'] - - @property - def viewport_size(self): - """返回视口宽高,不包括滚动条,格式:(宽, 高)""" - r = self._get_page_rect()['visualViewport'] - return r['clientWidth'], r['clientHeight'] - - @property - def viewport_size_with_scrollbar(self): - """返回视口宽高,包括滚动条,格式:(宽, 高)""" - r = self._page.run_js('return window.innerWidth.toString() + " " + window.innerHeight.toString();') - w, h = r.split(' ') - return int(w), int(h) - - def _get_page_rect(self): - """获取页面范围信息""" - return self._page.run_cdp_loaded('Page.getLayoutMetrics') - - def _get_browser_rect(self): - """获取浏览器范围信息""" - return self._page.browser.get_window_bounds() - - class Alert(object): """用于保存alert信息的类""" diff --git a/DrissionPage/_pages/chromium_page.pyi b/DrissionPage/_pages/chromium_page.pyi index 9f55304..9a02407 100644 --- a/DrissionPage/_pages/chromium_page.pyi +++ b/DrissionPage/_pages/chromium_page.pyi @@ -6,11 +6,12 @@ from typing import Union, Tuple, List, Optional from .._base.browser import Browser -from .._pages.chromium_base import ChromiumBase from .._base.chromium_driver import ChromiumDriver -from .._pages.chromium_tab import ChromiumTab from .._configs.chromium_options import ChromiumOptions +from .._pages.chromium_base import ChromiumBase +from .._pages.chromium_tab import ChromiumTab from .._units.setter import ChromiumPageSetter +from .._units.tab_rect import ChromiumTabRect from .._units.waiter import ChromiumPageWaiter @@ -24,7 +25,7 @@ class ChromiumPage(ChromiumBase): self._main_tab: str = ... self._alert: Alert = ... self._browser: Browser = ... - self._rect: ChromiumTabRect = ... + self._rect: Optional[ChromiumTabRect] = ... def _handle_options(self, addr_driver_opts: Union[str, ChromiumDriver, ChromiumOptions]) -> str: ... @@ -64,9 +65,7 @@ class ChromiumPage(ChromiumBase): def find_tabs(self, title: str = None, url: str = None, tab_type: Union[str, list, tuple] = None, single: bool = True) -> Union[str, List[str]]: ... - def _new_tab(self, url: str = None, switch_to: bool = False) -> str: ... - - def new_tab(self, url: str = None, switch_to: bool = False) -> ChromiumTab: ... + def new_tab(self, url: str = None, switch_to: bool = False) -> str: ... def to_main_tab(self) -> None: ... @@ -91,39 +90,6 @@ class ChromiumPage(ChromiumBase): def _on_alert_open(self, **kwargs): ... -class ChromiumTabRect(object): - def __init__(self, page: ChromiumPage): - self._page: ChromiumPage = ... - - @property - def window_state(self) -> str: ... - - @property - def browser_location(self) -> Tuple[int, int]: ... - - @property - def page_location(self) -> Tuple[int, int]: ... - - @property - def viewport_location(self) -> Tuple[int, int]: ... - - @property - def browser_size(self) -> Tuple[int, int]: ... - - @property - def page_size(self) -> Tuple[int, int]: ... - - @property - def viewport_size(self) -> Tuple[int, int]: ... - - @property - def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ... - - def _get_page_rect(self) -> dict: ... - - def _get_browser_rect(self) -> dict: ... - - class Alert(object): def __init__(self): diff --git a/DrissionPage/_pages/chromium_tab.py b/DrissionPage/_pages/chromium_tab.py index f5d6cff..8944559 100644 --- a/DrissionPage/_pages/chromium_tab.py +++ b/DrissionPage/_pages/chromium_tab.py @@ -10,6 +10,7 @@ from .._commons.web import set_session_cookies, set_browser_cookies from .._pages.chromium_base import ChromiumBase from .._pages.session_page import SessionPage from .._units.setter import TabSetter, WebPageTabSetter +from .._units.tab_rect import ChromiumTabRect from .._units.waiter import ChromiumTabWaiter @@ -24,6 +25,7 @@ class ChromiumTab(ChromiumBase): self._page = page self._browser = page.browser super().__init__(page.address, tab_id, page.timeout) + self._rect = None def _d_set_runtime_settings(self): """重写设置浏览器运行参数方法""" @@ -45,7 +47,9 @@ class ChromiumTab(ChromiumBase): @property def rect(self): """返回获取窗口坐标和大小的对象""" - return self.page.rect + if self._rect is None: + self._rect = ChromiumTabRect(self) + return self._rect @property def set(self): diff --git a/DrissionPage/_pages/chromium_tab.pyi b/DrissionPage/_pages/chromium_tab.pyi index 9bb19a5..923c8c7 100644 --- a/DrissionPage/_pages/chromium_tab.pyi +++ b/DrissionPage/_pages/chromium_tab.pyi @@ -3,13 +3,14 @@ @Author : g1879 @Contact : g1879@qq.com """ -from typing import Union, Tuple, Any, List +from typing import Union, Tuple, Any, List, Optional from requests import Session, Response +from .._units.tab_rect import ChromiumTabRect from .chromium_base import ChromiumBase from .chromium_frame import ChromiumFrame -from .chromium_page import ChromiumPage, ChromiumTabRect +from .chromium_page import ChromiumPage from .session_page import SessionPage from .web_page import WebPage from .._base.browser import Browser @@ -24,6 +25,7 @@ class ChromiumTab(ChromiumBase): def __init__(self, page: ChromiumPage, tab_id: str = None): self._page: ChromiumPage = ... self._browser: Browser = ... + self._rect: Optional[ChromiumTabRect] = ... def _d_set_runtime_settings(self) -> None: ... diff --git a/DrissionPage/_pages/web_page.py b/DrissionPage/_pages/web_page.py index e6b055f..f91aa78 100644 --- a/DrissionPage/_pages/web_page.py +++ b/DrissionPage/_pages/web_page.py @@ -294,14 +294,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage): """ return tab_id if isinstance(tab_id, WebPageTab) else WebPageTab(self, tab_id or self.tab_id) - def new_tab(self, url=None, switch_to=False): - """新建一个标签页,该标签页在最后面 - :param url: 新标签页跳转到的网址 - :param switch_to: 新建标签页后是否把焦点移过去 - :return: 新标签页对象 - """ - return WebPageTab(self, self._new_tab(url, switch_to)) - def close_driver(self): """关闭driver及浏览器""" if self._has_driver: diff --git a/DrissionPage/_pages/web_page.pyi b/DrissionPage/_pages/web_page.pyi index ce350da..e05cb9f 100644 --- a/DrissionPage/_pages/web_page.pyi +++ b/DrissionPage/_pages/web_page.pyi @@ -121,8 +121,6 @@ class WebPage(SessionPage, ChromiumPage, BasePage): def get_tab(self, tab_id: Union[str, WebPageTab] = None) -> WebPageTab: ... - def new_tab(self, url: str = None, switch_to: bool = False) -> WebPageTab: ... - def close_driver(self) -> None: ... def close_session(self) -> None: ... diff --git a/DrissionPage/_units/setter.py b/DrissionPage/_units/setter.py index 8102489..f0de74a 100644 --- a/DrissionPage/_units/setter.py +++ b/DrissionPage/_units/setter.py @@ -152,6 +152,10 @@ class TabSetter(ChromiumBaseSetter): self._page.browser._dl_mgr.set_file_exists(self._page.tab_id, mode) + def activate(self): + """使标签页处于最前面""" + self._page.browser.activate_tab(self._page.tab_id) + class ChromiumPageSetter(TabSetter): def main_tab(self, tab_id=None): diff --git a/DrissionPage/_units/setter.pyi b/DrissionPage/_units/setter.pyi index 989b368..f44413e 100644 --- a/DrissionPage/_units/setter.pyi +++ b/DrissionPage/_units/setter.pyi @@ -62,6 +62,8 @@ class TabSetter(ChromiumBaseSetter): def when_download_file_exists(self, mode: FILE_EXISTS) -> None: ... + def activate(self) -> None: ... + class ChromiumPageSetter(TabSetter): _page: ChromiumPage = ... diff --git a/DrissionPage/_units/tab_rect.py b/DrissionPage/_units/tab_rect.py new file mode 100644 index 0000000..6655932 --- /dev/null +++ b/DrissionPage/_units/tab_rect.py @@ -0,0 +1,76 @@ +# -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" + + +class ChromiumTabRect(object): + def __init__(self, page): + self._page = page + + @property + def window_state(self): + """返回窗口状态:normal、fullscreen、maximized、 minimized""" + return self._get_browser_rect()['windowState'] + + @property + def browser_location(self): + """返回浏览器在屏幕上的坐标,左上角为(0, 0)""" + r = self._get_browser_rect() + if r['windowState'] in ('maximized', 'fullscreen'): + return 0, 0 + return r['left'] + 7, r['top'] + + @property + def page_location(self): + """返回页面左上角在屏幕中坐标,左上角为(0, 0)""" + w, h = self.viewport_location + r = self._get_page_rect()['layoutViewport'] + return w - r['pageX'], h - r['pageY'] + + @property + def viewport_location(self): + """返回视口在屏幕中坐标,左上角为(0, 0)""" + w_bl, h_bl = self.browser_location + w_bs, h_bs = self.browser_size + w_vs, h_vs = self.viewport_size_with_scrollbar + return w_bl + w_bs - w_vs, h_bl + h_bs - h_vs + + @property + def browser_size(self): + """返回浏览器大小""" + r = self._get_browser_rect() + if r['windowState'] == 'fullscreen': + return r['width'], r['height'] + elif r['windowState'] == 'maximized': + return r['width'] - 16, r['height'] - 16 + else: + return r['width'] - 16, r['height'] - 7 + + @property + def page_size(self): + """返回页面总宽高,格式:(宽, 高)""" + r = self._get_page_rect()['contentSize'] + return r['width'], r['height'] + + @property + def viewport_size(self): + """返回视口宽高,不包括滚动条,格式:(宽, 高)""" + r = self._get_page_rect()['visualViewport'] + return r['clientWidth'], r['clientHeight'] + + @property + def viewport_size_with_scrollbar(self): + """返回视口宽高,包括滚动条,格式:(宽, 高)""" + r = self._page.run_js('return window.innerWidth.toString() + " " + window.innerHeight.toString();') + w, h = r.split(' ') + return int(w), int(h) + + def _get_page_rect(self): + """获取页面范围信息""" + return self._page.run_cdp_loaded('Page.getLayoutMetrics') + + def _get_browser_rect(self): + """获取浏览器范围信息""" + return self._page.browser.get_window_bounds(self._page.tab_id) diff --git a/DrissionPage/_units/tab_rect.pyi b/DrissionPage/_units/tab_rect.pyi new file mode 100644 index 0000000..95ebadc --- /dev/null +++ b/DrissionPage/_units/tab_rect.pyi @@ -0,0 +1,42 @@ +# -*- coding:utf-8 -*- +""" +@Author : g1879 +@Contact : g1879@qq.com +""" +from typing import Tuple, Union + +from .._pages.chromium_page import ChromiumPage +from .._pages.chromium_tab import ChromiumTab + + +class ChromiumTabRect(object): + def __init__(self, page: Union[ChromiumPage, ChromiumTab]): + self._page: Union[ChromiumPage, ChromiumTab] = ... + + @property + def window_state(self) -> str: ... + + @property + def browser_location(self) -> Tuple[int, int]: ... + + @property + def page_location(self) -> Tuple[int, int]: ... + + @property + def viewport_location(self) -> Tuple[int, int]: ... + + @property + def browser_size(self) -> Tuple[int, int]: ... + + @property + def page_size(self) -> Tuple[int, int]: ... + + @property + def viewport_size(self) -> Tuple[int, int]: ... + + @property + def viewport_size_with_scrollbar(self) -> Tuple[int, int]: ... + + def _get_page_rect(self) -> dict: ... + + def _get_browser_rect(self) -> dict: ...