A browser action is an action a user can take in the context of a browser window. An ActionItem is a definition describing how that action is invoked, along with its default text label and icon. These actions can be invoked from various parts of the browser UI, one of which is the page actions present in the URL bar.
The Page Action framework provides the means of displaying a page action in a convenient and consistent way.
This section describes how to leverage the Page Action framework to add a new icon or chip to the toolbar. At a high level, the implementation of a page action looks like:
Chrome action IDs are defined here, and browser-specific actions are defined here. There, the default visual parameters of the action are specified (icon, text label, tooltip, etc), as well as the callback executed when the action is invoked. Note that this portion of the implementation is not page action specific, but may be created solely to support a page action.
The action can do anything, but page actions often spawn bubble dialogs anchored to the URL bar. Examples include translation, zoom and memory saver.
Include the Action in the set of Page Actions here. This makes the framework aware of your ActionItem.
Note: The order of this array defines the order that page actions will appear in the UI.
Page Actions have extra properties beyond the underlying ActionItem, described in an additional set of descriptors here. These include:
Within feature code, use the PageActionController to show and control your page action.
Page Action state is tab-specific, and each tab has a PageActionController that can be used by other features. Hence, implementing feature-specific logic as a TabFeature is convenient in this model. A feature-specific TabFeature object can then be instantiated with a reference to the PageActionController, as seen in this example.
If the feature is browser-scoped, it can access a tab’s controller through the tab interface:
bwi->GetActiveTabInterface()->GetTabFeatures()->page_action_controller();
From there, controlling the page action is done through the PageActionController interface. Showing or hiding the page action is a simple call:
page_action_controller_->Show(kActionFooFeature); ... page_action_controller_->Hide(kActionFooFeature);
Optionally, a feature can request that an expanded “chip” be shown rather than just the icon. Note that the framework limits the page action UI to one chip at a time, so this request is not necessarily granted. When displayed, the chip sits in the leftmost position within the set of page actions.
This image shows three page actions, with Google Lens in expanded chip state:
To request expanded chip state, use the controller’s ShowSuggestionChip()
and HideSuggestionChip()
. Suggestion chip state only matters if the page action is shown. For example:
// Show feature suggestion chip. page_action_controller_->Show(kActionFooFeature); page_action_controller_->ShowSuggestionChip(kActionFooFeature); // Reduce to icon-only state. page_action_controller_->HideSuggestionChip(kActionFooFeature); // Hide the page action entirely. page_action_controller_->Hide(kActionFooFeature);
If the page action requires a different image or text than the default specified in the ActionItem, page action logic can override the defaults. Similarly, if a page action needs to change the icon or text dynamically based on feature state, the same overrides may be used. See OverrideImage() and similar methods on the controller interface. The overrides can be cleared if needed via the corresponding Clear calls.
Example: The Zoom page action shows different icons depending on whether the zoom level is more or less than 100%.
Typically, a feature can “set and forget” its page action. However, the feature may wish to observe the actual state of its page action (for example, to see if its requested chip was able to show). The framework provides an observation mechanism to watch this state. An example usage is here.
By registering the histogram and page action icon types in the previous steps, the new page action will automatically log usage alongside other page actions. Additional feature-specific metrics logging can be added if needed to feature code.
In unit tests, use a MockPageActionController.
In interactive UI tests, UI can be exercised by targeting the appropriate Page Action Icon element, specified in the Page Action properties described earlier.
Note: Interactive UI tests will typically target page action icons or expanded chips. The Location Bar view hierarchy containing the page actions contains some legacy layout code, which sometimes causes visibility flapping when showing an icon or chip. To avoid flakiness in tests, leverage the PageActionInteractiveTestMixin in your tests, and use the WaitForPageActionButtonVisible verb to wait for the action to show.
If the feature is utilizing a new bubble, its existence could be managed by a small controller class, to handle action invocations and create the required bubble. Note that this controller feeds bubble visibility state back into the ActionItem object (see toggling).
When a page action click spawns a bubble on the location bar, re-clicking the same page action should dismiss the bubble. This requires a link between the page action framework and the bubble. Most of this is managed by the framework, but the bubble must advertise its presence to the ActionItem (see bubbles). The Page Action uses this state to ensure the bubble is properly toggled when handling clicks.
Some legacy page actions have suggestion chips that show temporarily (eg. show for 10 seconds when the page action appears, then shrink back down to an icon). The new framework does not natively support this capability, beyond the ability to request a chip. Note that a request to show a chip does not guarantee its visibility.
Recommendation: Don’t use transient chips going forward.