Enhance markup inserter with logging and auto-attach functionality for textareas
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
// Simple markup inserter module
|
// Simple markup inserter module
|
||||||
(function(global){
|
(function(global){
|
||||||
|
console.log('markup_inserter.js loaded');
|
||||||
function insertAtCursor(el, text){
|
function insertAtCursor(el, text){
|
||||||
if(!el) return;
|
if(!el) return;
|
||||||
const start = el.selectionStart || 0;
|
const start = el.selectionStart || 0;
|
||||||
@@ -32,6 +33,7 @@
|
|||||||
if(!textarea) return null;
|
if(!textarea) return null;
|
||||||
// avoid double attaching
|
// avoid double attaching
|
||||||
if(textarea._markupToolbarAttached) return null;
|
if(textarea._markupToolbarAttached) return null;
|
||||||
|
console.log('Attaching markup toolbar to textarea', textarea);
|
||||||
const toolbar = createToolbar();
|
const toolbar = createToolbar();
|
||||||
textarea.parentNode.insertBefore(toolbar, textarea);
|
textarea.parentNode.insertBefore(toolbar, textarea);
|
||||||
toolbar.querySelectorAll('.markup-insert-button').forEach(function(btn){
|
toolbar.querySelectorAll('.markup-insert-button').forEach(function(btn){
|
||||||
@@ -53,6 +55,7 @@
|
|||||||
function initForNames(names){
|
function initForNames(names){
|
||||||
if(!Array.isArray(names)) return;
|
if(!Array.isArray(names)) return;
|
||||||
document.addEventListener('DOMContentLoaded', function(){
|
document.addEventListener('DOMContentLoaded', function(){
|
||||||
|
console.log('markupInserter.initForNames DOMContentLoaded handler running for', names);
|
||||||
names.forEach(function(name){
|
names.forEach(function(name){
|
||||||
const el = document.querySelector('textarea[name="'+name+'"]');
|
const el = document.querySelector('textarea[name="'+name+'"]');
|
||||||
if(el) attachToolbarToTextarea(el);
|
if(el) attachToolbarToTextarea(el);
|
||||||
@@ -70,23 +73,48 @@
|
|||||||
|
|
||||||
// Auto-attach to placeholders rendered in HTMX responses or server-side includes.
|
// Auto-attach to placeholders rendered in HTMX responses or server-side includes.
|
||||||
document.addEventListener('DOMContentLoaded', function(){
|
document.addEventListener('DOMContentLoaded', function(){
|
||||||
|
console.log('markupInserter DOMContentLoaded auto-attach running');
|
||||||
|
// Attach to explicit placeholders
|
||||||
document.querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){
|
document.querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){
|
||||||
// find next textarea sibling
|
|
||||||
let ta = ph.nextElementSibling;
|
let ta = ph.nextElementSibling;
|
||||||
if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta);
|
if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Also auto-init for common case textarea names to cover full-page forms
|
||||||
|
try{ initForNames(['description','history','discussion','report','notes']); }catch(e){}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('htmx:afterSwap', function(evt){
|
document.addEventListener('htmx:afterSwap', function(evt){
|
||||||
|
console.log('markupInserter htmx:afterSwap event', evt && evt.detail && evt.detail.target);
|
||||||
try{
|
try{
|
||||||
const target = evt.detail && evt.detail.target ? evt.detail.target : document;
|
const target = evt.detail && evt.detail.target ? evt.detail.target : document;
|
||||||
(target.querySelectorAll ? target : document).querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){
|
(target.querySelectorAll ? target : document).querySelectorAll('.markup-toolbar-placeholder').forEach(function(ph){
|
||||||
let ta = ph.nextElementSibling;
|
let ta = ph.nextElementSibling;
|
||||||
if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta);
|
if(ta && ta.tagName === 'TEXTAREA') attachToolbarToTextarea(ta);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Also attach to any textareas within the swapped target that match our common names
|
||||||
|
var ctx = evt.detail && evt.detail.target ? evt.detail.target : document;
|
||||||
|
['description','history','discussion','report','notes'].forEach(function(name){
|
||||||
|
ctx.querySelectorAll && ctx.querySelectorAll('textarea[name="'+name+'"]') && ctx.querySelectorAll('textarea[name="'+name+'"]').forEach(function(ta){ attachToolbarToTextarea(ta); });
|
||||||
|
});
|
||||||
}catch(e){/* ignore */}
|
}catch(e){/* ignore */}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Fallback: attach toolbar when a textarea receives focus (covers dynamically created editors)
|
||||||
|
document.addEventListener('focusin', function(e){
|
||||||
|
console.log('markupInserter focusin event for', e && e.target);
|
||||||
|
try{
|
||||||
|
var el = e.target;
|
||||||
|
if(!el || el.tagName !== 'TEXTAREA') return;
|
||||||
|
// Attach for common names or if a placeholder is present
|
||||||
|
var name = el.getAttribute('name') || '';
|
||||||
|
if(['description','history','discussion','report','notes'].includes(name) || (el.previousElementSibling && el.previousElementSibling.classList && el.previousElementSibling.classList.contains('markup-toolbar-placeholder'))){
|
||||||
|
attachToolbarToTextarea(el);
|
||||||
|
}
|
||||||
|
}catch(err){/* ignore */}
|
||||||
|
}, true);
|
||||||
|
|
||||||
// Expose API
|
// Expose API
|
||||||
global.markupInserter = {
|
global.markupInserter = {
|
||||||
attachToolbarToTextarea: attachToolbarToTextarea,
|
attachToolbarToTextarea: attachToolbarToTextarea,
|
||||||
|
|||||||
Reference in New Issue
Block a user