= Gerrit Code Review - JavaScript API

Gerrit Code Review supports an API for JavaScript plugins to interact
with the web UI and the server process.

== Entry Point

JavaScript is loaded using a standard `<script src='...'>` HTML tag.
Plugins should protect the global namespace by defining their code
within an anonymous function passed to `Gerrit.install()`. The plugin
will be passed an object describing its registration with Gerrit:

[source,javascript]
----
Gerrit.install(function (self) {
  // ... plugin JavaScript code here ...
});
----


[[self]]
== Plugin Instance

The plugin instance is passed to the plugin's initialization function
and provides a number of utility services to plugin authors.

[[self_delete]]
=== self.delete() / self.del()
Issues a DELETE REST API request to the Gerrit server.

.Signature
[source,javascript]
----
Gerrit.delete(url, callback)
Gerrit.del(url, callback)
----

* url: URL relative to the plugin's URL space. The JavaScript
  library prefixes the supplied URL with `/plugins/{getPluginName}/`.

* callback: JavaScript function to be invoked with the parsed
  JSON result of the API call. DELETE methods often return
  `204 No Content`, which is passed as null.

[[self_get]]
=== self.get()
Issues a GET REST API request to the Gerrit server.

.Signature
[source,javascript]
----
self.get(url, callback)
----

* url: URL relative to the plugin's URL space. The JavaScript
  library prefixes the supplied URL with `/plugins/{getPluginName}/`.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[[self_getServerInfo]]
=== self.getServerInfo()
Returns the server's link:rest-api-config.html#server-info[ServerInfo]
data.

[[self_getCurrentUser]]
=== self.getCurrentUser()
Returns the currently signed in user's AccountInfo data; empty account
data if no user is currently signed in.

[[Gerrit_getUserPreferences]]
=== Gerrit.getUserPreferences()
Returns the preferences of the currently signed in user; the default
preferences if no user is currently signed in.

[[Gerrit_refreshUserPreferences]]
=== Gerrit.refreshUserPreferences()
Refreshes the preferences of the current user.

[[self_getPluginName]]
=== self.getPluginName()
Returns the name this plugin was installed as by the server
administrator. The plugin name is required to access REST API
views installed by the plugin, or to access resources.

[[self_post]]
=== self.post()
Issues a POST REST API request to the Gerrit server.

.Signature
[source,javascript]
----
self.post(url, input, callback)
----

* url: URL relative to the plugin's URL space. The JavaScript
  library prefixes the supplied URL with `/plugins/{getPluginName}/`.

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
self.post(
  '/my-servlet',
  {start_build: true, platform_type: 'Linux'},
  function (r) {});
----

[[self_put]]
=== self.put()
Issues a PUT REST API request to the Gerrit server.

.Signature
[source,javascript]
----
self.put(url, input, callback)
----

* url: URL relative to the plugin's URL space. The JavaScript
  library prefixes the supplied URL with `/plugins/{getPluginName}/`.

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
self.put(
  '/builds',
  {start_build: true, platform_type: 'Linux'},
  function (r) {});
----

[[self_on]]
=== self.on()
Register a JavaScript callback to be invoked when events occur within
the web interface.

.Signature
[source,javascript]
----
Gerrit.on(event, callback);
----

* event: A supported event type. See below for description.

* callback: JavaScript function to be invoked when event happens.
  Arguments may be passed to this function, depending on the event.

Supported events:

* `history`: Invoked when the view is changed to a new screen within
  the Gerrit web application.  The token after "#" is passed as the
  argument to the callback function, for example "/c/42/" while
  showing change 42.

* `showchange`: Invoked when a change is made visible. A
  link:rest-api-changes.html#change-info[ChangeInfo] and
  link:rest-api-changes.html#revision-info[RevisionInfo]
  are passed as arguments. PolyGerrit provides a third parameter which
  is an object with a `mergeable` boolean.

* `submitchange`: Invoked when the submit button is clicked
  on a change. A link:rest-api-changes.html#change-info[ChangeInfo]
  and link:rest-api-changes.html#revision-info[RevisionInfo] are
  passed as arguments. Similar to a form submit validation, the
  function must return true to allow the operation to continue, or
  false to prevent it. The function may be called multiple times, for
  example, if submitting a change shows a confirmation dialog, this
  event may be called to validate that the check whether dialog can be
  shown, and called again when the submit is confirmed to check whether
  the actual submission action can proceed.

