Commit 265d9c20 authored by Sungguk Lim's avatar Sungguk Lim

Implement chrome.tabs.goBack and chrome.tabs.goForward

Implementation for chrome.tabs.goBack and chrome.tabs.goForward
Above APIs provide a reliable way to trigger a navigate-back/forward
action like back/forward button on toolbar.

Bug: 830622
Change-Id: I1f5e8d5e4768161f43b2df1621a03a6cc3383b4f
Reviewed-on: https://chromium-review.googlesource.com/c/1274225Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604831}
parent d4727fc8
......@@ -193,6 +193,32 @@ bool GetTabById(int tab_id,
return false;
}
// Gets the WebContents for |tab_id| if it is specified. Otherwise get the
// WebContents for the active tab in the |function|'s current window.
// Returns nullptr and fills |error| if failed.
content::WebContents* GetTabsAPIDefaultWebContents(
UIThreadExtensionFunction* function,
int tab_id,
std::string* error) {
content::WebContents* web_contents = nullptr;
if (tab_id != -1) {
// We assume this call leaves web_contents unchanged if it is unsuccessful.
GetTabById(tab_id, function->browser_context(),
function->include_incognito_information(),
nullptr /* ignore Browser* output */,
nullptr /* ignore TabStripModel* output */, &web_contents,
nullptr /* ignore int tab_index output */, error);
} else {
Browser* browser =
ChromeExtensionFunctionDetails(function).GetCurrentBrowser();
if (!browser)
*error = tabs_constants::kNoCurrentWindowError;
else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, nullptr))
*error = tabs_constants::kNoSelectedTabError;
}
return web_contents;
}
// Returns true if either |boolean| is a null pointer, or if |*boolean| and
// |value| are equal. This function is used to check if a tab's parameters match
// those of the browser.
......@@ -1992,25 +2018,6 @@ bool TabsInsertCSSFunction::ShouldInsertCSS() const {
return true;
}
content::WebContents* ZoomAPIFunction::GetWebContents(int tab_id,
std::string* error) {
content::WebContents* web_contents = NULL;
if (tab_id != -1) {
// We assume this call leaves web_contents unchanged if it is unsuccessful.
GetTabById(tab_id, browser_context(), include_incognito_information(),
nullptr /* ignore Browser* output */,
nullptr /* ignore TabStripModel* output */, &web_contents,
nullptr /* ignore int tab_index output */, error);
} else {
Browser* browser = ChromeExtensionFunctionDetails(this).GetCurrentBrowser();
if (!browser)
*error = tabs_constants::kNoCurrentWindowError;
else if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, NULL))
*error = tabs_constants::kNoSelectedTabError;
}
return web_contents;
}
ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() {
std::unique_ptr<tabs::SetZoom::Params> params(
tabs::SetZoom::Params::Create(*args_));
......@@ -2018,7 +2025,8 @@ ExtensionFunction::ResponseAction TabsSetZoomFunction::Run() {
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents = GetWebContents(tab_id, &error);
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
......@@ -2049,7 +2057,8 @@ ExtensionFunction::ResponseAction TabsGetZoomFunction::Run() {
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents = GetWebContents(tab_id, &error);
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
......@@ -2069,7 +2078,8 @@ ExtensionFunction::ResponseAction TabsSetZoomSettingsFunction::Run() {
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents = GetWebContents(tab_id, &error);
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
......@@ -2118,7 +2128,8 @@ ExtensionFunction::ResponseAction TabsGetZoomSettingsFunction::Run() {
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents = GetWebContents(tab_id, &error);
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
ZoomController* zoom_controller =
......@@ -2173,4 +2184,44 @@ ExtensionFunction::ResponseAction TabsDiscardFunction::Run() {
TabsDiscardFunction::TabsDiscardFunction() {}
TabsDiscardFunction::~TabsDiscardFunction() {}
ExtensionFunction::ResponseAction TabsGoForwardFunction::Run() {
std::unique_ptr<tabs::GoForward::Params> params(
tabs::GoForward::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
NavigationController& controller = web_contents->GetController();
if (!controller.CanGoForward())
return RespondNow(Error(tabs_constants::kNotFoundNextPageError));
controller.GoForward();
return RespondNow(NoArguments());
}
ExtensionFunction::ResponseAction TabsGoBackFunction::Run() {
std::unique_ptr<tabs::GoBack::Params> params(
tabs::GoBack::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params.get());
int tab_id = params->tab_id ? *params->tab_id : -1;
std::string error;
WebContents* web_contents =
GetTabsAPIDefaultWebContents(this, tab_id, &error);
if (!web_contents)
return RespondNow(Error(error));
NavigationController& controller = web_contents->GetController();
if (!controller.CanGoBack())
return RespondNow(Error(tabs_constants::kNotFoundNextPageError));
controller.GoBack();
return RespondNow(NoArguments());
}
} // namespace extensions
......@@ -268,20 +268,7 @@ class TabsInsertCSSFunction : public ExecuteCodeInTabFunction {
DECLARE_EXTENSION_FUNCTION("tabs.insertCSS", TABS_INSERTCSS)
};
class ZoomAPIFunction : public UIThreadExtensionFunction {
protected:
~ZoomAPIFunction() override {}
// Gets the WebContents for |tab_id| if it is specified. Otherwise get the
// WebContents for the active tab in the current window. Calling this function
// may set error_.
//
// TODO(...) many other tabs API functions use similar behavior. There should
// be a way to share this implementation somehow.
content::WebContents* GetWebContents(int tab_id, std::string* error);
};
class TabsSetZoomFunction : public ZoomAPIFunction {
class TabsSetZoomFunction : public UIThreadExtensionFunction {
private:
~TabsSetZoomFunction() override {}
......@@ -290,7 +277,7 @@ class TabsSetZoomFunction : public ZoomAPIFunction {
DECLARE_EXTENSION_FUNCTION("tabs.setZoom", TABS_SETZOOM)
};
class TabsGetZoomFunction : public ZoomAPIFunction {
class TabsGetZoomFunction : public UIThreadExtensionFunction {
private:
~TabsGetZoomFunction() override {}
......@@ -299,7 +286,7 @@ class TabsGetZoomFunction : public ZoomAPIFunction {
DECLARE_EXTENSION_FUNCTION("tabs.getZoom", TABS_GETZOOM)
};
class TabsSetZoomSettingsFunction : public ZoomAPIFunction {
class TabsSetZoomSettingsFunction : public UIThreadExtensionFunction {
private:
~TabsSetZoomSettingsFunction() override {}
......@@ -308,7 +295,7 @@ class TabsSetZoomSettingsFunction : public ZoomAPIFunction {
DECLARE_EXTENSION_FUNCTION("tabs.setZoomSettings", TABS_SETZOOMSETTINGS)
};
class TabsGetZoomSettingsFunction : public ZoomAPIFunction {
class TabsGetZoomSettingsFunction : public UIThreadExtensionFunction {
private:
~TabsGetZoomSettingsFunction() override {}
......@@ -332,6 +319,36 @@ class TabsDiscardFunction : public UIThreadExtensionFunction {
DISALLOW_COPY_AND_ASSIGN(TabsDiscardFunction);
};
class TabsGoForwardFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("tabs.goForward", TABS_GOFORWARD)
TabsGoForwardFunction() {}
private:
~TabsGoForwardFunction() override {}
// ExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DISALLOW_COPY_AND_ASSIGN(TabsGoForwardFunction);
};
class TabsGoBackFunction : public UIThreadExtensionFunction {
public:
DECLARE_EXTENSION_FUNCTION("tabs.goBack", TABS_GOBACK)
TabsGoBackFunction() {}
private:
~TabsGoBackFunction() override {}
// ExtensionFunction:
ExtensionFunction::ResponseAction Run() override;
DISALLOW_COPY_AND_ASSIGN(TabsGoBackFunction);
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_TABS_TABS_API_H_
......@@ -86,6 +86,7 @@ const char kPerOriginOnlyInAutomaticError[] = "Can only set scope to "
"\"per-origin\" in \"automatic\" mode.";
const char kWindowNotFoundError[] = "No window with id: *.";
const char kTabIndexNotFoundError[] = "No tab at index: *.";
const char kNotFoundNextPageError[] = "Cannot find a next page in history.";
const char kTabNotFoundError[] = "No tab with id: *.";
const char kCannotDiscardTab[] = "Cannot discard tab with id: *.";
const char kCannotFindTabToDiscard[] = "Cannot find a tab to discard.";
......
......@@ -86,6 +86,7 @@ extern const char kNoTabInBrowserWindowError[];
extern const char kPerOriginOnlyInAutomaticError[];
extern const char kWindowNotFoundError[];
extern const char kTabIndexNotFoundError[];
extern const char kNotFoundNextPageError[];
extern const char kTabNotFoundError[];
extern const char kCannotDiscardTab[];
extern const char kCannotFindTabToDiscard[];
......
......@@ -946,6 +946,46 @@
]
}
]
},
{
"name": "goForward",
"type": "function",
"description": "Go foward to the next page, if one is available.",
"parameters": [
{
"type": "integer",
"name": "tabId",
"optional": true,
"minimum": 0,
"description": "The ID of the tab to navigate forward; defaults to the selected tab of the current window."
},
{
"type": "function",
"name": "callback",
"optional": true,
"parameters": []
}
]
},
{
"name": "goBack",
"type": "function",
"description": "Go back to the previous page, if one is available.",
"parameters": [
{
"type": "integer",
"name": "tabId",
"optional": true,
"minimum": 0,
"description": "The ID of the tab to navigate back; defaults to the selected tab of the current window."
},
{
"type": "function",
"name": "callback",
"optional": true,
"parameters": []
}
]
}
],
"events": [
......
......@@ -1349,6 +1349,8 @@ enum HistogramValue {
ACCESSIBILITY_PRIVATE_SENDSYNTHETICMOUSEEVENT = 1286,
FILEMANAGERPRIVATE_DETECTCHARACTERENCODING = 1287,
FILEMANAGERPRIVATEINTERNAL_GETLINUXPACKAGEINFO = 1288,
TABS_GOFORWARD = 1289,
TABS_GOBACK = 1290,
// Last entry: Add new entries above, then run:
// python tools/metrics/histograms/update_extension_histograms.py
ENUM_BOUNDARY
......
......@@ -17183,6 +17183,8 @@ Called by update_net_error_codes.py.-->
<int value="1286" label="ACCESSIBILITY_PRIVATE_SENDSYNTHETICMOUSEEVENT"/>
<int value="1287" label="FILEMANAGERPRIVATE_DETECTCHARACTERENCODING"/>
<int value="1288" label="FILEMANAGERPRIVATEINTERNAL_GETLINUXPACKAGEINFO"/>
<int value="1289" label="TABS_GOFORWARD"/>
<int value="1290" label="TABS_GOBACK"/>
</enum>
<enum name="ExtensionIconState">
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment