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

View File

@ -148,6 +148,11 @@ Gerrit.on(event, callback);
Supported events: 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 * `showchange`: Invoked when a change is made visible. A
link:rest-api-changes.html#change-info[ChangeInfo] and link:rest-api-changes.html#change-info[ChangeInfo] and
link:rest-api-changes.html#revision-info[RevisionInfo] 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.gwtjsonrpc.common.AsyncCallback;
import com.google.gwtorm.client.KeyUtil; import com.google.gwtorm.client.KeyUtil;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -446,38 +445,13 @@ public class Gerrit implements EntryPoint {
} }
} }
private static ArrayList<JavaScriptObject> historyHooks;
private static Anchor signInAnchor; private static Anchor signInAnchor;
private static native void initHistoryHooks() private static void dispatchHistoryHooks(String token) {
/*-{ $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) {
if (signInAnchor != null) { if (signInAnchor != null) {
signInAnchor.setHref(loginRedirect(historyToken)); signInAnchor.setHref(loginRedirect(token));
}
if (historyHooks != null) {
final String url = Location.getPath() + "#" + historyToken;
for (final JavaScriptObject hook : historyHooks) {
callHistoryHook(hook, url);
}
} }
ApiGlue.fireEvent("history", token);
} }
private static void populateBottomMenu(RootPanel btmmenu, HostPageData hpd) { private static void populateBottomMenu(RootPanel btmmenu, HostPageData hpd) {
@ -572,15 +546,15 @@ public class Gerrit implements EntryPoint {
gStarting.getElement().getParentElement().removeChild( gStarting.getElement().getParentElement().removeChild(
gStarting.getElement()); gStarting.getElement());
RootPanel.detachNow(gStarting); RootPanel.detachNow(gStarting);
ApiGlue.init();
applyUserPreferences(); applyUserPreferences();
initHistoryHooks();
populateBottomMenu(bottomMenu, hpd); populateBottomMenu(bottomMenu, hpd);
refreshMenuBar(); refreshMenuBar();
History.addValueChangeHandler(new ValueChangeHandler<String>() { History.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override @Override
public void onValueChange(final ValueChangeEvent<String> event) { public void onValueChange(ValueChangeEvent<String> event) {
display(event.getValue()); display(event.getValue());
} }
}); });
@ -607,7 +581,6 @@ public class Gerrit implements EntryPoint {
} }
private void loadPlugins(HostPageData hpd, final String token) { private void loadPlugins(HostPageData hpd, final String token) {
ApiGlue.init();
if (hpd.plugins != null && !hpd.plugins.isEmpty()) { if (hpd.plugins != null && !hpd.plugins.isEmpty()) {
for (final String url : hpd.plugins) { for (final String url : hpd.plugins) {
ScriptInjector.fromUrl(url) ScriptInjector.fromUrl(url)

View File

@ -26,6 +26,7 @@ public class ApiGlue {
public static void init() { public static void init() {
init0(); init0();
ActionContext.init(); ActionContext.init();
addHistoryHook();
} }
private static native void init0() /*-{ private static native void init0() /*-{
@ -110,6 +111,14 @@ public class ApiGlue {
$wnd.Gerrit = Gerrit; $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) { private static void install(JavaScriptObject cb, JavaScriptObject p) {
try { try {
pluginName = PluginName.get(); 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, JavaScriptObject a, JavaScriptObject b) /*-{ f(a,b) }-*/;
static final native void invoke(JavaScriptObject f, String a) /*-{ f(a); }-*/; 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) { static final void fireEvent(String event, JavaScriptObject a, JavaScriptObject b) {
JsArray<JavaScriptObject> h = getEventHandlers(event); JsArray<JavaScriptObject> h = getEventHandlers(event);
for (int i = 0; i < h.length(); i++) { for (int i = 0; i < h.length(); i++) {