changeset 60:8b5b1bce7d6b

bcode menus
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 30 Nov 2022 23:50:52 -0700
parents 02d8876dc41d
children 389e5d8e5f8a
files src/bbcode/bbcode.css src/bbcode/bbcode.js src/edit.js.luan src/thread.html.luan
diffstat 4 files changed, 66 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
diff -r 02d8876dc41d -r 8b5b1bce7d6b src/bbcode/bbcode.css
--- a/src/bbcode/bbcode.css	Tue Nov 29 18:45:22 2022 -0700
+++ b/src/bbcode/bbcode.css	Wed Nov 30 23:50:52 2022 -0700
@@ -12,21 +12,34 @@
 	display: none;
 }
 
-div[bbcode_editor] button:hover {
+div[bbcode_editor] input[type="checkbox"],
+div[bbcode_editor] button {
 	cursor: pointer;
 }
 
 div[bbcode_editor] div[buttons] {
 	display: flex;
+	gap: 4px;
+	align-items: center;
+}
+div[bbcode_editor] div[buttons="top"] {
+	margin-bottom: 2px;
+}
+div[bbcode_editor] div[buttons="bottom"] {
 	justify-content: flex-end;
-	gap: 4px;
 }
 div[bbcode_editor] button {
+	padding-top: 2px;
+}
+div[bbcode_editor] button:has(img) {
 	border: 0;
 	background-color: transparent;
 	border-radius: 4px;
 }
-div[bbcode_editor] button:hover {
+div[bbcode_editor] button input[type="checkbox"] {
+	margin: 0;
+}
+div[bbcode_editor] button:has(img):hover {
 	background-color: lightgrey;
 }
 div[bbcode_editor] button[checked] {
diff -r 02d8876dc41d -r 8b5b1bce7d6b src/bbcode/bbcode.js
--- a/src/bbcode/bbcode.js	Tue Nov 29 18:45:22 2022 -0700
+++ b/src/bbcode/bbcode.js	Wed Nov 30 23:50:52 2022 -0700
@@ -52,14 +52,11 @@
 		if(!div) throw 'selector not found';
 	}
 	options = options || {};
+	options.buttons = options.buttons || {};
 	let content = options.content || '';
-	let save = options.save;
-	let cancel = options.cancel;
 	let html = `\
 		<div bbcode_editor>
-			<textarea name=bbcode>${content}</textarea>
-			<div preview from_bbcode></div>
-			<div buttons>
+			<div buttons=top>
 				<button type=button bold title="Bold"><img src="/bbcode/icons/format_bold.svg"></button>
 				<button type=button italic title="Italic"><img src="/bbcode/icons/format_italic.svg"></button>
 				<button type=button underline title="Underline"><img src="/bbcode/icons/format_underlined.svg"></button>
@@ -70,21 +67,19 @@
 				<button type=button ol title="Numbered list"><img src="/bbcode/icons/format_list_numbered.svg"></button>
 				<button type=button code_block title="Code block"><img src="/bbcode/icons/code_blocks.svg"></button>
 				<button type=button code_inline title="Inline code"><img src="/bbcode/icons/code.svg"></button>
-				<button type=button convert_urls checked title="Convert URLs"><img src="/bbcode/icons/media_link.svg"></button>
-				<input type=hidden name=convert_urls value=true>
-				<button type=button more checked title="More..."><img src="/bbcode/icons/more_horiz.svg"></button>
+				<button type=button convert_urls><input type=checkbox name=convert_urls checked> Convert URLs</button>
+			</div>
+			<textarea name=bbcode>${content}</textarea>
+			<div preview from_bbcode></div>
+			<div buttons=bottom>
+				<button type=button more><input type=checkbox> BBCode menu</button>
 				<input type=file>
-				<button type=button upload title="Upload File"><img src="/bbcode/icons/file_upload.svg"></button>
-				<button type=button preview title="Preview"><img src="/bbcode/icons/preview.svg"></button>
+				<button type=button upload>Upload file</button>
+				<button type=button preview><input type=checkbox> Preview</button>
 `	;
-	if(save) {
+	for( let key of Object.keys(options.buttons) ) {
 		html += `\
-				<button type=button save title="Send message"><img src="/bbcode/icons/send.svg"></button>
-`		;
-	}
-	if(cancel) {
-		html += `\
-				<button type=button cancel title="Cancel"><img src="/bbcode/icons/cancel.svg"></button>
+				<button type=button key="${key}">${key}</button>
 `		;
 	}
 	html += `\
@@ -96,19 +91,16 @@
 	let enabledInPreview = [];
 	let convertUrls = true;
 
-	if(save) {
-		let button = div.querySelector('button[save]');
+	for( let entry of Object.entries(options.buttons) ) {
+		console.log(entry);
+		let button = div.querySelector('button[key="'+entry[0]+'"]');
+		let fn = entry[1];
 		button.onclick = function(event) {
 			event.convertUrls = convertUrls;
-			save(event);
+			fn(event);
 		};
 		enabledInPreview.push(button);
 	}
-	if(cancel) {
-		let button = div.querySelector('button[cancel]');
-		button.onclick = cancel;
-		enabledInPreview.push(button);
-	}
 
 	let textarea = div.querySelector('textarea');
 	function fixTextarea() {
@@ -120,38 +112,23 @@
 	textarea.oninput = fixTextarea;
 	fixTextarea();
 
-	function toggle(button) {
-		let checked = button.getAttribute('checked') !== null;
-		checked = !checked;  // toggle
-		if( checked ) {
-			button.setAttribute('checked','');
-		} else {
-			button.removeAttribute('checked');
-		}
-		return checked;
-	}
+	function checkboxButtonClick(event) {
+		event.target.querySelector('input').click();
+	};
 
+	let topButtons = div.querySelector('[buttons="top"]');
+	topButtons.style.display = 'none';
 	let moreButton = div.querySelector('button[more]');
-	function more() {
-		let checked = toggle(moreButton);
-		let buttons = moreButton.parentNode.querySelectorAll('button');
-		if( checked ) {
-			for( let b of buttons ) {
-				if( b === moreButton )
-					break;
-				b.removeAttribute('hidden');
-			}
+	moreButton.onclick = checkboxButtonClick;
+	let moreCheckbox = moreButton.querySelector('input');
+	moreCheckbox.onclick = function() {
+		if( moreCheckbox.checked ) {
+			topButtons.style.display = 'flex';
 		} else {
-			for( let b of buttons ) {
-				if( b === moreButton )
-					break;
-				b.setAttribute('hidden','');
-			}
+			topButtons.style.display = 'none';
 		}
+		event.stopPropagation();
 	};
-	moreButton.onclick = more;
-	more();
-	enabledInPreview.push(moreButton);
 
 	let divPreview = div.querySelector('div[preview]');
 	function contextPreview(bbcode,html) {
@@ -159,16 +136,18 @@
 		divPreview.innerHTML = html;
 	}
 	let previewButton = div.querySelector('button[preview]');
-	function preview() {
-		let checked = toggle(previewButton);
+	previewButton.onclick = checkboxButtonClick;
+	let previewCheckbox = previewButton.querySelector('input');
+	previewCheckbox.onclick = function() {
 		let buttons = previewButton.parentNode.querySelectorAll('button');
-		if( checked ) {
+		if( previewCheckbox.checked ) {
 			for( let b of buttons ) {
 				if( !enabledInPreview.includes(b) )
 					b.disabled = true;
 			}
 			textarea.style.display = 'none';
 			divPreview.style.display = 'block';
+			topButtons.style.display = 'none';
 			let postData = 'text=' + encodeURIComponent(textarea.value) + '&convert_urls=' + convertUrls;
 			ajax( '/bbcode/preview.js', postData, {preview: contextPreview} );
 		} else {
@@ -177,19 +156,21 @@
 			}
 			textarea.style.display = 'initial';
 			divPreview.style.display = 'none';
+			if( moreCheckbox.checked )
+				topButtons.style.display = 'flex';
 			textarea.focus();
 		}
+		event.stopPropagation();
 	}
-	previewButton.onclick = preview;
 	enabledInPreview.push(previewButton);
 
 	let convertUrlsButton = div.querySelector('button[convert_urls]');
-	let convertUrlsInput = div.querySelector('input[name="convert_urls"]');
-	function toggleConvertUrls() {
-		convertUrls = toggle(convertUrlsButton);
-		convertUrlsInput.value = convertUrls;
-	}
-	convertUrlsButton.onclick = toggleConvertUrls;
+	convertUrlsButton.onclick = checkboxButtonClick;
+	let convertUrlsCheckbox = convertUrlsButton.querySelector('input');
+	convertUrlsCheckbox.onclick = function(event) {
+		convertUrls = convertUrlsCheckbox.checked;
+		event.stopPropagation();
+	};
 
 	function add(tag,openTag,closeTag) {
 		let button = div.querySelector('button['+tag+']');
diff -r 02d8876dc41d -r 8b5b1bce7d6b src/edit.js.luan
--- a/src/edit.js.luan	Tue Nov 29 18:45:22 2022 -0700
+++ b/src/edit.js.luan	Wed Nov 30 23:50:52 2022 -0700
@@ -18,8 +18,10 @@
 	postDiv.querySelector('[output]').style.display = 'none';
 	bbcodeCreate( postDiv.querySelector('[edit]'), {
 		content: <%= json_string(html_encode(post.content)) %>,
-		save: saveEdit,
-		cancel: cancelEdit,
+		buttons: {
+			Save: saveEdit,
+			Cancel: cancelEdit,
+		}
 	} );
 	let textarea = postDiv.querySelector('textarea');
 	textarea.focus();
diff -r 02d8876dc41d -r 8b5b1bce7d6b src/thread.html.luan
--- a/src/thread.html.luan	Tue Nov 29 18:45:22 2022 -0700
+++ b/src/thread.html.luan	Wed Nov 30 23:50:52 2022 -0700
@@ -179,9 +179,9 @@
 		<span hidden undelete><%delete_post()%></span>
 	</body>
 	<script>
-		bbcodeCreate('div[post="new"] div[editor]',{
-			save: newPost
-		});
+		bbcodeCreate('div[post="new"] div[editor]',{buttons:{
+			Save: newPost
+		}});
 	</script>
 </html>
 <%