mirror of
https://github.com/zulip/zulip.git
synced 2025-11-23 07:52:35 +00:00
markdown: Allow setting a default language for code blocks.
This adds a new realm setting: default_code_block_language. This PR also adds a new widget to specify a language, which behaves somewhat differently from other widgets of the same kind; instead of exposing methods to the whole module, we just create a single IIFE that handles all the interactions with the DOM for the widget. We also move the code for remapping languages to format_code function since we want to preserve the original language to decide if we override it using default_code_clock_language. Fixes #14404.
This commit is contained in:
committed by
Tim Abbott
parent
3f6541b306
commit
f9caf522f0
@@ -789,6 +789,8 @@ run_test('set_up', () => {
|
|||||||
|
|
||||||
const stub_render_notifications_stream_ui = settings_org.render_notifications_stream_ui;
|
const stub_render_notifications_stream_ui = settings_org.render_notifications_stream_ui;
|
||||||
settings_org.render_notifications_stream_ui = noop;
|
settings_org.render_notifications_stream_ui = noop;
|
||||||
|
const stub_language_render = settings_org.default_code_language_widget.render;
|
||||||
|
settings_org.default_code_language_widget.render = noop;
|
||||||
$("#id_realm_message_content_edit_limit_minutes").set_parent($.create('<stub edit limit parent>'));
|
$("#id_realm_message_content_edit_limit_minutes").set_parent($.create('<stub edit limit parent>'));
|
||||||
$("#id_realm_message_content_delete_limit_minutes").set_parent($.create('<stub delete limit parent>'));
|
$("#id_realm_message_content_delete_limit_minutes").set_parent($.create('<stub delete limit parent>'));
|
||||||
$("#message_content_in_email_notifications_label").set_parent($.create('<stub in-content setting checkbox>'));
|
$("#message_content_in_email_notifications_label").set_parent($.create('<stub in-content setting checkbox>'));
|
||||||
@@ -826,6 +828,7 @@ run_test('set_up', () => {
|
|||||||
test_discard_changes_button(discard_changes);
|
test_discard_changes_button(discard_changes);
|
||||||
|
|
||||||
settings_org.render_notifications_stream_ui = stub_render_notifications_stream_ui;
|
settings_org.render_notifications_stream_ui = stub_render_notifications_stream_ui;
|
||||||
|
settings_org.default_code_language_widget.render = stub_language_render;
|
||||||
});
|
});
|
||||||
|
|
||||||
run_test('test get_organization_settings_options', () => {
|
run_test('test get_organization_settings_options', () => {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const admin_settings_label = {
|
|||||||
realm_message_content_allowed_in_email_notifications:
|
realm_message_content_allowed_in_email_notifications:
|
||||||
i18n.t("Allow message content in missed message emails"),
|
i18n.t("Allow message content in missed message emails"),
|
||||||
realm_digest_emails_enabled: i18n.t("Send weekly digest emails to inactive users"),
|
realm_digest_emails_enabled: i18n.t("Send weekly digest emails to inactive users"),
|
||||||
|
realm_default_code_language: i18n.t("Default language for code blocks:"),
|
||||||
|
|
||||||
// Organization permissions
|
// Organization permissions
|
||||||
realm_name_changes_disabled: i18n.t("Prevent users from changing their name"),
|
realm_name_changes_disabled: i18n.t("Prevent users from changing their name"),
|
||||||
|
|||||||
@@ -3,11 +3,104 @@ const render_settings_admin_auth_methods_list = require('../templates/settings/a
|
|||||||
const render_settings_admin_realm_domains_list = require("../templates/settings/admin_realm_domains_list.hbs");
|
const render_settings_admin_realm_domains_list = require("../templates/settings/admin_realm_domains_list.hbs");
|
||||||
const render_settings_admin_realm_dropdown_stream_list = require("../templates/settings/admin_realm_dropdown_stream_list.hbs");
|
const render_settings_admin_realm_dropdown_stream_list = require("../templates/settings/admin_realm_dropdown_stream_list.hbs");
|
||||||
const render_settings_organization_settings_tip = require("../templates/settings/organization_settings_tip.hbs");
|
const render_settings_organization_settings_tip = require("../templates/settings/organization_settings_tip.hbs");
|
||||||
|
const pygments_data = require("../generated/pygments_data.json");
|
||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
loaded: false,
|
loaded: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.default_code_language_widget = (function (element_id) {
|
||||||
|
|
||||||
|
const render_language_list = require("../templates/settings/admin_realm_dropdown_code_languages_list.hbs");
|
||||||
|
const language_list = Object.keys(pygments_data.langs).map(x => {
|
||||||
|
return {
|
||||||
|
name: x,
|
||||||
|
priority: pygments_data.langs[x],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const setup = () => {
|
||||||
|
// populate the dropdown
|
||||||
|
const dropdown_list_body = $(`#${element_id} .dropdown-list-body`).expectOne();
|
||||||
|
const search_input = $(`#${element_id} .dropdown-search > input[type=text]`);
|
||||||
|
list_render.create(dropdown_list_body, language_list, {
|
||||||
|
name: "admin-realm-default-code-language-dropdown-list",
|
||||||
|
modifier: function (item) {
|
||||||
|
return render_language_list({ language: item });
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
element: search_input,
|
||||||
|
predicate: function (item, value) {
|
||||||
|
return item.name.toLowerCase().includes(value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).init();
|
||||||
|
$(`#${element_id} .dropdown-search`).click(function (e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(`#${element_id} .dropdown-toggle`).click(function () {
|
||||||
|
search_input.val("").trigger("input");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const render = (name) => {
|
||||||
|
$(`#${element_id} #id_realm_default_code_block_language`).data("language", name);
|
||||||
|
|
||||||
|
const elem = $(`#${element_id} #realm_default_code_block_language_name`);
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
elem.text(i18n.t("No language set"));
|
||||||
|
elem.addClass("text-warning");
|
||||||
|
elem.closest('.input-group').find('.default_code_block_language_unset').hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Happy path
|
||||||
|
elem.text(name);
|
||||||
|
elem.removeClass('text-warning');
|
||||||
|
elem.closest('.input-group').find('.default_code_block_language_unset').show();
|
||||||
|
};
|
||||||
|
|
||||||
|
const update = (lang, save_discard_widget_status_handler) => {
|
||||||
|
render(lang);
|
||||||
|
save_discard_widget_status_handler($('#org-other-settings'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const register_event_handlers = (save_discard_widget_status_handler) => {
|
||||||
|
$(`#${element_id} .dropdown-list-body`).on("click keypress", ".lang_name", function (e) {
|
||||||
|
const setting_elem = $(this).closest(".realm_default_code_block_language_setting");
|
||||||
|
if (e.type === "keypress") {
|
||||||
|
if (e.which === 13) {
|
||||||
|
setting_elem.find(".dropdown-menu").dropdown("toggle");
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const lang = $(this).attr('data-language');
|
||||||
|
update(lang, save_discard_widget_status_handler);
|
||||||
|
});
|
||||||
|
$(`#${element_id} .default_code_block_language_unset`).click(function () {
|
||||||
|
update(null, save_discard_widget_status_handler);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const value = () => {
|
||||||
|
let val = $(`#${element_id} #id_realm_default_code_block_language`).data('language');
|
||||||
|
if (val === null) {
|
||||||
|
val = '';
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
setup,
|
||||||
|
render,
|
||||||
|
register_event_handlers,
|
||||||
|
value,
|
||||||
|
};
|
||||||
|
}('realm_default_code_block_language_widget'));
|
||||||
|
|
||||||
exports.reset = function () {
|
exports.reset = function () {
|
||||||
meta.loaded = false;
|
meta.loaded = false;
|
||||||
};
|
};
|
||||||
@@ -431,6 +524,8 @@ function discard_property_element_changes(elem) {
|
|||||||
exports.render_notifications_stream_ui(property_value, "notifications");
|
exports.render_notifications_stream_ui(property_value, "notifications");
|
||||||
} else if (property_name === 'realm_signup_notifications_stream') {
|
} else if (property_name === 'realm_signup_notifications_stream') {
|
||||||
exports.render_notifications_stream_ui(property_value, "signup_notifications");
|
exports.render_notifications_stream_ui(property_value, "signup_notifications");
|
||||||
|
} else if (property_name === 'realm_default_code_block_language') {
|
||||||
|
exports.default_code_language_widget.render(property_value);
|
||||||
} else if (typeof property_value === 'boolean') {
|
} else if (typeof property_value === 'boolean') {
|
||||||
elem.prop('checked', property_value);
|
elem.prop('checked', property_value);
|
||||||
} else if (typeof property_value === 'string' || typeof property_value === 'number') {
|
} else if (typeof property_value === 'string' || typeof property_value === 'number') {
|
||||||
@@ -557,9 +652,11 @@ exports.build_page = function () {
|
|||||||
const streams = stream_data.get_streams_for_settings_page();
|
const streams = stream_data.get_streams_for_settings_page();
|
||||||
exports.populate_notifications_stream_dropdown(streams);
|
exports.populate_notifications_stream_dropdown(streams);
|
||||||
exports.populate_signup_notifications_stream_dropdown(streams);
|
exports.populate_signup_notifications_stream_dropdown(streams);
|
||||||
|
exports.default_code_language_widget.setup();
|
||||||
}
|
}
|
||||||
exports.render_notifications_stream_ui(page_params.realm_notifications_stream_id, 'notifications');
|
exports.render_notifications_stream_ui(page_params.realm_notifications_stream_id, 'notifications');
|
||||||
exports.render_notifications_stream_ui(page_params.realm_signup_notifications_stream_id, 'signup_notifications');
|
exports.render_notifications_stream_ui(page_params.realm_signup_notifications_stream_id, 'signup_notifications');
|
||||||
|
exports.default_code_language_widget.render(page_params.realm_default_code_block_language);
|
||||||
|
|
||||||
// Populate realm domains
|
// Populate realm domains
|
||||||
exports.populate_realm_domains(page_params.realm_domains);
|
exports.populate_realm_domains(page_params.realm_domains);
|
||||||
@@ -604,6 +701,8 @@ exports.build_page = function () {
|
|||||||
changed_val = parseInt($("#id_realm_notifications_stream").data('stream-id'), 10);
|
changed_val = parseInt($("#id_realm_notifications_stream").data('stream-id'), 10);
|
||||||
} else if (property_name === 'realm_signup_notifications_stream') {
|
} else if (property_name === 'realm_signup_notifications_stream') {
|
||||||
changed_val = parseInt($("#id_realm_signup_notifications_stream").data('stream-id'), 10);
|
changed_val = parseInt($("#id_realm_signup_notifications_stream").data('stream-id'), 10);
|
||||||
|
} else if (property_name === 'realm_default_code_block_language') {
|
||||||
|
changed_val = exports.default_code_language_widget.value();
|
||||||
} else if (typeof current_val === 'boolean') {
|
} else if (typeof current_val === 'boolean') {
|
||||||
changed_val = elem.prop('checked');
|
changed_val = elem.prop('checked');
|
||||||
} else if (typeof current_val === 'string') {
|
} else if (typeof current_val === 'string') {
|
||||||
@@ -727,6 +826,9 @@ exports.build_page = function () {
|
|||||||
new_message_retention_days = "";
|
new_message_retention_days = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const code_block_language_value = exports.default_code_language_widget.value();
|
||||||
|
data.default_code_block_language = JSON.stringify(code_block_language_value);
|
||||||
|
|
||||||
data.message_retention_days = new_message_retention_days !== "" ?
|
data.message_retention_days = new_message_retention_days !== "" ?
|
||||||
JSON.stringify(parseInt(new_message_retention_days, 10)) : null;
|
JSON.stringify(parseInt(new_message_retention_days, 10)) : null;
|
||||||
} else if (subsection === 'other_permissions') {
|
} else if (subsection === 'other_permissions') {
|
||||||
@@ -960,6 +1062,9 @@ exports.build_page = function () {
|
|||||||
save_discard_widget_status_handler($('#org-notifications'));
|
save_discard_widget_status_handler($('#org-notifications'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.default_code_language_widget.register_event_handlers(
|
||||||
|
save_discard_widget_status_handler);
|
||||||
|
|
||||||
$(".notifications-stream-setting .dropdown-list-body").on("click keypress", ".stream_name", function (e) {
|
$(".notifications-stream-setting .dropdown-list-body").on("click keypress", ".stream_name", function (e) {
|
||||||
const notifications_stream_setting_elem = $(this).closest(".notifications-stream-setting");
|
const notifications_stream_setting_elem = $(this).closest(".notifications-stream-setting");
|
||||||
if (e.type === "keypress") {
|
if (e.type === "keypress") {
|
||||||
|
|||||||
@@ -710,6 +710,7 @@ input[type=checkbox].inline-block {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#realm_default_code_block_language_widget button,
|
||||||
#realm_notifications_stream_label > button,
|
#realm_notifications_stream_label > button,
|
||||||
#realm_signup_notifications_stream_label > button {
|
#realm_signup_notifications_stream_label > button {
|
||||||
margin: 0px 5px;
|
margin: 0px 5px;
|
||||||
@@ -1614,11 +1615,13 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
|
|||||||
top: 5px;
|
top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#realm_default_code_block_language_widget .dropdown-search > input[type=text],
|
||||||
#id_realm_notifications_stream .dropdown-search > input[type=text],
|
#id_realm_notifications_stream .dropdown-search > input[type=text],
|
||||||
#id_realm_signup_notifications_stream .dropdown-search > input[type=text] {
|
#id_realm_signup_notifications_stream .dropdown-search > input[type=text] {
|
||||||
margin: 9px;
|
margin: 9px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#realm_default_code_block_language_widget .dropdown-list-body,
|
||||||
#id_realm_notifications_stream .dropdown-list-body,
|
#id_realm_notifications_stream .dropdown-list-body,
|
||||||
#id_realm_signup_notifications_stream .dropdown-list-body {
|
#id_realm_signup_notifications_stream .dropdown-list-body {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{{#with language}}
|
||||||
|
<li class="lang_name" role="presentation" data-language="{{name}}">
|
||||||
|
<a role="menuitem" tabindex="0">
|
||||||
|
{{name}}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{/with}}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
<div class="input-group" id="realm_default_code_block_language_widget">
|
||||||
|
<label for="realm_default_code_block_language" id="realm_default_code_block_language_label" class="inline-block">
|
||||||
|
{{ label }}
|
||||||
|
<span class="realm_default_code_block_language_setting dropup actual-dropdown-menu prop-element" id="id_realm_default_code_block_language"
|
||||||
|
name="realm_default_code_block_language" aria-labelledby="realm_default_code_block_language_label">
|
||||||
|
<button class="button small rounded dropdown-toggle" data-toggle="dropdown">
|
||||||
|
<span id="realm_default_code_block_language_name"></span>
|
||||||
|
<i class="fa fa-pencil"></i>
|
||||||
|
</button>
|
||||||
|
<ul class="dropdown-menu modal-bg" role="menu">
|
||||||
|
<li class="dropdown-search" role="presentation">
|
||||||
|
<input class="no-input-change-detection" type="text" role="menuitem" placeholder="{{t 'Filter languages' }}" autofocus/>
|
||||||
|
</li>
|
||||||
|
<span class="dropdown-list-body" data-simplebar></span>
|
||||||
|
</ul>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
{{#if is_admin }}
|
||||||
|
<a class="default_code_block_language_unset" id="default_code_block_language_unset">{{t "[Unset]" }}</a>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
@@ -192,6 +192,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{> default_code_language_settings_widget
|
||||||
|
label=admin_settings_label.realm_default_code_language }}
|
||||||
|
|
||||||
{{> settings_checkbox
|
{{> settings_checkbox
|
||||||
setting_name="realm_message_content_allowed_in_email_notifications"
|
setting_name="realm_message_content_allowed_in_email_notifications"
|
||||||
prefix="id_"
|
prefix="id_"
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ Import your existing organization from [Slack](/help/import-from-slack),
|
|||||||
syntax highlighting, makes it easy to discuss code, paste an error message,
|
syntax highlighting, makes it easy to discuss code, paste an error message,
|
||||||
or explain a complicated point. Full LaTeX support as well.
|
or explain a complicated point. Full LaTeX support as well.
|
||||||
|
|
||||||
|
If your community primarily uses a single programming language,
|
||||||
|
consider setting a default language for syntax highlighting.
|
||||||
|
|
||||||
### Permalink to conversations.
|
### Permalink to conversations.
|
||||||
|
|
||||||
Zulip makes it easy to get a [permanent link to a
|
Zulip makes it easy to get a [permanent link to a
|
||||||
|
|||||||
@@ -111,6 +111,10 @@ typeahead will pop up when you start typing after the ` ``` `. If you can't
|
|||||||
find your language, search for it [here](https://pygments.org/docs/lexers/)
|
find your language, search for it [here](https://pygments.org/docs/lexers/)
|
||||||
and try the **short names** listed for the lexers for your language.
|
and try the **short names** listed for the lexers for your language.
|
||||||
|
|
||||||
|
Organization administrators can also configure a default syntax
|
||||||
|
highlighting language. In this configuration, one can use ````text`
|
||||||
|
to display content without any syntax highlighting.
|
||||||
|
|
||||||
## Latex
|
## Latex
|
||||||
~~~
|
~~~
|
||||||
Inline: $$O(n^2)$$
|
Inline: $$O(n^2)$$
|
||||||
|
|||||||
@@ -177,8 +177,6 @@ def check_for_new_fence(processor: Any, output: MutableSequence[str], line: str,
|
|||||||
fence = m.group('fence')
|
fence = m.group('fence')
|
||||||
lang = m.group('lang')
|
lang = m.group('lang')
|
||||||
|
|
||||||
lang = remap_language(lang)
|
|
||||||
|
|
||||||
handler = generic_handler(processor, output, fence, lang, run_content_validators)
|
handler = generic_handler(processor, output, fence, lang, run_content_validators)
|
||||||
processor.push(handler)
|
processor.push(handler)
|
||||||
else:
|
else:
|
||||||
@@ -315,6 +313,12 @@ class FencedBlockPreprocessor(markdown.preprocessors.Preprocessor):
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
def format_code(self, lang: str, text: str) -> str:
|
def format_code(self, lang: str, text: str) -> str:
|
||||||
|
if not lang:
|
||||||
|
try:
|
||||||
|
lang = self.md.zulip_realm.default_code_block_language
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
lang = remap_language(lang)
|
||||||
if lang:
|
if lang:
|
||||||
langclass = LANG_TAG % (lang,)
|
langclass = LANG_TAG % (lang,)
|
||||||
else:
|
else:
|
||||||
|
|||||||
18
zerver/migrations/0272_realm_default_code_block_language.py
Normal file
18
zerver/migrations/0272_realm_default_code_block_language.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 2.2.10 on 2020-03-31 00:21
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('zerver', '0271_huddle_set_recipient_column_values'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='realm',
|
||||||
|
name='default_code_block_language',
|
||||||
|
field=models.TextField(default=None, null=True),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -320,6 +320,8 @@ class Realm(models.Model):
|
|||||||
zoom_api_key = models.TextField(default="")
|
zoom_api_key = models.TextField(default="")
|
||||||
zoom_api_secret = models.TextField(default="")
|
zoom_api_secret = models.TextField(default="")
|
||||||
|
|
||||||
|
default_code_block_language = models.TextField(null=True, default=None) # type: Optional[str]
|
||||||
|
|
||||||
# Define the types of the various automatically managed properties
|
# Define the types of the various automatically managed properties
|
||||||
property_types = dict(
|
property_types = dict(
|
||||||
add_emoji_by_admins_only=bool,
|
add_emoji_by_admins_only=bool,
|
||||||
@@ -356,6 +358,7 @@ class Realm(models.Model):
|
|||||||
digest_weekday=int,
|
digest_weekday=int,
|
||||||
private_message_policy=int,
|
private_message_policy=int,
|
||||||
user_group_edit_policy=int,
|
user_group_edit_policy=int,
|
||||||
|
default_code_block_language=(str, type(None)),
|
||||||
) # type: Dict[str, Union[type, Tuple[type, ...]]]
|
) # type: Dict[str, Union[type, Tuple[type, ...]]]
|
||||||
|
|
||||||
DIGEST_WEEKDAY_VALUES = [0, 1, 2, 3, 4, 5, 6]
|
DIGEST_WEEKDAY_VALUES = [0, 1, 2, 3, 4, 5, 6]
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from zerver.lib.actions import (
|
|||||||
do_set_user_display_setting,
|
do_set_user_display_setting,
|
||||||
do_remove_realm_emoji,
|
do_remove_realm_emoji,
|
||||||
do_set_alert_words,
|
do_set_alert_words,
|
||||||
|
do_set_realm_property,
|
||||||
)
|
)
|
||||||
from zerver.lib.alert_words import get_alert_word_automaton
|
from zerver.lib.alert_words import get_alert_word_automaton
|
||||||
from zerver.lib.create_user import create_user
|
from zerver.lib.create_user import create_user
|
||||||
@@ -120,7 +121,7 @@ class FencedBlockPreprocessorTest(TestCase):
|
|||||||
'weirdchar()',
|
'weirdchar()',
|
||||||
'```',
|
'```',
|
||||||
'',
|
'',
|
||||||
'``` none',
|
'```',
|
||||||
'no-highlight()',
|
'no-highlight()',
|
||||||
'```',
|
'```',
|
||||||
''
|
''
|
||||||
@@ -1342,6 +1343,34 @@ class BugdownTest(ZulipTestCase):
|
|||||||
# Only hamlet has alert-word 'issue124' present in the message content
|
# Only hamlet has alert-word 'issue124' present in the message content
|
||||||
self.assertEqual(msg.user_ids_with_alert_words, expected_user_ids)
|
self.assertEqual(msg.user_ids_with_alert_words, expected_user_ids)
|
||||||
|
|
||||||
|
def test_default_code_block_language(self) -> None:
|
||||||
|
realm = get_realm('zulip')
|
||||||
|
self.assertEqual(realm.default_code_block_language, None)
|
||||||
|
text = "```{}\nconsole.log('Hello World');\n```\n"
|
||||||
|
|
||||||
|
# Render without default language
|
||||||
|
msg_with_js_before = bugdown_convert(text.format('js'))
|
||||||
|
msg_with_python_before = bugdown_convert(text.format('python'))
|
||||||
|
msg_without_language_before = bugdown_convert(text.format(''))
|
||||||
|
|
||||||
|
# Render with default=javascript
|
||||||
|
do_set_realm_property(realm, 'default_code_block_language', 'javascript')
|
||||||
|
msg_without_language_after = bugdown_convert(text.format(''))
|
||||||
|
msg_with_python_after = bugdown_convert(text.format('python'))
|
||||||
|
|
||||||
|
# Render with default=python
|
||||||
|
do_set_realm_property(realm, 'default_code_block_language', 'python')
|
||||||
|
msg_without_language_later = bugdown_convert(text.format(''))
|
||||||
|
msg_with_none_later = bugdown_convert(text.format('none'))
|
||||||
|
|
||||||
|
# Render without default language
|
||||||
|
do_set_realm_property(realm, 'default_code_block_language', None)
|
||||||
|
msg_without_language_final = bugdown_convert(text.format(''))
|
||||||
|
|
||||||
|
self.assertTrue(msg_with_js_before == msg_without_language_after)
|
||||||
|
self.assertTrue(msg_with_python_before == msg_with_python_after == msg_without_language_later)
|
||||||
|
self.assertTrue(msg_without_language_before == msg_with_none_later == msg_without_language_final)
|
||||||
|
|
||||||
def test_mention_wildcard(self) -> None:
|
def test_mention_wildcard(self) -> None:
|
||||||
user_profile = self.example_user('othello')
|
user_profile = self.example_user('othello')
|
||||||
msg = Message(sender=user_profile, sending_client=get_client("test"))
|
msg = Message(sender=user_profile, sending_client=get_client("test"))
|
||||||
|
|||||||
@@ -1626,7 +1626,8 @@ class EventsRegisterTest(ZulipTestCase):
|
|||||||
google_hangouts_domain=[u"zulip.com", u"zulip.org"],
|
google_hangouts_domain=[u"zulip.com", u"zulip.org"],
|
||||||
zoom_api_secret=[u"abc", u"xyz"],
|
zoom_api_secret=[u"abc", u"xyz"],
|
||||||
zoom_api_key=[u"abc", u"xyz"],
|
zoom_api_key=[u"abc", u"xyz"],
|
||||||
zoom_user_id=[u"example@example.com", u"example@example.org"]
|
zoom_user_id=[u"example@example.com", u"example@example.org"],
|
||||||
|
default_code_block_language=[u'python', u'javascript']
|
||||||
) # type: Dict[str, Any]
|
) # type: Dict[str, Any]
|
||||||
|
|
||||||
vals = test_values.get(name)
|
vals = test_values.get(name)
|
||||||
@@ -1636,6 +1637,8 @@ class EventsRegisterTest(ZulipTestCase):
|
|||||||
vals = bool_tests
|
vals = bool_tests
|
||||||
elif property_type is str:
|
elif property_type is str:
|
||||||
validator = check_string
|
validator = check_string
|
||||||
|
elif property_type == (str, type(None)):
|
||||||
|
validator = check_string
|
||||||
elif property_type is int:
|
elif property_type is int:
|
||||||
validator = check_int
|
validator = check_int
|
||||||
elif property_type == (int, type(None)):
|
elif property_type == (int, type(None)):
|
||||||
|
|||||||
@@ -134,6 +134,7 @@ class HomeTest(ZulipTestCase):
|
|||||||
"realm_bot_domain",
|
"realm_bot_domain",
|
||||||
"realm_bots",
|
"realm_bots",
|
||||||
"realm_create_stream_policy",
|
"realm_create_stream_policy",
|
||||||
|
"realm_default_code_block_language",
|
||||||
"realm_default_external_accounts",
|
"realm_default_external_accounts",
|
||||||
"realm_default_language",
|
"realm_default_language",
|
||||||
"realm_default_stream_groups",
|
"realm_default_stream_groups",
|
||||||
|
|||||||
@@ -710,6 +710,7 @@ class RealmAPITest(ZulipTestCase):
|
|||||||
bool_tests = [False, True] # type: List[bool]
|
bool_tests = [False, True] # type: List[bool]
|
||||||
test_values = dict(
|
test_values = dict(
|
||||||
default_language=[u'de', u'en'],
|
default_language=[u'de', u'en'],
|
||||||
|
default_code_block_language=[u'javascript', u''],
|
||||||
description=[u'Realm description', u'New description'],
|
description=[u'Realm description', u'New description'],
|
||||||
digest_weekday=[0, 1, 2],
|
digest_weekday=[0, 1, 2],
|
||||||
message_retention_days=[10, 20],
|
message_retention_days=[10, 20],
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ def update_realm(
|
|||||||
zoom_user_id: Optional[str]=REQ(validator=check_string, default=None),
|
zoom_user_id: Optional[str]=REQ(validator=check_string, default=None),
|
||||||
zoom_api_key: Optional[str]=REQ(validator=check_string, default=None),
|
zoom_api_key: Optional[str]=REQ(validator=check_string, default=None),
|
||||||
zoom_api_secret: Optional[str]=REQ(validator=check_string, default=None),
|
zoom_api_secret: Optional[str]=REQ(validator=check_string, default=None),
|
||||||
|
default_code_block_language: Optional[str]=REQ(validator=check_string, default=None),
|
||||||
digest_weekday: Optional[int]=REQ(validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None),
|
digest_weekday: Optional[int]=REQ(validator=check_int_in(Realm.DIGEST_WEEKDAY_VALUES), default=None),
|
||||||
) -> HttpResponse:
|
) -> HttpResponse:
|
||||||
realm = user_profile.realm
|
realm = user_profile.realm
|
||||||
@@ -196,6 +197,13 @@ def update_realm(
|
|||||||
signup_notifications_stream_id)
|
signup_notifications_stream_id)
|
||||||
data['signup_notifications_stream_id'] = signup_notifications_stream_id
|
data['signup_notifications_stream_id'] = signup_notifications_stream_id
|
||||||
|
|
||||||
|
if default_code_block_language is not None:
|
||||||
|
# Migrate '', used in the API to encode the default/None behavior of this feature.
|
||||||
|
if default_code_block_language == '':
|
||||||
|
data['default_code_block_language'] = None
|
||||||
|
else:
|
||||||
|
data['default_code_block_language'] = default_code_block_language
|
||||||
|
|
||||||
return json_success(data)
|
return json_success(data)
|
||||||
|
|
||||||
@require_realm_admin
|
@require_realm_admin
|
||||||
|
|||||||
Reference in New Issue
Block a user