Advanced TypeScript Programming Projects
上QQ阅读APP看书,第一时间看更新

Bringing it all together

The last class that we are going to write is used to take the text that the user is typing in and split it into individual lines, and create our ParseElement, chain-of-responsibility handlers, and MarkdownDocument instance. Each line is then forwarded to Header1ChainHandler to start the processing of the line. Finally, we get the text from the document and return it so that we can display it in the label:

class Markdown {
public ToHtml(text : string) : string {
let document : IMarkdownDocument = new MarkdownDocument();
let header1 : Header1ChainHandler = new ChainOfResponsibilityFactory().Build(document);
let lines : string[] = text.split(`\n`);
for (let index = 0; index < lines.length; index++) {
let parseElement : ParseElement = new ParseElement();
parseElement.CurrentLine = lines[index];
header1.HandleRequest(parseElement);
}
return document.Get();
}
}

Now that we can generate our HTML content, we have one change left to do. We are going to revisit the HtmlHandler method and change it so that it calls our ToHtml markdown method. At the same time, we are going to address an issue with our original implementation where refreshing the page loses our content until we press a key. To handle this, we are going to add a window.onload event handler:

class HtmlHandler {
private markdownChange : Markdown = new Markdown;
public TextChangeHandler(id : string, output : string) : void {
let markdown = <HTMLTextAreaElement>document.getElementById(id);
let markdownOutput = <HTMLLabelElement>document.getElementById(output);

if (markdown !== null) {
markdown.onkeyup = (e) => {
this.RenderHtmlContent(markdown, markdownOutput);
}
window.onload = (e) => {
this.RenderHtmlContent(markdown, markdownOutput);
}
}
}

private RenderHtmlContent(markdown: HTMLTextAreaElement, markdownOutput: HTMLLabelElement) {
if (markdown.value) {
markdownOutput.innerHTML = this.markdownChange.ToHtml(markdown.value);
}
else
markdownOutput.innerHTML = "<p></p>";
}
}

Now, when we run our application, it displays the rendered HTML content, even when we refresh our page. We have successfully created a simple markdown editor that satisfies the points that we laid out in our requirements, gathering stage.

I cannot stress enough how important the requirements, gathering stage is. All too often, poor requirements lead to us having to make assumptions about the behavior of an application. These assumptions can lead to delivering an application that users do not want. If you find yourself making an assumption, go back and ask your users exactly what they want. As we built our code here, we referred back to our requirements to make sure that we were building exactly what we were meant to build.

A final point about requirements—they change. It is common for requirements to evolve or get removed while we are writing an application. When they do change, we make sure that the requirements are updated, that we are making no assumptions, and that we check the work that has already been produced to make sure that it matches the updated requirements. This is what we do because we are professionals.