diff src/bbcode/bbcode.js @ 48:4e1a01db19ec

add lists
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 17 Nov 2022 00:11:44 -0700
parents 7ef9222474e2
children f225e82b2bf8
line wrap: on
line diff
--- a/src/bbcode/bbcode.js	Mon Nov 14 23:01:29 2022 -0700
+++ b/src/bbcode/bbcode.js	Thu Nov 17 00:11:44 2022 -0700
@@ -1,17 +1,6 @@
 // https://fonts.google.com/icons
 
-function bb_fixTextarea(textarea) {
-	let height = textarea.scrollHeight;
-	if( height > textarea.clientHeight ) {
-		textarea.style.height = (height+2) + "px";
-	}
-}
-
-function bb_fileButtonClick(button) {
-	button.parentNode.querySelector('input[type="file"]').click();
-}
-
-function bb_upload(input,callback) {
+function upload(input,callback) {
 	let file = input.files[0];
 	input.value = null;
 	let request = new XMLHttpRequest();
@@ -39,55 +28,6 @@
 	request.send(formData);
 }
 
-function bb_getDivBbcode(node) {
-	do {
-		//console.log(node);
-		if( node.getAttribute('bbcode') !== null )
-			return node;
-	} while( node = node.parentNode );
-}
-
-function bb_getTextarea(node) {
-	return bb_getDivBbcode(node).querySelector('textarea');
-}
-
-function bb_uploaded(input,url,filename) {
-	let textarea = bb_getTextarea(input);
-	textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select');
-	textarea.focus();
-}
-
-function bb_add(input,openTag,closeTag) {
-	let textarea = bb_getTextarea(input);
-	let start = textarea.selectionStart;
-	let end = textarea.selectionEnd;
-	textarea.setRangeText(closeTag,end,end);
-	textarea.setRangeText(openTag,start,start);
-	let len = openTag.length;
-	textarea.setSelectionRange(start+len,end+len);
-	textarea.focus();
-}
-
-function bb_more(button) {
-	let checked = button.getAttribute('checked') !== null;
-	let buttons = button.parentNode.querySelectorAll('button');
-	if( checked ) {
-		button.removeAttribute('checked');
-		for( let b of buttons ) {
-			if( b === button )
-				break;
-			b.setAttribute('hidden','');
-		}
-	} else {
-		button.setAttribute('checked','');
-		for( let b of buttons ) {
-			if( b === button )
-				break;
-			b.removeAttribute('hidden');
-		}
-	}
-}
-
 function bbcodeCreate(div,options) {
 	if( typeof(div) === 'string' ) {
 		div = document.querySelector(div);
@@ -99,17 +39,19 @@
 	let cancel = options.cancel;
 	let html = `\
 		<div bbcode>
-			<textarea name=bbcode oninput="bb_fixTextarea(this)">${content}</textarea>
+			<textarea name=bbcode>${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>
-				<button type=button onclick="bb_add(this,'[u]','[/u]')" title="Underline"><img src="/bbcode/icons/format_underlined.svg"></button>
-				<button type=button onclick="bb_add(this,'[s]','[/s]')" title="Strikethrough"><img src="/bbcode/icons/format_strikethrough.svg"></button>
-				<button type=button onclick="bb_add(this,'[sub]','[/sub]')" title="Subscript"><img src="/bbcode/icons/subscript.svg"></button>
-				<button type=button onclick="bb_add(this,'[sup]','[/sup]')" title="Superscript"><img src="/bbcode/icons/superscript.svg"></button>
-				<button more checked type=button onclick="bb_more(this)" title="More..."><img src="/bbcode/icons/more_horiz.svg"></button>
-				<input type=file onchange="bb_upload(this,bb_uploaded)">
-				<button type=button onclick="bb_fileButtonClick(this)" title="Upload File"><img src="/bbcode/icons/file_upload.svg"></button>
+				<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>
+				<button type=button strikethrough title="Strikethrough"><img src="/bbcode/icons/format_strikethrough.svg"></button>
+				<button type=button sub title="Subscript"><img src="/bbcode/icons/subscript.svg"></button>
+				<button type=button sup title="Superscript"><img src="/bbcode/icons/superscript.svg"></button>
+				<button type=button ul title="Bullet list"><img src="/bbcode/icons/format_list_bulleted.svg"></button>
+				<button type=button ol title="Numbered list"><img src="/bbcode/icons/format_list_numbered.svg"></button>
+				<button type=button more checked title="More..."><img src="/bbcode/icons/more_horiz.svg"></button>
+				<input type=file>
+				<button type=button upload title="Upload File"><img src="/bbcode/icons/file_upload.svg"></button>
 `	;
 	if(save) {
 		html += `\
@@ -126,11 +68,73 @@
 		</div>
 `	;
 	div.innerHTML = html;
+
 	if(save)
-		div.querySelector('button[save]').addEventListener('click',save);
+		div.querySelector('button[save]').onclick = save;
 	if(cancel)
-		div.querySelector('button[cancel]').addEventListener('click',cancel);
-	let textarea = div.querySelector('textarea')
-	bb_fixTextarea(textarea);
-	bb_more( div.querySelector('button[more]') );
+		div.querySelector('button[cancel]').onclick = cancel;
+
+	let textarea = div.querySelector('textarea');
+	function fixTextarea() {
+		let height = textarea.scrollHeight;
+		if( height > textarea.clientHeight ) {
+			textarea.style.height = (height+2) + "px";
+		}
+	};
+	textarea.oninput = fixTextarea;
+	fixTextarea();
+
+	let moreButton = div.querySelector('button[more]');
+	function more() {
+		let button = moreButton;
+		let checked = button.getAttribute('checked') !== null;
+		let buttons = button.parentNode.querySelectorAll('button');
+		if( checked ) {
+			button.removeAttribute('checked');
+			for( let b of buttons ) {
+				if( b === button )
+					break;
+				b.setAttribute('hidden','');
+			}
+		} else {
+			button.setAttribute('checked','');
+			for( let b of buttons ) {
+				if( b === button )
+					break;
+				b.removeAttribute('hidden');
+			}
+		}
+	};
+	moreButton.onclick = more;
+	more();
+
+	function add(tag,openTag,closeTag) {
+		let button = div.querySelector('button['+tag+']');
+		button.onclick = function() {
+			let start = textarea.selectionStart;
+			let end = textarea.selectionEnd;
+			textarea.setRangeText(closeTag,end,end);
+			textarea.setRangeText(openTag,start,start);
+			let len = openTag.length;
+			textarea.setSelectionRange(start+len,end+len);
+			fixTextarea();
+			textarea.focus();
+		};
+	}
+	add('bold','[b]','[/b]');
+	add('italic','[i]','[/i]');
+	add('underline','[u]','[/u]');
+	add('strikethrough','[s]','[/s]');
+	add('sub','[sub]','[/sub]');
+	add('sup','[sup]','[/sup]');
+	add('ul','[list]\n[item]','[/item]\n[/list]');
+	add('ol','[list=1]\n[item]','[/item]\n[/list]');
+
+	let fileInput = div.querySelector('input[type="file"]');
+	div.querySelector('button[upload]').onclick = function(){ fileInput.click(); };
+	function uploaded(input,url,filename) {
+		textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select');
+		textarea.focus();
+	}
+	fileInput.onchange = function() { upload(fileInput,uploaded); };
 }