* `comment`: Invoked when a DOM element that represents a comment is
  created. This DOM element is passed as argument. This DOM element
  contains nested elements that Gerrit uses to format the comment. The
  DOM structure may differ between comment types such as inline
  comments, file-level comments and summary comments, and it may change
  with new Gerrit versions.

* `highlightjs-loaded`: Invoked when the highlight.js library has
  finished loading. The global `hljs` object (also now accessible via
  `window.hljs`) is passed as an argument to the callback function.
  This event can be used to register a new language highlighter with
  the highlight.js library before syntax highlighting begins.

[[self_onAction]]
=== self.onAction()
Register a JavaScript callback to be invoked when the user clicks
on a button associated with a server side `UiAction`.

.Signature
[source,javascript]
----
self.onAction(type, view_name, callback);
----

* type: `'change'`, `'edit'`, `'revision'`, `'project'`, or `'branch'`
  indicating which type of resource the `UiAction` was bound to
  in the server.

* view_name: string appearing in URLs to name the view. This is the
  second argument of the `get()`, `post()`, `put()`, and `delete()`
  binding methods in a `RestApiModule`.

* callback: JavaScript function to invoke when the user clicks. The
  function will be passed a link:#ActionContext[action context].

[[self_screen]]
=== self.screen()
Register a JavaScript callback to be invoked when the user navigates
to an extension screen provided by the plugin. Extension screens are
usually linked from the link:dev-plugins.html#top-menu-extensions[top menu].
The callback can populate the DOM with the screen's contents.

.Signature
[source,javascript]
----
self.screen(pattern, callback);
----

* pattern: URL token pattern to identify the screen. Argument can be
  either a string (`'index'`) or a RegExp object (`/list\/(.*)/`).
  If a RegExp is used the matching groups will be available inside of
  the context as `token_match`.

* callback: JavaScript function to invoke when the user navigates to
  the screen. The function will be passed a link:#ScreenContext[screen context].

[[self_settingsScreen]]
=== self.settingsScreen()
Register a JavaScript callback to be invoked when the user navigates
to an extension settings screen provided by the plugin. Extension settings
screens are automatically linked from the settings menu under the given
menu entry.
The callback can populate the DOM with the screen's contents.

.Signature
[source,javascript]
----
self.settingsScreen(path, menu, callback);
----

* path: URL path to identify the settings screen.

* menu: The name of the menu entry in the settings menu that should
  link to the settings screen.

* callback: JavaScript function to invoke when the user navigates to
  the settings screen. The function will be passed a
  link:#SettingsScreenContext[settings screen context].

[[self_panel]]
=== self.panel()
Register a JavaScript callback to be invoked when a screen with the
given extension point is loaded.
The callback can populate the DOM with the panel's contents.

.Signature
[source,javascript]
----
self.panel(extensionpoint, callback);
----

* extensionpoint: The name of the extension point that marks the
  position where the panel is added to an existing screen. The
  available extension points are described in the
  link:dev-plugins.html#panels[plugin development documentation].

* callback: JavaScript function to invoke when a screen with the
  extension point is loaded. The function will be passed a
  link:#PanelContext[panel context].

[[self_url]]
=== self.url()
Returns a URL within the plugin's URL space. If invoked with no
parameter the URL of the plugin is returned. If passed a string
the argument is appended to the plugin URL.

[source,javascript]
----
self.url();                    // "https://gerrit-review.googlesource.com/plugins/demo/"
self.url('/static/icon.png');  // "https://gerrit-review.googlesource.com/plugins/demo/static/icon.png"
----


[[ActionContext]]
== Action Context
A new action context is passed to the `onAction` callback function
each time the associated action button is clicked by the user. A
context is initialized with sufficient state to issue the associated
REST API RPC.

[[context_action]]
=== context.action
An link:rest-api-changes.html#action-info[ActionInfo] object instance
supplied by the server describing the UI button the user used to
invoke the action.

