Firefox doesn't implement the IE6 fromElement/toElement, and it's not in the MouseEvent spec (at the moment). Replace with the worse-named but better-specified target and relatedTarget attributes instead. Upstream change: https://gerrit-review.googlesource.com/q/I9eeb26c032a38de9d7185749373c7982c796acb2 Change-Id: I9f9a1eb9342bc80b91b5b364a04cc5fa9a7ccaeb Reviewed-on: https://cl.tvl.fyi/c/depot/+/1442 Tested-by: BuildkiteCI Reviewed-by: glittershark <grfn@gws.fyi>
		
			
				
	
	
		
			217 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
	
		
			8.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 61035d1e81884390708675ab994e0e7210659883 Mon Sep 17 00:00:00 2001
 | |
| From: Luke Granger-Brown <git@lukegb.com>
 | |
| Date: Thu, 2 Jul 2020 23:03:02 +0100
 | |
| Subject: [PATCH 4/7] Add titles to CLs over HTTP
 | |
| 
 | |
| ---
 | |
|  .../gerrit/httpd/raw/IndexHtmlUtil.java       | 14 +++-
 | |
|  .../google/gerrit/httpd/raw/IndexServlet.java |  7 +-
 | |
|  .../google/gerrit/httpd/raw/StaticModule.java |  5 +-
 | |
|  .../gerrit/httpd/raw/TitleComputer.java       | 67 +++++++++++++++++++
 | |
|  .../gerrit/httpd/raw/PolyGerritIndexHtml.soy  |  4 +-
 | |
|  5 files changed, 89 insertions(+), 8 deletions(-)
 | |
|  create mode 100644 java/com/google/gerrit/httpd/raw/TitleComputer.java
 | |
| 
 | |
| diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | |
| index cddaea4aaf..d5f43de025 100644
 | |
| --- a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | |
| +++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
 | |
| @@ -42,6 +42,7 @@ import java.util.Arrays;
 | |
|  import java.util.Collections;
 | |
|  import java.util.HashMap;
 | |
|  import java.util.Map;
 | |
| +import java.util.Optional;
 | |
|  import java.util.Set;
 | |
|  import java.util.function.Function;
 | |
|  import java.util.regex.Matcher;
 | |
| @@ -110,7 +111,8 @@ public class IndexHtmlUtil {
 | |
|        String faviconPath,
 | |
|        Map<String, String[]> urlParameterMap,
 | |
|        Function<String, SanitizedContent> urlInScriptTagOrdainer,
 | |
| -      String requestedURL)
 | |
| +      String requestedURL,
 | |
| +      TitleComputer titleComputer)
 | |
