diff --git a/frontend_tests/node_tests/markdown.js b/frontend_tests/node_tests/markdown.js index 7ae95b84a2..ff75407356 100644 --- a/frontend_tests/node_tests/markdown.js +++ b/frontend_tests/node_tests/markdown.js @@ -425,6 +425,18 @@ run_test('topic_links', () => { assert.equal(util.get_topic_links(message).length, 1); assert.equal(util.get_topic_links(message)[0], "https://zone_45.zulip.net/ticket/123"); + message = {type: 'stream', topic: "Hello https://google.com"}; + markdown.add_topic_links(message); + assert.equal(util.get_topic_links(message).length, 1); + assert.equal(util.get_topic_links(message)[0], "https://google.com"); + + message = {type: 'stream', topic: "#456 https://google.com https://github.com"}; + markdown.add_topic_links(message); + assert.equal(util.get_topic_links(message).length, 3); + assert(util.get_topic_links(message).indexOf("https://google.com") !== -1); + assert(util.get_topic_links(message).indexOf("https://github.com") !== -1); + assert(util.get_topic_links(message).indexOf("https://trac.zulip.net/ticket/456") !== -1); + message = {type: "not-stream"}; markdown.add_topic_links(message); assert.equal(util.get_topic_links(message).length, 0); diff --git a/static/js/markdown.js b/static/js/markdown.js index 26695b1886..20b79314dc 100644 --- a/static/js/markdown.js +++ b/static/js/markdown.js @@ -160,6 +160,14 @@ exports.add_topic_links = function (message) { links.push(link_url); } }); + + // Also make raw urls navigable + var url_re = /\b(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/g; // Slightly modified from third/marked.js + var match = topic.match(url_re); + if (match) { + links = links.concat(match); + } + util.set_topic_links(message, links); }; diff --git a/zerver/lib/bugdown/__init__.py b/zerver/lib/bugdown/__init__.py index 6f5b67c212..3d124d7c76 100644 --- a/zerver/lib/bugdown/__init__.py +++ b/zerver/lib/bugdown/__init__.py @@ -1969,6 +1969,10 @@ def build_engine(realm_filters: List[Tuple[str, str, int]], ]) return engine +# Split the topic name into multiple sections so that we can easily use +# our common single link matching regex on it. +basic_link_splitter = re.compile(r'[ !;\?\),\'\"]') + # Security note: We don't do any HTML escaping in this # function on the URLs; they are expected to be HTML-escaped when # rendered by clients (just as links rendered into message bodies @@ -1982,6 +1986,13 @@ def topic_links(realm_filters_key: int, topic_name: str) -> List[str]: pattern = prepare_realm_pattern(realm_filter[0]) for m in re.finditer(pattern, topic_name): matches += [realm_filter[1] % m.groupdict()] + + # Also make raw urls navigable. + for sub_string in basic_link_splitter.split(topic_name): + link_match = re.match(get_web_link_regex(), sub_string) + if link_match: + matches.append(link_match.group('url')) + return matches def maybe_update_markdown_engines(realm_filters_key: Optional[int], email_gateway: bool) -> None: diff --git a/zerver/tests/test_bugdown.py b/zerver/tests/test_bugdown.py index 54da194b48..6faac7b3a6 100644 --- a/zerver/tests/test_bugdown.py +++ b/zerver/tests/test_bugdown.py @@ -787,6 +787,18 @@ class BugdownTest(ZulipTestCase): converted = bugdown_convert(msg) self.assertEqual(converted, unicode_converted) + def test_links_in_topic_name(self) -> None: + realm = get_realm('zulip') + msg = Message(sender=self.example_user('othello')) + + msg.set_topic_name("https://google.com/hello-world") + converted_topic = bugdown.topic_links(realm.id, msg.topic_name()) + self.assertEqual(converted_topic, [u'https://google.com/hello-world']) + + msg.set_topic_name("Try out http://ftp.debian.org, https://google.com/ and https://google.in/.") + converted_topic = bugdown.topic_links(realm.id, msg.topic_name()) + self.assertEqual(converted_topic, [u'http://ftp.debian.org', 'https://google.com/', 'https://google.in/']) + def test_realm_patterns(self) -> None: realm = get_realm('zulip') url_format_string = r"https://trac.zulip.net/ticket/%(id)s" @@ -811,6 +823,10 @@ class BugdownTest(ZulipTestCase): self.assertEqual(converted, '

We should fix #224 and #115, but not issue#124 or #1124z or trac #15 today.

') self.assertEqual(converted_topic, [u'https://trac.zulip.net/ticket/444']) + msg.set_topic_name("#444 https://google.com") + converted_topic = bugdown.topic_links(realm.id, msg.topic_name()) + self.assertEqual(converted_topic, [u'https://trac.zulip.net/ticket/444', u'https://google.com']) + RealmFilter(realm=realm, pattern=r'#(?P[a-zA-Z]+-[0-9]+)', url_format_string=r'https://trac.zulip.net/ticket/%(id)s').save() msg = Message(sender=self.example_user('hamlet'))