8199278: Javadoc search results does not link to anchors on a page
authorbpatel
Mon, 26 Mar 2018 18:07:24 -0700
changeset 49427 d2fd2581325b
parent 49426 7f3986bad197
child 49428 ce86061aff12
8199278: Javadoc search results does not link to anchors on a page Reviewed-by: jjg, ksrini
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java
src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js
test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java
test/langtools/jdk/javadoc/doclet/testSearch/pkg/AnotherClass.java
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java	Mon Mar 26 17:30:14 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AbstractIndexWriter.java	Mon Mar 26 18:07:24 2018 -0700
@@ -30,6 +30,7 @@
 import java.util.zip.*;
 
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
 import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.PackageElement;
@@ -316,10 +317,10 @@
             ExecutableElement ee = (ExecutableElement)member;
             name = name + utils.flatSignature(ee);
             si.setLabel(name);
-            if (!((utils.signature(ee)).equals(utils.flatSignature(ee)))) {
-                si.setUrl(links.getName(getAnchor(ee)));
+            String url = HtmlTree.encodeURL(links.getName(getAnchor(ee)));
+            if (!name.equals(url)) {
+                si.setUrl(url);
             }
-
         }  else {
             si.setLabel(name);
         }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Mon Mar 26 17:30:14 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlTree.java	Mon Mar 26 18:07:24 2018 -0700
@@ -263,8 +263,11 @@
      * is less aggressive about encoding some characters,
      * like '(', ')', ',' which are used in the anchor
      * names for Java methods in HTML5 mode.
+     *
+     * @param url the url to be percent-encoded.
+     * @return a percent-encoded string.
      */