|        throws URISyntaxException, RestApiException {
 | |
|      ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
 | |
|      data.putAll(
 | |
| @@ -121,7 +123,7 @@ public class IndexHtmlUtil {
 | |
|                  urlParameterMap,
 | |
|                  urlInScriptTagOrdainer,
 | |
|                  requestedURL))
 | |
| -        .putAll(dynamicTemplateData(gerritApi));
 | |
| +        .putAll(dynamicTemplateData(gerritApi, requestedURL, titleComputer));
 | |
|  
 | |
|      Set<String> enabledExperiments = experimentData(urlParameterMap);
 | |
|      if (!enabledExperiments.isEmpty()) {
 | |
| @@ -131,7 +133,9 @@ public class IndexHtmlUtil {
 | |
|    }
 | |
|  
 | |
|    /** Returns dynamic parameters of {@code index.html}. */
 | |
| -  public static ImmutableMap<String, Object> dynamicTemplateData(GerritApi gerritApi)
 | |
| +  public static ImmutableMap<String, Object> dynamicTemplateData(GerritApi gerritApi,
 | |
| +                                                                 String requestedURL,
 | |
| +                                                                 TitleComputer titleComputer)
 | |
|        throws RestApiException {
 | |
|      ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
 | |
|      Map<String, SanitizedContent> initialData = new HashMap<>();
 | |
| @@ -158,6 +162,10 @@ public class IndexHtmlUtil {
 | |
|      }
 | |
|  
 | |
|      data.put("gerritInitialData", initialData);
 | |
| +
 | |
| +    Optional<String> title = titleComputer.computeTitle(requestedURL);
 | |
| +    title.ifPresent(s -> data.put("title", s));
 | |
| +
 | |
|      return data.build();
 | |
|    }
 | |
|  
 | |
| diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | |
| index 97d22701de..089ef4725f 100644
 | |
| --- a/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | |
| +++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java
 | |
| @@ -44,12 +44,14 @@ public class IndexServlet extends HttpServlet {
 | |
|    private final GerritApi gerritApi;
 | |
|    private final SoySauce soySauce;
 | |
|    private final Function<String, SanitizedContent> urlOrdainer;
 | |
| +  private TitleComputer titleComputer;
 | |
|  
 | |
|    IndexServlet(
 | |
|        @Nullable String canonicalUrl,
 | |
|        @Nullable String cdnPath,
 | |
|        @Nullable String faviconPath,
 | |
| -      GerritApi gerritApi) {
 | |
| +      GerritApi gerritApi,
 | |
| +      TitleComputer titleComputer) {
 | |
|      this.canonicalUrl = canonicalUrl;
 | |
|      this.cdnPath = cdnPath;
 | |
|      this.faviconPath = faviconPath;
 | |
| @@ -63,6 +65,7 @@ public class IndexServlet extends HttpServlet {
 | |
|          (s) ->
 | |
|              UnsafeSanitizedContentOrdainer.ordainAsSafe(
 | |
|                  s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
 | |
| +    this.titleComputer = titleComputer;
 | |
|    }
 | |
|  
 | |
|    @Override
 | |
| @@ -74,7 +77,7 @@ public class IndexServlet extends HttpServlet {
 | |
|        // TODO(hiesel): Remove URL ordainer as parameter once Soy is consistent
 | |
|        ImmutableMap<String, Object> templateData =
 | |
|            IndexHtmlUtil.templateData(
 | |
| -              gerritApi, canonicalUrl, cdnPath, faviconPath, parameterMap, urlOrdainer, requestUrl);
 | |
| +              gerritApi, canonicalUrl, cdnPath, faviconPath, parameterMap, urlOrdainer, requestUrl, titleComputer);
 | |
|        renderer = soySauce.renderTemplate("com.google.gerrit.httpd.raw.Index").setData(templateData);
 | |
|      } catch (URISyntaxException | RestApiException e) {
 | |
|        throw new IOException(e);
 | |
| diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
 | |
| index 414a120194..e1b6fb082d 100644
 | |
| --- a/java/com/google/gerrit/httpd/raw/StaticModule.java
 | |
| +++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
 | |
| @@ -220,11 +220,12 @@ public class StaticModule extends ServletModule {
 | |
|      HttpServlet getPolyGerritUiIndexServlet(
 | |
|          @CanonicalWebUrl @Nullable String canonicalUrl,
 | |
|          @GerritServerConfig Config cfg,
 | |
| -        GerritApi gerritApi) {
 | |
| +        GerritApi gerritApi,
 | |
| +        TitleComputer titleComputer) {
 | |
|        String cdnPath =
 | |
|            options.useDevCdn() ? options.devCdn() : cfg.getString("gerrit", null, "cdnPath");
 | |
|        String faviconPath = cfg.getString("gerrit", null, "faviconPath");
 | |
| -      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi);
 | |
| +      return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi, titleComputer);
 | |
|      }
 | |
|  
 | |
|      @Provides
 | |
| diff --git a/java/com/google/gerrit/httpd/raw/TitleComputer.java b/java/com/google/gerrit/httpd/raw/TitleComputer.java
 | |
| new file mode 100644
 | |
| index 0000000000..8fd2053ad0
 | |
| --- /dev/null
 | |
| +++ b/java/com/google/gerrit/httpd/raw/TitleComputer.java
 | |
| @@ -0,0 +1,67 @@
 | |
| +package com.google.gerrit.httpd.raw;
 | |
| +
 | |
| +import com.google.common.flogger.FluentLogger;
 | |
| +import com.google.gerrit.entities.Change;
 | |
| +import com.google.gerrit.extensions.restapi.ResourceConflictException;
 | |
| +import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 | |
| +import com.google.gerrit.server.change.ChangeResource;
 | |
| +import com.google.gerrit.server.permissions.PermissionBackendException;
 | |
| +import com.google.gerrit.server.restapi.change.ChangesCollection;
 | |
| +import com.google.inject.Inject;
 | |
| +import com.google.inject.Provider;
 | |
| +import com.google.inject.Singleton;
 | |
| +
 | |
| +import java.net.MalformedURLException;
 | |
| +import java.net.URL;
 | |
| +import java.util.Optional;
 | |
| +import java.util.regex.Matcher;
 | |
| +import java.util.regex.Pattern;
 | |
| +
 | |
| +@Singleton
 | |
| +public class TitleComputer {
 | |
| +  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 | |
| +
 | |
| +  @Inject
 | |
| +  public TitleComputer(Provider<ChangesCollection> changes) {
 | |
| +    this.changes = changes;
 | |
| +  }
 | |
| +
 | |
| +  public Optional<String> computeTitle(String requestedURI) {
 | |
| +    URL url = null;
 | |
| +    try {
 | |
| +      url = new URL(requestedURI);
 | |
| +    } catch (MalformedURLException e) {
 | |
| +      logger.atWarning().log("Failed to turn %s into a URL.", requestedURI);
 | |
| +      return Optional.empty();
 | |
| +    }
 | |
| +
 | |
| +    // Try to turn this into a change.
 | |
| +    Optional<Change.Id> changeId = tryExtractChange(url.getPath());
 | |
| +    if (changeId.isPresent()) {
 | |
| +      return titleFromChangeId(changeId.get());
 | |
| +    }
 | |
| +
 | |
| +    return Optional.empty();
 | |
| +  }
 | |
| +
 | |
| +  private static final Pattern extractChangeIdRegex = Pattern.compile("^/(?:c/.*/\\+/)?(?<changeId>[0-9]+)(?:/[0-9]+)?(?:/.*)?$");
 | |
| +  private final Provider<ChangesCollection> changes;
 | |
| +
 | |
| +  private Optional<Change.Id> tryExtractChange(String path) {
 | |
| +    Matcher m = extractChangeIdRegex.matcher(path);
 | |
| +    if (!m.matches()) {
 | |
| +      return Optional.empty();
 | |
| +    }
 | |
| +    return Change.Id.tryParse(m.group("changeId"));
 | |
| +  }
 | |
| +
 | |
| +  private Optional<String> titleFromChangeId(Change.Id changeId) {
 | |
| +    ChangesCollection changesCollection = changes.get();
 | |
| +    try {
 | |
| +      ChangeResource changeResource = changesCollection.parse(changeId);
 | |
| +      return Optional.of(changeResource.getChange().getSubject());
 | |
| +    } catch (ResourceConflictException | ResourceNotFoundException | PermissionBackendException e) {
 | |
| +      return Optional.empty();
 | |
| +    }
 | |
| +  }
 | |
| +}
 | |
| diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | |
| index 32ba0bc790..2515c71d6a 100644
 | |
| --- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | |
| +++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
 | |
| @@ -33,10 +33,12 @@
 | |
|    {@param? preloadChangePage: ?}
 | |
|    {@param? preloadDiffPage: ?}
 | |
|    {@param? userIsAuthenticated: ?}
 | |
| +  {@param? title: ?}
 | |
|    <!DOCTYPE html>{\n}
 | |
|    <html lang="en">{\n}
 | |
|    <meta charset="utf-8">{\n}
 | |
| -  <meta name="description" content="Gerrit Code Review">{\n}
 | |
| +  {if $title}<title>{$title} · Gerrit Code Review</title>{\n}{/if}
 | |
| +  <meta name="description" content="{if $title}{$title} · {/if}Gerrit Code Review">{\n}
 | |
|    <meta name="referrer" content="never">{\n}
 | |
|    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n}
 | |
|  
 | |
| -- 
 | |
| 2.27.0
 | |
| 
 |