Add support for html and enabled fields in link configs
Bug: Issue 3804 Change-Id: I8c885662296368faa073957d426082b3bded81fc
This commit is contained in:
		@@ -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));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 +
 | 
				
			||||||
 | 
					            ' doesn’t contain a link or html attribute.');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  this.addText(text);
 | 
					  this.addText(text);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user