[[context_call]]
=== context.call()
Issues the REST API call associated with the action. The HTTP method
used comes from `context.action.method`, hiding the JavaScript from
needing to care.

.Signature
[source,javascript]
----
context.call(input, callback)
----

* input: JavaScript object to serialize as the request payload. This
  parameter is ignored for GET and DELETE methods.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
context.call(
  {message: "..."},
  function (result) {
    // ... use result here ...
  });
----

[[context_change]]
=== context.change
When the action is invoked on a change a
link:rest-api-changes.html#change-info[ChangeInfo] object instance
describing the change. Available fields of the ChangeInfo may vary
based on the options used by the UI when it loaded the change.

[[context_delete]]
=== context.delete()
Issues a DELETE REST API call to the URL associated with the action.

.Signature
[source,javascript]
----
context.delete(callback)
----

* callback: JavaScript function to be invoked with the parsed
  JSON result of the API call. DELETE methods often return
  `204 No Content`, which is passed as null.

[source,javascript]
----
context.delete(function () {});
----

[[context_get]]
=== context.get()
Issues a GET REST API call to the URL associated with the action.

.Signature
[source,javascript]
----
context.get(callback)
----

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
context.get(function (result) {
  // ... use result here ...
});
----

[[context_go]]
=== context.go()
Go to a screen. Shorthand for link:#Gerrit_go[`Gerrit.go()`].

[[context_hide]]
=== context.hide()
Hide the currently visible popup displayed by
link:#context_popup[`context.popup()`].

[[context_post]]
=== context.post()
Issues a POST REST API call to the URL associated with the action.

.Signature
[source,javascript]
----
context.post(input, callback)
----

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
context.post(
  {message: "..."},
  function (result) {
    // ... use result here ...
  });
----

[[context_popup]]
=== context.popup()

Displays a small popup near the activation button to gather
additional input from the user before executing the REST API RPC.

The caller is always responsible for closing the popup with
link#context_hide[`context.hide()`]. Gerrit will handle closing a
popup if the user presses `Escape` while keyboard focus is within
the popup.

.Signature
[source,javascript]
----
context.popup(element)
----

* element: an HTML DOM element to display as the body of the
  popup. This is typically a `div` element but can be any valid HTML
  element. CSS can be used to style the element beyond the defaults.

A common usage is to gather more input:

