blob: 50e0b61e15e4b6f0b133df593a9d01e7df35fa73 [file] [log] [blame]
Shawn Pearce99cdbce2015-02-10 12:05:45 -08001// Copyright 2015 Google Inc. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.gitiles.doc;
16
Shawn Pearce99cdbce2015-02-10 12:05:45 -080017import com.google.gitiles.doc.html.HtmlBuilder;
Shawn Pearce47fd6562016-05-28 14:15:15 -070018import com.google.template.soy.shared.restricted.EscapingConventions.FilterImageDataUri;
Dave Borowitz3b744b12016-08-19 16:11:10 -040019import com.google.template.soy.shared.restricted.Sanitizers;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080020import java.util.HashMap;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080021import java.util.Map;
Shawn Pearce12c8fab2016-05-15 16:55:21 -070022import java.util.regex.Matcher;
23import java.util.regex.Pattern;
Dave Borowitz3b744b12016-08-19 16:11:10 -040024import org.commonmark.node.Heading;
25import org.commonmark.node.Node;
26import org.eclipse.jgit.util.RawParseUtils;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080027
28class Navbar {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070029 private static final Pattern REF_LINK =
30 Pattern.compile("^\\[(logo|home)\\]:\\s*(.+)$", Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
31
Shawn Pearce47fd6562016-05-28 14:15:15 -070032 private MarkdownToHtml fmt;
33 private Node node;
34 private String siteTitle;
35 private String logoUrl;
36 private String homeUrl;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080037
Shawn Pearce47fd6562016-05-28 14:15:15 -070038 Navbar() {}
39
40 Navbar setFormatter(MarkdownToHtml html) {
41 this.fmt = html;
42 return this;
43 }
44
45 Navbar setMarkdown(byte[] md) {
46 if (md != null && md.length > 0) {
47 parse(RawParseUtils.decode(md));
48 }
49 return this;
50 }
51
52 Map<String, Object> toSoyData() {
53 Map<String, Object> data = new HashMap<>();
54 data.put("siteTitle", siteTitle);
55 data.put("logoUrl", logo());
56 data.put("homeUrl", homeUrl != null ? fmt.href(homeUrl) : null);
57 data.put("navbarHtml", node != null ? fmt.toSoyHtml(node) : null);
58 return data;
59 }
60
61 private Object logo() {
62 if (logoUrl == null) {
63 return null;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080064 }
65
Shawn Pearce47fd6562016-05-28 14:15:15 -070066 String url = fmt.image(logoUrl);
67 if (HtmlBuilder.isValidHttpUri(url)) {
68 return url;
69 } else if (HtmlBuilder.isImageDataUri(url)) {
70 return Sanitizers.filterImageDataUri(url);
71 } else {
72 return FilterImageDataUri.INSTANCE.getInnocuousOutput();
73 }
74 }
75
76 private void parse(String markdown) {
77 node = GitilesMarkdown.parse(markdown);
78
79 extractSiteTitle();
80 extractRefLinks(markdown);
81 }
82
83 private void extractSiteTitle() {
84 for (Node c = node.getFirstChild(); c != null; c = c.getNext()) {
Shawn Pearce12c8fab2016-05-15 16:55:21 -070085 if (c instanceof Heading) {
86 Heading h = (Heading) c;
Shawn Pearce99cdbce2015-02-10 12:05:45 -080087 if (h.getLevel() == 1) {
Shawn Pearce47fd6562016-05-28 14:15:15 -070088 siteTitle = MarkdownUtil.getInnerText(h);
Shawn Pearce12c8fab2016-05-15 16:55:21 -070089 h.unlink();
Shawn Pearce99cdbce2015-02-10 12:05:45 -080090 break;
91 }
92 }
93 }
Shawn Pearce47fd6562016-05-28 14:15:15 -070094 }
Shawn Pearce99cdbce2015-02-10 12:05:45 -080095
Shawn Pearce47fd6562016-05-28 14:15:15 -070096 private void extractRefLinks(String markdown) {
97 Matcher m = REF_LINK.matcher(markdown);
Shawn Pearce12c8fab2016-05-15 16:55:21 -070098 while (m.find()) {
99 String key = m.group(1).toLowerCase();
100 String url = m.group(2).trim();
101 switch (key) {
102 case "logo":
Shawn Pearce47fd6562016-05-28 14:15:15 -0700103 logoUrl = url;
Shawn Pearce12c8fab2016-05-15 16:55:21 -0700104 break;
Shawn Pearce12c8fab2016-05-15 16:55:21 -0700105 case "home":
Shawn Pearce47fd6562016-05-28 14:15:15 -0700106 homeUrl = url;
Shawn Pearce12c8fab2016-05-15 16:55:21 -0700107 break;
Shawn Pearce99cdbce2015-02-10 12:05:45 -0800108 }
109 }
Shawn Pearce99cdbce2015-02-10 12:05:45 -0800110 }
Shawn Pearce99cdbce2015-02-10 12:05:45 -0800111}