From 30c762921212c221de266b1b29235adab629a106 Mon Sep 17 00:00:00 2001 From: Cory Lynch Date: Sat, 1 Jul 2017 16:17:22 -0400 Subject: [PATCH] Change code block typeahead to only sometimes close fence. Fixes #5556. Some tests needed to be moved around to make sure the stubbing wouldn't break future tests. --- .../node_tests/composebox_typeahead.js | 10 +++ frontend_tests/node_tests/stream_events.js | 68 +++++++++++++++++++ static/js/composebox_typeahead.js | 17 ++++- 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 frontend_tests/node_tests/stream_events.js diff --git a/frontend_tests/node_tests/composebox_typeahead.js b/frontend_tests/node_tests/composebox_typeahead.js index 37ebcd5c60..9889161392 100644 --- a/frontend_tests/node_tests/composebox_typeahead.js +++ b/frontend_tests/node_tests/composebox_typeahead.js @@ -191,6 +191,16 @@ global.people.add(deactivated_user); expected_value = '```python\n\n```'; assert.equal(actual_value, expected_value); + // Test special case to not close code blocks if there is text afterward + fake_this.query = '```p\nsome existing code'; + fake_this.token = 'p'; + fake_this.$element.caret = function () { + return 4; // Put cursor right after ```p + }; + actual_value = ct.content_typeahead_selected.call(fake_this, 'python'); + expected_value = '```python\nsome existing code'; + assert.equal(actual_value, expected_value); + fake_this.completing = 'something-else'; fake_this.query = 'foo'; diff --git a/frontend_tests/node_tests/stream_events.js b/frontend_tests/node_tests/stream_events.js new file mode 100644 index 0000000000..54c43b7bd6 --- /dev/null +++ b/frontend_tests/node_tests/stream_events.js @@ -0,0 +1,68 @@ +var assert = require('assert'); +var noop = function () {}; +set_global('$', global.make_zjquery()); + +set_global('colorspace', { + sRGB_to_linear: noop, + luminance_to_lightness: function () { + return 1; + }, +}); + +add_dependencies({ + stream_events: 'js/stream_events.js', + stream_data: 'js/stream_data.js', + stream_color: 'js/stream_color.js', + util: 'js/util.js', +}); + +var stream_events = require('js/stream_events.js'); +var with_overrides = global.with_overrides; + +var frontend = { + subscribed: true, + color: 'yellow', + name: 'frontend', + stream_id: 1, + in_home_view: false, + invite_only: false, +}; +stream_data.add_sub('Frontend', frontend); + +(function test_update_property() { + // Invoke error for non-existent stream/property + with_overrides(function (override) { + var errors = 0; + override('blueslip.warn', function () { + errors += 1; + }); + + stream_events.update_property(99, 'color', 'blue'); + assert.equal(errors, 1); + + stream_events.update_property(1, 'not_real', 42); + assert.equal(errors, 2); + }); + + // Test update color + with_overrides(function (override) { + global.with_stub(function (stub) { + override('stream_color.update_stream_color', stub.f); + stream_events.update_property(1, 'color', 'blue'); + var args = stub.get_args('sub', 'val'); + assert.equal(args.sub.stream_id, 1); + assert.equal(args.val, 'blue'); + }); + }); + + // Test in home view + with_overrides(function (override) { + global.with_stub(function (stub) { + override('stream_muting.update_in_home_view', stub.f); + stream_events.update_property(1, 'in_home_view', true); + var args = stub.get_args('sub', 'val'); + assert.equal(args.sub.stream_id, 1); + assert.equal(args.val, true); + }); + }); +}()); diff --git a/static/js/composebox_typeahead.js b/static/js/composebox_typeahead.js index dfe8cebd48..abb968fb2b 100644 --- a/static/js/composebox_typeahead.js +++ b/static/js/composebox_typeahead.js @@ -349,9 +349,20 @@ exports.content_typeahead_selected = function (item) { + '#**' + item.name + '** '); $(document).trigger('streamname_completed.zulip', {stream: item}); } else if (this.completing === 'syntax') { - rest = "\n" + beginning.substring(beginning.length - this.token.length - 4, - beginning.length - this.token.length).trim() + rest; - beginning = beginning.substring(0, beginning.length - this.token.length) + item + "\n"; + // Isolate the end index of the triple backticks/tildes, including + // possibly a space afterward + var backticks = beginning.length - this.token.length; + if (rest === '') { + // If cursor is at end of input ("rest" is empty), then + // complete the token before the cursor, and add a closing fence + // after the cursor + beginning = beginning.substring(0, backticks) + item + '\n'; + rest = "\n" + beginning.substring(backticks - 4, backticks).trim() + rest; + } else { + // If more text after the input, then complete the token, but don't touch + // "rest" (i.e. do not add a closing fence) + beginning = beginning.substring(0, backticks) + item; + } } // Keep the cursor after the newly inserted text, as Bootstrap will call textbox.change() to