This repository has been archived by the owner on Jul 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 39
/
CommentField.ts
159 lines (136 loc) · 8.13 KB
/
CommentField.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/// <reference path="index.ts" />
/**
* Namespace for All AlienTube operations.
* @namespace AlienTube
*/
module AlienTube {
/**
* The representation and management of an AlienTube loading screen.
* @class CommentField
* @param commentSection The active CommentSection to retrieve data from.
* @param insertionPoint The DOM element in which the loading screen should be appended to as a child.
* @param [initialState] An optional initial state for the loading screen, the default is "Loading"
*/
"use strict";
export class CommentField {
private representedHTMLElement: HTMLDivElement;
private parentHTMLElement: HTMLDivElement;
private commentThread: CommentThread;
private parentClass: any;
private previewElement: HTMLDivElement;
private edit: boolean;
constructor(parent: any, initialText?: string, edit?: boolean) {
/* Check if the paramter is a Coment Thread and assign the correct parent HTML element .*/
if (parent instanceof CommentThread) {
this.parentClass = <CommentThread> parent;
this.commentThread = this.parentClass;
this.parentHTMLElement = this.parentClass.threadContainer.querySelector(".options");
/* Check if the parameter is a Comment and assign the correct parent HTML element.*/
} else if (parent instanceof Comment) {
this.parentClass = <Comment> parent;
this.commentThread = this.parentClass.commentThread;
this.parentHTMLElement = this.parentClass.representedHTMLElement.querySelector(".options");
} else {
new TypeError("parent needs to be type CommentThread or Type Comment");
}
this.edit = edit;
let template = Application.getExtensionTemplateItem(this.commentThread.commentSection.template, "commentfield");
this.representedHTMLElement = <HTMLDivElement> template.querySelector(".at_commentfield");
/* Set the "You are now commenting as" text under the comment field. */
let authorName = <HTMLSpanElement> this.representedHTMLElement.querySelector(".at_writingauthor");
authorName.textContent = Application.localisationManager.get("commentfield_label_author", [Preferences.getString("username")]);
/* Set the button text and event listener for the submit button */
let submitButton = <HTMLButtonElement> this.representedHTMLElement.querySelector(".at_submit");
submitButton.textContent = Application.localisationManager.get("commentfield_button_submit");
submitButton.addEventListener("click", this.onSubmitButtonClick.bind(this), false);
/* Set the button text and event listener for the cancel button */
let cancelButton = <HTMLButtonElement> this.representedHTMLElement.querySelector(".at_cancel");
cancelButton.textContent = Application.localisationManager.get("commentfield_button_cancel")
cancelButton.addEventListener("click", this.onCancelButtonClick.bind(this), false);
/* Set the text for the markdown preview header */
let previewHeader = <HTMLSpanElement> this.representedHTMLElement.querySelector(".at_preview_header");
previewHeader.textContent = Application.localisationManager.get("commentfield_label_preview");
/* Check if we were initialised with some text (most likely from the show source button) and add event listener for input
change */
let inputField = <HTMLInputElement> this.representedHTMLElement.querySelector(".at_textarea");
if (initialText) {
inputField.value = initialText;
}
inputField.addEventListener("input", this.onInputFieldChange.bind(this), false);
this.previewElement = <HTMLDivElement> this.representedHTMLElement.querySelector(".at_comment_preview");
this.parentHTMLElement.appendChild(this.representedHTMLElement);
}
/**
* Get the HTML element of the comment field.
*/
get HTMLElement() {
return this.representedHTMLElement;
}
/**
* Handle the click of the submit button of the comment field.
* @param eventObject The event object of the click of the submit button.
* @private
*/
private onSubmitButtonClick(eventObject: Event) {
/* Disable the button on click so the user does not accidentally press it multiple times */
let submitButton = <HTMLButtonElement> eventObject.target;
submitButton.disabled = true;
let inputField = <HTMLInputElement> this.representedHTMLElement.querySelector(".at_textarea");
let thing_id = (this.parentClass instanceof CommentThread)
? this.parentClass.threadInformation.name : this.parentClass.commentObject.name;
if (this.edit) {
/* Send the edit comment request to reddit */
new AlienTube.Reddit.EditCommentRequest(thing_id, inputField.value, function (responseText) {
this.parentClass.commentObject.body = inputField.value;
let editedCommentBody = this.parentClass.representedHTMLElement.querySelector(".at_commentcontent");
editedCommentBody.innerHTML = SnuOwnd.getParser().render(inputField.value);
this.parentClass.representedHTMLElement.classList.add("edited");
/* The comment box is no longer needed, remove it and clear outselves out of memory */
this.representedHTMLElement.parentNode.removeChild(this.representedHTMLElement);
});
} else {
/* Send the comment to Reddit */
new AlienTube.Reddit.CommentRequest(thing_id, inputField.value, function (responseText) {
let responseObject = JSON.parse(responseText);
let comment = new Comment(responseObject.json.data.things[0].data, this.commentThread);
this.parentClass.children.push(comment);
/* Find the correct insert location and append the new comment to DOM */
if (this.parentClass instanceof CommentThread) {
this.parentClass.threadContainer.appendChild(comment.representedHTMLElement);
new CommentField(this.parentClass);
} else {
this.parentClass.representedHTMLElement.querySelector(".at_replies").appendChild(comment.representedHTMLElement);
}
this.parentClass.children.push(comment);
/* Scroll the new comment in to view */
comment.representedHTMLElement.scrollIntoView(false);
/* The comment box is no longer needed, remove it and clear outselves out of memory */
this.representedHTMLElement.parentNode.removeChild(this.representedHTMLElement);
});
}
}
/**
* Cancel / Remove the comment field.
* @private
*/
private onCancelButtonClick() {
this.representedHTMLElement.parentNode.removeChild(this.representedHTMLElement);
}
/**
* Handle the contents of the comment field changing.
* @param eventObject The event object of the input field change.
* @private
*/
private onInputFieldChange(eventObject: Event) {
let inputField = <HTMLInputElement> eventObject.target;
/* If there is any contents of the input box, display the markdown preview and populate it. */
if (inputField.value.length > 0) {
this.previewElement.style.display = "block";
let previewContents = <HTMLDivElement> this.previewElement.querySelector(".at_preview_contents");
previewContents.innerHTML = SnuOwnd.getParser().render(inputField.value);
} else {
this.previewElement.style.display = "none";
}
}
}
}