mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 13:33:24 +00:00
js: Prefix jQuery object variable names with $.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
@@ -18,9 +18,9 @@ The pills will automatically be inserted in before the ".input" in order.
|
||||
## Basic usage
|
||||
|
||||
```js
|
||||
var pill_containter = $("#input_container");
|
||||
var $pill_containter = $("#input_container");
|
||||
var pills = input_pill.create({
|
||||
container: pill_container,
|
||||
$container: $pill_container,
|
||||
create_item_from_text: user_pill.create_item_from_email,
|
||||
get_text_from_item: user_pill.get_email_from_item,
|
||||
});
|
||||
|
||||
@@ -312,7 +312,7 @@ The code in `static/js/zform.js` renders the form (not
|
||||
shown here) and then sets up a click handler like below:
|
||||
|
||||
```js
|
||||
elem.find('button').on('click', function (e) {
|
||||
$elem.find('button').on('click', function (e) {
|
||||
e.stopPropagation();
|
||||
|
||||
// Grab our index from the markup.
|
||||
|
||||
@@ -8,8 +8,8 @@ const blueslip = require("../zjsunit/zblueslip");
|
||||
const $ = require("../zjsunit/zjquery");
|
||||
const {page_params, user_settings} = require("../zjsunit/zpage_params");
|
||||
|
||||
const window_stub = $.create("window-stub");
|
||||
set_global("to_$", () => window_stub);
|
||||
const $window_stub = $.create("window-stub");
|
||||
set_global("to_$", () => $window_stub);
|
||||
$(window).idle = () => {};
|
||||
|
||||
const _document = {
|
||||
@@ -242,34 +242,34 @@ function simulate_right_column_buddy_list() {
|
||||
};
|
||||
}
|
||||
|
||||
function buddy_list_add(user_id, stub) {
|
||||
if (stub.attr) {
|
||||
stub.attr("data-user-id", user_id);
|
||||
function buddy_list_add(user_id, $stub) {
|
||||
if ($stub.attr) {
|
||||
$stub.attr("data-user-id", user_id);
|
||||
}
|
||||
stub.length = 1;
|
||||
$stub.length = 1;
|
||||
const sel = `li.user_sidebar_entry[data-user-id='${CSS.escape(user_id)}']`;
|
||||
$("#user_presences").set_find_results(sel, stub);
|
||||
$("#user_presences").set_find_results(sel, $stub);
|
||||
}
|
||||
|
||||
test("PM_update_dom_counts", () => {
|
||||
const count = $.create("alice-unread-count");
|
||||
const $count = $.create("alice-unread-count");
|
||||
const pm_key = alice.user_id.toString();
|
||||
const li = $.create("alice stub");
|
||||
buddy_list_add(pm_key, li);
|
||||
li.set_find_results(".unread_count", count);
|
||||
count.set_parents_result("li", li);
|
||||
const $li = $.create("alice stub");
|
||||
buddy_list_add(pm_key, $li);
|
||||
$li.set_find_results(".unread_count", $count);
|
||||
$count.set_parents_result("li", $li);
|
||||
|
||||
const counts = new Map();
|
||||
counts.set(pm_key, 5);
|
||||
li.addClass("user_sidebar_entry");
|
||||
$li.addClass("user_sidebar_entry");
|
||||
|
||||
activity.update_dom_with_unread_counts({pm_count: counts});
|
||||
assert.equal(count.text(), "5");
|
||||
assert.equal($count.text(), "5");
|
||||
|
||||
counts.set(pm_key, 0);
|
||||
|
||||
activity.update_dom_with_unread_counts({pm_count: counts});
|
||||
assert.equal(count.text(), "");
|
||||
assert.equal($count.text(), "");
|
||||
});
|
||||
|
||||
test("handlers", ({override, override_rewire, mock_template}) => {
|
||||
@@ -289,9 +289,9 @@ test("handlers", ({override, override_rewire, mock_template}) => {
|
||||
|
||||
// This is kind of weak coverage; we are mostly making sure that
|
||||
// keys and clicks got mapped to functions that don't crash.
|
||||
let me_li;
|
||||
let alice_li;
|
||||
let fred_li;
|
||||
let $me_li;
|
||||
let $alice_li;
|
||||
let $fred_li;
|
||||
|
||||
let narrowed;
|
||||
|
||||
@@ -307,13 +307,13 @@ test("handlers", ({override, override_rewire, mock_template}) => {
|
||||
});
|
||||
activity.set_cursor_and_filter();
|
||||
|
||||
me_li = $.create("me stub");
|
||||
alice_li = $.create("alice stub");
|
||||
fred_li = $.create("fred stub");
|
||||
$me_li = $.create("me stub");
|
||||
$alice_li = $.create("alice stub");
|
||||
$fred_li = $.create("fred stub");
|
||||
|
||||
buddy_list_add(me.user_id, me_li);
|
||||
buddy_list_add(alice.user_id, alice_li);
|
||||
buddy_list_add(fred.user_id, fred_li);
|
||||
buddy_list_add(me.user_id, $me_li);
|
||||
buddy_list_add(alice.user_id, $alice_li);
|
||||
buddy_list_add(fred.user_id, $fred_li);
|
||||
}
|
||||
|
||||
(function test_filter_keys() {
|
||||
@@ -364,7 +364,7 @@ test("handlers", ({override, override_rewire, mock_template}) => {
|
||||
// We wire up the click handler in click_handlers.js,
|
||||
// so this just tests the called function.
|
||||
narrowed = false;
|
||||
activity.narrow_for_user({li: alice_li});
|
||||
activity.narrow_for_user({$li: $alice_li});
|
||||
assert.ok(narrowed);
|
||||
})();
|
||||
|
||||
@@ -420,7 +420,7 @@ test("first/prev/next", ({override, mock_template}) => {
|
||||
assert.equal(buddy_list.prev_key(alice.user_id), undefined);
|
||||
assert.equal(buddy_list.next_key(alice.user_id), undefined);
|
||||
|
||||
override(buddy_list.container, "append", () => {});
|
||||
override(buddy_list.$container, "append", () => {});
|
||||
|
||||
activity.redraw_user(alice.user_id);
|
||||
activity.redraw_user(fred.user_id);
|
||||
@@ -457,7 +457,7 @@ test("insert_one_user_into_empty_list", ({override, mock_template}) => {
|
||||
override(padded_widget, "update_padding", () => {});
|
||||
|
||||
let appended_html;
|
||||
override(buddy_list.container, "append", (html) => {
|
||||
override(buddy_list.$container, "append", (html) => {
|
||||
appended_html = html;
|
||||
});
|
||||
|
||||
@@ -470,7 +470,7 @@ test("insert_alice_then_fred", ({override, mock_template}) => {
|
||||
mock_template("user_presence_row.hbs", true, (data, html) => html);
|
||||
|
||||
let appended_html;
|
||||
override(buddy_list.container, "append", (html) => {
|
||||
override(buddy_list.$container, "append", (html) => {
|
||||
appended_html = html;
|
||||
});
|
||||
override(padded_widget, "update_padding", () => {});
|
||||
@@ -488,7 +488,7 @@ test("insert_fred_then_alice_then_rename", ({override, mock_template}) => {
|
||||
mock_template("user_presence_row.hbs", true, (data, html) => html);
|
||||
|
||||
let appended_html;
|
||||
override(buddy_list.container, "append", (html) => {
|
||||
override(buddy_list.$container, "append", (html) => {
|
||||
appended_html = html;
|
||||
});
|
||||
override(padded_widget, "update_padding", () => {});
|
||||
@@ -497,16 +497,16 @@ test("insert_fred_then_alice_then_rename", ({override, mock_template}) => {
|
||||
assert.ok(appended_html.indexOf('data-user-id="2"') > 0);
|
||||
assert.ok(appended_html.indexOf("user_circle_green") > 0);
|
||||
|
||||
const fred_stub = $.create("fred-first");
|
||||
buddy_list_add(fred.user_id, fred_stub);
|
||||
const $fred_stub = $.create("fred-first");
|
||||
buddy_list_add(fred.user_id, $fred_stub);
|
||||
|
||||
let inserted_html;
|
||||
fred_stub.before = (html) => {
|
||||
$fred_stub.before = (html) => {
|
||||
inserted_html = html;
|
||||
};
|
||||
|
||||
let fred_removed;
|
||||
fred_stub.remove = () => {
|
||||
$fred_stub.remove = () => {
|
||||
fred_removed = true;
|
||||
};
|
||||
|
||||
@@ -522,10 +522,10 @@ test("insert_fred_then_alice_then_rename", ({override, mock_template}) => {
|
||||
};
|
||||
people.add_active_user(fred_with_new_name);
|
||||
|
||||
const alice_stub = $.create("alice-first");
|
||||
buddy_list_add(alice.user_id, alice_stub);
|
||||
const $alice_stub = $.create("alice-first");
|
||||
buddy_list_add(alice.user_id, $alice_stub);
|
||||
|
||||
alice_stub.before = (html) => {
|
||||
$alice_stub.before = (html) => {
|
||||
inserted_html = html;
|
||||
};
|
||||
|
||||
@@ -541,8 +541,8 @@ test("insert_unfiltered_user_with_filter", () => {
|
||||
// This test only tests that we do not explode when
|
||||
// try to insert Fred into a list where he does not
|
||||
// match the search filter.
|
||||
const user_filter = $(".user-list-filter");
|
||||
user_filter.val("do-not-match-filter");
|
||||
const $user_filter = $(".user-list-filter");
|
||||
$user_filter.val("do-not-match-filter");
|
||||
activity.redraw_user(fred.user_id);
|
||||
});
|
||||
|
||||
@@ -579,8 +579,8 @@ test("update_presence_info", ({override, override_rewire}) => {
|
||||
|
||||
override_rewire(buddy_data, "matches_filter", () => true);
|
||||
|
||||
const alice_li = $.create("alice stub");
|
||||
buddy_list_add(alice.user_id, alice_li);
|
||||
const $alice_li = $.create("alice stub");
|
||||
buddy_list_add(alice.user_id, $alice_li);
|
||||
|
||||
let inserted;
|
||||
override(buddy_list, "insert_or_move", () => {
|
||||
@@ -613,8 +613,8 @@ test("initialize", ({override, mock_template}) => {
|
||||
|
||||
function clear() {
|
||||
$.clear_all_elements();
|
||||
buddy_list.container = $("#user_presences");
|
||||
buddy_list.container.append = () => {};
|
||||
buddy_list.$container = $("#user_presences");
|
||||
buddy_list.$container.append = () => {};
|
||||
clear_buddy_list();
|
||||
page_params.presences = {};
|
||||
}
|
||||
|
||||
@@ -50,31 +50,31 @@ run_test("add_alert_word", ({override_rewire}) => {
|
||||
|
||||
alert_words_ui.set_up_alert_words();
|
||||
|
||||
const create_form = $("#create_alert_word_form");
|
||||
const add_func = create_form.get_on_handler("click", "#create_alert_word_button");
|
||||
const $create_form = $("#create_alert_word_form");
|
||||
const add_func = $create_form.get_on_handler("click", "#create_alert_word_button");
|
||||
|
||||
const new_alert_word = $("#create_alert_word_name");
|
||||
const alert_word_status = $("#alert_word_status");
|
||||
const alert_word_status_text = $(".alert_word_status_text");
|
||||
alert_word_status.set_find_results(".alert_word_status_text", alert_word_status_text);
|
||||
const $new_alert_word = $("#create_alert_word_name");
|
||||
const $alert_word_status = $("#alert_word_status");
|
||||
const $alert_word_status_text = $(".alert_word_status_text");
|
||||
$alert_word_status.set_find_results(".alert_word_status_text", $alert_word_status_text);
|
||||
|
||||
// add '' as alert word
|
||||
add_func();
|
||||
assert.equal(new_alert_word.val(), "");
|
||||
assert.ok(alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal(alert_word_status_text.text(), "translated: Alert word can't be empty!");
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.equal($new_alert_word.val(), "");
|
||||
assert.ok($alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal($alert_word_status_text.text(), "translated: Alert word can't be empty!");
|
||||
assert.ok($alert_word_status.visible());
|
||||
|
||||
// add 'foo' as alert word (existing word)
|
||||
new_alert_word.val("foo");
|
||||
$new_alert_word.val("foo");
|
||||
|
||||
add_func();
|
||||
assert.ok(alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal(alert_word_status_text.text(), "translated: Alert word already exists!");
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.ok($alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal($alert_word_status_text.text(), "translated: Alert word already exists!");
|
||||
assert.ok($alert_word_status.visible());
|
||||
|
||||
// add 'zot' as alert word (new word)
|
||||
new_alert_word.val("zot");
|
||||
$new_alert_word.val("zot");
|
||||
|
||||
let success_func;
|
||||
let fail_func;
|
||||
@@ -89,26 +89,29 @@ run_test("add_alert_word", ({override_rewire}) => {
|
||||
|
||||
// test failure
|
||||
fail_func();
|
||||
assert.ok(alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal(alert_word_status_text.text(), "translated: Error adding alert word!");
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.ok($alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal($alert_word_status_text.text(), "translated: Error adding alert word!");
|
||||
assert.ok($alert_word_status.visible());
|
||||
|
||||
// test success
|
||||
success_func();
|
||||
assert.ok(alert_word_status.hasClass("alert-success"));
|
||||
assert.equal(alert_word_status_text.text(), 'translated: Alert word "zot" added successfully!');
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.ok($alert_word_status.hasClass("alert-success"));
|
||||
assert.equal(
|
||||
$alert_word_status_text.text(),
|
||||
'translated: Alert word "zot" added successfully!',
|
||||
);
|
||||
assert.ok($alert_word_status.visible());
|
||||
});
|
||||
|
||||
run_test("add_alert_word_keypress", ({override_rewire}) => {
|
||||
override_rewire(alert_words_ui, "rerender_alert_words_ui", () => {});
|
||||
alert_words_ui.set_up_alert_words();
|
||||
|
||||
const create_form = $("#create_alert_word_form");
|
||||
const keypress_func = create_form.get_on_handler("keypress", "#create_alert_word_name");
|
||||
const $create_form = $("#create_alert_word_form");
|
||||
const keypress_func = $create_form.get_on_handler("keypress", "#create_alert_word_name");
|
||||
|
||||
const new_alert_word = $("#create_alert_word_name");
|
||||
new_alert_word.val("zot");
|
||||
const $new_alert_word = $("#create_alert_word_name");
|
||||
$new_alert_word.val("zot");
|
||||
|
||||
const event = {
|
||||
preventDefault: () => {},
|
||||
@@ -130,16 +133,16 @@ run_test("remove_alert_word", ({override_rewire}) => {
|
||||
override_rewire(alert_words_ui, "rerender_alert_words_ui", () => {});
|
||||
alert_words_ui.set_up_alert_words();
|
||||
|
||||
const word_list = $("#alert-words-table");
|
||||
const remove_func = word_list.get_on_handler("click", ".remove-alert-word");
|
||||
const $word_list = $("#alert-words-table");
|
||||
const remove_func = $word_list.get_on_handler("click", ".remove-alert-word");
|
||||
|
||||
const remove_alert_word = $(".remove-alert-word");
|
||||
const list_item = $("tr.alert-word-item");
|
||||
const val_item = $("span.value");
|
||||
val_item.text($t({defaultMessage: "zot"}));
|
||||
const $remove_alert_word = $(".remove-alert-word");
|
||||
const $list_item = $("tr.alert-word-item");
|
||||
const $val_item = $("span.value");
|
||||
$val_item.text($t({defaultMessage: "zot"}));
|
||||
|
||||
remove_alert_word.set_parents_result("tr", list_item);
|
||||
list_item.set_find_results(".value", val_item);
|
||||
$remove_alert_word.set_parents_result("tr", $list_item);
|
||||
$list_item.set_find_results(".value", $val_item);
|
||||
|
||||
const event = {
|
||||
currentTarget: ".remove-alert-word",
|
||||
@@ -156,42 +159,42 @@ run_test("remove_alert_word", ({override_rewire}) => {
|
||||
|
||||
remove_func(event);
|
||||
|
||||
const alert_word_status = $("#alert_word_status");
|
||||
const alert_word_status_text = $(".alert_word_status_text");
|
||||
alert_word_status.set_find_results(".alert_word_status_text", alert_word_status_text);
|
||||
const $alert_word_status = $("#alert_word_status");
|
||||
const $alert_word_status_text = $(".alert_word_status_text");
|
||||
$alert_word_status.set_find_results(".alert_word_status_text", $alert_word_status_text);
|
||||
|
||||
// test failure
|
||||
fail_func();
|
||||
assert.ok(alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal(alert_word_status_text.text(), "translated: Error removing alert word!");
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.ok($alert_word_status.hasClass("alert-danger"));
|
||||
assert.equal($alert_word_status_text.text(), "translated: Error removing alert word!");
|
||||
assert.ok($alert_word_status.visible());
|
||||
|
||||
// test success
|
||||
success_func();
|
||||
assert.ok(alert_word_status.hasClass("alert-success"));
|
||||
assert.equal(alert_word_status_text.text(), "translated: Alert word removed successfully!");
|
||||
assert.ok(alert_word_status.visible());
|
||||
assert.ok($alert_word_status.hasClass("alert-success"));
|
||||
assert.equal($alert_word_status_text.text(), "translated: Alert word removed successfully!");
|
||||
assert.ok($alert_word_status.visible());
|
||||
});
|
||||
|
||||
run_test("close_status_message", ({override_rewire}) => {
|
||||
override_rewire(alert_words_ui, "rerender_alert_words_ui", () => {});
|
||||
alert_words_ui.set_up_alert_words();
|
||||
|
||||
const alert_word_settings = $("#alert-word-settings");
|
||||
const close = alert_word_settings.get_on_handler("click", ".close-alert-word-status");
|
||||
const $alert_word_settings = $("#alert-word-settings");
|
||||
const close = $alert_word_settings.get_on_handler("click", ".close-alert-word-status");
|
||||
|
||||
const alert = $(".alert");
|
||||
const close_btn = $(".close-alert-word-status");
|
||||
close_btn.set_parents_result(".alert", alert);
|
||||
const $alert = $(".alert");
|
||||
const $close_btn = $(".close-alert-word-status");
|
||||
$close_btn.set_parents_result(".alert", $alert);
|
||||
|
||||
alert.show();
|
||||
$alert.show();
|
||||
|
||||
const event = {
|
||||
preventDefault: () => {},
|
||||
currentTarget: ".close-alert-word-status",
|
||||
};
|
||||
|
||||
assert.ok(alert.visible());
|
||||
assert.ok($alert.visible());
|
||||
close(event);
|
||||
assert.ok(!alert.visible());
|
||||
assert.ok(!$alert.visible());
|
||||
});
|
||||
|
||||
@@ -39,18 +39,18 @@ people.add_active_user(alice);
|
||||
run_test("get_items", () => {
|
||||
const buddy_list = new BuddyList();
|
||||
|
||||
// We don't make alice_li an actual jQuery stub,
|
||||
// We don't make $alice_li an actual jQuery stub,
|
||||
// because our test only cares that it comes
|
||||
// back from get_items.
|
||||
const alice_li = "alice stub";
|
||||
const $alice_li = "alice stub";
|
||||
const sel = "li.user_sidebar_entry";
|
||||
const container = $.create("get_items container", {
|
||||
children: [{to_$: () => alice_li}],
|
||||
const $container = $.create("get_items container", {
|
||||
children: [{to_$: () => $alice_li}],
|
||||
});
|
||||
buddy_list.container.set_find_results(sel, container);
|
||||
buddy_list.$container.set_find_results(sel, $container);
|
||||
|
||||
const items = buddy_list.get_items();
|
||||
assert.deepEqual(items, [alice_li]);
|
||||
assert.deepEqual(items, [$alice_li]);
|
||||
});
|
||||
|
||||
run_test("basics", ({override}) => {
|
||||
@@ -83,19 +83,19 @@ run_test("basics", ({override}) => {
|
||||
});
|
||||
assert.ok(appended);
|
||||
|
||||
const alice_li = {length: 1};
|
||||
const $alice_li = {length: 1};
|
||||
|
||||
override(buddy_list, "get_li_from_key", (opts) => {
|
||||
const key = opts.key;
|
||||
|
||||
assert.equal(key, alice.user_id);
|
||||
return alice_li;
|
||||
return $alice_li;
|
||||
});
|
||||
|
||||
const li = buddy_list.find_li({
|
||||
const $li = buddy_list.find_li({
|
||||
key: alice.user_id,
|
||||
});
|
||||
assert.equal(li, alice_li);
|
||||
assert.equal($li, $alice_li);
|
||||
});
|
||||
|
||||
run_test("big_list", ({override}) => {
|
||||
@@ -163,11 +163,11 @@ run_test("find_li w/force_render", ({override}) => {
|
||||
// key is not already rendered in DOM, then the
|
||||
// widget will call show_key to force-render it.
|
||||
const key = "999";
|
||||
const stub_li = {length: 0};
|
||||
const $stub_li = {length: 0};
|
||||
|
||||
override(buddy_list, "get_li_from_key", (opts) => {
|
||||
assert.equal(opts.key, key);
|
||||
return stub_li;
|
||||
return $stub_li;
|
||||
});
|
||||
|
||||
buddy_list.keys = ["foo", "bar", key, "baz"];
|
||||
@@ -179,18 +179,18 @@ run_test("find_li w/force_render", ({override}) => {
|
||||
shown = true;
|
||||
});
|
||||
|
||||
const empty_li = buddy_list.find_li({
|
||||
const $empty_li = buddy_list.find_li({
|
||||
key,
|
||||
});
|
||||
assert.equal(empty_li, stub_li);
|
||||
assert.equal($empty_li, $stub_li);
|
||||
assert.ok(!shown);
|
||||
|
||||
const li = buddy_list.find_li({
|
||||
const $li = buddy_list.find_li({
|
||||
key,
|
||||
force_render: true,
|
||||
});
|
||||
|
||||
assert.equal(li, stub_li);
|
||||
assert.equal($li, $stub_li);
|
||||
assert.ok(shown);
|
||||
});
|
||||
|
||||
@@ -198,12 +198,12 @@ run_test("find_li w/bad key", ({override}) => {
|
||||
const buddy_list = new BuddyList();
|
||||
override(buddy_list, "get_li_from_key", () => ({length: 0}));
|
||||
|
||||
const undefined_li = buddy_list.find_li({
|
||||
const $undefined_li = buddy_list.find_li({
|
||||
key: "not-there",
|
||||
force_render: true,
|
||||
});
|
||||
|
||||
assert.deepEqual(undefined_li, []);
|
||||
assert.deepEqual($undefined_li, []);
|
||||
});
|
||||
|
||||
run_test("scrolling", ({override}) => {
|
||||
|
||||
@@ -39,41 +39,41 @@ run_test("phrase_match", () => {
|
||||
run_test("copy_data_attribute_value", ({override}) => {
|
||||
const admin_emails_val = "iago@zulip.com";
|
||||
|
||||
const input = $.create("input");
|
||||
const $input = $.create("input");
|
||||
|
||||
let removed;
|
||||
input.remove = () => {
|
||||
$input.remove = () => {
|
||||
removed = true;
|
||||
};
|
||||
|
||||
override(document, "createElement", () => input);
|
||||
override(document, "createElement", () => $input);
|
||||
override(document, "execCommand", noop);
|
||||
|
||||
$("body").append = noop;
|
||||
$(input).val = (arg) => {
|
||||
$($input).val = (arg) => {
|
||||
assert.equal(arg, admin_emails_val);
|
||||
return {
|
||||
trigger: noop,
|
||||
};
|
||||
};
|
||||
|
||||
const elem = {};
|
||||
const $elem = {};
|
||||
let faded_in = false;
|
||||
let faded_out = false;
|
||||
|
||||
elem.data = (key) => {
|
||||
$elem.data = (key) => {
|
||||
assert.equal(key, "admin-emails");
|
||||
return admin_emails_val;
|
||||
};
|
||||
elem.fadeOut = (val) => {
|
||||
$elem.fadeOut = (val) => {
|
||||
assert.equal(val, 250);
|
||||
faded_out = true;
|
||||
};
|
||||
elem.fadeIn = (val) => {
|
||||
$elem.fadeIn = (val) => {
|
||||
assert.equal(val, 1000);
|
||||
faded_in = true;
|
||||
};
|
||||
common.copy_data_attribute_value(elem, "admin-emails");
|
||||
common.copy_data_attribute_value($elem, "admin-emails");
|
||||
assert.ok(removed);
|
||||
assert.ok(faded_in);
|
||||
assert.ok(faded_out);
|
||||
@@ -111,17 +111,17 @@ run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
|
||||
|
||||
for (const [old_key, mac_key] of keys_to_test_mac) {
|
||||
const test_item = {};
|
||||
const stub = $.create("hotkey_" + key_no);
|
||||
stub.text(old_key);
|
||||
assert.equal(stub.hasClass("mac-cmd-key"), false);
|
||||
test_item.stub = stub;
|
||||
const $stub = $.create("hotkey_" + key_no);
|
||||
$stub.text(old_key);
|
||||
assert.equal($stub.hasClass("mac-cmd-key"), false);
|
||||
test_item.$stub = $stub;
|
||||
test_item.mac_key = mac_key;
|
||||
test_item.is_cmd_key = old_key.includes("Ctrl");
|
||||
test_items.push(test_item);
|
||||
key_no += 1;
|
||||
}
|
||||
|
||||
const children = test_items.map((test_item) => ({to_$: () => test_item.stub}));
|
||||
const children = test_items.map((test_item) => ({to_$: () => test_item.$stub}));
|
||||
|
||||
$.create(".markdown_content", {children});
|
||||
|
||||
@@ -129,8 +129,8 @@ run_test("adjust_mac_shortcuts mac", ({override_rewire}) => {
|
||||
common.adjust_mac_shortcuts(".markdown_content", require_cmd);
|
||||
|
||||
for (const test_item of test_items) {
|
||||
assert.equal(test_item.stub.hasClass("mac-cmd-key"), test_item.is_cmd_key);
|
||||
assert.equal(test_item.stub.text(), test_item.mac_key);
|
||||
assert.equal(test_item.$stub.hasClass("mac-cmd-key"), test_item.is_cmd_key);
|
||||
assert.equal(test_item.$stub.text(), test_item.mac_key);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,35 +10,35 @@ const blueslip = require("../zjsunit/zblueslip");
|
||||
let env;
|
||||
|
||||
function make_tab(i) {
|
||||
const self = {};
|
||||
const $self = {};
|
||||
|
||||
assert.equal(env.tabs.length, i);
|
||||
|
||||
self.stub = true;
|
||||
self.class = [];
|
||||
$self.stub = true;
|
||||
$self.class = [];
|
||||
|
||||
self.addClass = (c) => {
|
||||
self.class += " " + c;
|
||||
const tokens = self.class.trim().split(/ +/);
|
||||
self.class = Array.from(new Set(tokens)).join(" ");
|
||||
$self.addClass = (c) => {
|
||||
$self.class += " " + c;
|
||||
const tokens = $self.class.trim().split(/ +/);
|
||||
$self.class = Array.from(new Set(tokens)).join(" ");
|
||||
};
|
||||
|
||||
self.removeClass = (c) => {
|
||||
const tokens = self.class.trim().split(/ +/);
|
||||
self.class = tokens.filter((token) => token !== c).join(" ");
|
||||
$self.removeClass = (c) => {
|
||||
const tokens = $self.class.trim().split(/ +/);
|
||||
$self.class = tokens.filter((token) => token !== c).join(" ");
|
||||
};
|
||||
|
||||
self.hasClass = (c) => {
|
||||
const tokens = self.class.trim().split(/ +/);
|
||||
$self.hasClass = (c) => {
|
||||
const tokens = $self.class.trim().split(/ +/);
|
||||
return tokens.includes(c);
|
||||
};
|
||||
|
||||
self.data = (name) => {
|
||||
$self.data = (name) => {
|
||||
assert.equal(name, "tab-id");
|
||||
return i;
|
||||
};
|
||||
|
||||
self.text = (text) => {
|
||||
$self.text = (text) => {
|
||||
assert.equal(
|
||||
text,
|
||||
[
|
||||
@@ -49,23 +49,23 @@ function make_tab(i) {
|
||||
);
|
||||
};
|
||||
|
||||
self.trigger = (type) => {
|
||||
$self.trigger = (type) => {
|
||||
if (type === "focus") {
|
||||
env.focused_tab = i;
|
||||
}
|
||||
};
|
||||
|
||||
env.tabs.push(self);
|
||||
env.tabs.push($self);
|
||||
|
||||
return self;
|
||||
return $self;
|
||||
}
|
||||
|
||||
const ind_tab = (function () {
|
||||
const self = {};
|
||||
const $self = {};
|
||||
|
||||
self.stub = true;
|
||||
$self.stub = true;
|
||||
|
||||
self.on = (name, f) => {
|
||||
$self.on = (name, f) => {
|
||||
if (name === "click") {
|
||||
env.click_f = f;
|
||||
} else if (name === "keydown") {
|
||||
@@ -73,36 +73,36 @@ const ind_tab = (function () {
|
||||
}
|
||||
};
|
||||
|
||||
self.removeClass = (c) => {
|
||||
for (const tab of env.tabs) {
|
||||
tab.removeClass(c);
|
||||
$self.removeClass = (c) => {
|
||||
for (const $tab of env.tabs) {
|
||||
$tab.removeClass(c);
|
||||
}
|
||||
};
|
||||
|
||||
self.eq = (idx) => env.tabs[idx];
|
||||
$self.eq = (idx) => env.tabs[idx];
|
||||
|
||||
return self;
|
||||
return $self;
|
||||
})();
|
||||
|
||||
function make_switcher() {
|
||||
const self = {};
|
||||
const $self = {};
|
||||
|
||||
self.stub = true;
|
||||
$self.stub = true;
|
||||
|
||||
self.children = [];
|
||||
$self.children = [];
|
||||
|
||||
self.classList = new Set();
|
||||
$self.classList = new Set();
|
||||
|
||||
self.append = (child) => {
|
||||
self.children.push(child);
|
||||
$self.append = (child) => {
|
||||
$self.children.push(child);
|
||||
};
|
||||
|
||||
self.addClass = (c) => {
|
||||
self.classList.add(c);
|
||||
self.addedClass = c;
|
||||
$self.addClass = (c) => {
|
||||
$self.classList.add(c);
|
||||
$self.addedClass = c;
|
||||
};
|
||||
|
||||
self.find = (sel) => {
|
||||
$self.find = (sel) => {
|
||||
switch (sel) {
|
||||
case ".ind-tab":
|
||||
return ind_tab;
|
||||
@@ -111,7 +111,7 @@ function make_switcher() {
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
return $self;
|
||||
}
|
||||
|
||||
mock_jquery((sel, attributes) => {
|
||||
|
||||
@@ -552,27 +552,28 @@ test_ui("on_events", ({override, override_rewire}) => {
|
||||
override(rendered_markdown, "update_elements", () => {});
|
||||
|
||||
function setup_parents_and_mock_remove(container_sel, target_sel, parent) {
|
||||
const container = $.create("fake " + container_sel);
|
||||
const $container = $.create("fake " + container_sel);
|
||||
let container_removed = false;
|
||||
|
||||
container.remove = () => {
|
||||
$container.remove = () => {
|
||||
container_removed = true;
|
||||
};
|
||||
|
||||
const target = $.create("fake click target (" + target_sel + ")");
|
||||
const $target = $.create("fake click target (" + target_sel + ")");
|
||||
|
||||
target.set_parents_result(parent, container);
|
||||
$target.set_parents_result(parent, $container);
|
||||
|
||||
const event = {
|
||||
preventDefault: noop,
|
||||
stopPropagation: noop,
|
||||
target,
|
||||
// FIXME: event.target should not be a jQuery object
|
||||
target: $target,
|
||||
};
|
||||
|
||||
const helper = {
|
||||
event,
|
||||
container,
|
||||
target,
|
||||
$container,
|
||||
$target,
|
||||
container_was_removed: () => container_removed,
|
||||
};
|
||||
|
||||
@@ -633,7 +634,7 @@ test_ui("on_events", ({override, override_rewire}) => {
|
||||
".compose_invite_user",
|
||||
);
|
||||
|
||||
helper.container.data = (field) => {
|
||||
helper.$container.data = (field) => {
|
||||
if (field === "user-id") {
|
||||
return "34";
|
||||
}
|
||||
@@ -642,7 +643,7 @@ test_ui("on_events", ({override, override_rewire}) => {
|
||||
}
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
};
|
||||
helper.target.prop("disabled", false);
|
||||
helper.$target.prop("disabled", false);
|
||||
|
||||
// !sub will result in true here and we check the success code path.
|
||||
stream_data.add_sub(subscription);
|
||||
|
||||
@@ -43,9 +43,9 @@ run_test("pills", ({override}) => {
|
||||
|
||||
people.get_realm_users = () => [iago, othello, hamlet];
|
||||
|
||||
const recipient_stub = $("#private_message_recipient");
|
||||
const $recipient_stub = $("#private_message_recipient");
|
||||
const pill_container_stub = "pill-container";
|
||||
recipient_stub.set_parent(pill_container_stub);
|
||||
$recipient_stub.set_parent(pill_container_stub);
|
||||
let create_item_handler;
|
||||
|
||||
const all_pills = new Map();
|
||||
@@ -132,7 +132,7 @@ run_test("pills", ({override}) => {
|
||||
}
|
||||
|
||||
function input_pill_stub(opts) {
|
||||
assert.equal(opts.container, pill_container_stub);
|
||||
assert.equal(opts.$container, pill_container_stub);
|
||||
create_item_handler = opts.create_item_from_text;
|
||||
assert.ok(create_item_handler);
|
||||
return pills;
|
||||
|
||||
@@ -46,48 +46,48 @@ people.add_active_user(bob);
|
||||
|
||||
function make_textbox(s) {
|
||||
// Simulate a jQuery textbox for testing purposes.
|
||||
const widget = {};
|
||||
const $widget = {};
|
||||
|
||||
widget.s = s;
|
||||
widget.focused = false;
|
||||
$widget.s = s;
|
||||
$widget.focused = false;
|
||||
|
||||
widget.caret = function (arg) {
|
||||
$widget.caret = function (arg) {
|
||||
if (typeof arg === "number") {
|
||||
widget.pos = arg;
|
||||
$widget.pos = arg;
|
||||
return this;
|
||||
}
|
||||
|
||||
if (arg) {
|
||||
widget.insert_pos = widget.pos;
|
||||
widget.insert_text = arg;
|
||||
const before = widget.s.slice(0, widget.pos);
|
||||
const after = widget.s.slice(widget.pos);
|
||||
widget.s = before + arg + after;
|
||||
widget.pos += arg.length;
|
||||
$widget.insert_pos = $widget.pos;
|
||||
$widget.insert_text = arg;
|
||||
const before = $widget.s.slice(0, $widget.pos);
|
||||
const after = $widget.s.slice($widget.pos);
|
||||
$widget.s = before + arg + after;
|
||||
$widget.pos += arg.length;
|
||||
return this;
|
||||
}
|
||||
|
||||
return widget.pos;
|
||||
return $widget.pos;
|
||||
};
|
||||
|
||||
widget.val = function (new_val) {
|
||||
$widget.val = function (new_val) {
|
||||
if (new_val) {
|
||||
widget.s = new_val;
|
||||
$widget.s = new_val;
|
||||
return this;
|
||||
}
|
||||
return widget.s;
|
||||
return $widget.s;
|
||||
};
|
||||
|
||||
widget.trigger = function (type) {
|
||||
$widget.trigger = function (type) {
|
||||
if (type === "focus") {
|
||||
widget.focused = true;
|
||||
$widget.focused = true;
|
||||
} else if (type === "blur") {
|
||||
widget.focused = false;
|
||||
$widget.focused = false;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
return widget;
|
||||
return $widget;
|
||||
}
|
||||
|
||||
run_test("autosize_textarea", ({override}) => {
|
||||
@@ -121,59 +121,59 @@ run_test("insert_syntax_and_focus", () => {
|
||||
});
|
||||
|
||||
run_test("smart_insert", () => {
|
||||
let textbox = make_textbox("abc");
|
||||
textbox.caret(4);
|
||||
let $textbox = make_textbox("abc");
|
||||
$textbox.caret(4);
|
||||
|
||||
compose_ui.smart_insert(textbox, ":smile:");
|
||||
assert.equal(textbox.insert_pos, 4);
|
||||
assert.equal(textbox.insert_text, " :smile: ");
|
||||
assert.equal(textbox.val(), "abc :smile: ");
|
||||
assert.ok(textbox.focused);
|
||||
compose_ui.smart_insert($textbox, ":smile:");
|
||||
assert.equal($textbox.insert_pos, 4);
|
||||
assert.equal($textbox.insert_text, " :smile: ");
|
||||
assert.equal($textbox.val(), "abc :smile: ");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, ":airplane:");
|
||||
assert.equal(textbox.insert_text, ":airplane: ");
|
||||
assert.equal(textbox.val(), "abc :smile: :airplane: ");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, ":airplane:");
|
||||
assert.equal($textbox.insert_text, ":airplane: ");
|
||||
assert.equal($textbox.val(), "abc :smile: :airplane: ");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
textbox.caret(0);
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, ":octopus:");
|
||||
assert.equal(textbox.insert_text, ":octopus: ");
|
||||
assert.equal(textbox.val(), ":octopus: abc :smile: :airplane: ");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox.caret(0);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, ":octopus:");
|
||||
assert.equal($textbox.insert_text, ":octopus: ");
|
||||
assert.equal($textbox.val(), ":octopus: abc :smile: :airplane: ");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
textbox.caret(textbox.val().length);
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, ":heart:");
|
||||
assert.equal(textbox.insert_text, ":heart: ");
|
||||
assert.equal(textbox.val(), ":octopus: abc :smile: :airplane: :heart: ");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox.caret($textbox.val().length);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, ":heart:");
|
||||
assert.equal($textbox.insert_text, ":heart: ");
|
||||
assert.equal($textbox.val(), ":octopus: abc :smile: :airplane: :heart: ");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
// Test handling of spaces for ```quote
|
||||
textbox = make_textbox("");
|
||||
textbox.caret(0);
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, "```quote\nquoted message\n```\n");
|
||||
assert.equal(textbox.insert_text, "```quote\nquoted message\n```\n");
|
||||
assert.equal(textbox.val(), "```quote\nquoted message\n```\n");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox = make_textbox("");
|
||||
$textbox.caret(0);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, "```quote\nquoted message\n```\n");
|
||||
assert.equal($textbox.insert_text, "```quote\nquoted message\n```\n");
|
||||
assert.equal($textbox.val(), "```quote\nquoted message\n```\n");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
textbox = make_textbox("");
|
||||
textbox.caret(0);
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, "translated: [Quoting…]\n");
|
||||
assert.equal(textbox.insert_text, "translated: [Quoting…]\n");
|
||||
assert.equal(textbox.val(), "translated: [Quoting…]\n");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox = make_textbox("");
|
||||
$textbox.caret(0);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, "translated: [Quoting…]\n");
|
||||
assert.equal($textbox.insert_text, "translated: [Quoting…]\n");
|
||||
assert.equal($textbox.val(), "translated: [Quoting…]\n");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
textbox = make_textbox("abc");
|
||||
textbox.caret(3);
|
||||
textbox.trigger("blur");
|
||||
compose_ui.smart_insert(textbox, " test with space");
|
||||
assert.equal(textbox.insert_text, " test with space ");
|
||||
assert.equal(textbox.val(), "abc test with space ");
|
||||
assert.ok(textbox.focused);
|
||||
$textbox = make_textbox("abc");
|
||||
$textbox.caret(3);
|
||||
$textbox.trigger("blur");
|
||||
compose_ui.smart_insert($textbox, " test with space");
|
||||
assert.equal($textbox.insert_text, " test with space ");
|
||||
assert.equal($textbox.val(), "abc test with space ");
|
||||
assert.ok($textbox.focused);
|
||||
|
||||
// Note that we don't have any special logic for strings that are
|
||||
// already surrounded by spaces, since we are usually inserting things
|
||||
@@ -481,14 +481,14 @@ run_test("format_text", () => {
|
||||
wrap_syntax = "";
|
||||
}
|
||||
|
||||
const textarea = $("#compose-textarea");
|
||||
textarea.get = () => ({
|
||||
const $textarea = $("#compose-textarea");
|
||||
$textarea.get = () => ({
|
||||
setSelectionRange: () => {},
|
||||
});
|
||||
|
||||
function init_textarea(val, range) {
|
||||
textarea.val = () => val;
|
||||
textarea.range = () => range;
|
||||
$textarea.val = () => val;
|
||||
$textarea.range = () => range;
|
||||
}
|
||||
|
||||
const italic_syntax = "*";
|
||||
@@ -502,7 +502,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 3,
|
||||
});
|
||||
compose_ui.format_text(textarea, "bold");
|
||||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "");
|
||||
assert.equal(wrap_selection_called, true);
|
||||
assert.equal(wrap_syntax, bold_syntax);
|
||||
@@ -515,7 +515,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 7,
|
||||
});
|
||||
compose_ui.format_text(textarea, "bold");
|
||||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "abc");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -527,7 +527,7 @@ run_test("format_text", () => {
|
||||
text: "**abc**",
|
||||
length: 7,
|
||||
});
|
||||
compose_ui.format_text(textarea, "bold");
|
||||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "abc");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -539,7 +539,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 3,
|
||||
});
|
||||
compose_ui.format_text(textarea, "italic");
|
||||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "");
|
||||
assert.equal(wrap_selection_called, true);
|
||||
assert.equal(wrap_syntax, italic_syntax);
|
||||
@@ -552,7 +552,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 3,
|
||||
});
|
||||
compose_ui.format_text(textarea, "italic");
|
||||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "abc");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -564,7 +564,7 @@ run_test("format_text", () => {
|
||||
text: "*abc*",
|
||||
length: 5,
|
||||
});
|
||||
compose_ui.format_text(textarea, "italic");
|
||||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "abc");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -576,7 +576,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 3,
|
||||
});
|
||||
compose_ui.format_text(textarea, "bold");
|
||||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "*abc*");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -588,7 +588,7 @@ run_test("format_text", () => {
|
||||
text: "***abc***",
|
||||
length: 9,
|
||||
});
|
||||
compose_ui.format_text(textarea, "bold");
|
||||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "*abc*");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -600,7 +600,7 @@ run_test("format_text", () => {
|
||||
text: "abc",
|
||||
length: 3,
|
||||
});
|
||||
compose_ui.format_text(textarea, "italic");
|
||||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "**abc**");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
|
||||
@@ -612,14 +612,14 @@ run_test("format_text", () => {
|
||||
text: "***abc***",
|
||||
length: 9,
|
||||
});
|
||||
compose_ui.format_text(textarea, "italic");
|
||||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "**abc**");
|
||||
assert.equal(wrap_selection_called, false);
|
||||
});
|
||||
|
||||
run_test("markdown_shortcuts", ({override_rewire}) => {
|
||||
let format_text_type;
|
||||
override_rewire(compose_ui, "format_text", (textarea, type) => {
|
||||
override_rewire(compose_ui, "format_text", ($textarea, type) => {
|
||||
format_text_type = type;
|
||||
});
|
||||
|
||||
@@ -711,21 +711,21 @@ run_test("markdown_shortcuts", ({override_rewire}) => {
|
||||
});
|
||||
|
||||
run_test("right-to-left", () => {
|
||||
const textarea = $("#compose-textarea");
|
||||
const $textarea = $("#compose-textarea");
|
||||
|
||||
const event = {
|
||||
key: "A",
|
||||
};
|
||||
|
||||
assert.equal(textarea.hasClass("rtl"), false);
|
||||
assert.equal($textarea.hasClass("rtl"), false);
|
||||
|
||||
textarea.val("```quote\nمرحبا");
|
||||
$textarea.val("```quote\nمرحبا");
|
||||
compose_ui.handle_keyup(event, $("#compose-textarea"));
|
||||
|
||||
assert.equal(textarea.hasClass("rtl"), true);
|
||||
assert.equal($textarea.hasClass("rtl"), true);
|
||||
|
||||
textarea.val("```quote foo");
|
||||
compose_ui.handle_keyup(event, textarea);
|
||||
$textarea.val("```quote foo");
|
||||
compose_ui.handle_keyup(event, $textarea);
|
||||
|
||||
assert.equal(textarea.hasClass("rtl"), false);
|
||||
assert.equal($textarea.hasClass("rtl"), false);
|
||||
});
|
||||
|
||||
@@ -131,10 +131,10 @@ test_ui("validate", ({override, mock_template}) => {
|
||||
$("#compose-send-button").trigger("focus");
|
||||
$("#compose-send-button .loader").hide();
|
||||
|
||||
const pm_pill_container = $.create("fake-pm-pill-container");
|
||||
const $pm_pill_container = $.create("fake-pm-pill-container");
|
||||
$("#private_message_recipient")[0] = {};
|
||||
$("#private_message_recipient").set_parent(pm_pill_container);
|
||||
pm_pill_container.set_find_results(".input", $("#private_message_recipient"));
|
||||
$("#private_message_recipient").set_parent($pm_pill_container);
|
||||
$pm_pill_container.set_find_results(".input", $("#private_message_recipient"));
|
||||
$("#private_message_recipient").before = () => {};
|
||||
|
||||
compose_pm_pill.initialize();
|
||||
@@ -474,38 +474,38 @@ test_ui("test_validate_stream_message_post_policy_full_members_only", () => {
|
||||
test_ui("test_check_overflow_text", () => {
|
||||
page_params.max_message_length = 10000;
|
||||
|
||||
const textarea = $("#compose-textarea");
|
||||
const indicator = $("#compose_limit_indicator");
|
||||
const send_button = $("#compose-send-button");
|
||||
const $textarea = $("#compose-textarea");
|
||||
const $indicator = $("#compose_limit_indicator");
|
||||
const $send_button = $("#compose-send-button");
|
||||
|
||||
// Indicator should show red colored text
|
||||
textarea.val("a".repeat(10000 + 1));
|
||||
$textarea.val("a".repeat(10000 + 1));
|
||||
compose_validate.check_overflow_text();
|
||||
assert.ok(indicator.hasClass("over_limit"));
|
||||
assert.equal(indicator.text(), "10001/10000");
|
||||
assert.ok(textarea.hasClass("over_limit"));
|
||||
assert.ok($indicator.hasClass("over_limit"));
|
||||
assert.equal($indicator.text(), "10001/10000");
|
||||
assert.ok($textarea.hasClass("over_limit"));
|
||||
assert.equal(
|
||||
$("#compose-error-msg").html(),
|
||||
"translated HTML: Message length shouldn't be greater than 10000 characters.",
|
||||
);
|
||||
assert.ok(send_button.prop("disabled"));
|
||||
assert.ok($send_button.prop("disabled"));
|
||||
|
||||
$("#compose-send-status").stop = () => ({fadeOut: () => {}});
|
||||
|
||||
// Indicator should show orange colored text
|
||||
textarea.val("a".repeat(9000 + 1));
|
||||
$textarea.val("a".repeat(9000 + 1));
|
||||
compose_validate.check_overflow_text();
|
||||
assert.ok(!indicator.hasClass("over_limit"));
|
||||
assert.equal(indicator.text(), "9001/10000");
|
||||
assert.ok(!textarea.hasClass("over_limit"));
|
||||
assert.ok(!send_button.prop("disabled"));
|
||||
assert.ok(!$indicator.hasClass("over_limit"));
|
||||
assert.equal($indicator.text(), "9001/10000");
|
||||
assert.ok(!$textarea.hasClass("over_limit"));
|
||||
assert.ok(!$send_button.prop("disabled"));
|
||||
|
||||
// Indicator must be empty
|
||||
textarea.val("a".repeat(9000));
|
||||
$textarea.val("a".repeat(9000));
|
||||
compose_validate.check_overflow_text();
|
||||
assert.ok(!indicator.hasClass("over_limit"));
|
||||
assert.equal(indicator.text(), "");
|
||||
assert.ok(!textarea.hasClass("over_limit"));
|
||||
assert.ok(!$indicator.hasClass("over_limit"));
|
||||
assert.equal($indicator.text(), "");
|
||||
assert.ok(!$textarea.hasClass("over_limit"));
|
||||
});
|
||||
|
||||
test_ui("test_message_overflow", () => {
|
||||
@@ -736,10 +736,10 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, override_rewire, moc
|
||||
}
|
||||
|
||||
// Simulate that the row was added to the DOM.
|
||||
const warning_row = $("<warning row>");
|
||||
const $warning_row = $("<warning row>");
|
||||
|
||||
let looked_for_existing;
|
||||
warning_row.data = (field) => {
|
||||
$warning_row.data = (field) => {
|
||||
if (field === "user-id") {
|
||||
looked_for_existing = true;
|
||||
return "34";
|
||||
@@ -750,9 +750,9 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, override_rewire, moc
|
||||
throw new Error(`Unknown field ${field}`);
|
||||
};
|
||||
|
||||
const previous_users = $("#compose_invite_users .compose_invite_user");
|
||||
previous_users.length = 1;
|
||||
previous_users[0] = warning_row;
|
||||
const $previous_users = $("#compose_invite_users .compose_invite_user");
|
||||
$previous_users.length = 1;
|
||||
$previous_users[0] = $warning_row;
|
||||
$("#compose_invite_users").hide();
|
||||
|
||||
// Now try to mention the same person again. The template should
|
||||
@@ -788,12 +788,12 @@ test_ui("test warn_if_topic_resolved", ({override, mock_template}) => {
|
||||
stream_data.add_sub(sub);
|
||||
|
||||
// The error message area where it is shown
|
||||
const error_area = $("#compose_resolved_topic");
|
||||
const $error_area = $("#compose_resolved_topic");
|
||||
compose_validate.clear_topic_resolved_warning();
|
||||
// Hack to make this empty for zjquery; this is conceptually done
|
||||
// in the previous line.
|
||||
error_area.html("");
|
||||
assert.ok(!error_area.visible());
|
||||
$error_area.html("");
|
||||
assert.ok(!$error_area.visible());
|
||||
|
||||
compose_state.set_message_type("stream");
|
||||
compose_state.stream_name("Do not exist");
|
||||
@@ -802,25 +802,25 @@ test_ui("test warn_if_topic_resolved", ({override, mock_template}) => {
|
||||
|
||||
// Do not show a warning if stream name does not exist
|
||||
compose_validate.warn_if_topic_resolved(true);
|
||||
assert.ok(!error_area.visible());
|
||||
assert.ok(!$error_area.visible());
|
||||
|
||||
compose_state.stream_name("random");
|
||||
|
||||
// Show the warning now as stream also exists
|
||||
compose_validate.warn_if_topic_resolved(true);
|
||||
assert.ok(error_area.visible());
|
||||
assert.ok($error_area.visible());
|
||||
|
||||
// Call it again with false; this should be a noop.
|
||||
compose_validate.warn_if_topic_resolved(false);
|
||||
assert.ok(error_area.visible());
|
||||
assert.ok($error_area.visible());
|
||||
|
||||
compose_state.topic("hello");
|
||||
|
||||
// The warning will be cleared now
|
||||
compose_validate.warn_if_topic_resolved(true);
|
||||
assert.ok(!error_area.visible());
|
||||
assert.ok(!$error_area.visible());
|
||||
|
||||
// Calling with false won't do anything.
|
||||
compose_validate.warn_if_topic_resolved(false);
|
||||
assert.ok(!error_area.visible());
|
||||
assert.ok(!$error_area.visible());
|
||||
});
|
||||
|
||||
@@ -29,12 +29,12 @@ const server_events_dispatch = zrequire("server_events_dispatch");
|
||||
const compose_ui = zrequire("compose_ui");
|
||||
const compose = zrequire("compose");
|
||||
function stub_out_video_calls() {
|
||||
const elem = $("#below-compose-content .video_link");
|
||||
elem.toggle = (show) => {
|
||||
const $elem = $("#below-compose-content .video_link");
|
||||
$elem.toggle = (show) => {
|
||||
if (show) {
|
||||
elem.show();
|
||||
$elem.show();
|
||||
} else {
|
||||
elem.hide();
|
||||
$elem.hide();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -78,14 +78,14 @@ test("videos", ({override, override_rewire}) => {
|
||||
(function test_no_provider_video_link_compose_clicked() {
|
||||
let called = false;
|
||||
|
||||
const textarea = $.create("target-stub");
|
||||
textarea.set_parents_result(".message_edit_form", []);
|
||||
const $textarea = $.create("target-stub");
|
||||
$textarea.set_parents_result(".message_edit_form", []);
|
||||
|
||||
const ev = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
to_$: () => textarea,
|
||||
to_$: () => $textarea,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -104,14 +104,14 @@ test("videos", ({override, override_rewire}) => {
|
||||
let syntax_to_insert;
|
||||
let called = false;
|
||||
|
||||
const textarea = $.create("jitsi-target-stub");
|
||||
textarea.set_parents_result(".message_edit_form", []);
|
||||
const $textarea = $.create("jitsi-target-stub");
|
||||
$textarea.set_parents_result(".message_edit_form", []);
|
||||
|
||||
const ev = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
to_$: () => textarea,
|
||||
to_$: () => $textarea,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -142,14 +142,14 @@ test("videos", ({override, override_rewire}) => {
|
||||
let syntax_to_insert;
|
||||
let called = false;
|
||||
|
||||
const textarea = $.create("zoom-target-stub");
|
||||
textarea.set_parents_result(".message_edit_form", []);
|
||||
const $textarea = $.create("zoom-target-stub");
|
||||
$textarea.set_parents_result(".message_edit_form", []);
|
||||
|
||||
const ev = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
to_$: () => textarea,
|
||||
to_$: () => $textarea,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -188,14 +188,14 @@ test("videos", ({override, override_rewire}) => {
|
||||
let syntax_to_insert;
|
||||
let called = false;
|
||||
|
||||
const textarea = $.create("bbb-target-stub");
|
||||
textarea.set_parents_result(".message_edit_form", []);
|
||||
const $textarea = $.create("bbb-target-stub");
|
||||
$textarea.set_parents_result(".message_edit_form", []);
|
||||
|
||||
const ev = {
|
||||
preventDefault: () => {},
|
||||
stopPropagation: () => {},
|
||||
target: {
|
||||
to_$: () => textarea,
|
||||
to_$: () => $textarea,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -120,8 +120,8 @@ test("draft_model add", ({override}) => {
|
||||
const ls = localstorage();
|
||||
assert.equal(ls.get("draft"), undefined);
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
override(Date, "now", () => 1);
|
||||
const expected = {...draft_1};
|
||||
@@ -136,8 +136,8 @@ test("draft_model edit", () => {
|
||||
assert.equal(ls.get("draft"), undefined);
|
||||
let id;
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
with_overrides(({override}) => {
|
||||
override(Date, "now", () => 1);
|
||||
@@ -161,8 +161,8 @@ test("draft_model delete", ({override}) => {
|
||||
const ls = localstorage();
|
||||
assert.equal(ls.get("draft"), undefined);
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
override(Date, "now", () => 1);
|
||||
const expected = {...draft_1};
|
||||
@@ -212,8 +212,8 @@ test("initialize", ({override_rewire}) => {
|
||||
assert.ok(called);
|
||||
};
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
drafts.initialize();
|
||||
});
|
||||
@@ -239,8 +239,8 @@ test("remove_old_drafts", () => {
|
||||
ls.set("drafts", data);
|
||||
assert.deepEqual(draft_model.get(), data);
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
drafts.remove_old_drafts();
|
||||
assert.deepEqual(draft_model.get(), {id3: draft_3});
|
||||
@@ -256,9 +256,9 @@ test("update_draft", ({override}) => {
|
||||
override(compose_state, "get_message_type", () => "private");
|
||||
override(compose_state, "private_message_recipient", () => "aaron@zulip.com");
|
||||
|
||||
const container = $(".top_left_drafts");
|
||||
const child = $(".unread_count");
|
||||
container.set_find_results(".unread_count", child);
|
||||
const $container = $(".top_left_drafts");
|
||||
const $child = $(".unread_count");
|
||||
$container.set_find_results(".unread_count", $child);
|
||||
|
||||
tippy_args = {
|
||||
content: "translated: Saved as draft",
|
||||
@@ -313,8 +313,8 @@ test("delete_all_drafts", () => {
|
||||
ls.set("drafts", data);
|
||||
assert.deepEqual(draft_model.get(), data);
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
drafts.delete_all_drafts();
|
||||
assert.deepEqual(draft_model.get(), {});
|
||||
@@ -451,8 +451,8 @@ test("format_drafts", ({override_rewire, mock_template}) => {
|
||||
|
||||
expected[0].stream_name = "stream-rename";
|
||||
|
||||
const unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", unread_count);
|
||||
const $unread_count = $('<span class="unread_count"></span>');
|
||||
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
|
||||
|
||||
drafts.launch();
|
||||
timerender.__Rewire__("render_now", stub_render_now);
|
||||
|
||||
@@ -25,12 +25,12 @@ const {DropdownListWidget, MultiSelectDropdownListWidget} = zrequire("dropdown_l
|
||||
|
||||
// For DropdownListWidget
|
||||
const setup_dropdown_zjquery_data = (name) => {
|
||||
const input_group = $(".input_group");
|
||||
const reset_button = $(".dropdown_list_reset_button");
|
||||
input_group.set_find_results(".dropdown_list_reset_button", reset_button);
|
||||
$(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`).closest = () => input_group;
|
||||
const $input_group = $(".input_group");
|
||||
const $reset_button = $(".dropdown_list_reset_button");
|
||||
$input_group.set_find_results(".dropdown_list_reset_button", $reset_button);
|
||||
$(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`).closest = () => $input_group;
|
||||
const $widget = $(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`);
|
||||
return {reset_button, $widget};
|
||||
return {$reset_button, $widget};
|
||||
};
|
||||
|
||||
run_test("basic_functions", () => {
|
||||
@@ -46,31 +46,31 @@ run_test("basic_functions", () => {
|
||||
render_text: (text) => `rendered: ${text}`,
|
||||
};
|
||||
|
||||
const {reset_button, $widget} = setup_dropdown_zjquery_data(opts.widget_name);
|
||||
const {$reset_button, $widget} = setup_dropdown_zjquery_data(opts.widget_name);
|
||||
|
||||
const widget = new DropdownListWidget(opts);
|
||||
|
||||
assert.equal(widget.value(), "one");
|
||||
assert.equal(updated_value, undefined); // We haven't 'updated' the widget yet.
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
|
||||
widget.update("two");
|
||||
assert.equal($widget.text(), "rendered: two");
|
||||
assert.equal(widget.value(), "two");
|
||||
assert.equal(updated_value, "two");
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
|
||||
widget.update(null);
|
||||
assert.equal($widget.text(), "translated: not set");
|
||||
assert.equal(widget.value(), "");
|
||||
assert.equal(updated_value, null);
|
||||
assert.ok(!reset_button.visible());
|
||||
assert.ok(!$reset_button.visible());
|
||||
|
||||
widget.update("four");
|
||||
assert.equal($widget.text(), "translated: not set");
|
||||
assert.equal(widget.value(), "four");
|
||||
assert.equal(updated_value, "four");
|
||||
assert.ok(!reset_button.visible());
|
||||
assert.ok(!$reset_button.visible());
|
||||
});
|
||||
|
||||
run_test("no_default_value", () => {
|
||||
@@ -110,7 +110,7 @@ run_test("basic MDLW functions", () => {
|
||||
default_text: $t({defaultMessage: "not set"}),
|
||||
};
|
||||
|
||||
const {reset_button, $widget} = setup_multiselect_dropdown_zjquery_data(opts.widget_name);
|
||||
const {$reset_button, $widget} = setup_multiselect_dropdown_zjquery_data(opts.widget_name);
|
||||
const widget = new MultiSelectDropdownListWidget(opts);
|
||||
|
||||
function set_dropdown_variables(widget, value) {
|
||||
@@ -121,7 +121,7 @@ run_test("basic MDLW functions", () => {
|
||||
assert.deepEqual(widget.value(), ["one"]);
|
||||
assert.equal(updated_value, undefined);
|
||||
assert.equal($widget.text(), "one");
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
|
||||
set_dropdown_variables(widget, ["one", "two"]);
|
||||
widget.update(widget.data_selected);
|
||||
@@ -129,7 +129,7 @@ run_test("basic MDLW functions", () => {
|
||||
assert.equal($widget.text(), "one,two");
|
||||
assert.deepEqual(widget.value(), ["one", "two"]);
|
||||
assert.deepEqual(updated_value, ["one", "two"]);
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
|
||||
set_dropdown_variables(widget, ["one", "two", "three"]);
|
||||
widget.update(widget.data_selected);
|
||||
@@ -137,7 +137,7 @@ run_test("basic MDLW functions", () => {
|
||||
assert.equal($widget.text(), "translated: 3 selected");
|
||||
assert.deepEqual(widget.value(), ["one", "two", "three"]);
|
||||
assert.deepEqual(updated_value, ["one", "two", "three"]);
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
|
||||
set_dropdown_variables(widget, null);
|
||||
widget.update(widget.data_selected);
|
||||
@@ -145,7 +145,7 @@ run_test("basic MDLW functions", () => {
|
||||
assert.equal($widget.text(), "translated: not set");
|
||||
assert.equal(widget.value(), null);
|
||||
assert.equal(updated_value, null);
|
||||
assert.ok(!reset_button.visible());
|
||||
assert.ok(!$reset_button.visible());
|
||||
|
||||
set_dropdown_variables(widget, ["one"]);
|
||||
widget.update(widget.data_selected);
|
||||
@@ -153,7 +153,7 @@ run_test("basic MDLW functions", () => {
|
||||
assert.equal($widget.text(), "one");
|
||||
assert.deepEqual(widget.value(), ["one"]);
|
||||
assert.deepEqual(updated_value, ["one"]);
|
||||
assert.ok(reset_button.visible());
|
||||
assert.ok($reset_button.visible());
|
||||
});
|
||||
|
||||
run_test("MDLW no_default_value", () => {
|
||||
|
||||
@@ -67,7 +67,7 @@ people.add_active_user(kitty);
|
||||
*/
|
||||
run_test("typing_events.render_notifications_for_narrow", ({override_rewire, mock_template}) => {
|
||||
// All typists are rendered in `#typing_notifications`.
|
||||
const typing_notifications = $("#typing_notifications");
|
||||
const $typing_notifications = $("#typing_notifications");
|
||||
|
||||
const two_typing_users_ids = [anna.user_id, vronsky.user_id];
|
||||
const two_typing_users = [anna, vronsky];
|
||||
@@ -107,7 +107,7 @@ run_test("typing_events.render_notifications_for_narrow", ({override_rewire, moc
|
||||
typing_events.render_notifications_for_narrow();
|
||||
// Make sure #typing_notifications's html content is set to the rendered template
|
||||
// which we mocked and gave a custom return value.
|
||||
assert.equal(typing_notifications.html(), two_typing_users_rendered_html);
|
||||
assert.equal($typing_notifications.html(), two_typing_users_rendered_html);
|
||||
|
||||
// Now we'll see how setting the second argument to `true`
|
||||
// can be helpful in testing conditionals inside the template.
|
||||
@@ -118,9 +118,9 @@ run_test("typing_events.render_notifications_for_narrow", ({override_rewire, moc
|
||||
// Since we only have two(<MAX_USERS_TO_DISPLAY_NAME) typists, both of them
|
||||
// should be rendered but not 'Several people are typing…'
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok($typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes("Several people are typing…"));
|
||||
|
||||
// Change to having four typists and verify the rendered html has
|
||||
// 'Several people are typing…' but not the list of users.
|
||||
@@ -128,9 +128,9 @@ run_test("typing_events.render_notifications_for_narrow", ({override_rewire, moc
|
||||
override_rewire(typing_events, "get_users_typing_for_narrow", () => four_typing_users_ids);
|
||||
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok(!typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${kitty.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok(!$typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${kitty.full_name} is typing…`));
|
||||
});
|
||||
|
||||
@@ -8,8 +8,8 @@ const blueslip = require("../zjsunit/zblueslip");
|
||||
const $ = require("../zjsunit/zjquery");
|
||||
const {user_settings} = require("../zjsunit/zpage_params");
|
||||
|
||||
let window_stub;
|
||||
set_global("to_$", () => window_stub);
|
||||
let $window_stub;
|
||||
set_global("to_$", () => $window_stub);
|
||||
|
||||
mock_esm("../../static/js/search", {
|
||||
update_button_visibility: () => {},
|
||||
@@ -165,7 +165,7 @@ function test_helper({override, override_rewire, change_tab}) {
|
||||
}
|
||||
|
||||
run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window_stub = $.create("window-stub");
|
||||
$window_stub = $.create("window-stub");
|
||||
user_settings.default_view = "recent_topics";
|
||||
|
||||
override_rewire(recent_topics_util, "is_visible", () => false);
|
||||
@@ -189,7 +189,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#all_messages";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
@@ -199,7 +199,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
]);
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
@@ -211,7 +211,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#narrow/stream/Denmark";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
@@ -225,7 +225,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#narrow";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
@@ -240,7 +240,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#narrow/foo.foo";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
@@ -251,7 +251,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#streams/whatever";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[stream_settings_ui, "launch"],
|
||||
@@ -261,7 +261,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#reload:send_after_reload=0...";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([]);
|
||||
// If it's reload hash it shouldn't show the default view.
|
||||
assert.equal(recent_topics_ui_shown, false);
|
||||
@@ -269,25 +269,25 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#keyboard-shortcuts/whatever";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([[overlays, "close_for_hash_change"], "info: keyboard-shortcuts"]);
|
||||
|
||||
window.location.hash = "#message-formatting/whatever";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([[overlays, "close_for_hash_change"], "info: message-formatting"]);
|
||||
|
||||
window.location.hash = "#search-operators/whatever";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([[overlays, "close_for_hash_change"], "info: search-operators"]);
|
||||
|
||||
window.location.hash = "#drafts";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[drafts, "launch"],
|
||||
@@ -296,7 +296,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#settings/alert-words";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[settings, "launch"],
|
||||
@@ -305,7 +305,7 @@ run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
window.location.hash = "#organization/user-list-admin";
|
||||
|
||||
helper.clear_events();
|
||||
window_stub.trigger("hashchange");
|
||||
$window_stub.trigger("hashchange");
|
||||
helper.assert_events([
|
||||
[overlays, "close_for_hash_change"],
|
||||
[admin, "launch"],
|
||||
|
||||
@@ -69,12 +69,12 @@ run_test("basics", ({override_rewire, mock_template}) => {
|
||||
blueslip.expect("error", "Pill needs container.");
|
||||
input_pill.create(config);
|
||||
|
||||
const pill_input = $.create("pill_input");
|
||||
const container = $.create("container");
|
||||
container.set_find_results(".input", pill_input);
|
||||
const $pill_input = $.create("pill_input");
|
||||
const $container = $.create("container");
|
||||
$container.set_find_results(".input", $pill_input);
|
||||
|
||||
blueslip.expect("error", "Pill needs create_item_from_text");
|
||||
config.container = container;
|
||||
config.$container = $container;
|
||||
input_pill.create(config);
|
||||
|
||||
blueslip.expect("error", "Pill needs get_text_from_item");
|
||||
@@ -101,9 +101,9 @@ run_test("basics", ({override_rewire, mock_template}) => {
|
||||
let inserted_before;
|
||||
const expected_html = pill_html("JavaScript", "some_id1", example_img_link, status_emoji_info);
|
||||
|
||||
pill_input.before = (elem) => {
|
||||
$pill_input.before = ($elem) => {
|
||||
inserted_before = true;
|
||||
assert.equal(elem.html(), expected_html);
|
||||
assert.equal($elem.html(), expected_html);
|
||||
};
|
||||
|
||||
widget.appendValidatedData(item);
|
||||
@@ -134,27 +134,27 @@ function set_up() {
|
||||
},
|
||||
};
|
||||
|
||||
const pill_input = $.create("pill_input");
|
||||
const $pill_input = $.create("pill_input");
|
||||
|
||||
pill_input[0] = {};
|
||||
pill_input.before = () => {};
|
||||
$pill_input[0] = {};
|
||||
$pill_input.before = () => {};
|
||||
|
||||
const create_item_from_text = (text) => items[text];
|
||||
|
||||
const container = $.create("container");
|
||||
container.set_find_results(".input", pill_input);
|
||||
const $container = $.create("container");
|
||||
$container.set_find_results(".input", $pill_input);
|
||||
|
||||
const config = {
|
||||
container,
|
||||
$container,
|
||||
create_item_from_text,
|
||||
get_text_from_item: (item) => item.display_value,
|
||||
};
|
||||
|
||||
return {
|
||||
config,
|
||||
pill_input,
|
||||
$pill_input,
|
||||
items,
|
||||
container,
|
||||
$container,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,16 +167,16 @@ run_test("copy from pill", ({override_rewire, mock_template}) => {
|
||||
override_random_id({override_rewire});
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
widget.appendValue("blue,red");
|
||||
|
||||
const copy_handler = container.get_on_handler("copy", ".pill");
|
||||
const copy_handler = $container.get_on_handler("copy", ".pill");
|
||||
|
||||
let copied_text;
|
||||
|
||||
const pill_stub = {
|
||||
const $pill_stub = {
|
||||
data: (field) => {
|
||||
assert.equal(field, "id");
|
||||
return "some_id2";
|
||||
@@ -195,7 +195,7 @@ run_test("copy from pill", ({override_rewire, mock_template}) => {
|
||||
preventDefault: noop,
|
||||
};
|
||||
|
||||
container.set_find_results(":focus", pill_stub);
|
||||
$container.set_find_results(":focus", $pill_stub);
|
||||
|
||||
copy_handler(e);
|
||||
|
||||
@@ -210,12 +210,12 @@ run_test("paste to input", ({mock_template}) => {
|
||||
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
const items = info.items;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
|
||||
const paste_handler = container.get_on_handler("paste", ".input");
|
||||
const paste_handler = $container.get_on_handler("paste", ".input");
|
||||
|
||||
const paste_text = "blue,yellow";
|
||||
|
||||
@@ -233,7 +233,7 @@ run_test("paste to input", ({mock_template}) => {
|
||||
|
||||
document.execCommand = (cmd, _, text) => {
|
||||
assert.equal(cmd, "insertText");
|
||||
container.find(".input").text(text);
|
||||
$container.find(".input").text(text);
|
||||
};
|
||||
|
||||
paste_handler(e);
|
||||
@@ -257,12 +257,12 @@ run_test("arrows on pills", ({mock_template}) => {
|
||||
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
widget.appendValue("blue,red");
|
||||
|
||||
const key_handler = container.get_on_handler("keydown", ".pill");
|
||||
const key_handler = $container.get_on_handler("keydown", ".pill");
|
||||
|
||||
function test_key(c) {
|
||||
key_handler({
|
||||
@@ -273,7 +273,7 @@ run_test("arrows on pills", ({mock_template}) => {
|
||||
let prev_focused = false;
|
||||
let next_focused = false;
|
||||
|
||||
const pill_stub = {
|
||||
const $pill_stub = {
|
||||
prev: () => ({
|
||||
trigger: (type) => {
|
||||
if (type === "focus") {
|
||||
@@ -290,7 +290,7 @@ run_test("arrows on pills", ({mock_template}) => {
|
||||
}),
|
||||
};
|
||||
|
||||
container.set_find_results(".pill:focus", pill_stub);
|
||||
$container.set_find_results(".pill:focus", $pill_stub);
|
||||
|
||||
// We use the same stub to test both arrows, since we don't
|
||||
// actually cause any real state changes here. We stub out
|
||||
@@ -310,16 +310,16 @@ run_test("left arrow on input", ({mock_template}) => {
|
||||
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
widget.appendValue("blue,red");
|
||||
|
||||
const key_handler = container.get_on_handler("keydown", ".input");
|
||||
const key_handler = $container.get_on_handler("keydown", ".input");
|
||||
|
||||
let last_pill_focused = false;
|
||||
|
||||
container.set_find_results(".pill", {
|
||||
$container.set_find_results(".pill", {
|
||||
last: () => ({
|
||||
trigger: (type) => {
|
||||
if (type === "focus") {
|
||||
@@ -345,17 +345,17 @@ run_test("comma", ({mock_template}) => {
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const items = info.items;
|
||||
const pill_input = info.pill_input;
|
||||
const container = info.container;
|
||||
const $pill_input = info.$pill_input;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
widget.appendValue("blue,red");
|
||||
|
||||
assert.deepEqual(widget.items(), [items.blue, items.red]);
|
||||
|
||||
const key_handler = container.get_on_handler("keydown", ".input");
|
||||
const key_handler = $container.get_on_handler("keydown", ".input");
|
||||
|
||||
pill_input.text(" yel");
|
||||
$pill_input.text(" yel");
|
||||
|
||||
key_handler({
|
||||
key: ",",
|
||||
@@ -364,7 +364,7 @@ run_test("comma", ({mock_template}) => {
|
||||
|
||||
assert.deepEqual(widget.items(), [items.blue, items.red]);
|
||||
|
||||
pill_input.text(" yellow");
|
||||
$pill_input.text(" yellow");
|
||||
|
||||
key_handler({
|
||||
key: ",",
|
||||
@@ -383,14 +383,14 @@ run_test("Enter key with text", ({mock_template}) => {
|
||||
const info = set_up();
|
||||
const config = info.config;
|
||||
const items = info.items;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
widget.appendValue("blue,red");
|
||||
|
||||
assert.deepEqual(widget.items(), [items.blue, items.red]);
|
||||
|
||||
const key_handler = container.get_on_handler("keydown", ".input");
|
||||
const key_handler = $container.get_on_handler("keydown", ".input");
|
||||
|
||||
key_handler({
|
||||
key: "Enter",
|
||||
@@ -415,13 +415,13 @@ run_test("insert_remove", ({override_rewire, mock_template}) => {
|
||||
const info = set_up();
|
||||
|
||||
const config = info.config;
|
||||
const pill_input = info.pill_input;
|
||||
const $pill_input = info.$pill_input;
|
||||
const items = info.items;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const inserted_html = [];
|
||||
pill_input.before = (elem) => {
|
||||
inserted_html.push(elem.html());
|
||||
$pill_input.before = ($elem) => {
|
||||
inserted_html.push($elem.html());
|
||||
};
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
@@ -450,11 +450,11 @@ run_test("insert_remove", ({override_rewire, mock_template}) => {
|
||||
|
||||
assert.deepEqual(widget.items(), [items.blue, items.red, items.yellow]);
|
||||
|
||||
assert.equal(pill_input.text(), "chartreuse, mauve");
|
||||
assert.equal($pill_input.text(), "chartreuse, mauve");
|
||||
|
||||
assert.equal(widget.is_pending(), true);
|
||||
widget.clear_text();
|
||||
assert.equal(pill_input.text(), "");
|
||||
assert.equal($pill_input.text(), "");
|
||||
assert.equal(widget.is_pending(), false);
|
||||
|
||||
let color_removed;
|
||||
@@ -469,7 +469,7 @@ run_test("insert_remove", ({override_rewire, mock_template}) => {
|
||||
pill.$element.remove = set_colored_removed_func(pill.item.display_value);
|
||||
}
|
||||
|
||||
let key_handler = container.get_on_handler("keydown", ".input");
|
||||
let key_handler = $container.get_on_handler("keydown", ".input");
|
||||
|
||||
key_handler({
|
||||
key: "Backspace",
|
||||
@@ -486,7 +486,7 @@ run_test("insert_remove", ({override_rewire, mock_template}) => {
|
||||
|
||||
let next_pill_focused = false;
|
||||
|
||||
const next_pill_stub = {
|
||||
const $next_pill_stub = {
|
||||
trigger: (type) => {
|
||||
if (type === "focus") {
|
||||
next_pill_focused = true;
|
||||
@@ -494,17 +494,17 @@ run_test("insert_remove", ({override_rewire, mock_template}) => {
|
||||
},
|
||||
};
|
||||
|
||||
const focus_pill_stub = {
|
||||
next: () => next_pill_stub,
|
||||
const $focus_pill_stub = {
|
||||
next: () => $next_pill_stub,
|
||||
data: (field) => {
|
||||
assert.equal(field, "id");
|
||||
return "some_id1";
|
||||
},
|
||||
};
|
||||
|
||||
container.set_find_results(".pill:focus", focus_pill_stub);
|
||||
$container.set_find_results(".pill:focus", $focus_pill_stub);
|
||||
|
||||
key_handler = container.get_on_handler("keydown", ".pill");
|
||||
key_handler = $container.get_on_handler("keydown", ".pill");
|
||||
key_handler({
|
||||
key: "Backspace",
|
||||
preventDefault: noop,
|
||||
@@ -526,7 +526,7 @@ run_test("exit button on pill", ({override_rewire, mock_template}) => {
|
||||
|
||||
const config = info.config;
|
||||
const items = info.items;
|
||||
const container = info.container;
|
||||
const $container = info.$container;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
|
||||
@@ -539,7 +539,7 @@ run_test("exit button on pill", ({override_rewire, mock_template}) => {
|
||||
|
||||
let next_pill_focused = false;
|
||||
|
||||
const next_pill_stub = {
|
||||
const $next_pill_stub = {
|
||||
trigger: (type) => {
|
||||
if (type === "focus") {
|
||||
next_pill_focused = true;
|
||||
@@ -547,8 +547,8 @@ run_test("exit button on pill", ({override_rewire, mock_template}) => {
|
||||
},
|
||||
};
|
||||
|
||||
const curr_pill_stub = {
|
||||
next: () => next_pill_stub,
|
||||
const $curr_pill_stub = {
|
||||
next: () => $next_pill_stub,
|
||||
data: (field) => {
|
||||
assert.equal(field, "id");
|
||||
return "some_id1";
|
||||
@@ -559,7 +559,7 @@ run_test("exit button on pill", ({override_rewire, mock_template}) => {
|
||||
to_$: () => ({
|
||||
closest: (sel) => {
|
||||
assert.equal(sel, ".pill");
|
||||
return curr_pill_stub;
|
||||
return $curr_pill_stub;
|
||||
},
|
||||
}),
|
||||
};
|
||||
@@ -567,7 +567,7 @@ run_test("exit button on pill", ({override_rewire, mock_template}) => {
|
||||
const e = {
|
||||
stopPropagation: noop,
|
||||
};
|
||||
const exit_click_handler = container.get_on_handler("click", ".exit");
|
||||
const exit_click_handler = $container.get_on_handler("click", ".exit");
|
||||
|
||||
exit_click_handler.call(exit_button_stub, e);
|
||||
|
||||
@@ -580,13 +580,13 @@ run_test("misc things", () => {
|
||||
const info = set_up();
|
||||
|
||||
const config = info.config;
|
||||
const container = info.container;
|
||||
const pill_input = info.pill_input;
|
||||
const $container = info.$container;
|
||||
const $pill_input = info.$pill_input;
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
|
||||
// animation
|
||||
const animation_end_handler = container.get_on_handler("animationend", ".input");
|
||||
const animation_end_handler = $container.get_on_handler("animationend", ".input");
|
||||
|
||||
let shake_class_removed = false;
|
||||
|
||||
@@ -614,17 +614,17 @@ run_test("misc things", () => {
|
||||
});
|
||||
|
||||
// click on container
|
||||
const container_click_handler = container.get_on_handler("click");
|
||||
const container_click_handler = $container.get_on_handler("click");
|
||||
|
||||
const stub = $.create("the-pill-container");
|
||||
stub.set_find_results(".input", pill_input);
|
||||
stub.is = (sel) => {
|
||||
const $stub = $.create("the-pill-container");
|
||||
$stub.set_find_results(".input", $pill_input);
|
||||
$stub.is = (sel) => {
|
||||
assert.equal(sel, ".pill-container");
|
||||
return true;
|
||||
};
|
||||
|
||||
const this_ = {
|
||||
to_$: () => stub,
|
||||
to_$: () => $stub,
|
||||
};
|
||||
|
||||
container_click_handler.call(this_, {target: this_});
|
||||
@@ -637,18 +637,18 @@ run_test("appendValue/clear", ({mock_template}) => {
|
||||
return html;
|
||||
});
|
||||
|
||||
const pill_input = $.create("pill_input");
|
||||
const container = $.create("container");
|
||||
container.set_find_results(".input", pill_input);
|
||||
const $pill_input = $.create("pill_input");
|
||||
const $container = $.create("container");
|
||||
$container.set_find_results(".input", $pill_input);
|
||||
|
||||
const config = {
|
||||
container,
|
||||
$container,
|
||||
create_item_from_text: (s) => ({type: "color", display_value: s}),
|
||||
get_text_from_item: (s) => s.display_value,
|
||||
};
|
||||
|
||||
pill_input.before = () => {};
|
||||
pill_input[0] = {};
|
||||
$pill_input.before = () => {};
|
||||
$pill_input[0] = {};
|
||||
|
||||
const widget = input_pill.create(config);
|
||||
|
||||
@@ -672,5 +672,5 @@ run_test("appendValue/clear", ({mock_template}) => {
|
||||
|
||||
// Note that we remove colors in the reverse order that we inserted.
|
||||
assert.deepEqual(removed_colors, ["blue", "yellow", "red"]);
|
||||
assert.equal(pill_input[0].textContent, "");
|
||||
assert.equal($pill_input[0].textContent, "");
|
||||
});
|
||||
|
||||
@@ -7,9 +7,9 @@ const $ = require("../zjsunit/zjquery");
|
||||
const keydown_util = zrequire("keydown_util");
|
||||
|
||||
run_test("test_early_returns", () => {
|
||||
const stub = $.create("stub");
|
||||
const $stub = $.create("stub");
|
||||
const opts = {
|
||||
elem: stub,
|
||||
$elem: $stub,
|
||||
handlers: {
|
||||
ArrowLeft: () => {
|
||||
throw new Error("do not dispatch this with alt key");
|
||||
@@ -24,14 +24,14 @@ run_test("test_early_returns", () => {
|
||||
key: "a", // not in keys
|
||||
};
|
||||
|
||||
stub.trigger(e1);
|
||||
$stub.trigger(e1);
|
||||
|
||||
const e2 = {
|
||||
type: "keydown",
|
||||
key: "Enter", // no handler
|
||||
};
|
||||
|
||||
stub.trigger(e2);
|
||||
$stub.trigger(e2);
|
||||
|
||||
const e3 = {
|
||||
type: "keydown",
|
||||
@@ -39,5 +39,5 @@ run_test("test_early_returns", () => {
|
||||
altKey: true, // let browser handle
|
||||
};
|
||||
|
||||
stub.trigger(e3);
|
||||
$stub.trigger(e3);
|
||||
});
|
||||
|
||||
@@ -30,21 +30,21 @@ function test(label, f) {
|
||||
}
|
||||
|
||||
test("pan_and_zoom", ({override_rewire}) => {
|
||||
const img = $.create("img-stub");
|
||||
const link = $.create("link-stub");
|
||||
const msg = $.create("msg-stub");
|
||||
const $img = $.create("img-stub");
|
||||
const $link = $.create("link-stub");
|
||||
const $msg = $.create("msg-stub");
|
||||
|
||||
$(img).closest = () => [];
|
||||
$($img).closest = () => [];
|
||||
|
||||
img.set_parent(link);
|
||||
link.closest = () => msg;
|
||||
$img.set_parent($link);
|
||||
$link.closest = () => $msg;
|
||||
|
||||
override_rewire(rows, "id", (row) => {
|
||||
assert.equal(row, msg);
|
||||
override_rewire(rows, "id", ($row) => {
|
||||
assert.equal($row, $msg);
|
||||
return 1234;
|
||||
});
|
||||
|
||||
img.attr("src", "example");
|
||||
$img.attr("src", "example");
|
||||
|
||||
let fetched_zid;
|
||||
|
||||
@@ -55,25 +55,25 @@ test("pan_and_zoom", ({override_rewire}) => {
|
||||
|
||||
override_rewire(lightbox, "render_lightbox_list_images", () => {});
|
||||
const open_image = lightbox.build_open_image_function();
|
||||
open_image(img);
|
||||
open_image($img);
|
||||
|
||||
assert.equal(fetched_zid, 1234);
|
||||
});
|
||||
|
||||
test("youtube", ({override_rewire}) => {
|
||||
const href = "https://youtube.com/some-random-clip";
|
||||
const img = $.create("img-stub");
|
||||
const link = $.create("link-stub");
|
||||
const msg = $.create("msg-stub");
|
||||
const $img = $.create("img-stub");
|
||||
const $link = $.create("link-stub");
|
||||
const $msg = $.create("msg-stub");
|
||||
|
||||
override_rewire(rows, "id", (row) => {
|
||||
assert.equal(row, msg);
|
||||
override_rewire(rows, "id", ($row) => {
|
||||
assert.equal($row, $msg);
|
||||
return 4321;
|
||||
});
|
||||
|
||||
$(img).attr("src", href);
|
||||
$($img).attr("src", href);
|
||||
|
||||
$(img).closest = (sel) => {
|
||||
$($img).closest = (sel) => {
|
||||
if (sel === ".youtube-video") {
|
||||
// We just need a nonempty array to
|
||||
// set is_youtube_video to true.
|
||||
@@ -82,13 +82,13 @@ test("youtube", ({override_rewire}) => {
|
||||
return [];
|
||||
};
|
||||
|
||||
img.set_parent(link);
|
||||
link.closest = () => msg;
|
||||
link.attr("href", href);
|
||||
$img.set_parent($link);
|
||||
$link.closest = () => $msg;
|
||||
$link.attr("href", href);
|
||||
|
||||
override_rewire(lightbox, "render_lightbox_list_images", () => {});
|
||||
|
||||
const open_image = lightbox.build_open_image_function();
|
||||
open_image(img);
|
||||
open_image($img);
|
||||
assert.equal($(".image-actions .open").attr("href"), href);
|
||||
});
|
||||
|
||||
@@ -70,12 +70,12 @@ run_test("single item list", ({override}) => {
|
||||
});
|
||||
const cursor = new ListCursor(conf);
|
||||
|
||||
const li_stub = {
|
||||
const $li_stub = {
|
||||
length: 1,
|
||||
addClass: () => {},
|
||||
};
|
||||
|
||||
override(conf.list, "find_li", () => li_stub);
|
||||
override(conf.list, "find_li", () => $li_stub);
|
||||
override(cursor, "adjust_scroll", () => {});
|
||||
|
||||
cursor.go_to(valid_key);
|
||||
|
||||
@@ -41,81 +41,81 @@ const ListWidget = zrequire("list_widget");
|
||||
// in the real code.
|
||||
|
||||
function make_container() {
|
||||
const container = {};
|
||||
const $container = {};
|
||||
|
||||
container.length = () => 1;
|
||||
container.is = () => false;
|
||||
container.css = (prop) => {
|
||||
$container.length = () => 1;
|
||||
$container.is = () => false;
|
||||
$container.css = (prop) => {
|
||||
assert.equal(prop, "max-height");
|
||||
return "none";
|
||||
};
|
||||
|
||||
// Make our append function just set a field we can
|
||||
// check in our tests.
|
||||
container.append = (data) => {
|
||||
container.appended_data = data;
|
||||
$container.append = ($data) => {
|
||||
$container.$appended_data = $data;
|
||||
};
|
||||
|
||||
return container;
|
||||
return $container;
|
||||
}
|
||||
|
||||
function make_scroll_container() {
|
||||
const scroll_container = {};
|
||||
const $scroll_container = {};
|
||||
|
||||
scroll_container.cleared = false;
|
||||
$scroll_container.cleared = false;
|
||||
|
||||
// Capture the scroll callback so we can call it in
|
||||
// our tests.
|
||||
scroll_container.on = (ev, f) => {
|
||||
$scroll_container.on = (ev, f) => {
|
||||
assert.equal(ev, "scroll.list_widget_container");
|
||||
scroll_container.call_scroll = () => {
|
||||
f.call(scroll_container);
|
||||
$scroll_container.call_scroll = () => {
|
||||
f.call($scroll_container);
|
||||
};
|
||||
};
|
||||
|
||||
scroll_container.off = (ev) => {
|
||||
$scroll_container.off = (ev) => {
|
||||
assert.equal(ev, "scroll.list_widget_container");
|
||||
scroll_container.cleared = true;
|
||||
$scroll_container.cleared = true;
|
||||
};
|
||||
|
||||
return scroll_container;
|
||||
return $scroll_container;
|
||||
}
|
||||
|
||||
function make_sort_container() {
|
||||
const sort_container = {};
|
||||
const $sort_container = {};
|
||||
|
||||
sort_container.cleared = false;
|
||||
$sort_container.cleared = false;
|
||||
|
||||
sort_container.on = (ev, sel, f) => {
|
||||
$sort_container.on = (ev, sel, f) => {
|
||||
assert.equal(ev, "click.list_widget_sort");
|
||||
assert.equal(sel, "[data-sort]");
|
||||
sort_container.f = f;
|
||||
$sort_container.f = f;
|
||||
};
|
||||
|
||||
sort_container.off = (ev) => {
|
||||
$sort_container.off = (ev) => {
|
||||
assert.equal(ev, "click.list_widget_sort");
|
||||
sort_container.cleared = true;
|
||||
$sort_container.cleared = true;
|
||||
};
|
||||
|
||||
return sort_container;
|
||||
return $sort_container;
|
||||
}
|
||||
|
||||
function make_filter_element() {
|
||||
const element = {};
|
||||
const $element = {};
|
||||
|
||||
element.cleared = false;
|
||||
$element.cleared = false;
|
||||
|
||||
element.on = (ev, f) => {
|
||||
$element.on = (ev, f) => {
|
||||
assert.equal(ev, "input.list_widget_filter");
|
||||
element.f = f;
|
||||
$element.f = f;
|
||||
};
|
||||
|
||||
element.off = (ev) => {
|
||||
$element.off = (ev) => {
|
||||
assert.equal(ev, "input.list_widget_filter");
|
||||
element.cleared = true;
|
||||
$element.cleared = true;
|
||||
};
|
||||
|
||||
return element;
|
||||
return $element;
|
||||
}
|
||||
|
||||
function make_search_input() {
|
||||
@@ -143,15 +143,15 @@ function div(item) {
|
||||
}
|
||||
|
||||
run_test("scrolling", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
|
||||
const items = [];
|
||||
|
||||
let get_scroll_element_called = false;
|
||||
ui.get_scroll_element = (element) => {
|
||||
ui.get_scroll_element = ($element) => {
|
||||
get_scroll_element_called = true;
|
||||
return element;
|
||||
return $element;
|
||||
};
|
||||
|
||||
for (let i = 0; i < 200; i += 1) {
|
||||
@@ -160,38 +160,38 @@ run_test("scrolling", () => {
|
||||
|
||||
const opts = {
|
||||
modifier: (item) => item,
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
||||
container.html = (html) => {
|
||||
$container.html = (html) => {
|
||||
assert.equal(html, "");
|
||||
};
|
||||
ListWidget.create(container, items, opts);
|
||||
ListWidget.create($container, items, opts);
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), items.slice(0, 80).join(""));
|
||||
assert.deepEqual($container.$appended_data.html(), items.slice(0, 80).join(""));
|
||||
assert.equal(get_scroll_element_called, true);
|
||||
|
||||
// Set up our fake geometry so it forces a scroll action.
|
||||
scroll_container.scrollTop = 180;
|
||||
scroll_container.clientHeight = 100;
|
||||
scroll_container.scrollHeight = 260;
|
||||
$scroll_container.scrollTop = 180;
|
||||
$scroll_container.clientHeight = 100;
|
||||
$scroll_container.scrollHeight = 260;
|
||||
|
||||
// Scrolling gets the next two elements from the list into
|
||||
// our widget.
|
||||
scroll_container.call_scroll();
|
||||
assert.deepEqual(container.appended_data.html(), items.slice(80, 100).join(""));
|
||||
$scroll_container.call_scroll();
|
||||
assert.deepEqual($container.$appended_data.html(), items.slice(80, 100).join(""));
|
||||
});
|
||||
|
||||
run_test("not_scrolling", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
|
||||
const items = [];
|
||||
|
||||
let get_scroll_element_called = false;
|
||||
ui.get_scroll_element = (element) => {
|
||||
ui.get_scroll_element = ($element) => {
|
||||
get_scroll_element_called = true;
|
||||
return element;
|
||||
return $element;
|
||||
};
|
||||
|
||||
let post_scroll__pre_render_callback_called = false;
|
||||
@@ -211,54 +211,54 @@ run_test("not_scrolling", () => {
|
||||
|
||||
const opts = {
|
||||
modifier: (item) => item,
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
is_scroll_position_for_render: () => false,
|
||||
post_scroll__pre_render_callback,
|
||||
get_min_load_count,
|
||||
};
|
||||
|
||||
container.html = (html) => {
|
||||
$container.html = (html) => {
|
||||
assert.equal(html, "");
|
||||
};
|
||||
ListWidget.create(container, items, opts);
|
||||
ListWidget.create($container, items, opts);
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), items.slice(0, 80).join(""));
|
||||
assert.deepEqual($container.$appended_data.html(), items.slice(0, 80).join(""));
|
||||
assert.equal(get_scroll_element_called, true);
|
||||
|
||||
// Set up our fake geometry.
|
||||
scroll_container.scrollTop = 180;
|
||||
scroll_container.clientHeight = 100;
|
||||
scroll_container.scrollHeight = 260;
|
||||
$scroll_container.scrollTop = 180;
|
||||
$scroll_container.clientHeight = 100;
|
||||
$scroll_container.scrollHeight = 260;
|
||||
|
||||
// Since `should_render` is always false, no elements will be
|
||||
// added regardless of scrolling.
|
||||
scroll_container.call_scroll();
|
||||
// appended_data remains the same.
|
||||
assert.deepEqual(container.appended_data.html(), items.slice(0, 80).join(""));
|
||||
$scroll_container.call_scroll();
|
||||
// $appended_data remains the same.
|
||||
assert.deepEqual($container.$appended_data.html(), items.slice(0, 80).join(""));
|
||||
assert.equal(post_scroll__pre_render_callback_called, true);
|
||||
assert.equal(get_min_load_count_called, true);
|
||||
});
|
||||
|
||||
run_test("filtering", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
|
||||
const search_input = make_search_input();
|
||||
const $search_input = make_search_input();
|
||||
|
||||
const list = ["apple", "banana", "carrot", "dog", "egg", "fence", "grape"];
|
||||
const opts = {
|
||||
filter: {
|
||||
element: search_input,
|
||||
$element: $search_input,
|
||||
predicate: (item, value) => item.includes(value),
|
||||
},
|
||||
modifier: (item) => div(item),
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
||||
container.html = (html) => {
|
||||
$container.html = (html) => {
|
||||
assert.equal(html, "");
|
||||
};
|
||||
const widget = ListWidget.create(container, list, opts);
|
||||
const widget = ListWidget.create($container, list, opts);
|
||||
|
||||
let expected_html =
|
||||
"<div>apple</div>" +
|
||||
@@ -269,45 +269,45 @@ run_test("filtering", () => {
|
||||
"<div>fence</div>" +
|
||||
"<div>grape</div>";
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
|
||||
// Filtering will pick out dog/egg/grape when we put "g"
|
||||
// into our search input. (This uses the default filter, which
|
||||
// is a glorified indexOf call.)
|
||||
search_input.val = () => "g";
|
||||
search_input.simulate_input_event();
|
||||
$search_input.val = () => "g";
|
||||
$search_input.simulate_input_event();
|
||||
assert.deepEqual(widget.get_current_list(), ["dog", "egg", "grape"]);
|
||||
expected_html = "<div>dog</div><div>egg</div><div>grape</div>";
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
|
||||
// We can insert new data into the widget.
|
||||
const new_data = ["greta", "faye", "gary", "frank", "giraffe", "fox"];
|
||||
|
||||
widget.replace_list_data(new_data);
|
||||
expected_html = "<div>greta</div><div>gary</div><div>giraffe</div>";
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
});
|
||||
|
||||
run_test("no filtering", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
container.html = () => {};
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
$container.html = () => {};
|
||||
|
||||
let callback_called = false;
|
||||
// Opts does not require a filter key.
|
||||
const opts = {
|
||||
modifier: (item) => div(item),
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
callback_after_render: () => {
|
||||
callback_called = true;
|
||||
},
|
||||
};
|
||||
const widget = ListWidget.create(container, ["apple", "banana"], opts);
|
||||
const widget = ListWidget.create($container, ["apple", "banana"], opts);
|
||||
widget.render();
|
||||
assert.deepEqual(callback_called, true);
|
||||
|
||||
const expected_html = "<div>apple</div><div>banana</div>";
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
});
|
||||
|
||||
function sort_button(opts) {
|
||||
@@ -336,7 +336,7 @@ function sort_button(opts) {
|
||||
|
||||
const classList = new Set();
|
||||
|
||||
const button = {
|
||||
const $button = {
|
||||
data,
|
||||
closest: lookup(".progressive-table-wrapper", {
|
||||
data: lookup("list-widget", opts.list_name),
|
||||
@@ -351,47 +351,47 @@ function sort_button(opts) {
|
||||
siblings: lookup(".active", {
|
||||
removeClass: (cls) => {
|
||||
assert.equal(cls, "active");
|
||||
button.siblings_deactivated = true;
|
||||
$button.siblings_deactivated = true;
|
||||
},
|
||||
}),
|
||||
siblings_deactivated: false,
|
||||
to_jquery: () => button,
|
||||
to_jquery: () => $button,
|
||||
};
|
||||
|
||||
return button;
|
||||
return $button;
|
||||
}
|
||||
|
||||
run_test("wire up filter element", () => {
|
||||
const lst = ["alice", "JESSE", "moses", "scott", "Sean", "Xavier"];
|
||||
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const filter_element = make_filter_element();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
const $filter_element = make_filter_element();
|
||||
|
||||
// We don't care about what gets drawn initially.
|
||||
container.html = () => {};
|
||||
$container.html = () => {};
|
||||
|
||||
const opts = {
|
||||
filter: {
|
||||
filterer: (list, value) => list.filter((item) => item.toLowerCase().includes(value)),
|
||||
element: filter_element,
|
||||
$element: $filter_element,
|
||||
},
|
||||
modifier: (s) => "(" + s + ")",
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
||||
ListWidget.create(container, lst, opts);
|
||||
filter_element.f.apply({value: "se"});
|
||||
assert.equal(container.appended_data.html(), "(JESSE)(moses)(Sean)");
|
||||
ListWidget.create($container, lst, opts);
|
||||
$filter_element.f.apply({value: "se"});
|
||||
assert.equal($container.$appended_data.html(), "(JESSE)(moses)(Sean)");
|
||||
});
|
||||
|
||||
run_test("sorting", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const sort_container = make_sort_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
const $sort_container = make_sort_container();
|
||||
|
||||
let cleared;
|
||||
container.html = (html) => {
|
||||
$container.html = (html) => {
|
||||
assert.equal(html, "");
|
||||
cleared = true;
|
||||
};
|
||||
@@ -406,22 +406,22 @@ run_test("sorting", () => {
|
||||
|
||||
const opts = {
|
||||
name: "sorting-list",
|
||||
parent_container: sort_container,
|
||||
$parent_container: $sort_container,
|
||||
modifier: (item) => div(item.name) + div(item.salary),
|
||||
filter: {
|
||||
predicate: () => true,
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
||||
function html_for(people) {
|
||||
return people.map((item) => opts.modifier(item)).join("");
|
||||
}
|
||||
|
||||
ListWidget.create(container, list, opts);
|
||||
ListWidget.create($container, list, opts);
|
||||
|
||||
let button_opts;
|
||||
let button;
|
||||
let $button;
|
||||
let expected_html;
|
||||
|
||||
button_opts = {
|
||||
@@ -431,31 +431,31 @@ run_test("sorting", () => {
|
||||
active: false,
|
||||
};
|
||||
|
||||
button = sort_button(button_opts);
|
||||
$button = sort_button(button_opts);
|
||||
|
||||
sort_container.f.apply(button);
|
||||
$sort_container.f.apply($button);
|
||||
|
||||
assert.ok(cleared);
|
||||
assert.ok(button.siblings_deactivated);
|
||||
assert.ok($button.siblings_deactivated);
|
||||
|
||||
expected_html = html_for([alice, bob, cal, dave, ellen]);
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
|
||||
// Hit same button again to reverse the data.
|
||||
cleared = false;
|
||||
sort_container.f.apply(button);
|
||||
$sort_container.f.apply($button);
|
||||
assert.ok(cleared);
|
||||
expected_html = html_for([ellen, dave, cal, bob, alice]);
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.ok(button.hasClass("descend"));
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
assert.ok($button.hasClass("descend"));
|
||||
|
||||
// And then hit a third time to go back to the forward sort.
|
||||
cleared = false;
|
||||
sort_container.f.apply(button);
|
||||
$sort_container.f.apply($button);
|
||||
assert.ok(cleared);
|
||||
expected_html = html_for([alice, bob, cal, dave, ellen]);
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.ok(!button.hasClass("descend"));
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
assert.ok(!$button.hasClass("descend"));
|
||||
|
||||
// Now try a numeric sort.
|
||||
button_opts = {
|
||||
@@ -465,32 +465,32 @@ run_test("sorting", () => {
|
||||
active: false,
|
||||
};
|
||||
|
||||
button = sort_button(button_opts);
|
||||
$button = sort_button(button_opts);
|
||||
|
||||
cleared = false;
|
||||
button.siblings_deactivated = false;
|
||||
$button.siblings_deactivated = false;
|
||||
|
||||
sort_container.f.apply(button);
|
||||
$sort_container.f.apply($button);
|
||||
|
||||
assert.ok(cleared);
|
||||
assert.ok(button.siblings_deactivated);
|
||||
assert.ok($button.siblings_deactivated);
|
||||
|
||||
expected_html = html_for([dave, cal, bob, alice, ellen]);
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
|
||||
// Hit same button again to reverse the numeric sort.
|
||||
cleared = false;
|
||||
sort_container.f.apply(button);
|
||||
$sort_container.f.apply($button);
|
||||
assert.ok(cleared);
|
||||
expected_html = html_for([ellen, alice, bob, cal, dave]);
|
||||
assert.deepEqual(container.appended_data.html(), expected_html);
|
||||
assert.ok(button.hasClass("descend"));
|
||||
assert.deepEqual($container.$appended_data.html(), expected_html);
|
||||
assert.ok($button.hasClass("descend"));
|
||||
});
|
||||
|
||||
run_test("custom sort", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
container.html = () => {};
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
$container.html = () => {};
|
||||
|
||||
const n42 = {x: 6, y: 7};
|
||||
const n43 = {x: 1, y: 43};
|
||||
@@ -506,7 +506,7 @@ run_test("custom sort", () => {
|
||||
return a.x * a.y - b.x * b.y;
|
||||
}
|
||||
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
name: "custom-sort-list",
|
||||
modifier: (n) => "(" + n.x + ", " + n.y + ")",
|
||||
sort_fields: {
|
||||
@@ -514,15 +514,15 @@ run_test("custom sort", () => {
|
||||
x_value: sort_by_x,
|
||||
},
|
||||
init_sort: [sort_by_product],
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), "(6, 7)(1, 43)(4, 11)");
|
||||
assert.deepEqual($container.$appended_data.html(), "(6, 7)(1, 43)(4, 11)");
|
||||
|
||||
const widget = ListWidget.get("custom-sort-list");
|
||||
|
||||
widget.sort("x_value");
|
||||
assert.deepEqual(container.appended_data.html(), "(1, 43)(4, 11)(6, 7)");
|
||||
assert.deepEqual($container.$appended_data.html(), "(1, 43)(4, 11)(6, 7)");
|
||||
|
||||
// We can sort without registering the function, too.
|
||||
function sort_by_y(a, b) {
|
||||
@@ -530,97 +530,97 @@ run_test("custom sort", () => {
|
||||
}
|
||||
|
||||
widget.sort(sort_by_y);
|
||||
assert.deepEqual(container.appended_data.html(), "(6, 7)(4, 11)(1, 43)");
|
||||
assert.deepEqual($container.$appended_data.html(), "(6, 7)(4, 11)(1, 43)");
|
||||
});
|
||||
|
||||
run_test("clear_event_handlers", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const sort_container = make_sort_container();
|
||||
const filter_element = make_filter_element();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
const $sort_container = make_sort_container();
|
||||
const $filter_element = make_filter_element();
|
||||
|
||||
// We don't care about actual data for this test.
|
||||
const list = [];
|
||||
container.html = () => {};
|
||||
$container.html = () => {};
|
||||
|
||||
const opts = {
|
||||
name: "list-we-create-twice",
|
||||
parent_container: sort_container,
|
||||
$parent_container: $sort_container,
|
||||
modifier: () => {},
|
||||
filter: {
|
||||
element: filter_element,
|
||||
$element: $filter_element,
|
||||
predicate: () => true,
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
};
|
||||
|
||||
// Create it the first time.
|
||||
ListWidget.create(container, list, opts);
|
||||
assert.equal(sort_container.cleared, false);
|
||||
assert.equal(scroll_container.cleared, false);
|
||||
assert.equal(filter_element.cleared, false);
|
||||
ListWidget.create($container, list, opts);
|
||||
assert.equal($sort_container.cleared, false);
|
||||
assert.equal($scroll_container.cleared, false);
|
||||
assert.equal($filter_element.cleared, false);
|
||||
|
||||
// The second time we'll clear the old events.
|
||||
ListWidget.create(container, list, opts);
|
||||
assert.equal(sort_container.cleared, true);
|
||||
assert.equal(scroll_container.cleared, true);
|
||||
assert.equal(filter_element.cleared, true);
|
||||
ListWidget.create($container, list, opts);
|
||||
assert.equal($sort_container.cleared, true);
|
||||
assert.equal($scroll_container.cleared, true);
|
||||
assert.equal($filter_element.cleared, true);
|
||||
});
|
||||
|
||||
run_test("errors", () => {
|
||||
// We don't care about actual data for this test.
|
||||
const list = ["stub"];
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
|
||||
blueslip.expect("error", "Need opts to create widget.");
|
||||
ListWidget.create(container, list);
|
||||
ListWidget.create($container, list);
|
||||
blueslip.reset();
|
||||
|
||||
blueslip.expect("error", "simplebar_container is missing.");
|
||||
ListWidget.create(container, list, {
|
||||
blueslip.expect("error", "$simplebar_container is missing.");
|
||||
ListWidget.create($container, list, {
|
||||
modifier: "hello world",
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
blueslip.expect("error", "get_item should be a function");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
get_item: "not a function",
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
blueslip.expect("error", "Filter predicate is not a function.");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
filter: {
|
||||
predicate: "wrong type",
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
blueslip.expect("error", "Filterer and predicate are mutually exclusive.");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
filter: {
|
||||
filterer: () => true,
|
||||
predicate: () => true,
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
blueslip.expect("error", "Filter filterer is not a function (or missing).");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
filter: {},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
container.html = () => {};
|
||||
$container.html = () => {};
|
||||
blueslip.expect("error", "List item is not a string: 999");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
modifier: () => 999,
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
});
|
||||
@@ -648,14 +648,14 @@ run_test("sort helpers", () => {
|
||||
});
|
||||
|
||||
run_test("replace_list_data w/filter update", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
container.html = () => {};
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
$container.html = () => {};
|
||||
|
||||
const list = [1, 2, 3, 4];
|
||||
let num_updates = 0;
|
||||
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (n) => "(" + n.toString() + ")",
|
||||
filter: {
|
||||
@@ -664,19 +664,19 @@ run_test("replace_list_data w/filter update", () => {
|
||||
num_updates += 1;
|
||||
},
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
|
||||
assert.equal(num_updates, 0);
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), "(2)(4)");
|
||||
assert.deepEqual($container.$appended_data.html(), "(2)(4)");
|
||||
|
||||
const widget = ListWidget.get("replace-list");
|
||||
widget.replace_list_data([5, 6, 7, 8]);
|
||||
|
||||
assert.equal(num_updates, 1);
|
||||
|
||||
assert.deepEqual(container.appended_data.html(), "(6)(8)");
|
||||
assert.deepEqual($container.$appended_data.html(), "(6)(8)");
|
||||
});
|
||||
|
||||
run_test("opts.get_item", () => {
|
||||
@@ -722,12 +722,12 @@ run_test("opts.get_item", () => {
|
||||
});
|
||||
|
||||
run_test("render item", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
const INITIAL_RENDER_COUNT = 80; // Keep this in sync with the actual code.
|
||||
container.html = () => {};
|
||||
$container.html = () => {};
|
||||
let called = false;
|
||||
scroll_container.find = (query) => {
|
||||
$scroll_container.find = (query) => {
|
||||
const expected_queries = [
|
||||
`tr[data-item='${INITIAL_RENDER_COUNT}']`,
|
||||
`tr[data-item='${INITIAL_RENDER_COUNT - 1}']`,
|
||||
@@ -746,7 +746,7 @@ run_test("render item", () => {
|
||||
replaceWith: (html) => {
|
||||
assert.equal(new_html, html);
|
||||
called = true;
|
||||
container.appended_data.replace(regex, new_html);
|
||||
$container.$appended_data.replace(regex, new_html);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -756,29 +756,29 @@ run_test("render item", () => {
|
||||
let text = "initial";
|
||||
const get_item = (item) => ({text: `${text}: ${item}`, value: item});
|
||||
|
||||
const widget = ListWidget.create(container, list, {
|
||||
const widget = ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
|
||||
get_item,
|
||||
html_selector: (item) => `tr[data-item='${item}']`,
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
const item = INITIAL_RENDER_COUNT - 1;
|
||||
|
||||
assert.ok(container.appended_data.html().includes("<tr data-item=2>initial: 2</tr>"));
|
||||
assert.ok(container.appended_data.html().includes("<tr data-item=3>initial: 3</tr>"));
|
||||
assert.ok($container.$appended_data.html().includes("<tr data-item=2>initial: 2</tr>"));
|
||||
assert.ok($container.$appended_data.html().includes("<tr data-item=3>initial: 3</tr>"));
|
||||
text = "updated";
|
||||
called = false;
|
||||
widget.render_item(INITIAL_RENDER_COUNT - 1);
|
||||
assert.ok(called);
|
||||
assert.ok(container.appended_data.html().includes("<tr data-item=2>initial: 2</tr>"));
|
||||
assert.ok($container.$appended_data.html().includes("<tr data-item=2>initial: 2</tr>"));
|
||||
assert.ok(
|
||||
container.appended_data.html().includes(`<tr data-item=${item}>updated: ${item}</tr>`),
|
||||
$container.$appended_data.html().includes(`<tr data-item=${item}>updated: ${item}</tr>`),
|
||||
);
|
||||
|
||||
// Item 80 should not be in the rendered list. (0 indexed)
|
||||
assert.ok(
|
||||
!container.appended_data
|
||||
!$container.$appended_data
|
||||
.html()
|
||||
.includes(
|
||||
`<tr data-item=${INITIAL_RENDER_COUNT}>initial: ${INITIAL_RENDER_COUNT}</tr>`,
|
||||
@@ -793,24 +793,24 @@ run_test("render item", () => {
|
||||
// Tests below this are for the corner cases, where we abort the rerender.
|
||||
|
||||
blueslip.expect("error", "html_selector should be a function.");
|
||||
ListWidget.create(container, list, {
|
||||
ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
|
||||
get_item,
|
||||
html_selector: "hello world",
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
blueslip.reset();
|
||||
|
||||
let get_item_called;
|
||||
const widget_2 = ListWidget.create(container, list, {
|
||||
const widget_2 = ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => `<tr data-item=${item.value}>${item.text}</tr>\n`,
|
||||
get_item: (item) => {
|
||||
get_item_called = true;
|
||||
return item;
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
get_item_called = false;
|
||||
widget_2.render_item(item);
|
||||
@@ -818,12 +818,12 @@ run_test("render item", () => {
|
||||
assert.ok(!get_item_called);
|
||||
|
||||
let rendering_item = false;
|
||||
const widget_3 = ListWidget.create(container, list, {
|
||||
const widget_3 = ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => (rendering_item ? undefined : `${item}\n`),
|
||||
get_item,
|
||||
html_selector: (item) => `tr[data-item='${item}']`,
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
// Once we have initially rendered the widget, change the
|
||||
// behavior of the modifier function.
|
||||
@@ -834,16 +834,16 @@ run_test("render item", () => {
|
||||
});
|
||||
|
||||
run_test("Multiselect dropdown retain_selected_items", () => {
|
||||
const container = make_container();
|
||||
const scroll_container = make_scroll_container();
|
||||
const filter_element = make_filter_element();
|
||||
const $container = make_container();
|
||||
const $scroll_container = make_scroll_container();
|
||||
const $filter_element = make_filter_element();
|
||||
let data_rendered = [];
|
||||
|
||||
const list = ["one", "two", "three", "four"].map((x) => ({name: x, value: x}));
|
||||
const data = ["one"]; // Data initially selected.
|
||||
|
||||
container.html = () => {};
|
||||
container.find = (elem) => DropdownItem(elem);
|
||||
$container.html = () => {};
|
||||
$container.find = (elem) => DropdownItem(elem);
|
||||
|
||||
// We essentially create fake jQuery functions
|
||||
// whose return value are stored in objects so that
|
||||
@@ -880,8 +880,8 @@ run_test("Multiselect dropdown retain_selected_items", () => {
|
||||
return ListItem(element, temp);
|
||||
}
|
||||
|
||||
function prepend(data) {
|
||||
temp.prepended_data = data.html();
|
||||
function prepend($data) {
|
||||
temp.prepended_data = $data.html();
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -890,17 +890,17 @@ run_test("Multiselect dropdown retain_selected_items", () => {
|
||||
};
|
||||
}
|
||||
|
||||
const widget = ListWidget.create(container, list, {
|
||||
const widget = ListWidget.create($container, list, {
|
||||
name: "replace-list",
|
||||
modifier: (item) => `<li data-value="${item.value}">${item.name}</li>\n`,
|
||||
multiselect: {
|
||||
selected_items: data,
|
||||
},
|
||||
filter: {
|
||||
element: filter_element,
|
||||
$element: $filter_element,
|
||||
predicate: () => true,
|
||||
},
|
||||
simplebar_container: scroll_container,
|
||||
$simplebar_container: $scroll_container,
|
||||
});
|
||||
|
||||
const expected_value = [
|
||||
|
||||
@@ -117,9 +117,9 @@ run_test("update_messages", () => {
|
||||
page_params.realm_allow_edit_history = false;
|
||||
message_list.narrowed = "stub-to-ignore";
|
||||
|
||||
const message_edit_history_modal = $.create("#message-edit-history");
|
||||
const modal = $.create("micromodal").addClass("modal--open");
|
||||
message_edit_history_modal.set_parents_result(".micromodal", modal);
|
||||
const $message_edit_history_modal = $.create("#message-edit-history");
|
||||
const $modal = $.create("micromodal").addClass("modal--open");
|
||||
$message_edit_history_modal.set_parents_result(".micromodal", $modal);
|
||||
|
||||
// TEST THIS:
|
||||
message_events.update_messages(events);
|
||||
|
||||
@@ -27,47 +27,47 @@ run_test("basics w/progress bar", () => {
|
||||
let password;
|
||||
let warning;
|
||||
|
||||
const bar = (function () {
|
||||
const self = {};
|
||||
const $bar = (function () {
|
||||
const $self = {};
|
||||
|
||||
self.width = (width) => {
|
||||
self.w = width;
|
||||
return self;
|
||||
$self.width = (width) => {
|
||||
$self.w = width;
|
||||
return $self;
|
||||
};
|
||||
|
||||
self.removeClass = (arg) => {
|
||||
$self.removeClass = (arg) => {
|
||||
assert.equal(arg, "bar-success bar-danger");
|
||||
return self;
|
||||
return $self;
|
||||
};
|
||||
|
||||
self.addClass = (arg) => {
|
||||
self.added_class = arg;
|
||||
return self;
|
||||
$self.addClass = (arg) => {
|
||||
$self.added_class = arg;
|
||||
return $self;
|
||||
};
|
||||
|
||||
return self;
|
||||
return $self;
|
||||
})();
|
||||
|
||||
password = "z!X4@S_&";
|
||||
accepted = password_quality(password, bar, password_field(10, 80000));
|
||||
accepted = password_quality(password, $bar, password_field(10, 80000));
|
||||
assert.ok(!accepted);
|
||||
assert.equal(bar.w, "39.7%");
|
||||
assert.equal(bar.added_class, "bar-danger");
|
||||
assert.equal($bar.w, "39.7%");
|
||||
assert.equal($bar.added_class, "bar-danger");
|
||||
warning = password_warning(password, password_field(10));
|
||||
assert.equal(warning, "translated: Password should be at least 10 characters long");
|
||||
|
||||
password = "foo";
|
||||
accepted = password_quality(password, bar, password_field(2, 200));
|
||||
accepted = password_quality(password, $bar, password_field(2, 200));
|
||||
assert.ok(accepted);
|
||||
assert.equal(bar.w, "10.390277164940581%");
|
||||
assert.equal(bar.added_class, "bar-success");
|
||||
assert.equal($bar.w, "10.390277164940581%");
|
||||
assert.equal($bar.added_class, "bar-success");
|
||||
warning = password_warning(password, password_field(2));
|
||||
assert.equal(warning, "translated: Password is too weak");
|
||||
|
||||
password = "aaaaaaaa";
|
||||
accepted = password_quality(password, bar, password_field(6, 1e100));
|
||||
accepted = password_quality(password, $bar, password_field(6, 1e100));
|
||||
assert.ok(!accepted);
|
||||
assert.equal(bar.added_class, "bar-danger");
|
||||
assert.equal($bar.added_class, "bar-danger");
|
||||
warning = password_warning(password, password_field(6));
|
||||
assert.equal(warning, 'Repeats like "aaa" are easy to guess');
|
||||
});
|
||||
|
||||
@@ -19,19 +19,19 @@ const user_groups = zrequire("user_groups");
|
||||
// set global test variables.
|
||||
let sort_recipients_called = false;
|
||||
let sort_streams_called = false;
|
||||
const fake_rendered_person = $.create("fake-rendered-person");
|
||||
const fake_rendered_stream = $.create("fake-rendered-stream");
|
||||
const fake_rendered_group = $.create("fake-rendered-group");
|
||||
const $fake_rendered_person = $.create("fake-rendered-person");
|
||||
const $fake_rendered_stream = $.create("fake-rendered-stream");
|
||||
const $fake_rendered_group = $.create("fake-rendered-group");
|
||||
|
||||
mock_esm("../../static/js/typeahead_helper", {
|
||||
render_person() {
|
||||
return fake_rendered_person;
|
||||
return $fake_rendered_person;
|
||||
},
|
||||
render_user_group() {
|
||||
return fake_rendered_group;
|
||||
return $fake_rendered_group;
|
||||
},
|
||||
render_stream() {
|
||||
return fake_rendered_stream;
|
||||
return $fake_rendered_stream;
|
||||
},
|
||||
sort_streams() {
|
||||
sort_streams_called = true;
|
||||
@@ -113,20 +113,20 @@ run_test("set_up", ({mock_template}) => {
|
||||
return html;
|
||||
});
|
||||
let input_pill_typeahead_called = false;
|
||||
const fake_input = $.create(".input");
|
||||
fake_input.before = noop;
|
||||
const $fake_input = $.create(".input");
|
||||
$fake_input.before = noop;
|
||||
|
||||
const container = $.create(".pill-container");
|
||||
container.find = () => fake_input;
|
||||
const $container = $.create(".pill-container");
|
||||
$container.find = () => $fake_input;
|
||||
|
||||
const pill_widget = input_pill.create({
|
||||
container,
|
||||
const $pill_widget = input_pill.create({
|
||||
$container,
|
||||
create_item_from_text: noop,
|
||||
get_text_from_item: noop,
|
||||
});
|
||||
|
||||
let opts = {};
|
||||
fake_input.typeahead = (config) => {
|
||||
$fake_input.typeahead = (config) => {
|
||||
assert.equal(config.items, 5);
|
||||
assert.ok(config.fixed);
|
||||
assert.ok(config.dropup);
|
||||
@@ -154,7 +154,7 @@ run_test("set_up", ({mock_template}) => {
|
||||
// Test stream highlighter for widgets that allow stream pills.
|
||||
assert.equal(
|
||||
config.highlighter.call(fake_stream_this, denmark),
|
||||
fake_rendered_stream,
|
||||
$fake_rendered_stream,
|
||||
);
|
||||
}
|
||||
if (opts.user_group && opts.user) {
|
||||
@@ -162,17 +162,17 @@ run_test("set_up", ({mock_template}) => {
|
||||
// then we should check that each of them rendered correctly.
|
||||
assert.equal(
|
||||
config.highlighter.call(fake_group_this, testers),
|
||||
fake_rendered_group,
|
||||
$fake_rendered_group,
|
||||
);
|
||||
assert.equal(config.highlighter.call(fake_person_this, me), fake_rendered_person);
|
||||
assert.equal(config.highlighter.call(fake_person_this, me), $fake_rendered_person);
|
||||
}
|
||||
if (opts.user && !opts.user_group) {
|
||||
assert.equal(config.highlighter.call(fake_person_this, me), fake_rendered_person);
|
||||
assert.equal(config.highlighter.call(fake_person_this, me), $fake_rendered_person);
|
||||
}
|
||||
if (!opts.user && opts.user_group) {
|
||||
assert.equal(
|
||||
config.highlighter.call(fake_group_this, testers),
|
||||
fake_rendered_group,
|
||||
$fake_rendered_group,
|
||||
);
|
||||
}
|
||||
})();
|
||||
@@ -288,7 +288,7 @@ run_test("set_up", ({mock_template}) => {
|
||||
// updater in pill_typeahead.
|
||||
|
||||
function number_of_pills() {
|
||||
const pills = pill_widget.items();
|
||||
const pills = $pill_widget.items();
|
||||
return pills.length;
|
||||
}
|
||||
assert.equal(number_of_pills(), 0);
|
||||
@@ -307,7 +307,7 @@ run_test("set_up", ({mock_template}) => {
|
||||
};
|
||||
|
||||
function test_pill_typeahead(opts) {
|
||||
pill_typeahead.set_up(fake_input, pill_widget, opts);
|
||||
pill_typeahead.set_up($fake_input, $pill_widget, opts);
|
||||
assert.ok(input_pill_typeahead_called);
|
||||
}
|
||||
|
||||
@@ -339,6 +339,6 @@ run_test("set_up", ({mock_template}) => {
|
||||
opts = {};
|
||||
input_pill_typeahead_called = false;
|
||||
blueslip.expect("error", "Unspecified possible item types");
|
||||
pill_typeahead.set_up(fake_input, pill_widget, {});
|
||||
pill_typeahead.set_up($fake_input, $pill_widget, {});
|
||||
assert.ok(!input_pill_typeahead_called);
|
||||
});
|
||||
|
||||
@@ -16,23 +16,23 @@ run_test("update_dom_with_unread_counts", () => {
|
||||
narrow_state.set_current_filter("stub");
|
||||
assert.equal(narrow_state.active(), true);
|
||||
|
||||
const total_count = $.create("total-count-stub");
|
||||
const private_li = $(".top_left_private_messages .private_messages_header");
|
||||
private_li.set_find_results(".unread_count", total_count);
|
||||
const $total_count = $.create("total-count-stub");
|
||||
const $private_li = $(".top_left_private_messages .private_messages_header");
|
||||
$private_li.set_find_results(".unread_count", $total_count);
|
||||
|
||||
counts = {
|
||||
private_message_count: 10,
|
||||
};
|
||||
|
||||
pm_list.update_dom_with_unread_counts(counts);
|
||||
assert.equal(total_count.text(), "10");
|
||||
assert.ok(total_count.visible());
|
||||
assert.equal($total_count.text(), "10");
|
||||
assert.ok($total_count.visible());
|
||||
|
||||
counts = {
|
||||
private_message_count: 0,
|
||||
};
|
||||
|
||||
pm_list.update_dom_with_unread_counts(counts);
|
||||
assert.equal(total_count.text(), "");
|
||||
assert.ok(!total_count.visible());
|
||||
assert.equal($total_count.text(), "");
|
||||
assert.ok(!$total_count.visible());
|
||||
});
|
||||
|
||||
@@ -210,7 +210,7 @@ run_test("activate another person poll", ({mock_template}) => {
|
||||
mock_template("widgets/poll_widget.hbs", false, () => "widgets/poll_widget");
|
||||
mock_template("widgets/poll_widget_results.hbs", false, () => "widgets/poll_widget_results");
|
||||
|
||||
const widget_elem = $("<div>").addClass("widget-content");
|
||||
const $widget_elem = $("<div>").addClass("widget-content");
|
||||
|
||||
let out_data; // Used to check the event data sent to the server
|
||||
const callback = (data) => {
|
||||
@@ -218,7 +218,7 @@ run_test("activate another person poll", ({mock_template}) => {
|
||||
};
|
||||
|
||||
const opts = {
|
||||
elem: widget_elem,
|
||||
$elem: $widget_elem,
|
||||
callback,
|
||||
message: {
|
||||
sender_id: alice.user_id,
|
||||
@@ -229,53 +229,53 @@ run_test("activate another person poll", ({mock_template}) => {
|
||||
};
|
||||
|
||||
const set_widget_find_result = (selector) => {
|
||||
const elem = $.create(selector);
|
||||
widget_elem.set_find_results(selector, elem);
|
||||
return elem;
|
||||
const $elem = $.create(selector);
|
||||
$widget_elem.set_find_results(selector, $elem);
|
||||
return $elem;
|
||||
};
|
||||
|
||||
const poll_option = set_widget_find_result("button.poll-option");
|
||||
const poll_option_input = set_widget_find_result("input.poll-option");
|
||||
const widget_option_container = set_widget_find_result("ul.poll-widget");
|
||||
const $poll_option = set_widget_find_result("button.poll-option");
|
||||
const $poll_option_input = set_widget_find_result("input.poll-option");
|
||||
const $widget_option_container = set_widget_find_result("ul.poll-widget");
|
||||
|
||||
const poll_question_submit = set_widget_find_result("button.poll-question-check");
|
||||
const poll_edit_question = set_widget_find_result(".poll-edit-question");
|
||||
const poll_question_header = set_widget_find_result(".poll-question-header");
|
||||
const poll_question_container = set_widget_find_result(".poll-question-bar");
|
||||
const poll_option_container = set_widget_find_result(".poll-option-bar");
|
||||
const $poll_question_submit = set_widget_find_result("button.poll-question-check");
|
||||
const $poll_edit_question = set_widget_find_result(".poll-edit-question");
|
||||
const $poll_question_header = set_widget_find_result(".poll-question-header");
|
||||
const $poll_question_container = set_widget_find_result(".poll-question-bar");
|
||||
const $poll_option_container = set_widget_find_result(".poll-option-bar");
|
||||
|
||||
const poll_vote_button = set_widget_find_result("button.poll-vote");
|
||||
const poll_please_wait = set_widget_find_result(".poll-please-wait");
|
||||
const poll_author_help = set_widget_find_result(".poll-author-help");
|
||||
const $poll_vote_button = set_widget_find_result("button.poll-vote");
|
||||
const $poll_please_wait = set_widget_find_result(".poll-please-wait");
|
||||
const $poll_author_help = set_widget_find_result(".poll-author-help");
|
||||
|
||||
set_widget_find_result("button.poll-question-remove");
|
||||
set_widget_find_result("input.poll-question");
|
||||
|
||||
poll_widget.activate(opts);
|
||||
|
||||
assert.ok(poll_option_container.visible());
|
||||
assert.ok(poll_question_header.visible());
|
||||
assert.ok($poll_option_container.visible());
|
||||
assert.ok($poll_question_header.visible());
|
||||
|
||||
assert.ok(!poll_question_container.visible());
|
||||
assert.ok(!poll_question_submit.visible());
|
||||
assert.ok(!poll_edit_question.visible());
|
||||
assert.ok(!poll_please_wait.visible());
|
||||
assert.ok(!poll_author_help.visible());
|
||||
assert.ok(!$poll_question_container.visible());
|
||||
assert.ok(!$poll_question_submit.visible());
|
||||
assert.ok(!$poll_edit_question.visible());
|
||||
assert.ok(!$poll_please_wait.visible());
|
||||
assert.ok(!$poll_author_help.visible());
|
||||
|
||||
assert.equal(widget_elem.html(), "widgets/poll_widget");
|
||||
assert.equal(widget_option_container.html(), "widgets/poll_widget_results");
|
||||
assert.equal(poll_question_header.text(), "What do you want?");
|
||||
assert.equal($widget_elem.html(), "widgets/poll_widget");
|
||||
assert.equal($widget_option_container.html(), "widgets/poll_widget_results");
|
||||
assert.equal($poll_question_header.text(), "What do you want?");
|
||||
|
||||
{
|
||||
/* Testing data sent to server on adding option */
|
||||
poll_option_input.val("cool choice");
|
||||
$poll_option_input.val("cool choice");
|
||||
out_data = undefined;
|
||||
poll_option.trigger("click");
|
||||
$poll_option.trigger("click");
|
||||
assert.deepEqual(out_data, {type: "new_option", idx: 1, option: "cool choice"});
|
||||
|
||||
poll_option_input.val("");
|
||||
$poll_option_input.val("");
|
||||
out_data = undefined;
|
||||
poll_option.trigger("click");
|
||||
$poll_option.trigger("click");
|
||||
assert.deepEqual(out_data, undefined);
|
||||
}
|
||||
|
||||
@@ -298,13 +298,13 @@ run_test("activate another person poll", ({mock_template}) => {
|
||||
},
|
||||
];
|
||||
|
||||
widget_elem.handle_events(vote_events);
|
||||
$widget_elem.handle_events(vote_events);
|
||||
|
||||
{
|
||||
/* Testing data sent to server on voting */
|
||||
poll_vote_button.attr("data-key", "100,1");
|
||||
$poll_vote_button.attr("data-key", "100,1");
|
||||
out_data = undefined;
|
||||
poll_vote_button.trigger("click");
|
||||
$poll_vote_button.trigger("click");
|
||||
assert.deepEqual(out_data, {type: "vote", key: "100,1", vote: 1});
|
||||
}
|
||||
|
||||
@@ -318,20 +318,20 @@ run_test("activate another person poll", ({mock_template}) => {
|
||||
},
|
||||
];
|
||||
|
||||
widget_elem.handle_events(add_question_event);
|
||||
$widget_elem.handle_events(add_question_event);
|
||||
});
|
||||
|
||||
run_test("activate own poll", ({mock_template}) => {
|
||||
mock_template("widgets/poll_widget.hbs", false, () => "widgets/poll_widget");
|
||||
mock_template("widgets/poll_widget_results.hbs", false, () => "widgets/poll_widget_results");
|
||||
|
||||
const widget_elem = $("<div>").addClass("widget-content");
|
||||
const $widget_elem = $("<div>").addClass("widget-content");
|
||||
let out_data;
|
||||
const callback = (data) => {
|
||||
out_data = data;
|
||||
};
|
||||
const opts = {
|
||||
elem: widget_elem,
|
||||
$elem: $widget_elem,
|
||||
callback,
|
||||
message: {
|
||||
sender_id: me.user_id,
|
||||
@@ -342,59 +342,59 @@ run_test("activate own poll", ({mock_template}) => {
|
||||
};
|
||||
|
||||
const set_widget_find_result = (selector) => {
|
||||
const elem = $.create(selector);
|
||||
widget_elem.set_find_results(selector, elem);
|
||||
return elem;
|
||||
const $elem = $.create(selector);
|
||||
$widget_elem.set_find_results(selector, $elem);
|
||||
return $elem;
|
||||
};
|
||||
|
||||
set_widget_find_result("button.poll-option");
|
||||
const poll_option_input = set_widget_find_result("input.poll-option");
|
||||
const widget_option_container = set_widget_find_result("ul.poll-widget");
|
||||
const $poll_option_input = set_widget_find_result("input.poll-option");
|
||||
const $widget_option_container = set_widget_find_result("ul.poll-widget");
|
||||
|
||||
const poll_question_submit = set_widget_find_result("button.poll-question-check");
|
||||
const poll_edit_question = set_widget_find_result(".poll-edit-question");
|
||||
const poll_question_input = set_widget_find_result("input.poll-question");
|
||||
const poll_question_header = set_widget_find_result(".poll-question-header");
|
||||
const poll_question_container = set_widget_find_result(".poll-question-bar");
|
||||
const poll_option_container = set_widget_find_result(".poll-option-bar");
|
||||
const $poll_question_submit = set_widget_find_result("button.poll-question-check");
|
||||
const $poll_edit_question = set_widget_find_result(".poll-edit-question");
|
||||
const $poll_question_input = set_widget_find_result("input.poll-question");
|
||||
const $poll_question_header = set_widget_find_result(".poll-question-header");
|
||||
const $poll_question_container = set_widget_find_result(".poll-question-bar");
|
||||
const $poll_option_container = set_widget_find_result(".poll-option-bar");
|
||||
|
||||
set_widget_find_result("button.poll-vote");
|
||||
const poll_please_wait = set_widget_find_result(".poll-please-wait");
|
||||
const poll_author_help = set_widget_find_result(".poll-author-help");
|
||||
const $poll_please_wait = set_widget_find_result(".poll-please-wait");
|
||||
const $poll_author_help = set_widget_find_result(".poll-author-help");
|
||||
|
||||
set_widget_find_result("button.poll-question-remove");
|
||||
|
||||
function assert_visibility() {
|
||||
assert.ok(poll_option_container.visible());
|
||||
assert.ok(poll_question_header.visible());
|
||||
assert.ok(!poll_question_container.visible());
|
||||
assert.ok(poll_edit_question.visible());
|
||||
assert.ok(!poll_please_wait.visible());
|
||||
assert.ok(!poll_author_help.visible());
|
||||
assert.ok($poll_option_container.visible());
|
||||
assert.ok($poll_question_header.visible());
|
||||
assert.ok(!$poll_question_container.visible());
|
||||
assert.ok($poll_edit_question.visible());
|
||||
assert.ok(!$poll_please_wait.visible());
|
||||
assert.ok(!$poll_author_help.visible());
|
||||
}
|
||||
|
||||
poll_widget.activate(opts);
|
||||
|
||||
assert_visibility();
|
||||
assert.ok(!poll_question_submit.visible());
|
||||
assert.ok(!$poll_question_submit.visible());
|
||||
|
||||
assert.equal(widget_elem.html(), "widgets/poll_widget");
|
||||
assert.equal(widget_option_container.html(), "widgets/poll_widget_results");
|
||||
assert.equal(poll_question_header.text(), "Where to go?");
|
||||
assert.equal($widget_elem.html(), "widgets/poll_widget");
|
||||
assert.equal($widget_option_container.html(), "widgets/poll_widget_results");
|
||||
assert.equal($poll_question_header.text(), "Where to go?");
|
||||
|
||||
{
|
||||
/* Testing data sent to server on editing question */
|
||||
poll_question_input.val("Is it new?");
|
||||
$poll_question_input.val("Is it new?");
|
||||
out_data = undefined;
|
||||
poll_question_submit.trigger("click");
|
||||
$poll_question_submit.trigger("click");
|
||||
assert.deepEqual(out_data, {type: "question", question: "Is it new?"});
|
||||
|
||||
assert_visibility();
|
||||
assert.ok(poll_question_submit.visible());
|
||||
assert.ok($poll_question_submit.visible());
|
||||
|
||||
poll_option_input.val("");
|
||||
$poll_option_input.val("");
|
||||
out_data = undefined;
|
||||
poll_question_submit.trigger("click");
|
||||
$poll_question_submit.trigger("click");
|
||||
assert.deepEqual(out_data, undefined);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -146,9 +146,9 @@ test_ui("sender_hover", ({override, mock_template}) => {
|
||||
assert.equal(msg_id, message.id);
|
||||
};
|
||||
|
||||
const target = $.create("click target");
|
||||
const $target = $.create("click target");
|
||||
|
||||
target.closest = (sel) => {
|
||||
$target.closest = (sel) => {
|
||||
assert.equal(sel, ".message_row");
|
||||
return {};
|
||||
};
|
||||
@@ -205,7 +205,7 @@ test_ui("sender_hover", ({override, mock_template}) => {
|
||||
|
||||
$.create(".user_popover_email", {children: []});
|
||||
const image_stubber = make_image_stubber();
|
||||
handler.call(target, e);
|
||||
handler.call($target, e);
|
||||
|
||||
const avatar_img = image_stubber.get(0);
|
||||
assert.equal(avatar_img.src.toString(), "/avatar/42/medium");
|
||||
@@ -216,7 +216,7 @@ test_ui("sender_hover", ({override, mock_template}) => {
|
||||
test_ui("actions_popover", ({override, override_rewire, mock_template}) => {
|
||||
override($.fn, "popover", noop);
|
||||
|
||||
const target = $.create("click target");
|
||||
const $target = $.create("click target");
|
||||
|
||||
const handler = $("#main_div").get_on_handler("click", ".actions_hover");
|
||||
|
||||
@@ -241,7 +241,7 @@ test_ui("actions_popover", ({override, override_rewire, mock_template}) => {
|
||||
|
||||
override_rewire(message_edit, "get_editability", () => 4);
|
||||
|
||||
target.closest = (sel) => {
|
||||
$target.closest = (sel) => {
|
||||
assert.equal(sel, ".message_row");
|
||||
return {
|
||||
toggleClass: noop,
|
||||
@@ -257,5 +257,5 @@ test_ui("actions_popover", ({override, override_rewire, mock_template}) => {
|
||||
return "actions-content";
|
||||
});
|
||||
|
||||
handler.call(target, e);
|
||||
handler.call($target, e);
|
||||
});
|
||||
|
||||
@@ -361,46 +361,46 @@ test("sending", ({override, override_rewire}) => {
|
||||
});
|
||||
|
||||
test("set_reaction_count", () => {
|
||||
const count_element = $.create("count-stub");
|
||||
const reaction_element = $.create("reaction-stub");
|
||||
const $count_element = $.create("count-stub");
|
||||
const $reaction_element = $.create("reaction-stub");
|
||||
|
||||
reaction_element.set_find_results(".message_reaction_count", count_element);
|
||||
$reaction_element.set_find_results(".message_reaction_count", $count_element);
|
||||
|
||||
reactions.set_reaction_count(reaction_element, 5);
|
||||
reactions.set_reaction_count($reaction_element, 5);
|
||||
|
||||
assert.equal(count_element.text(), "5");
|
||||
assert.equal($count_element.text(), "5");
|
||||
});
|
||||
|
||||
test("find_reaction", ({override_rewire}) => {
|
||||
const message_id = 99;
|
||||
const local_id = "unicode_emoji,1f44b";
|
||||
const reaction_section = $.create("section-stub");
|
||||
const $reaction_section = $.create("section-stub");
|
||||
|
||||
const reaction_stub = "reaction-stub";
|
||||
reaction_section.set_find_results(
|
||||
$reaction_section.set_find_results(
|
||||
`[data-reaction-id='${CSS.escape(local_id)}']`,
|
||||
reaction_stub,
|
||||
);
|
||||
|
||||
override_rewire(reactions, "get_reaction_section", (arg) => {
|
||||
assert.equal(arg, message_id);
|
||||
return reaction_section;
|
||||
return $reaction_section;
|
||||
});
|
||||
|
||||
assert.equal(reactions.find_reaction(message_id, local_id), reaction_stub);
|
||||
});
|
||||
|
||||
test("get_reaction_section", () => {
|
||||
const message_table = $.create(".message_table");
|
||||
const message_row = $.create("some-message-row");
|
||||
const message_reactions = $.create("our-reactions-section");
|
||||
const $message_table = $.create(".message_table");
|
||||
const $message_row = $.create("some-message-row");
|
||||
const $message_reactions = $.create("our-reactions-section");
|
||||
|
||||
message_table.set_find_results(`[zid='${CSS.escape(555)}']`, message_row);
|
||||
message_row.set_find_results(".message_reactions", message_reactions);
|
||||
$message_table.set_find_results(`[zid='${CSS.escape(555)}']`, $message_row);
|
||||
$message_row.set_find_results(".message_reactions", $message_reactions);
|
||||
|
||||
const section = reactions.get_reaction_section(555);
|
||||
|
||||
assert.equal(section, message_reactions);
|
||||
assert.equal(section, $message_reactions);
|
||||
});
|
||||
|
||||
test("emoji_reaction_title", ({override}) => {
|
||||
@@ -599,14 +599,14 @@ test("view.insert_new_reaction (me w/unicode emoji)", ({override_rewire, mock_te
|
||||
user_id: alice.user_id,
|
||||
};
|
||||
|
||||
const message_reactions = $.create("our-reactions");
|
||||
const $message_reactions = $.create("our-reactions");
|
||||
|
||||
override_rewire(reactions, "get_reaction_section", (message_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
return message_reactions;
|
||||
return $message_reactions;
|
||||
});
|
||||
|
||||
message_reactions.find = (selector) => {
|
||||
$message_reactions.find = (selector) => {
|
||||
assert.equal(selector, ".reaction_button");
|
||||
return "reaction-button-stub";
|
||||
};
|
||||
@@ -646,14 +646,14 @@ test("view.insert_new_reaction (them w/zulip emoji)", ({override_rewire, mock_te
|
||||
user_id: bob.user_id,
|
||||
};
|
||||
|
||||
const message_reactions = $.create("our-reactions");
|
||||
const $message_reactions = $.create("our-reactions");
|
||||
|
||||
override_rewire(reactions, "get_reaction_section", (message_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
return message_reactions;
|
||||
return $message_reactions;
|
||||
});
|
||||
|
||||
message_reactions.find = (selector) => {
|
||||
$message_reactions.find = (selector) => {
|
||||
assert.equal(selector, ".reaction_button");
|
||||
return "reaction-button-stub";
|
||||
};
|
||||
@@ -696,24 +696,24 @@ test("view.update_existing_reaction (me)", ({override_rewire}) => {
|
||||
user_list: [alice.user_id, bob.user_id],
|
||||
};
|
||||
|
||||
const our_reaction = $.create("our-reaction-stub");
|
||||
const $our_reaction = $.create("our-reaction-stub");
|
||||
|
||||
override_rewire(reactions, "find_reaction", (message_id, local_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
assert.equal(local_id, "unicode_emoji,1f3b1");
|
||||
return our_reaction;
|
||||
return $our_reaction;
|
||||
});
|
||||
|
||||
override_rewire(reactions, "set_reaction_count", (reaction, count) => {
|
||||
assert.equal(reaction, our_reaction);
|
||||
assert.equal(reaction, $our_reaction);
|
||||
assert.equal(count, 2);
|
||||
});
|
||||
|
||||
reactions.view.update_existing_reaction(opts);
|
||||
|
||||
assert.ok(our_reaction.hasClass("reacted"));
|
||||
assert.ok($our_reaction.hasClass("reacted"));
|
||||
assert.equal(
|
||||
our_reaction.attr("aria-label"),
|
||||
$our_reaction.attr("aria-label"),
|
||||
"translated: You (click to remove) and Bob van Roberts reacted with :8ball:",
|
||||
);
|
||||
});
|
||||
@@ -728,24 +728,24 @@ test("view.update_existing_reaction (them)", ({override_rewire}) => {
|
||||
user_list: [alice.user_id, bob.user_id, cali.user_id, alexus.user_id],
|
||||
};
|
||||
|
||||
const our_reaction = $.create("our-reaction-stub");
|
||||
const $our_reaction = $.create("our-reaction-stub");
|
||||
|
||||
override_rewire(reactions, "find_reaction", (message_id, local_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
assert.equal(local_id, "unicode_emoji,1f3b1");
|
||||
return our_reaction;
|
||||
return $our_reaction;
|
||||
});
|
||||
|
||||
override_rewire(reactions, "set_reaction_count", (reaction, count) => {
|
||||
assert.equal(reaction, our_reaction);
|
||||
assert.equal(reaction, $our_reaction);
|
||||
assert.equal(count, 4);
|
||||
});
|
||||
|
||||
reactions.view.update_existing_reaction(opts);
|
||||
|
||||
assert.ok(!our_reaction.hasClass("reacted"));
|
||||
assert.ok(!$our_reaction.hasClass("reacted"));
|
||||
assert.equal(
|
||||
our_reaction.attr("aria-label"),
|
||||
$our_reaction.attr("aria-label"),
|
||||
"translated: You (click to remove), Bob van Roberts, Cali and Alexus reacted with :8ball:",
|
||||
);
|
||||
});
|
||||
@@ -760,25 +760,25 @@ test("view.remove_reaction (me)", ({override_rewire}) => {
|
||||
user_list: [bob.user_id, cali.user_id],
|
||||
};
|
||||
|
||||
const our_reaction = $.create("our-reaction-stub");
|
||||
our_reaction.addClass("reacted");
|
||||
const $our_reaction = $.create("our-reaction-stub");
|
||||
$our_reaction.addClass("reacted");
|
||||
|
||||
override_rewire(reactions, "find_reaction", (message_id, local_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
assert.equal(local_id, "unicode_emoji,1f3b1");
|
||||
return our_reaction;
|
||||
return $our_reaction;
|
||||
});
|
||||
|
||||
override_rewire(reactions, "set_reaction_count", (reaction, count) => {
|
||||
assert.equal(reaction, our_reaction);
|
||||
assert.equal(reaction, $our_reaction);
|
||||
assert.equal(count, 2);
|
||||
});
|
||||
|
||||
reactions.view.remove_reaction(opts);
|
||||
|
||||
assert.ok(!our_reaction.hasClass("reacted"));
|
||||
assert.ok(!$our_reaction.hasClass("reacted"));
|
||||
assert.equal(
|
||||
our_reaction.attr("aria-label"),
|
||||
$our_reaction.attr("aria-label"),
|
||||
"translated: Bob van Roberts and Cali reacted with :8ball:",
|
||||
);
|
||||
});
|
||||
@@ -793,26 +793,26 @@ test("view.remove_reaction (them)", ({override_rewire}) => {
|
||||
user_list: [alice.user_id],
|
||||
};
|
||||
|
||||
const our_reaction = $.create("our-reaction-stub");
|
||||
our_reaction.addClass("reacted");
|
||||
const $our_reaction = $.create("our-reaction-stub");
|
||||
$our_reaction.addClass("reacted");
|
||||
|
||||
override_rewire(reactions, "find_reaction", (message_id, local_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
assert.equal(local_id, "unicode_emoji,1f3b1");
|
||||
return our_reaction;
|
||||
return $our_reaction;
|
||||
});
|
||||
|
||||
override_rewire(reactions, "set_reaction_count", (reaction, count) => {
|
||||
assert.equal(reaction, our_reaction);
|
||||
assert.equal(reaction, $our_reaction);
|
||||
assert.equal(count, 1);
|
||||
});
|
||||
|
||||
our_reaction.addClass("reacted");
|
||||
$our_reaction.addClass("reacted");
|
||||
reactions.view.remove_reaction(opts);
|
||||
|
||||
assert.ok(our_reaction.hasClass("reacted"));
|
||||
assert.ok($our_reaction.hasClass("reacted"));
|
||||
assert.equal(
|
||||
our_reaction.attr("aria-label"),
|
||||
$our_reaction.attr("aria-label"),
|
||||
"translated: You (click to remove) reacted with :8ball:",
|
||||
);
|
||||
});
|
||||
@@ -827,16 +827,16 @@ test("view.remove_reaction (last person)", ({override_rewire}) => {
|
||||
user_list: [],
|
||||
};
|
||||
|
||||
const our_reaction = $.create("our-reaction-stub");
|
||||
const $our_reaction = $.create("our-reaction-stub");
|
||||
|
||||
override_rewire(reactions, "find_reaction", (message_id, local_id) => {
|
||||
assert.equal(message_id, opts.message_id);
|
||||
assert.equal(local_id, "unicode_emoji,1f3b1");
|
||||
return our_reaction;
|
||||
return $our_reaction;
|
||||
});
|
||||
|
||||
let removed;
|
||||
our_reaction.remove = () => {
|
||||
$our_reaction.remove = () => {
|
||||
removed = true;
|
||||
};
|
||||
reactions.view.remove_reaction(opts);
|
||||
|
||||
@@ -323,9 +323,9 @@ function stub_out_filter_buttons() {
|
||||
// See show_selected_filters() and set_filter() in the
|
||||
// implementation.
|
||||
for (const filter of ["all", "unread", "muted", "participated"]) {
|
||||
const stub = $.create(`filter-${filter}-stub`);
|
||||
const $stub = $.create(`filter-${filter}-stub`);
|
||||
const selector = `[data-filter="${filter}"]`;
|
||||
$("#recent_topics_filter_buttons").set_find_results(selector, stub);
|
||||
$("#recent_topics_filter_buttons").set_find_results(selector, $stub);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,12 +104,12 @@ const get_content_element = () => {
|
||||
};
|
||||
|
||||
run_test("misc_helpers", () => {
|
||||
const elem = $.create("user-mention");
|
||||
rm.set_name_in_mention_element(elem, "Aaron");
|
||||
assert.equal(elem.text(), "@Aaron");
|
||||
elem.addClass("silent");
|
||||
rm.set_name_in_mention_element(elem, "Aaron, but silent");
|
||||
assert.equal(elem.text(), "Aaron, but silent");
|
||||
const $elem = $.create("user-mention");
|
||||
rm.set_name_in_mention_element($elem, "Aaron");
|
||||
assert.equal($elem.text(), "@Aaron");
|
||||
$elem.addClass("silent");
|
||||
rm.set_name_in_mention_element($elem, "Aaron, but silent");
|
||||
assert.equal($elem.text(), "Aaron, but silent");
|
||||
});
|
||||
|
||||
run_test("user-mention", () => {
|
||||
@@ -423,8 +423,8 @@ function test_code_playground(mock_template, viewing_code) {
|
||||
|
||||
return {
|
||||
prepends,
|
||||
copy_code: $copy_code_button,
|
||||
view_code: $view_code_in_playground,
|
||||
$copy_code: $copy_code_button,
|
||||
$view_code: $view_code_in_playground,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -434,12 +434,12 @@ run_test("code playground none", ({override, mock_template}) => {
|
||||
return undefined;
|
||||
});
|
||||
|
||||
const {prepends, copy_code, view_code} = test_code_playground(mock_template, false);
|
||||
assert.deepEqual(prepends, [copy_code]);
|
||||
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, false);
|
||||
assert.deepEqual(prepends, [$copy_code]);
|
||||
assert_clipboard_setup();
|
||||
|
||||
assert.equal(view_code.attr("data-tippy-content"), undefined);
|
||||
assert.equal(view_code.attr("aria-label"), undefined);
|
||||
assert.equal($view_code.attr("data-tippy-content"), undefined);
|
||||
assert.equal($view_code.attr("aria-label"), undefined);
|
||||
});
|
||||
|
||||
run_test("code playground single", ({override, mock_template}) => {
|
||||
@@ -448,16 +448,16 @@ run_test("code playground single", ({override, mock_template}) => {
|
||||
return [{name: "Some Javascript Playground"}];
|
||||
});
|
||||
|
||||
const {prepends, copy_code, view_code} = test_code_playground(mock_template, true);
|
||||
assert.deepEqual(prepends, [view_code, copy_code]);
|
||||
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, true);
|
||||
assert.deepEqual(prepends, [$view_code, $copy_code]);
|
||||
assert_clipboard_setup();
|
||||
|
||||
assert.equal(
|
||||
view_code.attr("data-tippy-content"),
|
||||
$view_code.attr("data-tippy-content"),
|
||||
"translated: View in Some Javascript Playground",
|
||||
);
|
||||
assert.equal(view_code.attr("aria-label"), "translated: View in Some Javascript Playground");
|
||||
assert.equal(view_code.attr("aria-haspopup"), undefined);
|
||||
assert.equal($view_code.attr("aria-label"), "translated: View in Some Javascript Playground");
|
||||
assert.equal($view_code.attr("aria-haspopup"), undefined);
|
||||
});
|
||||
|
||||
run_test("code playground multiple", ({override, mock_template}) => {
|
||||
@@ -466,13 +466,13 @@ run_test("code playground multiple", ({override, mock_template}) => {
|
||||
return ["whatever", "whatever"];
|
||||
});
|
||||
|
||||
const {prepends, copy_code, view_code} = test_code_playground(mock_template, true);
|
||||
assert.deepEqual(prepends, [view_code, copy_code]);
|
||||
const {prepends, $copy_code, $view_code} = test_code_playground(mock_template, true);
|
||||
assert.deepEqual(prepends, [$view_code, $copy_code]);
|
||||
assert_clipboard_setup();
|
||||
|
||||
assert.equal(view_code.attr("data-tippy-content"), "translated: View in playground");
|
||||
assert.equal(view_code.attr("aria-label"), "translated: View in playground");
|
||||
assert.equal(view_code.attr("aria-haspopup"), "true");
|
||||
assert.equal($view_code.attr("data-tippy-content"), "translated: View in playground");
|
||||
assert.equal($view_code.attr("aria-label"), "translated: View in playground");
|
||||
assert.equal($view_code.attr("aria-haspopup"), "true");
|
||||
});
|
||||
|
||||
run_test("rtl", () => {
|
||||
|
||||
@@ -129,20 +129,20 @@ run_test("get_direction", () => {
|
||||
});
|
||||
|
||||
run_test("set_rtl_class_for_textarea rtl", () => {
|
||||
const textarea = $.create("some-textarea");
|
||||
assert.ok(!textarea.hasClass("rtl"));
|
||||
const $textarea = $.create("some-textarea");
|
||||
assert.ok(!$textarea.hasClass("rtl"));
|
||||
const text = "```quote\nمرحبا";
|
||||
textarea.val(text);
|
||||
rtl.set_rtl_class_for_textarea(textarea);
|
||||
assert.ok(textarea.hasClass("rtl"));
|
||||
$textarea.val(text);
|
||||
rtl.set_rtl_class_for_textarea($textarea);
|
||||
assert.ok($textarea.hasClass("rtl"));
|
||||
});
|
||||
|
||||
run_test("set_rtl_class_for_textarea ltr", () => {
|
||||
const textarea = $.create("some-textarea");
|
||||
textarea.addClass("rtl");
|
||||
assert.ok(textarea.hasClass("rtl"));
|
||||
const $textarea = $.create("some-textarea");
|
||||
$textarea.addClass("rtl");
|
||||
assert.ok($textarea.hasClass("rtl"));
|
||||
const text = "```quote\nEnglish text";
|
||||
textarea.val(text);
|
||||
rtl.set_rtl_class_for_textarea(textarea);
|
||||
assert.ok(!textarea.hasClass("rtl"));
|
||||
$textarea.val(text);
|
||||
rtl.set_rtl_class_for_textarea($textarea);
|
||||
assert.ok(!$textarea.hasClass("rtl"));
|
||||
});
|
||||
|
||||
@@ -89,7 +89,7 @@ run_test("scroll_delta", () => {
|
||||
});
|
||||
|
||||
run_test("scroll_element_into_container", () => {
|
||||
const container = (function () {
|
||||
const $container = (function () {
|
||||
let top = 3;
|
||||
return {
|
||||
height: () => 100,
|
||||
@@ -103,21 +103,21 @@ run_test("scroll_element_into_container", () => {
|
||||
};
|
||||
})();
|
||||
|
||||
const elem1 = {
|
||||
const $elem1 = {
|
||||
innerHeight: () => 25,
|
||||
position: () => ({
|
||||
top: 0,
|
||||
}),
|
||||
};
|
||||
scroll_util.scroll_element_into_container(elem1, container);
|
||||
assert.equal(container.scrollTop(), 3);
|
||||
scroll_util.scroll_element_into_container($elem1, $container);
|
||||
assert.equal($container.scrollTop(), 3);
|
||||
|
||||
const elem2 = {
|
||||
const $elem2 = {
|
||||
innerHeight: () => 15,
|
||||
position: () => ({
|
||||
top: 250,
|
||||
}),
|
||||
};
|
||||
scroll_util.scroll_element_into_container(elem2, container);
|
||||
assert.equal(container.scrollTop(), 250 - 100 + 3 + 15);
|
||||
scroll_util.scroll_element_into_container($elem2, $container);
|
||||
assert.equal($container.scrollTop(), 250 - 100 + 3 + 15);
|
||||
});
|
||||
|
||||
@@ -51,50 +51,50 @@ test("clear_search_form", () => {
|
||||
});
|
||||
|
||||
test("update_button_visibility", () => {
|
||||
const search_query = $("#search_query");
|
||||
const search_button = $(".search_button");
|
||||
const $search_query = $("#search_query");
|
||||
const $search_button = $(".search_button");
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(search_button.prop("disabled"));
|
||||
assert.ok($search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => true;
|
||||
search_query.val("");
|
||||
$search_query.is = () => true;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("Test search term");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("Test search term");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => true;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
});
|
||||
|
||||
test("initialize", () => {
|
||||
const search_query_box = $("#search_query");
|
||||
const searchbox_form = $("#searchbox_form");
|
||||
const search_button = $(".search_button");
|
||||
const searchbox = $("#searchbox");
|
||||
const $search_query_box = $("#search_query");
|
||||
const $searchbox_form = $("#searchbox_form");
|
||||
const $search_button = $(".search_button");
|
||||
const $searchbox = $("#searchbox");
|
||||
|
||||
search_query_box[0] = "stub";
|
||||
$search_query_box[0] = "stub";
|
||||
|
||||
search_pill.get_search_string_for_current_filter = () => "is:starred";
|
||||
|
||||
search_suggestion.max_num_of_search_results = 99;
|
||||
search_query_box.typeahead = (opts) => {
|
||||
$search_query_box.typeahead = (opts) => {
|
||||
assert.equal(opts.fixed, true);
|
||||
assert.equal(opts.items, 99);
|
||||
assert.equal(opts.naturalSearch, true);
|
||||
@@ -144,7 +144,7 @@ test("initialize", () => {
|
||||
let operators;
|
||||
let is_blurred;
|
||||
let is_append_search_string_called;
|
||||
search_query_box.on("blur", () => {
|
||||
$search_query_box.on("blur", () => {
|
||||
is_blurred = true;
|
||||
});
|
||||
search_pill.append_search_string = () => {
|
||||
@@ -154,7 +154,7 @@ test("initialize", () => {
|
||||
const _setup = (search_box_val) => {
|
||||
is_blurred = false;
|
||||
is_append_search_string_called = false;
|
||||
search_query_box.val(search_box_val);
|
||||
$search_query_box.val(search_box_val);
|
||||
Filter.parse = (search_string) => {
|
||||
assert.equal(search_string, search_box_val);
|
||||
return operators;
|
||||
@@ -199,34 +199,35 @@ test("initialize", () => {
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(is_append_search_string_called);
|
||||
|
||||
search_query_box.off("blur");
|
||||
$search_query_box.off("blur");
|
||||
}
|
||||
};
|
||||
|
||||
search.initialize();
|
||||
|
||||
const search_pill_stub = $.create(".pill");
|
||||
search_pill_stub.closest = () => ({data: noop});
|
||||
const $search_pill_stub = $.create(".pill");
|
||||
$search_pill_stub.closest = () => ({data: noop});
|
||||
const stub_event = {
|
||||
relatedTarget: search_pill_stub,
|
||||
// FIXME: event.relatedTarget should not be a jQuery object
|
||||
relatedTarget: $search_pill_stub,
|
||||
};
|
||||
search_query_box.val("test string");
|
||||
$search_query_box.val("test string");
|
||||
narrow_state.search_string = () => "ver";
|
||||
search_query_box.trigger(new $.Event("blur", stub_event));
|
||||
assert.equal(search_query_box.val(), "test string");
|
||||
$search_query_box.trigger(new $.Event("blur", stub_event));
|
||||
assert.equal($search_query_box.val(), "test string");
|
||||
|
||||
let css_args;
|
||||
searchbox.css = (args) => {
|
||||
$searchbox.css = (args) => {
|
||||
css_args = args;
|
||||
};
|
||||
searchbox.trigger("focusout");
|
||||
$searchbox.trigger("focusout");
|
||||
assert.deepEqual(css_args, {"box-shadow": "unset"});
|
||||
|
||||
search.__Rewire__("is_using_input_method", false);
|
||||
searchbox_form.trigger("compositionend");
|
||||
$searchbox_form.trigger("compositionend");
|
||||
assert.ok(search.is_using_input_method);
|
||||
|
||||
const keydown = searchbox_form.get_on_handler("keydown");
|
||||
const keydown = $searchbox_form.get_on_handler("keydown");
|
||||
let default_prevented = false;
|
||||
let ev = {
|
||||
type: "keydown",
|
||||
@@ -235,7 +236,7 @@ test("initialize", () => {
|
||||
default_prevented = true;
|
||||
},
|
||||
};
|
||||
search_query_box.is = () => false;
|
||||
$search_query_box.is = () => false;
|
||||
assert.equal(keydown(ev), undefined);
|
||||
assert.ok(!default_prevented);
|
||||
|
||||
@@ -244,22 +245,22 @@ test("initialize", () => {
|
||||
assert.ok(!default_prevented);
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
$search_query_box.is = () => true;
|
||||
assert.equal(keydown(ev), undefined);
|
||||
assert.ok(default_prevented);
|
||||
|
||||
let operators;
|
||||
let is_blurred;
|
||||
narrow_state.active = () => false;
|
||||
search_query_box.off("blur");
|
||||
search_query_box.on("blur", () => {
|
||||
$search_query_box.off("blur");
|
||||
$search_query_box.on("blur", () => {
|
||||
is_blurred = true;
|
||||
});
|
||||
|
||||
const _setup = (search_box_val) => {
|
||||
is_blurred = false;
|
||||
search_button.prop("disabled", false);
|
||||
search_query_box.val(search_box_val);
|
||||
$search_button.prop("disabled", false);
|
||||
$search_query_box.val(search_box_val);
|
||||
Filter.parse = (search_string) => {
|
||||
assert.equal(search_string, search_box_val);
|
||||
return operators;
|
||||
@@ -284,41 +285,41 @@ test("initialize", () => {
|
||||
type: "keyup",
|
||||
which: 15,
|
||||
};
|
||||
search_query_box.is = () => false;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => false;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => true;
|
||||
$searchbox_form.trigger(ev);
|
||||
assert.ok(is_blurred);
|
||||
|
||||
_setup("ver");
|
||||
search.__Rewire__("is_using_input_method", true);
|
||||
searchbox_form.trigger(ev);
|
||||
$searchbox_form.trigger(ev);
|
||||
// No change on Enter keyup event when using input tool
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
_setup("ver");
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => true;
|
||||
$searchbox_form.trigger(ev);
|
||||
assert.ok(is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_button.prop("disabled", true);
|
||||
search_query_box.trigger("focus");
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
$search_button.prop("disabled", true);
|
||||
$search_query_box.trigger("focus");
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
});
|
||||
|
||||
test("initiate_search", () => {
|
||||
@@ -345,9 +346,9 @@ test("initiate_search", () => {
|
||||
|
||||
$("#search_query")[0] = "stub";
|
||||
|
||||
const searchbox = $("#searchbox");
|
||||
const $searchbox = $("#searchbox");
|
||||
let css_args;
|
||||
searchbox.css = (args) => {
|
||||
$searchbox.css = (args) => {
|
||||
css_args = args;
|
||||
};
|
||||
|
||||
|
||||
@@ -29,45 +29,45 @@ set_global("setTimeout", (func) => func());
|
||||
const search = zrequire("search");
|
||||
|
||||
run_test("update_button_visibility", () => {
|
||||
const search_query = $("#search_query");
|
||||
const search_button = $(".search_button");
|
||||
const $search_query = $("#search_query");
|
||||
const $search_button = $(".search_button");
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(search_button.prop("disabled"));
|
||||
assert.ok($search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => true;
|
||||
search_query.val("");
|
||||
$search_query.is = () => true;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("Test search term");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("Test search term");
|
||||
narrow_state.active = () => false;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_query.is = () => false;
|
||||
search_query.val("");
|
||||
$search_query.is = () => false;
|
||||
$search_query.val("");
|
||||
narrow_state.active = () => true;
|
||||
search_button.prop("disabled", true);
|
||||
$search_button.prop("disabled", true);
|
||||
search.update_button_visibility();
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
});
|
||||
|
||||
run_test("initialize", () => {
|
||||
const search_query_box = $("#search_query");
|
||||
const searchbox_form = $("#searchbox_form");
|
||||
const search_button = $(".search_button");
|
||||
const $search_query_box = $("#search_query");
|
||||
const $searchbox_form = $("#searchbox_form");
|
||||
const $search_button = $(".search_button");
|
||||
|
||||
search_suggestion.max_num_of_search_results = 999;
|
||||
search_query_box.typeahead = (opts) => {
|
||||
$search_query_box.typeahead = (opts) => {
|
||||
assert.equal(opts.fixed, true);
|
||||
assert.equal(opts.items, 999);
|
||||
assert.equal(opts.naturalSearch, true);
|
||||
@@ -115,13 +115,13 @@ run_test("initialize", () => {
|
||||
{
|
||||
let operators;
|
||||
let is_blurred;
|
||||
search_query_box.on("blur", () => {
|
||||
$search_query_box.on("blur", () => {
|
||||
is_blurred = true;
|
||||
});
|
||||
/* Test updater */
|
||||
const _setup = (search_box_val) => {
|
||||
is_blurred = false;
|
||||
search_query_box.val(search_box_val);
|
||||
$search_query_box.val(search_box_val);
|
||||
Filter.parse = (search_string) => {
|
||||
assert.equal(search_string, search_box_val);
|
||||
return operators;
|
||||
@@ -159,26 +159,26 @@ run_test("initialize", () => {
|
||||
assert.equal(opts.updater("stream:Verona"), "stream:Verona");
|
||||
assert.ok(!is_blurred);
|
||||
|
||||
search_query_box.off("blur");
|
||||
$search_query_box.off("blur");
|
||||
}
|
||||
};
|
||||
|
||||
search.initialize();
|
||||
|
||||
search_button.prop("disabled", true);
|
||||
search_query_box.trigger("focus");
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
$search_button.prop("disabled", true);
|
||||
$search_query_box.trigger("focus");
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
search_query_box.val("test string");
|
||||
$search_query_box.val("test string");
|
||||
narrow_state.search_string = () => "ver";
|
||||
search_query_box.trigger("blur");
|
||||
assert.equal(search_query_box.val(), "test string");
|
||||
$search_query_box.trigger("blur");
|
||||
assert.equal($search_query_box.val(), "test string");
|
||||
|
||||
search.__Rewire__("is_using_input_method", false);
|
||||
searchbox_form.trigger("compositionend");
|
||||
$searchbox_form.trigger("compositionend");
|
||||
assert.ok(search.is_using_input_method);
|
||||
|
||||
const keydown = searchbox_form.get_on_handler("keydown");
|
||||
const keydown = $searchbox_form.get_on_handler("keydown");
|
||||
let default_prevented = false;
|
||||
let ev = {
|
||||
type: "keydown",
|
||||
@@ -187,7 +187,7 @@ run_test("initialize", () => {
|
||||
default_prevented = true;
|
||||
},
|
||||
};
|
||||
search_query_box.is = () => false;
|
||||
$search_query_box.is = () => false;
|
||||
assert.equal(keydown(ev), undefined);
|
||||
assert.ok(!default_prevented);
|
||||
|
||||
@@ -196,7 +196,7 @@ run_test("initialize", () => {
|
||||
assert.ok(!default_prevented);
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
$search_query_box.is = () => true;
|
||||
assert.equal(keydown(ev), undefined);
|
||||
assert.ok(default_prevented);
|
||||
|
||||
@@ -206,15 +206,15 @@ run_test("initialize", () => {
|
||||
let operators;
|
||||
let is_blurred;
|
||||
narrow_state.active = () => false;
|
||||
search_query_box.off("blur");
|
||||
search_query_box.on("blur", () => {
|
||||
$search_query_box.off("blur");
|
||||
$search_query_box.on("blur", () => {
|
||||
is_blurred = true;
|
||||
});
|
||||
|
||||
const _setup = (search_box_val) => {
|
||||
is_blurred = false;
|
||||
search_button.prop("disabled", false);
|
||||
search_query_box.val(search_box_val);
|
||||
$search_button.prop("disabled", false);
|
||||
$search_query_box.val(search_box_val);
|
||||
Filter.parse = (search_string) => {
|
||||
assert.equal(search_string, search_box_val);
|
||||
return operators;
|
||||
@@ -235,37 +235,37 @@ run_test("initialize", () => {
|
||||
_setup("");
|
||||
|
||||
ev.key = "a";
|
||||
search_query_box.is = () => false;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => false;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => false;
|
||||
$searchbox_form.trigger(ev);
|
||||
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => true;
|
||||
$searchbox_form.trigger(ev);
|
||||
assert.ok(is_blurred);
|
||||
|
||||
_setup("ver");
|
||||
search.__Rewire__("is_using_input_method", true);
|
||||
searchbox_form.trigger(ev);
|
||||
$searchbox_form.trigger(ev);
|
||||
// No change on Enter keyup event when using input tool
|
||||
assert.ok(!is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
|
||||
_setup("ver");
|
||||
ev.key = "Enter";
|
||||
search_query_box.is = () => true;
|
||||
searchbox_form.trigger(ev);
|
||||
$search_query_box.is = () => true;
|
||||
$searchbox_form.trigger(ev);
|
||||
assert.ok(is_blurred);
|
||||
assert.ok(!search_button.prop("disabled"));
|
||||
assert.ok(!$search_button.prop("disabled"));
|
||||
});
|
||||
|
||||
run_test("initiate_search", () => {
|
||||
|
||||
@@ -91,32 +91,32 @@ test("generate_botserverrc_content", () => {
|
||||
});
|
||||
|
||||
function test_create_bot_type_input_box_toggle(f) {
|
||||
const create_payload_url = $("#create_payload_url");
|
||||
const payload_url_inputbox = $("#payload_url_inputbox");
|
||||
const config_inputbox = $("#config_inputbox");
|
||||
const $create_payload_url = $("#create_payload_url");
|
||||
const $payload_url_inputbox = $("#payload_url_inputbox");
|
||||
const $config_inputbox = $("#config_inputbox");
|
||||
const EMBEDDED_BOT_TYPE = "4";
|
||||
const OUTGOING_WEBHOOK_BOT_TYPE = "3";
|
||||
const GENERIC_BOT_TYPE = "1";
|
||||
|
||||
$("#create_bot_type :selected").val(EMBEDDED_BOT_TYPE);
|
||||
f();
|
||||
assert.ok(!create_payload_url.hasClass("required"));
|
||||
assert.ok(!payload_url_inputbox.visible());
|
||||
assert.ok(!$create_payload_url.hasClass("required"));
|
||||
assert.ok(!$payload_url_inputbox.visible());
|
||||
assert.ok($("#select_service_name").hasClass("required"));
|
||||
assert.ok($("#service_name_list").visible());
|
||||
assert.ok(config_inputbox.visible());
|
||||
assert.ok($config_inputbox.visible());
|
||||
|
||||
$("#create_bot_type :selected").val(OUTGOING_WEBHOOK_BOT_TYPE);
|
||||
f();
|
||||
assert.ok(create_payload_url.hasClass("required"));
|
||||
assert.ok(payload_url_inputbox.visible());
|
||||
assert.ok(!config_inputbox.visible());
|
||||
assert.ok($create_payload_url.hasClass("required"));
|
||||
assert.ok($payload_url_inputbox.visible());
|
||||
assert.ok(!$config_inputbox.visible());
|
||||
|
||||
$("#create_bot_type :selected").val(GENERIC_BOT_TYPE);
|
||||
f();
|
||||
assert.ok(!create_payload_url.hasClass("required"));
|
||||
assert.ok(!payload_url_inputbox.visible());
|
||||
assert.ok(!config_inputbox.visible());
|
||||
assert.ok(!$create_payload_url.hasClass("required"));
|
||||
assert.ok(!$payload_url_inputbox.visible());
|
||||
assert.ok(!$config_inputbox.visible());
|
||||
}
|
||||
|
||||
test("test tab clicks", ({override}) => {
|
||||
@@ -125,10 +125,10 @@ test("test tab clicks", ({override}) => {
|
||||
$("#create_bot_form").validate = () => {};
|
||||
|
||||
$("#config_inputbox").children = () => {
|
||||
const mock_children = {
|
||||
const $mock_children = {
|
||||
hide: () => {},
|
||||
};
|
||||
return mock_children;
|
||||
return $mock_children;
|
||||
};
|
||||
|
||||
override(avatar, "build_bot_create_widget", () => {});
|
||||
@@ -137,55 +137,55 @@ test("test tab clicks", ({override}) => {
|
||||
|
||||
test_create_bot_type_input_box_toggle(() => $("#create_bot_type").trigger("change"));
|
||||
|
||||
function click_on_tab(tab_elem) {
|
||||
tab_elem.trigger("click");
|
||||
function click_on_tab($tab_elem) {
|
||||
$tab_elem.trigger("click");
|
||||
}
|
||||
|
||||
const tabs = {
|
||||
add: $("#bots_lists_navbar .add-a-new-bot-tab"),
|
||||
active: $("#bots_lists_navbar .active-bots-tab"),
|
||||
inactive: $("#bots_lists_navbar .inactive-bots-tab"),
|
||||
$add: $("#bots_lists_navbar .add-a-new-bot-tab"),
|
||||
$active: $("#bots_lists_navbar .active-bots-tab"),
|
||||
$inactive: $("#bots_lists_navbar .inactive-bots-tab"),
|
||||
};
|
||||
|
||||
$("#bots_lists_navbar .active").removeClass = (cls) => {
|
||||
assert.equal(cls, "active");
|
||||
for (const tab of Object.values(tabs)) {
|
||||
tab.removeClass("active");
|
||||
for (const $tab of Object.values(tabs)) {
|
||||
$tab.removeClass("active");
|
||||
}
|
||||
};
|
||||
|
||||
const forms = {
|
||||
add: $("#add-a-new-bot-form"),
|
||||
active: $("#active_bots_list"),
|
||||
inactive: $("#inactive_bots_list"),
|
||||
$add: $("#add-a-new-bot-form"),
|
||||
$active: $("#active_bots_list"),
|
||||
$inactive: $("#inactive_bots_list"),
|
||||
};
|
||||
|
||||
click_on_tab(tabs.add);
|
||||
assert.ok(tabs.add.hasClass("active"));
|
||||
assert.ok(!tabs.active.hasClass("active"));
|
||||
assert.ok(!tabs.inactive.hasClass("active"));
|
||||
click_on_tab(tabs.$add);
|
||||
assert.ok(tabs.$add.hasClass("active"));
|
||||
assert.ok(!tabs.$active.hasClass("active"));
|
||||
assert.ok(!tabs.$inactive.hasClass("active"));
|
||||
|
||||
assert.ok(forms.add.visible());
|
||||
assert.ok(!forms.active.visible());
|
||||
assert.ok(!forms.inactive.visible());
|
||||
assert.ok(forms.$add.visible());
|
||||
assert.ok(!forms.$active.visible());
|
||||
assert.ok(!forms.$inactive.visible());
|
||||
|
||||
click_on_tab(tabs.active);
|
||||
assert.ok(!tabs.add.hasClass("active"));
|
||||
assert.ok(tabs.active.hasClass("active"));
|
||||
assert.ok(!tabs.inactive.hasClass("active"));
|
||||
click_on_tab(tabs.$active);
|
||||
assert.ok(!tabs.$add.hasClass("active"));
|
||||
assert.ok(tabs.$active.hasClass("active"));
|
||||
assert.ok(!tabs.$inactive.hasClass("active"));
|
||||
|
||||
assert.ok(!forms.add.visible());
|
||||
assert.ok(forms.active.visible());
|
||||
assert.ok(!forms.inactive.visible());
|
||||
assert.ok(!forms.$add.visible());
|
||||
assert.ok(forms.$active.visible());
|
||||
assert.ok(!forms.$inactive.visible());
|
||||
|
||||
click_on_tab(tabs.inactive);
|
||||
assert.ok(!tabs.add.hasClass("active"));
|
||||
assert.ok(!tabs.active.hasClass("active"));
|
||||
assert.ok(tabs.inactive.hasClass("active"));
|
||||
click_on_tab(tabs.$inactive);
|
||||
assert.ok(!tabs.$add.hasClass("active"));
|
||||
assert.ok(!tabs.$active.hasClass("active"));
|
||||
assert.ok(tabs.$inactive.hasClass("active"));
|
||||
|
||||
assert.ok(!forms.add.visible());
|
||||
assert.ok(!forms.active.visible());
|
||||
assert.ok(forms.inactive.visible());
|
||||
assert.ok(!forms.$add.visible());
|
||||
assert.ok(!forms.$active.visible());
|
||||
assert.ok(forms.$inactive.visible());
|
||||
});
|
||||
|
||||
test("can_create_new_bots", () => {
|
||||
|
||||
@@ -51,15 +51,15 @@ run_test("settings", ({override_rewire}) => {
|
||||
stopPropagation: noop,
|
||||
};
|
||||
|
||||
const topic_fake_this = $.create("fake.settings-unmute-topic");
|
||||
const topic_tr_html = $('tr[data-topic="js"]');
|
||||
topic_fake_this.closest = (opts) => {
|
||||
const $topic_fake_this = $.create("fake.settings-unmute-topic");
|
||||
const $topic_tr_html = $('tr[data-topic="js"]');
|
||||
$topic_fake_this.closest = (opts) => {
|
||||
assert.equal(opts, "tr");
|
||||
return topic_tr_html;
|
||||
return $topic_tr_html;
|
||||
};
|
||||
|
||||
let topic_data_called = 0;
|
||||
topic_tr_html.attr = (opts) => {
|
||||
$topic_tr_html.attr = (opts) => {
|
||||
if (opts === "data-stream-id") {
|
||||
topic_data_called += 1;
|
||||
return frontend.stream_id;
|
||||
@@ -77,7 +77,7 @@ run_test("settings", ({override_rewire}) => {
|
||||
assert.equal(topic, "js");
|
||||
unmute_topic_called = true;
|
||||
};
|
||||
topic_click_handler.call(topic_fake_this, event);
|
||||
topic_click_handler.call($topic_fake_this, event);
|
||||
assert.ok(unmute_topic_called);
|
||||
assert.equal(topic_data_called, 2);
|
||||
});
|
||||
|
||||
@@ -42,15 +42,15 @@ run_test("settings", ({override_rewire}) => {
|
||||
stopPropagation: noop,
|
||||
};
|
||||
|
||||
const unmute_button = $.create("settings-unmute-user");
|
||||
const fake_row = $('tr[data-user-id="5"]');
|
||||
unmute_button.closest = (opts) => {
|
||||
const $unmute_button = $.create("settings-unmute-user");
|
||||
const $fake_row = $('tr[data-user-id="5"]');
|
||||
$unmute_button.closest = (opts) => {
|
||||
assert.equal(opts, "tr");
|
||||
return fake_row;
|
||||
return $fake_row;
|
||||
};
|
||||
|
||||
let row_attribute_fetched = false;
|
||||
fake_row.attr = (opts) => {
|
||||
$fake_row.attr = (opts) => {
|
||||
if (opts === "data-user-id") {
|
||||
row_attribute_fetched += 1;
|
||||
return "5";
|
||||
@@ -64,7 +64,7 @@ run_test("settings", ({override_rewire}) => {
|
||||
unmute_user_called = true;
|
||||
};
|
||||
|
||||
unmute_click_handler.call(unmute_button, event);
|
||||
unmute_click_handler.call($unmute_button, event);
|
||||
assert.ok(unmute_user_called);
|
||||
assert.ok(row_attribute_fetched);
|
||||
});
|
||||
|
||||
@@ -31,12 +31,12 @@ mock_esm("../../static/js/loading", {
|
||||
destroy_indicator: noop,
|
||||
});
|
||||
mock_esm("../../static/js/ui_report", {
|
||||
success(msg, elem) {
|
||||
elem.val(msg);
|
||||
success(msg, $elem) {
|
||||
$elem.val(msg);
|
||||
},
|
||||
|
||||
error(msg, xhr, elem) {
|
||||
elem.val(msg);
|
||||
error(msg, xhr, $elem) {
|
||||
$elem.val(msg);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -74,9 +74,9 @@ test("unloaded", () => {
|
||||
});
|
||||
|
||||
function simulate_realm_domains_table() {
|
||||
const tr_stub = $.create("realm-tr-stub");
|
||||
$("#realm_domains_table tbody").set_find_results("tr", tr_stub);
|
||||
tr_stub.remove = () => {};
|
||||
const $tr_stub = $.create("realm-tr-stub");
|
||||
$("#realm_domains_table tbody").set_find_results("tr", $tr_stub);
|
||||
$tr_stub.remove = () => {};
|
||||
|
||||
let appended;
|
||||
$("#realm_domains_table tbody").append = (html) => {
|
||||
@@ -90,7 +90,7 @@ function simulate_realm_domains_table() {
|
||||
}
|
||||
|
||||
function test_realms_domain_modal(override, add_realm_domain) {
|
||||
const info = $(".realm_domains_info");
|
||||
const $info = $(".realm_domains_info");
|
||||
|
||||
$("#add-realm-domain-widget").set_find_results(
|
||||
".new-realm-domain",
|
||||
@@ -117,46 +117,46 @@ function test_realms_domain_modal(override, add_realm_domain) {
|
||||
assert.ok(posted);
|
||||
|
||||
success_callback();
|
||||
assert.equal(info.val(), "translated HTML: Added successfully!");
|
||||
assert.equal($info.val(), "translated HTML: Added successfully!");
|
||||
|
||||
error_callback({});
|
||||
assert.equal(info.val(), "translated HTML: Failed");
|
||||
assert.equal($info.val(), "translated HTML: Failed");
|
||||
}
|
||||
|
||||
function createSaveButtons(subsection) {
|
||||
const stub_save_button_header = $(`#org-${CSS.escape(subsection)}`);
|
||||
const save_button_controls = $(".save-button-controls");
|
||||
const stub_save_button = $(`#org-submit-${CSS.escape(subsection)}`);
|
||||
const stub_discard_button = $(`#org-discard-${CSS.escape(subsection)}`);
|
||||
const stub_save_button_text = $(".save-discard-widget-button-text");
|
||||
stub_save_button_header.set_find_results(
|
||||
const $stub_save_button_header = $(`#org-${CSS.escape(subsection)}`);
|
||||
const $save_button_controls = $(".save-button-controls");
|
||||
const $stub_save_button = $(`#org-submit-${CSS.escape(subsection)}`);
|
||||
const $stub_discard_button = $(`#org-discard-${CSS.escape(subsection)}`);
|
||||
const $stub_save_button_text = $(".save-discard-widget-button-text");
|
||||
$stub_save_button_header.set_find_results(
|
||||
".subsection-failed-status p",
|
||||
$("<failed status element>"),
|
||||
);
|
||||
stub_save_button.closest = () => stub_save_button_header;
|
||||
save_button_controls.set_find_results(".save-button", stub_save_button);
|
||||
stub_save_button.set_find_results(".save-discard-widget-button-text", stub_save_button_text);
|
||||
stub_save_button_header.set_find_results(".save-button-controls", save_button_controls);
|
||||
stub_save_button_header.set_find_results(
|
||||
$stub_save_button.closest = () => $stub_save_button_header;
|
||||
$save_button_controls.set_find_results(".save-button", $stub_save_button);
|
||||
$stub_save_button.set_find_results(".save-discard-widget-button-text", $stub_save_button_text);
|
||||
$stub_save_button_header.set_find_results(".save-button-controls", $save_button_controls);
|
||||
$stub_save_button_header.set_find_results(
|
||||
".subsection-changes-discard button",
|
||||
$(`#org-discard-${CSS.escape(subsection)}`),
|
||||
);
|
||||
save_button_controls.set_find_results(".discard-button", stub_discard_button);
|
||||
$save_button_controls.set_find_results(".discard-button", $stub_discard_button);
|
||||
const props = {};
|
||||
props.hidden = false;
|
||||
save_button_controls.fadeIn = () => {
|
||||
$save_button_controls.fadeIn = () => {
|
||||
props.hidden = false;
|
||||
};
|
||||
save_button_controls.fadeOut = () => {
|
||||
$save_button_controls.fadeOut = () => {
|
||||
props.hidden = true;
|
||||
};
|
||||
return {
|
||||
props,
|
||||
save_button: stub_save_button,
|
||||
discard_button: stub_discard_button,
|
||||
save_button_header: stub_save_button_header,
|
||||
save_button_controls,
|
||||
save_button_text: stub_save_button_text,
|
||||
$save_button: $stub_save_button,
|
||||
$discard_button: $stub_discard_button,
|
||||
$save_button_header: $stub_save_button_header,
|
||||
$save_button_controls,
|
||||
$save_button_text: $stub_save_button_text,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -193,55 +193,55 @@ function test_submit_settings_form(override, submit_form) {
|
||||
let subsection = "other-permissions";
|
||||
ev.currentTarget = `#org-submit-${CSS.escape(subsection)}`;
|
||||
let stubs = createSaveButtons(subsection);
|
||||
let save_button = stubs.save_button;
|
||||
save_button.attr("id", `org-submit-${subsection}`);
|
||||
save_button.replace = () => `${subsection}`;
|
||||
let $save_button = stubs.$save_button;
|
||||
$save_button.attr("id", `org-submit-${subsection}`);
|
||||
$save_button.replace = () => `${subsection}`;
|
||||
|
||||
$("#id_realm_waiting_period_threshold").val(10);
|
||||
|
||||
const invite_to_stream_policy_elem = $("#id_realm_invite_to_stream_policy");
|
||||
invite_to_stream_policy_elem.val("1");
|
||||
invite_to_stream_policy_elem.attr("id", "id_realm_invite_to_stream_policy");
|
||||
invite_to_stream_policy_elem.data = () => "number";
|
||||
const $invite_to_stream_policy_elem = $("#id_realm_invite_to_stream_policy");
|
||||
$invite_to_stream_policy_elem.val("1");
|
||||
$invite_to_stream_policy_elem.attr("id", "id_realm_invite_to_stream_policy");
|
||||
$invite_to_stream_policy_elem.data = () => "number";
|
||||
|
||||
const create_public_stream_policy_elem = $("#id_realm_create_public_stream_policy");
|
||||
create_public_stream_policy_elem.val("2");
|
||||
create_public_stream_policy_elem.attr("id", "id_realm_create_public_stream_policy");
|
||||
create_public_stream_policy_elem.data = () => "number";
|
||||
const $create_public_stream_policy_elem = $("#id_realm_create_public_stream_policy");
|
||||
$create_public_stream_policy_elem.val("2");
|
||||
$create_public_stream_policy_elem.attr("id", "id_realm_create_public_stream_policy");
|
||||
$create_public_stream_policy_elem.data = () => "number";
|
||||
|
||||
const create_private_stream_policy_elem = $("#id_realm_create_private_stream_policy");
|
||||
create_private_stream_policy_elem.val("2");
|
||||
create_private_stream_policy_elem.attr("id", "id_realm_create_private_stream_policy");
|
||||
create_private_stream_policy_elem.data = () => "number";
|
||||
const $create_private_stream_policy_elem = $("#id_realm_create_private_stream_policy");
|
||||
$create_private_stream_policy_elem.val("2");
|
||||
$create_private_stream_policy_elem.attr("id", "id_realm_create_private_stream_policy");
|
||||
$create_private_stream_policy_elem.data = () => "number";
|
||||
|
||||
const add_custom_emoji_policy_elem = $("#id_realm_add_custom_emoji_policy");
|
||||
add_custom_emoji_policy_elem.val("1");
|
||||
add_custom_emoji_policy_elem.attr("id", "id_realm_add_custom_emoji_policy");
|
||||
add_custom_emoji_policy_elem.data = () => "number";
|
||||
const $add_custom_emoji_policy_elem = $("#id_realm_add_custom_emoji_policy");
|
||||
$add_custom_emoji_policy_elem.val("1");
|
||||
$add_custom_emoji_policy_elem.attr("id", "id_realm_add_custom_emoji_policy");
|
||||
$add_custom_emoji_policy_elem.data = () => "number";
|
||||
|
||||
const bot_creation_policy_elem = $("#id_realm_bot_creation_policy");
|
||||
bot_creation_policy_elem.val("1");
|
||||
bot_creation_policy_elem.attr("id", "id_realm_bot_creation_policy");
|
||||
bot_creation_policy_elem.data = () => "number";
|
||||
const email_address_visibility_elem = $("#id_realm_email_address_visibility");
|
||||
email_address_visibility_elem.val("1");
|
||||
email_address_visibility_elem.attr("id", "id_realm_email_address_visibility");
|
||||
email_address_visibility_elem.data = () => "number";
|
||||
const $bot_creation_policy_elem = $("#id_realm_bot_creation_policy");
|
||||
$bot_creation_policy_elem.val("1");
|
||||
$bot_creation_policy_elem.attr("id", "id_realm_bot_creation_policy");
|
||||
$bot_creation_policy_elem.data = () => "number";
|
||||
const $email_address_visibility_elem = $("#id_realm_email_address_visibility");
|
||||
$email_address_visibility_elem.val("1");
|
||||
$email_address_visibility_elem.attr("id", "id_realm_email_address_visibility");
|
||||
$email_address_visibility_elem.data = () => "number";
|
||||
|
||||
const invite_to_realm_policy_elem = $("#id_realm_invite_to_realm_policy");
|
||||
invite_to_realm_policy_elem.val("2");
|
||||
invite_to_realm_policy_elem.attr("id", "id_realm_invite_to_realm_policy");
|
||||
invite_to_realm_policy_elem.data = () => "number";
|
||||
const $invite_to_realm_policy_elem = $("#id_realm_invite_to_realm_policy");
|
||||
$invite_to_realm_policy_elem.val("2");
|
||||
$invite_to_realm_policy_elem.attr("id", "id_realm_invite_to_realm_policy");
|
||||
$invite_to_realm_policy_elem.data = () => "number";
|
||||
|
||||
let subsection_elem = $(`#org-${CSS.escape(subsection)}`);
|
||||
subsection_elem.closest = () => subsection_elem;
|
||||
subsection_elem.set_find_results(".prop-element", [
|
||||
bot_creation_policy_elem,
|
||||
email_address_visibility_elem,
|
||||
add_custom_emoji_policy_elem,
|
||||
create_public_stream_policy_elem,
|
||||
create_private_stream_policy_elem,
|
||||
invite_to_stream_policy_elem,
|
||||
let $subsection_elem = $(`#org-${CSS.escape(subsection)}`);
|
||||
$subsection_elem.closest = () => $subsection_elem;
|
||||
$subsection_elem.set_find_results(".prop-element", [
|
||||
$bot_creation_policy_elem,
|
||||
$email_address_visibility_elem,
|
||||
$add_custom_emoji_policy_elem,
|
||||
$create_public_stream_policy_elem,
|
||||
$create_private_stream_policy_elem,
|
||||
$invite_to_stream_policy_elem,
|
||||
]);
|
||||
|
||||
patched = false;
|
||||
@@ -261,17 +261,17 @@ function test_submit_settings_form(override, submit_form) {
|
||||
subsection = "user-defaults";
|
||||
ev.currentTarget = `#org-submit-${CSS.escape(subsection)}`;
|
||||
stubs = createSaveButtons(subsection);
|
||||
save_button = stubs.save_button;
|
||||
save_button.attr("id", `org-submit-${subsection}`);
|
||||
$save_button = stubs.$save_button;
|
||||
$save_button.attr("id", `org-submit-${subsection}`);
|
||||
|
||||
const realm_default_language_elem = $("#id_realm_default_language");
|
||||
realm_default_language_elem.val("en");
|
||||
realm_default_language_elem.attr("id", "id_realm_default_language");
|
||||
realm_default_language_elem.data = () => "string";
|
||||
const $realm_default_language_elem = $("#id_realm_default_language");
|
||||
$realm_default_language_elem.val("en");
|
||||
$realm_default_language_elem.attr("id", "id_realm_default_language");
|
||||
$realm_default_language_elem.data = () => "string";
|
||||
|
||||
subsection_elem = $(`#org-${CSS.escape(subsection)}`);
|
||||
subsection_elem.closest = () => subsection_elem;
|
||||
subsection_elem.set_find_results(".prop-element", [realm_default_language_elem]);
|
||||
$subsection_elem = $(`#org-${CSS.escape(subsection)}`);
|
||||
$subsection_elem.closest = () => $subsection_elem;
|
||||
$subsection_elem.set_find_results(".prop-element", [$realm_default_language_elem]);
|
||||
|
||||
submit_form(ev);
|
||||
assert.ok(patched);
|
||||
@@ -284,50 +284,50 @@ function test_submit_settings_form(override, submit_form) {
|
||||
// Testing only once for since callback is same for all cases
|
||||
success_callback();
|
||||
assert.equal(stubs.props.hidden, true);
|
||||
assert.equal(save_button.attr("data-status"), "saved");
|
||||
assert.equal(stubs.save_button_text.text(), "translated: Saved");
|
||||
assert.equal($save_button.attr("data-status"), "saved");
|
||||
assert.equal(stubs.$save_button_text.text(), "translated: Saved");
|
||||
}
|
||||
|
||||
function test_change_save_button_state() {
|
||||
const {save_button_controls, save_button_text, save_button, discard_button, props} =
|
||||
const {$save_button_controls, $save_button_text, $save_button, $discard_button, props} =
|
||||
createSaveButtons("msg-editing");
|
||||
save_button.attr("id", "org-submit-msg-editing");
|
||||
$save_button.attr("id", "org-submit-msg-editing");
|
||||
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "unsaved");
|
||||
assert.equal(save_button_text.text(), "translated: Save changes");
|
||||
settings_org.change_save_button_state($save_button_controls, "unsaved");
|
||||
assert.equal($save_button_text.text(), "translated: Save changes");
|
||||
assert.equal(props.hidden, false);
|
||||
assert.equal(save_button.attr("data-status"), "unsaved");
|
||||
assert.equal(discard_button.visible(), true);
|
||||
assert.equal($save_button.attr("data-status"), "unsaved");
|
||||
assert.equal($discard_button.visible(), true);
|
||||
}
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "saved");
|
||||
assert.equal(save_button_text.text(), "translated: Save changes");
|
||||
settings_org.change_save_button_state($save_button_controls, "saved");
|
||||
assert.equal($save_button_text.text(), "translated: Save changes");
|
||||
assert.equal(props.hidden, true);
|
||||
assert.equal(save_button.attr("data-status"), "");
|
||||
assert.equal($save_button.attr("data-status"), "");
|
||||
}
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "saving");
|
||||
assert.equal(save_button_text.text(), "translated: Saving");
|
||||
assert.equal(save_button.attr("data-status"), "saving");
|
||||
assert.equal(save_button.hasClass("saving"), true);
|
||||
assert.equal(discard_button.visible(), false);
|
||||
settings_org.change_save_button_state($save_button_controls, "saving");
|
||||
assert.equal($save_button_text.text(), "translated: Saving");
|
||||
assert.equal($save_button.attr("data-status"), "saving");
|
||||
assert.equal($save_button.hasClass("saving"), true);
|
||||
assert.equal($discard_button.visible(), false);
|
||||
}
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "discarded");
|
||||
settings_org.change_save_button_state($save_button_controls, "discarded");
|
||||
assert.equal(props.hidden, true);
|
||||
}
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "succeeded");
|
||||
settings_org.change_save_button_state($save_button_controls, "succeeded");
|
||||
assert.equal(props.hidden, true);
|
||||
assert.equal(save_button.attr("data-status"), "saved");
|
||||
assert.equal(save_button_text.text(), "translated: Saved");
|
||||
assert.equal($save_button.attr("data-status"), "saved");
|
||||
assert.equal($save_button_text.text(), "translated: Saved");
|
||||
}
|
||||
{
|
||||
settings_org.change_save_button_state(save_button_controls, "failed");
|
||||
settings_org.change_save_button_state($save_button_controls, "failed");
|
||||
assert.equal(props.hidden, false);
|
||||
assert.equal(save_button.attr("data-status"), "failed");
|
||||
assert.equal(save_button_text.text(), "translated: Save changes");
|
||||
assert.equal($save_button.attr("data-status"), "failed");
|
||||
assert.equal($save_button_text.text(), "translated: Save changes");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,8 +358,8 @@ function test_change_allow_subdomains(change_allow_subdomains) {
|
||||
stopPropagation: noop,
|
||||
};
|
||||
|
||||
const info = $(".realm_domains_info");
|
||||
info.fadeOut = noop;
|
||||
const $info = $(".realm_domains_info");
|
||||
$info.fadeOut = noop;
|
||||
const domain = "example.com";
|
||||
let allow = true;
|
||||
|
||||
@@ -372,33 +372,33 @@ function test_change_allow_subdomains(change_allow_subdomains) {
|
||||
error_callback = req.error;
|
||||
};
|
||||
|
||||
const domain_obj = $.create("domain object");
|
||||
domain_obj.text(domain);
|
||||
const $domain_obj = $.create("domain object");
|
||||
$domain_obj.text(domain);
|
||||
|
||||
const elem_obj = $.create("<elem html>");
|
||||
const parents_obj = $.create("parents object");
|
||||
const $elem_obj = $.create("<elem html>");
|
||||
const $parents_obj = $.create("parents object");
|
||||
|
||||
elem_obj.set_parents_result("tr", parents_obj);
|
||||
parents_obj.set_find_results(".domain", domain_obj);
|
||||
elem_obj.prop("checked", allow);
|
||||
$elem_obj.set_parents_result("tr", $parents_obj);
|
||||
$parents_obj.set_find_results(".domain", $domain_obj);
|
||||
$elem_obj.prop("checked", allow);
|
||||
|
||||
change_allow_subdomains.call(elem_obj, ev);
|
||||
change_allow_subdomains.call($elem_obj, ev);
|
||||
|
||||
success_callback();
|
||||
assert.equal(
|
||||
info.val(),
|
||||
$info.val(),
|
||||
"translated HTML: Update successful: Subdomains allowed for example.com",
|
||||
);
|
||||
|
||||
error_callback({});
|
||||
assert.equal(info.val(), "translated HTML: Failed");
|
||||
assert.equal($info.val(), "translated HTML: Failed");
|
||||
|
||||
allow = false;
|
||||
elem_obj.prop("checked", allow);
|
||||
change_allow_subdomains.call(elem_obj, ev);
|
||||
$elem_obj.prop("checked", allow);
|
||||
change_allow_subdomains.call($elem_obj, ev);
|
||||
success_callback();
|
||||
assert.equal(
|
||||
info.val(),
|
||||
$info.val(),
|
||||
"translated HTML: Update successful: Subdomains no longer allowed for example.com",
|
||||
);
|
||||
}
|
||||
@@ -431,9 +431,9 @@ function test_sync_realm_settings() {
|
||||
|
||||
{
|
||||
/* Test invalid settings property sync */
|
||||
const property_elem = $("#id_realm_invalid_settings_property");
|
||||
property_elem.attr("id", "id_realm_invalid_settings_property");
|
||||
property_elem.length = 1;
|
||||
const $property_elem = $("#id_realm_invalid_settings_property");
|
||||
$property_elem.attr("id", "id_realm_invalid_settings_property");
|
||||
$property_elem.length = 1;
|
||||
|
||||
blueslip.expect(
|
||||
"error",
|
||||
@@ -443,9 +443,9 @@ function test_sync_realm_settings() {
|
||||
}
|
||||
|
||||
function test_common_policy(property_name) {
|
||||
const property_elem = $(`#id_realm_${CSS.escape(property_name)}`);
|
||||
property_elem.length = 1;
|
||||
property_elem.attr("id", `id_realm_${CSS.escape(property_name)}`);
|
||||
const $property_elem = $(`#id_realm_${CSS.escape(property_name)}`);
|
||||
$property_elem.length = 1;
|
||||
$property_elem.attr("id", `id_realm_${CSS.escape(property_name)}`);
|
||||
|
||||
/* Each policy is initialized to 'by_members' and then all the values are tested
|
||||
in the following order - by_admins_only, by_moderators_only, by_full_members,
|
||||
@@ -453,14 +453,14 @@ function test_sync_realm_settings() {
|
||||
|
||||
page_params[`realm_${property_name}`] =
|
||||
settings_config.common_policy_values.by_members.code;
|
||||
property_elem.val(settings_config.common_policy_values.by_members.code);
|
||||
$property_elem.val(settings_config.common_policy_values.by_members.code);
|
||||
|
||||
for (const policy_value of Array.from(
|
||||
Object.values(settings_config.common_policy_values),
|
||||
)) {
|
||||
page_params[`realm_${property_name}`] = policy_value.code;
|
||||
settings_org.sync_realm_settings(property_name);
|
||||
assert.equal(property_elem.val(), policy_value.code);
|
||||
assert.equal($property_elem.val(), policy_value.code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,9 +471,9 @@ function test_sync_realm_settings() {
|
||||
|
||||
{
|
||||
/* Test message content edit limit minutes sync */
|
||||
const property_elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
property_elem.length = 1;
|
||||
property_elem.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
const $property_elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
$property_elem.length = 1;
|
||||
$property_elem.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
|
||||
page_params.realm_create_public_stream_policy = 1;
|
||||
page_params.realm_message_content_edit_limit_seconds = 120;
|
||||
@@ -484,9 +484,9 @@ function test_sync_realm_settings() {
|
||||
|
||||
{
|
||||
/* Test message content edit limit dropdown value sync */
|
||||
const property_elem = $("#id_realm_msg_edit_limit_setting");
|
||||
property_elem.length = 1;
|
||||
property_elem.attr("id", "id_realm_msg_edit_limit_setting");
|
||||
const $property_elem = $("#id_realm_msg_edit_limit_setting");
|
||||
$property_elem.length = 1;
|
||||
$property_elem.attr("id", "id_realm_msg_edit_limit_setting");
|
||||
|
||||
page_params.realm_allow_message_editing = false;
|
||||
page_params.realm_message_content_edit_limit_seconds = 120;
|
||||
@@ -506,9 +506,9 @@ function test_sync_realm_settings() {
|
||||
|
||||
{
|
||||
/* Test message content edit limit minutes sync */
|
||||
const property_elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
property_elem.length = 1;
|
||||
property_elem.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
const $property_elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
$property_elem.length = 1;
|
||||
$property_elem.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
|
||||
page_params.realm_create_public_stream_policy = 1;
|
||||
page_params.realm_message_content_edit_limit_seconds = 120;
|
||||
@@ -519,9 +519,9 @@ function test_sync_realm_settings() {
|
||||
|
||||
{
|
||||
/* Test organization joining restrictions settings sync */
|
||||
const property_elem = $("#id_realm_org_join_restrictions");
|
||||
property_elem.length = 1;
|
||||
property_elem.attr("id", "id_realm_org_join_restrictions");
|
||||
const $property_elem = $("#id_realm_org_join_restrictions");
|
||||
$property_elem.length = 1;
|
||||
$property_elem.attr("id", "id_realm_org_join_restrictions");
|
||||
|
||||
page_params.realm_emails_restricted_to_domains = true;
|
||||
page_params.realm_disallow_disposable_email_addresses = false;
|
||||
@@ -541,10 +541,10 @@ function test_sync_realm_settings() {
|
||||
}
|
||||
|
||||
function test_parse_time_limit() {
|
||||
const elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
const $elem = $("#id_realm_message_content_edit_limit_minutes");
|
||||
const test_function = (value, expected_value = value) => {
|
||||
elem.val(value);
|
||||
page_params.realm_message_content_edit_limit_seconds = settings_org.parse_time_limit(elem);
|
||||
$elem.val(value);
|
||||
page_params.realm_message_content_edit_limit_seconds = settings_org.parse_time_limit($elem);
|
||||
assert.equal(
|
||||
settings_org.get_realm_time_limits_in_minutes(
|
||||
"realm_message_content_edit_limit_seconds",
|
||||
@@ -587,40 +587,40 @@ function test_discard_changes_button(discard_changes) {
|
||||
settings_config.common_message_policy_values.by_everyone.code;
|
||||
page_params.realm_message_content_delete_limit_seconds = 120;
|
||||
|
||||
const allow_edit_history = $("#id_realm_allow_edit_history").prop("checked", false);
|
||||
const edit_topic_policy = $("#id_realm_edit_topic_policy").val(
|
||||
const $allow_edit_history = $("#id_realm_allow_edit_history").prop("checked", false);
|
||||
const $edit_topic_policy = $("#id_realm_edit_topic_policy").val(
|
||||
settings_config.common_message_policy_values.by_admins_only.code,
|
||||
);
|
||||
const msg_edit_limit_setting = $("#id_realm_msg_edit_limit_setting").val("custom_limit");
|
||||
const message_content_edit_limit_minutes = $(
|
||||
const $msg_edit_limit_setting = $("#id_realm_msg_edit_limit_setting").val("custom_limit");
|
||||
const $message_content_edit_limit_minutes = $(
|
||||
"#id_realm_message_content_edit_limit_minutes",
|
||||
).val(130);
|
||||
const msg_delete_limit_setting = $("#id_realm_msg_delete_limit_setting").val("custom_limit");
|
||||
const message_content_delete_limit_minutes = $(
|
||||
const $msg_delete_limit_setting = $("#id_realm_msg_delete_limit_setting").val("custom_limit");
|
||||
const $message_content_delete_limit_minutes = $(
|
||||
"#id_realm_message_content_delete_limit_minutes",
|
||||
).val(130);
|
||||
|
||||
allow_edit_history.attr("id", "id_realm_allow_edit_history");
|
||||
msg_edit_limit_setting.attr("id", "id_realm_msg_edit_limit_setting");
|
||||
msg_delete_limit_setting.attr("id", "id_realm_msg_delete_limit_setting");
|
||||
edit_topic_policy.attr("id", "id_realm_edit_topic_policy");
|
||||
message_content_edit_limit_minutes.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
message_content_delete_limit_minutes.attr(
|
||||
$allow_edit_history.attr("id", "id_realm_allow_edit_history");
|
||||
$msg_edit_limit_setting.attr("id", "id_realm_msg_edit_limit_setting");
|
||||
$msg_delete_limit_setting.attr("id", "id_realm_msg_delete_limit_setting");
|
||||
$edit_topic_policy.attr("id", "id_realm_edit_topic_policy");
|
||||
$message_content_edit_limit_minutes.attr("id", "id_realm_message_content_edit_limit_minutes");
|
||||
$message_content_delete_limit_minutes.attr(
|
||||
"id",
|
||||
"id_realm_message_content_delete_limit_minutes",
|
||||
);
|
||||
|
||||
const discard_button_parent = $(".org-subsection-parent");
|
||||
discard_button_parent.find = () => [
|
||||
allow_edit_history,
|
||||
msg_edit_limit_setting,
|
||||
msg_delete_limit_setting,
|
||||
edit_topic_policy,
|
||||
message_content_edit_limit_minutes,
|
||||
message_content_delete_limit_minutes,
|
||||
const $discard_button_parent = $(".org-subsection-parent");
|
||||
$discard_button_parent.find = () => [
|
||||
$allow_edit_history,
|
||||
$msg_edit_limit_setting,
|
||||
$msg_delete_limit_setting,
|
||||
$edit_topic_policy,
|
||||
$message_content_edit_limit_minutes,
|
||||
$message_content_delete_limit_minutes,
|
||||
];
|
||||
|
||||
$("#org-discard-msg-editing").closest = () => discard_button_parent;
|
||||
$("#org-discard-msg-editing").closest = () => $discard_button_parent;
|
||||
|
||||
const stubbed_function = settings_org.change_save_button_state;
|
||||
settings_org.__Rewire__("change_save_button_state", (save_button_controls, state) => {
|
||||
@@ -629,15 +629,15 @@ function test_discard_changes_button(discard_changes) {
|
||||
|
||||
discard_changes(ev);
|
||||
|
||||
assert.equal(allow_edit_history.prop("checked"), true);
|
||||
assert.equal($allow_edit_history.prop("checked"), true);
|
||||
assert.equal(
|
||||
edit_topic_policy.val(),
|
||||
$edit_topic_policy.val(),
|
||||
settings_config.common_message_policy_values.by_everyone.code,
|
||||
);
|
||||
assert.equal(msg_edit_limit_setting.val(), "upto_one_hour");
|
||||
assert.equal(message_content_edit_limit_minutes.val(), "60");
|
||||
assert.equal(msg_delete_limit_setting.val(), "upto_two_min");
|
||||
assert.equal(message_content_delete_limit_minutes.val(), "2");
|
||||
assert.equal($msg_edit_limit_setting.val(), "upto_one_hour");
|
||||
assert.equal($message_content_edit_limit_minutes.val(), "60");
|
||||
assert.equal($msg_delete_limit_setting.val(), "upto_two_min");
|
||||
assert.equal($message_content_delete_limit_minutes.val(), "2");
|
||||
|
||||
settings_org.__Rewire__("change_save_button_state", stubbed_function);
|
||||
}
|
||||
@@ -683,8 +683,8 @@ test("set_up", ({override, override_rewire, mock_template}) => {
|
||||
$("#enable_digest_emails_label").set_parent($.create("<stub digest setting checkbox>"));
|
||||
$("#id_realm_digest_weekday").set_parent($.create("<stub digest weekday setting dropdown>"));
|
||||
$("#allowed_domains_label").set_parent($.create("<stub-allowed-domain-label-parent>"));
|
||||
const waiting_period_parent_elem = $.create("waiting-period-parent-stub");
|
||||
$("#id_realm_waiting_period_threshold").set_parent(waiting_period_parent_elem);
|
||||
const $waiting_period_parent_elem = $.create("waiting-period-parent-stub");
|
||||
$("#id_realm_waiting_period_threshold").set_parent($waiting_period_parent_elem);
|
||||
$("#id_realm_create_web_public_stream_policy").set_parent(
|
||||
$.create("<stub-create-web-public-stream-policy-parent>"),
|
||||
);
|
||||
@@ -829,8 +829,8 @@ test("test get_sorted_options_list", () => {
|
||||
test("misc", ({override_rewire}) => {
|
||||
page_params.is_admin = false;
|
||||
|
||||
const stub_notification_disable_parent = $.create("<stub notification_disable parent");
|
||||
stub_notification_disable_parent.set_find_results(
|
||||
const $stub_notification_disable_parent = $.create("<stub notification_disable parent");
|
||||
$stub_notification_disable_parent.set_find_results(
|
||||
".dropdown_list_reset_button",
|
||||
$.create("<disable link>"),
|
||||
);
|
||||
@@ -904,14 +904,14 @@ test("misc", ({override_rewire}) => {
|
||||
"realm_signup_notifications_stream_id",
|
||||
"realm_default_code_block_language",
|
||||
];
|
||||
const dropdown_list_parent = $.create("<list parent>");
|
||||
dropdown_list_parent.set_find_results(
|
||||
const $dropdown_list_parent = $.create("<list parent>");
|
||||
$dropdown_list_parent.set_find_results(
|
||||
".dropdown_list_reset_button",
|
||||
$.create("<disable button>"),
|
||||
);
|
||||
for (const name of widget_settings) {
|
||||
const elem = $.create(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`);
|
||||
elem.closest = () => dropdown_list_parent;
|
||||
const $elem = $.create(`#${CSS.escape(name)}_widget #${CSS.escape(name)}_name`);
|
||||
$elem.closest = () => $dropdown_list_parent;
|
||||
}
|
||||
|
||||
// We do not define any settings we need in page_params yet, but we don't need to for this test.
|
||||
@@ -923,32 +923,32 @@ test("misc", ({override_rewire}) => {
|
||||
settings_org.init_dropdown_widgets();
|
||||
|
||||
let setting_name = "realm_notifications_stream_id";
|
||||
let elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
elem.closest = () => stub_notification_disable_parent;
|
||||
let $elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
$elem.closest = () => $stub_notification_disable_parent;
|
||||
sub_store.__Rewire__("get", (stream_id) => {
|
||||
assert.equal(stream_id, 42);
|
||||
return {name: "some_stream"};
|
||||
});
|
||||
settings_org.notifications_stream_widget.render(42);
|
||||
assert.equal(elem.text(), "#some_stream");
|
||||
assert.ok(!elem.hasClass("text-warning"));
|
||||
assert.equal($elem.text(), "#some_stream");
|
||||
assert.ok(!$elem.hasClass("text-warning"));
|
||||
|
||||
settings_org.notifications_stream_widget.render(undefined);
|
||||
assert.equal(elem.text(), "translated: Disabled");
|
||||
assert.ok(elem.hasClass("text-warning"));
|
||||
assert.equal($elem.text(), "translated: Disabled");
|
||||
assert.ok($elem.hasClass("text-warning"));
|
||||
|
||||
setting_name = "realm_signup_notifications_stream_id";
|
||||
elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
elem.closest = () => stub_notification_disable_parent;
|
||||
$elem = $(`#${CSS.escape(setting_name)}_widget #${CSS.escape(setting_name)}_name`);
|
||||
$elem.closest = () => $stub_notification_disable_parent;
|
||||
sub_store.__Rewire__("get", (stream_id) => {
|
||||
assert.equal(stream_id, 75);
|
||||
return {name: "some_stream"};
|
||||
});
|
||||
settings_org.signup_notifications_stream_widget.render(75);
|
||||
assert.equal(elem.text(), "#some_stream");
|
||||
assert.ok(!elem.hasClass("text-warning"));
|
||||
assert.equal($elem.text(), "#some_stream");
|
||||
assert.ok(!$elem.hasClass("text-warning"));
|
||||
|
||||
settings_org.signup_notifications_stream_widget.render(undefined);
|
||||
assert.equal(elem.text(), "translated: Disabled");
|
||||
assert.ok(elem.hasClass("text-warning"));
|
||||
assert.equal($elem.text(), "translated: Disabled");
|
||||
assert.ok($elem.hasClass("text-warning"));
|
||||
});
|
||||
|
||||
@@ -43,19 +43,19 @@ function test_populate(opts, template_data) {
|
||||
const fields_data = opts.fields_data;
|
||||
|
||||
page_params.is_admin = opts.is_admin;
|
||||
const table = $("#admin_profile_fields_table");
|
||||
const rows = $.create("rows");
|
||||
const form = $.create("forms");
|
||||
table.set_find_results("tr.profile-field-row", rows);
|
||||
table.set_find_results("tr.profile-field-form", form);
|
||||
const $table = $("#admin_profile_fields_table");
|
||||
const $rows = $.create("rows");
|
||||
const $form = $.create("forms");
|
||||
$table.set_find_results("tr.profile-field-row", $rows);
|
||||
$table.set_find_results("tr.profile-field-form", $form);
|
||||
|
||||
table[0] = "stub";
|
||||
$table[0] = "stub";
|
||||
|
||||
rows.remove = () => {};
|
||||
form.remove = () => {};
|
||||
$rows.remove = () => {};
|
||||
$form.remove = () => {};
|
||||
|
||||
let num_appends = 0;
|
||||
table.append = () => {
|
||||
$table.append = () => {
|
||||
num_appends += 1;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ const settings_data = zrequire("settings_data");
|
||||
const settings_user_groups = zrequire("settings_user_groups");
|
||||
const user_pill = zrequire("user_pill");
|
||||
|
||||
function reset_test_setup(pill_container_stub) {
|
||||
function reset_test_setup($pill_container_stub) {
|
||||
function input_pill_stub(opts) {
|
||||
assert.equal(opts.container, pill_container_stub);
|
||||
assert.equal(opts.$container, $pill_container_stub);
|
||||
create_item_handler = opts.create_item_from_text;
|
||||
assert.ok(create_item_handler);
|
||||
return pills;
|
||||
@@ -119,18 +119,18 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
people.get_visible_email = () => bob.email;
|
||||
|
||||
let templates_render_called = false;
|
||||
const fake_rendered_temp = $.create("fake_admin_user_group_list_template_rendered");
|
||||
const $fake_rendered_temp = $.create("fake_admin_user_group_list_template_rendered");
|
||||
mock_template("settings/admin_user_group_list.hbs", false, (args) => {
|
||||
assert.equal(args.user_group.id, 1);
|
||||
assert.equal(args.user_group.name, "Mobile");
|
||||
assert.equal(args.user_group.description, "All mobile people");
|
||||
templates_render_called = true;
|
||||
return fake_rendered_temp;
|
||||
return $fake_rendered_temp;
|
||||
});
|
||||
|
||||
let user_groups_list_append_called = false;
|
||||
$("#user-groups").append = (rendered_temp) => {
|
||||
assert.equal(rendered_temp, fake_rendered_temp);
|
||||
assert.equal(rendered_temp, $fake_rendered_temp);
|
||||
user_groups_list_append_called = true;
|
||||
};
|
||||
|
||||
@@ -158,7 +158,7 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
|
||||
const all_pills = new Map();
|
||||
|
||||
const pill_container_stub = $(`.pill-container[data-group-pills="${CSS.escape(1)}"]`);
|
||||
const $pill_container_stub = $(`.pill-container[data-group-pills="${CSS.escape(1)}"]`);
|
||||
pills.appendValidatedData = (item) => {
|
||||
const id = item.user_id;
|
||||
assert.ok(!all_pills.has(id));
|
||||
@@ -171,11 +171,11 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
text_cleared = true;
|
||||
};
|
||||
|
||||
const input_field_stub = $.create("fake-input-field");
|
||||
pill_container_stub.children = () => input_field_stub;
|
||||
const $input_field_stub = $.create("fake-input-field");
|
||||
$pill_container_stub.children = () => $input_field_stub;
|
||||
|
||||
let input_typeahead_called = false;
|
||||
input_field_stub.typeahead = (config) => {
|
||||
$input_field_stub.typeahead = (config) => {
|
||||
assert.equal(config.items, 5);
|
||||
assert.ok(config.fixed);
|
||||
assert.ok(config.dropup);
|
||||
@@ -187,9 +187,9 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
assert.equal(typeof config.updater, "function");
|
||||
|
||||
(function test_highlighter() {
|
||||
const fake_person = $.create("fake-person");
|
||||
typeahead_helper.render_person = () => fake_person;
|
||||
assert.equal(config.highlighter(), fake_person);
|
||||
const $fake_person = $.create("fake-person");
|
||||
typeahead_helper.render_person = () => $fake_person;
|
||||
assert.equal(config.highlighter(), $fake_person);
|
||||
})();
|
||||
|
||||
const fake_context = {
|
||||
@@ -236,7 +236,7 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
})();
|
||||
|
||||
(function test_updater() {
|
||||
input_field_stub.text("@ali");
|
||||
$input_field_stub.text("@ali");
|
||||
user_groups.get_user_group_from_id = () => realm_user_group;
|
||||
|
||||
let saved_fade_out_called = false;
|
||||
@@ -334,7 +334,7 @@ test_ui("populate_user_groups", ({override_rewire, mock_template}) => {
|
||||
handler();
|
||||
};
|
||||
|
||||
reset_test_setup(pill_container_stub);
|
||||
reset_test_setup($pill_container_stub);
|
||||
settings_user_groups.set_up();
|
||||
assert.ok(templates_render_called);
|
||||
assert.ok(user_groups_list_append_called);
|
||||
@@ -386,63 +386,63 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
||||
$.clear_all_elements();
|
||||
|
||||
let user_group_find_called = 0;
|
||||
const user_group_stub = $(`div.user-group[id="${CSS.escape(1)}"]`);
|
||||
const name_field_stub = $.create("fake-name-field");
|
||||
const description_field_stub = $.create("fake-description-field");
|
||||
const input_stub = $.create("fake-input");
|
||||
user_group_stub.find = (elem) => {
|
||||
const $user_group_stub = $(`div.user-group[id="${CSS.escape(1)}"]`);
|
||||
const $name_field_stub = $.create("fake-name-field");
|
||||
const $description_field_stub = $.create("fake-description-field");
|
||||
const $input_stub = $.create("fake-input");
|
||||
$user_group_stub.find = (elem) => {
|
||||
if (elem === ".name") {
|
||||
user_group_find_called += 1;
|
||||
return name_field_stub;
|
||||
return $name_field_stub;
|
||||
}
|
||||
if (elem === ".description") {
|
||||
user_group_find_called += 1;
|
||||
return description_field_stub;
|
||||
return $description_field_stub;
|
||||
}
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
};
|
||||
|
||||
const pill_container_stub = $(`.pill-container[data-group-pills="${CSS.escape(1)}"]`);
|
||||
const pill_stub = $.create("fake-pill");
|
||||
const $pill_container_stub = $(`.pill-container[data-group-pills="${CSS.escape(1)}"]`);
|
||||
const $pill_stub = $.create("fake-pill");
|
||||
let pill_container_find_called = 0;
|
||||
pill_container_stub.find = (elem) => {
|
||||
$pill_container_stub.find = (elem) => {
|
||||
if (elem === ".input") {
|
||||
pill_container_find_called += 1;
|
||||
return input_stub;
|
||||
return $input_stub;
|
||||
}
|
||||
if (elem === ".pill") {
|
||||
pill_container_find_called += 1;
|
||||
return pill_stub;
|
||||
return $pill_stub;
|
||||
}
|
||||
throw new Error(`Unknown element ${elem}`);
|
||||
};
|
||||
|
||||
input_stub.css = (property, val) => {
|
||||
$input_stub.css = (property, val) => {
|
||||
assert.equal(property, "display");
|
||||
assert.equal(val, "none");
|
||||
};
|
||||
|
||||
// Test the 'off' handlers on the pill-container
|
||||
const turned_off = {};
|
||||
pill_container_stub.off = (event_name, sel = "whole") => {
|
||||
$pill_container_stub.off = (event_name, sel = "whole") => {
|
||||
turned_off[event_name + "/" + sel] = true;
|
||||
};
|
||||
|
||||
const exit_button = $.create("fake-pill-exit");
|
||||
pill_stub.set_find_results(".exit", exit_button);
|
||||
const $exit_button = $.create("fake-pill-exit");
|
||||
$pill_stub.set_find_results(".exit", $exit_button);
|
||||
let exit_button_called = false;
|
||||
exit_button.css = (property, value) => {
|
||||
$exit_button.css = (property, value) => {
|
||||
exit_button_called = true;
|
||||
assert.equal(property, "opacity");
|
||||
assert.equal(value, "0.5");
|
||||
};
|
||||
|
||||
// We return noop because these are already tested, so we skip them
|
||||
pill_container_stub.children = () => noop;
|
||||
$pill_container_stub.children = () => noop;
|
||||
|
||||
$("#user-groups").append = () => noop;
|
||||
|
||||
reset_test_setup(pill_container_stub);
|
||||
reset_test_setup($pill_container_stub);
|
||||
|
||||
settings_user_groups.set_up();
|
||||
|
||||
@@ -451,8 +451,8 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
||||
|
||||
// Test different handlers with an external user
|
||||
const delete_handler = $("#user-groups").get_on_handler("click", ".delete");
|
||||
const fake_delete = $.create("fk-#user-groups.delete_btn");
|
||||
fake_delete.set_parents_result(".user-group", $(".user-group"));
|
||||
const $fake_delete = $.create("fk-#user-groups.delete_btn");
|
||||
$fake_delete.set_parents_result(".user-group", $(".user-group"));
|
||||
set_parents_result_called += 1;
|
||||
$(".user-group").attr("id", "1");
|
||||
set_attributes_called += 1;
|
||||
@@ -470,11 +470,11 @@ test_ui("with_external_user", ({override_rewire, mock_template}) => {
|
||||
const event = {
|
||||
stopPropagation: noop,
|
||||
};
|
||||
const pill_mouseenter_handler = pill_stub.get_on_handler("mouseenter");
|
||||
const pill_click_handler = pill_container_stub.get_on_handler("click");
|
||||
const pill_mouseenter_handler = $pill_stub.get_on_handler("mouseenter");
|
||||
const pill_click_handler = $pill_container_stub.get_on_handler("click");
|
||||
pill_mouseenter_handler(event);
|
||||
pill_click_handler(event);
|
||||
assert.equal(delete_handler.call(fake_delete), undefined);
|
||||
assert.equal(delete_handler.call($fake_delete), undefined);
|
||||
assert.equal(name_update_handler(), undefined);
|
||||
assert.equal(des_update_handler(), undefined);
|
||||
assert.equal(member_change_handler(), undefined);
|
||||
@@ -524,7 +524,7 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
stopPropagation: noop,
|
||||
preventDefault: noop,
|
||||
};
|
||||
const fake_this = $.create("fake-form.admin-user-group-form");
|
||||
const $fake_this = $.create("fake-form.admin-user-group-form");
|
||||
const fake_object_array = [
|
||||
{
|
||||
name: "fake-name",
|
||||
@@ -535,7 +535,7 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
value: "fake-value",
|
||||
},
|
||||
];
|
||||
fake_this.serializeArray = () => fake_object_array;
|
||||
$fake_this.serializeArray = () => fake_object_array;
|
||||
channel.post = (opts) => {
|
||||
const data = {
|
||||
members: "[null]",
|
||||
@@ -577,13 +577,13 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
})();
|
||||
};
|
||||
|
||||
handler.call(fake_this, event);
|
||||
handler.call($fake_this, event);
|
||||
})();
|
||||
|
||||
(function test_user_groups_delete_click_triggered() {
|
||||
const handler = $("#user-groups").get_on_handler("click", ".delete");
|
||||
const fake_this = $.create("fake-#user-groups.delete_btn");
|
||||
fake_this.set_parents_result(".user-group", $(".user-group"));
|
||||
const $fake_this = $.create("fake-#user-groups.delete_btn");
|
||||
$fake_this.set_parents_result(".user-group", $(".user-group"));
|
||||
$(".user-group").attr("id", "1");
|
||||
|
||||
channel.del = (opts) => {
|
||||
@@ -593,16 +593,16 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
assert.equal(opts.url, "/json/user_groups/1");
|
||||
assert.deepEqual(opts.data, data);
|
||||
|
||||
fake_this.text($t({defaultMessage: "fake-text"}));
|
||||
$fake_this.text($t({defaultMessage: "fake-text"}));
|
||||
opts.error();
|
||||
assert.equal(fake_this.text(), "translated: Failed!");
|
||||
assert.equal($fake_this.text(), "translated: Failed!");
|
||||
};
|
||||
|
||||
confirm_dialog.launch = (conf) => {
|
||||
conf.on_click();
|
||||
};
|
||||
|
||||
handler.call(fake_this);
|
||||
handler.call($fake_this);
|
||||
})();
|
||||
|
||||
(function test_user_groups_keypress_enter_triggered() {
|
||||
@@ -625,9 +625,10 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
api_endpoint_called = true;
|
||||
};
|
||||
channel.patch = noop;
|
||||
const fake_this = $.create("fake-#user-groups_do_not_blur");
|
||||
const $fake_this = $.create("fake-#user-groups_do_not_blur");
|
||||
const event = {
|
||||
relatedTarget: fake_this,
|
||||
// FIXME: event.relatedTarget should not be a jQuery object
|
||||
relatedTarget: $fake_this,
|
||||
};
|
||||
|
||||
// Any of the blur_exceptions trigger blur event.
|
||||
@@ -645,24 +646,24 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
continue;
|
||||
}
|
||||
api_endpoint_called = false;
|
||||
fake_this.closest = (class_name) => {
|
||||
$fake_this.closest = (class_name) => {
|
||||
if (class_name === blur_exception || class_name === user_group_selector) {
|
||||
return [1];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
handler.call(fake_this, event);
|
||||
handler.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
}
|
||||
|
||||
api_endpoint_called = false;
|
||||
fake_this.closest = (class_name) => {
|
||||
$fake_this.closest = (class_name) => {
|
||||
if (class_name === ".typeahead") {
|
||||
return [1];
|
||||
}
|
||||
return [];
|
||||
};
|
||||
handler.call(fake_this, event);
|
||||
handler.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
|
||||
// Cancel button triggers blur event.
|
||||
@@ -671,7 +672,7 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
settings_user_groups_reload_called = true;
|
||||
});
|
||||
api_endpoint_called = false;
|
||||
fake_this.closest = (class_name) => {
|
||||
$fake_this.closest = (class_name) => {
|
||||
if (
|
||||
class_name === ".save-status.btn-danger" ||
|
||||
class_name === user_group_selector
|
||||
@@ -680,7 +681,7 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
}
|
||||
return [];
|
||||
};
|
||||
handler.call(fake_this, event);
|
||||
handler.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
assert.ok(settings_user_groups_reload_called);
|
||||
}
|
||||
@@ -689,10 +690,10 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
(function test_update_cancel_button() {
|
||||
const handler_name = $(user_group_selector).get_on_handler("input", ".name");
|
||||
const handler_desc = $(user_group_selector).get_on_handler("input", ".description");
|
||||
const sib_des = $(description_selector);
|
||||
const sib_name = $(name_selector);
|
||||
sib_name.text($t({defaultMessage: "mobile"}));
|
||||
sib_des.text($t({defaultMessage: "All mobile members"}));
|
||||
const $sib_des = $(description_selector);
|
||||
const $sib_name = $(name_selector);
|
||||
$sib_name.text($t({defaultMessage: "mobile"}));
|
||||
$sib_des.text($t({defaultMessage: "All mobile members"}));
|
||||
|
||||
const group_data = {
|
||||
name: "translated: mobile",
|
||||
@@ -712,8 +713,8 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
};
|
||||
|
||||
// Cancel button removed if user group if user group has no changes.
|
||||
const fake_this = $.create("fake-#update_cancel_button");
|
||||
handler_name.call(fake_this);
|
||||
const $fake_this = $.create("fake-#update_cancel_button");
|
||||
handler_name.call($fake_this);
|
||||
assert.ok(cancel_fade_out_called);
|
||||
assert.ok(instructions_fade_out_called);
|
||||
|
||||
@@ -721,14 +722,14 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
$(user_group_selector + " .user-group-status").show();
|
||||
cancel_fade_out_called = false;
|
||||
instructions_fade_out_called = false;
|
||||
handler_name.call(fake_this);
|
||||
handler_name.call($fake_this);
|
||||
assert.ok(cancel_fade_out_called);
|
||||
assert.ok(instructions_fade_out_called);
|
||||
|
||||
// Check for handler_desc to achieve 100% coverage.
|
||||
cancel_fade_out_called = false;
|
||||
instructions_fade_out_called = false;
|
||||
handler_desc.call(fake_this);
|
||||
handler_desc.call($fake_this);
|
||||
assert.ok(cancel_fade_out_called);
|
||||
assert.ok(instructions_fade_out_called);
|
||||
})();
|
||||
@@ -736,10 +737,10 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
(function test_user_groups_save_group_changes_triggered() {
|
||||
const handler_name = $(user_group_selector).get_on_handler("blur", ".name");
|
||||
const handler_desc = $(user_group_selector).get_on_handler("blur", ".description");
|
||||
const sib_des = $(description_selector);
|
||||
const sib_name = $(name_selector);
|
||||
sib_name.text($t({defaultMessage: "mobile"}));
|
||||
sib_des.text($t({defaultMessage: "All mobile members"}));
|
||||
const $sib_des = $(description_selector);
|
||||
const $sib_name = $(name_selector);
|
||||
$sib_name.text($t({defaultMessage: "mobile"}));
|
||||
$sib_des.text($t({defaultMessage: "All mobile members"}));
|
||||
|
||||
const group_data = {members: new Set([2, 31])};
|
||||
user_groups.get_user_group_from_id = () => group_data;
|
||||
@@ -782,46 +783,47 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
assert.ok(saved_fade_to_called);
|
||||
})();
|
||||
(function test_post_error() {
|
||||
const user_group_error = $(user_group_selector + " .user-group-status");
|
||||
user_group_error.show();
|
||||
const $user_group_error = $(user_group_selector + " .user-group-status");
|
||||
$user_group_error.show();
|
||||
ui_report.error = (error_msg, error_obj, ele) => {
|
||||
const xhr = {
|
||||
responseText: '{"msg":"fake-msg"}',
|
||||
};
|
||||
assert.equal(error_msg, "translated HTML: Failed");
|
||||
assert.deepEqual(error_obj, xhr);
|
||||
assert.equal(ele, user_group_error);
|
||||
assert.equal(ele, $user_group_error);
|
||||
};
|
||||
const xhr = {
|
||||
responseText: '{"msg":"fake-msg", "attrib":"val"}',
|
||||
};
|
||||
opts.error(xhr);
|
||||
|
||||
assert.ok(user_group_error.visible());
|
||||
assert.ok($user_group_error.visible());
|
||||
})();
|
||||
};
|
||||
|
||||
const fake_this = $.create("fake-#user-groups_blur_name");
|
||||
fake_this.closest = () => [];
|
||||
fake_this.set_parents_result(user_group_selector, $(user_group_selector));
|
||||
const $fake_this = $.create("fake-#user-groups_blur_name");
|
||||
$fake_this.closest = () => [];
|
||||
$fake_this.set_parents_result(user_group_selector, $(user_group_selector));
|
||||
const event = {
|
||||
relatedTarget: fake_this,
|
||||
// FIXME: event.relatedTarget should not be a jQuery object
|
||||
relatedTarget: $fake_this,
|
||||
};
|
||||
|
||||
api_endpoint_called = false;
|
||||
handler_name.call(fake_this, event);
|
||||
handler_name.call($fake_this, event);
|
||||
assert.ok(api_endpoint_called);
|
||||
|
||||
// Check API endpoint isn't called if name and desc haven't changed.
|
||||
group_data.name = "translated: mobile";
|
||||
group_data.description = "translated: All mobile members";
|
||||
api_endpoint_called = false;
|
||||
handler_name.call(fake_this, event);
|
||||
handler_name.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
|
||||
// Check for handler_desc to achieve 100% coverage.
|
||||
api_endpoint_called = false;
|
||||
handler_desc.call(fake_this, event);
|
||||
handler_desc.call($fake_this, event);
|
||||
assert.ok(!api_endpoint_called);
|
||||
})();
|
||||
|
||||
@@ -869,15 +871,16 @@ test_ui("on_events", ({override_rewire, mock_template}) => {
|
||||
})();
|
||||
};
|
||||
|
||||
const fake_this = $.create("fake-#user-groups_blur_input");
|
||||
fake_this.set_parents_result(user_group_selector, $(user_group_selector));
|
||||
fake_this.closest = () => [];
|
||||
const $fake_this = $.create("fake-#user-groups_blur_input");
|
||||
$fake_this.set_parents_result(user_group_selector, $(user_group_selector));
|
||||
$fake_this.closest = () => [];
|
||||
const event = {
|
||||
relatedTarget: fake_this,
|
||||
// FIXME: event.relatedTarget should not be a jQuery object
|
||||
relatedTarget: $fake_this,
|
||||
};
|
||||
|
||||
api_endpoint_called = false;
|
||||
handler.call(fake_this, event);
|
||||
handler.call($fake_this, event);
|
||||
assert.ok(api_endpoint_called);
|
||||
})();
|
||||
});
|
||||
|
||||
@@ -11,30 +11,30 @@ const spoilers = zrequire("spoilers");
|
||||
// This function is taken from rendered_markdown.js and slightly modified.
|
||||
const $array = (array) => {
|
||||
const each = (func) => {
|
||||
for (const [index, elem] of array.entries()) {
|
||||
func.call(this, index, elem);
|
||||
for (const [index, $elem] of array.entries()) {
|
||||
func.call(this, index, $elem);
|
||||
}
|
||||
};
|
||||
return {each};
|
||||
};
|
||||
|
||||
const get_spoiler_elem = (title) => {
|
||||
const block = $.create(`block-${title}`);
|
||||
const header = $.create(`header-${title}`);
|
||||
const content = $.create(`content-${title}`);
|
||||
content.remove = () => {};
|
||||
header.text(title);
|
||||
block.set_find_results(".spoiler-header", header);
|
||||
block.set_find_results(".spoiler-content", content);
|
||||
return block;
|
||||
const $block = $.create(`block-${title}`);
|
||||
const $header = $.create(`header-${title}`);
|
||||
const $content = $.create(`content-${title}`);
|
||||
$content.remove = () => {};
|
||||
$header.text(title);
|
||||
$block.set_find_results(".spoiler-header", $header);
|
||||
$block.set_find_results(".spoiler-content", $content);
|
||||
return $block;
|
||||
};
|
||||
|
||||
run_test("hide spoilers in notifications", () => {
|
||||
const root = $.create("root element");
|
||||
const spoiler_1 = get_spoiler_elem("this is the title");
|
||||
const spoiler_2 = get_spoiler_elem("");
|
||||
root.set_find_results(".spoiler-block", $array([spoiler_1, spoiler_2]));
|
||||
spoilers.hide_spoilers_in_notification(root);
|
||||
assert.equal(spoiler_1.find(".spoiler-header").text(), "this is the title (…)");
|
||||
assert.equal(spoiler_2.find(".spoiler-header").text(), "(…)");
|
||||
const $root = $.create("root element");
|
||||
const $spoiler_1 = get_spoiler_elem("this is the title");
|
||||
const $spoiler_2 = get_spoiler_elem("");
|
||||
$root.set_find_results(".spoiler-block", $array([$spoiler_1, $spoiler_2]));
|
||||
spoilers.hide_spoilers_in_notification($root);
|
||||
assert.equal($spoiler_1.find(".spoiler-header").text(), "this is the title (…)");
|
||||
assert.equal($spoiler_2.find(".spoiler-header").text(), "(…)");
|
||||
});
|
||||
|
||||
@@ -136,32 +136,32 @@ test("update_property", ({override}) => {
|
||||
// Test desktop notifications
|
||||
stream_events.update_property(stream_id, "desktop_notifications", true);
|
||||
assert.equal(sub.desktop_notifications, true);
|
||||
let checkbox = checkbox_for("desktop_notifications");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
let $checkbox = checkbox_for("desktop_notifications");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
|
||||
// Tests audible notifications
|
||||
stream_events.update_property(stream_id, "audible_notifications", true);
|
||||
assert.equal(sub.audible_notifications, true);
|
||||
checkbox = checkbox_for("audible_notifications");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
$checkbox = checkbox_for("audible_notifications");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
|
||||
// Tests push notifications
|
||||
stream_events.update_property(stream_id, "push_notifications", true);
|
||||
assert.equal(sub.push_notifications, true);
|
||||
checkbox = checkbox_for("push_notifications");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
$checkbox = checkbox_for("push_notifications");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
|
||||
// Tests email notifications
|
||||
stream_events.update_property(stream_id, "email_notifications", true);
|
||||
assert.equal(sub.email_notifications, true);
|
||||
checkbox = checkbox_for("email_notifications");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
$checkbox = checkbox_for("email_notifications");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
|
||||
// Tests wildcard_mentions_notify notifications
|
||||
stream_events.update_property(stream_id, "wildcard_mentions_notify", true);
|
||||
assert.equal(sub.wildcard_mentions_notify, true);
|
||||
checkbox = checkbox_for("wildcard_mentions_notify");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
$checkbox = checkbox_for("wildcard_mentions_notify");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
|
||||
// Test name change
|
||||
{
|
||||
@@ -195,8 +195,8 @@ test("update_property", ({override}) => {
|
||||
{
|
||||
override(stream_list, "refresh_pinned_or_unpinned_stream", noop);
|
||||
stream_events.update_property(stream_id, "pin_to_top", true);
|
||||
checkbox = checkbox_for("pin_to_top");
|
||||
assert.equal(checkbox.prop("checked"), true);
|
||||
$checkbox = checkbox_for("pin_to_top");
|
||||
assert.equal($checkbox.prop("checked"), true);
|
||||
}
|
||||
|
||||
// Test stream privacy change event
|
||||
|
||||
@@ -19,7 +19,7 @@ const topic_list = mock_esm("../../static/js/topic_list");
|
||||
mock_esm("../../static/js/keydown_util", {
|
||||
handle: noop,
|
||||
});
|
||||
mock_esm("../../static/js/ui", {get_scroll_element: (element) => element});
|
||||
mock_esm("../../static/js/ui", {get_scroll_element: ($element) => $element});
|
||||
|
||||
const {Filter} = zrequire("../js/filter");
|
||||
const stream_sort = zrequire("stream_sort");
|
||||
@@ -47,13 +47,13 @@ const social = {
|
||||
let num_unread_for_stream;
|
||||
|
||||
function create_devel_sidebar_row({mock_template}) {
|
||||
const devel_count = $.create("devel-count");
|
||||
const subscription_block = $.create("devel-block");
|
||||
const $devel_count = $.create("devel-count");
|
||||
const $subscription_block = $.create("devel-block");
|
||||
|
||||
const sidebar_row = $("<devel sidebar row>");
|
||||
const $sidebar_row = $("<devel sidebar row>");
|
||||
|
||||
sidebar_row.set_find_results(".subscription_block", subscription_block);
|
||||
subscription_block.set_find_results(".unread_count", devel_count);
|
||||
$sidebar_row.set_find_results(".subscription_block", $subscription_block);
|
||||
$subscription_block.set_find_results(".unread_count", $devel_count);
|
||||
|
||||
mock_template("stream_sidebar_row.hbs", false, (data) => {
|
||||
assert.equal(data.uri, "#narrow/stream/100-devel");
|
||||
@@ -62,17 +62,17 @@ function create_devel_sidebar_row({mock_template}) {
|
||||
|
||||
num_unread_for_stream = 42;
|
||||
stream_list.create_sidebar_row(devel);
|
||||
assert.equal(devel_count.text(), "42");
|
||||
assert.equal($devel_count.text(), "42");
|
||||
}
|
||||
|
||||
function create_social_sidebar_row({mock_template}) {
|
||||
const social_count = $.create("social-count");
|
||||
const subscription_block = $.create("social-block");
|
||||
const $social_count = $.create("social-count");
|
||||
const $subscription_block = $.create("social-block");
|
||||
|
||||
const sidebar_row = $("<social sidebar row>");
|
||||
const $sidebar_row = $("<social sidebar row>");
|
||||
|
||||
sidebar_row.set_find_results(".subscription_block", subscription_block);
|
||||
subscription_block.set_find_results(".unread_count", social_count);
|
||||
$sidebar_row.set_find_results(".subscription_block", $subscription_block);
|
||||
$subscription_block.set_find_results(".unread_count", $social_count);
|
||||
|
||||
mock_template("stream_sidebar_row.hbs", false, (data) => {
|
||||
assert.equal(data.uri, "#narrow/stream/200-social");
|
||||
@@ -81,7 +81,7 @@ function create_social_sidebar_row({mock_template}) {
|
||||
|
||||
num_unread_for_stream = 99;
|
||||
stream_list.create_sidebar_row(social);
|
||||
assert.equal(social_count.text(), "99");
|
||||
assert.equal($social_count.text(), "99");
|
||||
}
|
||||
|
||||
function test_ui(label, f) {
|
||||
@@ -105,8 +105,8 @@ test_ui("create_sidebar_row", ({override_rewire, mock_template}) => {
|
||||
create_social_sidebar_row({mock_template});
|
||||
|
||||
const split = '<hr class="stream-split">';
|
||||
const devel_sidebar = $("<devel sidebar row>");
|
||||
const social_sidebar = $("<social sidebar row>");
|
||||
const $devel_sidebar = $("<devel sidebar row>");
|
||||
const $social_sidebar = $("<social sidebar row>");
|
||||
|
||||
let appended_elems;
|
||||
$("#stream_filters").append = (elems) => {
|
||||
@@ -123,20 +123,20 @@ test_ui("create_sidebar_row", ({override_rewire, mock_template}) => {
|
||||
assert.ok(topic_list_cleared);
|
||||
|
||||
const expected_elems = [
|
||||
devel_sidebar, // pinned
|
||||
$devel_sidebar, // pinned
|
||||
split, // separator
|
||||
social_sidebar, // not pinned
|
||||
$social_sidebar, // not pinned
|
||||
];
|
||||
|
||||
assert.deepEqual(appended_elems, expected_elems);
|
||||
|
||||
const social_li = $("<social sidebar row>");
|
||||
const $social_li = $("<social sidebar row>");
|
||||
const stream_id = social.stream_id;
|
||||
|
||||
social_li.length = 0;
|
||||
$social_li.length = 0;
|
||||
|
||||
const privacy_elem = $.create("privacy-stub");
|
||||
social_li.set_find_results(".stream-privacy", privacy_elem);
|
||||
const $privacy_elem = $.create("privacy-stub");
|
||||
$social_li.set_find_results(".stream-privacy", $privacy_elem);
|
||||
|
||||
social.invite_only = true;
|
||||
social.color = "#222222";
|
||||
@@ -147,25 +147,25 @@ test_ui("create_sidebar_row", ({override_rewire, mock_template}) => {
|
||||
return "<div>privacy-html";
|
||||
});
|
||||
stream_list.redraw_stream_privacy(social);
|
||||
assert.equal(privacy_elem.html(), "<div>privacy-html");
|
||||
assert.equal($privacy_elem.html(), "<div>privacy-html");
|
||||
|
||||
stream_list.set_in_home_view(stream_id, false);
|
||||
assert.ok(social_li.hasClass("out_of_home_view"));
|
||||
assert.ok($social_li.hasClass("out_of_home_view"));
|
||||
|
||||
stream_list.set_in_home_view(stream_id, true);
|
||||
assert.ok(!social_li.hasClass("out_of_home_view"));
|
||||
assert.ok(!$social_li.hasClass("out_of_home_view"));
|
||||
|
||||
const row = stream_list.stream_sidebar.get_row(stream_id);
|
||||
override_rewire(stream_data, "is_active", () => true);
|
||||
row.update_whether_active();
|
||||
assert.ok(!social_li.hasClass("inactive_stream"));
|
||||
assert.ok(!$social_li.hasClass("inactive_stream"));
|
||||
|
||||
override_rewire(stream_data, "is_active", () => false);
|
||||
row.update_whether_active();
|
||||
assert.ok(social_li.hasClass("inactive_stream"));
|
||||
assert.ok($social_li.hasClass("inactive_stream"));
|
||||
|
||||
let removed;
|
||||
social_li.remove = () => {
|
||||
$social_li.remove = () => {
|
||||
removed = true;
|
||||
};
|
||||
|
||||
@@ -183,33 +183,33 @@ test_ui("pinned_streams_never_inactive", ({override_rewire, mock_template}) => {
|
||||
create_social_sidebar_row({mock_template});
|
||||
|
||||
// non-pinned streams can be made inactive
|
||||
const social_sidebar = $("<social sidebar row>");
|
||||
const $social_sidebar = $("<social sidebar row>");
|
||||
let stream_id = social.stream_id;
|
||||
let row = stream_list.stream_sidebar.get_row(stream_id);
|
||||
override_rewire(stream_data, "is_active", () => false);
|
||||
|
||||
stream_list.build_stream_list();
|
||||
assert.ok(social_sidebar.hasClass("inactive_stream"));
|
||||
assert.ok($social_sidebar.hasClass("inactive_stream"));
|
||||
|
||||
override_rewire(stream_data, "is_active", () => true);
|
||||
row.update_whether_active();
|
||||
assert.ok(!social_sidebar.hasClass("inactive_stream"));
|
||||
assert.ok(!$social_sidebar.hasClass("inactive_stream"));
|
||||
|
||||
override_rewire(stream_data, "is_active", () => false);
|
||||
row.update_whether_active();
|
||||
assert.ok(social_sidebar.hasClass("inactive_stream"));
|
||||
assert.ok($social_sidebar.hasClass("inactive_stream"));
|
||||
|
||||
// pinned streams can never be made inactive
|
||||
const devel_sidebar = $("<devel sidebar row>");
|
||||
const $devel_sidebar = $("<devel sidebar row>");
|
||||
stream_id = devel.stream_id;
|
||||
row = stream_list.stream_sidebar.get_row(stream_id);
|
||||
override_rewire(stream_data, "is_active", () => false);
|
||||
|
||||
stream_list.build_stream_list();
|
||||
assert.ok(!devel_sidebar.hasClass("inactive_stream"));
|
||||
assert.ok(!$devel_sidebar.hasClass("inactive_stream"));
|
||||
|
||||
row.update_whether_active();
|
||||
assert.ok(!devel_sidebar.hasClass("inactive_stream"));
|
||||
assert.ok(!$devel_sidebar.hasClass("inactive_stream"));
|
||||
});
|
||||
|
||||
function add_row(sub) {
|
||||
@@ -218,11 +218,11 @@ function add_row(sub) {
|
||||
update_whether_active() {},
|
||||
get_li() {
|
||||
const html = "<" + sub.name + " sidebar row html>";
|
||||
const obj = $(html);
|
||||
const $obj = $(html);
|
||||
|
||||
obj.length = 1; // bypass blueslip error
|
||||
$obj.length = 1; // bypass blueslip error
|
||||
|
||||
return obj;
|
||||
return $obj;
|
||||
},
|
||||
};
|
||||
stream_list.stream_sidebar.set_row(sub.stream_id, row);
|
||||
@@ -293,30 +293,30 @@ function elem($obj) {
|
||||
}
|
||||
|
||||
test_ui("zoom_in_and_zoom_out", () => {
|
||||
const label1 = $.create("label1 stub");
|
||||
const label2 = $.create("label2 stub");
|
||||
const $label1 = $.create("label1 stub");
|
||||
const $label2 = $.create("label2 stub");
|
||||
|
||||
label1.show();
|
||||
label2.show();
|
||||
$label1.show();
|
||||
$label2.show();
|
||||
|
||||
assert.ok(label1.visible());
|
||||
assert.ok(label2.visible());
|
||||
assert.ok($label1.visible());
|
||||
assert.ok($label2.visible());
|
||||
|
||||
$.create(".stream-filters-label", {
|
||||
children: [elem(label1), elem(label2)],
|
||||
children: [elem($label1), elem($label2)],
|
||||
});
|
||||
|
||||
const splitter = $.create("hr stub");
|
||||
const $splitter = $.create("hr stub");
|
||||
|
||||
splitter.show();
|
||||
assert.ok(splitter.visible());
|
||||
$splitter.show();
|
||||
assert.ok($splitter.visible());
|
||||
|
||||
$.create(".stream-split", {
|
||||
children: [elem(splitter)],
|
||||
children: [elem($splitter)],
|
||||
});
|
||||
|
||||
const stream_li1 = $.create("stream1 stub");
|
||||
const stream_li2 = $.create("stream2 stub");
|
||||
const $stream_li1 = $.create("stream1 stub");
|
||||
const $stream_li2 = $.create("stream2 stub");
|
||||
|
||||
function make_attr(arg) {
|
||||
return (sel) => {
|
||||
@@ -325,12 +325,12 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
};
|
||||
}
|
||||
|
||||
stream_li1.attr = make_attr("42");
|
||||
stream_li1.hide();
|
||||
stream_li2.attr = make_attr("99");
|
||||
$stream_li1.attr = make_attr("42");
|
||||
$stream_li1.hide();
|
||||
$stream_li2.attr = make_attr("99");
|
||||
|
||||
$.create("#stream_filters li.narrow-filter", {
|
||||
children: [elem(stream_li1), elem(stream_li2)],
|
||||
children: [elem($stream_li1), elem($stream_li2)],
|
||||
});
|
||||
|
||||
$("#stream-filters-container")[0] = {
|
||||
@@ -340,26 +340,26 @@ test_ui("zoom_in_and_zoom_out", () => {
|
||||
|
||||
stream_list.zoom_in_topics({stream_id: 42});
|
||||
|
||||
assert.ok(!label1.visible());
|
||||
assert.ok(!label2.visible());
|
||||
assert.ok(!splitter.visible());
|
||||
assert.ok(stream_li1.visible());
|
||||
assert.ok(!stream_li2.visible());
|
||||
assert.ok(!$label1.visible());
|
||||
assert.ok(!$label2.visible());
|
||||
assert.ok(!$splitter.visible());
|
||||
assert.ok($stream_li1.visible());
|
||||
assert.ok(!$stream_li2.visible());
|
||||
assert.ok($("#streams_list").hasClass("zoom-in"));
|
||||
|
||||
$("#stream_filters li.narrow-filter").show = () => {
|
||||
stream_li1.show();
|
||||
stream_li2.show();
|
||||
$stream_li1.show();
|
||||
$stream_li2.show();
|
||||
};
|
||||
|
||||
stream_li1.length = 1;
|
||||
stream_list.zoom_out_topics({stream_li: stream_li1});
|
||||
$stream_li1.length = 1;
|
||||
stream_list.zoom_out_topics({$stream_li: $stream_li1});
|
||||
|
||||
assert.ok(label1.visible());
|
||||
assert.ok(label2.visible());
|
||||
assert.ok(splitter.visible());
|
||||
assert.ok(stream_li1.visible());
|
||||
assert.ok(stream_li2.visible());
|
||||
assert.ok($label1.visible());
|
||||
assert.ok($label2.visible());
|
||||
assert.ok($splitter.visible());
|
||||
assert.ok($stream_li1.visible());
|
||||
assert.ok($stream_li2.visible());
|
||||
assert.ok($("#streams_list").hasClass("zoom-out"));
|
||||
});
|
||||
|
||||
@@ -591,8 +591,8 @@ test_ui("rename_stream", ({override_rewire, mock_template}) => {
|
||||
|
||||
stream_data.rename_sub(sub, new_name);
|
||||
|
||||
const li_stub = $.create("li stub");
|
||||
li_stub.length = 0;
|
||||
const $li_stub = $.create("li stub");
|
||||
$li_stub.length = 0;
|
||||
|
||||
mock_template("stream_sidebar_row.hbs", false, (payload) => {
|
||||
assert.deepEqual(payload, {
|
||||
@@ -606,12 +606,12 @@ test_ui("rename_stream", ({override_rewire, mock_template}) => {
|
||||
pin_to_top: true,
|
||||
dark_background: payload.dark_background,
|
||||
});
|
||||
return {to_$: () => li_stub};
|
||||
return {to_$: () => $li_stub};
|
||||
});
|
||||
|
||||
let count_updated;
|
||||
override_rewire(stream_list, "update_count_in_dom", (li) => {
|
||||
assert.equal(li, li_stub);
|
||||
override_rewire(stream_list, "update_count_in_dom", ($li) => {
|
||||
assert.equal($li, $li_stub);
|
||||
count_updated = true;
|
||||
});
|
||||
|
||||
@@ -638,17 +638,17 @@ test_ui("refresh_pin", ({override_rewire, mock_template}) => {
|
||||
pin_to_top: true,
|
||||
};
|
||||
|
||||
const li_stub = $.create("li stub");
|
||||
li_stub.length = 0;
|
||||
const $li_stub = $.create("li stub");
|
||||
$li_stub.length = 0;
|
||||
|
||||
mock_template("stream_sidebar_row.hbs", false, () => ({to_$: () => li_stub}));
|
||||
mock_template("stream_sidebar_row.hbs", false, () => ({to_$: () => $li_stub}));
|
||||
|
||||
override_rewire(stream_list, "update_count_in_dom", noop);
|
||||
$("#stream_filters").append = noop;
|
||||
|
||||
let scrolled;
|
||||
override_rewire(stream_list, "scroll_stream_into_view", (li) => {
|
||||
assert.equal(li, li_stub);
|
||||
override_rewire(stream_list, "scroll_stream_into_view", ($li) => {
|
||||
assert.equal($li, $li_stub);
|
||||
scrolled = true;
|
||||
});
|
||||
|
||||
|
||||
@@ -64,32 +64,32 @@ function clear_search_input() {
|
||||
|
||||
run_test("basics", ({override_rewire}) => {
|
||||
let cursor_helper;
|
||||
const input = $(".stream-list-filter");
|
||||
const section = $(".stream_search_section");
|
||||
const $input = $(".stream-list-filter");
|
||||
const $section = $(".stream_search_section");
|
||||
|
||||
expand_sidebar();
|
||||
section.addClass("notdisplayed");
|
||||
$section.addClass("notdisplayed");
|
||||
|
||||
cursor_helper = make_cursor_helper();
|
||||
|
||||
function verify_expanded() {
|
||||
assert.ok(!section.hasClass("notdisplayed"));
|
||||
assert.ok(!$section.hasClass("notdisplayed"));
|
||||
simulate_search_expanded();
|
||||
}
|
||||
|
||||
function verify_focused() {
|
||||
assert.ok(stream_list.searching());
|
||||
assert.ok(input.is_focused());
|
||||
assert.ok($input.is_focused());
|
||||
}
|
||||
|
||||
function verify_blurred() {
|
||||
assert.ok(stream_list.searching());
|
||||
assert.ok(input.is_focused());
|
||||
assert.ok($input.is_focused());
|
||||
}
|
||||
|
||||
function verify_collapsed() {
|
||||
assert.ok(section.hasClass("notdisplayed"));
|
||||
assert.ok(!input.is_focused());
|
||||
assert.ok($section.hasClass("notdisplayed"));
|
||||
assert.ok(!$input.is_focused());
|
||||
assert.ok(!stream_list.searching());
|
||||
simulate_search_collapsed();
|
||||
}
|
||||
@@ -126,7 +126,7 @@ run_test("basics", ({override_rewire}) => {
|
||||
|
||||
(function add_some_text_and_collapse() {
|
||||
cursor_helper = make_cursor_helper();
|
||||
input.val("foo");
|
||||
$input.val("foo");
|
||||
verify_list_updated(() => {
|
||||
toggle_filter();
|
||||
});
|
||||
@@ -149,7 +149,7 @@ run_test("basics", ({override_rewire}) => {
|
||||
stream_list.initiate_search();
|
||||
|
||||
// Clear a non-empty search.
|
||||
input.val("foo");
|
||||
$input.val("foo");
|
||||
verify_list_updated(() => {
|
||||
clear_search_input();
|
||||
});
|
||||
@@ -160,7 +160,7 @@ run_test("basics", ({override_rewire}) => {
|
||||
stream_list.initiate_search();
|
||||
|
||||
// Escape a non-empty search.
|
||||
input.val("foo");
|
||||
$input.val("foo");
|
||||
stream_list.escape_search();
|
||||
verify_blurred();
|
||||
|
||||
@@ -169,7 +169,7 @@ run_test("basics", ({override_rewire}) => {
|
||||
stream_list.initiate_search();
|
||||
|
||||
// Escape an empty search.
|
||||
input.val("");
|
||||
$input.val("");
|
||||
stream_list.escape_search();
|
||||
verify_collapsed();
|
||||
});
|
||||
|
||||
@@ -9,8 +9,8 @@ const $ = require("../zjsunit/zjquery");
|
||||
const denmark_stream_id = 101;
|
||||
|
||||
const ui = mock_esm("../../static/js/ui", {
|
||||
get_content_element: (element) => element,
|
||||
get_scroll_element: (element) => element,
|
||||
get_content_element: ($element) => $element,
|
||||
get_scroll_element: ($element) => $element,
|
||||
});
|
||||
|
||||
mock_esm("../../static/js/hash_util", {
|
||||
@@ -103,16 +103,16 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
||||
$.create("#manage_streams_container .stream-row", {children: sub_stubs});
|
||||
|
||||
let ui_called = false;
|
||||
ui.reset_scrollbar = (elem) => {
|
||||
ui.reset_scrollbar = ($elem) => {
|
||||
ui_called = true;
|
||||
assert.equal(elem, $("#subscription_overlay .streams-list"));
|
||||
assert.equal($elem, $("#subscription_overlay .streams-list"));
|
||||
};
|
||||
|
||||
// Filtering has the side effect of setting the "active" class
|
||||
// on our current stream, even if it doesn't match the filter.
|
||||
const denmark_row = $(`.stream-row[data-stream-id='${CSS.escape(denmark_stream_id)}']`);
|
||||
const $denmark_row = $(`.stream-row[data-stream-id='${CSS.escape(denmark_stream_id)}']`);
|
||||
// sanity check it's not set to active
|
||||
assert.ok(!denmark_row.hasClass("active"));
|
||||
assert.ok(!$denmark_row.hasClass("active"));
|
||||
|
||||
function test_filter(params, expected_streams) {
|
||||
const stream_ids = stream_settings_ui.redraw_left_panel(params);
|
||||
@@ -127,7 +127,7 @@ run_test("redraw_left_panel", ({mock_template}) => {
|
||||
assert.ok(ui_called);
|
||||
|
||||
// The denmark row is active, even though it's not displayed.
|
||||
assert.ok(denmark_row.hasClass("active"));
|
||||
assert.ok($denmark_row.hasClass("active"));
|
||||
|
||||
// Search with multiple keywords
|
||||
test_filter({input: "Denmark, Pol", subscribed_only: false}, [denmark, poland]);
|
||||
|
||||
@@ -19,14 +19,14 @@ run_test("scrub_realm", () => {
|
||||
$.get_initialize_function()();
|
||||
const click_handler = $("body").get_on_handler("click", ".scrub-realm-button");
|
||||
|
||||
const fake_this = $.create("fake-.scrub-realm-button");
|
||||
fake_this.data = (name) => {
|
||||
const $fake_this = $.create("fake-.scrub-realm-button");
|
||||
$fake_this.data = (name) => {
|
||||
assert.equal(name, "string-id");
|
||||
return "zulip";
|
||||
};
|
||||
|
||||
let submit_form_called = false;
|
||||
fake_this.form = {
|
||||
$fake_this.form = {
|
||||
submit: () => {
|
||||
submit_form_called = true;
|
||||
},
|
||||
@@ -36,7 +36,7 @@ run_test("scrub_realm", () => {
|
||||
};
|
||||
|
||||
window.prompt = () => "zulip";
|
||||
click_handler.call(fake_this, event);
|
||||
click_handler.call($fake_this, event);
|
||||
assert.ok(submit_form_called);
|
||||
|
||||
submit_form_called = false;
|
||||
@@ -45,7 +45,7 @@ run_test("scrub_realm", () => {
|
||||
window.alert = () => {
|
||||
alert_called = true;
|
||||
};
|
||||
click_handler.call(fake_this, event);
|
||||
click_handler.call($fake_this, event);
|
||||
assert.ok(!submit_form_called);
|
||||
assert.ok(alert_called);
|
||||
|
||||
|
||||
@@ -210,20 +210,20 @@ run_test("render_date_renders_time_html", () => {
|
||||
const expected_html = $t({defaultMessage: "Today"});
|
||||
|
||||
const attrs = {};
|
||||
const span_stub = $("<span />");
|
||||
const $span_stub = $("<span />");
|
||||
|
||||
span_stub.attr = (name, val) => {
|
||||
$span_stub.attr = (name, val) => {
|
||||
attrs[name] = val;
|
||||
return span_stub;
|
||||
return $span_stub;
|
||||
};
|
||||
|
||||
span_stub.append = (str) => {
|
||||
span_stub.html(str);
|
||||
return span_stub;
|
||||
$span_stub.append = (str) => {
|
||||
$span_stub.html(str);
|
||||
return $span_stub;
|
||||
};
|
||||
|
||||
const actual = timerender.render_date(message_time, undefined, today);
|
||||
assert.equal(actual.html(), expected_html);
|
||||
const $actual = timerender.render_date(message_time, undefined, today);
|
||||
assert.equal($actual.html(), expected_html);
|
||||
assert.equal(attrs["data-tippy-content"], "Friday, April 12, 2019");
|
||||
assert.equal(attrs.class, "timerender0");
|
||||
});
|
||||
@@ -234,12 +234,12 @@ run_test("render_date_renders_time_above_html", () => {
|
||||
const message_time = today;
|
||||
const message_time_above = add(today, {days: -1});
|
||||
|
||||
const span_stub = $("<span />");
|
||||
const $span_stub = $("<span />");
|
||||
|
||||
let appended_val;
|
||||
span_stub.append = (...val) => {
|
||||
$span_stub.append = (...val) => {
|
||||
appended_val = val;
|
||||
return span_stub;
|
||||
return $span_stub;
|
||||
};
|
||||
|
||||
const expected = [
|
||||
|
||||
@@ -104,12 +104,12 @@ run_test("narrowing", ({override_rewire}) => {
|
||||
});
|
||||
|
||||
run_test("update_count_in_dom", () => {
|
||||
function make_elem(elem, count_selector) {
|
||||
const count = $(count_selector);
|
||||
elem.set_find_results(".unread_count", count);
|
||||
count.set_parent(elem);
|
||||
function make_elem($elem, count_selector) {
|
||||
const $count = $(count_selector);
|
||||
$elem.set_find_results(".unread_count", $count);
|
||||
$count.set_parent($elem);
|
||||
|
||||
return elem;
|
||||
return $elem;
|
||||
}
|
||||
|
||||
const counts = {
|
||||
|
||||
@@ -39,7 +39,7 @@ people.add_active_user(levin);
|
||||
people.add_active_user(kitty);
|
||||
|
||||
run_test("render_notifications_for_narrow", ({override_rewire, mock_template}) => {
|
||||
const typing_notifications = $("#typing_notifications");
|
||||
const $typing_notifications = $("#typing_notifications");
|
||||
|
||||
const two_typing_users_ids = [anna.user_id, vronsky.user_id];
|
||||
const three_typing_users_ids = [anna.user_id, vronsky.user_id, levin.user_id];
|
||||
@@ -51,32 +51,32 @@ run_test("render_notifications_for_narrow", ({override_rewire, mock_template}) =
|
||||
// should be rendered but not 'Several people are typing…'
|
||||
override_rewire(typing_events, "get_users_typing_for_narrow", () => two_typing_users_ids);
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(typing_notifications.visible());
|
||||
assert.ok(typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok($typing_notifications.visible());
|
||||
assert.ok($typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes("Several people are typing…"));
|
||||
|
||||
// Having 3(=MAX_USERS_TO_DISPLAY_NAME) typists should also display only names
|
||||
override_rewire(typing_events, "get_users_typing_for_narrow", () => three_typing_users_ids);
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(typing_notifications.visible());
|
||||
assert.ok(typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok($typing_notifications.visible());
|
||||
assert.ok($typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes("Several people are typing…"));
|
||||
|
||||
// Having 4(>MAX_USERS_TO_DISPLAY_NAME) typists should display "Several people are typing…"
|
||||
override_rewire(typing_events, "get_users_typing_for_narrow", () => four_typing_users_ids);
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(typing_notifications.visible());
|
||||
assert.ok(typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok(!typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!typing_notifications.html().includes(`${kitty.full_name} is typing…`));
|
||||
assert.ok($typing_notifications.visible());
|
||||
assert.ok($typing_notifications.html().includes("Several people are typing…"));
|
||||
assert.ok(!$typing_notifications.html().includes(`${anna.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${vronsky.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${levin.full_name} is typing…`));
|
||||
assert.ok(!$typing_notifications.html().includes(`${kitty.full_name} is typing…`));
|
||||
|
||||
// #typing_notifications should be hidden when there are no typists.
|
||||
override_rewire(typing_events, "get_users_typing_for_narrow", () => []);
|
||||
typing_events.render_notifications_for_narrow();
|
||||
assert.ok(!typing_notifications.visible());
|
||||
assert.ok(!$typing_notifications.visible());
|
||||
});
|
||||
|
||||
@@ -36,14 +36,14 @@ function test(label, f) {
|
||||
}
|
||||
|
||||
test("feature_check", ({override}) => {
|
||||
const upload_button = $.create("upload-button-stub");
|
||||
upload_button.addClass("notdisplayed");
|
||||
upload.feature_check(upload_button);
|
||||
assert.ok(upload_button.hasClass("notdisplayed"));
|
||||
const $upload_button = $.create("upload-button-stub");
|
||||
$upload_button.addClass("notdisplayed");
|
||||
upload.feature_check($upload_button);
|
||||
assert.ok($upload_button.hasClass("notdisplayed"));
|
||||
|
||||
override(window, "XMLHttpRequest", () => ({upload: true}));
|
||||
upload.feature_check(upload_button);
|
||||
assert.ok(!upload_button.hasClass("notdisplayed"));
|
||||
upload.feature_check($upload_button);
|
||||
assert.ok(!$upload_button.hasClass("notdisplayed"));
|
||||
});
|
||||
|
||||
test("get_item", () => {
|
||||
|
||||
@@ -194,7 +194,7 @@ test("filter_user_ids", ({override}) => {
|
||||
});
|
||||
|
||||
test("click on user header to toggle display", ({override}) => {
|
||||
const user_filter = $(".user-list-filter");
|
||||
const $user_filter = $(".user-list-filter");
|
||||
|
||||
override(popovers, "hide_all", () => {});
|
||||
override(popovers, "hide_all_except_sidebars", () => {});
|
||||
@@ -205,11 +205,11 @@ test("click on user header to toggle display", ({override}) => {
|
||||
|
||||
assert.ok(!$("#user_search_section").hasClass("notdisplayed"));
|
||||
|
||||
user_filter.val("bla");
|
||||
$user_filter.val("bla");
|
||||
|
||||
$("#userlist-header").trigger("click");
|
||||
assert.ok($("#user_search_section").hasClass("notdisplayed"));
|
||||
assert.equal(user_filter.val(), "");
|
||||
assert.equal($user_filter.val(), "");
|
||||
|
||||
$(".user-list-filter").closest = (selector) => {
|
||||
assert.equal(selector, ".app-main [class^='column-']");
|
||||
|
||||
@@ -35,16 +35,16 @@ const sample_events = [
|
||||
];
|
||||
|
||||
let events;
|
||||
let widget_elem;
|
||||
let $widget_elem;
|
||||
let is_event_handled;
|
||||
let is_widget_activated;
|
||||
|
||||
const fake_poll_widget = {
|
||||
activate(data) {
|
||||
is_widget_activated = true;
|
||||
widget_elem = data.elem;
|
||||
assert.ok(widget_elem.hasClass("widget-content"));
|
||||
widget_elem.handle_events = (e) => {
|
||||
$widget_elem = data.$elem;
|
||||
assert.ok($widget_elem.hasClass("widget-content"));
|
||||
$widget_elem.handle_events = (e) => {
|
||||
is_event_handled = true;
|
||||
assert.notDeepStrictEqual(e, events);
|
||||
events.shift();
|
||||
@@ -65,7 +65,7 @@ const widgetize = zrequire("widgetize");
|
||||
function test(label, f) {
|
||||
run_test(label, ({override}) => {
|
||||
events = [...sample_events];
|
||||
widget_elem = undefined;
|
||||
$widget_elem = undefined;
|
||||
is_event_handled = false;
|
||||
is_widget_activated = false;
|
||||
widgetize.clear_for_testing();
|
||||
@@ -76,10 +76,10 @@ function test(label, f) {
|
||||
test("activate", ({override}) => {
|
||||
// Both widgetize.activate and widgetize.handle_event are tested
|
||||
// here to use the "caching" of widgets
|
||||
const row = $.create("<stub message row>");
|
||||
row.attr("id", "zhome2909");
|
||||
const message_content = $.create("#zhome2909");
|
||||
row.set_find_results(".message_content", message_content);
|
||||
const $row = $.create("<stub message row>");
|
||||
$row.attr("id", "zhome2909");
|
||||
const $message_content = $.create("#zhome2909");
|
||||
$row.set_find_results(".message_content", $message_content);
|
||||
|
||||
let narrow_active;
|
||||
override(narrow_state, "active", () => narrow_active);
|
||||
@@ -94,16 +94,16 @@ test("activate", ({override}) => {
|
||||
assert.equal(data.msg_type, "widget");
|
||||
assert.equal(data.data, "test_data");
|
||||
},
|
||||
row,
|
||||
$row,
|
||||
widget_type: "poll",
|
||||
};
|
||||
|
||||
let is_widget_elem_inserted;
|
||||
|
||||
message_content.append = (elem) => {
|
||||
$message_content.append = ($elem) => {
|
||||
is_widget_elem_inserted = true;
|
||||
assert.equal(elem, widget_elem);
|
||||
assert.ok(elem.hasClass("widget-content"));
|
||||
assert.equal($elem, $widget_elem);
|
||||
assert.ok($elem.hasClass("widget-content"));
|
||||
};
|
||||
|
||||
is_widget_elem_inserted = false;
|
||||
@@ -111,19 +111,19 @@ test("activate", ({override}) => {
|
||||
is_event_handled = false;
|
||||
assert.ok(!widgetize.widget_contents.has(opts.message.id));
|
||||
|
||||
message_content.set_find_results(".widget-content", false);
|
||||
$message_content.set_find_results(".widget-content", false);
|
||||
widgetize.activate(opts);
|
||||
|
||||
assert.ok(is_widget_elem_inserted);
|
||||
assert.ok(is_widget_activated);
|
||||
assert.ok(is_event_handled);
|
||||
assert.equal(widgetize.widget_contents.get(opts.message.id), widget_elem);
|
||||
assert.equal(widgetize.widget_contents.get(opts.message.id), $widget_elem);
|
||||
|
||||
is_widget_elem_inserted = false;
|
||||
is_widget_activated = false;
|
||||
is_event_handled = false;
|
||||
|
||||
message_content.set_find_results(".widget-content", false);
|
||||
$message_content.set_find_results(".widget-content", false);
|
||||
widgetize.activate(opts);
|
||||
|
||||
assert.ok(is_widget_elem_inserted);
|
||||
@@ -135,7 +135,7 @@ test("activate", ({override}) => {
|
||||
is_widget_activated = false;
|
||||
is_event_handled = false;
|
||||
|
||||
message_content.set_find_results(".widget-content", false);
|
||||
$message_content.set_find_results(".widget-content", false);
|
||||
widgetize.activate(opts);
|
||||
|
||||
assert.ok(!is_widget_elem_inserted);
|
||||
@@ -171,7 +171,7 @@ test("activate", ({override}) => {
|
||||
message_id: 2001,
|
||||
sender_id: 102,
|
||||
};
|
||||
widget_elem.handle_events = (e) => {
|
||||
$widget_elem.handle_events = (e) => {
|
||||
is_event_handled = true;
|
||||
assert.deepEqual(e, [post_activate_event]);
|
||||
};
|
||||
@@ -191,7 +191,7 @@ test("activate", ({override}) => {
|
||||
});
|
||||
override(message_lists.current, "get_row", (idx) => {
|
||||
assert.equal(idx, 2001);
|
||||
return row;
|
||||
return $row;
|
||||
});
|
||||
widgetize.set_widgets_for_list();
|
||||
});
|
||||
|
||||
@@ -45,28 +45,28 @@ run_test("basics", () => {
|
||||
|
||||
// Next, look at how several functions correctly simulate setting
|
||||
// and getting for you.
|
||||
const widget = $("#my-widget");
|
||||
const $widget = $("#my-widget");
|
||||
|
||||
widget.attr("data-employee-id", 42);
|
||||
assert.equal(widget.attr("data-employee-id"), 42);
|
||||
assert.equal(widget.data("employee-id"), 42);
|
||||
$widget.attr("data-employee-id", 42);
|
||||
assert.equal($widget.attr("data-employee-id"), 42);
|
||||
assert.equal($widget.data("employee-id"), 42);
|
||||
|
||||
widget.data("department-id", 77);
|
||||
assert.equal(widget.attr("data-department-id"), 77);
|
||||
assert.equal(widget.data("department-id"), 77);
|
||||
$widget.data("department-id", 77);
|
||||
assert.equal($widget.attr("data-department-id"), 77);
|
||||
assert.equal($widget.data("department-id"), 77);
|
||||
|
||||
widget.data("department-name", "hr");
|
||||
assert.equal(widget.attr("data-department-name"), "hr");
|
||||
assert.equal(widget.data("department-name"), "hr");
|
||||
$widget.data("department-name", "hr");
|
||||
assert.equal($widget.attr("data-department-name"), "hr");
|
||||
assert.equal($widget.data("department-name"), "hr");
|
||||
|
||||
widget.html("<b>hello</b>");
|
||||
assert.equal(widget.html(), "<b>hello</b>");
|
||||
$widget.html("<b>hello</b>");
|
||||
assert.equal($widget.html(), "<b>hello</b>");
|
||||
|
||||
widget.prop("title", "My widget");
|
||||
assert.equal(widget.prop("title"), "My widget");
|
||||
$widget.prop("title", "My widget");
|
||||
assert.equal($widget.prop("title"), "My widget");
|
||||
|
||||
widget.val("42");
|
||||
assert.equal(widget.val(), "42");
|
||||
$widget.val("42");
|
||||
assert.equal($widget.val(), "42");
|
||||
});
|
||||
|
||||
run_test("finding_related_objects", () => {
|
||||
@@ -84,17 +84,17 @@ run_test("finding_related_objects", () => {
|
||||
// But you can set up your tests to simulate DOM relationships.
|
||||
//
|
||||
// We will use set_find_results(), which is a special zjquery helper.
|
||||
const emoji = $('<div class="emoji">');
|
||||
$("#my-message").set_find_results(".emoji", emoji);
|
||||
const $emoji = $('<div class="emoji">');
|
||||
$("#my-message").set_find_results(".emoji", $emoji);
|
||||
|
||||
// And then calling the function produces the desired effect:
|
||||
update_message_emoji("foo.png");
|
||||
assert.equal(emoji.attr("src"), "foo.png");
|
||||
assert.equal($emoji.attr("src"), "foo.png");
|
||||
|
||||
// Sometimes you want to deliberately test paths that do not find an
|
||||
// element. You can pass 'false' as the result for those cases.
|
||||
emoji.set_find_results(".random", false);
|
||||
assert.equal(emoji.find(".random").length, 0);
|
||||
$emoji.set_find_results(".random", false);
|
||||
assert.equal($emoji.find(".random").length, 0);
|
||||
/*
|
||||
An important thing to understand is that zjquery doesn't truly
|
||||
simulate DOM. The way you make relationships work in zjquery
|
||||
@@ -103,12 +103,12 @@ run_test("finding_related_objects", () => {
|
||||
Here is another example.
|
||||
*/
|
||||
|
||||
const my_parents = $("#folder1,#folder4");
|
||||
const elem = $("#folder555");
|
||||
const $my_parents = $("#folder1,#folder4");
|
||||
const $elem = $("#folder555");
|
||||
|
||||
elem.set_parents_result(".folder", my_parents);
|
||||
elem.parents(".folder").addClass("active");
|
||||
assert.ok(my_parents.hasClass("active"));
|
||||
$elem.set_parents_result(".folder", $my_parents);
|
||||
$elem.parents(".folder").addClass("active");
|
||||
assert.ok($my_parents.hasClass("active"));
|
||||
});
|
||||
|
||||
run_test("clicks", () => {
|
||||
@@ -188,12 +188,12 @@ run_test("create", () => {
|
||||
// You can create jQuery objects that aren't tied to any particular
|
||||
// selector, and which just have a name.
|
||||
|
||||
const obj1 = $.create("the table holding employees");
|
||||
const obj2 = $.create("the collection of rows in the table");
|
||||
const $obj1 = $.create("the table holding employees");
|
||||
const $obj2 = $.create("the collection of rows in the table");
|
||||
|
||||
obj1.show();
|
||||
assert.ok(obj1.visible());
|
||||
$obj1.show();
|
||||
assert.ok($obj1.visible());
|
||||
|
||||
obj2.addClass(".striped");
|
||||
assert.ok(obj2.hasClass(".striped"));
|
||||
$obj2.addClass(".striped");
|
||||
assert.ok($obj2.hasClass(".striped"));
|
||||
});
|
||||
|
||||
@@ -331,8 +331,8 @@ class CommonUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
const row = zulip_test.last_visible_row();
|
||||
if (zulip_test.row_id(row) !== last_msg.id) {
|
||||
const $row = zulip_test.last_visible_row();
|
||||
if (zulip_test.row_id($row) !== last_msg.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ class CommonUtils {
|
||||
don't add the star icon until the server
|
||||
responds.
|
||||
*/
|
||||
return row.find(".star").length === 1;
|
||||
return $row.find(".star").length === 1;
|
||||
},
|
||||
{},
|
||||
content,
|
||||
|
||||
@@ -31,8 +31,8 @@ async function copy_messages(
|
||||
$("body").trigger(new $.Event("keydown", {which: 67, ctrlKey: true}));
|
||||
|
||||
// find temp div with copied text
|
||||
const temp_div = $("#copytempdiv");
|
||||
return temp_div
|
||||
const $temp_div = $("#copytempdiv");
|
||||
return $temp_div
|
||||
.children("p")
|
||||
.get()
|
||||
.map((p) => p.textContent!);
|
||||
|
||||
@@ -4,10 +4,10 @@ import common from "../puppeteer_lib/common";
|
||||
|
||||
async function click_delete_and_return_last_msg_id(page: Page): Promise<string | undefined> {
|
||||
return await page.evaluate(() => {
|
||||
const msg = $("#zhome .message_row").last();
|
||||
msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
const $msg = $("#zhome .message_row").last();
|
||||
$msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
$(".delete_message").trigger("click");
|
||||
return msg.attr("id");
|
||||
return $msg.attr("id");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import common from "../puppeteer_lib/common";
|
||||
|
||||
async function trigger_edit_last_message(page: Page): Promise<void> {
|
||||
await page.evaluate(() => {
|
||||
const msg = $("#zhome .message_row").last();
|
||||
msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
const $msg = $("#zhome .message_row").last();
|
||||
$msg.find(".message_control_button.actions_hover").trigger("click");
|
||||
$(".popover_edit_message").trigger("click");
|
||||
});
|
||||
await page.waitForSelector(".message_edit_content", {visible: true});
|
||||
|
||||
@@ -12,17 +12,17 @@ async function stars_count(page: Page): Promise<number> {
|
||||
|
||||
async function toggle_test_star_message(page: Page): Promise<void> {
|
||||
await page.evaluate((message: string) => {
|
||||
const msg = $(`.message_content:contains("${CSS.escape(message)}"):visible`).last();
|
||||
if (msg.length !== 1) {
|
||||
const $msg = $(`.message_content:contains("${CSS.escape(message)}"):visible`).last();
|
||||
if ($msg.length !== 1) {
|
||||
throw new Error("cannot find test star message");
|
||||
}
|
||||
|
||||
const star_icon = msg.closest(".messagebox").find(".star");
|
||||
if (star_icon.length !== 1) {
|
||||
const $star_icon = $msg.closest(".messagebox").find(".star");
|
||||
if ($star_icon.length !== 1) {
|
||||
throw new Error("cannot find star icon");
|
||||
}
|
||||
|
||||
star_icon.trigger("click");
|
||||
$star_icon.trigger("click");
|
||||
}, message);
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ exports.mock_cjs = (module_path, obj) => {
|
||||
};
|
||||
|
||||
exports.mock_jquery = ($) => {
|
||||
jquery_function = $;
|
||||
jquery_function = $; // eslint-disable-line no-jquery/variable-pattern
|
||||
return $;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ function make_zjquery() {
|
||||
const fn = {};
|
||||
|
||||
function new_elem(selector, create_opts) {
|
||||
const elem = FakeElement(selector, {...create_opts});
|
||||
Object.assign(elem, fn);
|
||||
const $elem = FakeElement(selector, {...create_opts});
|
||||
Object.assign($elem, fn);
|
||||
|
||||
// Create a proxy handler to detect missing stubs.
|
||||
//
|
||||
@@ -76,7 +76,7 @@ function make_zjquery() {
|
||||
},
|
||||
};
|
||||
|
||||
const proxy = new Proxy(elem, handler);
|
||||
const proxy = new Proxy($elem, handler);
|
||||
|
||||
return proxy;
|
||||
}
|
||||
@@ -130,8 +130,8 @@ function make_zjquery() {
|
||||
verify_selector_for_zulip(selector);
|
||||
|
||||
if (!elems.has(selector)) {
|
||||
const elem = new_elem(selector);
|
||||
elems.set(selector, elem);
|
||||
const $elem = new_elem(selector);
|
||||
elems.set(selector, $elem);
|
||||
}
|
||||
return elems.get(selector);
|
||||
};
|
||||
@@ -146,10 +146,10 @@ function make_zjquery() {
|
||||
|
||||
zjquery.create = function (name, opts) {
|
||||
assert.ok(!elems.has(name), "You already created an object with this name!!");
|
||||
const elem = new_elem(name, opts);
|
||||
elems.set(name, elem);
|
||||
const $elem = new_elem(name, opts);
|
||||
elems.set(name, $elem);
|
||||
|
||||
return elem;
|
||||
return $elem;
|
||||
};
|
||||
|
||||
zjquery.trim = function (s) {
|
||||
@@ -250,4 +250,4 @@ const $ = new Proxy(make_zjquery(), {
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = $;
|
||||
module.exports = $; // eslint-disable-line no-jquery/variable-pattern
|
||||
|
||||
@@ -15,38 +15,38 @@ function FakeElement(selector, opts) {
|
||||
let height;
|
||||
|
||||
const find_results = new Map();
|
||||
let my_parent;
|
||||
let $my_parent;
|
||||
const parents_result = new Map();
|
||||
const properties = new Map();
|
||||
const attrs = new Map();
|
||||
const classes = new Map();
|
||||
const event_store = make_event_store(selector);
|
||||
|
||||
const self = {
|
||||
const $self = {
|
||||
addClass(class_name) {
|
||||
classes.set(class_name, true);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
append(arg) {
|
||||
html = html + arg;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
attr(name, val) {
|
||||
if (val === undefined) {
|
||||
return attrs.get(name);
|
||||
}
|
||||
attrs.set(name, val);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
data(name, val) {
|
||||
if (val === undefined) {
|
||||
return attrs.get("data-" + name);
|
||||
}
|
||||
attrs.set("data-" + name, val);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
delay() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
debug() {
|
||||
return {
|
||||
@@ -59,22 +59,22 @@ function FakeElement(selector, opts) {
|
||||
if (arg === undefined) {
|
||||
find_results.clear();
|
||||
}
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
eq() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
expectOne() {
|
||||
// silently do nothing
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
fadeTo: noop,
|
||||
find(child_selector) {
|
||||
const child = find_results.get(child_selector);
|
||||
if (child) {
|
||||
return child;
|
||||
const $child = find_results.get(child_selector);
|
||||
if ($child) {
|
||||
return $child;
|
||||
}
|
||||
if (child === false) {
|
||||
if ($child === false) {
|
||||
// This is deliberately set to simulate missing find results.
|
||||
// Return an empty array, the most common check is
|
||||
// if ($.find().length) { //success }
|
||||
@@ -84,12 +84,12 @@ function FakeElement(selector, opts) {
|
||||
We need you to simulate the results of $(...).find(...)
|
||||
by using set_find_results. You want something like this:
|
||||
|
||||
const container = ...;
|
||||
const child = ...;
|
||||
container.set_find_results("${child_selector}", child);
|
||||
const $container = ...;
|
||||
const $child = ...;
|
||||
$container.set_find_results("${child_selector}", $child);
|
||||
|
||||
Then calling container.find("${child_selector}") will return
|
||||
the "child" zjquery element.
|
||||
Then calling $container.find("${child_selector}") will return
|
||||
the "$child" zjquery element.
|
||||
|
||||
`);
|
||||
},
|
||||
@@ -107,12 +107,12 @@ function FakeElement(selector, opts) {
|
||||
},
|
||||
hide() {
|
||||
shown = false;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
html(arg) {
|
||||
if (arg !== undefined) {
|
||||
html = arg;
|
||||
return self;
|
||||
return $self;
|
||||
}
|
||||
return html;
|
||||
},
|
||||
@@ -121,9 +121,9 @@ function FakeElement(selector, opts) {
|
||||
return shown;
|
||||
}
|
||||
if (arg === ":focus") {
|
||||
return self.is_focused();
|
||||
return $self.is_focused();
|
||||
}
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
is_focused() {
|
||||
// is_focused is not a jQuery thing; this is
|
||||
@@ -132,7 +132,7 @@ function FakeElement(selector, opts) {
|
||||
},
|
||||
off(...args) {
|
||||
event_store.off(...args);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
offset() {
|
||||
return {
|
||||
@@ -142,44 +142,44 @@ function FakeElement(selector, opts) {
|
||||
},
|
||||
on(...args) {
|
||||
event_store.on(...args);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
one(...args) {
|
||||
event_store.one(...args);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
parent() {
|
||||
return my_parent;
|
||||
return $my_parent;
|
||||
},
|
||||
parents(parents_selector) {
|
||||
const result = parents_result.get(parents_selector);
|
||||
const $result = parents_result.get(parents_selector);
|
||||
assert.ok(
|
||||
result,
|
||||
$result,
|
||||
"You need to call set_parents_result for " + parents_selector + " in " + selector,
|
||||
);
|
||||
return result;
|
||||
return $result;
|
||||
},
|
||||
prepend(arg) {
|
||||
html = arg + html;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
prop(name, val) {
|
||||
if (val === undefined) {
|
||||
return properties.get(name);
|
||||
}
|
||||
properties.set(name, val);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
removeAttr(name) {
|
||||
attrs.delete(name);
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
removeClass(class_names) {
|
||||
class_names = class_names.split(" ");
|
||||
for (const class_name of class_names) {
|
||||
classes.delete(class_name);
|
||||
}
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
remove() {
|
||||
throw new Error(`
|
||||
@@ -193,68 +193,68 @@ function FakeElement(selector, opts) {
|
||||
},
|
||||
removeData: noop,
|
||||
replaceWith() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
scrollTop() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
serializeArray() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
set_find_results(find_selector, jquery_object) {
|
||||
if (jquery_object === undefined) {
|
||||
set_find_results(find_selector, $jquery_object) {
|
||||
if ($jquery_object === undefined) {
|
||||
throw new Error(
|
||||
"Please make the 'find result' be something like $.create('unused')",
|
||||
);
|
||||
}
|
||||
find_results.set(find_selector, jquery_object);
|
||||
find_results.set(find_selector, $jquery_object);
|
||||
},
|
||||
set_height(fake_height) {
|
||||
height = fake_height;
|
||||
},
|
||||
set_parent(parent_elem) {
|
||||
my_parent = parent_elem;
|
||||
set_parent($parent_elem) {
|
||||
$my_parent = $parent_elem;
|
||||
},
|
||||
set_parents_result(selector, result) {
|
||||
parents_result.set(selector, result);
|
||||
set_parents_result(selector, $result) {
|
||||
parents_result.set(selector, $result);
|
||||
},
|
||||
show() {
|
||||
shown = true;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
slice() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
stop() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
text(...args) {
|
||||
if (args.length !== 0) {
|
||||
if (args[0] !== undefined) {
|
||||
text = args[0].toString();
|
||||
}
|
||||
return self;
|
||||
return $self;
|
||||
}
|
||||
return text;
|
||||
},
|
||||
toggle(show) {
|
||||
assert.ok([true, false].includes(show));
|
||||
shown = show;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
tooltip() {
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
trigger(ev) {
|
||||
event_store.trigger(self, ev);
|
||||
return self;
|
||||
event_store.trigger($self, ev);
|
||||
return $self;
|
||||
},
|
||||
val(...args) {
|
||||
if (args.length === 0) {
|
||||
return value || "";
|
||||
}
|
||||
[value] = args;
|
||||
return self;
|
||||
return $self;
|
||||
},
|
||||
visible() {
|
||||
return shown;
|
||||
@@ -262,34 +262,34 @@ function FakeElement(selector, opts) {
|
||||
};
|
||||
|
||||
if (opts.children) {
|
||||
self.map = (f) => opts.children.map((i, elem) => f(elem, i));
|
||||
self.each = (f) => {
|
||||
$self.map = (f) => opts.children.map((i, elem) => f(elem, i));
|
||||
$self.each = (f) => {
|
||||
for (const child of opts.children) {
|
||||
f.call(child);
|
||||
}
|
||||
};
|
||||
self[Symbol.iterator] = function* () {
|
||||
$self[Symbol.iterator] = function* () {
|
||||
for (const child of opts.children) {
|
||||
yield child;
|
||||
}
|
||||
};
|
||||
|
||||
for (const [i, child] of opts.children.entries()) {
|
||||
self[i] = child;
|
||||
$self[i] = child;
|
||||
}
|
||||
|
||||
self.length = opts.children.length;
|
||||
$self.length = opts.children.length;
|
||||
}
|
||||
|
||||
if (selector[0] === "<") {
|
||||
self.html(selector);
|
||||
$self.html(selector);
|
||||
}
|
||||
|
||||
self.selector = selector;
|
||||
$self.selector = selector;
|
||||
|
||||
self.__zjquery = true;
|
||||
$self.__zjquery = true;
|
||||
|
||||
return self;
|
||||
return $self;
|
||||
}
|
||||
|
||||
function make_event_store(selector) {
|
||||
@@ -394,7 +394,8 @@ function make_event_store(selector) {
|
||||
ev = new FakeEvent(ev);
|
||||
}
|
||||
if (!ev.target) {
|
||||
ev.target = $element;
|
||||
// FIXME: event.target should not be a jQuery object
|
||||
ev.target = $element; // eslint-disable-line no-jquery/variable-pattern
|
||||
}
|
||||
const func = on_functions.get(ev.type);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import {page_params} from "./page_params";
|
||||
export function launch() {
|
||||
overlays.open_overlay({
|
||||
name: "about-zulip",
|
||||
overlay: $("#about-zulip"),
|
||||
$overlay: $("#about-zulip"),
|
||||
on_close() {
|
||||
browser_history.exit_overlay();
|
||||
},
|
||||
|
||||
@@ -59,8 +59,8 @@ function get_pm_list_item(user_id) {
|
||||
}
|
||||
|
||||
function set_pm_count(user_ids_string, count) {
|
||||
const pm_li = get_pm_list_item(user_ids_string);
|
||||
ui_util.update_unread_count_in_dom(pm_li, count);
|
||||
const $pm_li = get_pm_list_item(user_ids_string);
|
||||
ui_util.update_unread_count_in_dom($pm_li, count);
|
||||
}
|
||||
|
||||
export function update_dom_with_unread_counts(counts) {
|
||||
@@ -285,7 +285,7 @@ export function reset_users() {
|
||||
}
|
||||
|
||||
export function narrow_for_user(opts) {
|
||||
const user_id = buddy_list.get_key_from_li({li: opts.li});
|
||||
const user_id = buddy_list.get_key_from_li({$li: opts.$li});
|
||||
return narrow_for_user_id({user_id});
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ export function set_cursor_and_filter() {
|
||||
$input.on("blur", () => user_cursor.clear());
|
||||
|
||||
keydown_util.handle({
|
||||
elem: $input,
|
||||
$elem: $input,
|
||||
handlers: {
|
||||
Enter() {
|
||||
keydown_enter_key();
|
||||
|
||||
@@ -34,19 +34,19 @@ function get_text_from_item(item) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function set_up_pill_typeahead({pill_widget, pill_container, get_users}) {
|
||||
function set_up_pill_typeahead({pill_widget, $pill_container, get_users}) {
|
||||
const opts = {
|
||||
user_source: get_users,
|
||||
stream: true,
|
||||
user_group: true,
|
||||
user: true,
|
||||
};
|
||||
pill_typeahead.set_up(pill_container.find(".input"), pill_widget, opts);
|
||||
pill_typeahead.set_up($pill_container.find(".input"), pill_widget, opts);
|
||||
}
|
||||
|
||||
export function create({pill_container, get_potential_subscribers}) {
|
||||
export function create({$pill_container, get_potential_subscribers}) {
|
||||
const pill_widget = input_pill.create({
|
||||
container: pill_container,
|
||||
$container: $pill_container,
|
||||
create_item_from_text,
|
||||
get_text_from_item,
|
||||
});
|
||||
@@ -56,7 +56,7 @@ export function create({pill_container, get_potential_subscribers}) {
|
||||
return user_pill.filter_taken_users(potential_subscribers, pill_widget);
|
||||
}
|
||||
|
||||
set_up_pill_typeahead({pill_widget, pill_container, get_users});
|
||||
set_up_pill_typeahead({pill_widget, $pill_container, get_users});
|
||||
|
||||
return pill_widget;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ function get_pill_user_ids(pill_widget) {
|
||||
|
||||
export function set_up_handlers({
|
||||
get_pill_widget,
|
||||
parent_container,
|
||||
$parent_container,
|
||||
pill_selector,
|
||||
button_selector,
|
||||
action,
|
||||
@@ -108,14 +108,14 @@ export function set_up_handlers({
|
||||
action({pill_user_ids});
|
||||
}
|
||||
|
||||
parent_container.on("keyup", pill_selector, (e) => {
|
||||
$parent_container.on("keyup", pill_selector, (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
parent_container.on("click", button_selector, (e) => {
|
||||
$parent_container.on("click", button_selector, (e) => {
|
||||
e.preventDefault();
|
||||
callback();
|
||||
});
|
||||
|
||||
@@ -16,15 +16,15 @@ export function rerender_alert_words_ui() {
|
||||
|
||||
const words = alert_words.get_word_list();
|
||||
words.sort();
|
||||
const word_list = $("#alert-words-table");
|
||||
const $word_list = $("#alert-words-table");
|
||||
|
||||
ListWidget.create(word_list, words, {
|
||||
ListWidget.create($word_list, words, {
|
||||
name: "alert-words-list",
|
||||
modifier(alert_word) {
|
||||
return render_alert_word_settings_item({alert_word});
|
||||
},
|
||||
parent_container: $("#alert-word-settings"),
|
||||
simplebar_container: $("#alert-word-settings .progressive-table-wrapper"),
|
||||
$parent_container: $("#alert-word-settings"),
|
||||
$simplebar_container: $("#alert-word-settings .progressive-table-wrapper"),
|
||||
});
|
||||
|
||||
// Focus new alert word name text box.
|
||||
@@ -32,14 +32,14 @@ export function rerender_alert_words_ui() {
|
||||
}
|
||||
|
||||
function update_alert_word_status(status_text, is_error) {
|
||||
const alert_word_status = $("#alert_word_status");
|
||||
const $alert_word_status = $("#alert_word_status");
|
||||
if (is_error) {
|
||||
alert_word_status.removeClass("alert-success").addClass("alert-danger");
|
||||
$alert_word_status.removeClass("alert-success").addClass("alert-danger");
|
||||
} else {
|
||||
alert_word_status.removeClass("alert-danger").addClass("alert-success");
|
||||
$alert_word_status.removeClass("alert-danger").addClass("alert-success");
|
||||
}
|
||||
alert_word_status.find(".alert_word_status_text").text(status_text);
|
||||
alert_word_status.show();
|
||||
$alert_word_status.find(".alert_word_status_text").text(status_text);
|
||||
$alert_word_status.show();
|
||||
}
|
||||
|
||||
function add_alert_word(alert_word) {
|
||||
@@ -114,8 +114,8 @@ export function set_up_alert_words() {
|
||||
|
||||
$("#alert-word-settings").on("click", ".close-alert-word-status", (event) => {
|
||||
event.preventDefault();
|
||||
const alert = $(event.currentTarget).parents(".alert");
|
||||
alert.hide();
|
||||
const $alert = $(event.currentTarget).parents(".alert");
|
||||
$alert.hide();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -50,15 +50,15 @@ function set_upload_space_stats() {
|
||||
}
|
||||
|
||||
function delete_attachments(attachment) {
|
||||
const status = $("#delete-upload-status");
|
||||
const $status = $("#delete-upload-status");
|
||||
channel.del({
|
||||
url: "/json/attachments/" + attachment,
|
||||
idempotent: true,
|
||||
error(xhr) {
|
||||
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, status);
|
||||
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, $status);
|
||||
},
|
||||
success() {
|
||||
ui_report.success($t_html({defaultMessage: "Attachment deleted"}), status);
|
||||
ui_report.success($t_html({defaultMessage: "Attachment deleted"}), $status);
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -86,32 +86,32 @@ function sort_mentioned_in(a, b) {
|
||||
function render_attachments_ui() {
|
||||
set_upload_space_stats();
|
||||
|
||||
const uploaded_files_table = $("#uploaded_files_table").expectOne();
|
||||
const $uploaded_files_table = $("#uploaded_files_table").expectOne();
|
||||
const $search_input = $("#upload_file_search");
|
||||
|
||||
ListWidget.create(uploaded_files_table, attachments, {
|
||||
ListWidget.create($uploaded_files_table, attachments, {
|
||||
name: "uploaded-files-list",
|
||||
modifier(attachment) {
|
||||
return render_uploaded_files_list({attachment});
|
||||
},
|
||||
filter: {
|
||||
element: $search_input,
|
||||
$element: $search_input,
|
||||
predicate(item, value) {
|
||||
return item.name.toLocaleLowerCase().includes(value);
|
||||
},
|
||||
onupdate() {
|
||||
ui.reset_scrollbar(uploaded_files_table.closest(".progressive-table-wrapper"));
|
||||
ui.reset_scrollbar($uploaded_files_table.closest(".progressive-table-wrapper"));
|
||||
},
|
||||
},
|
||||
parent_container: $("#attachments-settings").expectOne(),
|
||||
$parent_container: $("#attachments-settings").expectOne(),
|
||||
init_sort: ["numeric", "create_time"],
|
||||
sort_fields: {
|
||||
mentioned_in: sort_mentioned_in,
|
||||
},
|
||||
simplebar_container: $("#attachments-settings .progressive-table-wrapper"),
|
||||
$simplebar_container: $("#attachments-settings .progressive-table-wrapper"),
|
||||
});
|
||||
|
||||
ui.reset_scrollbar(uploaded_files_table.closest(".progressive-table-wrapper"));
|
||||
ui.reset_scrollbar($uploaded_files_table.closest(".progressive-table-wrapper"));
|
||||
}
|
||||
|
||||
function format_attachment_data(new_attachments) {
|
||||
@@ -143,7 +143,7 @@ export function update_attachments(event) {
|
||||
export function set_up_attachments() {
|
||||
// The settings page must be rendered before this function gets called.
|
||||
|
||||
const status = $("#delete-upload-status");
|
||||
const $status = $("#delete-upload-status");
|
||||
loading.make_indicator($("#attachments_loading_indicator"), {text: "Loading..."});
|
||||
|
||||
$("#uploaded_files_table").on("click", ".remove-attachment", (e) => {
|
||||
@@ -162,7 +162,7 @@ export function set_up_attachments() {
|
||||
},
|
||||
error(xhr) {
|
||||
loading.destroy_indicator($("#attachments_loading_indicator"));
|
||||
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, status);
|
||||
ui_report.error($t_html({defaultMessage: "Failed"}), xhr, $status);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,36 +17,36 @@ export function build_bot_create_widget() {
|
||||
return $("#bot_avatar_file_input");
|
||||
};
|
||||
|
||||
const file_name_field = $("#bot_avatar_file");
|
||||
const input_error = $("#bot_avatar_file_input_error");
|
||||
const clear_button = $("#bot_avatar_clear_button");
|
||||
const upload_button = $("#bot_avatar_upload_button");
|
||||
const $file_name_field = $("#bot_avatar_file");
|
||||
const $input_error = $("#bot_avatar_file_input_error");
|
||||
const $clear_button = $("#bot_avatar_clear_button");
|
||||
const $upload_button = $("#bot_avatar_upload_button");
|
||||
|
||||
return upload_widget.build_widget(
|
||||
get_file_input,
|
||||
file_name_field,
|
||||
input_error,
|
||||
clear_button,
|
||||
upload_button,
|
||||
$file_name_field,
|
||||
$input_error,
|
||||
$clear_button,
|
||||
$upload_button,
|
||||
);
|
||||
}
|
||||
|
||||
export function build_bot_edit_widget(target) {
|
||||
export function build_bot_edit_widget($target) {
|
||||
const get_file_input = function () {
|
||||
return target.find(".edit_bot_avatar_file_input");
|
||||
return $target.find(".edit_bot_avatar_file_input");
|
||||
};
|
||||
|
||||
const file_name_field = target.find(".edit_bot_avatar_file");
|
||||
const input_error = target.find(".edit_bot_avatar_error");
|
||||
const clear_button = target.find(".edit_bot_avatar_clear_button");
|
||||
const upload_button = target.find(".edit_bot_avatar_upload_button");
|
||||
const $file_name_field = $target.find(".edit_bot_avatar_file");
|
||||
const $input_error = $target.find(".edit_bot_avatar_error");
|
||||
const $clear_button = $target.find(".edit_bot_avatar_clear_button");
|
||||
const $upload_button = $target.find(".edit_bot_avatar_upload_button");
|
||||
|
||||
return upload_widget.build_widget(
|
||||
get_file_input,
|
||||
file_name_field,
|
||||
input_error,
|
||||
clear_button,
|
||||
upload_button,
|
||||
$file_name_field,
|
||||
$input_error,
|
||||
$clear_button,
|
||||
$upload_button,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ export function create_ajax_request(
|
||||
type = "POST",
|
||||
success_callback,
|
||||
) {
|
||||
const form = $(`#${CSS.escape(form_name)}-form`);
|
||||
const $form = $(`#${CSS.escape(form_name)}-form`);
|
||||
const form_loading_indicator = `#${CSS.escape(form_name)}_loading_indicator`;
|
||||
const form_input_section = `#${CSS.escape(form_name)}-input-section`;
|
||||
const form_success = `#${CSS.escape(form_name)}-success`;
|
||||
@@ -32,7 +32,7 @@ export function create_ajax_request(
|
||||
|
||||
const data = {};
|
||||
|
||||
for (const item of form.serializeArray()) {
|
||||
for (const item of $form.serializeArray()) {
|
||||
if (ignored_inputs.includes(item.name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ class BuddyListConf {
|
||||
|
||||
get_li_from_key(opts) {
|
||||
const user_id = opts.key;
|
||||
const container = $(this.container_sel);
|
||||
return container.find(`${this.item_sel}[data-user-id='${CSS.escape(user_id)}']`);
|
||||
const $container = $(this.container_sel);
|
||||
return $container.find(`${this.item_sel}[data-user-id='${CSS.escape(user_id)}']`);
|
||||
}
|
||||
|
||||
get_key_from_li(opts) {
|
||||
return Number.parseInt(opts.li.expectOne().attr("data-user-id"), 10);
|
||||
return Number.parseInt(opts.$li.expectOne().attr("data-user-id"), 10);
|
||||
}
|
||||
|
||||
get_data_from_keys(opts) {
|
||||
@@ -60,7 +60,7 @@ export class BuddyList extends BuddyListConf {
|
||||
|
||||
populate(opts) {
|
||||
this.render_count = 0;
|
||||
this.container.html("");
|
||||
this.$container.html("");
|
||||
|
||||
// We rely on our caller to give us items
|
||||
// in already-sorted order.
|
||||
@@ -88,8 +88,8 @@ export class BuddyList extends BuddyListConf {
|
||||
const html = this.items_to_html({
|
||||
items,
|
||||
});
|
||||
this.container = $(this.container_sel);
|
||||
this.container.append(html);
|
||||
this.$container = $(this.container_sel);
|
||||
this.$container.append(html);
|
||||
|
||||
// Invariant: more_keys.length >= items.length.
|
||||
// (Usually they're the same, but occasionally keys
|
||||
@@ -102,8 +102,8 @@ export class BuddyList extends BuddyListConf {
|
||||
}
|
||||
|
||||
get_items() {
|
||||
const obj = this.container.find(`${this.item_sel}`);
|
||||
return obj.map((i, elem) => $(elem));
|
||||
const $obj = this.$container.find(`${this.item_sel}`);
|
||||
return $obj.map((i, elem) => $(elem));
|
||||
}
|
||||
|
||||
first_key() {
|
||||
@@ -141,8 +141,8 @@ export class BuddyList extends BuddyListConf {
|
||||
|
||||
if (pos < this.render_count) {
|
||||
this.render_count -= 1;
|
||||
const li = this.find_li({key: opts.key});
|
||||
li.remove();
|
||||
const $li = this.find_li({key: opts.key});
|
||||
$li.remove();
|
||||
this.update_padding();
|
||||
}
|
||||
}
|
||||
@@ -182,18 +182,18 @@ export class BuddyList extends BuddyListConf {
|
||||
const key = opts.key;
|
||||
|
||||
// Try direct DOM lookup first for speed.
|
||||
let li = this.get_li_from_key({
|
||||
let $li = this.get_li_from_key({
|
||||
key,
|
||||
});
|
||||
|
||||
if (li.length === 1) {
|
||||
return li;
|
||||
if ($li.length === 1) {
|
||||
return $li;
|
||||
}
|
||||
|
||||
if (!opts.force_render) {
|
||||
// Most callers don't force us to render a list
|
||||
// item that wouldn't be on-screen anyway.
|
||||
return li;
|
||||
return $li;
|
||||
}
|
||||
|
||||
const pos = this.keys.indexOf(key);
|
||||
@@ -208,11 +208,11 @@ export class BuddyList extends BuddyListConf {
|
||||
pos,
|
||||
});
|
||||
|
||||
li = this.get_li_from_key({
|
||||
$li = this.get_li_from_key({
|
||||
key,
|
||||
});
|
||||
|
||||
return li;
|
||||
return $li;
|
||||
}
|
||||
|
||||
insert_new_html(opts) {
|
||||
@@ -223,7 +223,7 @@ export class BuddyList extends BuddyListConf {
|
||||
if (other_key === undefined) {
|
||||
if (pos === this.render_count) {
|
||||
this.render_count += 1;
|
||||
this.container.append(html);
|
||||
this.$container.append(html);
|
||||
this.update_padding();
|
||||
}
|
||||
return;
|
||||
@@ -231,8 +231,8 @@ export class BuddyList extends BuddyListConf {
|
||||
|
||||
if (pos < this.render_count) {
|
||||
this.render_count += 1;
|
||||
const li = this.find_li({key: other_key});
|
||||
li.before(html);
|
||||
const $li = this.find_li({key: other_key});
|
||||
$li.before(html);
|
||||
this.update_padding();
|
||||
}
|
||||
}
|
||||
@@ -288,14 +288,14 @@ export class BuddyList extends BuddyListConf {
|
||||
|
||||
// This is a bit of a hack to make sure we at least have
|
||||
// an empty list to start, before we get the initial payload.
|
||||
container = $(this.container_sel);
|
||||
$container = $(this.container_sel);
|
||||
|
||||
start_scroll_handler() {
|
||||
// We have our caller explicitly call this to make
|
||||
// sure everything's in place.
|
||||
const scroll_container = ui.get_scroll_element($(this.scroll_container_sel));
|
||||
const $scroll_container = ui.get_scroll_element($(this.scroll_container_sel));
|
||||
|
||||
scroll_container.on("scroll", () => {
|
||||
$scroll_container.on("scroll", () => {
|
||||
this.fill_screen_with_content();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,49 +101,49 @@ export function initialize() {
|
||||
initialize_long_tap();
|
||||
}
|
||||
|
||||
function is_clickable_message_element(target) {
|
||||
function is_clickable_message_element($target) {
|
||||
// This function defines all the elements within a message
|
||||
// body that have UI behavior other than starting a reply.
|
||||
|
||||
// Links should be handled by the browser.
|
||||
if (target.closest("a").length > 0) {
|
||||
if ($target.closest("a").length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Forms for message editing contain input elements
|
||||
if (target.is("textarea") || target.is("input")) {
|
||||
if ($target.is("textarea") || $target.is("input")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Widget for adjusting the height of a message.
|
||||
if (target.is("div.message_length_controller")) {
|
||||
if ($target.is("div.message_length_controller")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Inline image and twitter previews.
|
||||
if (target.is("img.message_inline_image") || target.is("img.twitter-avatar")) {
|
||||
if ($target.is("img.message_inline_image") || $target.is("img.twitter-avatar")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// UI elements for triggering message editing or viewing edit history.
|
||||
if (target.is("i.edit_content_button") || target.is(".message_edit_notice")) {
|
||||
if ($target.is("i.edit_content_button") || $target.is(".message_edit_notice")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// For spoilers, allow clicking either the header or elements within it
|
||||
if (target.is(".spoiler-header") || target.parents(".spoiler-header").length > 0) {
|
||||
if ($target.is(".spoiler-header") || $target.parents(".spoiler-header").length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ideally, this should be done via ClipboardJS, but it doesn't support
|
||||
// feature of stopPropagation once clicked.
|
||||
// See https://github.com/zenorocha/clipboard.js/pull/475
|
||||
if (target.is(".copy_codeblock") || target.parents(".copy_codeblock").length > 0) {
|
||||
if ($target.is(".copy_codeblock") || $target.parents(".copy_codeblock").length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Don't select message on clicking message control buttons.
|
||||
if (target.parents(".message_controls").length > 0) {
|
||||
if ($target.parents(".message_controls").length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -169,8 +169,8 @@ export function initialize() {
|
||||
return;
|
||||
}
|
||||
|
||||
const row = $(this).closest(".message_row");
|
||||
const id = rows.id(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
const id = rows.id($row);
|
||||
|
||||
if (message_edit.is_editing(id)) {
|
||||
// Clicks on a message being edited shouldn't trigger a reply.
|
||||
@@ -261,45 +261,45 @@ export function initialize() {
|
||||
// MESSAGE EDITING
|
||||
|
||||
$("body").on("click", ".edit_content_button", function (e) {
|
||||
const row = message_lists.current.get_row(rows.id($(this).closest(".message_row")));
|
||||
message_lists.current.select_id(rows.id(row));
|
||||
message_edit.start(row);
|
||||
const $row = message_lists.current.get_row(rows.id($(this).closest(".message_row")));
|
||||
message_lists.current.select_id(rows.id($row));
|
||||
message_edit.start($row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".always_visible_topic_edit,.on_hover_topic_edit", function (e) {
|
||||
const recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.start_inline_topic_edit(recipient_row);
|
||||
const $recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.start_inline_topic_edit($recipient_row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".topic_edit_save", function (e) {
|
||||
const recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.save_inline_topic_edit(recipient_row);
|
||||
const $recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.save_inline_topic_edit($recipient_row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".topic_edit_cancel", function (e) {
|
||||
const recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.end_inline_topic_edit(recipient_row);
|
||||
const $recipient_row = $(this).closest(".recipient_row");
|
||||
message_edit.end_inline_topic_edit($recipient_row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".message_edit_save", function (e) {
|
||||
const row = $(this).closest(".message_row");
|
||||
message_edit.save_message_row_edit(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
message_edit.save_message_row_edit($row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".message_edit_cancel", function (e) {
|
||||
const row = $(this).closest(".message_row");
|
||||
message_edit.end_message_row_edit(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
message_edit.end_message_row_edit($row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
$("body").on("click", ".message_edit_close", function (e) {
|
||||
const row = $(this).closest(".message_row");
|
||||
message_edit.end_message_row_edit(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
message_edit.end_message_row_edit($row);
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
});
|
||||
@@ -310,8 +310,8 @@ export function initialize() {
|
||||
});
|
||||
$(".message_edit_form .send-status-close").on("click", function () {
|
||||
const row_id = rows.id($(this).closest(".message_row"));
|
||||
const send_status = $(`#message-edit-send-status-${CSS.escape(row_id)}`);
|
||||
$(send_status).stop(true).fadeOut(200);
|
||||
const $send_status = $(`#message-edit-send-status-${CSS.escape(row_id)}`);
|
||||
$($send_status).stop(true).fadeOut(200);
|
||||
});
|
||||
$("body").on("click", ".message_edit_form .compose_upload_file", function (e) {
|
||||
e.preventDefault();
|
||||
@@ -322,44 +322,44 @@ export function initialize() {
|
||||
|
||||
$("body").on("click", ".message_edit_form .markdown_preview", (e) => {
|
||||
e.preventDefault();
|
||||
const row = rows.get_closest_row(e.target);
|
||||
const $msg_edit_content = row.find(".message_edit_content");
|
||||
const $row = rows.get_closest_row(e.target);
|
||||
const $msg_edit_content = $row.find(".message_edit_content");
|
||||
const content = $msg_edit_content.val();
|
||||
$msg_edit_content.hide();
|
||||
row.find(".markdown_preview").hide();
|
||||
row.find(".undo_markdown_preview").show();
|
||||
row.find(".preview_message_area").show();
|
||||
$row.find(".markdown_preview").hide();
|
||||
$row.find(".undo_markdown_preview").show();
|
||||
$row.find(".preview_message_area").show();
|
||||
|
||||
compose.render_and_show_preview(
|
||||
row.find(".markdown_preview_spinner"),
|
||||
row.find(".preview_content"),
|
||||
$row.find(".markdown_preview_spinner"),
|
||||
$row.find(".preview_content"),
|
||||
content,
|
||||
);
|
||||
});
|
||||
|
||||
$("body").on("click", ".message_edit_form .undo_markdown_preview", (e) => {
|
||||
e.preventDefault();
|
||||
const row = rows.get_closest_row(e.target);
|
||||
row.find(".message_edit_content").show();
|
||||
row.find(".undo_markdown_preview").hide();
|
||||
row.find(".preview_message_area").hide();
|
||||
row.find(".preview_content").empty();
|
||||
row.find(".markdown_preview").show();
|
||||
const $row = rows.get_closest_row(e.target);
|
||||
$row.find(".message_edit_content").show();
|
||||
$row.find(".undo_markdown_preview").hide();
|
||||
$row.find(".preview_message_area").hide();
|
||||
$row.find(".preview_content").empty();
|
||||
$row.find(".markdown_preview").show();
|
||||
});
|
||||
|
||||
// RESOLVED TOPICS
|
||||
$("body").on("click", ".message_header .on_hover_topic_resolve", (e) => {
|
||||
e.stopPropagation();
|
||||
const recipient_row = $(e.target).closest(".recipient_row");
|
||||
const message_id = rows.id_for_recipient_row(recipient_row);
|
||||
const $recipient_row = $(e.target).closest(".recipient_row");
|
||||
const message_id = rows.id_for_recipient_row($recipient_row);
|
||||
const topic_name = $(e.target).attr("data-topic-name");
|
||||
message_edit.toggle_resolve_topic(message_id, topic_name);
|
||||
});
|
||||
|
||||
$("body").on("click", ".message_header .on_hover_topic_unresolve", (e) => {
|
||||
e.stopPropagation();
|
||||
const recipient_row = $(e.target).closest(".recipient_row");
|
||||
const message_id = rows.id_for_recipient_row(recipient_row);
|
||||
const $recipient_row = $(e.target).closest(".recipient_row");
|
||||
const message_id = rows.id_for_recipient_row($recipient_row);
|
||||
const topic_name = $(e.target).attr("data-topic-name");
|
||||
message_edit.toggle_resolve_topic(message_id, topic_name);
|
||||
});
|
||||
@@ -449,9 +449,9 @@ export function initialize() {
|
||||
e.stopPropagation();
|
||||
// The element's parent may re-render while it is being passed to
|
||||
// other functions, so, we get topic_key first.
|
||||
const topic_row = $(e.target).closest("tr");
|
||||
const topic_key = topic_row.attr("id").slice("recent_topics:".length - 1);
|
||||
const topic_row_index = topic_row.index();
|
||||
const $topic_row = $(e.target).closest("tr");
|
||||
const topic_key = $topic_row.attr("id").slice("recent_topics:".length - 1);
|
||||
const topic_row_index = $topic_row.index();
|
||||
recent_topics_ui.focus_clicked_element(
|
||||
topic_row_index,
|
||||
recent_topics_ui.COLUMNS.topic,
|
||||
@@ -479,8 +479,8 @@ export function initialize() {
|
||||
// RECIPIENT BARS
|
||||
|
||||
function get_row_id_for_narrowing(narrow_link_elem) {
|
||||
const group = rows.get_closest_group(narrow_link_elem);
|
||||
const msg_id = rows.id_for_recipient_row(group);
|
||||
const $group = rows.get_closest_group(narrow_link_elem);
|
||||
const msg_id = rows.id_for_recipient_row($group);
|
||||
|
||||
const nearest = message_lists.current.get(msg_id);
|
||||
const selected = message_lists.current.selected_message();
|
||||
@@ -535,9 +535,9 @@ export function initialize() {
|
||||
$("#user_presences")
|
||||
.expectOne()
|
||||
.on("click", ".selectable_sidebar_block", (e) => {
|
||||
const li = $(e.target).parents("li");
|
||||
const $li = $(e.target).parents("li");
|
||||
|
||||
activity.narrow_for_user({li});
|
||||
activity.narrow_for_user({$li});
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
@@ -545,7 +545,7 @@ export function initialize() {
|
||||
$(".tooltip").remove();
|
||||
});
|
||||
|
||||
function do_render_buddy_list_tooltip(elem, title_data) {
|
||||
function do_render_buddy_list_tooltip($elem, title_data) {
|
||||
let placement = "left";
|
||||
let observer;
|
||||
if (window.innerWidth < media_breakpoints_num.md) {
|
||||
@@ -553,7 +553,7 @@ export function initialize() {
|
||||
// This will default to "bottom" placement for this tooltip.
|
||||
placement = "auto";
|
||||
}
|
||||
tippy(elem[0], {
|
||||
tippy($elem[0], {
|
||||
// Quickly display and hide right sidebar tooltips
|
||||
// so that they don't stick and overlap with
|
||||
// each other.
|
||||
@@ -598,22 +598,22 @@ export function initialize() {
|
||||
// BUDDY LIST TOOLTIPS
|
||||
$("#user_presences").on("mouseenter", ".selectable_sidebar_block", (e) => {
|
||||
e.stopPropagation();
|
||||
const elem = $(e.currentTarget).closest(".user_sidebar_entry").find(".user-presence-link");
|
||||
const user_id_string = elem.attr("data-user-id");
|
||||
const $elem = $(e.currentTarget).closest(".user_sidebar_entry").find(".user-presence-link");
|
||||
const user_id_string = $elem.attr("data-user-id");
|
||||
const title_data = buddy_data.get_title_data(user_id_string, false);
|
||||
do_render_buddy_list_tooltip(elem.parent(), title_data);
|
||||
do_render_buddy_list_tooltip($elem.parent(), title_data);
|
||||
});
|
||||
|
||||
// PM LIST TOOLTIPS
|
||||
$("body").on("mouseenter", "#pm_user_status", (e) => {
|
||||
e.stopPropagation();
|
||||
const elem = $(e.currentTarget);
|
||||
const user_ids_string = elem.attr("data-user-ids-string");
|
||||
const $elem = $(e.currentTarget);
|
||||
const user_ids_string = $elem.attr("data-user-ids-string");
|
||||
// This converts from 'true' in the DOM to true.
|
||||
const is_group = JSON.parse(elem.attr("data-is-group"));
|
||||
const is_group = JSON.parse($elem.attr("data-is-group"));
|
||||
|
||||
const title_data = buddy_data.get_title_data(user_ids_string, is_group);
|
||||
do_render_buddy_list_tooltip(elem, title_data);
|
||||
do_render_buddy_list_tooltip($elem, title_data);
|
||||
});
|
||||
|
||||
// MISC
|
||||
@@ -791,7 +791,7 @@ export function initialize() {
|
||||
|
||||
overlays.open_overlay({
|
||||
name: overlay_name,
|
||||
overlay: $(`#${CSS.escape(overlay_name)}`),
|
||||
$overlay: $(`#${CSS.escape(overlay_name)}`),
|
||||
on_close: function () {
|
||||
// close popover
|
||||
$(this).css({display: "block"});
|
||||
|
||||
@@ -32,16 +32,16 @@ export function phrase_match(query: string, phrase: string): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function copy_data_attribute_value(elem: JQuery, key: string): void {
|
||||
export function copy_data_attribute_value($elem: JQuery, key: string): void {
|
||||
// function to copy the value of data-key
|
||||
// attribute of the element to clipboard
|
||||
const temp = $(document.createElement("input"));
|
||||
$("body").append(temp);
|
||||
temp.val(elem.data(key)).trigger("select");
|
||||
const $temp = $(document.createElement("input"));
|
||||
$("body").append($temp);
|
||||
$temp.val($elem.data(key)).trigger("select");
|
||||
document.execCommand("copy");
|
||||
temp.remove();
|
||||
elem.fadeOut(250);
|
||||
elem.fadeIn(1000);
|
||||
$temp.remove();
|
||||
$elem.fadeOut(250);
|
||||
$elem.fadeIn(1000);
|
||||
}
|
||||
|
||||
export function has_mac_keyboard(): boolean {
|
||||
@@ -105,14 +105,14 @@ function toggle_password_visibility(
|
||||
tippy_tooltips: boolean,
|
||||
): void {
|
||||
let label;
|
||||
const password_field = $(password_field_id);
|
||||
const $password_field = $(password_field_id);
|
||||
|
||||
if (password_field.attr("type") === "password") {
|
||||
password_field.attr("type", "text");
|
||||
if ($password_field.attr("type") === "password") {
|
||||
$password_field.attr("type", "text");
|
||||
$(password_selector).removeClass("fa-eye-slash").addClass("fa-eye");
|
||||
label = $t({defaultMessage: "Hide password"});
|
||||
} else {
|
||||
password_field.attr("type", "password");
|
||||
$password_field.attr("type", "password");
|
||||
$(password_selector).removeClass("fa-eye").addClass("fa-eye-slash");
|
||||
label = $t({defaultMessage: "Show password"});
|
||||
}
|
||||
|
||||
@@ -32,16 +32,16 @@ export function toggle(opts: {
|
||||
child_wants_focus?: boolean;
|
||||
selected?: number;
|
||||
}): Toggle {
|
||||
const component = $("<div class='tab-switcher'></div>");
|
||||
const $component = $("<div class='tab-switcher'></div>");
|
||||
if (opts.html_class) {
|
||||
// add a check inside passed arguments in case some extra
|
||||
// classes need to be added for correct alignment or other purposes
|
||||
component.addClass(opts.html_class);
|
||||
$component.addClass(opts.html_class);
|
||||
}
|
||||
for (const [i, value] of opts.values.entries()) {
|
||||
// create a tab with a tab-id so they don't have to be referenced
|
||||
// by text value which can be inconsistent.
|
||||
const tab = $("<div>", {
|
||||
const $tab = $("<div>", {
|
||||
class: "ind-tab",
|
||||
"data-tab-key": value.key,
|
||||
"data-tab-id": i,
|
||||
@@ -51,37 +51,37 @@ export function toggle(opts: {
|
||||
/* istanbul ignore if */
|
||||
if (value.label_html !== undefined) {
|
||||
const html = value.label_html;
|
||||
tab.html(html);
|
||||
$tab.html(html);
|
||||
} else {
|
||||
tab.text(value.label);
|
||||
$tab.text(value.label);
|
||||
}
|
||||
|
||||
// add proper classes for styling in CSS.
|
||||
if (i === 0) {
|
||||
// this should be default selected unless otherwise specified.
|
||||
tab.addClass("first selected");
|
||||
$tab.addClass("first selected");
|
||||
} else if (i === opts.values.length - 1) {
|
||||
tab.addClass("last");
|
||||
$tab.addClass("last");
|
||||
} else {
|
||||
tab.addClass("middle");
|
||||
$tab.addClass("middle");
|
||||
}
|
||||
component.append(tab);
|
||||
$component.append($tab);
|
||||
}
|
||||
|
||||
const meta = {
|
||||
$ind_tab: component.find(".ind-tab"),
|
||||
$ind_tab: $component.find(".ind-tab"),
|
||||
idx: -1,
|
||||
};
|
||||
|
||||
// Returns false if the requested tab is disabled.
|
||||
function select_tab(idx: number): boolean {
|
||||
const elem = meta.$ind_tab.eq(idx);
|
||||
if (elem.hasClass("disabled")) {
|
||||
const $elem = meta.$ind_tab.eq(idx);
|
||||
if ($elem.hasClass("disabled")) {
|
||||
return false;
|
||||
}
|
||||
meta.$ind_tab.removeClass("selected");
|
||||
|
||||
elem.addClass("selected");
|
||||
$elem.addClass("selected");
|
||||
|
||||
meta.idx = idx;
|
||||
if (opts.callback) {
|
||||
@@ -89,7 +89,7 @@ export function toggle(opts: {
|
||||
}
|
||||
|
||||
if (!opts.child_wants_focus) {
|
||||
elem.trigger("focus");
|
||||
$elem.trigger("focus");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -124,7 +124,7 @@ export function toggle(opts: {
|
||||
});
|
||||
|
||||
keydown_util.handle({
|
||||
elem: meta.$ind_tab,
|
||||
$elem: meta.$ind_tab,
|
||||
handlers: {
|
||||
ArrowLeft: maybe_go_left,
|
||||
ArrowRight: maybe_go_right,
|
||||
@@ -172,7 +172,7 @@ export function toggle(opts: {
|
||||
},
|
||||
|
||||
get() {
|
||||
return component;
|
||||
return $component;
|
||||
},
|
||||
// go through the process of finding the correct tab for a given name,
|
||||
// and when found, select that one and provide the proper callback.
|
||||
|
||||
@@ -328,7 +328,7 @@ function insert_video_call_url(url, target_textarea) {
|
||||
compose_ui.insert_syntax_and_focus(`[${link_text}](${url})`, target_textarea);
|
||||
}
|
||||
|
||||
export function render_and_show_preview(preview_spinner, preview_content_box, content) {
|
||||
export function render_and_show_preview($preview_spinner, $preview_content_box, content) {
|
||||
function show_preview(rendered_content, raw_content) {
|
||||
// content is passed to check for status messages ("/me ...")
|
||||
// and will be undefined in case of errors
|
||||
@@ -344,16 +344,16 @@ export function render_and_show_preview(preview_spinner, preview_content_box, co
|
||||
rendered_preview_html = rendered_content;
|
||||
}
|
||||
|
||||
preview_content_box.html(util.clean_user_content_links(rendered_preview_html));
|
||||
rendered_markdown.update_elements(preview_content_box);
|
||||
$preview_content_box.html(util.clean_user_content_links(rendered_preview_html));
|
||||
rendered_markdown.update_elements($preview_content_box);
|
||||
}
|
||||
|
||||
if (content.length === 0) {
|
||||
show_preview($t_html({defaultMessage: "Nothing to preview"}));
|
||||
} else {
|
||||
if (markdown.contains_backend_only_syntax(content)) {
|
||||
const spinner = preview_spinner.expectOne();
|
||||
loading.make_indicator(spinner);
|
||||
const $spinner = $preview_spinner.expectOne();
|
||||
loading.make_indicator($spinner);
|
||||
} else {
|
||||
// For messages that don't appear to contain syntax that
|
||||
// is only supported by our backend Markdown processor, we
|
||||
@@ -374,13 +374,13 @@ export function render_and_show_preview(preview_spinner, preview_content_box, co
|
||||
data: {content},
|
||||
success(response_data) {
|
||||
if (markdown.contains_backend_only_syntax(content)) {
|
||||
loading.destroy_indicator(preview_spinner);
|
||||
loading.destroy_indicator($preview_spinner);
|
||||
}
|
||||
show_preview(response_data.rendered, content);
|
||||
},
|
||||
error() {
|
||||
if (markdown.contains_backend_only_syntax(content)) {
|
||||
loading.destroy_indicator(preview_spinner);
|
||||
loading.destroy_indicator($preview_spinner);
|
||||
}
|
||||
show_preview($t_html({defaultMessage: "Failed to generate preview"}));
|
||||
},
|
||||
@@ -463,9 +463,9 @@ export function initialize() {
|
||||
$("#compose_resolved_topic").on("click", ".compose_unresolve_topic", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const target = $(event.target).parents(".compose_resolved_topic");
|
||||
const stream_id = Number.parseInt(target.attr("data-stream-id"), 10);
|
||||
const topic_name = target.attr("data-topic-name");
|
||||
const $target = $(event.target).parents(".compose_resolved_topic");
|
||||
const stream_id = Number.parseInt($target.attr("data-stream-id"), 10);
|
||||
const topic_name = $target.attr("data-topic-name");
|
||||
|
||||
message_edit.with_first_message_id(stream_id, topic_name, (message_id) => {
|
||||
message_edit.toggle_resolve_topic(message_id, topic_name);
|
||||
@@ -482,17 +482,17 @@ export function initialize() {
|
||||
$("#compose_invite_users").on("click", ".compose_invite_link", (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const invite_row = $(event.target).parents(".compose_invite_user");
|
||||
const $invite_row = $(event.target).parents(".compose_invite_user");
|
||||
|
||||
const user_id = Number.parseInt($(invite_row).data("user-id"), 10);
|
||||
const stream_id = Number.parseInt($(invite_row).data("stream-id"), 10);
|
||||
const user_id = Number.parseInt($($invite_row).data("user-id"), 10);
|
||||
const stream_id = Number.parseInt($($invite_row).data("stream-id"), 10);
|
||||
|
||||
function success() {
|
||||
const all_invites = $("#compose_invite_users");
|
||||
invite_row.remove();
|
||||
const $all_invites = $("#compose_invite_users");
|
||||
$invite_row.remove();
|
||||
|
||||
if (all_invites.children().length === 0) {
|
||||
all_invites.hide();
|
||||
if ($all_invites.children().length === 0) {
|
||||
$all_invites.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,13 +513,13 @@ export function initialize() {
|
||||
});
|
||||
|
||||
$("#compose_invite_users").on("click", ".compose_invite_close", (event) => {
|
||||
const invite_row = $(event.target).parents(".compose_invite_user");
|
||||
const all_invites = $("#compose_invite_users");
|
||||
const $invite_row = $(event.target).parents(".compose_invite_user");
|
||||
const $all_invites = $("#compose_invite_users");
|
||||
|
||||
invite_row.remove();
|
||||
$invite_row.remove();
|
||||
|
||||
if (all_invites.children().length === 0) {
|
||||
all_invites.hide();
|
||||
if ($all_invites.children().length === 0) {
|
||||
$all_invites.hide();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -527,13 +527,13 @@ export function initialize() {
|
||||
"click",
|
||||
".compose_private_stream_alert_close",
|
||||
(event) => {
|
||||
const stream_alert_row = $(event.target).parents(".compose_private_stream_alert");
|
||||
const stream_alert = $("#compose_private_stream_alert");
|
||||
const $stream_alert_row = $(event.target).parents(".compose_private_stream_alert");
|
||||
const $stream_alert = $("#compose_private_stream_alert");
|
||||
|
||||
stream_alert_row.remove();
|
||||
$stream_alert_row.remove();
|
||||
|
||||
if (stream_alert.children().length === 0) {
|
||||
stream_alert.hide();
|
||||
if ($stream_alert.children().length === 0) {
|
||||
$stream_alert.hide();
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -552,11 +552,11 @@ export function initialize() {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
let target_textarea;
|
||||
let $target_textarea;
|
||||
let edit_message_id;
|
||||
if ($(e.target).parents(".message_edit_form").length === 1) {
|
||||
edit_message_id = rows.id($(e.target).parents(".message_row"));
|
||||
target_textarea = $(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`);
|
||||
$target_textarea = $(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`);
|
||||
}
|
||||
|
||||
let video_call_link;
|
||||
@@ -581,7 +581,7 @@ export function initialize() {
|
||||
url: "/json/calls/zoom/create",
|
||||
success(res) {
|
||||
video_call_xhrs.delete(key);
|
||||
insert_video_call_url(res.url, target_textarea);
|
||||
insert_video_call_url(res.url, $target_textarea);
|
||||
},
|
||||
error(xhr, status) {
|
||||
video_call_xhrs.delete(key);
|
||||
@@ -619,13 +619,13 @@ export function initialize() {
|
||||
channel.get({
|
||||
url: "/json/calls/bigbluebutton/create",
|
||||
success(response) {
|
||||
insert_video_call_url(response.url, target_textarea);
|
||||
insert_video_call_url(response.url, $target_textarea);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const video_call_id = util.random_int(100000000000000, 999999999999999);
|
||||
video_call_link = page_params.jitsi_server_url + "/" + video_call_id;
|
||||
insert_video_call_url(video_call_link, target_textarea);
|
||||
insert_video_call_url(video_call_link, $target_textarea);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -635,20 +635,20 @@ export function initialize() {
|
||||
|
||||
$(e.target).toggleClass("has_popover");
|
||||
|
||||
let target_textarea;
|
||||
let $target_textarea;
|
||||
let edit_message_id;
|
||||
const compose_click_target = compose_ui.get_compose_click_target(e);
|
||||
if ($(compose_click_target).parents(".message_edit_form").length === 1) {
|
||||
edit_message_id = rows.id($(compose_click_target).parents(".message_row"));
|
||||
target_textarea = $(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`);
|
||||
$target_textarea = $(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`);
|
||||
} else {
|
||||
target_textarea = $(compose_click_target).closest("form").find("textarea");
|
||||
$target_textarea = $(compose_click_target).closest("form").find("textarea");
|
||||
}
|
||||
|
||||
if ($(e.target).hasClass("has_popover")) {
|
||||
const on_timestamp_selection = (val) => {
|
||||
const timestr = `<time:${val}> `;
|
||||
compose_ui.insert_syntax_and_focus(timestr, target_textarea);
|
||||
compose_ui.insert_syntax_and_focus(timestr, $target_textarea);
|
||||
};
|
||||
|
||||
flatpickr.show_flatpickr(
|
||||
@@ -716,10 +716,10 @@ export function initialize() {
|
||||
|
||||
$("body").on("click", ".formatting_button", (e) => {
|
||||
const $compose_click_target = $(compose_ui.get_compose_click_target(e));
|
||||
const textarea = $compose_click_target.closest("form").find("textarea");
|
||||
const $textarea = $compose_click_target.closest("form").find("textarea");
|
||||
const format_type = $(e.target).attr("data-format-type");
|
||||
compose_ui.format_text(textarea, format_type);
|
||||
textarea.trigger("focus");
|
||||
compose_ui.format_text($textarea, format_type);
|
||||
$textarea.trigger("focus");
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
@@ -72,8 +72,8 @@ export const _get_focus_area = get_focus_area;
|
||||
export function set_focus(msg_type, opts) {
|
||||
const focus_area = get_focus_area(msg_type, opts);
|
||||
if (window.getSelection().toString() === "" || opts.trigger !== "message click") {
|
||||
const elt = $(focus_area);
|
||||
elt.trigger("focus").trigger("select");
|
||||
const $elt = $(focus_area);
|
||||
$elt.trigger("focus").trigger("select");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,9 +156,9 @@ export function maybe_scroll_up_selected_message() {
|
||||
// scroll the compose box to avoid it.
|
||||
return;
|
||||
}
|
||||
const selected_row = message_lists.current.selected_row();
|
||||
const $selected_row = message_lists.current.selected_row();
|
||||
|
||||
if (selected_row.height() > message_viewport.height() - 100) {
|
||||
if ($selected_row.height() > message_viewport.height() - 100) {
|
||||
// For very tall messages whose height is close to the entire
|
||||
// height of the viewport, don't auto-scroll the viewport to
|
||||
// the end of the message (since that makes it feel annoying
|
||||
@@ -166,7 +166,7 @@ export function maybe_scroll_up_selected_message() {
|
||||
return;
|
||||
}
|
||||
|
||||
const cover = selected_row.offset().top + selected_row.height() - $("#compose").offset().top;
|
||||
const cover = $selected_row.offset().top + $selected_row.height() - $("#compose").offset().top;
|
||||
if (cover > 0) {
|
||||
message_viewport.user_initiated_animate_scroll(cover + 20);
|
||||
}
|
||||
@@ -471,7 +471,7 @@ export function on_topic_narrow() {
|
||||
}
|
||||
|
||||
export function quote_and_reply(opts) {
|
||||
const textarea = $("#compose-textarea");
|
||||
const $textarea = $("#compose-textarea");
|
||||
const message_id = message_lists.current.selected_id();
|
||||
const message = message_lists.current.selected_message();
|
||||
const quoting_placeholder = $t({defaultMessage: "[Quoting…]"});
|
||||
@@ -484,17 +484,17 @@ export function quote_and_reply(opts) {
|
||||
// text, plus it's a complicated codepath that
|
||||
// can have other unintended consequences.)
|
||||
|
||||
if (textarea.caret() !== 0) {
|
||||
if ($textarea.caret() !== 0) {
|
||||
// Insert a newline before quoted message if there is
|
||||
// already some content in the compose box and quoted
|
||||
// message is not being inserted at the beginning.
|
||||
textarea.caret("\n");
|
||||
$textarea.caret("\n");
|
||||
}
|
||||
} else {
|
||||
respond_to_message(opts);
|
||||
}
|
||||
|
||||
compose_ui.insert_syntax_and_focus(quoting_placeholder + "\n", textarea);
|
||||
compose_ui.insert_syntax_and_focus(quoting_placeholder + "\n", $textarea);
|
||||
|
||||
function replace_content(message) {
|
||||
// Final message looks like:
|
||||
@@ -502,7 +502,7 @@ export function quote_and_reply(opts) {
|
||||
// ```quote
|
||||
// message content
|
||||
// ```
|
||||
const prev_caret = textarea.caret();
|
||||
const prev_caret = $textarea.caret();
|
||||
let content = $t(
|
||||
{defaultMessage: "{username} [said]({link_to_message}):"},
|
||||
{
|
||||
@@ -514,8 +514,8 @@ export function quote_and_reply(opts) {
|
||||
const fence = fenced_code.get_unused_fence(message.raw_content);
|
||||
content += `${fence}quote\n${message.raw_content}\n${fence}`;
|
||||
|
||||
const placeholder_offset = $(textarea).val().indexOf(quoting_placeholder);
|
||||
compose_ui.replace_syntax(quoting_placeholder, content, textarea);
|
||||
const placeholder_offset = $($textarea).val().indexOf(quoting_placeholder);
|
||||
compose_ui.replace_syntax(quoting_placeholder, content, $textarea);
|
||||
compose_ui.autosize_textarea($("#compose-textarea"));
|
||||
|
||||
// When replacing content in a textarea, we need to move the
|
||||
@@ -524,14 +524,14 @@ export function quote_and_reply(opts) {
|
||||
// position. If we do, we need to move it by the increase in
|
||||
// the length of the content before the placeholder.
|
||||
if (prev_caret >= placeholder_offset + quoting_placeholder.length) {
|
||||
textarea.caret(prev_caret + content.length - quoting_placeholder.length);
|
||||
$textarea.caret(prev_caret + content.length - quoting_placeholder.length);
|
||||
} else if (prev_caret > placeholder_offset) {
|
||||
/* In the rare case that our cursor was inside the
|
||||
* placeholder, we treat that as though the cursor was
|
||||
* just after the placeholder. */
|
||||
textarea.caret(placeholder_offset + content.length + 1);
|
||||
$textarea.caret(placeholder_offset + content.length + 1);
|
||||
} else {
|
||||
textarea.caret(prev_caret);
|
||||
$textarea.caret(prev_caret);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import $ from "jquery";
|
||||
|
||||
import * as common from "./common";
|
||||
|
||||
export function show(error_html: string, bad_input?: JQuery, alert_class = "alert-error"): void {
|
||||
export function show(error_html: string, $bad_input?: JQuery, alert_class = "alert-error"): void {
|
||||
$("#compose-send-status")
|
||||
.removeClass(common.status_classes)
|
||||
.addClass(alert_class)
|
||||
@@ -14,13 +14,13 @@ export function show(error_html: string, bad_input?: JQuery, alert_class = "aler
|
||||
$("#compose-send-button span").show();
|
||||
$("#compose-send-button").removeClass("disable-btn");
|
||||
|
||||
if (bad_input !== undefined) {
|
||||
bad_input.trigger("focus").trigger("select");
|
||||
if ($bad_input !== undefined) {
|
||||
$bad_input.trigger("focus").trigger("select");
|
||||
}
|
||||
}
|
||||
|
||||
export function show_not_subscribed(error_html: string, bad_input?: JQuery): void {
|
||||
show(error_html, bad_input, "home-error-bar");
|
||||
export function show_not_subscribed(error_html: string, $bad_input?: JQuery): void {
|
||||
show(error_html, $bad_input, "home-error-bar");
|
||||
$(".compose-send-status-close").hide();
|
||||
}
|
||||
|
||||
|
||||
@@ -46,25 +46,25 @@ export function set_focused_recipient(msg_type) {
|
||||
}
|
||||
|
||||
function display_messages_normally() {
|
||||
const table = rows.get_table(message_lists.current.table_name);
|
||||
table.find(".recipient_row").removeClass("message-fade");
|
||||
const $table = rows.get_table(message_lists.current.table_name);
|
||||
$table.find(".recipient_row").removeClass("message-fade");
|
||||
|
||||
normal_display = true;
|
||||
floating_recipient_bar.update();
|
||||
}
|
||||
|
||||
function change_fade_state(elt, should_fade_group) {
|
||||
function change_fade_state($elt, should_fade_group) {
|
||||
if (should_fade_group) {
|
||||
elt.addClass("message-fade");
|
||||
$elt.addClass("message-fade");
|
||||
} else {
|
||||
elt.removeClass("message-fade");
|
||||
$elt.removeClass("message-fade");
|
||||
}
|
||||
}
|
||||
|
||||
function fade_messages() {
|
||||
let i;
|
||||
let first_message;
|
||||
let first_row;
|
||||
let $first_row;
|
||||
let should_fade_group = false;
|
||||
const visible_groups = message_viewport.visible_groups(false);
|
||||
|
||||
@@ -72,8 +72,8 @@ function fade_messages() {
|
||||
|
||||
// Update the visible messages first, before the compose box opens
|
||||
for (i = 0; i < visible_groups.length; i += 1) {
|
||||
first_row = rows.first_message_in_group(visible_groups[i]);
|
||||
first_message = message_lists.current.get(rows.id(first_row));
|
||||
$first_row = rows.first_message_in_group(visible_groups[i]);
|
||||
first_message = message_lists.current.get(rows.id($first_row));
|
||||
should_fade_group = compose_fade_helper.should_fade_message(first_message);
|
||||
|
||||
change_fade_state($(visible_groups[i]), should_fade_group);
|
||||
@@ -99,11 +99,11 @@ function fade_messages() {
|
||||
// Note: The below algorithm relies on the fact that all_elts is
|
||||
// sorted as it would be displayed in the message view
|
||||
for (i = 0; i < all_groups.length; i += 1) {
|
||||
const group_elt = $(all_groups[i]);
|
||||
const $group_elt = $(all_groups[i]);
|
||||
should_fade_group = compose_fade_helper.should_fade_message(
|
||||
rows.recipient_from_group(group_elt),
|
||||
rows.recipient_from_group($group_elt),
|
||||
);
|
||||
change_fade_state(group_elt, should_fade_group);
|
||||
change_fade_state($group_elt, should_fade_group);
|
||||
}
|
||||
|
||||
floating_recipient_bar.update();
|
||||
@@ -115,14 +115,14 @@ function fade_messages() {
|
||||
}
|
||||
|
||||
const user_fade_config = {
|
||||
get_user_id(li) {
|
||||
return buddy_list.get_key_from_li({li});
|
||||
get_user_id($li) {
|
||||
return buddy_list.get_key_from_li({$li});
|
||||
},
|
||||
fade(li) {
|
||||
return li.addClass("user-fade");
|
||||
fade($li) {
|
||||
return $li.addClass("user-fade");
|
||||
},
|
||||
unfade(li) {
|
||||
return li.removeClass("user-fade");
|
||||
unfade($li) {
|
||||
return $li.removeClass("user-fade");
|
||||
},
|
||||
};
|
||||
|
||||
@@ -180,9 +180,9 @@ export function update_rendered_message_groups(message_groups, get_element) {
|
||||
// important difference here is that we look at each message individually, whereas
|
||||
// the other code takes advantage of blocks beneath recipient bars.
|
||||
for (const message_group of message_groups) {
|
||||
const elt = get_element(message_group);
|
||||
const $elt = get_element(message_group);
|
||||
const first_message = message_group.message_containers[0].msg;
|
||||
const should_fade = compose_fade_helper.should_fade_message(first_message);
|
||||
change_fade_state(elt, should_fade);
|
||||
change_fade_state($elt, should_fade);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ const pill_config = {
|
||||
};
|
||||
|
||||
export function initialize_pill() {
|
||||
const container = $("#private_message_recipient").parent();
|
||||
const $container = $("#private_message_recipient").parent();
|
||||
|
||||
const pill = input_pill.create({
|
||||
container,
|
||||
$container,
|
||||
pill_config,
|
||||
create_item_from_text: user_pill.create_item_from_email,
|
||||
get_text_from_item: user_pill.get_email_from_item,
|
||||
|
||||
@@ -19,14 +19,14 @@ export function composing() {
|
||||
}
|
||||
|
||||
function get_or_set(fieldname, keep_leading_whitespace) {
|
||||
// We can't hoist the assignment of 'elem' out of this lambda,
|
||||
// We can't hoist the assignment of '$elem' out of this lambda,
|
||||
// because the DOM element might not exist yet when get_or_set
|
||||
// is called.
|
||||
return function (newval) {
|
||||
const elem = $(`#${CSS.escape(fieldname)}`);
|
||||
const oldval = elem.val();
|
||||
const $elem = $(`#${CSS.escape(fieldname)}`);
|
||||
const oldval = $elem.val();
|
||||
if (newval !== undefined) {
|
||||
elem.val(newval);
|
||||
$elem.val(newval);
|
||||
}
|
||||
return keep_leading_whitespace ? oldval.trimEnd() : oldval.trim();
|
||||
};
|
||||
|
||||
@@ -21,22 +21,22 @@ export function is_full_size() {
|
||||
return full_size_status;
|
||||
}
|
||||
|
||||
export function autosize_textarea(textarea) {
|
||||
export function autosize_textarea($textarea) {
|
||||
// Since this supports both compose and file upload, one must pass
|
||||
// in the text area to autosize.
|
||||
if (!is_full_size()) {
|
||||
autosize.update(textarea);
|
||||
autosize.update($textarea);
|
||||
}
|
||||
}
|
||||
|
||||
export function smart_insert(textarea, syntax) {
|
||||
export function smart_insert($textarea, syntax) {
|
||||
function is_space(c) {
|
||||
return c === " " || c === "\t" || c === "\n";
|
||||
}
|
||||
|
||||
const pos = textarea.caret();
|
||||
const before_str = textarea.val().slice(0, pos);
|
||||
const after_str = textarea.val().slice(pos);
|
||||
const pos = $textarea.caret();
|
||||
const before_str = $textarea.val().slice(0, pos);
|
||||
const after_str = $textarea.val().slice(pos);
|
||||
|
||||
if (
|
||||
pos > 0 &&
|
||||
@@ -60,32 +60,32 @@ export function smart_insert(textarea, syntax) {
|
||||
syntax += " ";
|
||||
}
|
||||
|
||||
textarea.trigger("focus");
|
||||
$textarea.trigger("focus");
|
||||
|
||||
// We prefer to use insertText, which supports things like undo better
|
||||
// for rich-text editing features like inserting links. But we fall
|
||||
// back to textarea.caret if the browser doesn't support insertText.
|
||||
if (!document.execCommand("insertText", false, syntax)) {
|
||||
textarea.caret(syntax);
|
||||
$textarea.caret(syntax);
|
||||
}
|
||||
|
||||
autosize_textarea(textarea);
|
||||
autosize_textarea($textarea);
|
||||
}
|
||||
|
||||
export function insert_syntax_and_focus(syntax, textarea = $("#compose-textarea")) {
|
||||
export function insert_syntax_and_focus(syntax, $textarea = $("#compose-textarea")) {
|
||||
// Generic helper for inserting syntax into the main compose box
|
||||
// where the cursor was and focusing the area. Mostly a thin
|
||||
// wrapper around smart_insert.
|
||||
smart_insert(textarea, syntax);
|
||||
smart_insert($textarea, syntax);
|
||||
}
|
||||
|
||||
export function replace_syntax(old_syntax, new_syntax, textarea = $("#compose-textarea")) {
|
||||
export function replace_syntax(old_syntax, new_syntax, $textarea = $("#compose-textarea")) {
|
||||
// Replaces `old_syntax` with `new_syntax` text in the compose box. Due to
|
||||
// the way that JavaScript handles string replacements, if `old_syntax` is
|
||||
// a string it will only replace the first instance. If `old_syntax` is
|
||||
// a RegExp with a global flag, it will replace all instances.
|
||||
textarea.val(
|
||||
textarea.val().replace(
|
||||
$textarea.val(
|
||||
$textarea.val().replace(
|
||||
old_syntax,
|
||||
() =>
|
||||
// We need this anonymous function to avoid JavaScript's
|
||||
@@ -193,7 +193,7 @@ export function make_compose_box_original_size() {
|
||||
$("#compose-textarea").trigger("focus");
|
||||
}
|
||||
|
||||
export function handle_keydown(event, textarea) {
|
||||
export function handle_keydown(event, $textarea) {
|
||||
// The event.key property will have uppercase letter if
|
||||
// the "Shift + <key>" combo was used or the Caps Lock
|
||||
// key was on. We turn to key to lowercase so the key bindings
|
||||
@@ -212,26 +212,26 @@ export function handle_keydown(event, textarea) {
|
||||
const isCmdOrCtrl = common.has_mac_keyboard() ? event.metaKey : event.ctrlKey;
|
||||
|
||||
if (type && isCmdOrCtrl) {
|
||||
format_text(textarea, type);
|
||||
autosize_textarea(textarea);
|
||||
format_text($textarea, type);
|
||||
autosize_textarea($textarea);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
export function handle_keyup(event, textarea) {
|
||||
export function handle_keyup(event, $textarea) {
|
||||
// Set the rtl class if the text has an rtl direction, remove it otherwise
|
||||
rtl.set_rtl_class_for_textarea(textarea);
|
||||
rtl.set_rtl_class_for_textarea($textarea);
|
||||
}
|
||||
|
||||
export function format_text(textarea, type) {
|
||||
export function format_text($textarea, type) {
|
||||
const italic_syntax = "*";
|
||||
const bold_syntax = "**";
|
||||
const bold_and_italic_syntax = "***";
|
||||
let is_selected_text_italic = false;
|
||||
let is_inner_text_italic = false;
|
||||
const field = textarea.get(0);
|
||||
let range = textarea.range();
|
||||
let text = textarea.val();
|
||||
const field = $textarea.get(0);
|
||||
let range = $textarea.range();
|
||||
let text = $textarea.val();
|
||||
const selected_text = range.text;
|
||||
|
||||
// Remove new line and space around selected text.
|
||||
@@ -239,7 +239,7 @@ export function format_text(textarea, type) {
|
||||
const right_trim_length = range.text.length - range.text.trimEnd().length;
|
||||
|
||||
field.setSelectionRange(range.start + left_trim_length, range.end - right_trim_length);
|
||||
range = textarea.range();
|
||||
range = $textarea.range();
|
||||
|
||||
const is_selection_bold = () =>
|
||||
// First check if there are enough characters before/after selection.
|
||||
|
||||
@@ -106,12 +106,12 @@ export function warn_if_private_stream_is_linked(linked_stream) {
|
||||
|
||||
const stream_name = linked_stream.name;
|
||||
|
||||
const warning_area = $("#compose_private_stream_alert");
|
||||
const $warning_area = $("#compose_private_stream_alert");
|
||||
const context = {stream_name};
|
||||
const new_row = render_compose_private_stream_alert(context);
|
||||
|
||||
warning_area.append(new_row);
|
||||
warning_area.show();
|
||||
$warning_area.append(new_row);
|
||||
$warning_area.show();
|
||||
}
|
||||
|
||||
export function warn_if_mentioning_unsubscribed_user(mentioned) {
|
||||
@@ -143,10 +143,10 @@ export function warn_if_mentioning_unsubscribed_user(mentioned) {
|
||||
}
|
||||
|
||||
if (needs_subscribe_warning(user_id, sub.stream_id)) {
|
||||
const error_area = $("#compose_invite_users");
|
||||
const existing_invites_area = $("#compose_invite_users .compose_invite_user");
|
||||
const $error_area = $("#compose_invite_users");
|
||||
const $existing_invites_area = $("#compose_invite_users .compose_invite_user");
|
||||
|
||||
const existing_invites = Array.from($(existing_invites_area), (user_row) =>
|
||||
const existing_invites = Array.from($($existing_invites_area), (user_row) =>
|
||||
Number.parseInt($(user_row).data("user-id"), 10),
|
||||
);
|
||||
|
||||
@@ -159,10 +159,10 @@ export function warn_if_mentioning_unsubscribed_user(mentioned) {
|
||||
};
|
||||
|
||||
const new_row = render_compose_invite_users(context);
|
||||
error_area.append(new_row);
|
||||
$error_area.append(new_row);
|
||||
}
|
||||
|
||||
error_area.show();
|
||||
$error_area.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,14 +224,14 @@ function show_all_everyone_warnings(stream_id) {
|
||||
count: stream_count,
|
||||
mention: wildcard_mention,
|
||||
});
|
||||
const error_area_all_everyone = $("#compose-all-everyone");
|
||||
const $error_area_all_everyone = $("#compose-all-everyone");
|
||||
|
||||
// only show one error for any number of @all or @everyone mentions
|
||||
if (!error_area_all_everyone.is(":visible")) {
|
||||
error_area_all_everyone.append(all_everyone_template);
|
||||
if (!$error_area_all_everyone.is(":visible")) {
|
||||
$error_area_all_everyone.append(all_everyone_template);
|
||||
}
|
||||
|
||||
error_area_all_everyone.show();
|
||||
$error_area_all_everyone.show();
|
||||
user_acknowledged_all_everyone = false;
|
||||
}
|
||||
|
||||
@@ -245,13 +245,13 @@ function show_announce_warnings(stream_id) {
|
||||
const stream_count = peer_data.get_subscriber_count(stream_id) || 0;
|
||||
|
||||
const announce_template = render_compose_announce({count: stream_count});
|
||||
const error_area_announce = $("#compose-announce");
|
||||
const $error_area_announce = $("#compose-announce");
|
||||
|
||||
if (!error_area_announce.is(":visible")) {
|
||||
error_area_announce.append(announce_template);
|
||||
if (!$error_area_announce.is(":visible")) {
|
||||
$error_area_announce.append(announce_template);
|
||||
}
|
||||
|
||||
error_area_announce.show();
|
||||
$error_area_announce.show();
|
||||
user_acknowledged_announce = false;
|
||||
}
|
||||
|
||||
@@ -660,12 +660,12 @@ export function check_overflow_text() {
|
||||
// expensive.
|
||||
const text = compose_state.message_content();
|
||||
const max_length = page_params.max_message_length;
|
||||
const indicator = $("#compose_limit_indicator");
|
||||
const $indicator = $("#compose_limit_indicator");
|
||||
|
||||
if (text.length > max_length) {
|
||||
indicator.addClass("over_limit");
|
||||
$indicator.addClass("over_limit");
|
||||
$("#compose-textarea").addClass("over_limit");
|
||||
indicator.text(text.length + "/" + max_length);
|
||||
$indicator.text(text.length + "/" + max_length);
|
||||
compose_error.show(
|
||||
$t_html(
|
||||
{
|
||||
@@ -677,16 +677,16 @@ export function check_overflow_text() {
|
||||
);
|
||||
$("#compose-send-button").prop("disabled", true);
|
||||
} else if (text.length > 0.9 * max_length) {
|
||||
indicator.removeClass("over_limit");
|
||||
$indicator.removeClass("over_limit");
|
||||
$("#compose-textarea").removeClass("over_limit");
|
||||
indicator.text(text.length + "/" + max_length);
|
||||
$indicator.text(text.length + "/" + max_length);
|
||||
|
||||
$("#compose-send-button").prop("disabled", false);
|
||||
if ($("#compose-send-status").hasClass("alert-error")) {
|
||||
$("#compose-send-status").stop(true).fadeOut();
|
||||
}
|
||||
} else {
|
||||
indicator.text("");
|
||||
$indicator.text("");
|
||||
$("#compose-textarea").removeClass("over_limit");
|
||||
|
||||
$("#compose-send-button").prop("disabled", false);
|
||||
|
||||
@@ -153,7 +153,7 @@ export function should_enter_send(e) {
|
||||
return this_enter_sends;
|
||||
}
|
||||
|
||||
export function handle_enter(textarea, e) {
|
||||
export function handle_enter($textarea, e) {
|
||||
// Used only if Enter doesn't send.
|
||||
|
||||
// Since this Enter doesn't send, we just want to do
|
||||
@@ -175,15 +175,15 @@ export function handle_enter(textarea, e) {
|
||||
// To properly emulate browser "Enter", if the
|
||||
// user had selected something in the textarea,
|
||||
// we need those characters to be cleared.
|
||||
const range = textarea.range();
|
||||
const range = $textarea.range();
|
||||
if (range.length > 0) {
|
||||
textarea.range(range.start, range.end).range("");
|
||||
$textarea.range(range.start, range.end).range("");
|
||||
}
|
||||
|
||||
// Now add the newline, remembering to resize the
|
||||
// textarea if needed.
|
||||
textarea.caret("\n");
|
||||
compose_ui.autosize_textarea(textarea);
|
||||
$textarea.caret("\n");
|
||||
compose_ui.autosize_textarea($textarea);
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ export function handle_enter(textarea, e) {
|
||||
// We can't focus at the time of keydown because we need to wait for typeahead.
|
||||
// And we can't compute where to focus at the time of keyup because only the keydown
|
||||
// has reliable information about whether it was a Tab or a Shift+Tab.
|
||||
let nextFocus = false;
|
||||
let $nextFocus = false;
|
||||
|
||||
function handle_keydown(e) {
|
||||
const key = e.key;
|
||||
@@ -245,11 +245,11 @@ function handle_keydown(e) {
|
||||
} else if (on_stream || on_topic || on_pm) {
|
||||
// We are doing the focusing on keyup to not abort the typeahead.
|
||||
if (on_stream) {
|
||||
nextFocus = $("#stream_message_recipient_topic");
|
||||
$nextFocus = $("#stream_message_recipient_topic");
|
||||
} else if (on_topic) {
|
||||
nextFocus = $("#compose-textarea");
|
||||
$nextFocus = $("#compose-textarea");
|
||||
} else if (on_pm) {
|
||||
nextFocus = $("#compose-textarea");
|
||||
$nextFocus = $("#compose-textarea");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,18 +259,18 @@ function handle_keyup(e) {
|
||||
if (
|
||||
// Enter key or Tab key
|
||||
(e.key === "Enter" || (e.key === "Tab" && !e.shiftKey)) &&
|
||||
nextFocus
|
||||
$nextFocus
|
||||
) {
|
||||
nextFocus.trigger("focus");
|
||||
nextFocus = false;
|
||||
$nextFocus.trigger("focus");
|
||||
$nextFocus = false;
|
||||
|
||||
// Prevent the form from submitting
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
export function split_at_cursor(query, input) {
|
||||
const cursor = input.caret();
|
||||
export function split_at_cursor(query, $input) {
|
||||
const cursor = $input.caret();
|
||||
return [query.slice(0, cursor), query.slice(cursor)];
|
||||
}
|
||||
|
||||
@@ -517,10 +517,10 @@ export function get_person_suggestions(query, opts) {
|
||||
|
||||
export function get_stream_topic_data(hacky_this) {
|
||||
const opts = {};
|
||||
const message_row = hacky_this.$element.closest(".message_row");
|
||||
if (message_row.length === 1) {
|
||||
const $message_row = hacky_this.$element.closest(".message_row");
|
||||
if ($message_row.length === 1) {
|
||||
// we are editing a message so we try to use it's keys.
|
||||
const msg = message_store.get(rows.id(message_row));
|
||||
const msg = message_store.get(rows.id($message_row));
|
||||
if (msg.type === "stream") {
|
||||
opts.stream = msg.stream;
|
||||
opts.topic = msg.topic;
|
||||
@@ -770,7 +770,7 @@ export function content_typeahead_selected(item, event) {
|
||||
const pieces = split_at_cursor(this.query, this.$element);
|
||||
let beginning = pieces[0];
|
||||
let rest = pieces[1];
|
||||
const textbox = this.$element;
|
||||
const $textbox = this.$element;
|
||||
// this highlight object will hold the start and end indices
|
||||
// for highlighting any placeholder text
|
||||
const highlight = {};
|
||||
@@ -898,9 +898,9 @@ export function content_typeahead_selected(item, event) {
|
||||
if (rest.startsWith(">")) {
|
||||
rest = rest.slice(1);
|
||||
}
|
||||
textbox.val(beginning + rest);
|
||||
textbox.caret(beginning.length, beginning.length);
|
||||
compose_ui.autosize_textarea(textbox);
|
||||
$textbox.val(beginning + rest);
|
||||
$textbox.caret(beginning.length, beginning.length);
|
||||
compose_ui.autosize_textarea($textbox);
|
||||
};
|
||||
flatpickr.show_flatpickr(this.$element[0], on_timestamp_selection, timestamp);
|
||||
return beginning + rest;
|
||||
@@ -908,19 +908,19 @@ export function content_typeahead_selected(item, event) {
|
||||
}
|
||||
|
||||
// Keep the cursor after the newly inserted text / selecting the
|
||||
// placeholder text, as Bootstrap will call textbox.change() to
|
||||
// placeholder text, as Bootstrap will call $textbox.change() to
|
||||
// overwrite the text in the textbox.
|
||||
setTimeout(() => {
|
||||
if (item.placeholder) {
|
||||
// This placeholder block is exclusively for slash
|
||||
// commands, which always appear at the start of the message.
|
||||
textbox.get(0).setSelectionRange(highlight.start, highlight.end);
|
||||
textbox.trigger("focus");
|
||||
$textbox.get(0).setSelectionRange(highlight.start, highlight.end);
|
||||
$textbox.trigger("focus");
|
||||
} else {
|
||||
textbox.caret(beginning.length, beginning.length);
|
||||
$textbox.caret(beginning.length, beginning.length);
|
||||
}
|
||||
// Also, trigger autosize to check if compose box needs to be resized.
|
||||
compose_ui.autosize_textarea(textbox);
|
||||
compose_ui.autosize_textarea($textbox);
|
||||
}, 0);
|
||||
return beginning + rest;
|
||||
}
|
||||
|
||||
@@ -20,67 +20,67 @@ This library implements two related, similar concepts:
|
||||
|
||||
const _message_content_height_cache = new Map();
|
||||
|
||||
function show_more_link(row) {
|
||||
row.find(".message_condenser").hide();
|
||||
row.find(".message_expander").show();
|
||||
function show_more_link($row) {
|
||||
$row.find(".message_condenser").hide();
|
||||
$row.find(".message_expander").show();
|
||||
}
|
||||
|
||||
function show_condense_link(row) {
|
||||
row.find(".message_expander").hide();
|
||||
row.find(".message_condenser").show();
|
||||
function show_condense_link($row) {
|
||||
$row.find(".message_expander").hide();
|
||||
$row.find(".message_condenser").show();
|
||||
}
|
||||
|
||||
function condense_row(row) {
|
||||
const content = row.find(".message_content");
|
||||
content.addClass("condensed");
|
||||
show_more_link(row);
|
||||
function condense_row($row) {
|
||||
const $content = $row.find(".message_content");
|
||||
$content.addClass("condensed");
|
||||
show_more_link($row);
|
||||
}
|
||||
|
||||
function uncondense_row(row) {
|
||||
const content = row.find(".message_content");
|
||||
content.removeClass("condensed");
|
||||
show_condense_link(row);
|
||||
function uncondense_row($row) {
|
||||
const $content = $row.find(".message_content");
|
||||
$content.removeClass("condensed");
|
||||
show_condense_link($row);
|
||||
}
|
||||
|
||||
export function uncollapse(row) {
|
||||
export function uncollapse($row) {
|
||||
// Uncollapse a message, restoring the condensed message [More] or
|
||||
// [Show less] link if necessary.
|
||||
const message = message_lists.current.get(rows.id(row));
|
||||
const message = message_lists.current.get(rows.id($row));
|
||||
message.collapsed = false;
|
||||
message_flags.save_uncollapsed(message);
|
||||
|
||||
const process_row = function process_row(row) {
|
||||
const content = row.find(".message_content");
|
||||
content.removeClass("collapsed");
|
||||
const process_row = function process_row($row) {
|
||||
const $content = $row.find(".message_content");
|
||||
$content.removeClass("collapsed");
|
||||
|
||||
if (message.condensed === true) {
|
||||
// This message was condensed by the user, so re-show the
|
||||
// [More] link.
|
||||
condense_row(row);
|
||||
condense_row($row);
|
||||
} else if (message.condensed === false) {
|
||||
// This message was un-condensed by the user, so re-show the
|
||||
// [Show less] link.
|
||||
uncondense_row(row);
|
||||
} else if (content.hasClass("could-be-condensed")) {
|
||||
uncondense_row($row);
|
||||
} else if ($content.hasClass("could-be-condensed")) {
|
||||
// By default, condense a long message.
|
||||
condense_row(row);
|
||||
condense_row($row);
|
||||
} else {
|
||||
// This was a short message, no more need for a [More] link.
|
||||
row.find(".message_expander").hide();
|
||||
$row.find(".message_expander").hide();
|
||||
}
|
||||
};
|
||||
|
||||
// We also need to collapse this message in the home view
|
||||
const home_row = message_lists.home.get_row(rows.id(row));
|
||||
const $home_row = message_lists.home.get_row(rows.id($row));
|
||||
|
||||
process_row(row);
|
||||
process_row(home_row);
|
||||
process_row($row);
|
||||
process_row($home_row);
|
||||
}
|
||||
|
||||
export function collapse(row) {
|
||||
export function collapse($row) {
|
||||
// Collapse a message, hiding the condensed message [More] or
|
||||
// [Show less] link if necessary.
|
||||
const message = message_lists.current.get(rows.id(row));
|
||||
const message = message_lists.current.get(rows.id($row));
|
||||
message.collapsed = true;
|
||||
|
||||
if (message.locally_echoed) {
|
||||
@@ -93,16 +93,16 @@ export function collapse(row) {
|
||||
|
||||
message_flags.save_collapsed(message);
|
||||
|
||||
const process_row = function process_row(row) {
|
||||
row.find(".message_content").addClass("collapsed");
|
||||
show_more_link(row);
|
||||
const process_row = function process_row($row) {
|
||||
$row.find(".message_content").addClass("collapsed");
|
||||
show_more_link($row);
|
||||
};
|
||||
|
||||
// We also need to collapse this message in the home view
|
||||
const home_row = message_lists.home.get_row(rows.id(row));
|
||||
const $home_row = message_lists.home.get_row(rows.id($row));
|
||||
|
||||
process_row(row);
|
||||
process_row(home_row);
|
||||
process_row($row);
|
||||
process_row($home_row);
|
||||
}
|
||||
|
||||
export function toggle_collapse(message) {
|
||||
@@ -121,30 +121,30 @@ export function toggle_collapse(message) {
|
||||
// * If the message is fully visible, either because it's too short to
|
||||
// condense or because it's already uncondensed, collapse it
|
||||
|
||||
const row = message_lists.current.get_row(message.id);
|
||||
if (!row) {
|
||||
const $row = message_lists.current.get_row(message.id);
|
||||
if (!$row) {
|
||||
return;
|
||||
}
|
||||
|
||||
const content = row.find(".message_content");
|
||||
const is_condensable = content.hasClass("could-be-condensed");
|
||||
const is_condensed = content.hasClass("condensed");
|
||||
const $content = $row.find(".message_content");
|
||||
const is_condensable = $content.hasClass("could-be-condensed");
|
||||
const is_condensed = $content.hasClass("condensed");
|
||||
if (message.collapsed) {
|
||||
if (is_condensable) {
|
||||
message.condensed = true;
|
||||
content.addClass("condensed");
|
||||
show_message_expander(row);
|
||||
row.find(".message_condenser").hide();
|
||||
$content.addClass("condensed");
|
||||
show_message_expander($row);
|
||||
$row.find(".message_condenser").hide();
|
||||
}
|
||||
uncollapse(row);
|
||||
uncollapse($row);
|
||||
} else {
|
||||
if (is_condensed) {
|
||||
message.condensed = false;
|
||||
content.removeClass("condensed");
|
||||
hide_message_expander(row);
|
||||
row.find(".message_condenser").show();
|
||||
$content.removeClass("condensed");
|
||||
hide_message_expander($row);
|
||||
$row.find(".message_condenser").show();
|
||||
} else {
|
||||
collapse(row);
|
||||
collapse($row);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,27 +170,27 @@ function get_message_height(elem, message_id) {
|
||||
return height;
|
||||
}
|
||||
|
||||
export function hide_message_expander(row) {
|
||||
if (row.find(".could-be-condensed").length !== 0) {
|
||||
row.find(".message_expander").hide();
|
||||
export function hide_message_expander($row) {
|
||||
if ($row.find(".could-be-condensed").length !== 0) {
|
||||
$row.find(".message_expander").hide();
|
||||
}
|
||||
}
|
||||
|
||||
export function hide_message_condenser(row) {
|
||||
if (row.find(".could-be-condensed").length !== 0) {
|
||||
row.find(".message_condenser").hide();
|
||||
export function hide_message_condenser($row) {
|
||||
if ($row.find(".could-be-condensed").length !== 0) {
|
||||
$row.find(".message_condenser").hide();
|
||||
}
|
||||
}
|
||||
|
||||
export function show_message_expander(row) {
|
||||
if (row.find(".could-be-condensed").length !== 0) {
|
||||
row.find(".message_expander").show();
|
||||
export function show_message_expander($row) {
|
||||
if ($row.find(".could-be-condensed").length !== 0) {
|
||||
$row.find(".message_expander").show();
|
||||
}
|
||||
}
|
||||
|
||||
export function show_message_condenser(row) {
|
||||
if (row.find(".could-be-condensed").length !== 0) {
|
||||
row.find(".message_condenser").show();
|
||||
export function show_message_condenser($row) {
|
||||
if ($row.find(".could-be-condensed").length !== 0) {
|
||||
$row.find(".message_condenser").show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,9 +198,9 @@ export function condense_and_collapse(elems) {
|
||||
const height_cutoff = message_viewport.height() * 0.65;
|
||||
|
||||
for (const elem of elems) {
|
||||
const content = $(elem).find(".message_content");
|
||||
const $content = $(elem).find(".message_content");
|
||||
|
||||
if (content.length !== 1) {
|
||||
if ($content.length !== 1) {
|
||||
// We could have a "/me did this" message or something
|
||||
// else without a `message_content` div.
|
||||
continue;
|
||||
@@ -221,9 +221,9 @@ export function condense_and_collapse(elems) {
|
||||
const long_message = message_height > height_cutoff;
|
||||
if (long_message) {
|
||||
// All long messages are flagged as such.
|
||||
content.addClass("could-be-condensed");
|
||||
$content.addClass("could-be-condensed");
|
||||
} else {
|
||||
content.removeClass("could-be-condensed");
|
||||
$content.removeClass("could-be-condensed");
|
||||
}
|
||||
|
||||
// If message.condensed is defined, then the user has manually
|
||||
@@ -242,14 +242,14 @@ export function condense_and_collapse(elems) {
|
||||
// By default, condense a long message.
|
||||
condense_row($(elem));
|
||||
} else {
|
||||
content.removeClass("condensed");
|
||||
$content.removeClass("condensed");
|
||||
$(elem).find(".message_expander").hide();
|
||||
}
|
||||
|
||||
// Completely hide the message and replace it with a [More]
|
||||
// link if the user has collapsed it.
|
||||
if (message.collapsed) {
|
||||
content.addClass("collapsed");
|
||||
$content.addClass("collapsed");
|
||||
$(elem).find(".message_expander").show();
|
||||
}
|
||||
}
|
||||
@@ -259,27 +259,27 @@ export function initialize() {
|
||||
$("#message_feed_container").on("click", ".message_expander", function (e) {
|
||||
// Expanding a message can mean either uncollapsing or
|
||||
// uncondensing it.
|
||||
const row = $(this).closest(".message_row");
|
||||
const message = message_lists.current.get(rows.id(row));
|
||||
const content = row.find(".message_content");
|
||||
const $row = $(this).closest(".message_row");
|
||||
const message = message_lists.current.get(rows.id($row));
|
||||
const $content = $row.find(".message_content");
|
||||
if (message.collapsed) {
|
||||
// Uncollapse.
|
||||
uncollapse(row);
|
||||
} else if (content.hasClass("condensed")) {
|
||||
uncollapse($row);
|
||||
} else if ($content.hasClass("condensed")) {
|
||||
// Uncondense (show the full long message).
|
||||
message.condensed = false;
|
||||
content.removeClass("condensed");
|
||||
$content.removeClass("condensed");
|
||||
$(this).hide();
|
||||
row.find(".message_condenser").show();
|
||||
$row.find(".message_condenser").show();
|
||||
}
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$("#message_feed_container").on("click", ".message_condenser", function (e) {
|
||||
const row = $(this).closest(".message_row");
|
||||
message_lists.current.get(rows.id(row)).condensed = true;
|
||||
condense_row(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
message_lists.current.get(rows.id($row)).condensed = true;
|
||||
condense_row($row);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
@@ -6,15 +6,15 @@ import * as message_lists from "./message_lists";
|
||||
import {page_params} from "./page_params";
|
||||
import * as rows from "./rows";
|
||||
|
||||
function find_boundary_tr(initial_tr, iterate_row) {
|
||||
function find_boundary_tr($initial_tr, iterate_row) {
|
||||
let j;
|
||||
let skip_same_td_check = false;
|
||||
let tr = initial_tr;
|
||||
let $tr = $initial_tr;
|
||||
|
||||
// If the selection boundary is somewhere that does not have a
|
||||
// parent tr, we should let the browser handle the copy-paste
|
||||
// entirely on its own
|
||||
if (tr.length === 0) {
|
||||
if ($tr.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ function find_boundary_tr(initial_tr, iterate_row) {
|
||||
// To ensure we can't enter an infinite loop, bail out (and let the
|
||||
// browser handle the copy-paste on its own) if we don't hit what we
|
||||
// are looking for within 10 rows.
|
||||
for (j = 0; !tr.is(".message_row") && j < 10; j += 1) {
|
||||
tr = iterate_row(tr);
|
||||
for (j = 0; !$tr.is(".message_row") && j < 10; j += 1) {
|
||||
$tr = iterate_row($tr);
|
||||
}
|
||||
if (j === 10) {
|
||||
return undefined;
|
||||
@@ -36,12 +36,12 @@ function find_boundary_tr(initial_tr, iterate_row) {
|
||||
// in this case)
|
||||
skip_same_td_check = true;
|
||||
}
|
||||
return [rows.id(tr), skip_same_td_check];
|
||||
return [rows.id($tr), skip_same_td_check];
|
||||
}
|
||||
|
||||
function construct_recipient_header(message_row) {
|
||||
function construct_recipient_header($message_row) {
|
||||
const message_header_content = rows
|
||||
.get_message_recipient_header(message_row)
|
||||
.get_message_recipient_header($message_row)
|
||||
.text()
|
||||
.replace(/\s+/g, " ")
|
||||
.replace(/^\s/, "")
|
||||
@@ -64,40 +64,40 @@ Do not be afraid to change this code if you understand
|
||||
how modern browsers deal with copy/paste. Just test
|
||||
your changes carefully.
|
||||
*/
|
||||
function construct_copy_div(div, start_id, end_id) {
|
||||
function construct_copy_div($div, start_id, end_id) {
|
||||
const copy_rows = rows.visible_range(start_id, end_id);
|
||||
|
||||
const start_row = copy_rows[0];
|
||||
const start_recipient_row = rows.get_message_recipient_row(start_row);
|
||||
const start_recipient_row_id = rows.id_for_recipient_row(start_recipient_row);
|
||||
const $start_row = copy_rows[0];
|
||||
const $start_recipient_row = rows.get_message_recipient_row($start_row);
|
||||
const start_recipient_row_id = rows.id_for_recipient_row($start_recipient_row);
|
||||
let should_include_start_recipient_header = false;
|
||||
let last_recipient_row_id = start_recipient_row_id;
|
||||
|
||||
for (const row of copy_rows) {
|
||||
const recipient_row_id = rows.id_for_recipient_row(rows.get_message_recipient_row(row));
|
||||
for (const $row of copy_rows) {
|
||||
const recipient_row_id = rows.id_for_recipient_row(rows.get_message_recipient_row($row));
|
||||
// if we found a message from another recipient,
|
||||
// it means that we have messages from several recipients,
|
||||
// so we have to add new recipient's bar to final copied message
|
||||
// and wouldn't forget to add start_recipient's bar at the beginning of final message
|
||||
if (recipient_row_id !== last_recipient_row_id) {
|
||||
div.append(construct_recipient_header(row));
|
||||
$div.append(construct_recipient_header($row));
|
||||
last_recipient_row_id = recipient_row_id;
|
||||
should_include_start_recipient_header = true;
|
||||
}
|
||||
const message = message_lists.current.get(rows.id(row));
|
||||
const message_firstp = $(message.content).slice(0, 1);
|
||||
message_firstp.prepend(message.sender_full_name + ": ");
|
||||
div.append(message_firstp);
|
||||
div.append($(message.content).slice(1));
|
||||
const message = message_lists.current.get(rows.id($row));
|
||||
const $message_firstp = $(message.content).slice(0, 1);
|
||||
$message_firstp.prepend(message.sender_full_name + ": ");
|
||||
$div.append($message_firstp);
|
||||
$div.append($(message.content).slice(1));
|
||||
}
|
||||
|
||||
if (should_include_start_recipient_header) {
|
||||
div.prepend(construct_recipient_header(start_row));
|
||||
$div.prepend(construct_recipient_header($start_row));
|
||||
}
|
||||
}
|
||||
|
||||
function select_div(div, selection) {
|
||||
div.css({
|
||||
function select_div($div, selection) {
|
||||
$div.css({
|
||||
position: "absolute",
|
||||
left: "-99999px",
|
||||
// Color and background is made according to "light theme"
|
||||
@@ -110,8 +110,8 @@ function select_div(div, selection) {
|
||||
color: "#333",
|
||||
background: "#FFF",
|
||||
}).attr("id", "copytempdiv");
|
||||
$("body").append(div);
|
||||
selection.selectAllChildren(div[0]);
|
||||
$("body").append($div);
|
||||
selection.selectAllChildren($div[0]);
|
||||
}
|
||||
|
||||
function remove_div(div, ranges, selection) {
|
||||
@@ -149,7 +149,7 @@ export function copy_handler() {
|
||||
const start_id = analysis.start_id;
|
||||
const end_id = analysis.end_id;
|
||||
const skip_same_td_check = analysis.skip_same_td_check;
|
||||
const div = $("<div>");
|
||||
const $div = $("<div>");
|
||||
|
||||
if (start_id === undefined || end_id === undefined) {
|
||||
// In this case either the starting message or the ending
|
||||
@@ -176,13 +176,13 @@ export function copy_handler() {
|
||||
// chance for overlaps between same message ids, avoiding which is much
|
||||
// more difficult since we can get a range (start_id and end_id) for
|
||||
// each selection `Range`.
|
||||
construct_copy_div(div, start_id, end_id);
|
||||
construct_copy_div($div, start_id, end_id);
|
||||
|
||||
// Select div so that the browser will copy it
|
||||
// instead of copying the original selection
|
||||
select_div(div, selection);
|
||||
select_div($div, selection);
|
||||
document.execCommand("copy");
|
||||
remove_div(div, ranges, selection);
|
||||
remove_div($div, ranges, selection);
|
||||
}
|
||||
|
||||
export function analyze_selection(selection) {
|
||||
@@ -200,9 +200,9 @@ export function analyze_selection(selection) {
|
||||
let i;
|
||||
let range;
|
||||
const ranges = [];
|
||||
let startc;
|
||||
let endc;
|
||||
let initial_end_tr;
|
||||
let $startc;
|
||||
let $endc;
|
||||
let $initial_end_tr;
|
||||
let start_id;
|
||||
let end_id;
|
||||
let start_data;
|
||||
@@ -216,10 +216,10 @@ export function analyze_selection(selection) {
|
||||
range = selection.getRangeAt(i);
|
||||
ranges.push(range);
|
||||
|
||||
startc = $(range.startContainer);
|
||||
$startc = $(range.startContainer);
|
||||
start_data = find_boundary_tr(
|
||||
$(startc.parents(".selectable_row, .message_header")[0]),
|
||||
(row) => row.next(),
|
||||
$($startc.parents(".selectable_row, .message_header")[0]),
|
||||
($row) => $row.next(),
|
||||
);
|
||||
if (start_data === undefined) {
|
||||
// Skip any selection sections that don't intersect a message.
|
||||
@@ -231,21 +231,21 @@ export function analyze_selection(selection) {
|
||||
start_id = start_data[0];
|
||||
}
|
||||
|
||||
endc = $(range.endContainer);
|
||||
$endc = $(range.endContainer);
|
||||
// If the selection ends in the bottom whitespace, we should
|
||||
// act as though the selection ends on the final message.
|
||||
// This handles the issue that Chrome seems to like selecting
|
||||
// the compose_close button when you go off the end of the
|
||||
// last message
|
||||
if (endc.attr("id") === "bottom_whitespace" || endc.attr("id") === "compose_close") {
|
||||
initial_end_tr = $(".message_row").last();
|
||||
if ($endc.attr("id") === "bottom_whitespace" || $endc.attr("id") === "compose_close") {
|
||||
$initial_end_tr = $(".message_row").last();
|
||||
// The selection goes off the end of the message feed, so
|
||||
// this is a multi-message selection.
|
||||
skip_same_td_check = true;
|
||||
} else {
|
||||
initial_end_tr = $(endc.parents(".selectable_row")[0]);
|
||||
$initial_end_tr = $($endc.parents(".selectable_row")[0]);
|
||||
}
|
||||
end_data = find_boundary_tr(initial_end_tr, (row) => row.prev());
|
||||
end_data = find_boundary_tr($initial_end_tr, ($row) => $row.prev());
|
||||
|
||||
if (end_data === undefined) {
|
||||
// Skip any selection sections that don't intersect a message.
|
||||
|
||||
@@ -4,8 +4,8 @@ export let csrf_token: string | undefined;
|
||||
|
||||
$(() => {
|
||||
// This requires that we used Jinja2's {% csrf_input %} somewhere on the page.
|
||||
const csrf_input = $('input[name="csrfmiddlewaretoken"]');
|
||||
csrf_token = csrf_input.attr("value");
|
||||
const $csrf_input = $('input[name="csrfmiddlewaretoken"]');
|
||||
csrf_token = $csrf_input.attr("value");
|
||||
if (csrf_token === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ export function hide_dialog_spinner() {
|
||||
$(".dialog_submit_button span").show();
|
||||
$("#dialog_widget_modal .modal__btn").prop("disabled", false);
|
||||
|
||||
const spinner = $("#dialog_widget_modal .modal__spinner");
|
||||
loading.destroy_indicator(spinner);
|
||||
const $spinner = $("#dialog_widget_modal .modal__spinner");
|
||||
loading.destroy_indicator($spinner);
|
||||
}
|
||||
|
||||
export function show_dialog_spinner() {
|
||||
@@ -54,8 +54,8 @@ export function show_dialog_spinner() {
|
||||
// Disable both the buttons.
|
||||
$("#dialog_widget_modal .modal__btn").prop("disabled", true);
|
||||
|
||||
const spinner = $("#dialog_widget_modal .modal__spinner");
|
||||
loading.make_indicator(spinner);
|
||||
const $spinner = $("#dialog_widget_modal .modal__spinner");
|
||||
loading.make_indicator($spinner);
|
||||
}
|
||||
|
||||
// Supports a callback to be called once the modal finishes closing.
|
||||
@@ -109,24 +109,24 @@ export function launch(conf) {
|
||||
id: conf.id,
|
||||
single_footer_button: conf.single_footer_button,
|
||||
});
|
||||
const dialog = $(html);
|
||||
$("body").append(dialog);
|
||||
const $dialog = $(html);
|
||||
$("body").append($dialog);
|
||||
|
||||
if (conf.post_render !== undefined) {
|
||||
conf.post_render();
|
||||
}
|
||||
|
||||
const submit_button = dialog.find(".dialog_submit_button");
|
||||
const $submit_button = $dialog.find(".dialog_submit_button");
|
||||
|
||||
// This is used to link the submit button with the form, if present, in the modal.
|
||||
// This makes it so that submitting this form by pressing Enter on an input element
|
||||
// triggers a click on the submit button.
|
||||
if (conf.form_id) {
|
||||
submit_button.attr("form", conf.form_id);
|
||||
$submit_button.attr("form", conf.form_id);
|
||||
}
|
||||
|
||||
// Set up handlers.
|
||||
submit_button.on("click", (e) => {
|
||||
$submit_button.on("click", (e) => {
|
||||
if (conf.validate_input && !conf.validate_input(e)) {
|
||||
return;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ export function launch(conf) {
|
||||
micromodal: true,
|
||||
on_show: () => {
|
||||
if (conf.focus_submit_on_open) {
|
||||
submit_button.trigger("focus");
|
||||
$submit_button.trigger("focus");
|
||||
}
|
||||
if (conf.on_show) {
|
||||
conf.on_show();
|
||||
|
||||
@@ -30,8 +30,8 @@ import * as ui_util from "./ui_util";
|
||||
import * as util from "./util";
|
||||
|
||||
function set_count(count) {
|
||||
const drafts_li = $(".top_left_drafts");
|
||||
ui_util.update_unread_count_in_dom(drafts_li, count);
|
||||
const $drafts_li = $(".top_left_drafts");
|
||||
ui_util.update_unread_count_in_dom($drafts_li, count);
|
||||
}
|
||||
|
||||
export const draft_model = (function () {
|
||||
@@ -360,22 +360,22 @@ function row_with_focus() {
|
||||
}
|
||||
|
||||
function row_before_focus() {
|
||||
const focused_row = row_with_focus();
|
||||
return focused_row.prev(".draft-row:visible");
|
||||
const $focused_row = row_with_focus();
|
||||
return $focused_row.prev(".draft-row:visible");
|
||||
}
|
||||
|
||||
function row_after_focus() {
|
||||
const focused_row = row_with_focus();
|
||||
return focused_row.next(".draft-row:visible");
|
||||
const $focused_row = row_with_focus();
|
||||
return $focused_row.next(".draft-row:visible");
|
||||
}
|
||||
|
||||
function remove_draft(draft_row) {
|
||||
function remove_draft($draft_row) {
|
||||
// Deletes the draft and removes it from the list
|
||||
const draft_id = draft_row.data("draft-id");
|
||||
const draft_id = $draft_row.data("draft-id");
|
||||
|
||||
draft_model.deleteDraft(draft_id);
|
||||
|
||||
draft_row.remove();
|
||||
$draft_row.remove();
|
||||
|
||||
if ($("#drafts_table .draft-row").length === 0) {
|
||||
$("#drafts_table .no-drafts").show();
|
||||
@@ -407,15 +407,15 @@ export function launch() {
|
||||
drafts,
|
||||
draft_lifetime: DRAFT_LIFETIME,
|
||||
});
|
||||
const drafts_table = $("#drafts_table");
|
||||
drafts_table.append(rendered);
|
||||
const $drafts_table = $("#drafts_table");
|
||||
$drafts_table.append(rendered);
|
||||
if ($("#drafts_table .draft-row").length > 0) {
|
||||
$("#drafts_table .no-drafts").hide();
|
||||
// Update possible dynamic elements.
|
||||
const rendered_drafts = drafts_table.find(
|
||||
const $rendered_drafts = $drafts_table.find(
|
||||
".message_content.rendered_markdown.restore-draft",
|
||||
);
|
||||
rendered_drafts.each(function () {
|
||||
$rendered_drafts.each(function () {
|
||||
rendered_markdown.update_elements($(this));
|
||||
});
|
||||
}
|
||||
@@ -429,15 +429,15 @@ export function launch() {
|
||||
|
||||
e.stopPropagation();
|
||||
|
||||
const draft_row = $(this).closest(".draft-row");
|
||||
const draft_id = draft_row.data("draft-id");
|
||||
restore_draft(draft_id);
|
||||
const $draft_row = $(this).closest(".draft-row");
|
||||
const $draft_id = $draft_row.data("draft-id");
|
||||
restore_draft($draft_id);
|
||||
});
|
||||
|
||||
$(".draft_controls .delete-draft").on("click", function () {
|
||||
const draft_row = $(this).closest(".draft-row");
|
||||
const $draft_row = $(this).closest(".draft-row");
|
||||
|
||||
remove_draft(draft_row);
|
||||
remove_draft($draft_row);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -489,35 +489,35 @@ function drafts_initialize_focus(event_name) {
|
||||
activate_element(focus_element);
|
||||
}
|
||||
|
||||
function drafts_scroll(next_focus_draft_row) {
|
||||
if (next_focus_draft_row[0] === undefined) {
|
||||
function drafts_scroll($next_focus_draft_row) {
|
||||
if ($next_focus_draft_row[0] === undefined) {
|
||||
return;
|
||||
}
|
||||
if (next_focus_draft_row[0].children[0] === undefined) {
|
||||
if ($next_focus_draft_row[0].children[0] === undefined) {
|
||||
return;
|
||||
}
|
||||
activate_element(next_focus_draft_row[0].children[0]);
|
||||
activate_element($next_focus_draft_row[0].children[0]);
|
||||
|
||||
// If focused draft is first draft, scroll to the top.
|
||||
if ($(".draft-info-box").first()[0].parentElement === next_focus_draft_row[0]) {
|
||||
if ($(".draft-info-box").first()[0].parentElement === $next_focus_draft_row[0]) {
|
||||
$(".drafts-list")[0].scrollTop = 0;
|
||||
}
|
||||
|
||||
// If focused draft is the last draft, scroll to the bottom.
|
||||
if ($(".draft-info-box").last()[0].parentElement === next_focus_draft_row[0]) {
|
||||
if ($(".draft-info-box").last()[0].parentElement === $next_focus_draft_row[0]) {
|
||||
$(".drafts-list")[0].scrollTop =
|
||||
$(".drafts-list")[0].scrollHeight - $(".drafts-list").height();
|
||||
}
|
||||
|
||||
// If focused draft is cut off from the top, scroll up halfway in draft modal.
|
||||
if (next_focus_draft_row.position().top < 55) {
|
||||
if ($next_focus_draft_row.position().top < 55) {
|
||||
// 55 is the minimum distance from the top that will require extra scrolling.
|
||||
$(".drafts-list")[0].scrollTop -= $(".drafts-list")[0].clientHeight / 2;
|
||||
}
|
||||
|
||||
// If focused draft is cut off from the bottom, scroll down halfway in draft modal.
|
||||
const dist_from_top = next_focus_draft_row.position().top;
|
||||
const total_dist = dist_from_top + next_focus_draft_row[0].clientHeight;
|
||||
const dist_from_top = $next_focus_draft_row.position().top;
|
||||
const total_dist = dist_from_top + $next_focus_draft_row[0].clientHeight;
|
||||
const dist_from_bottom = $(".drafts-container")[0].clientHeight - total_dist;
|
||||
if (dist_from_bottom < -4) {
|
||||
// -4 is the min dist from the bottom that will require extra scrolling.
|
||||
@@ -545,17 +545,17 @@ export function drafts_handle_events(e, event_key) {
|
||||
const focused_draft_id = row_with_focus().data("draft-id");
|
||||
// Allows user to delete drafts with Backspace
|
||||
if ((event_key === "backspace" || event_key === "delete") && focused_draft_id !== undefined) {
|
||||
const draft_row = row_with_focus();
|
||||
const next_draft_row = row_after_focus();
|
||||
const prev_draft_row = row_before_focus();
|
||||
const $draft_row = row_with_focus();
|
||||
const $next_draft_row = row_after_focus();
|
||||
const $prev_draft_row = row_before_focus();
|
||||
let draft_to_be_focused_id;
|
||||
|
||||
// Try to get the next draft in the list and 'focus' it
|
||||
// Use previous draft as a fallback
|
||||
if (next_draft_row[0] !== undefined) {
|
||||
draft_to_be_focused_id = next_draft_row.data("draft-id");
|
||||
} else if (prev_draft_row[0] !== undefined) {
|
||||
draft_to_be_focused_id = prev_draft_row.data("draft-id");
|
||||
if ($next_draft_row[0] !== undefined) {
|
||||
draft_to_be_focused_id = $next_draft_row.data("draft-id");
|
||||
} else if ($prev_draft_row[0] !== undefined) {
|
||||
draft_to_be_focused_id = $prev_draft_row.data("draft-id");
|
||||
}
|
||||
|
||||
const new_focus_element = document.querySelectorAll(
|
||||
@@ -565,7 +565,7 @@ export function drafts_handle_events(e, event_key) {
|
||||
activate_element(new_focus_element[0].children[0]);
|
||||
}
|
||||
|
||||
remove_draft(draft_row);
|
||||
remove_draft($draft_row);
|
||||
}
|
||||
|
||||
// This handles when pressing Enter while looking at drafts.
|
||||
@@ -583,7 +583,7 @@ export function drafts_handle_events(e, event_key) {
|
||||
export function open_overlay() {
|
||||
overlays.open_overlay({
|
||||
name: "drafts",
|
||||
overlay: $("#draft_overlay"),
|
||||
$overlay: $("#draft_overlay"),
|
||||
on_close() {
|
||||
browser_history.exit_overlay();
|
||||
},
|
||||
|
||||
@@ -40,19 +40,19 @@ export function DropdownListWidget({
|
||||
this.setup();
|
||||
}
|
||||
|
||||
DropdownListWidget.prototype.render_default_text = function (elem) {
|
||||
elem.text(this.default_text);
|
||||
elem.addClass("text-warning");
|
||||
elem.closest(".input-group").find(".dropdown_list_reset_button").hide();
|
||||
DropdownListWidget.prototype.render_default_text = function ($elem) {
|
||||
$elem.text(this.default_text);
|
||||
$elem.addClass("text-warning");
|
||||
$elem.closest(".input-group").find(".dropdown_list_reset_button").hide();
|
||||
};
|
||||
|
||||
DropdownListWidget.prototype.render = function (value) {
|
||||
$(`#${CSS.escape(this.container_id)} #${CSS.escape(this.value_id)}`).data("value", value);
|
||||
|
||||
const elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
const $elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
|
||||
if (!value || value === this.null_value) {
|
||||
this.render_default_text(elem);
|
||||
this.render_default_text($elem);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ DropdownListWidget.prototype.render = function (value) {
|
||||
const item = this.data.find((x) => x.value === value.toString());
|
||||
|
||||
if (item === undefined) {
|
||||
this.render_default_text(elem);
|
||||
this.render_default_text($elem);
|
||||
return;
|
||||
}
|
||||
|
||||
const text = this.render_text(item.name);
|
||||
elem.text(text);
|
||||
elem.removeClass("text-warning");
|
||||
elem.closest(".input-group").find(".dropdown_list_reset_button").show();
|
||||
$elem.text(text);
|
||||
$elem.removeClass("text-warning");
|
||||
$elem.closest(".input-group").find(".dropdown_list_reset_button").show();
|
||||
};
|
||||
|
||||
DropdownListWidget.prototype.update = function (value) {
|
||||
@@ -80,12 +80,12 @@ DropdownListWidget.prototype.register_event_handlers = function () {
|
||||
"click keypress",
|
||||
".list_item",
|
||||
(e) => {
|
||||
const setting_elem = $(e.currentTarget).closest(
|
||||
const $setting_elem = $(e.currentTarget).closest(
|
||||
`.${CSS.escape(this.widget_name)}_setting`,
|
||||
);
|
||||
if (e.type === "keypress") {
|
||||
if (e.key === "Enter") {
|
||||
setting_elem.find(".dropdown-menu").dropdown("toggle");
|
||||
$setting_elem.find(".dropdown-menu").dropdown("toggle");
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@@ -101,10 +101,12 @@ DropdownListWidget.prototype.register_event_handlers = function () {
|
||||
};
|
||||
|
||||
DropdownListWidget.prototype.setup_dropdown_widget = function (data) {
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
const get_data = () => {
|
||||
if (this.include_current_item) {
|
||||
return data;
|
||||
@@ -112,59 +114,63 @@ DropdownListWidget.prototype.setup_dropdown_widget = function (data) {
|
||||
return data.filter((x) => x.value !== this.value.toString());
|
||||
};
|
||||
|
||||
ListWidget.create(dropdown_list_body, get_data(data), {
|
||||
ListWidget.create($dropdown_list_body, get_data(data), {
|
||||
name: `${CSS.escape(this.widget_name)}_list`,
|
||||
modifier(item) {
|
||||
return render_dropdown_list({item});
|
||||
},
|
||||
filter: {
|
||||
element: search_input,
|
||||
$element: $search_input,
|
||||
predicate(item, value) {
|
||||
return item.name.toLowerCase().includes(value);
|
||||
},
|
||||
},
|
||||
simplebar_container: $(`#${CSS.escape(this.container_id)} .dropdown-list-wrapper`),
|
||||
$simplebar_container: $(`#${CSS.escape(this.container_id)} .dropdown-list-wrapper`),
|
||||
});
|
||||
};
|
||||
|
||||
// Sets the focus to the ListWidget input once the dropdown button is clicked.
|
||||
DropdownListWidget.prototype.dropdown_toggle_click_handler = function () {
|
||||
const dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const $dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
|
||||
dropdown_toggle.on("click", () => {
|
||||
search_input.val("").trigger("input");
|
||||
$dropdown_toggle.on("click", () => {
|
||||
$search_input.val("").trigger("input");
|
||||
});
|
||||
};
|
||||
|
||||
DropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const dropdown_menu = $(`.${CSS.escape(this.widget_name)}_setting .dropdown-menu`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
const $dropdown_menu = $(`.${CSS.escape(this.widget_name)}_setting .dropdown-menu`);
|
||||
|
||||
const dropdown_elements = () => {
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
|
||||
return dropdown_list_body.children().find("a");
|
||||
return $dropdown_list_body.children().find("a");
|
||||
};
|
||||
|
||||
// Rest of the key handlers are supported by our
|
||||
// bootstrap library.
|
||||
dropdown_menu.on("keydown", (e) => {
|
||||
function trigger_element_focus(element) {
|
||||
$dropdown_menu.on("keydown", (e) => {
|
||||
function trigger_element_focus($element) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
element.trigger("focus");
|
||||
$element.trigger("focus");
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowDown": {
|
||||
switch (e.target) {
|
||||
case dropdown_elements().last()[0]:
|
||||
trigger_element_focus(search_input);
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
case search_input[0]:
|
||||
case $search_input[0]:
|
||||
trigger_element_focus(dropdown_elements().first());
|
||||
break;
|
||||
}
|
||||
@@ -174,9 +180,9 @@ DropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
case "ArrowUp": {
|
||||
switch (e.target) {
|
||||
case dropdown_elements().first()[0]:
|
||||
trigger_element_focus(search_input);
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
case search_input[0]:
|
||||
case $search_input[0]:
|
||||
trigger_element_focus(dropdown_elements().last());
|
||||
}
|
||||
|
||||
@@ -184,11 +190,11 @@ DropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
}
|
||||
case "Tab": {
|
||||
switch (e.target) {
|
||||
case search_input[0]:
|
||||
case $search_input[0]:
|
||||
trigger_element_focus(dropdown_elements().first());
|
||||
break;
|
||||
case dropdown_elements().last()[0]:
|
||||
trigger_element_focus(search_input);
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -200,11 +206,13 @@ DropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
|
||||
DropdownListWidget.prototype.setup = function () {
|
||||
// populate the dropdown
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
const $dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
|
||||
this.setup_dropdown_widget(this.data);
|
||||
|
||||
@@ -214,7 +222,7 @@ DropdownListWidget.prototype.setup = function () {
|
||||
|
||||
this.dropdown_toggle_click_handler();
|
||||
|
||||
dropdown_toggle.on("focus", (e) => {
|
||||
$dropdown_toggle.on("focus", (e) => {
|
||||
// On opening a Bootstrap Dropdown, the parent element receives focus.
|
||||
// Here, we want our search input to have focus instead.
|
||||
e.preventDefault();
|
||||
@@ -222,8 +230,8 @@ DropdownListWidget.prototype.setup = function () {
|
||||
// dropdown, and only in the second call is the input
|
||||
// field visible in the DOM; so the following visibility
|
||||
// check ensures we wait for the second call to focus.
|
||||
if (dropdown_list_body.is(":visible")) {
|
||||
search_input.trigger("focus");
|
||||
if ($dropdown_list_body.is(":visible")) {
|
||||
$search_input.trigger("focus");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -292,15 +300,15 @@ MultiSelectDropdownListWidget.prototype.initialize_dropdown_values = function ()
|
||||
if (!this.initial_value || this.initial_value === this.null_value) {
|
||||
return;
|
||||
}
|
||||
const elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
const $elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
|
||||
// Push values from initial valued array to `data_selected`.
|
||||
this.data_selected.push(...this.initial_value);
|
||||
this.render_button_text(elem, this.limit);
|
||||
this.render_button_text($elem, this.limit);
|
||||
};
|
||||
|
||||
// Set the button text as per the selected data.
|
||||
MultiSelectDropdownListWidget.prototype.render_button_text = function (elem, limit) {
|
||||
MultiSelectDropdownListWidget.prototype.render_button_text = function ($elem, limit) {
|
||||
const items_selected = this.data_selected.length;
|
||||
let text = "";
|
||||
|
||||
@@ -308,7 +316,7 @@ MultiSelectDropdownListWidget.prototype.render_button_text = function (elem, lim
|
||||
this.destroy_tooltip();
|
||||
|
||||
if (items_selected === 0) {
|
||||
this.render_default_text(elem);
|
||||
this.render_default_text($elem);
|
||||
return;
|
||||
} else if (limit >= items_selected) {
|
||||
const data_selected = this.data.filter((data) => this.data_selected.includes(data.value));
|
||||
@@ -318,29 +326,31 @@ MultiSelectDropdownListWidget.prototype.render_button_text = function (elem, lim
|
||||
this.render_tooltip();
|
||||
}
|
||||
|
||||
elem.text(text);
|
||||
elem.removeClass("text-warning");
|
||||
elem.closest(".input-group").find(".dropdown_list_reset_button").show();
|
||||
$elem.text(text);
|
||||
$elem.removeClass("text-warning");
|
||||
$elem.closest(".input-group").find(".dropdown_list_reset_button").show();
|
||||
};
|
||||
|
||||
// Override the DrodownListWidget `render` function.
|
||||
MultiSelectDropdownListWidget.prototype.render = function (value) {
|
||||
const elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
const $elem = $(`#${CSS.escape(this.container_id)} #${CSS.escape(this.widget_name)}_name`);
|
||||
|
||||
if (!value || value === this.null_value) {
|
||||
this.render_default_text(elem);
|
||||
this.render_default_text($elem);
|
||||
return;
|
||||
}
|
||||
this.render_button_text(elem, this.limit);
|
||||
this.render_button_text($elem, this.limit);
|
||||
};
|
||||
|
||||
MultiSelectDropdownListWidget.prototype.dropdown_toggle_click_handler = function () {
|
||||
const dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const $dropdown_toggle = $(`#${CSS.escape(this.container_id)} .dropdown-toggle`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
|
||||
dropdown_toggle.on("click", () => {
|
||||
$dropdown_toggle.on("click", () => {
|
||||
this.reset_dropdown_items();
|
||||
search_input.val("").trigger("input");
|
||||
$search_input.val("").trigger("input");
|
||||
});
|
||||
};
|
||||
|
||||
@@ -372,12 +382,14 @@ MultiSelectDropdownListWidget.prototype.reset_dropdown_items = function () {
|
||||
|
||||
// Override the DrodownListWidget `setup_dropdown_widget` function.
|
||||
MultiSelectDropdownListWidget.prototype.setup_dropdown_widget = function (data) {
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
|
||||
ListWidget.create(dropdown_list_body, data, {
|
||||
ListWidget.create($dropdown_list_body, data, {
|
||||
name: `${CSS.escape(this.widget_name)}_list`,
|
||||
modifier(item) {
|
||||
return render_dropdown_list({item});
|
||||
@@ -386,51 +398,51 @@ MultiSelectDropdownListWidget.prototype.setup_dropdown_widget = function (data)
|
||||
selected_items: this.data_selected,
|
||||
},
|
||||
filter: {
|
||||
element: search_input,
|
||||
$element: $search_input,
|
||||
predicate(item, value) {
|
||||
return item.name.toLowerCase().includes(value);
|
||||
},
|
||||
},
|
||||
simplebar_container: $(`#${CSS.escape(this.container_id)} .dropdown-list-wrapper`),
|
||||
$simplebar_container: $(`#${CSS.escape(this.container_id)} .dropdown-list-wrapper`),
|
||||
});
|
||||
};
|
||||
|
||||
// Add the check mark to dropdown element passed.
|
||||
MultiSelectDropdownListWidget.prototype.add_check_mark = function (element) {
|
||||
const value = element.attr("data-value");
|
||||
const link_elem = element.find("a").expectOne();
|
||||
link_elem.prepend($("<i>", {class: "fa fa-check"}));
|
||||
element.addClass("checked");
|
||||
MultiSelectDropdownListWidget.prototype.add_check_mark = function ($element) {
|
||||
const value = $element.attr("data-value");
|
||||
const $link_elem = $element.find("a").expectOne();
|
||||
$link_elem.prepend($("<i>", {class: "fa fa-check"}));
|
||||
$element.addClass("checked");
|
||||
this.data_selected.push(value);
|
||||
};
|
||||
|
||||
// Remove the check mark from dropdown element.
|
||||
MultiSelectDropdownListWidget.prototype.remove_check_mark = function (element) {
|
||||
const icon = element.find("i").expectOne();
|
||||
const value = element.attr("data-value");
|
||||
MultiSelectDropdownListWidget.prototype.remove_check_mark = function ($element) {
|
||||
const $icon = $element.find("i").expectOne();
|
||||
const value = $element.attr("data-value");
|
||||
const index = this.data_selected.indexOf(value);
|
||||
|
||||
if (index > -1) {
|
||||
icon.remove();
|
||||
element.removeClass("checked");
|
||||
$icon.remove();
|
||||
$element.removeClass("checked");
|
||||
this.data_selected.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Render the tooltip once the text changes to `n` selected.
|
||||
MultiSelectDropdownListWidget.prototype.render_tooltip = function () {
|
||||
const elem = $(`#${CSS.escape(this.container_id)}`);
|
||||
const $elem = $(`#${CSS.escape(this.container_id)}`);
|
||||
const selected_items = this.data.filter((item) => this.checked_items.includes(item.value));
|
||||
|
||||
tippy(elem[0], {
|
||||
tippy($elem[0], {
|
||||
content: selected_items.map((item) => item.name).join(", "),
|
||||
placement: "top",
|
||||
});
|
||||
};
|
||||
|
||||
MultiSelectDropdownListWidget.prototype.destroy_tooltip = function () {
|
||||
const elem = $(`#${CSS.escape(this.container_id)}`);
|
||||
const tippy_instance = elem[0]._tippy;
|
||||
const $elem = $(`#${CSS.escape(this.container_id)}`);
|
||||
const tippy_instance = $elem[0]._tippy;
|
||||
if (!tippy_instance) {
|
||||
return;
|
||||
}
|
||||
@@ -442,35 +454,37 @@ MultiSelectDropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
// Main keydown event handler which transfers the focus from one child element
|
||||
// to another.
|
||||
|
||||
const search_input = $(`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`);
|
||||
const dropdown_menu = $(`.${CSS.escape(this.widget_name)}_setting .dropdown-menu`);
|
||||
const filter_button = $(`#${CSS.escape(this.container_id)} .multiselect_btn`);
|
||||
const $search_input = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-search > input[type=text]`,
|
||||
);
|
||||
const $dropdown_menu = $(`.${CSS.escape(this.widget_name)}_setting .dropdown-menu`);
|
||||
const $filter_button = $(`#${CSS.escape(this.container_id)} .multiselect_btn`);
|
||||
|
||||
const dropdown_elements = () => {
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
|
||||
return dropdown_list_body.children().find("a");
|
||||
return $dropdown_list_body.children().find("a");
|
||||
};
|
||||
|
||||
dropdown_menu.on("keydown", (e) => {
|
||||
function trigger_element_focus(element) {
|
||||
$dropdown_menu.on("keydown", (e) => {
|
||||
function trigger_element_focus($element) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
element.trigger("focus");
|
||||
$element.trigger("focus");
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowDown": {
|
||||
switch (e.target) {
|
||||
case dropdown_elements().last()[0]:
|
||||
trigger_element_focus(filter_button);
|
||||
trigger_element_focus($filter_button);
|
||||
break;
|
||||
case $(`#${CSS.escape(this.container_id)} .multiselect_btn`)[0]:
|
||||
trigger_element_focus(search_input);
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
case search_input[0]:
|
||||
case $search_input[0]:
|
||||
trigger_element_focus(dropdown_elements().first());
|
||||
break;
|
||||
}
|
||||
@@ -480,10 +494,10 @@ MultiSelectDropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
case "ArrowUp": {
|
||||
switch (e.target) {
|
||||
case dropdown_elements().first()[0]:
|
||||
trigger_element_focus(search_input);
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
case search_input[0]:
|
||||
trigger_element_focus(filter_button);
|
||||
case $search_input[0]:
|
||||
trigger_element_focus($filter_button);
|
||||
break;
|
||||
case $(`#${CSS.escape(this.container_id)} .multiselect_btn`)[0]:
|
||||
trigger_element_focus(dropdown_elements().last());
|
||||
@@ -494,11 +508,11 @@ MultiSelectDropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
}
|
||||
case "Tab": {
|
||||
switch (e.target) {
|
||||
case search_input[0]:
|
||||
case $search_input[0]:
|
||||
trigger_element_focus(dropdown_elements().first());
|
||||
break;
|
||||
case filter_button[0]:
|
||||
trigger_element_focus(search_input);
|
||||
case $filter_button[0]:
|
||||
trigger_element_focus($search_input);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -510,20 +524,20 @@ MultiSelectDropdownListWidget.prototype.dropdown_focus_events = function () {
|
||||
|
||||
// Override the `register_event_handlers` function.
|
||||
MultiSelectDropdownListWidget.prototype.register_event_handlers = function () {
|
||||
const dropdown_list_body = $(
|
||||
const $dropdown_list_body = $(
|
||||
`#${CSS.escape(this.container_id)} .dropdown-list-body`,
|
||||
).expectOne();
|
||||
|
||||
dropdown_list_body.on("click keypress", ".list_item", (e) => {
|
||||
$dropdown_list_body.on("click keypress", ".list_item", (e) => {
|
||||
if (e.type === "keypress" && e.key !== "Enter") {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = $(e.target.closest("li"));
|
||||
if (element.hasClass("checked")) {
|
||||
this.remove_check_mark(element);
|
||||
const $element = $(e.target.closest("li"));
|
||||
if ($element.hasClass("checked")) {
|
||||
this.remove_check_mark($element);
|
||||
} else {
|
||||
this.add_check_mark(element);
|
||||
this.add_check_mark($element);
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
@@ -556,10 +570,10 @@ MultiSelectDropdownListWidget.prototype.register_event_handlers = function () {
|
||||
// the dropdown is closed.
|
||||
if (this.on_close) {
|
||||
e.stopPropagation();
|
||||
const setting_elem = $(e.currentTarget).closest(
|
||||
const $setting_elem = $(e.currentTarget).closest(
|
||||
`.${CSS.escape(this.widget_name)}_setting`,
|
||||
);
|
||||
setting_elem.find(".dropdown-menu").dropdown("toggle");
|
||||
$setting_elem.find(".dropdown-menu").dropdown("toggle");
|
||||
|
||||
this.on_close();
|
||||
}
|
||||
|
||||
@@ -35,21 +35,21 @@ let waiting_for_ack = new Map();
|
||||
// These retry spinner functions return true if and only if the
|
||||
// spinner already is in the requested state, which can be used to
|
||||
// avoid sending duplicate requests.
|
||||
function show_retry_spinner(row) {
|
||||
const retry_spinner = row.find(".refresh-failed-message");
|
||||
function show_retry_spinner($row) {
|
||||
const $retry_spinner = $row.find(".refresh-failed-message");
|
||||
|
||||
if (!retry_spinner.hasClass("rotating")) {
|
||||
retry_spinner.toggleClass("rotating", true);
|
||||
if (!$retry_spinner.hasClass("rotating")) {
|
||||
$retry_spinner.toggleClass("rotating", true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function hide_retry_spinner(row) {
|
||||
const retry_spinner = row.find(".refresh-failed-message");
|
||||
function hide_retry_spinner($row) {
|
||||
const $retry_spinner = $row.find(".refresh-failed-message");
|
||||
|
||||
if (retry_spinner.hasClass("rotating")) {
|
||||
retry_spinner.toggleClass("rotating", false);
|
||||
if ($retry_spinner.hasClass("rotating")) {
|
||||
$retry_spinner.toggleClass("rotating", false);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -67,9 +67,9 @@ function failed_message_success(message_id) {
|
||||
ui.show_failed_message_success(message_id);
|
||||
}
|
||||
|
||||
function resend_message(message, row) {
|
||||
function resend_message(message, $row) {
|
||||
message.content = message.raw_content;
|
||||
if (show_retry_spinner(row)) {
|
||||
if (show_retry_spinner($row)) {
|
||||
// retry already in in progress
|
||||
return;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ function resend_message(message, row) {
|
||||
const message_id = data.id;
|
||||
const locally_echoed = true;
|
||||
|
||||
hide_retry_spinner(row);
|
||||
hide_retry_spinner($row);
|
||||
|
||||
compose.send_message_success(local_id, message_id, locally_echoed);
|
||||
|
||||
@@ -95,7 +95,7 @@ function resend_message(message, row) {
|
||||
function on_error(response) {
|
||||
message_send_error(message.id, response);
|
||||
setTimeout(() => {
|
||||
hide_retry_spinner(row);
|
||||
hide_retry_spinner($row);
|
||||
}, 300);
|
||||
blueslip.log("Manual resend of message failed");
|
||||
}
|
||||
@@ -470,8 +470,8 @@ export function initialize() {
|
||||
$("#main_div").on("click", selector, function (e) {
|
||||
e.stopPropagation();
|
||||
popovers.hide_all();
|
||||
const row = $(this).closest(".message_row");
|
||||
const local_id = rows.local_echo_id(row);
|
||||
const $row = $(this).closest(".message_row");
|
||||
const local_id = rows.local_echo_id($row);
|
||||
// Message should be waiting for ack and only have a local id,
|
||||
// otherwise send would not have failed
|
||||
const message = waiting_for_ack.get(local_id);
|
||||
@@ -482,7 +482,7 @@ export function initialize() {
|
||||
);
|
||||
return;
|
||||
}
|
||||
callback(message, row);
|
||||
callback(message, $row);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ const APPROX_WIDTH = 255;
|
||||
// implemented as the emoji_popover.
|
||||
export let complete_emoji_catalog = [];
|
||||
|
||||
let current_message_emoji_popover_elem;
|
||||
let $current_message_emoji_popover_elem;
|
||||
let emoji_catalog_last_coordinates = {
|
||||
section: 0,
|
||||
index: 0,
|
||||
@@ -175,9 +175,9 @@ const generate_emoji_picker_content = function (id) {
|
||||
});
|
||||
};
|
||||
|
||||
function refill_section_head_offsets(popover) {
|
||||
function refill_section_head_offsets($popover) {
|
||||
section_head_offsets = [];
|
||||
popover.find(".emoji-popover-subheading").each(function () {
|
||||
$popover.find(".emoji-popover-subheading").each(function () {
|
||||
section_head_offsets.push({
|
||||
section: $(this).attr("data-section"),
|
||||
position_y: $(this).position().top,
|
||||
@@ -186,7 +186,7 @@ function refill_section_head_offsets(popover) {
|
||||
}
|
||||
|
||||
export function reactions_popped() {
|
||||
return current_message_emoji_popover_elem !== undefined;
|
||||
return $current_message_emoji_popover_elem !== undefined;
|
||||
}
|
||||
|
||||
export function hide_emoji_popover() {
|
||||
@@ -198,9 +198,9 @@ export function hide_emoji_popover() {
|
||||
$(".app, .header, .modal__overlay, #set_user_status_modal").css("pointer-events", "all");
|
||||
}
|
||||
if (reactions_popped()) {
|
||||
current_message_emoji_popover_elem.popover("destroy");
|
||||
current_message_emoji_popover_elem.removeClass("reaction_button_visible");
|
||||
current_message_emoji_popover_elem = undefined;
|
||||
$current_message_emoji_popover_elem.popover("destroy");
|
||||
$current_message_emoji_popover_elem.removeClass("reaction_button_visible");
|
||||
$current_message_emoji_popover_elem = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,16 +210,16 @@ function get_selected_emoji() {
|
||||
|
||||
function get_rendered_emoji(section, index) {
|
||||
const emoji_id = get_emoji_id(section, index);
|
||||
const emoji = $(`.emoji-popover-emoji[data-emoji-id='${CSS.escape(emoji_id)}']`);
|
||||
if (emoji.length > 0) {
|
||||
return emoji;
|
||||
const $emoji = $(`.emoji-popover-emoji[data-emoji-id='${CSS.escape(emoji_id)}']`);
|
||||
if ($emoji.length > 0) {
|
||||
return $emoji;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function filter_emojis() {
|
||||
const elt = $(".emoji-popover-filter").expectOne();
|
||||
const query = elt.val().trim().toLowerCase();
|
||||
const $elt = $(".emoji-popover-filter").expectOne();
|
||||
const query = $elt.val().trim().toLowerCase();
|
||||
const message_id = $(".emoji-search-results-container").data("message-id");
|
||||
const search_results_visible = $(".emoji-search-results-container").is(":visible");
|
||||
if (query !== "") {
|
||||
@@ -288,12 +288,12 @@ function is_status_emoji(emoji) {
|
||||
function process_enter_while_filtering(e) {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
const first_emoji = get_rendered_emoji(0, 0);
|
||||
if (first_emoji) {
|
||||
if (is_composition(first_emoji)) {
|
||||
first_emoji.trigger("click");
|
||||
const $first_emoji = get_rendered_emoji(0, 0);
|
||||
if ($first_emoji) {
|
||||
if (is_composition($first_emoji)) {
|
||||
$first_emoji.trigger("click");
|
||||
} else {
|
||||
toggle_reaction(first_emoji.attr("data-emoji-name"), e);
|
||||
toggle_reaction($first_emoji.attr("data-emoji-name"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -345,20 +345,20 @@ function update_emoji_showcase($focused_emoji) {
|
||||
}
|
||||
|
||||
function maybe_change_focused_emoji($emoji_map, next_section, next_index, preserve_scroll) {
|
||||
const next_emoji = get_rendered_emoji(next_section, next_index);
|
||||
if (next_emoji) {
|
||||
const $next_emoji = get_rendered_emoji(next_section, next_index);
|
||||
if ($next_emoji) {
|
||||
current_section = next_section;
|
||||
current_index = next_index;
|
||||
if (!preserve_scroll) {
|
||||
next_emoji.trigger("focus");
|
||||
$next_emoji.trigger("focus");
|
||||
} else {
|
||||
const start = ui.get_scroll_element($emoji_map).scrollTop();
|
||||
next_emoji.trigger("focus");
|
||||
$next_emoji.trigger("focus");
|
||||
if (ui.get_scroll_element($emoji_map).scrollTop() !== start) {
|
||||
ui.get_scroll_element($emoji_map).scrollTop(start);
|
||||
}
|
||||
}
|
||||
update_emoji_showcase(next_emoji);
|
||||
update_emoji_showcase($next_emoji);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -449,7 +449,7 @@ export function navigate(event_name, e) {
|
||||
const $popover = $(".emoji-popover").expectOne();
|
||||
const $emoji_map = $popover.find(".emoji-popover-emoji-map").expectOne();
|
||||
|
||||
const selected_emoji = get_rendered_emoji(current_section, current_index);
|
||||
const $selected_emoji = get_rendered_emoji(current_section, current_index);
|
||||
const is_filter_focused = $(".emoji-popover-filter").is(":focus");
|
||||
// special cases
|
||||
if (is_filter_focused) {
|
||||
@@ -457,16 +457,16 @@ export function navigate(event_name, e) {
|
||||
const filter_text = $(".emoji-popover-filter").val();
|
||||
const is_cursor_at_end = $(".emoji-popover-filter").caret() === filter_text.length;
|
||||
if (event_name === "down_arrow" || (is_cursor_at_end && event_name === "right_arrow")) {
|
||||
selected_emoji.trigger("focus");
|
||||
$selected_emoji.trigger("focus");
|
||||
if (current_section === 0 && current_index < 6) {
|
||||
ui.get_scroll_element($emoji_map).scrollTop(0);
|
||||
}
|
||||
update_emoji_showcase(selected_emoji);
|
||||
update_emoji_showcase($selected_emoji);
|
||||
return true;
|
||||
}
|
||||
if (event_name === "tab") {
|
||||
selected_emoji.trigger("focus");
|
||||
update_emoji_showcase(selected_emoji);
|
||||
$selected_emoji.trigger("focus");
|
||||
update_emoji_showcase($selected_emoji);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -474,7 +474,7 @@ export function navigate(event_name, e) {
|
||||
(current_section === 0 && current_index < 6 && event_name === "up_arrow") ||
|
||||
(current_section === 0 && current_index === 0 && event_name === "left_arrow")
|
||||
) {
|
||||
if (selected_emoji) {
|
||||
if ($selected_emoji) {
|
||||
// In this case, we're move up into the reaction
|
||||
// filter. Here, we override the default browser
|
||||
// behavior, which in Firefox is good (preserving
|
||||
@@ -531,8 +531,8 @@ function process_keypress(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const emoji_filter = $(".emoji-popover-filter");
|
||||
const old_query = emoji_filter.val();
|
||||
const $emoji_filter = $(".emoji-popover-filter");
|
||||
const old_query = $emoji_filter.val();
|
||||
let new_query = "";
|
||||
|
||||
if (pressed_key === 8) {
|
||||
@@ -544,16 +544,16 @@ function process_keypress(e) {
|
||||
new_query = old_query + key_str;
|
||||
}
|
||||
|
||||
emoji_filter.val(new_query);
|
||||
$emoji_filter.val(new_query);
|
||||
change_focus_to_filter();
|
||||
filter_emojis();
|
||||
}
|
||||
}
|
||||
|
||||
export function emoji_select_tab(elt) {
|
||||
const scrolltop = elt.scrollTop();
|
||||
const scrollheight = elt.prop("scrollHeight");
|
||||
const elt_height = elt.height();
|
||||
export function emoji_select_tab($elt) {
|
||||
const scrolltop = $elt.scrollTop();
|
||||
const scrollheight = $elt.prop("scrollHeight");
|
||||
const elt_height = $elt.height();
|
||||
let currently_selected = "";
|
||||
for (const o of section_head_offsets) {
|
||||
if (scrolltop + elt_height / 2 >= o.position_y) {
|
||||
@@ -577,8 +577,8 @@ export function emoji_select_tab(elt) {
|
||||
}
|
||||
}
|
||||
|
||||
function register_popover_events(popover) {
|
||||
const $emoji_map = popover.find(".emoji-popover-emoji-map");
|
||||
function register_popover_events($popover) {
|
||||
const $emoji_map = $popover.find(".emoji-popover-emoji-map");
|
||||
|
||||
ui.get_scroll_element($emoji_map).on("scroll", () => {
|
||||
emoji_select_tab(ui.get_scroll_element($emoji_map));
|
||||
@@ -598,11 +598,11 @@ function register_popover_events(popover) {
|
||||
});
|
||||
}
|
||||
|
||||
export function build_emoji_popover(elt, id) {
|
||||
export function build_emoji_popover($elt, id) {
|
||||
const template_args = {
|
||||
class: "emoji-info-popover",
|
||||
};
|
||||
let placement = popovers.compute_placement(elt, APPROX_HEIGHT, APPROX_WIDTH, true);
|
||||
let placement = popovers.compute_placement($elt, APPROX_HEIGHT, APPROX_WIDTH, true);
|
||||
|
||||
if (placement === "viewport_center") {
|
||||
// For legacy reasons `compute_placement` actually can
|
||||
@@ -619,7 +619,7 @@ export function build_emoji_popover(elt, id) {
|
||||
template = "<div class='popover-flex'>" + template + "</div>";
|
||||
}
|
||||
|
||||
elt.popover({
|
||||
$elt.popover({
|
||||
// temporary patch for handling popover placement of `viewport_center`
|
||||
placement,
|
||||
fix_positions: true,
|
||||
@@ -629,11 +629,11 @@ export function build_emoji_popover(elt, id) {
|
||||
html: true,
|
||||
trigger: "manual",
|
||||
});
|
||||
elt.popover("show");
|
||||
$elt.popover("show");
|
||||
|
||||
const popover = elt.data("popover").$tip;
|
||||
popover.find(".emoji-popover-filter").trigger("focus");
|
||||
current_message_emoji_popover_elem = elt;
|
||||
const $popover = $elt.data("popover").$tip;
|
||||
$popover.find(".emoji-popover-filter").trigger("focus");
|
||||
$current_message_emoji_popover_elem = $elt;
|
||||
|
||||
emoji_catalog_last_coordinates = {
|
||||
section: 0,
|
||||
@@ -641,31 +641,31 @@ export function build_emoji_popover(elt, id) {
|
||||
};
|
||||
show_emoji_catalog();
|
||||
|
||||
elt.ready(() => refill_section_head_offsets(popover));
|
||||
register_popover_events(popover);
|
||||
$elt.ready(() => refill_section_head_offsets($popover));
|
||||
register_popover_events($popover);
|
||||
}
|
||||
|
||||
export function toggle_emoji_popover(element, id) {
|
||||
const last_popover_elem = current_message_emoji_popover_elem;
|
||||
const $last_popover_elem = $current_message_emoji_popover_elem;
|
||||
popovers.hide_all();
|
||||
if (last_popover_elem !== undefined && last_popover_elem.get()[0] === element) {
|
||||
if ($last_popover_elem !== undefined && $last_popover_elem.get()[0] === element) {
|
||||
// We want it to be the case that a user can dismiss a popover
|
||||
// by clicking on the same element that caused the popover.
|
||||
return;
|
||||
}
|
||||
|
||||
$(element).closest(".message_row").toggleClass("has_popover has_emoji_popover");
|
||||
const elt = $(element);
|
||||
const $elt = $(element);
|
||||
if (id !== undefined) {
|
||||
message_lists.current.select_id(id);
|
||||
}
|
||||
|
||||
if (user_status_ui.user_status_picker_open()) {
|
||||
build_emoji_popover(elt, id, true);
|
||||
} else if (elt.data("popover") === undefined) {
|
||||
build_emoji_popover($elt, id, true);
|
||||
} else if ($elt.data("popover") === undefined) {
|
||||
// Keep the element over which the popover is based off visible.
|
||||
elt.addClass("reaction_button_visible");
|
||||
build_emoji_popover(elt, id);
|
||||
$elt.addClass("reaction_button_visible");
|
||||
build_emoji_popover($elt, id);
|
||||
}
|
||||
reset_emoji_showcase();
|
||||
}
|
||||
@@ -686,13 +686,13 @@ export function register_click_handlers() {
|
||||
// The following check will return false if emoji was not selected in
|
||||
// message edit form.
|
||||
if (edit_message_id !== null) {
|
||||
const edit_message_textarea = $(
|
||||
const $edit_message_textarea = $(
|
||||
`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`,
|
||||
);
|
||||
// Assign null to edit_message_id so that the selection of emoji in new
|
||||
// message composition form works correctly.
|
||||
edit_message_id = null;
|
||||
compose_ui.insert_syntax_and_focus(emoji_text, edit_message_textarea);
|
||||
compose_ui.insert_syntax_and_focus(emoji_text, $edit_message_textarea);
|
||||
} else {
|
||||
compose_ui.insert_syntax_and_focus(emoji_text);
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ function is_numeric_key(key) {
|
||||
}
|
||||
|
||||
export function show_flatpickr(element, callback, default_timestamp, options = {}) {
|
||||
const flatpickr_input = $("<input id='#timestamp_flatpickr'>");
|
||||
const $flatpickr_input = $("<input id='#timestamp_flatpickr'>");
|
||||
|
||||
const instance = flatpickr_input.flatpickr({
|
||||
const instance = $flatpickr_input.flatpickr({
|
||||
mode: "single",
|
||||
enableTime: true,
|
||||
clickOpens: false,
|
||||
@@ -59,9 +59,9 @@ export function show_flatpickr(element, callback, default_timestamp, options = {
|
||||
...options,
|
||||
});
|
||||
|
||||
const container = $($(instance.innerContainer).parent());
|
||||
const $container = $($(instance.innerContainer).parent());
|
||||
|
||||
container.on("keydown", (e) => {
|
||||
$container.on("keydown", (e) => {
|
||||
if (is_numeric_key(e.key)) {
|
||||
// Let users type numeric values
|
||||
return true;
|
||||
@@ -83,7 +83,7 @@ export function show_flatpickr(element, callback, default_timestamp, options = {
|
||||
return true; // use flatpickr default implementation
|
||||
}
|
||||
$(element).toggleClass("has_popover");
|
||||
container.find(".flatpickr-confirm").trigger("click");
|
||||
$container.find(".flatpickr-confirm").trigger("click");
|
||||
}
|
||||
|
||||
if (hotkey.name === "escape") {
|
||||
@@ -106,8 +106,8 @@ export function show_flatpickr(element, callback, default_timestamp, options = {
|
||||
return true;
|
||||
});
|
||||
|
||||
container.on("click", ".flatpickr-confirm", () => {
|
||||
callback(flatpickr_input.val());
|
||||
$container.on("click", ".flatpickr-confirm", () => {
|
||||
callback($flatpickr_input.val());
|
||||
instance.close();
|
||||
instance.destroy();
|
||||
});
|
||||
|
||||
@@ -8,28 +8,28 @@ import * as timerender from "./timerender";
|
||||
|
||||
let is_floating_recipient_bar_showing = false;
|
||||
|
||||
function top_offset(elem) {
|
||||
function top_offset($elem) {
|
||||
return (
|
||||
elem.offset().top -
|
||||
$elem.offset().top -
|
||||
$("#message_view_header").safeOuterHeight() -
|
||||
$("#navbar_alerts_wrapper").height()
|
||||
);
|
||||
}
|
||||
|
||||
export function first_visible_message(bar) {
|
||||
export function first_visible_message($bar) {
|
||||
// The first truly visible message would be computed using the
|
||||
// bottom of the floating recipient bar; but we want the date from
|
||||
// the first visible message were the floating recipient bar not
|
||||
// displayed, which will always be the first messages whose bottom
|
||||
// overlaps the floating recipient bar's space (since you ).
|
||||
|
||||
const messages = bar.children(".message_row");
|
||||
const frb = $("#floating_recipient_bar");
|
||||
const frb_top = top_offset(frb);
|
||||
const frb_bottom = frb_top + frb.safeOuterHeight();
|
||||
let result;
|
||||
const $messages = $bar.children(".message_row");
|
||||
const $frb = $("#floating_recipient_bar");
|
||||
const frb_top = top_offset($frb);
|
||||
const frb_bottom = frb_top + $frb.safeOuterHeight();
|
||||
let $result;
|
||||
|
||||
for (const message_element of messages) {
|
||||
for (const message_element of $messages) {
|
||||
// The details of this comparison function are sensitive, since we're
|
||||
// balancing between three possible bugs:
|
||||
//
|
||||
@@ -56,40 +56,40 @@ export function first_visible_message(bar) {
|
||||
// message_viewport.scrollTop() to set precise scrolling
|
||||
// positions determines the value for date_bar_height_offset.
|
||||
|
||||
let message = $(message_element);
|
||||
const message_bottom = top_offset(message) + message.safeOuterHeight();
|
||||
let $message = $(message_element);
|
||||
const message_bottom = top_offset($message) + $message.safeOuterHeight();
|
||||
const date_bar_height_offset = 10;
|
||||
|
||||
if (message_bottom > frb_top) {
|
||||
result = message;
|
||||
$result = $message;
|
||||
}
|
||||
|
||||
// Important: This will break if we ever have things that are
|
||||
// not message rows inside a recipient_row block.
|
||||
message = message.next(".message_row");
|
||||
$message = $message.next(".message_row");
|
||||
if (
|
||||
message.length > 0 &&
|
||||
result &&
|
||||
$message.length > 0 &&
|
||||
$result &&
|
||||
// Before returning a result, we check whether the next
|
||||
// message's top is actually below the bottom of the
|
||||
// floating recipient bar; this is different from the
|
||||
// bottom of our current message because there may be a
|
||||
// between-messages date separator row in between.
|
||||
top_offset(message) < frb_bottom - date_bar_height_offset
|
||||
top_offset($message) < frb_bottom - date_bar_height_offset
|
||||
) {
|
||||
result = message;
|
||||
$result = $message;
|
||||
}
|
||||
if (result) {
|
||||
return result;
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// If none of the messages are visible, just take the last message.
|
||||
return messages.last();
|
||||
return $messages.last();
|
||||
}
|
||||
|
||||
export function get_date(elem) {
|
||||
const message_row = first_visible_message(elem);
|
||||
export function get_date($elem) {
|
||||
const message_row = first_visible_message($elem);
|
||||
|
||||
if (!message_row || !message_row.length) {
|
||||
return undefined;
|
||||
@@ -123,39 +123,39 @@ export function relevant_recipient_bars() {
|
||||
// not exactly where we want. The value we get
|
||||
// may be be too far up in the feed, but we can
|
||||
// deal with that later.
|
||||
let first_elem = candidate_recipient_bar();
|
||||
let $first_elem = candidate_recipient_bar();
|
||||
|
||||
if (!first_elem) {
|
||||
first_elem = $(".focused_table").find(".recipient_row").first();
|
||||
if (!$first_elem) {
|
||||
$first_elem = $(".focused_table").find(".recipient_row").first();
|
||||
}
|
||||
|
||||
if (first_elem.length === 0) {
|
||||
if ($first_elem.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
elems.push(first_elem);
|
||||
elems.push($first_elem);
|
||||
|
||||
const max_offset = top_offset($("#compose"));
|
||||
let header_height = first_elem.find(".message_header").safeOuterHeight();
|
||||
let header_height = $first_elem.find(".message_header").safeOuterHeight();
|
||||
|
||||
// It's okay to overestimate header_height a bit, as we don't
|
||||
// really need an FRB for a section that barely shows.
|
||||
header_height += 10;
|
||||
|
||||
function next(elem) {
|
||||
elem = elem.next();
|
||||
while (elem.length !== 0 && !elem.hasClass("recipient_row")) {
|
||||
elem = elem.next();
|
||||
function next($elem) {
|
||||
$elem = $elem.next();
|
||||
while ($elem.length !== 0 && !$elem.hasClass("recipient_row")) {
|
||||
$elem = $elem.next();
|
||||
}
|
||||
return elem;
|
||||
return $elem;
|
||||
}
|
||||
|
||||
// Now start the forward traversal of recipient bars.
|
||||
// We'll stop when we go below the fold.
|
||||
let elem = next(first_elem);
|
||||
let $elem = next($first_elem);
|
||||
|
||||
while (elem.length) {
|
||||
if (top_offset(elem) < header_height) {
|
||||
while ($elem.length) {
|
||||
if (top_offset($elem) < header_height) {
|
||||
// If we are close to the top, then the prior
|
||||
// elements we found are no longer relevant,
|
||||
// because either the selected item we started
|
||||
@@ -165,15 +165,15 @@ export function relevant_recipient_bars() {
|
||||
elems = [];
|
||||
}
|
||||
|
||||
if (top_offset(elem) > max_offset) {
|
||||
if (top_offset($elem) > max_offset) {
|
||||
// Out of sight, out of mind!
|
||||
// (The element is below the fold, so we stop the
|
||||
// traversal.)
|
||||
break;
|
||||
}
|
||||
|
||||
elems.push(elem);
|
||||
elem = next(elem);
|
||||
elems.push($elem);
|
||||
$elem = next($elem);
|
||||
}
|
||||
|
||||
if (elems.length === 0) {
|
||||
@@ -181,25 +181,25 @@ export function relevant_recipient_bars() {
|
||||
return [];
|
||||
}
|
||||
|
||||
const items = elems.map((elem, i) => {
|
||||
const items = elems.map(($elem, i) => {
|
||||
let date_html;
|
||||
let need_frb;
|
||||
|
||||
if (i === 0) {
|
||||
date_html = get_date(elem);
|
||||
need_frb = top_offset(elem) < 0;
|
||||
date_html = get_date($elem);
|
||||
need_frb = top_offset($elem) < 0;
|
||||
} else {
|
||||
date_html = elem.find(".recipient_row_date").html();
|
||||
date_html = $elem.find(".recipient_row_date").html();
|
||||
need_frb = false;
|
||||
}
|
||||
|
||||
const date_text = $(date_html).text();
|
||||
|
||||
// Add title here to facilitate troubleshooting.
|
||||
const title = elem.find(".message_label_clickable").last().attr("title");
|
||||
const title = $elem.find(".message_label_clickable").last().attr("title");
|
||||
|
||||
const item = {
|
||||
elem,
|
||||
$elem,
|
||||
title,
|
||||
date_html,
|
||||
date_text,
|
||||
@@ -236,25 +236,25 @@ export function candidate_recipient_bar() {
|
||||
// bars that is still above the fold.
|
||||
|
||||
// Start with the pointer's current location.
|
||||
const selected_row = message_lists.current.selected_row();
|
||||
const $selected_row = message_lists.current.selected_row();
|
||||
|
||||
if (selected_row === undefined || selected_row.length === 0) {
|
||||
if ($selected_row === undefined || $selected_row.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let candidate = rows.get_message_recipient_row(selected_row);
|
||||
if (candidate === undefined) {
|
||||
let $candidate = rows.get_message_recipient_row($selected_row);
|
||||
if ($candidate === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
while (candidate.length) {
|
||||
if (candidate.hasClass("recipient_row") && top_offset(candidate) < 0) {
|
||||
return candidate;
|
||||
while ($candidate.length) {
|
||||
if ($candidate.hasClass("recipient_row") && top_offset($candidate) < 0) {
|
||||
return $candidate;
|
||||
}
|
||||
// We cannot use .prev(".recipient_row") here, because that
|
||||
// returns nothing if the previous element is not a recipient
|
||||
// row, rather than finding the first recipient_row.
|
||||
candidate = candidate.prev();
|
||||
$candidate = $candidate.prev();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -267,31 +267,31 @@ function show_floating_recipient_bar() {
|
||||
}
|
||||
}
|
||||
|
||||
let old_source;
|
||||
let $old_source;
|
||||
function replace_floating_recipient_bar(source_info) {
|
||||
const source_recipient_bar = source_info.elem;
|
||||
const $source_recipient_bar = source_info.$elem;
|
||||
|
||||
let new_label;
|
||||
let other_label;
|
||||
let header;
|
||||
let $new_label;
|
||||
let $other_label;
|
||||
let $header;
|
||||
|
||||
if (source_recipient_bar !== old_source) {
|
||||
if (source_recipient_bar.children(".message_header_stream").length !== 0) {
|
||||
new_label = $("#current_label_stream");
|
||||
other_label = $("#current_label_private_message");
|
||||
header = source_recipient_bar.children(".message_header_stream");
|
||||
if ($source_recipient_bar !== $old_source) {
|
||||
if ($source_recipient_bar.children(".message_header_stream").length !== 0) {
|
||||
$new_label = $("#current_label_stream");
|
||||
$other_label = $("#current_label_private_message");
|
||||
$header = $source_recipient_bar.children(".message_header_stream");
|
||||
} else {
|
||||
new_label = $("#current_label_private_message");
|
||||
other_label = $("#current_label_stream");
|
||||
header = source_recipient_bar.children(".message_header_private_message");
|
||||
$new_label = $("#current_label_private_message");
|
||||
$other_label = $("#current_label_stream");
|
||||
$header = $source_recipient_bar.children(".message_header_private_message");
|
||||
}
|
||||
new_label.find(".message_header").replaceWith(header.clone());
|
||||
other_label.css("display", "none");
|
||||
new_label.css("display", "block");
|
||||
new_label.attr("zid", rows.id(rows.first_message_in_group(source_recipient_bar)));
|
||||
$new_label.find(".message_header").replaceWith($header.clone());
|
||||
$other_label.css("display", "none");
|
||||
$new_label.css("display", "block");
|
||||
$new_label.attr("zid", rows.id(rows.first_message_in_group($source_recipient_bar)));
|
||||
|
||||
new_label.toggleClass("message-fade", source_recipient_bar.hasClass("message-fade"));
|
||||
old_source = source_recipient_bar;
|
||||
$new_label.toggleClass("message-fade", $source_recipient_bar.hasClass("message-fade"));
|
||||
$old_source = $source_recipient_bar;
|
||||
}
|
||||
|
||||
const rendered_date = source_info.date_html || "";
|
||||
@@ -310,7 +310,7 @@ export function hide() {
|
||||
|
||||
export function de_clutter_dates(items) {
|
||||
for (const item of items) {
|
||||
item.elem.find(".recipient_row_date").toggle(item.show_date);
|
||||
item.$elem.find(".recipient_row_date").toggle(item.show_date);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,11 +90,11 @@ the selector and then calls browser_history.go_to_location.
|
||||
const scroll_positions = new Map();
|
||||
|
||||
export function update_org_settings_menu_item() {
|
||||
const item = $(".admin-menu-item").expectOne();
|
||||
const $item = $(".admin-menu-item").expectOne();
|
||||
if (page_params.is_admin) {
|
||||
item.find("span").text($t({defaultMessage: "Manage organization"}));
|
||||
$item.find("span").text($t({defaultMessage: "Manage organization"}));
|
||||
} else {
|
||||
item.find("span").text($t({defaultMessage: "Organization settings"}));
|
||||
$item.find("span").text($t({defaultMessage: "Organization settings"}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ import * as ui_util from "./ui_util";
|
||||
let giphy_fetch;
|
||||
let search_term = "";
|
||||
let gifs_grid;
|
||||
let active_popover_element;
|
||||
let $active_popover_element;
|
||||
|
||||
// Only used if popover called from edit message, otherwise it is `undefined`.
|
||||
let edit_message_id;
|
||||
|
||||
export function is_popped_from_edit_messsage() {
|
||||
return active_popover_element && edit_message_id !== undefined;
|
||||
return $active_popover_element && edit_message_id !== undefined;
|
||||
}
|
||||
|
||||
export function focus_current_edit_message() {
|
||||
@@ -102,16 +102,16 @@ async function renderGIPHYGrid(targetEl) {
|
||||
// GIF; nice in principle but too distracting.
|
||||
hideAttribution: true,
|
||||
onGifClick: (props) => {
|
||||
let textarea = $("#compose-textarea");
|
||||
let $textarea = $("#compose-textarea");
|
||||
if (edit_message_id !== undefined) {
|
||||
textarea = $(
|
||||
$textarea = $(
|
||||
`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`,
|
||||
);
|
||||
}
|
||||
|
||||
compose_ui.insert_syntax_and_focus(
|
||||
`[](${props.images.downsized_medium.url})`,
|
||||
textarea,
|
||||
$textarea,
|
||||
);
|
||||
hide_giphy_popover();
|
||||
},
|
||||
@@ -146,11 +146,11 @@ async function update_grid_with_search_term() {
|
||||
return;
|
||||
}
|
||||
|
||||
const search_elem = $("#giphy-search-query");
|
||||
const $search_elem = $("#giphy-search-query");
|
||||
// GIPHY popover may have been hidden by the
|
||||
// time this function is called.
|
||||
if (search_elem.length) {
|
||||
search_term = search_elem[0].value;
|
||||
if ($search_elem.length) {
|
||||
search_term = $search_elem[0].value;
|
||||
gifs_grid.remove();
|
||||
gifs_grid = await renderGIPHYGrid($("#giphy_grid_in_popover .giphy-content")[0]);
|
||||
return;
|
||||
@@ -162,15 +162,15 @@ async function update_grid_with_search_term() {
|
||||
|
||||
export function hide_giphy_popover() {
|
||||
// Returns `true` if the popover was open.
|
||||
if (active_popover_element) {
|
||||
if ($active_popover_element) {
|
||||
// We need to destroy the popover because when
|
||||
// we hide it, bootstrap popover
|
||||
// library removes `giphy-content` element
|
||||
// as part of cleaning up everything inside
|
||||
// `popover-content`, so we need to reinitialize
|
||||
// the popover by destroying it.
|
||||
active_popover_element.popover("destroy");
|
||||
active_popover_element = undefined;
|
||||
$active_popover_element.popover("destroy");
|
||||
$active_popover_element = undefined;
|
||||
edit_message_id = undefined;
|
||||
gifs_grid = undefined;
|
||||
return true;
|
||||
@@ -188,7 +188,7 @@ function get_popover_content() {
|
||||
|
||||
function get_popover_placement() {
|
||||
let placement = popovers.compute_placement(
|
||||
active_popover_element,
|
||||
$active_popover_element,
|
||||
APPROX_HEIGHT,
|
||||
APPROX_WIDTH,
|
||||
true,
|
||||
@@ -221,7 +221,7 @@ export function initialize() {
|
||||
e.stopPropagation();
|
||||
|
||||
const compose_click_target = compose_ui.get_compose_click_target(e);
|
||||
if (active_popover_element && active_popover_element.get()[0] === compose_click_target) {
|
||||
if ($active_popover_element && $active_popover_element.get()[0] === compose_click_target) {
|
||||
// Hide giphy popover if already active.
|
||||
hide_giphy_popover();
|
||||
return;
|
||||
@@ -237,8 +237,8 @@ export function initialize() {
|
||||
edit_message_id = undefined;
|
||||
}
|
||||
|
||||
active_popover_element = $elt;
|
||||
active_popover_element.popover({
|
||||
$active_popover_element = $elt;
|
||||
$active_popover_element.popover({
|
||||
animation: true,
|
||||
placement: get_popover_placement(),
|
||||
html: true,
|
||||
@@ -250,7 +250,7 @@ export function initialize() {
|
||||
content: " ",
|
||||
});
|
||||
|
||||
active_popover_element.popover("show");
|
||||
$active_popover_element.popover("show");
|
||||
// It takes about 1s for the popover to show; So,
|
||||
// we wait for popover to display before rendering GIFs
|
||||
// in it, otherwise popover is rendered with empty content.
|
||||
|
||||
@@ -476,20 +476,20 @@ export function process_tab_key() {
|
||||
// TODO: See if browsers like Safari can now handle tabbing correctly
|
||||
// without our intervention.
|
||||
|
||||
let message_edit_form;
|
||||
let $message_edit_form;
|
||||
|
||||
const focused_message_edit_content = $(".message_edit_content:focus");
|
||||
if (focused_message_edit_content.length > 0) {
|
||||
message_edit_form = focused_message_edit_content.closest(".message_edit_form");
|
||||
const $focused_message_edit_content = $(".message_edit_content:focus");
|
||||
if ($focused_message_edit_content.length > 0) {
|
||||
$message_edit_form = $focused_message_edit_content.closest(".message_edit_form");
|
||||
// Open message edit forms either have a save button or a close button, but not both.
|
||||
message_edit_form.find(".message_edit_save,.message_edit_close").trigger("focus");
|
||||
$message_edit_form.find(".message_edit_save,.message_edit_close").trigger("focus");
|
||||
return true;
|
||||
}
|
||||
|
||||
const focused_message_edit_save = $(".message_edit_save:focus");
|
||||
if (focused_message_edit_save.length > 0) {
|
||||
message_edit_form = focused_message_edit_save.closest(".message_edit_form");
|
||||
message_edit_form.find(".message_edit_cancel").trigger("focus");
|
||||
const $focused_message_edit_save = $(".message_edit_save:focus");
|
||||
if ($focused_message_edit_save.length > 0) {
|
||||
$message_edit_form = $focused_message_edit_save.closest(".message_edit_form");
|
||||
$message_edit_form.find(".message_edit_cancel").trigger("focus");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -519,9 +519,9 @@ export function process_shift_tab_key() {
|
||||
}
|
||||
|
||||
// Shift-Tabbing from the edit message save button takes you to the content.
|
||||
const focused_message_edit_save = $(".message_edit_save:focus");
|
||||
if (focused_message_edit_save.length > 0) {
|
||||
focused_message_edit_save
|
||||
const $focused_message_edit_save = $(".message_edit_save:focus");
|
||||
if ($focused_message_edit_save.length > 0) {
|
||||
$focused_message_edit_save
|
||||
.closest(".message_edit_form")
|
||||
.find(".message_edit_content")
|
||||
.trigger("focus");
|
||||
@@ -925,8 +925,8 @@ export function process_hotkey(e, hotkey) {
|
||||
compose_actions.quote_and_reply({trigger: "hotkey"});
|
||||
return true;
|
||||
case "edit_message": {
|
||||
const row = message_lists.current.get_row(msg.id);
|
||||
message_edit.start(row);
|
||||
const $row = message_lists.current.get_row(msg.id);
|
||||
message_edit.start($row);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,30 +69,30 @@ export function post_hotspot_as_read(hotspot_name) {
|
||||
}
|
||||
|
||||
function place_icon(hotspot) {
|
||||
const element = $(hotspot.location.element);
|
||||
const icon = $(`#hotspot_${CSS.escape(hotspot.name)}_icon`);
|
||||
const $element = $(hotspot.location.element);
|
||||
const $icon = $(`#hotspot_${CSS.escape(hotspot.name)}_icon`);
|
||||
|
||||
if (
|
||||
element.length === 0 ||
|
||||
element.css("display") === "none" ||
|
||||
!element.is(":visible") ||
|
||||
element.is(":hidden")
|
||||
$element.length === 0 ||
|
||||
$element.css("display") === "none" ||
|
||||
!$element.is(":visible") ||
|
||||
$element.is(":hidden")
|
||||
) {
|
||||
icon.css("display", "none");
|
||||
$icon.css("display", "none");
|
||||
return false;
|
||||
}
|
||||
|
||||
const offset = {
|
||||
top: element.outerHeight() * hotspot.location.offset_y,
|
||||
left: element.outerWidth() * hotspot.location.offset_x,
|
||||
top: $element.outerHeight() * hotspot.location.offset_y,
|
||||
left: $element.outerWidth() * hotspot.location.offset_x,
|
||||
};
|
||||
const client_rect = element.get(0).getBoundingClientRect();
|
||||
const client_rect = $element.get(0).getBoundingClientRect();
|
||||
const placement = {
|
||||
top: client_rect.top + offset.top,
|
||||
left: client_rect.left + offset.left,
|
||||
};
|
||||
icon.css("display", "block");
|
||||
icon.css(placement);
|
||||
$icon.css("display", "block");
|
||||
$icon.css(placement);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -189,19 +189,19 @@ export function set_up_toggler() {
|
||||
};
|
||||
|
||||
toggler = components.toggle(opts);
|
||||
const elem = toggler.get();
|
||||
elem.addClass("large allow-overflow");
|
||||
const $elem = toggler.get();
|
||||
$elem.addClass("large allow-overflow");
|
||||
|
||||
const modals = opts.values.map((item) => {
|
||||
const key = item.key; // e.g. message-formatting
|
||||
const modal = $(`#${CSS.escape(key)}`).find(".modal-body");
|
||||
return modal;
|
||||
const $modal = $(`#${CSS.escape(key)}`).find(".modal-body");
|
||||
return $modal;
|
||||
});
|
||||
|
||||
for (const modal of modals) {
|
||||
ui.get_scroll_element(modal).prop("tabindex", 0);
|
||||
for (const $modal of modals) {
|
||||
ui.get_scroll_element($modal).prop("tabindex", 0);
|
||||
keydown_util.handle({
|
||||
elem: modal,
|
||||
$elem: $modal,
|
||||
handlers: {
|
||||
ArrowLeft: toggler.maybe_go_left,
|
||||
ArrowRight: toggler.maybe_go_right,
|
||||
@@ -209,7 +209,7 @@ export function set_up_toggler() {
|
||||
});
|
||||
}
|
||||
|
||||
$(".informational-overlays .overlay-tabs").append(elem);
|
||||
$(".informational-overlays .overlay-tabs").append($elem);
|
||||
|
||||
$("#go-to-default-view-hotkey-help").toggleClass(
|
||||
"notdisplayed",
|
||||
@@ -224,12 +224,12 @@ export function show(target) {
|
||||
set_up_toggler();
|
||||
}
|
||||
|
||||
const overlay = $(".informational-overlays");
|
||||
const $overlay = $(".informational-overlays");
|
||||
|
||||
if (!overlay.hasClass("show")) {
|
||||
if (!$overlay.hasClass("show")) {
|
||||
overlays.open_overlay({
|
||||
name: "informationalOverlays",
|
||||
overlay,
|
||||
$overlay,
|
||||
on_close() {
|
||||
browser_history.exit_overlay();
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ export function random_id() {
|
||||
}
|
||||
|
||||
export function create(opts) {
|
||||
if (!opts.container) {
|
||||
if (!opts.$container) {
|
||||
blueslip.error("Pill needs container.");
|
||||
return undefined;
|
||||
}
|
||||
@@ -34,8 +34,8 @@ export function create(opts) {
|
||||
const store = {
|
||||
pills: [],
|
||||
pill_config: opts.pill_config,
|
||||
$parent: opts.container,
|
||||
$input: opts.container.find(".input").expectOne(),
|
||||
$parent: opts.$container,
|
||||
$input: opts.$container.find(".input").expectOne(),
|
||||
create_item_from_text: opts.create_item_from_text,
|
||||
get_text_from_item: opts.get_text_from_item,
|
||||
};
|
||||
|
||||
@@ -71,9 +71,9 @@ function beforeSend() {
|
||||
}
|
||||
|
||||
function submit_invitation_form() {
|
||||
const invite_status = $("#invite_status");
|
||||
const invitee_emails = $("#invitee_emails");
|
||||
const invitee_emails_group = invitee_emails.closest(".control-group");
|
||||
const $invite_status = $("#invite_status");
|
||||
const $invitee_emails = $("#invitee_emails");
|
||||
const $invitee_emails_group = $invitee_emails.closest(".control-group");
|
||||
const data = get_common_invitation_data();
|
||||
data.invitee_emails = $("#invitee_emails").val();
|
||||
|
||||
@@ -84,10 +84,10 @@ function submit_invitation_form() {
|
||||
success() {
|
||||
ui_report.success(
|
||||
$t_html({defaultMessage: "User(s) invited successfully."}),
|
||||
invite_status,
|
||||
$invite_status,
|
||||
);
|
||||
invitee_emails_group.removeClass("warning");
|
||||
invitee_emails.val("");
|
||||
$invitee_emails_group.removeClass("warning");
|
||||
$invitee_emails.val("");
|
||||
|
||||
if (page_params.development_environment) {
|
||||
const rendered_email_msg = render_settings_dev_env_email_access();
|
||||
@@ -98,7 +98,7 @@ function submit_invitation_form() {
|
||||
const arr = JSON.parse(xhr.responseText);
|
||||
if (arr.errors === undefined) {
|
||||
// There was a fatal error, no partial processing occurred.
|
||||
ui_report.error("", xhr, invite_status);
|
||||
ui_report.error("", xhr, $invite_status);
|
||||
} else {
|
||||
// Some users were not invited.
|
||||
const invitee_emails_errored = [];
|
||||
@@ -122,11 +122,11 @@ function submit_invitation_form() {
|
||||
has_billing_access: page_params.is_owner || page_params.is_billing_admin,
|
||||
daily_limit_reached: arr.daily_limit_reached,
|
||||
});
|
||||
ui_report.message(error_response, invite_status, "alert-warning");
|
||||
invitee_emails_group.addClass("warning");
|
||||
ui_report.message(error_response, $invite_status, "alert-warning");
|
||||
$invitee_emails_group.addClass("warning");
|
||||
|
||||
if (arr.sent_invitations) {
|
||||
invitee_emails.val(invitee_emails_errored.join("\n"));
|
||||
$invitee_emails.val(invitee_emails_errored.join("\n"));
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -140,7 +140,7 @@ function submit_invitation_form() {
|
||||
}
|
||||
|
||||
function generate_multiuse_invite() {
|
||||
const invite_status = $("#multiuse_invite_status");
|
||||
const $invite_status = $("#multiuse_invite_status");
|
||||
const data = get_common_invitation_data();
|
||||
channel.post({
|
||||
url: "/json/invites/multiuse",
|
||||
@@ -148,11 +148,11 @@ function generate_multiuse_invite() {
|
||||
beforeSend,
|
||||
success(data) {
|
||||
const copy_link_html = copy_invite_link(data);
|
||||
ui_report.success(copy_link_html, invite_status);
|
||||
ui_report.success(copy_link_html, $invite_status);
|
||||
new ClipboardJS("#copy_generated_invite_link");
|
||||
},
|
||||
error(xhr) {
|
||||
ui_report.error("", xhr, invite_status);
|
||||
ui_report.error("", xhr, $invite_status);
|
||||
},
|
||||
complete() {
|
||||
$("#submit-invitation").text($t({defaultMessage: "Generate invite link"}));
|
||||
@@ -187,7 +187,7 @@ export function launch() {
|
||||
|
||||
overlays.open_overlay({
|
||||
name: "invite",
|
||||
overlay: $("#invite-user"),
|
||||
$overlay: $("#invite-user"),
|
||||
on_close() {
|
||||
browser_history.exit_overlay();
|
||||
},
|
||||
|
||||
@@ -8,12 +8,12 @@ export const vim_up = "k";
|
||||
export const vim_right = "l";
|
||||
|
||||
export function handle(opts: {
|
||||
elem: JQuery;
|
||||
$elem: JQuery;
|
||||
handlers: {
|
||||
[handler: string]: (() => boolean) | undefined;
|
||||
};
|
||||
}): void {
|
||||
opts.elem.on("keydown", (e) => {
|
||||
opts.$elem.on("keydown", (e) => {
|
||||
if (e.altKey || e.ctrlKey || e.shiftKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -183,12 +183,12 @@ export function render_lightbox_list_images(preview_source) {
|
||||
const src = img.getAttribute("src");
|
||||
const className = preview_source === src ? "image selected" : "image";
|
||||
|
||||
const node = $("<div></div>", {
|
||||
const $node = $("<div></div>", {
|
||||
class: className,
|
||||
"data-src": src,
|
||||
}).css({backgroundImage: "url(" + src + ")"});
|
||||
|
||||
$image_list.append(node);
|
||||
$image_list.append($node);
|
||||
|
||||
// We parse the data for each image to show in the list,
|
||||
// while we still have its original DOM element handy, so
|
||||
@@ -205,10 +205,10 @@ function display_image(payload) {
|
||||
$(".player-container").hide();
|
||||
$(".image-preview, .image-actions, .image-description, .download, .lightbox-zoom-reset").show();
|
||||
|
||||
const img_container = $("#lightbox_overlay .image-preview > .zoom-element");
|
||||
const $img_container = $("#lightbox_overlay .image-preview > .zoom-element");
|
||||
const img = new Image();
|
||||
img.src = payload.source;
|
||||
img_container.html(img).show();
|
||||
$img_container.html(img).show();
|
||||
|
||||
$(".image-description .title")
|
||||
.text(payload.title || "N/A")
|
||||
@@ -244,16 +244,16 @@ function display_video(payload) {
|
||||
break;
|
||||
}
|
||||
|
||||
const iframe = $("<iframe></iframe>");
|
||||
iframe.attr(
|
||||
const $iframe = $("<iframe></iframe>");
|
||||
$iframe.attr(
|
||||
"sandbox",
|
||||
"allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts",
|
||||
);
|
||||
iframe.attr("src", source);
|
||||
iframe.attr("frameborder", 0);
|
||||
iframe.attr("allowfullscreen", true);
|
||||
$iframe.attr("src", source);
|
||||
$iframe.attr("frameborder", 0);
|
||||
$iframe.attr("allowfullscreen", true);
|
||||
|
||||
$("#lightbox_overlay .player-container").html(iframe).show();
|
||||
$("#lightbox_overlay .player-container").html($iframe).show();
|
||||
$(".image-actions .open").attr("href", payload.url);
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ export function build_open_image_function(on_close) {
|
||||
|
||||
overlays.open_overlay({
|
||||
name: "lightbox",
|
||||
overlay: $("#lightbox_overlay"),
|
||||
$overlay: $("#lightbox_overlay"),
|
||||
on_close,
|
||||
});
|
||||
|
||||
@@ -359,11 +359,11 @@ export function show_from_selected_message() {
|
||||
// retrieve the metadata from the DOM and store into the asset_map.
|
||||
export function parse_image_data(image) {
|
||||
const $image = $(image);
|
||||
const $preview_src = $image.attr("src");
|
||||
const preview_src = $image.attr("src");
|
||||
|
||||
if (asset_map.has($preview_src)) {
|
||||
if (asset_map.has(preview_src)) {
|
||||
// check if image's data is already present in asset_map.
|
||||
return asset_map.get($preview_src);
|
||||
return asset_map.get(preview_src);
|
||||
}
|
||||
|
||||
// if wrapped in the .youtube-video class, it will be length = 1, and therefore
|
||||
@@ -376,24 +376,24 @@ export function parse_image_data(image) {
|
||||
const is_compose_preview_image = $image.closest("#compose .preview_content").length === 1;
|
||||
|
||||
const $parent = $image.parent();
|
||||
let $type;
|
||||
let $source;
|
||||
const $url = $parent.attr("href");
|
||||
let type;
|
||||
let source;
|
||||
const url = $parent.attr("href");
|
||||
if (is_youtube_video) {
|
||||
$type = "youtube-video";
|
||||
$source = $parent.attr("data-id");
|
||||
type = "youtube-video";
|
||||
source = $parent.attr("data-id");
|
||||
} else if (is_vimeo_video) {
|
||||
$type = "vimeo-video";
|
||||
$source = $parent.attr("data-id");
|
||||
type = "vimeo-video";
|
||||
source = $parent.attr("data-id");
|
||||
} else if (is_embed_video) {
|
||||
$type = "embed-video";
|
||||
$source = $parent.attr("data-id");
|
||||
type = "embed-video";
|
||||
source = $parent.attr("data-id");
|
||||
} else {
|
||||
$type = "image";
|
||||
type = "image";
|
||||
if ($image.attr("data-src-fullsize")) {
|
||||
$source = $image.attr("data-src-fullsize");
|
||||
source = $image.attr("data-src-fullsize");
|
||||
} else {
|
||||
$source = $preview_src;
|
||||
source = preview_src;
|
||||
}
|
||||
}
|
||||
let sender_full_name;
|
||||
@@ -412,13 +412,13 @@ export function parse_image_data(image) {
|
||||
const payload = {
|
||||
user: sender_full_name,
|
||||
title: $parent.attr("title"),
|
||||
type: $type,
|
||||
preview: $preview_src,
|
||||
source: $source,
|
||||
url: $url,
|
||||
type,
|
||||
preview: preview_src,
|
||||
source,
|
||||
url,
|
||||
};
|
||||
|
||||
asset_map.set($preview_src, payload);
|
||||
asset_map.set(preview_src, payload);
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user