From 4a7b9c7f5e1048cfd92c8945c622c480b1a69d89 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 5 Jun 2019 16:56:37 +0200 Subject: [PATCH] Implemented custom JSX handler. --- .../typescript/{Comments.ts => Comments.tsx} | 183 +++++------------- assets/typescript/misuzu.ts | 45 ++++- tsconfig.json | 2 + 3 files changed, 99 insertions(+), 131 deletions(-) rename assets/typescript/{Comments.ts => Comments.tsx} (65%) diff --git a/assets/typescript/Comments.ts b/assets/typescript/Comments.tsx similarity index 65% rename from assets/typescript/Comments.ts rename to assets/typescript/Comments.tsx index 717a7752..ece46816 100644 --- a/assets/typescript/Comments.ts +++ b/assets/typescript/Comments.tsx @@ -187,147 +187,70 @@ function commentInputEventHandler(ev: KeyboardEvent): void { } function commentConstruct(comment: CommentPostInfo, layer: number = 0): HTMLElement { - const commentElement: HTMLDivElement = document.createElement('div'); - commentElement.className = 'comment'; - commentElement.id = 'comment-' + comment.comment_id; + const commentDate = new Date(comment.comment_created + 'Z'), + commentTime: HTMLElement = ; + let actions: HTMLElement[] = []; - // layer 2 - const commentContainer: HTMLDivElement = commentElement.appendChild(document.createElement('div')); - commentContainer.className = 'comment__container'; + if (checkUserPerm('comments', CommentPermission.Vote)) { + actions.push(Like); + actions.push(Dislike); + } - const commentReplies: HTMLDivElement = commentElement.appendChild(document.createElement('div')); - commentReplies.className = 'comment__replies comment__replies--indent-' + layer; - commentReplies.id = commentElement.id + '-replies'; - - // container - const commentAvatar: HTMLAnchorElement = commentContainer.appendChild(document.createElement('a')); - commentAvatar.className = 'avatar comment__avatar'; - commentAvatar.href = urlFormat('user-profile', [{name:'user',value:comment.user_id}]); - commentAvatar.style.backgroundImage = "url('{0}')".replace('{0}', urlFormat('user-avatar', [ - { name: 'user', value: comment.user_id }, - { name: 'res', value: layer < 1 ? 100 : 80 } - ])); - - const commentContent: HTMLDivElement = commentContainer.appendChild(document.createElement('div')); - commentContent.className = 'comment__content'; - - // content - const commentInfo = commentContent.appendChild(document.createElement('div')); - commentInfo.className = 'comment__info'; - - const commentText = commentContent.appendChild(document.createElement('div')); - commentText.className = 'comment__text'; + const commentText: HTMLDivElement =
; if (comment.comment_html) commentText.innerHTML = comment.comment_html; else commentText.textContent = comment.comment_text; - const commentActions = commentContent.appendChild(document.createElement('div')); - commentActions.className = 'comment__actions'; + const commentElement: HTMLDivElement =
+
+ +
+ + {commentText} +
+ {actions} + +
+
+
+
+ +
+ + + +
+
+
+
+ +
+ +
+
+
+
+
+
; - // info - const commentUser: HTMLAnchorElement = commentInfo.appendChild(document.createElement('a')); - commentUser.className = 'comment__user comment__user--link'; - commentUser.textContent = comment.username; - commentUser.href = '/profile?u=' + comment.user_id; - commentUser.style.setProperty('--user-colour', colourGetCSS(comment.user_colour)); - - const commentLink: HTMLAnchorElement = commentInfo.appendChild(document.createElement('a')); - commentLink.className = 'comment__link'; - commentLink.href = '#' + commentElement.id; - - const commentTime: HTMLTimeElement = commentLink.appendChild(document.createElement('time')), - commentDate = new Date(comment.comment_created + 'Z'); - commentTime.className = 'comment__date'; - commentTime.title = commentDate.toLocaleString(); - commentTime.dateTime = commentDate.toISOString(); - commentTime.textContent = timeago.format(commentDate); timeago.render(commentTime); - // actions - if (checkUserPerm('comments', CommentPermission.Vote)) { - const commentLike: HTMLAnchorElement = commentActions.appendChild(document.createElement('a')); - commentLike.dataset['commentId'] = comment.comment_id.toString(); - commentLike.dataset['commentVote'] = CommentVoteType.Like.toString(); - commentLike.className = 'comment__action comment__action--link comment__action--vote comment__action--like'; - commentLike.href = 'javascript:void(0);'; - commentLike.textContent = 'Like'; - commentLike.addEventListener('click', commentVoteEventHandler); - - const commentDislike: HTMLAnchorElement = commentActions.appendChild(document.createElement('a')); - commentDislike.dataset['commentId'] = comment.comment_id.toString(); - commentDislike.dataset['commentVote'] = CommentVoteType.Dislike.toString(); - commentDislike.className = 'comment__action comment__action--link comment__action--vote comment__action--dislike'; - commentDislike.href = 'javascript:void(0);'; - commentDislike.textContent = 'Dislike'; - commentDislike.addEventListener('click', commentVoteEventHandler); - } - - // if we're executing this it's fairly obvious that we can reply, - // so no need to have a permission check on it here - const commentReply: HTMLLabelElement = commentActions.appendChild(document.createElement('label')); - commentReply.className = 'comment__action comment__action--link'; - commentReply.htmlFor = 'comment-reply-toggle-' + comment.comment_id; - commentReply.textContent = 'Reply'; - - // reply section - const commentReplyState: HTMLInputElement = commentReplies.appendChild(document.createElement('input')); - commentReplyState.id = commentReply.htmlFor; - commentReplyState.type = 'checkbox'; - commentReplyState.className = 'comment__reply-toggle'; - - const commentReplyInput: HTMLFormElement = commentReplies.appendChild(document.createElement('form')); - commentReplyInput.id = 'comment-reply-' + comment.comment_id; - commentReplyInput.className = 'comment comment--input comment--reply'; - commentReplyInput.method = 'post'; - commentReplyInput.action = 'javascript:void(0);'; - commentReplyInput.addEventListener('submit', commentPostEventHandler); - - // reply attributes - const replyCategory: HTMLInputElement = commentReplyInput.appendChild(document.createElement('input')); - replyCategory.name = 'comment[category]'; - replyCategory.value = comment.category_id.toString(); - replyCategory.type = 'hidden'; - - const replyCsrf: HTMLInputElement = commentReplyInput.appendChild(document.createElement('input')); - replyCsrf.name = 'csrf[comments]'; - replyCsrf.value = getCSRFToken('comments'); - replyCsrf.type = 'hidden'; - - const replyId: HTMLInputElement = commentReplyInput.appendChild(document.createElement('input')); - replyId.name = 'comment[reply]'; - replyId.value = comment.comment_id.toString(); - replyId.type = 'hidden'; - - const replyContainer: HTMLDivElement = commentReplyInput.appendChild(document.createElement('div')); - replyContainer.className = 'comment__container'; - - // reply container - const replyAvatar: HTMLDivElement = replyContainer.appendChild(document.createElement('div')); - replyAvatar.className = 'avatar comment__avatar'; - replyAvatar.style.backgroundImage = "url('{0}')".replace('{0}', urlFormat('user-avatar', [{name:'user',value:comment.user_id},{name:'res',value:80}])); - - const replyContent: HTMLDivElement = replyContainer.appendChild(document.createElement('div')); - replyContent.className = 'comment__content'; - - // reply content - const replyInfo: HTMLDivElement = replyContent.appendChild(document.createElement('div')); - replyInfo.className = 'comment__info'; - - const replyText: HTMLTextAreaElement = replyContent.appendChild(document.createElement('textarea')); - replyText.className = 'comment__text input__textarea comment__text--input'; - replyText.name = 'comment[text]'; - replyText.placeholder = 'Share your extensive insights...'; - replyText.addEventListener('keydown', commentInputEventHandler); - - const replyActions: HTMLDivElement = replyContent.appendChild(document.createElement('div')); - replyActions.className = 'comment__actions'; - - const replyButton: HTMLButtonElement = replyActions.appendChild(document.createElement('button')); - replyButton.className = 'input__button comment__action comment__action--button comment__action--post'; - replyButton.textContent = 'Reply'; - return commentElement; } diff --git a/assets/typescript/misuzu.ts b/assets/typescript/misuzu.ts index 80980562..25b04d9a 100644 --- a/assets/typescript/misuzu.ts +++ b/assets/typescript/misuzu.ts @@ -2,7 +2,7 @@ /// /// /// -/// +/// /// /// /// @@ -15,6 +15,49 @@ declare const hljs: any; let loginFormAvatarTimeout: number = 0; +function mszCreateElement(type: string, properties: {} = {}, children: any[] = []): HTMLElement { + const element: HTMLElement = document.createElement(type); + + if(!Array.isArray(children)) + children = [children]; + + if(arguments.length > 3) + for(let i = 3; i < arguments.length; i++) + children.push(arguments[i]); + + if(properties) + for(let prop in properties) { + switch(typeof properties[prop]) { + case 'function': + element.addEventListener( + prop.substring(0, 2) === 'on' + ? prop.substring(2).toLowerCase() + : prop, + properties[prop] + ); + break; + default: + element.setAttribute(prop, properties[prop]); + break; + } + } + + if(children) + for(let child in children as []) { + switch(typeof children[child]) { + case 'string': + element.appendChild(document.createTextNode(children[child])); + break; + default: + if(children[child] instanceof Element) + element.appendChild(children[child]); + break; + } + } + + return element; +} + // Initialisation process. window.addEventListener('load', () => { console.log("%c __ ____\n / |/ (_)______ ______ __ __\n / /|_/ / / ___/ / / /_ / / / / /\n / / / / (__ ) /_/ / / /_/ /_/ /\n/_/ /_/_/____/\\__,_/ /___/\\__,_/\nhttps://github.com/flashwave/misuzu", 'color: #8559a5'); diff --git a/tsconfig.json b/tsconfig.json index 1aba81e0..703f692a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,8 @@ "compilerOptions": { "target": "es6", "module": "amd", + "jsx": "react", + "jsxFactory": "mszCreateElement", "removeComments": true, "preserveConstEnums": true, "out": "./public/js/misuzu.js",