changeset 46:289718f121e4

use bbcode editor
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 14 Nov 2022 18:43:38 -0700
parents 2d4f00755092
children 7ef9222474e2
files src/bbcode/bbcode.js src/bbcode/test.html src/edit.js.luan src/lib/Post.luan src/new_thread.html.luan src/site.css src/site.js src/thread.html.luan
diffstat 8 files changed, 46 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/src/bbcode/bbcode.js	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/bbcode/bbcode.js	Mon Nov 14 18:43:38 2022 -0700
@@ -39,7 +39,7 @@
 	request.send(formData);
 }
 
-function getBbcodeDiv(node) {
+function bb_getDiv(node) {
 	do {
 		//console.log(node);
 		if( node.getAttribute('bbcode') !== null )
@@ -47,16 +47,18 @@
 	} while( node = node.parentNode );
 }
 
+function bb_getTextarea(node) {
+	return bb_getDiv(node).querySelector('textarea');
+}
+
 function bb_uploaded(input,url,filename) {
-	let div = getBbcodeDiv(input);
-	let textarea = div.querySelector('textarea');
+	let textarea = bb_getTextarea(input);
 	textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select');
 	textarea.focus();
 }
 
 function bb_add(input,openTag,closeTag) {
-	let div = getBbcodeDiv(input);
-	let textarea = div.querySelector('textarea');
+	let textarea = bb_getTextarea(input);
 	let start = textarea.selectionStart;
 	let end = textarea.selectionEnd;
 	textarea.setRangeText(closeTag,end,end);
@@ -67,14 +69,17 @@
 }
 
 function bbcodeCreate(div,options) {
-	if( typeof(div) === 'string' )
+	if( typeof(div) === 'string' ) {
 		div = document.querySelector(div);
+		if(!div) throw 'selector not found';
+	}
+	options = options || {};
 	let content = options.content || '';
 	let save = options.save;
 	let cancel = options.cancel;
 	let html = `\
 		<div bbcode>
-			<textarea oninput="bb_fixTextarea(this)"></textarea>
+			<textarea name=bbcode oninput="bb_fixTextarea(this)">${content}</textarea>
 			<div buttons>
 				<button type=button onclick="bb_add(this,'[b]','[/b]')" title="Bold"><img src="/bbcode/icons/format_bold.svg"></button>
 				<button type=button onclick="bb_add(this,'[i]','[/i]')" title="Italic"><img src="/bbcode/icons/format_italic.svg"></button>
@@ -104,4 +109,6 @@
 		div.querySelector('button[save]').addEventListener('click',save);
 	if(cancel)
 		div.querySelector('button[cancel]').addEventListener('click',cancel);
+	let textarea = div.querySelector('textarea')
+	bb_fixTextarea(textarea);
 }
--- a/src/bbcode/test.html	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/bbcode/test.html	Mon Nov 14 18:43:38 2022 -0700
@@ -32,8 +32,7 @@
 			}
 
 			function save(event) {
-				let div = getBbcodeDiv(event.target);
-				let text = div.querySelector('textarea').value;
+				let text = document.querySelector('textarea').value;
 				ajax( 'test.js?text=' + encodeURIComponent(text) );
 			}
 
--- a/src/edit.js.luan	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/edit.js.luan	Mon Nov 14 18:43:38 2022 -0700
@@ -16,10 +16,12 @@
 %>
 	let postDiv = document.querySelector('[post="<%=post.id%>"]');
 	postDiv.querySelector('[output]').style.display = 'none';
-	postDiv.querySelector('[edit]').innerHTML = document.querySelector('[hidden][edit]').innerHTML;
+	bbcodeCreate( postDiv.querySelector('[edit]'), {
+		content: <%= json_string(html_encode(post.content)) %>,
+		save: saveEdit,
+		cancel: cancelEdit,
+	} );
 	let textarea = postDiv.querySelector('textarea');
-	textarea.innerHTML = <%= json_string(html_encode(post.content)) %>;
-	fixTextarea(textarea);
 	textarea.focus();
 <%
 end
--- a/src/lib/Post.luan	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/lib/Post.luan	Mon Nov 14 18:43:38 2022 -0700
@@ -143,6 +143,7 @@
 			author_name = author.name
 			is_root = true
 		}
+		post.root_id = -1
 		post.save()
 		post.root_id = post.id or error()
 		post.save()
--- a/src/new_thread.html.luan	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/new_thread.html.luan	Mon Nov 14 18:43:38 2022 -0700
@@ -17,7 +17,7 @@
 	if user==nil then return end
 	if Http.request.method == "POST" then
 		local subject = Http.request.parameters.subject or error()
-		local content = Http.request.parameters.content or error()
+		local content = Http.request.parameters.bbcode or error()
 		local post = Post.new_thread(user,subject,content)
 		Http.response.send_redirect("/thread.html?root="..post.id)
 		return
@@ -30,18 +30,9 @@
 <%		head() %>
 		<title><%=forum_title%>: new thread</title>
 		<style>
-			textarea {
-				width: 100%;
-			}
+			@import "/bbcode/bbcode.css";
 		</style>
-		<script>
-			function uploaded(input,url,filename) {
-				let textarea = document.querySelector('textarea');
-				textarea.focus();
-				textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select');
-			}
-		</script>
-	</head>
+		<script src="/bbcode/bbcode.js"></script>
 	<body>
 <%		header() %>
 		<div content>
@@ -51,16 +42,15 @@
 					<label>Subject</label>
 					<input name=subject required>
 				</p>
-				<p><textarea name=content oninput="fixTextarea(this)"></textarea></p>
-				<p>
-					<input type=file onchange="upload(this,uploaded)">
-					<button type=button onclick="fileButtonClick(this)">Upload File</button>
-				</p>
+				<p editor></p>
 				<p><input type=submit></p>
 			</form>
 		</div>
 <%		footer() %>
 	</body>
+	<script>
+		bbcodeCreate('p[editor]');
+	</script>
 </html>
 <%
 end
--- a/src/site.css	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/site.css	Mon Nov 14 18:43:38 2022 -0700
@@ -19,7 +19,6 @@
 	font: inherit;
 	padding: 7px;
 	border-color: #DDDDDD;
- 	box-sizing: content-box;
 }
 
 div[header], div[footer] {
@@ -40,10 +39,6 @@
 	display: none;
 }
 
-input[type="file"] {
-	display: none;
-}
-
 label[clickable] {
 	cursor: pointer;
 }
--- a/src/site.js	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/site.js	Mon Nov 14 18:43:38 2022 -0700
@@ -31,42 +31,3 @@
 		err += '\nstack = ' + error.stack;
 	ajax( '/error_log.js', 'err='+encodeURIComponent(err) );
 };
-
-function upload(input,callback) {
-	let file = input.files[0];
-	input.value = null;
-	let request = new XMLHttpRequest();
-	let url = 'https://upload.uploadcare.com/base/';
-	request.open( 'POST', url );
-	request.onload = function() {
-		if( request.status !== 200 ) {
-			let err = 'ajax failed: ' + request.status;
-			if( request.responseText ) {
-				err += '\n' + request.responseText;
-				document.write('<pre>'+request.responseText+'</pre>');
-			}
-			console.log(err);
-			ajax( '/error_log.js', 'err='+encodeURIComponent(err) );
-			return;
-		}
-		let response = JSON.parse(request.responseText);
-		let filename = file.name;
-		let url = 'https://ucarecdn.com/' + response.file + '/' + filename;
-		callback(input,url,filename);
-	};
-	let formData = new FormData();
-	formData.append( 'UPLOADCARE_PUB_KEY', 'fe3d30f3088a50941d45' );
-	formData.append( 'file', file );
-	request.send(formData);
-}
-
-function fileButtonClick(button) {
-	button.parentNode.querySelector('input[type="file"]').click();
-}
-
-function fixTextarea(textarea) {
-	let height = textarea.scrollHeight;
-	if( height > textarea.clientHeight ) {
-		textarea.style.height = height + "px";
-	}
-}
--- a/src/thread.html.luan	Sun Nov 13 22:07:18 2022 -0700
+++ b/src/thread.html.luan	Mon Nov 14 18:43:38 2022 -0700
@@ -36,6 +36,8 @@
 <%		head() %>
 		<title><%=forum_title%>: <%=subject_html%></title>
 		<style>
+			@import "/bbcode/bbcode.css";
+
 			div[author] {
 				margin-bottom: 6px;
 				font-size: 10px;
@@ -55,11 +57,6 @@
 				white-space: pre-wrap;
 				line-height: 1.4;
 			}
-			textarea {
-				width: 100%;
-				xmax-width: 450px;
-				xheight: 100px;
-			}
 <%	if user_name == nil then %>
 			[logged_in] {
 				display: none;
@@ -80,6 +77,7 @@
 				display: initial;
 			}
 		</style>
+		<script src="/bbcode/bbcode.js"></script>
 		<script>
 			function getPostDiv(node) {
 				do {
@@ -88,16 +86,16 @@
 				} while( node = node.parentNode );
 			}
 
-			function cancelEdit(src) {
-				let postDiv = getPostDiv(src);
+			function cancelEdit(event) {
+				let postDiv = getPostDiv(event.target);
 				postDiv.querySelector('[output]').style.display = 'block';
 				postDiv.querySelector('[edit]').innerHTML = '';
 			}
-			function saveEdit(src) {
-				let postDiv = getPostDiv(src);
+			function saveEdit(event) {
+				let postDiv = getPostDiv(event.target);
 				let post = postDiv.getAttribute('post');
 				let text = postDiv.querySelector('textarea').value;
-				cancelEdit(src);
+				cancelEdit(event);
 				let postData = 'post=' + post + '&text=' + encodeURIComponent(text);
 				ajax('save_edit.js',postData);
 			}
@@ -141,6 +139,10 @@
 				ajax( '/delete.js?post=' + post );
 			}
 			function deleted(postId,thread_size) {
+				if( thread_size === 0 ) {
+					location = '/';
+					return;
+				}
 				let postDiv = document.querySelector('[post="'+postId+'"]');
 				if(!postDiv)
 					return
@@ -173,28 +175,19 @@
 	end %>
 			<div post=new logged_in>
 				<hr>
-				<textarea oninput="fixTextarea(this)"></textarea>
-				<p>
-					<input type=file onchange="upload(this,uploaded)">
-					<button onclick="fileButtonClick(this)">Upload File</button>
-					<button onclick="newPost()">save</button>
-				</p>
+				<div editor></div>
 			</div>
 		</div>
 <%		footer() %>
 
 		<span hidden delete>Delete? <a href="javascript:" onclick="deleteYes(parentNode)">yes</a> / <a href="javascript:" onclick="deleteNo(parentNode)">no</a></span>
 		<span hidden undelete><%delete_post()%></span>
-		<div hidden edit>
-			<textarea oninput="fixTextarea(this)"></textarea>
-			<p>
-				<input type=file onchange="upload(this,uploaded)">
-				<button onclick="fileButtonClick(this)">Upload File</button>
-				<button onclick="saveEdit(this)">save</button>
-				<button onclick="cancelEdit(this)">cancel</button>
-			</p>
-		</div>
 	</body>
+	<script>
+		bbcodeCreate('div[post="new"] div[editor]',{
+			save: newPost
+		});
+	</script>
 </html>
 <%
 end