Skip to content

Commit 650209e

Browse files
committed
Clean: No longer need to explicitly call page_init() on the Client.
Improve docs. Wrap test.
1 parent d0331f4 commit 650209e

File tree

8 files changed

+77
-68
lines changed

8 files changed

+77
-68
lines changed

client/src/CodeChatEditor-test.mts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import "mocha/mocha.js";
2929
import "mocha/mocha.css";
3030
import { EditorView } from "@codemirror/view";
3131
import { ChangeSpec, EditorState, EditorSelection } from "@codemirror/state";
32-
import { exportedForTesting, page_init } from "./CodeChatEditor.mjs";
32+
import { exportedForTesting } from "./CodeChatEditor.mjs";
3333
import { CodeMirror, CodeMirrorDocBlockTuple } from "./shared_types.mjs";
3434
import {
3535
DocBlockPlugin,
@@ -40,7 +40,9 @@ import {
4040
// Otherwise, including [CodeChatEditor.mts](CodeChatEditor.mts) elsewhere would
4141
// double-define everything (producing complaints about two attempts to define
4242
// each web component).
43-
export { page_init };
43+
//
44+
// Nothing needed at present.
45+
//
4446
// Provide convenient access to all functions tested here.
4547
const { codechat_html_to_markdown } = exportedForTesting;
4648

client/src/CodeChatEditor.mts

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -171,42 +171,12 @@ turndownService.use(gfm);
171171

172172
// Page initialization
173173
// -------------------
174-
//
175-
// Load the dynamic content into the static page.
176-
export const page_init = () => {
177-
on_dom_content_loaded(async () => {
178-
// Intercept links in this document to save before following the link.
179-
/// @ts-ignore
180-
navigation.addEventListener("navigate", on_navigate);
181-
const ccb = document.getElementById("CodeChat-sidebar") as
182-
| HTMLIFrameElement
183-
| undefined;
184-
/// @ts-ignore
185-
ccb?.contentWindow?.navigation.addEventListener(
186-
"navigate",
187-
on_navigate,
188-
);
189-
document.addEventListener("click", on_click);
190-
// Provide basic error reporting for uncaught errors.
191-
window.addEventListener("unhandledrejection", on_error);
192-
window.addEventListener("error", on_error);
193-
194-
window.CodeChatEditor = {
195-
open_lp,
196-
on_save,
197-
scroll_to_line,
198-
show_toast,
199-
allow_navigation: false,
200-
};
201-
});
202-
};
203-
204174
export const set_is_dirty = (value: boolean = true) => {
205175
is_dirty = value;
206176
};
207177

208-
// This is copied
209-
// from[MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event#checking_whether_loading_is_already_complete).
178+
// This is copied from
179+
// [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event#checking_whether_loading_is_already_complete).
210180
export const on_dom_content_loaded = (on_load_func: () => void) => {
211181
if (document.readyState === "loading") {
212182
// Loading hasn't finished yet.
@@ -586,6 +556,32 @@ export const on_error = (event: Event) => {
586556
console.error(event);
587557
};
588558

559+
// Load the dynamic content into the static page. Place this last, since we need
560+
// functions above defined before assigning them to the `CodeChatEditor`
561+
// namespace.
562+
on_dom_content_loaded(async () => {
563+
// Intercept links in this document to save before following the link.
564+
/// @ts-ignore
565+
navigation.addEventListener("navigate", on_navigate);
566+
const ccb = document.getElementById("CodeChat-sidebar") as
567+
| HTMLIFrameElement
568+
| undefined;
569+
/// @ts-ignore
570+
ccb?.contentWindow?.navigation.addEventListener("navigate", on_navigate);
571+
document.addEventListener("click", on_click);
572+
// Provide basic error reporting for uncaught errors.
573+
window.addEventListener("unhandledrejection", on_error);
574+
window.addEventListener("error", on_error);
575+
576+
window.CodeChatEditor = {
577+
open_lp,
578+
on_save,
579+
scroll_to_line,
580+
show_toast,
581+
allow_navigation: false,
582+
};
583+
});
584+
589585
// Testing
590586
// -------
591587
//

client/src/CodeChatEditorFramework.mts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@
2626
// Imports
2727
// -------
2828
//
29-
// ### JavaScript/TypeScript
30-
//
31-
// #### Third-party
29+
// ### Third-party
3230
import ReconnectingWebSocket from "./third-party/ReconnectingWebSocket.cjs";
3331
import { show_toast as show_toast_core } from "./show_toast.mjs";
3432

35-
// #### Local
33+
// ### Local
3634
import { assert } from "./assert.mjs";
3735
import {
3836
CodeChatForWeb,
@@ -91,7 +89,7 @@ class WebSocketComm {
9189

9290
// A promise to serialize calls to and from the Client. This is important: a
9391
// `CurrentFile` requires the Client to save, then switch to a new web page.
94-
// If an `Update` comes in, it should be applied after the `CurrentFile` is
92+
// If an `Update` comes in, it should be applied after the `CurrentFile` has
9593
// finished executing.
9694
promise = Promise.resolve();
9795

@@ -123,7 +121,7 @@ class WebSocketComm {
123121
// Handle websocket messages.
124122
this.ws.onmessage = (event: MessageEvent) => {
125123
// Parse the received message, which must be a single element of a
126-
// dictionary representing a `JointMessage`.
124+
// dictionary representing an `EditorMessage`.
127125
const joint_message = JSON.parse(event.data) as EditorMessage;
128126
const { id, message } = joint_message;
129127
console_log(
@@ -160,10 +158,11 @@ class WebSocketComm {
160158
if (contents !== undefined) {
161159
// I'd prefer to use a system-maintained value to
162160
// determine the ready state of the iframe, such as
163-
// `readyState`. However, this value only applies to
164-
// the initial load of the iframe; it doesn't change
165-
// when the iframe's `src` attribute is changed. So,
166-
// we have to track this manually instead.
161+
// [readyState](https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState).
162+
// However, this value only applies to the initial
163+
// load of the iframe; it doesn't change when the
164+
// iframe's `src` attribute is changed. So, we have
165+
// to track this manually instead.
167166
if (!this.is_loading) {
168167
// Wait until after the DOM is ready, since we
169168
// rely on content set in
@@ -297,6 +296,8 @@ class WebSocketComm {
297296
callback: () => void = () => 0,
298297
) => {
299298
const id = this.ws_id;
299+
// The Client gets every third ID -- the IDE gets another third, while
300+
// the Server gets the final third.
300301
this.ws_id += 3;
301302
// Add in the current filename to the message, if it's an `Update`.
302303
if (typeof message == "object" && "Update" in message) {
@@ -321,6 +322,9 @@ class WebSocketComm {
321322

322323
// This is called by the Client when the user navigates to another webpage.
323324
current_file = (url: URL) => {
325+
// TODO: should we delay execution of user navigation until all previous
326+
// actions have finished, or ignore them and immediately perform the
327+
// user navigation?
324328
this.promise = this.promise.finally(() => {
325329
if (url.host === window.location.host) {
326330
// If this points to the Server, then tell the IDE to load a new

docs/design.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,27 @@ These form a set of high-level requirements to guide the project.
2626
* View source code as <a id="vision-code-blocks-and-doc-blocks"></a>[code
2727
blocks and doc blocks](index.md#code-blocks-and-doc-blocks). Doc blocks are
2828
lines of source which contain only correctly-formatted comments.
29+
2930
* Provide support for a <a id="vision-programming-language-support"></a>[wide
3031
variety of programming languages](index.md#programming-language-support).
32+
3133
* Provide integration with a <a id="vision-ide-integration"></a>[wide variety
3234
of IDEs/text editors](index.md#ide-integration).
33-
* Load a document from source code, allow edits in a GUI, then save it
34-
back to source code.
35+
36+
* Load a document from source code, allow edits in a GUI, then save it back to
37+
source code.
38+
3539
* Provide word processor GUI tools (insert hyperlink, images, headings,
3640
change font, etc.) for doc blocks.
3741
* Provide text editor/IDE tools (syntax highlighting, line numbers, show
3842
linter feedback) for code blocks.
3943
* Zero build: eliminate the traditional project build process -- make it
4044
almost instantaneous.
45+
4146
* Doc block markup should be readable and well-known: markdown.
47+
4248
* Support both a single-file mode and a project mode.
49+
4350
* A project is a specific directory tree, identified by the presence of a
4451
TOC. A TOC is just a plain Markdown file with a specific name. A better
4552
term: not a TOC, but a navigation pane, since the TOC can contain
@@ -50,8 +57,9 @@ These form a set of high-level requirements to guide the project.
5057
* Numbering comes from the current page's location within the TOC.
5158
Pages not in the TOC aren't numbered.
5259
* <a id="authoring-support"></a>Provide [authoring
53-
support](index.md#authoring-support), which allows authors to easily
54-
create book/project-like features. In particular:
60+
support](index.md#authoring-support), which allows authors to easily create
61+
book/project-like features. In particular:
62+
5563
* Counters for numbering figures, tables, equations, etc. All counters are
5664
page-local (no global counters).
5765
* Auto-titled links: the link text is automatically derived from the
@@ -108,9 +116,9 @@ These form a set of high-level requirements to guide the project.
108116
all anchors to be globally unique. HTML allows upper/lowercase ASCII
109117
plus the hyphen and underscore for IDs, meaning that a 5-character
110118
string provides >250 million unique anchors.
111-
112119
* Make picking a file/anchor easy: provide a searchable, expanded TOC listing
113120
every anchor.
121+
114122
* Provide edit and view options. (Rely on an IDE to edit raw source.)
115123

116124
### Nice to have features

docs/style_guide.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,12 @@ double accurate_g(
183183
// Properly configuring the text editor used with the CodeChat Editor
184184
// significantly improves the authoring process. Recommended settings:
185185
//
186-
// * Enable word wrap:
187-
// [vscode](https://learn.microsoft.com/en-us/visualstudio/ide/reference/how-to-manage-word-wrap-in-the-editor?view=vs-2022)
188-
// * Use spaces, not tabs​, for indentation:
189-
// [vscode](https://code.visualstudio.com/docs/editor/codebasics#_indentation)
190-
// * Enable auto-save:
191-
// [vscode](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save)
186+
// * Enable word wrap: [vscode](https://learn.microsoft.com/en-us/visualstudio/ide/reference/how-to-manage-word-wrap-in-the-editor?view=vs-2022)
187+
// * Use spaces, not tabs​, for indentation: [vscode](https://code.visualstudio.com/docs/editor/codebasics#_indentation)
188+
// * Enable auto-save: [vscode](https://code.visualstudio.com/docs/editor/codebasics#_save-auto-save)
192189
// * Auto-reload enabled​: default in vscode
193-
// * On save, remove trailing whitespace​:
194-
// [vscode](https://stackoverflow.com/a/53663494/16038919)
195-
// * Use a spell checker:
196-
// [vscode](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
190+
// * On save, remove trailing whitespace​: [vscode](https://stackoverflow.com/a/53663494/16038919)
191+
// * Use a spell checker: [vscode](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
197192
// * On a big monitor, place your IDE side by side with the CodeChat Editor.
198193
//
199194
// Common problems

server/src/lexer/pest/parser_design.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ In particular, a language-specific grammar must provide:
1818
inline_comment | block_comment }`. However, languages which lack an inline
1919
comment (such as CSS) or a block comment (such as Python) would contain only
2020
the appropriate comment type.
21+
2122
* Inline comment definitions:
23+
2224
* Opening inline delimiter(s) supported by the language. Three inline
2325
comment delimiters must be defined for a language. For C, this is:
2426

server/src/translation.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ pub async fn translation_task(
415415

416416
// Leave space for a server message during the init phase.
417417
let mut id: f64 = INITIAL_MESSAGE_ID + MESSAGE_ID_INCREMENT;
418-
// The source code, provided by the IDE. It will use whatever the IDE provides for EOLs, which is stored in `eol` below.
418+
// The source code, provided by the IDE. It will use whatever
419+
// the IDE provides for EOLs, which is stored in `eol` below.
419420
let mut source_code = String::new();
420421
let mut code_mirror_doc = String::new();
421422
// The initial state will be overwritten by the first `Update`
@@ -547,7 +548,8 @@ pub async fn translation_task(
547548
SimpleHttpResponse::Err(SimpleHttpResponseError::Io(err)),
548549
None,
549550
),
550-
// There's no file, so return empty contents, which will be ignored.
551+
// There's no file, so return empty
552+
// contents, which will be ignored.
551553
"".to_string()
552554
),
553555
Ok(mut fc) => {
@@ -560,7 +562,8 @@ pub async fn translation_task(
560562
use_pdf_js,
561563
)
562564
.await,
563-
// If the file is binary, return empty contents, which will be ignored.
565+
// If the file is binary, return empty
566+
// contents, which will be ignored.
564567
option_file_contents.unwrap_or("".to_string())
565568
)
566569
}
@@ -837,7 +840,8 @@ pub async fn translation_task(
837840
&cfw)
838841
{
839842
Ok(new_source_code) => {
840-
// Correct EOL endings for use with the IDE.
843+
// Correct EOL endings for use with the
844+
// IDE.
841845
let new_source_code_eol = eol_convert(new_source_code, &eol);
842846
let ccfw = if sync_state == SyncState::InSync && allow_source_diffs {
843847
Some(CodeChatForWeb {

server/src/webserver.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,8 @@ pub async fn file_to_response(
750750
{
751751
if is_current_file || is_toc {
752752
source_to_codechat_for_web_string(
753-
// Ensure we work with Unix-style (LF only) files, since other line endings break the translation process.
753+
// Ensure we work with Unix-style (LF only) files, since other
754+
// line endings break the translation process.
754755
&file_contents_text.replace("\r\n", "\n"),
755756
file_path,
756757
is_toc,
@@ -896,10 +897,7 @@ pub async fn file_to_response(
896897
<meta name="viewport" content="width=device-width, initial-scale=1">
897898
<title>{name} - The CodeChat Editor</title>
898899
{MATHJAX_TAGS}
899-
<script type="module">
900-
import {{ page_init }} from "/{codechat_editor_js}"
901-
page_init()
902-
</script>
900+
<script type="module">import "/{codechat_editor_js}"</script>
903901
<link rel="stylesheet" href="/{codehat_editor_css}">
904902
{sidebar_css}
905903
</head>

0 commit comments

Comments
 (0)