mirror of https://github.com/zulip/zulip.git
markdown: Fix stream link handler in corner cases.
* Fixes handling of multiple stream links and invalid stream names. * Fixes text regex so it handle hash sign the right way. * Adds tests for these stream link cases.
This commit is contained in:
parent
852bc6b491
commit
ade3bda025
|
@ -1,6 +1,8 @@
|
|||
/*global Dict */
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var jsdom = require("jsdom");
|
||||
var window = jsdom.jsdom().defaultView;
|
||||
|
||||
global.stub_out_jquery();
|
||||
|
||||
|
@ -30,6 +32,8 @@ add_dependencies({
|
|||
marked: 'third/marked/lib/marked.js',
|
||||
emoji: 'js/emoji.js',
|
||||
people: 'js/people.js',
|
||||
stream_data: 'js/stream_data.js',
|
||||
hashchange: 'js/hashchange',
|
||||
fenced_code: 'js/fenced_code.js'
|
||||
});
|
||||
|
||||
|
@ -49,6 +53,9 @@ set_global('$', function (obj) {
|
|||
|
||||
set_global('feature_flags', {local_echo: true});
|
||||
|
||||
jsdom.changeURL(window, 'http://zulip.zulipdev.com');
|
||||
set_global('window', window);
|
||||
|
||||
var people = global.people;
|
||||
|
||||
people.add({
|
||||
|
@ -57,6 +64,25 @@ people.add({
|
|||
email: 'cordelia@zulip.com'
|
||||
});
|
||||
|
||||
var stream_data = global.stream_data;
|
||||
var denmark = {
|
||||
subscribed: false,
|
||||
color: 'blue',
|
||||
name: 'Denmark',
|
||||
stream_id: 1,
|
||||
in_home_view: false
|
||||
};
|
||||
var social = {
|
||||
subscribed: true,
|
||||
color: 'red',
|
||||
name: 'social',
|
||||
stream_id: 2,
|
||||
in_home_view: true,
|
||||
invite_only: true
|
||||
};
|
||||
stream_data.add_sub('Denmark', denmark);
|
||||
stream_data.add_sub('social', social);
|
||||
|
||||
var echo = require('js/echo.js');
|
||||
|
||||
var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver/fixtures/bugdown-data.json'), 'utf8', 'r'));
|
||||
|
@ -79,6 +105,7 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
|
|||
"User Mention @**leo**",
|
||||
"User Mention @**leo f**",
|
||||
"User Mention @**leo with some name**",
|
||||
"Stream #**Verona**",
|
||||
"This contains !gravatar(leo@zulip.com)",
|
||||
"And an avatar !avatar(leo@zulip.com) is here"
|
||||
];
|
||||
|
@ -138,6 +165,12 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
|
|||
expected: '<blockquote>\n<p>quote this for me</p>\n</blockquote>\n<p>thanks</p>'},
|
||||
{input: 'This is a @**Cordelia Lear** mention',
|
||||
expected: '<p>This is a <span class="user-mention" data-user-email="cordelia@zulip.com">@Cordelia Lear</span> mention</p>'},
|
||||
{input: 'This is a #**Denmark** stream link',
|
||||
expected: '<p>This is a <a class="stream" data-stream-id="1" href="http://zulip.zulipdev.com/#narrow/stream/Denmark">#Denmark</a> stream link</p>'},
|
||||
{input: 'This is #**Denmark** and #**social** stream links',
|
||||
expected: '<p>This is <a class="stream" data-stream-id="1" href="http://zulip.zulipdev.com/#narrow/stream/Denmark">#Denmark</a> and <a class="stream" data-stream-id="2" href="http://zulip.zulipdev.com/#narrow/stream/social">#social</a> stream links</p>'},
|
||||
{input: 'And this is a #**wrong** stream link',
|
||||
expected: '<p>And this is a #**wrong** stream link</p>'},
|
||||
{input: 'mmm...:burrito:s',
|
||||
expected: '<p>mmm...<img alt=\":burrito:\" class=\"emoji\" src=\"/static/third/gemoji/images/emoji/burrito.png\" title=\":burrito:\">s</p>'},
|
||||
{input: 'This is an :poop: message',
|
||||
|
|
|
@ -327,6 +327,18 @@ function handleUserMentions(username) {
|
|||
}
|
||||
}
|
||||
|
||||
function handleStream(streamName) {
|
||||
var stream = stream_data.get_sub(streamName);
|
||||
if (stream === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return '<a class="stream" data-stream-id="' + stream.stream_id + '" ' +
|
||||
'href="' + window.location.origin + '/#narrow/stream/' +
|
||||
hashchange.encodeHashComponent(stream.name) + '"' +
|
||||
'>' + '#' + stream.name + '</a>';
|
||||
|
||||
}
|
||||
|
||||
function handleRealmFilter(pattern, matches) {
|
||||
var url = realm_filter_map[pattern];
|
||||
|
||||
|
@ -340,10 +352,6 @@ function handleRealmFilter(pattern, matches) {
|
|||
return url;
|
||||
}
|
||||
|
||||
function handleStreamLinks(stream_name) {
|
||||
return '<a href="' + window.location.origin + '#narrow/stream/' + hashchange.encodeHashComponent(stream_name) + '">#' + stream_name + '</a>';
|
||||
}
|
||||
|
||||
function python_to_js_filter(pattern, url) {
|
||||
// Converts a python named-group regex to a javascript-compatible numbered
|
||||
// group regex... with a regex!
|
||||
|
@ -487,7 +495,7 @@ $(function () {
|
|||
avatarHandler: handleAvatar,
|
||||
unicodeEmojiHandler: handleUnicodeEmoji,
|
||||
userMentionHandler: handleUserMentions,
|
||||
streamLinkHandler: handleStreamLinks,
|
||||
streamHandler: handleStream,
|
||||
realmFilterHandler: handleRealmFilter,
|
||||
renderer: r,
|
||||
preprocessors: [preprocess_code_blocks]
|
||||
|
|
|
@ -477,6 +477,7 @@ var inline = {
|
|||
emoji: noop,
|
||||
unicodeemoji: noop,
|
||||
usermention: noop,
|
||||
stream: noop,
|
||||
avatar: noop,
|
||||
gravatar: noop,
|
||||
realm_filters: [],
|
||||
|
@ -537,13 +538,13 @@ inline.zulip = merge({}, inline.breaks, {
|
|||
emoji: /^:([A-Za-z0-9_\-\+]+?):/,
|
||||
unicodeemoji: /^(\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff])/,
|
||||
usermention: /^(@(?:\*\*([^\*]+)?\*\*|(\w+)?))/m, // Match multi-word string between @** ** or match any one-word
|
||||
streamlink: /^(#\*\*([^\*]+)\*\*)/,
|
||||
stream: /^#\*\*([^\*]+)\*\*/m,
|
||||
avatar: /^!avatar\(([^)]+)\)/,
|
||||
gravatar: /^!gravatar\(([^)]+)\)/,
|
||||
realm_filters: [],
|
||||
text: replace(inline.breaks.text)
|
||||
('|', '|(\ud83c[\udf00-\udfff]|\ud83d[\udc00-\ude4f]|\ud83d[\ude80-\udeff])|')
|
||||
(']|', '@:]|')
|
||||
(']|', '#@:]|')
|
||||
()
|
||||
});
|
||||
|
||||
|
@ -725,10 +726,11 @@ InlineLexer.prototype.output = function(src) {
|
|||
out += this.usermention(cap[2] || cap[3], cap[1]);
|
||||
continue;
|
||||
}
|
||||
// streamlink (zulip)
|
||||
if (cap = this.rules.streamlink.exec(src)) {
|
||||
|
||||
// stream (zulip)
|
||||
if (cap = this.rules.stream.exec(src)) {
|
||||
src = src.substring(cap[0].length);
|
||||
out += this.streamlink(cap[2], cap[1]);
|
||||
out += this.stream(cap[1], cap[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -870,22 +872,16 @@ InlineLexer.prototype.usermention = function (username, orig) {
|
|||
return orig;
|
||||
};
|
||||
|
||||
InlineLexer.prototype.streamlink = function(stream_name, orig) {
|
||||
if (stream_data.get_sub(stream_name) === undefined) {
|
||||
InlineLexer.prototype.stream = function (streamName, orig) {
|
||||
if (typeof this.options.streamHandler !== 'function')
|
||||
return orig;
|
||||
}
|
||||
if (typeof this.options.streamLinkHandler !== 'function')
|
||||
{
|
||||
return orig;
|
||||
}
|
||||
|
||||
var handled = this.options.streamLinkHandler(stream_name);
|
||||
var handled = this.options.streamHandler(streamName);
|
||||
if (handled !== undefined) {
|
||||
return handled;
|
||||
}
|
||||
|
||||
return orig;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Smartypants Transformations
|
||||
|
|
Loading…
Reference in New Issue