Mercurial Hosting > freedit
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 47:7ef9222474e2 | 48:4e1a01db19ec |
|---|---|
| 1 // https://fonts.google.com/icons | 1 // https://fonts.google.com/icons |
| 2 | 2 |
| 3 function bb_fixTextarea(textarea) { | 3 function upload(input,callback) { |
| 4 let height = textarea.scrollHeight; | |
| 5 if( height > textarea.clientHeight ) { | |
| 6 textarea.style.height = (height+2) + "px"; | |
| 7 } | |
| 8 } | |
| 9 | |
| 10 function bb_fileButtonClick(button) { | |
| 11 button.parentNode.querySelector('input[type="file"]').click(); | |
| 12 } | |
| 13 | |
| 14 function bb_upload(input,callback) { | |
| 15 let file = input.files[0]; | 4 let file = input.files[0]; |
| 16 input.value = null; | 5 input.value = null; |
| 17 let request = new XMLHttpRequest(); | 6 let request = new XMLHttpRequest(); |
| 18 let url = 'https://upload.uploadcare.com/base/'; | 7 let url = 'https://upload.uploadcare.com/base/'; |
| 19 request.open( 'POST', url ); | 8 request.open( 'POST', url ); |
| 37 formData.append( 'UPLOADCARE_PUB_KEY', 'fe3d30f3088a50941d45' ); | 26 formData.append( 'UPLOADCARE_PUB_KEY', 'fe3d30f3088a50941d45' ); |
| 38 formData.append( 'file', file ); | 27 formData.append( 'file', file ); |
| 39 request.send(formData); | 28 request.send(formData); |
| 40 } | 29 } |
| 41 | 30 |
| 42 function bb_getDivBbcode(node) { | |
| 43 do { | |
| 44 //console.log(node); | |
| 45 if( node.getAttribute('bbcode') !== null ) | |
| 46 return node; | |
| 47 } while( node = node.parentNode ); | |
| 48 } | |
| 49 | |
| 50 function bb_getTextarea(node) { | |
| 51 return bb_getDivBbcode(node).querySelector('textarea'); | |
| 52 } | |
| 53 | |
| 54 function bb_uploaded(input,url,filename) { | |
| 55 let textarea = bb_getTextarea(input); | |
| 56 textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select'); | |
| 57 textarea.focus(); | |
| 58 } | |
| 59 | |
| 60 function bb_add(input,openTag,closeTag) { | |
| 61 let textarea = bb_getTextarea(input); | |
| 62 let start = textarea.selectionStart; | |
| 63 let end = textarea.selectionEnd; | |
| 64 textarea.setRangeText(closeTag,end,end); | |
| 65 textarea.setRangeText(openTag,start,start); | |
| 66 let len = openTag.length; | |
| 67 textarea.setSelectionRange(start+len,end+len); | |
| 68 textarea.focus(); | |
| 69 } | |
| 70 | |
| 71 function bb_more(button) { | |
| 72 let checked = button.getAttribute('checked') !== null; | |
| 73 let buttons = button.parentNode.querySelectorAll('button'); | |
| 74 if( checked ) { | |
| 75 button.removeAttribute('checked'); | |
| 76 for( let b of buttons ) { | |
| 77 if( b === button ) | |
| 78 break; | |
| 79 b.setAttribute('hidden',''); | |
| 80 } | |
| 81 } else { | |
| 82 button.setAttribute('checked',''); | |
| 83 for( let b of buttons ) { | |
| 84 if( b === button ) | |
| 85 break; | |
| 86 b.removeAttribute('hidden'); | |
| 87 } | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 function bbcodeCreate(div,options) { | 31 function bbcodeCreate(div,options) { |
| 92 if( typeof(div) === 'string' ) { | 32 if( typeof(div) === 'string' ) { |
| 93 div = document.querySelector(div); | 33 div = document.querySelector(div); |
| 94 if(!div) throw 'selector not found'; | 34 if(!div) throw 'selector not found'; |
| 95 } | 35 } |
| 97 let content = options.content || ''; | 37 let content = options.content || ''; |
| 98 let save = options.save; | 38 let save = options.save; |
| 99 let cancel = options.cancel; | 39 let cancel = options.cancel; |
| 100 let html = `\ | 40 let html = `\ |
| 101 <div bbcode> | 41 <div bbcode> |
| 102 <textarea name=bbcode oninput="bb_fixTextarea(this)">${content}</textarea> | 42 <textarea name=bbcode>${content}</textarea> |
| 103 <div buttons> | 43 <div buttons> |
| 104 <button type=button onclick="bb_add(this,'[b]','[/b]')" title="Bold"><img src="/bbcode/icons/format_bold.svg"></button> | 44 <button type=button bold title="Bold"><img src="/bbcode/icons/format_bold.svg"></button> |
| 105 <button type=button onclick="bb_add(this,'[i]','[/i]')" title="Italic"><img src="/bbcode/icons/format_italic.svg"></button> | 45 <button type=button italic title="Italic"><img src="/bbcode/icons/format_italic.svg"></button> |
| 106 <button type=button onclick="bb_add(this,'[u]','[/u]')" title="Underline"><img src="/bbcode/icons/format_underlined.svg"></button> | 46 <button type=button underline title="Underline"><img src="/bbcode/icons/format_underlined.svg"></button> |
| 107 <button type=button onclick="bb_add(this,'[s]','[/s]')" title="Strikethrough"><img src="/bbcode/icons/format_strikethrough.svg"></button> | 47 <button type=button strikethrough title="Strikethrough"><img src="/bbcode/icons/format_strikethrough.svg"></button> |
| 108 <button type=button onclick="bb_add(this,'[sub]','[/sub]')" title="Subscript"><img src="/bbcode/icons/subscript.svg"></button> | 48 <button type=button sub title="Subscript"><img src="/bbcode/icons/subscript.svg"></button> |
| 109 <button type=button onclick="bb_add(this,'[sup]','[/sup]')" title="Superscript"><img src="/bbcode/icons/superscript.svg"></button> | 49 <button type=button sup title="Superscript"><img src="/bbcode/icons/superscript.svg"></button> |
| 110 <button more checked type=button onclick="bb_more(this)" title="More..."><img src="/bbcode/icons/more_horiz.svg"></button> | 50 <button type=button ul title="Bullet list"><img src="/bbcode/icons/format_list_bulleted.svg"></button> |
| 111 <input type=file onchange="bb_upload(this,bb_uploaded)"> | 51 <button type=button ol title="Numbered list"><img src="/bbcode/icons/format_list_numbered.svg"></button> |
| 112 <button type=button onclick="bb_fileButtonClick(this)" title="Upload File"><img src="/bbcode/icons/file_upload.svg"></button> | 52 <button type=button more checked title="More..."><img src="/bbcode/icons/more_horiz.svg"></button> |
| 53 <input type=file> | |
| 54 <button type=button upload title="Upload File"><img src="/bbcode/icons/file_upload.svg"></button> | |
| 113 ` ; | 55 ` ; |
| 114 if(save) { | 56 if(save) { |
| 115 html += `\ | 57 html += `\ |
| 116 <button type=button save title="Send message"><img src="/bbcode/icons/send.svg"></button> | 58 <button type=button save title="Send message"><img src="/bbcode/icons/send.svg"></button> |
| 117 ` ; | 59 ` ; |
| 124 html += `\ | 66 html += `\ |
| 125 </div> | 67 </div> |
| 126 </div> | 68 </div> |
| 127 ` ; | 69 ` ; |
| 128 div.innerHTML = html; | 70 div.innerHTML = html; |
| 71 | |
| 129 if(save) | 72 if(save) |
| 130 div.querySelector('button[save]').addEventListener('click',save); | 73 div.querySelector('button[save]').onclick = save; |
| 131 if(cancel) | 74 if(cancel) |
| 132 div.querySelector('button[cancel]').addEventListener('click',cancel); | 75 div.querySelector('button[cancel]').onclick = cancel; |
| 133 let textarea = div.querySelector('textarea') | 76 |
| 134 bb_fixTextarea(textarea); | 77 let textarea = div.querySelector('textarea'); |
| 135 bb_more( div.querySelector('button[more]') ); | 78 function fixTextarea() { |
| 79 let height = textarea.scrollHeight; | |
| 80 if( height > textarea.clientHeight ) { | |
| 81 textarea.style.height = (height+2) + "px"; | |
| 82 } | |
| 83 }; | |
| 84 textarea.oninput = fixTextarea; | |
| 85 fixTextarea(); | |
| 86 | |
| 87 let moreButton = div.querySelector('button[more]'); | |
| 88 function more() { | |
| 89 let button = moreButton; | |
| 90 let checked = button.getAttribute('checked') !== null; | |
| 91 let buttons = button.parentNode.querySelectorAll('button'); | |
| 92 if( checked ) { | |
| 93 button.removeAttribute('checked'); | |
| 94 for( let b of buttons ) { | |
| 95 if( b === button ) | |
| 96 break; | |
| 97 b.setAttribute('hidden',''); | |
| 98 } | |
| 99 } else { | |
| 100 button.setAttribute('checked',''); | |
| 101 for( let b of buttons ) { | |
| 102 if( b === button ) | |
| 103 break; | |
| 104 b.removeAttribute('hidden'); | |
| 105 } | |
| 106 } | |
| 107 }; | |
| 108 moreButton.onclick = more; | |
| 109 more(); | |
| 110 | |
| 111 function add(tag,openTag,closeTag) { | |
| 112 let button = div.querySelector('button['+tag+']'); | |
| 113 button.onclick = function() { | |
| 114 let start = textarea.selectionStart; | |
| 115 let end = textarea.selectionEnd; | |
| 116 textarea.setRangeText(closeTag,end,end); | |
| 117 textarea.setRangeText(openTag,start,start); | |
| 118 let len = openTag.length; | |
| 119 textarea.setSelectionRange(start+len,end+len); | |
| 120 fixTextarea(); | |
| 121 textarea.focus(); | |
| 122 }; | |
| 123 } | |
| 124 add('bold','[b]','[/b]'); | |
| 125 add('italic','[i]','[/i]'); | |
| 126 add('underline','[u]','[/u]'); | |
| 127 add('strikethrough','[s]','[/s]'); | |
| 128 add('sub','[sub]','[/sub]'); | |
| 129 add('sup','[sup]','[/sup]'); | |
| 130 add('ul','[list]\n[item]','[/item]\n[/list]'); | |
| 131 add('ol','[list=1]\n[item]','[/item]\n[/list]'); | |
| 132 | |
| 133 let fileInput = div.querySelector('input[type="file"]'); | |
| 134 div.querySelector('button[upload]').onclick = function(){ fileInput.click(); }; | |
| 135 function uploaded(input,url,filename) { | |
| 136 textarea.setRangeText(url,textarea.selectionStart,textarea.selectionEnd,'select'); | |
| 137 textarea.focus(); | |
| 138 } | |
| 139 fileInput.onchange = function() { upload(fileInput,uploaded); }; | |
| 136 } | 140 } |