-    private static String encodeURL(String url) {
+    public static String encodeURL(String url) {
         BitSet nonEncodingChars = MAIN_CHARS;
         StringBuilder sb = new StringBuilder();
         for (byte c : url.getBytes(Charset.forName("UTF-8"))) {
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js	Mon Mar 26 17:30:14 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js	Mon Mar 26 18:07:24 2018 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,41 +33,6 @@
 var highlight = "<span class=\"resultHighlight\">$&</span>";
 var camelCaseRegexp = "";
 var secondaryMatcher = "";
-function getName(name) {
-    var anchor = "";
-    var ch = '';
-    for (i = 0; i < name.length; i++) {
-        ch = name.charAt(i);
-        switch (ch) {
-            case '(':
-            case ')':
-            case '<':
-            case '>':
-            case ',':
-                anchor += "-";
-                break;
-            case ' ':
-            case '[':
-                break;
-            case ']':
-                anchor += ":A";
-                break;
-            case '$':
-                if (i == 0)
-                    anchor += "Z:Z";
-                anchor += ":D";
-                break;
-            case '_':
-                if (i == 0)
-                    anchor += "Z:Z";
-                anchor += ch;
-                break;
-            default:
-                anchor += ch;
-        }
-    }
-    return anchor;
-}
 function getHighlightedText(item) {
     var ccMatcher = new RegExp(camelCaseRegexp);
     var label = item.replace(ccMatcher, highlight);
@@ -357,7 +322,7 @@
                     if (ui.item.url) {
                         url += ui.item.url;
                     } else {
-                        url += getName(ui.item.l);
+                        url += ui.item.l;
                     }
                 } else if (ui.item.category === catSearchTags) {
                     url += ui.item.u;
--- a/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Mon Mar 26 17:30:14 2018 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/TestSearch.java	Mon Mar 26 18:07:24 2018 -0700
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 8141492 8071982 8141636 8147890 8166175 8168965 8176794 8175218 8147881
- *      8181622 8182263 8074407 8187521 8198522 8182765
+ *      8181622 8182263 8074407 8187521 8198522 8182765 8199278
  * @summary Test the search feature of javadoc.
  * @author bpatel
  * @library ../lib
@@ -307,14 +307,44 @@
 
     @Test
     void testNoModuleDirectories() {
-        javadoc("-d", "out-noMdlDir", "--no-module-directories", "-Xdoclint:none",
+        javadoc("-d", "out-noMdlDir",
+                "--no-module-directories",
+                "-Xdoclint:none",
                 "-sourcepath", testSrc,
-                "-use", "pkg", "pkg1", "pkg2", "pkg3");
+                "-use",
+                "pkg", "pkg1", "pkg2", "pkg3");
         checkExit(Exit.OK);
         checkSearchOutput(true, false);
         checkSearchJS();
     }
 
+    @Test
+    void testURLEncoding() {
+        javadoc("-d", "out-encode-html5",
+                "--no-module-directories",
+                "-Xdoclint:none",
+                "-sourcepath", testSrc,
+                "-use",
+                "pkg", "pkg1", "pkg2", "pkg3");
+        checkExit(Exit.OK);
+        checkSearchJS();
+        checkSearchIndex(true);
+    }
+
+    @Test
+    void testURLEncoding_html4() {
+        javadoc("-d", "out-encode-html4",
+                "-html4",
+                "--no-module-directories",
+                "-Xdoclint:none",
+                "-sourcepath", testSrc,
+                "-use",
+                "pkg", "pkg1", "pkg2", "pkg3");
+        checkExit(Exit.OK);
+        checkSearchJS();
+        checkSearchIndex(false);
+    }
+
     void checkDocLintErrors() {
         checkOutput(Output.OUT, true,
                 "A sample method. Testing search tag for {@index \"unclosed quote}.",
@@ -327,6 +357,19 @@
         checkSearchOutput("overview-summary.html", expectedOutput, true);
     }
 
+    void checkSearchIndex(boolean expectedOutput) {
+        checkOutput("member-search-index.js", expectedOutput,
+                "{\"p\":\"pkg\",\"c\":\"AnotherClass\",\"l\":\"AnotherClass()\",\"url\":\"%3Cinit%3E()\"}",
+                "{\"p\":\"pkg1\",\"c\":\"RegClass\",\"l\":\"RegClass()\",\"url\":\"%3Cinit%3E()\"}",
+                "{\"p\":\"pkg2\",\"c\":\"TestError\",\"l\":\"TestError()\",\"url\":\"%3Cinit%3E()\"}",
+                "{\"p\":\"pkg\",\"c\":\"AnotherClass\",\"l\":\"method(byte[], int, String)\",\"url\":\"method(byte[],int,java.lang.String)\"}");
+        checkOutput("member-search-index.js", !expectedOutput,
+                "{\"p\":\"pkg\",\"c\":\"AnotherClass\",\"l\":\"method(RegClass)\",\"url\":\"method-pkg1.RegClass-\"}",
+                "{\"p\":\"pkg2\",\"c\":\"TestClass\",\"l\":\"TestClass()\",\"url\":\"TestClass--\"}",
+                "{\"p\":\"pkg\",\"c\":\"TestError\",\"l\":\"TestError()\",\"url\":\"TestError--\"}",
+                "{\"p\":\"pkg\",\"c\":\"AnotherClass\",\"l\":\"method(byte[], int, String)\",\"url\":\"method-byte:A-int-java.lang.String-\"}");
+    }
+
     void checkSearchOutput(boolean expectedOutput, boolean moduleDirectoriesVar) {
         checkSearchOutput("overview-summary.html", expectedOutput, moduleDirectoriesVar);
     }
@@ -594,7 +637,8 @@
                 + "        }\n"
                 + "    }\n"
                 + "    return urlPrefix;\n"
-                + "}");
+                + "}",
+                "url += ui.item.l;");
     }
 
     void checkSingleIndexSearchTagDuplication() {
--- a/test/langtools/jdk/javadoc/doclet/testSearch/pkg/AnotherClass.java	Mon Mar 26 17:30:14 2018 -0700
+++ b/test/langtools/jdk/javadoc/doclet/testSearch/pkg/AnotherClass.java	Mon Mar 26 18:07:24 2018 -0700
@@ -75,4 +75,14 @@
     public pkg1.RegClass method(pkg1.RegClass param) {
         return param;
     }
+
+    /**
+     * Method to test member search index URL.
+     *
+     * @param testArray some test array.
+     * @param testInt some test int.
+     * @param testString some test string.
+     */
+    public void method(byte[] testArray, int testInt, String testString) {
+    }
 }