[source,javascript]
----
self.onAction('revision', 'start-build', function (c) {
  var l = c.checkbox();
  var m = c.checkbox();
  c.popup(c.div(
    c.div(c.label(l, 'Linux')),
    c.div(c.label(m, 'Mac OS X')),
    c.button('Build', {onclick: function() {
      c.call(
        {
          commit: c.revision.name,
          linux: l.checked,
          mac: m.checked,
        },
        function() { c.hide() });
    });
});
----

[[context_put]]
=== context.put()
Issues a PUT REST API call to the URL associated with the action.

.Signature
[source,javascript]
----
context.put(input, callback)
----

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
context.put(
  {message: "..."},
  function (result) {
    // ... use result here ...
  });
----

[[context_refresh]]
=== context.refresh()
Refresh the current display. Shorthand for
link:#Gerrit_refresh[`Gerrit.refresh()`].

[[context_revision]]
=== context.revision
When the action is invoked on a specific revision of a change,
a link:rest-api-changes.html#revision-info[RevisionInfo]
object instance describing the revision. Available fields of the
RevisionInfo may vary based on the options used by the UI when it
loaded the change.

[[context_project]]
=== context.project
When the action is invoked on a specific project,
the name of the project.

=== HTML Helpers
The link:#ActionContext[action context] includes some HTML helper
functions to make working with DOM based widgets less painful.

* `br()`: new `<br>` element.

* `button(label, options)`: new `<button>` with the string `label`
  wrapped inside of a `div`. The optional `options` object may
  define `onclick` as a function to be invoked upon clicking. This
  calling pattern avoids circular references between the element
  and the onclick handler.

* `checkbox()`: new `<input type='checkbox'>` element.
* `div(...)`: a new `<div>` wrapping the (optional) arguments.
* `hr()`: new `<hr>` element.

* `label(c, label)`: a new `<label>` element wrapping element `c`
  and the string `label`. Used to wrap a checkbox with its label,
  `label(checkbox(), 'Click Me')`.

* `prependLabel(label, c)`: a new `<label>` element wrapping element `c`
  and the string `label`. Used to wrap an input field with its label,
  `prependLabel('Greeting message', textfield())`.

* `textarea(options)`: new `<textarea>` element. The options
  object may optionally include `rows` and `cols`. The textarea
  comes with an onkeypress handler installed to play nicely with
  Gerrit's keyboard binding system.

* `textfield()`: new `<input type='text'>` element.  The text field
  comes with an onkeypress handler installed to play nicely with
  Gerrit's keyboard binding system.

* `select(a,i)`: a new `<select>` element containing one `<option>`
  element for each entry in the provided array `a`.  The option with
  the index `i` will be pre-selected in the drop-down-list.

* `selected(s)`: returns the text of the `<option>` element that is
  currently selected in the provided `<select>` element `s`.

* `span(...)`: a new `<span>` wrapping the (optional) arguments.

* `msg(label)`: a new label.


[[ScreenContext]]
== Screen Context
A new screen context is passed to the `screen` callback function
each time the user navigates to a matching URL.

[[screen_body]]
=== screen.body
Empty HTML `<div>` node the plugin should add its content to.  The
node is already attached to the document, but is invisible.  Plugins
must call `screen.show()` to display the DOM node.  Deferred display
allows an implementor to partially populate the DOM, make remote HTTP
requests, finish populating when the callbacks arrive, and only then
make the view visible to the user.

[[screen_token]]
=== screen.token
URL token fragment that activated this screen.  The value is identical
to `screen.token_match[0]`.  If the URL is `/#/x/hello/list` the token
will be `"list"`.

[[screen_token_match]]
=== screen.token_match
Array of matching subgroups from the pattern specified to `screen()`.
This is identical to the result of RegExp.exec. Index 0 contains the
entire matching expression; index 1 the first matching group, etc.

[[screen_onUnload]]
=== screen.onUnload()
Configures an optional callback to be invoked just before the screen
is deleted from the browser DOM.  Plugins can use this callback to
remove event listeners from DOM nodes, preventing memory leaks.

.Signature
[source,javascript]
----
screen.onUnload(callback)
----

* callback: JavaScript function to be invoked just before the
  `screen.body` DOM element is removed from the browser DOM.
  This event happens when the user navigates to another screen.

[[screen.setTitle]]
=== screen.setTitle()
Sets the heading text to be displayed when the screen is visible.
This is presented in a large bold font below the menus, but above the
content in `screen.body`.  Setting the title also sets the window
title to the same string, if it has not already been set.

.Signature
[source,javascript]
----
screen.setPageTitle(titleText)
----

[[screen.setWindowTitle]]
=== screen.setWindowTitle()
Sets the text to be displayed in the browser's title bar when the
screen is visible.  Plugins should always prefer this method over
trying to set `window.title` directly.  The window title defaults to
the title given to `setTitle`.

.Signature
[source,javascript]
----
screen.setWindowTitle(titleText)
----

[[screen_show]]
=== screen.show()
Destroy the currently visible screen and display the plugin's screen.
This method must be called after adding content to `screen.body`.

[[SettingsScreenContext]]
== Settings Screen Context
A new settings screen context is passed to the `settingsScreen` callback
function each time the user navigates to a matching URL.

[[settingsScreen_body]]
=== settingsScreen.body
Empty HTML `<div>` node the plugin should add its content to.  The
node is already attached to the document, but is invisible.  Plugins
must call `settingsScreen.show()` to display the DOM node.  Deferred
display allows an implementor to partially populate the DOM, make
remote HTTP requests, finish populating when the callbacks arrive, and
only then make the view visible to the user.

[[settingsScreen_onUnload]]
=== settingsScreen.onUnload()
Configures an optional callback to be invoked just before the screen
is deleted from the browser DOM.  Plugins can use this callback to
remove event listeners from DOM nodes, preventing memory leaks.

.Signature
[source,javascript]
----
settingsScreen.onUnload(callback)
----

* callback: JavaScript function to be invoked just before the
  `settingsScreen.body` DOM element is removed from the browser DOM.
  This event happens when the user navigates to another screen.

[[settingsScreen.setTitle]]
=== settingsScreen.setTitle()
Sets the heading text to be displayed when the screen is visible.
This is presented in a large bold font below the menus, but above the
content in `settingsScreen.body`. Setting the title also sets the
window title to the same string, if it has not already been set.

.Signature
[source,javascript]
----
settingsScreen.setPageTitle(titleText)
----

[[settingsScreen.setWindowTitle]]
=== settingsScreen.setWindowTitle()
Sets the text to be displayed in the browser's title bar when the
screen is visible.  Plugins should always prefer this method over
trying to set `window.title` directly.  The window title defaults to
the title given to `setTitle`.

.Signature
[source,javascript]
----
settingsScreen.setWindowTitle(titleText)
----

[[settingsScreen_show]]
=== settingsScreen.show()
Destroy the currently visible screen and display the plugin's screen.
This method must be called after adding content to
`settingsScreen.body`.

[[PanelContext]]
== Panel Context
A new panel context is passed to the `panel` callback function each
time a screen with the given extension point is loaded.

[[panel_body]]
=== panel.body
Empty HTML `<div>` node the plugin should add the panel content to.
The node is already attached to the document.

[[PanelProperties]]
=== Properties

The extension panel parameters that are described in the
link:dev-plugins.html#panels[plugin development documentation] are
contained in the context as properties. Which properties are available
depends on the extension point.

[[Gerrit]]
== Gerrit

The `Gerrit` object is the only symbol provided into the global
namespace by Gerrit Code Review. All top-level functions can be
accessed through this name.

[[Gerrit_css]]
=== Gerrit.css()
[WARNING]
This method is deprecated. It doesn't work with Shadow DOM and
will be removed in the future. Please, use link:pg-plugin-dev.html#plugin-styles[plugin.styles] instead.

Creates a new unique CSS class and injects it into the document.
The name of the class is returned and can be used by the plugin.

Classes created with this function should be created once at install
time and reused throughout the plugin.  Repeatedly creating the same
class will explode the global stylesheet.

.Signature
[source,javascript]
----
Gerrit.install(function(self)) {
  var style = {
    name: Gerrit.css('background: #fff; color: #000;'),
  };
});
----

[[Gerrit_delete]]
=== Gerrit.delete()
Issues a DELETE REST API request to the Gerrit server. For plugin
private REST API URLs see link:#self_delete[self.delete()].

.Signature
[source,javascript]
----
Gerrit.delete(url, callback)
----

* url: URL relative to the Gerrit server. For example to access the
  link:rest-api-changes.html[changes REST API] use `'/changes/'`.

* callback: JavaScript function to be invoked with the parsed
  JSON result of the API call. DELETE methods often return
  `204 No Content`, which is passed as null.

[source,javascript]
----
Gerrit.delete(
  '/changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/topic',
  function () {});
----

[[Gerrit_get]]
=== Gerrit.get()
Issues a GET REST API request to the Gerrit server. For plugin
private REST API URLs see link:#self_get[self.get()].

.Signature
[source,javascript]
----
Gerrit.get(url, callback)
----

* url: URL relative to the Gerrit server. For example to access the
  link:rest-api-changes.html[changes REST API] use `'/changes/'`.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
Gerrit.get('/changes/?q=status:open', function (open) {
  for (var i = 0; i < open.length; i++) {
    console.log(open[i].change_id);
  }
});
----

[[Gerrit_getCurrentUser]]
=== Gerrit.getCurrentUser()
Returns the currently signed in user's AccountInfo data; empty account
data if no user is currently signed in.

[[Gerrit_getPluginName]]
=== Gerrit.getPluginName()
Returns the name this plugin was installed as by the server
administrator. The plugin name is required to access REST API
views installed by the plugin, or to access resources.

Unlike link:#self_getPluginName[`self.getPluginName()`] this method
must guess the name from the JavaScript call stack. Plugins are
encouraged to use `self.getPluginName()` whenever possible.

[[Gerrit_go]]
=== Gerrit.go()
Updates the web UI to display the screen identified by the supplied
URL token. The URL token is the text after `#` in the browser URL.

[source,javascript]
----
Gerrit.go('/admin/projects/');
----

If the URL passed matches `http://...`, `https://...`, or `//...`
the current browser window will navigate to the non-Gerrit URL.
The user can return to Gerrit with the back button.

[[Gerrit_install]]
=== Gerrit.install()
Registers a new plugin by invoking the supplied initialization
function. The function is passed the link:#self[plugin instance].

[source,javascript]
----
Gerrit.install(function (self) {
  // ... plugin JavaScript code here ...
});
----

[[Gerrit_post]]
=== Gerrit.post()
Issues a POST REST API request to the Gerrit server. For plugin
private REST API URLs see link:#self_post[self.post()].

.Signature
[source,javascript]
----
Gerrit.post(url, input, callback)
----

* url: URL relative to the Gerrit server. For example to access the
  link:rest-api-changes.html[changes REST API] use `'/changes/'`.

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
Gerrit.post(
  '/changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/topic',
  {topic: 'tests', message: 'Classify work as for testing.'},
  function (r) {});
----

[[Gerrit_put]]
=== Gerrit.put()
Issues a PUT REST API request to the Gerrit server. For plugin
private REST API URLs see link:#self_put[self.put()].

.Signature
[source,javascript]
----
Gerrit.put(url, input, callback)
----

* url: URL relative to the Gerrit server. For example to access the
  link:rest-api-changes.html[changes REST API] use `'/changes/'`.

* input: JavaScript object to serialize as the request payload.

* callback: JavaScript function to be invoked with the parsed JSON
  result of the API call. If the API returns a string the result is
  a string, otherwise the result is a JavaScript object or array,
  as described in the relevant REST API documentation.

[source,javascript]
----
Gerrit.put(
  '/changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/topic',
  {topic: 'tests', message: 'Classify work as for testing.'},
  function (r) {});
----

[[Gerrit_onAction]]
=== Gerrit.onAction()
Register a JavaScript callback to be invoked when the user clicks
on a button associated with a server side `UiAction`.

.Signature
[source,javascript]
----
Gerrit.onAction(type, view_name, callback);
----

* type: `'change'`, `'edit'`, `'revision'`, `'project'` or `'branch'`
  indicating what sort of resource the `UiAction` was bound to in the server.

* view_name: string appearing in URLs to name the view. This is the
  second argument of the `get()`, `post()`, `put()`, and `delete()`
  binding methods in a `RestApiModule`.

* callback: JavaScript function to invoke when the user clicks. The
  function will be passed a link:#ActionContext[ActionContext].

[[Gerrit_screen]]
=== Gerrit.screen()
Register a JavaScript callback to be invoked when the user navigates
to an extension screen provided by the plugin. Extension screens are
usually linked from the link:dev-plugins.html#top-menu-extensions[top menu].
The callback can populate the DOM with the screen's contents.

.Signature
[source,javascript]
----
Gerrit.screen(pattern, callback);
----

* pattern: URL token pattern to identify the screen. Argument can be
  either a string (`'index'`) or a RegExp object (`/list\/(.*)/`).
  If a RegExp is used the matching groups will be available inside of
  the context as `token_match`.

* callback: JavaScript function to invoke when the user navigates to
  the screen. The function will be passed link:#ScreenContext[screen context].

[[Gerrit_refresh]]
=== Gerrit.refresh()
Redisplays the current web UI view, refreshing all information.

[[Gerrit_refreshMenuBar]]
=== Gerrit.refreshMenuBar()
Refreshes Gerrit's menu bar.

[[Gerrit_isSignedIn]]
=== Gerrit.isSignedIn()
Checks if user is signed in.

[[Gerrit_url]]
=== Gerrit.url()
Returns the URL of the Gerrit Code Review server. If invoked with
no parameter the URL of the site is returned. If passed a string
the argument is appended to the site URL.

[source,javascript]
----
Gerrit.url();        // "https://gerrit-review.googlesource.com/"
Gerrit.url('/123');  // "https://gerrit-review.googlesource.com/123"
----

For a plugin specific version see link:#self_url()[`self.url()`].

[[Gerrit_showError]]
=== Gerrit.showError(message)
Displays the given message in the Gerrit ErrorDialog.

GERRIT
------
Part of link:index.html[Gerrit Code Review]

SEARCHBOX
---------
