Add Gerrit.on('history', f) to JS plugin API

The history event is fired when the browser displays a new screen.  It
replaces the older gerrit_addHistoryHook(f) function.  To give plugins
and site owners time to migrate the UI will continue supporting the
old function.

Change-Id: I3fdaa326b50cae1daa24564c4f1b3349fdc765fe
This commit is contained in:
Shawn Pearce 2013-11-29 20:38:55 -08:00
parent 7c418993fc
commit a48826eb20
4 changed files with 38 additions and 40 deletions

View File

@ -104,12 +104,13 @@ To connect Gerrit to Google Analytics add the following to your
var pageTracker = _gat._getTracker("UA-nnnnnnn-n");
pageTracker._trackPageview();
</script>
<!-- /standard analytics code -->
be <!-- /standard analytics code -->
<script type="text/javascript">
window.onload = function() {
gerrit_addHistoryHook(function (s) {
pageTracker._trackPageview(s.replace(/#/, '/'))
var p = window.location.pathname;
Gerrit.on('history', function (s) {
pageTracker._trackPageview(p + '/' + s)
});
};
</script>
@ -124,19 +125,22 @@ If your footer is otherwise empty, wrap all of the script tags into
a single `<div>` tag (like above) to ensure it is a well-formed
XHTML document file.
The global function `gerrit_addHistoryHook` accepts functions that
The global function `Gerrit.on("history")` accepts functions that
accept a string parameter. These functions are put into a list and
invoked any time Gerrit shifts URLs. You'll see page names like
`/#change,123` be passed to these functions, which in turn
are handed off to Google Analytics for tracking. Our example hook
above replaces '#' with '/' because Analytics won't track anchors.
`/c/123` be passed to these functions, which in turn are handed off
to Google Analytics for tracking. Our example hook above uses '/'
instead of '#' because Analytics won't track anchors.
The `window.onload` callback is necessary to ensure that the
`gerrit_addHistoryHook` function has actually been defined by the
`Gerrit.on()` function has actually been defined by the
page. Because GWT loads the module asynchronously any `<script>`
block in the header or footer will execute before Gerrit has defined
the function and is ready to register the hook callback.
The function `gerrit_addHistoryHook` is deprecated and may be
removed in a future release.
GERRIT
------
Part of link:index.html[Gerrit Code Review]

View File

@ -148,6 +148,11 @@ Gerrit.on(event, callback);
Supported events:
* `history`: Invoked when the view is changed to a new page 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]

View File

@ -92,7 +92,6 @@ import com.google.gwtjsonrpc.client.impl.ResultDeserializer;
import com.google.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.client.KeyUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -446,38 +445,13 @@ public class Gerrit implements EntryPoint {
}
}
private static ArrayList<JavaScriptObject> historyHooks;
private static Anchor signInAnchor;
private static native void initHistoryHooks()
/*-{ $wnd['gerrit_addHistoryHook'] = function(h) { @com.google.gerrit.client.Gerrit::addHistoryHook(Lcom/google/gwt/core/client/JavaScriptObject;)(h); }; }-*/;
static void addHistoryHook(final JavaScriptObject hook) {
if (historyHooks == null) {
historyHooks = new ArrayList<JavaScriptObject>();
History.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
dispatchHistoryHooks(event.getValue());
}
});
}
historyHooks.add(hook);
}
private static native void callHistoryHook(JavaScriptObject hook, String url)
/*-{ hook(url); }-*/;
private static void dispatchHistoryHooks(final String historyToken) {
private static void dispatchHistoryHooks(String token) {
if (signInAnchor != null) {
signInAnchor.setHref(loginRedirect(historyToken));
}
if (historyHooks != null) {
final String url = Location.getPath() + "#" + historyToken;
for (final JavaScriptObject hook : historyHooks) {
callHistoryHook(hook, url);
}
signInAnchor.setHref(loginRedirect(token));
}
ApiGlue.fireEvent("history", token);
}
private static void populateBottomMenu(RootPanel btmmenu, HostPageData hpd) {
@ -572,15 +546,15 @@ public class Gerrit implements EntryPoint {
gStarting.getElement().getParentElement().removeChild(
gStarting.getElement());
RootPanel.detachNow(gStarting);
ApiGlue.init();
applyUserPreferences();
initHistoryHooks();
populateBottomMenu(bottomMenu, hpd);
refreshMenuBar();
History.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(final ValueChangeEvent<String> event) {
public void onValueChange(ValueChangeEvent<String> event) {
display(event.getValue());
}
});
@ -607,7 +581,6 @@ public class Gerrit implements EntryPoint {
}
private void loadPlugins(HostPageData hpd, final String token) {
ApiGlue.init();
if (hpd.plugins != null && !hpd.plugins.isEmpty()) {
for (final String url : hpd.plugins) {
ScriptInjector.fromUrl(url)

View File

@ -26,6 +26,7 @@ public class ApiGlue {
public static void init() {
init0();
ActionContext.init();
addHistoryHook();
}
private static native void init0() /*-{
@ -110,6 +111,14 @@ public class ApiGlue {
$wnd.Gerrit = Gerrit;
}-*/;
/** Install deprecated {@code gerrit_addHistoryHook()} function. */
private static native void addHistoryHook() /*-{
$wnd.gerrit_addHistoryHook = function(h) {
var p = @com.google.gwt.user.client.Window.Location::getPath()();
$wnd.Gerrit.on('history', function(t) { h(p + "#" + t) })
};
}-*/;
private static void install(JavaScriptObject cb, JavaScriptObject p) {
try {
pluginName = PluginName.get();
@ -142,6 +151,13 @@ public class ApiGlue {
static final native void invoke(JavaScriptObject f, JavaScriptObject a, JavaScriptObject b) /*-{ f(a,b) }-*/;
static final native void invoke(JavaScriptObject f, String a) /*-{ f(a); }-*/;
public static final void fireEvent(String event, String a) {
JsArray<JavaScriptObject> h = getEventHandlers(event);
for (int i = 0; i < h.length(); i++) {
invoke(h.get(i), a);
}
}
static final void fireEvent(String event, JavaScriptObject a, JavaScriptObject b) {
JsArray<JavaScriptObject> h = getEventHandlers(event);
for (int i = 0; i < h.length(); i++) {