web: Move web app to ‘web’ directory.

Ever since we started bundling the app with webpack, there’s been less
and less overlap between our ‘static’ directory (files belonging to
the frontend app) and Django’s interpretation of the ‘static’
directory (files served directly to the web).

Split the app out to its own ‘web’ directory outside of ‘static’, and
remove all the custom collectstatic --ignore rules.  This makes it
much clearer what’s actually being served to the web, and what’s being
bundled by webpack.  It also shrinks the release tarball by 3%.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2023-02-22 14:03:47 -08:00
parent be0098146c
commit c1675913a2
866 changed files with 978 additions and 993 deletions

77
web/src/ui_util.ts Normal file
View File

@@ -0,0 +1,77 @@
import $ from "jquery";
import * as keydown_util from "./keydown_util";
// Add functions to this that have no non-trivial
// dependencies other than jQuery.
// https://stackoverflow.com/questions/4233265/contenteditable-set-caret-at-the-end-of-the-text-cross-browser
export function place_caret_at_end(el: HTMLElement): void {
el.focus();
const range = document.createRange();
range.selectNodeContents(el);
range.collapse(false);
const sel = window.getSelection();
sel?.removeAllRanges();
sel?.addRange(range);
}
export function blur_active_element(): void {
// this blurs anything that may perhaps be actively focused on.
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
}
export function convert_enter_to_click(e: JQuery.KeyDownEvent): void {
if (keydown_util.is_enter_event(e)) {
e.preventDefault();
e.stopPropagation();
$(e.currentTarget).trigger("click");
}
}
export function update_unread_count_in_dom($unread_count_elem: JQuery, count: number): void {
// This function is used to update unread count in top left corner
// elements.
const $unread_count_span = $unread_count_elem.find(".unread_count");
if (count === 0) {
$unread_count_span.hide();
$unread_count_span.text("");
return;
}
$unread_count_span.show();
$unread_count_span.text(count);
}
export function update_unread_mention_info_in_dom(
$unread_mention_info_elem: JQuery,
stream_has_any_unread_mention_messages: Boolean,
): void {
const $unread_mention_info_span = $unread_mention_info_elem.find(".unread_mention_info");
if (!stream_has_any_unread_mention_messages) {
$unread_mention_info_span.hide();
$unread_mention_info_span.text("");
return;
}
$unread_mention_info_span.show();
$unread_mention_info_span.text("@");
}
/**
* Parse HTML and return a DocumentFragment.
*
* Like any consumer of HTML, this function must only be given input
* from trusted producers of safe HTML, such as auto-escaping
* templates; violating this expectation will introduce bugs that are
* likely to be security vulnerabilities.
*/
export function parse_html(html: string): DocumentFragment {
const template = document.createElement("template");
template.innerHTML = html;
return template.content;
}