Chrome Release Bot (LUCI) 4762b62e7d Publish DEPS for 106.0.5249.13 | 1 year ago | |
---|---|---|
.. | ||
common | 1 year ago | |
test | 1 year ago | |
views | 1 year ago | |
webui | 1 year ago | |
DEPS | 1 year ago | |
DIR_METADATA | 1 year ago | |
OWNERS | 1 year ago | |
README.md | 1 year ago |
This library contains the code that will allow you to implement In-Product-Help (IPH) and Tutorials in any framework, as well as display the «New» Badge on menus and labels.
Familiarity with these libraries are strongly recommended; feel free to reach out to their respective OWNERS if you have any questions.
HelpBubble
s, IPH, and Tutorials.HelpBubble
in a
Views-based UI, as well as «New» Badge primitives.HelpBubble
on a WebUI surface.The core presentation element for both IPH and Tutorials is the
HelpBubble. A HelpBubble
is a blue bubble that
appears anchored to an element in your application’s UI and which contains
information about that element. For example, a HelpBubble
might appear
underneath the profile button the first time the user starts Chrome after
adding a second profile, showing the user how they can switch between profiles.
Different UI frameworks have different HelpBubble
implementations; for
example, HelpBubbleViews. Each type of
HelpBubble
is created by a different
HelpBubbleFactory, which is registered at
startup in the global
HelpBubbleFactoryRegistry. So for
example, Chrome registers separate factories for Views and WebUI, and on Mac
a third factory that can attach a Views-based HelpBubble
to a Mac native menu.
To actually show the bubble, the HelpBubbleFactoryRegistry
needs two things:
TrackedElement
the bubble will be anchored toYou will notice that this is an extremely bare-bones system. You are not
expected to call HelpBubbleFactoryRegistry
directly! Rather, the IPH and
Tutorial systems use this API to show help bubbles.
In-Product Help is the simpler of the two ways to display help bubbles, and can even be the entry point for a Tutorial.
IPH are:
Your application will provide a FeaturePromoController with a FeaturePromoRegistry. In order to add a new IPH, you will need to:
base::Feature
corresponding to the IPH.FeaturePromoController::MaybeShowPromo()
at the point in the code
when the promo should trigger, adding feature-specific logic for when the
promo is appropriate.feature_engagement::Tracker::NotifyEvent()
for
events that should affect whether the IPH should display.
FeaturePromoControllerCommon::feature_engagement_tracker()
.FeaturePromoController::CloseBubble()
or
FeaturePromoController::CloseBubbleAndContinuePromo()
to
programmatically end the promo when the user engages your feature.You will want to create a FeaturePromoSpecification
and register it with
FeaturePromoRegistry::RegisterFeature()
. There should be a common function
your application uses to register IPH journeys during startup; in Chrome it’s
MaybeRegisterChromeFeaturePromos()
.
There are several factory methods on FeaturePromoSpecification for different types of IPH:
CreateForSnoozePromo()
except that
the «got it» button is replaced by a «learn more» button that launches a
Tutorial.You may also call the following methods to add additional features to a bubble:
These are advanced features
ElementIdentifier
.Tutorials are the more complicated, in-depth way to display a series of help bubbles. Often an IPH is an entry point to a Tutorial but Tutorials can also be launched from e.g. a «What’s New» or «Tips» page.
Tutorials are:
Your application will provide a TutorialService with a TutorialRegistry. In order to add a new Tutorial, you will need to:
TutorialIdentifier
and
TutorialDescription; details will be
provided below.TutorialService::StartTutorial()
, or…CreateForTutorialPromo()
factory method.A TutorialDescription is the template from
which a Tutorial is built. A Tutorial
is a stateful,
executable object that «runs» the Tutorial itself; since they can’t be reused,
one needs to be created every time the Tutorial is started.
There are only a few fields in a TutorialDescription
:
histograms - Must be populated if you want UMA histograms regarding user engagement with your Tutorial.
The preferred syntax is:
const char kMyTutorialHistogramPrefix[] = "MyTutorial";
tutorial_description.histograms =
user_education::MakeTutorialHistograms<kMyTutorialHistogramPrefix>(
tutorial_description.steps.size());
The kMyTutorialHistogramPrefix
needs to be declared as a local
const char[]
and have a globally-unique value. This will appear in UMA
histogram entries associated with your tutorial. If this value is
duplicated the histogram behavior will be undefined.
Note that this cannot be done automatically by the TutorialRegistry as
the UMA histograms won’t work without the static declarations
implemented by the TutorialHistogramsImpl<>
template class (via C++
template specialization magic).
can_be_restarted - If set to true
the Tutorial will provide an option
to restart on the last step, in case the user wants to see the Tutorial
again.
false
(the default) will not prevent the user from
triggering the Tutorial again via other means.TutorialDescription::Step
is a bit more complex. Steps may
either be created all at once with the omnibus constructor, or created with the
default constructor and then have each field set individually. The fields of the
struct are as follows:
HelpBubbleParams::body_text
. If not set, this Tutorial step is a «hidden
step» and will have no bubble.HelpBubbleParams::title_text
.element_name
is set.HelpBubble
for this step will anchor to
the target element.step_type
is kCustomEvent
, specifies the custom
event the step will transition on. Ignored otherwise.ElementIdentifier
before the Tutorial runs.name_elements_callback
in a previous step, rather than using
element_id
. The element must have been named and still be visible.step_type
is kShown
or kHidden
,
causes this step to start only when a UI element actively becomes visible
or loses visibility. Corresponds to
InteractionSequence::StepBuilder::SetTransitionOnlyOnEvent()
.InteractionSequence::Step
. Should only be set if
the Tutorial won’t work properly otherwise.Notes:
TutorialDescription::Step
is copyable and a step can be added to the
steps
member of multiple related TutorialDescription
s.Step
is a little clunky;
at some future point they will be moved to a builder pattern like
FeaturePromoSpecification
.Once you have defined your Tutorial; call AddTutorial()
on the
TutorialRegistry provided by your application
and pass both your TutorialIdentifier
and your TutorialDescription
.
For implementation on adding a «New» Badge to Chrome, Googlers can refer to the following document: New Badge How-To and Best Practices.
There are a number of virtual methods that must be implemented before you can use these User Education libraries in a new application, mostly centered around localization, accelerators, and global input focus.
Fortunately for Chromium developers, the browser already has the necessary support built in for Views, WebUI, and Mac-native context menus. You may refer to the following locations for an example that could be extended to other platforms such as ChromeOS:
TutorialService
.FeaturePromoController
.