Add support for html and enabled fields in link configs

Bug: Issue 3804
Change-Id: I8c885662296368faa073957d426082b3bded81fc
This commit is contained in:
Andrew Bonventre
2016-01-14 14:18:20 -05:00
parent 9de8b68b77
commit e1a1c8b9c5
4 changed files with 78 additions and 13 deletions

View File

@@ -56,13 +56,22 @@ limitations under the License.
_contentOrConfigChanged: function(content, config) { _contentOrConfigChanged: function(content, config) {
var output = this.$.output; var output = this.$.output;
output.textContent = ''; output.textContent = '';
var parser = new GrLinkTextParser(config, function(text, href) { var parser = new GrLinkTextParser(config, function(text, href, html) {
if (href) { if (href) {
var a = document.createElement('a'); var a = document.createElement('a');
a.href = href; a.href = href;
a.textContent = text; a.textContent = text;
a.target = '_blank'; a.target = '_blank';
output.appendChild(a); output.appendChild(a);
} else if (html) {
var fragment = document.createDocumentFragment();
// Create temporary div to hold the nodes in.
var div = document.createElement('div');
div.innerHTML = html;
while (div.firstChild) {
fragment.appendChild(div.firstChild);
}
output.appendChild(fragment);
} else { } else {
output.appendChild(document.createTextNode(text)); output.appendChild(document.createTextNode(text));
} }

View File

@@ -27,6 +27,10 @@ GrLinkTextParser.prototype.addText = function(text, href) {
this.callback(text, href); this.callback(text, href);
}; };
GrLinkTextParser.prototype.addHTML = function(html) {
this.callback(null, null, html);
};
GrLinkTextParser.prototype.parse = function(text) { GrLinkTextParser.prototype.parse = function(text) {
linkify(text, { linkify(text, {
callback: this.parseChunk.bind(this) callback: this.parseChunk.bind(this)
@@ -43,21 +47,40 @@ GrLinkTextParser.prototype.parseChunk = function(text, href) {
GrLinkTextParser.prototype.parseLinks = function(text, patterns) { GrLinkTextParser.prototype.parseLinks = function(text, patterns) {
for (var p in patterns) { for (var p in patterns) {
if (patterns[p].enabled != null && patterns[p].enabled == false) {
continue;
}
// PolyGerrit doesn't use hash-based navigation like GWT.
// Account for this.
// TODO(andybons): Support Gerrit being served from a base other than /,
// e.g. https://git.eclipse.org/r/
if (patterns[p].html) {
patterns[p].html =
patterns[p].html.replace(/<a href=\"#\//g, '<a href="/');
} else if (patterns[p].link) {
if (patterns[p].link[0] == '#') {
patterns[p].link = patterns[p].link.substr(1);
}
}
var pattern = new RegExp(patterns[p].match, 'g'); var pattern = new RegExp(patterns[p].match, 'g');
var match; var match;
while (match = pattern.exec(text)) { while (match = pattern.exec(text)) {
var link = match[0].replace(pattern, patterns[p].link);
// PolyGerrit doesn't use hash-based navigation like GWT.
// Account for this.
if (link[0] == '#') {
link = link.substr(1);
}
var before = text.substr(0, match.index); var before = text.substr(0, match.index);
this.addText(before); this.addText(before);
text = text.substr(match.index + match[0].length); text = text.substr(match.index + match[0].length);
this.addText(match[0], link); var result = match[0].replace(pattern,
patterns[p].html || patterns[p].link);
if (patterns[p].html) {
this.addHTML(result);
} else if (patterns[p].link) {
this.addText(match[0], result);
} else {
throw Error('linkconfig entry ' + p +
' doesnt contain a link or html attribute.');
}
} }
} }
this.addText(text); this.addText(text);

View File

@@ -44,9 +44,23 @@ limitations under the License.
link: 'https://code.google.com/p/gerrit/issues/detail?id=$2' link: 'https://code.google.com/p/gerrit/issues/detail?id=$2'
}, },
changeid: { changeid: {
'match': '(I[0-9a-f]{8,40})', match: '(I[0-9a-f]{8,40})',
'link': '#/q/$1' link: '#/q/$1'
} },
googlesearch: {
match: 'google:(.+)',
link: 'https://bing.com/search?q=$1', // html should supercede link.
html: '<a href="https://google.com/search?q=$1">$1</a>',
},
hashedhtml: {
match: 'hash:(.+)',
html: '<a href="#/awesomesauce">$1</a>',
},
disabledconfig: {
match: 'foo:(.+)',
link: 'https://google.com/search?q=$1',
enabled: false,
},
}; };
}); });
@@ -109,5 +123,24 @@ limitations under the License.
'https://code.google.com/p/gerrit/issues/detail?id=3450'); 'https://code.google.com/p/gerrit/issues/detail?id=3450');
assert.equal(linkEl2.textContent, 'Issue 3450'); assert.equal(linkEl2.textContent, 'Issue 3450');
}); });
test('html field in link config', function() {
element.content = 'google:do a barrel roll';
assert.equal(element.$.output.innerHTML,
'<a href="https://google.com/search?q=do a barrel roll">' +
'do a barrel roll</a>');
});
test('removing hash from links', function() {
element.content = 'hash:foo';
assert.equal(element.$.output.innerHTML,
'<a href="/awesomesauce">foo</a>');
});
test('disabled config', function() {
element.content = 'foo:baz';
assert.equal(element.$.output.innerHTML, 'foo:baz');
});
}); });
</script> </script>

View File

@@ -30,7 +30,7 @@ import (
) )
var ( var (
restHost = flag.String("host", "gerrit-review.googlesource.com", "Host to proxy requests to") restHost = flag.String("host", "canary-chromium-review.googlesource.com", "Host to proxy requests to")
port = flag.String("port", ":8081", "Port to serve HTTP requests on") port = flag.String("port", ":8081", "Port to serve HTTP requests on")
prod = flag.Bool("prod", false, "Serve production assets") prod = flag.Bool("prod", false, "Serve production assets")
loggedIn = flag.Bool("logged_in", false, "Return user info as if the user is logged in") loggedIn = flag.Bool("logged_in", false, "Return user info as if the user is logged in")