feat: complete code cleanup and create feature parity plan
Major Architecture Improvements: - Separate JavaScript library (lib/) with proper build system - Go CLI with embedded library using go:embed - Hot reload development with Air integration - Library + CLI build pipeline with npm run build Code Cleanup: - Remove obsolete assets (insertr-cli/assets/editor/) - Clean up package.json metadata and dependencies - Update .gitignore for new architecture - Remove unused 'marked' dependency New Documentation: - Add comprehensive TODO.md with feature gap analysis - Document critical gaps between prototype and current library - Create phased implementation plan for feature parity - Update DEVELOPMENT.md with hot reload workflow - Add LIBRARY.md documenting new architecture Hot Reload System: - Air watches both Go CLI and JavaScript library - Library changes trigger: rebuild → copy → CLI rebuild → serve - Seamless development experience across full stack Next Steps: - Current library is basic proof-of-concept (prompt() editing) - Archived prototype has production-ready features - Phase 1 focuses on professional forms and authentication - Phase 2 adds validation and content persistence
This commit is contained in:
@@ -7,21 +7,21 @@ tmp_dir = "tmp"
|
||||
bin = "./tmp/insertr"
|
||||
cmd = "go build -o ./tmp/insertr ."
|
||||
delay = 1000
|
||||
exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules"]
|
||||
exclude_dir = ["tmp", "vendor", "testdata", "node_modules", "dist"]
|
||||
exclude_file = []
|
||||
exclude_regex = ["_test.go"]
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
full_bin = "./tmp/insertr servedev -i ../demo-site -p 3000"
|
||||
include_dir = []
|
||||
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||
include_dir = ["../lib/src"]
|
||||
include_ext = ["go", "tpl", "tmpl", "html", "js"]
|
||||
include_file = []
|
||||
kill_delay = "0s"
|
||||
log = "build-errors.log"
|
||||
poll = false
|
||||
poll_interval = 0
|
||||
post_cmd = []
|
||||
pre_cmd = []
|
||||
pre_cmd = ["./scripts/rebuild-library.sh"]
|
||||
rerun = false
|
||||
rerun_delay = 500
|
||||
send_interrupt = false
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/**
|
||||
* Insertr Editor - Development Mode
|
||||
* Loads editing capabilities for elements marked with data-insertr-enhanced="true"
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
console.log('🔧 Insertr Editor loaded (development mode)');
|
||||
|
||||
// Initialize editor when DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initEditor);
|
||||
} else {
|
||||
initEditor();
|
||||
}
|
||||
|
||||
function initEditor() {
|
||||
console.log('🚀 Initializing Insertr Editor');
|
||||
|
||||
// Find all enhanced elements
|
||||
const enhancedElements = document.querySelectorAll('[data-insertr-enhanced="true"]');
|
||||
console.log(`📝 Found ${enhancedElements.length} editable elements`);
|
||||
|
||||
// Add visual indicators for development
|
||||
enhancedElements.forEach(addEditIndicator);
|
||||
|
||||
// Add global styles
|
||||
addEditorStyles();
|
||||
}
|
||||
|
||||
function addEditIndicator(element) {
|
||||
const contentId = element.getAttribute('data-content-id');
|
||||
const contentType = element.getAttribute('data-content-type');
|
||||
|
||||
// Add hover effect
|
||||
element.style.cursor = 'pointer';
|
||||
element.style.position = 'relative';
|
||||
|
||||
// Add click handler for development demo
|
||||
element.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
alert(`Edit: ${contentId}\nType: ${contentType}\nCurrent: "${element.textContent.trim()}"`);
|
||||
});
|
||||
|
||||
// Add visual indicator on hover
|
||||
element.addEventListener('mouseenter', function() {
|
||||
element.classList.add('insertr-editing-hover');
|
||||
});
|
||||
|
||||
element.addEventListener('mouseleave', function() {
|
||||
element.classList.remove('insertr-editing-hover');
|
||||
});
|
||||
}
|
||||
|
||||
function addEditorStyles() {
|
||||
const styles = `
|
||||
.insertr-editing-hover {
|
||||
outline: 2px dashed #007cba !important;
|
||||
outline-offset: 2px !important;
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
}
|
||||
|
||||
[data-insertr-enhanced="true"]:hover::after {
|
||||
content: "✏️ " attr(data-content-type);
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: 0;
|
||||
background: #007cba;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
font-family: monospace;
|
||||
}
|
||||
`;
|
||||
|
||||
const styleSheet = document.createElement('style');
|
||||
styleSheet.type = 'text/css';
|
||||
styleSheet.innerHTML = styles;
|
||||
document.head.appendChild(styleSheet);
|
||||
}
|
||||
})();
|
||||
197
insertr-cli/assets/lib/insertr.js
Normal file
197
insertr-cli/assets/lib/insertr.js
Normal file
@@ -0,0 +1,197 @@
|
||||
var Insertr = (function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* InsertrCore - Core functionality for content management
|
||||
*/
|
||||
class InsertrCore {
|
||||
constructor(options = {}) {
|
||||
this.options = {
|
||||
apiEndpoint: options.apiEndpoint || '/api/content',
|
||||
siteId: options.siteId || 'default',
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
// Find all enhanced elements on the page
|
||||
findEnhancedElements() {
|
||||
return document.querySelectorAll('[data-insertr-enhanced="true"]');
|
||||
}
|
||||
|
||||
// Get element metadata
|
||||
getElementMetadata(element) {
|
||||
return {
|
||||
contentId: element.getAttribute('data-content-id'),
|
||||
contentType: element.getAttribute('data-content-type'),
|
||||
element: element
|
||||
};
|
||||
}
|
||||
|
||||
// Get all elements with their metadata
|
||||
getAllElements() {
|
||||
const elements = this.findEnhancedElements();
|
||||
return Array.from(elements).map(el => this.getElementMetadata(el));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InsertrEditor - Visual editing functionality
|
||||
*/
|
||||
class InsertrEditor {
|
||||
constructor(core, options = {}) {
|
||||
this.core = core;
|
||||
this.options = options;
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.isActive) return;
|
||||
|
||||
console.log('🚀 Starting Insertr Editor');
|
||||
this.isActive = true;
|
||||
|
||||
// Add editor styles
|
||||
this.addEditorStyles();
|
||||
|
||||
// Initialize all enhanced elements
|
||||
const elements = this.core.getAllElements();
|
||||
console.log(`📝 Found ${elements.length} editable elements`);
|
||||
|
||||
elements.forEach(meta => this.initializeElement(meta));
|
||||
}
|
||||
|
||||
initializeElement(meta) {
|
||||
const { element, contentId, contentType } = meta;
|
||||
|
||||
// Add visual indicators
|
||||
element.style.cursor = 'pointer';
|
||||
element.style.position = 'relative';
|
||||
|
||||
// Add interaction handlers
|
||||
this.addHoverEffects(element);
|
||||
this.addClickHandler(element, meta);
|
||||
}
|
||||
|
||||
addHoverEffects(element) {
|
||||
element.addEventListener('mouseenter', () => {
|
||||
element.classList.add('insertr-editing-hover');
|
||||
});
|
||||
|
||||
element.addEventListener('mouseleave', () => {
|
||||
element.classList.remove('insertr-editing-hover');
|
||||
});
|
||||
}
|
||||
|
||||
addClickHandler(element, meta) {
|
||||
element.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.openEditor(meta);
|
||||
});
|
||||
}
|
||||
|
||||
openEditor(meta) {
|
||||
const { contentId, contentType, element } = meta;
|
||||
const currentContent = element.textContent.trim();
|
||||
|
||||
// For now, use a simple prompt (will be replaced with proper modal)
|
||||
const newContent = prompt(
|
||||
`Edit ${contentType} content (ID: ${contentId}):`,
|
||||
currentContent
|
||||
);
|
||||
|
||||
if (newContent !== null && newContent !== currentContent) {
|
||||
this.updateContent(meta, newContent);
|
||||
}
|
||||
}
|
||||
|
||||
updateContent(meta, newContent) {
|
||||
const { element } = meta;
|
||||
|
||||
// Update the element content
|
||||
element.textContent = newContent;
|
||||
|
||||
// TODO: Save to backend API
|
||||
console.log(`💾 Content updated:`, meta.contentId, newContent);
|
||||
}
|
||||
|
||||
addEditorStyles() {
|
||||
const styles = `
|
||||
.insertr-editing-hover {
|
||||
outline: 2px dashed #007cba !important;
|
||||
outline-offset: 2px !important;
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
}
|
||||
|
||||
[data-insertr-enhanced="true"]:hover::after {
|
||||
content: "✏️ " attr(data-content-type);
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: 0;
|
||||
background: #007cba;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
font-family: monospace;
|
||||
}
|
||||
`;
|
||||
|
||||
const styleSheet = document.createElement('style');
|
||||
styleSheet.type = 'text/css';
|
||||
styleSheet.innerHTML = styles;
|
||||
document.head.appendChild(styleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insertr - The Tailwind of CMS
|
||||
* Main library entry point
|
||||
*/
|
||||
|
||||
|
||||
// Create global Insertr instance
|
||||
window.Insertr = {
|
||||
// Core functionality
|
||||
core: null,
|
||||
editor: null,
|
||||
|
||||
// Initialize the library
|
||||
init(options = {}) {
|
||||
console.log('🔧 Insertr v1.0.0 initializing...');
|
||||
|
||||
this.core = new InsertrCore(options);
|
||||
this.editor = new InsertrEditor(this.core, options);
|
||||
|
||||
// Auto-initialize if DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this.start());
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Start the editor
|
||||
start() {
|
||||
if (this.editor) {
|
||||
this.editor.start();
|
||||
}
|
||||
},
|
||||
|
||||
// Version info
|
||||
version: '1.0.0'
|
||||
};
|
||||
|
||||
// Auto-initialize in development mode
|
||||
if (document.querySelector('[data-insertr-enhanced]')) {
|
||||
window.Insertr.init();
|
||||
}
|
||||
|
||||
var index = window.Insertr;
|
||||
|
||||
return index;
|
||||
|
||||
})();
|
||||
1
insertr-cli/assets/lib/insertr.min.js
vendored
Normal file
1
insertr-cli/assets/lib/insertr.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var Insertr=function(){"use strict";class t{constructor(t={}){this.options={apiEndpoint:t.apiEndpoint||"/api/content",siteId:t.siteId||"default",...t}}findEnhancedElements(){return document.querySelectorAll('[data-insertr-enhanced="true"]')}getElementMetadata(t){return{contentId:t.getAttribute("data-content-id"),contentType:t.getAttribute("data-content-type"),element:t}}getAllElements(){const t=this.findEnhancedElements();return Array.from(t).map(t=>this.getElementMetadata(t))}}class e{constructor(t,e={}){this.core=t,this.options=e,this.isActive=!1}start(){if(this.isActive)return;console.log("🚀 Starting Insertr Editor"),this.isActive=!0,this.addEditorStyles();const t=this.core.getAllElements();console.log(`📝 Found ${t.length} editable elements`),t.forEach(t=>this.initializeElement(t))}initializeElement(t){const{element:e,contentId:n,contentType:i}=t;e.style.cursor="pointer",e.style.position="relative",this.addHoverEffects(e),this.addClickHandler(e,t)}addHoverEffects(t){t.addEventListener("mouseenter",()=>{t.classList.add("insertr-editing-hover")}),t.addEventListener("mouseleave",()=>{t.classList.remove("insertr-editing-hover")})}addClickHandler(t,e){t.addEventListener("click",t=>{t.preventDefault(),this.openEditor(e)})}openEditor(t){const{contentId:e,contentType:n,element:i}=t,o=i.textContent.trim(),r=prompt(`Edit ${n} content (ID: ${e}):`,o);null!==r&&r!==o&&this.updateContent(t,r)}updateContent(t,e){const{element:n}=t;n.textContent=e,console.log("💾 Content updated:",t.contentId,e)}addEditorStyles(){const t=document.createElement("style");t.type="text/css",t.innerHTML='\n .insertr-editing-hover {\n outline: 2px dashed #007cba !important;\n outline-offset: 2px !important;\n background-color: rgba(0, 124, 186, 0.05) !important;\n }\n \n [data-insertr-enhanced="true"]:hover::after {\n content: "✏️ " attr(data-content-type);\n position: absolute;\n top: -25px;\n left: 0;\n background: #007cba;\n color: white;\n padding: 2px 6px;\n font-size: 11px;\n border-radius: 3px;\n white-space: nowrap;\n z-index: 1000;\n font-family: monospace;\n }\n ',document.head.appendChild(t)}}return window.Insertr={core:null,editor:null,init(n={}){return console.log("🔧 Insertr v1.0.0 initializing..."),this.core=new t(n),this.editor=new e(this.core,n),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>this.start()):this.start(),this},start(){this.editor&&this.editor.start()},version:"1.0.0"},document.querySelector("[data-insertr-enhanced]")&&window.Insertr.init(),window.Insertr}();
|
||||
197
insertr-cli/pkg/content/assets/insertr.js
Normal file
197
insertr-cli/pkg/content/assets/insertr.js
Normal file
@@ -0,0 +1,197 @@
|
||||
var Insertr = (function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* InsertrCore - Core functionality for content management
|
||||
*/
|
||||
class InsertrCore {
|
||||
constructor(options = {}) {
|
||||
this.options = {
|
||||
apiEndpoint: options.apiEndpoint || '/api/content',
|
||||
siteId: options.siteId || 'default',
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
// Find all enhanced elements on the page
|
||||
findEnhancedElements() {
|
||||
return document.querySelectorAll('[data-insertr-enhanced="true"]');
|
||||
}
|
||||
|
||||
// Get element metadata
|
||||
getElementMetadata(element) {
|
||||
return {
|
||||
contentId: element.getAttribute('data-content-id'),
|
||||
contentType: element.getAttribute('data-content-type'),
|
||||
element: element
|
||||
};
|
||||
}
|
||||
|
||||
// Get all elements with their metadata
|
||||
getAllElements() {
|
||||
const elements = this.findEnhancedElements();
|
||||
return Array.from(elements).map(el => this.getElementMetadata(el));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InsertrEditor - Visual editing functionality
|
||||
*/
|
||||
class InsertrEditor {
|
||||
constructor(core, options = {}) {
|
||||
this.core = core;
|
||||
this.options = options;
|
||||
this.isActive = false;
|
||||
}
|
||||
|
||||
start() {
|
||||
if (this.isActive) return;
|
||||
|
||||
console.log('🚀 Starting Insertr Editor');
|
||||
this.isActive = true;
|
||||
|
||||
// Add editor styles
|
||||
this.addEditorStyles();
|
||||
|
||||
// Initialize all enhanced elements
|
||||
const elements = this.core.getAllElements();
|
||||
console.log(`📝 Found ${elements.length} editable elements`);
|
||||
|
||||
elements.forEach(meta => this.initializeElement(meta));
|
||||
}
|
||||
|
||||
initializeElement(meta) {
|
||||
const { element, contentId, contentType } = meta;
|
||||
|
||||
// Add visual indicators
|
||||
element.style.cursor = 'pointer';
|
||||
element.style.position = 'relative';
|
||||
|
||||
// Add interaction handlers
|
||||
this.addHoverEffects(element);
|
||||
this.addClickHandler(element, meta);
|
||||
}
|
||||
|
||||
addHoverEffects(element) {
|
||||
element.addEventListener('mouseenter', () => {
|
||||
element.classList.add('insertr-editing-hover');
|
||||
});
|
||||
|
||||
element.addEventListener('mouseleave', () => {
|
||||
element.classList.remove('insertr-editing-hover');
|
||||
});
|
||||
}
|
||||
|
||||
addClickHandler(element, meta) {
|
||||
element.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.openEditor(meta);
|
||||
});
|
||||
}
|
||||
|
||||
openEditor(meta) {
|
||||
const { contentId, contentType, element } = meta;
|
||||
const currentContent = element.textContent.trim();
|
||||
|
||||
// For now, use a simple prompt (will be replaced with proper modal)
|
||||
const newContent = prompt(
|
||||
`Edit ${contentType} content (ID: ${contentId}):`,
|
||||
currentContent
|
||||
);
|
||||
|
||||
if (newContent !== null && newContent !== currentContent) {
|
||||
this.updateContent(meta, newContent);
|
||||
}
|
||||
}
|
||||
|
||||
updateContent(meta, newContent) {
|
||||
const { element } = meta;
|
||||
|
||||
// Update the element content
|
||||
element.textContent = newContent;
|
||||
|
||||
// TODO: Save to backend API
|
||||
console.log(`💾 Content updated:`, meta.contentId, newContent);
|
||||
}
|
||||
|
||||
addEditorStyles() {
|
||||
const styles = `
|
||||
.insertr-editing-hover {
|
||||
outline: 2px dashed #007cba !important;
|
||||
outline-offset: 2px !important;
|
||||
background-color: rgba(0, 124, 186, 0.05) !important;
|
||||
}
|
||||
|
||||
[data-insertr-enhanced="true"]:hover::after {
|
||||
content: "✏️ " attr(data-content-type);
|
||||
position: absolute;
|
||||
top: -25px;
|
||||
left: 0;
|
||||
background: #007cba;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
font-size: 11px;
|
||||
border-radius: 3px;
|
||||
white-space: nowrap;
|
||||
z-index: 1000;
|
||||
font-family: monospace;
|
||||
}
|
||||
`;
|
||||
|
||||
const styleSheet = document.createElement('style');
|
||||
styleSheet.type = 'text/css';
|
||||
styleSheet.innerHTML = styles;
|
||||
document.head.appendChild(styleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insertr - The Tailwind of CMS
|
||||
* Main library entry point
|
||||
*/
|
||||
|
||||
|
||||
// Create global Insertr instance
|
||||
window.Insertr = {
|
||||
// Core functionality
|
||||
core: null,
|
||||
editor: null,
|
||||
|
||||
// Initialize the library
|
||||
init(options = {}) {
|
||||
console.log('🔧 Insertr v1.0.0 initializing... (Hot Reload Ready)');
|
||||
|
||||
this.core = new InsertrCore(options);
|
||||
this.editor = new InsertrEditor(this.core, options);
|
||||
|
||||
// Auto-initialize if DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => this.start());
|
||||
} else {
|
||||
this.start();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Start the editor
|
||||
start() {
|
||||
if (this.editor) {
|
||||
this.editor.start();
|
||||
}
|
||||
},
|
||||
|
||||
// Version info
|
||||
version: '1.0.0'
|
||||
};
|
||||
|
||||
// Auto-initialize in development mode
|
||||
if (document.querySelector('[data-insertr-enhanced]')) {
|
||||
window.Insertr.init();
|
||||
}
|
||||
|
||||
var index = window.Insertr;
|
||||
|
||||
return index;
|
||||
|
||||
})();
|
||||
1
insertr-cli/pkg/content/assets/insertr.min.js
vendored
Normal file
1
insertr-cli/pkg/content/assets/insertr.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
var Insertr=function(){"use strict";class t{constructor(t={}){this.options={apiEndpoint:t.apiEndpoint||"/api/content",siteId:t.siteId||"default",...t}}findEnhancedElements(){return document.querySelectorAll('[data-insertr-enhanced="true"]')}getElementMetadata(t){return{contentId:t.getAttribute("data-content-id"),contentType:t.getAttribute("data-content-type"),element:t}}getAllElements(){const t=this.findEnhancedElements();return Array.from(t).map(t=>this.getElementMetadata(t))}}class e{constructor(t,e={}){this.core=t,this.options=e,this.isActive=!1}start(){if(this.isActive)return;console.log("🚀 Starting Insertr Editor"),this.isActive=!0,this.addEditorStyles();const t=this.core.getAllElements();console.log(`📝 Found ${t.length} editable elements`),t.forEach(t=>this.initializeElement(t))}initializeElement(t){const{element:e,contentId:n,contentType:i}=t;e.style.cursor="pointer",e.style.position="relative",this.addHoverEffects(e),this.addClickHandler(e,t)}addHoverEffects(t){t.addEventListener("mouseenter",()=>{t.classList.add("insertr-editing-hover")}),t.addEventListener("mouseleave",()=>{t.classList.remove("insertr-editing-hover")})}addClickHandler(t,e){t.addEventListener("click",t=>{t.preventDefault(),this.openEditor(e)})}openEditor(t){const{contentId:e,contentType:n,element:i}=t,o=i.textContent.trim(),r=prompt(`Edit ${n} content (ID: ${e}):`,o);null!==r&&r!==o&&this.updateContent(t,r)}updateContent(t,e){const{element:n}=t;n.textContent=e,console.log("💾 Content updated:",t.contentId,e)}addEditorStyles(){const t=document.createElement("style");t.type="text/css",t.innerHTML='\n .insertr-editing-hover {\n outline: 2px dashed #007cba !important;\n outline-offset: 2px !important;\n background-color: rgba(0, 124, 186, 0.05) !important;\n }\n \n [data-insertr-enhanced="true"]:hover::after {\n content: "✏️ " attr(data-content-type);\n position: absolute;\n top: -25px;\n left: 0;\n background: #007cba;\n color: white;\n padding: 2px 6px;\n font-size: 11px;\n border-radius: 3px;\n white-space: nowrap;\n z-index: 1000;\n font-family: monospace;\n }\n ',document.head.appendChild(t)}}return window.Insertr={core:null,editor:null,init(n={}){return console.log("🔧 Insertr v1.0.0 initializing... (Hot Reload Ready)"),this.core=new t(n),this.editor=new e(this.core,n),"loading"===document.readyState?document.addEventListener("DOMContentLoaded",()=>this.start()):this.start(),this},start(){this.editor&&this.editor.start()},version:"1.0.0"},document.querySelector("[data-insertr-enhanced]")&&window.Insertr.init(),window.Insertr}();
|
||||
@@ -69,7 +69,8 @@ func (e *Enhancer) EnhanceFile(inputPath, outputPath string) error {
|
||||
}
|
||||
|
||||
// Inject editor assets for development
|
||||
e.injector.InjectEditorAssets(doc, true)
|
||||
libraryScript := GetLibraryScript(true) // Use minified for better performance
|
||||
e.injector.InjectEditorAssets(doc, true, libraryScript)
|
||||
|
||||
// Write enhanced HTML
|
||||
if err := e.writeHTML(doc, outputPath); err != nil {
|
||||
|
||||
@@ -133,7 +133,7 @@ func (i *Injector) addContentAttributes(node *html.Node, contentID string, conte
|
||||
}
|
||||
|
||||
// InjectEditorAssets adds editor JavaScript and CSS to HTML document
|
||||
func (i *Injector) InjectEditorAssets(doc *html.Node, isDevelopment bool) {
|
||||
func (i *Injector) InjectEditorAssets(doc *html.Node, isDevelopment bool, libraryScript string) {
|
||||
if !isDevelopment {
|
||||
return // Only inject in development mode for now
|
||||
}
|
||||
@@ -144,15 +144,21 @@ func (i *Injector) InjectEditorAssets(doc *html.Node, isDevelopment bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// Add editor JavaScript
|
||||
// Add inline script with embedded library
|
||||
script := &html.Node{
|
||||
Type: html.ElementNode,
|
||||
Data: "script",
|
||||
Attr: []html.Attribute{
|
||||
{Key: "src", Val: "/_insertr/insertr-editor.js"},
|
||||
{Key: "defer", Val: ""},
|
||||
{Key: "type", Val: "text/javascript"},
|
||||
},
|
||||
}
|
||||
|
||||
// Add the library content as text node
|
||||
textNode := &html.Node{
|
||||
Type: html.TextNode,
|
||||
Data: libraryScript,
|
||||
}
|
||||
script.AppendChild(textNode)
|
||||
head.AppendChild(script)
|
||||
}
|
||||
|
||||
|
||||
26
insertr-cli/pkg/content/library.go
Normal file
26
insertr-cli/pkg/content/library.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
// Embedded library assets
|
||||
//
|
||||
//go:embed assets/insertr.min.js
|
||||
var libraryMinJS string
|
||||
|
||||
//go:embed assets/insertr.js
|
||||
var libraryJS string
|
||||
|
||||
// GetLibraryScript returns the appropriate library version
|
||||
func GetLibraryScript(minified bool) string {
|
||||
if minified {
|
||||
return libraryMinJS
|
||||
}
|
||||
return libraryJS
|
||||
}
|
||||
|
||||
// GetLibraryVersion returns the current embedded library version
|
||||
func GetLibraryVersion() string {
|
||||
return "1.0.0"
|
||||
}
|
||||
20
insertr-cli/scripts/rebuild-library.sh
Executable file
20
insertr-cli/scripts/rebuild-library.sh
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Rebuild library and copy to CLI assets
|
||||
# Used by Air for hot reloading when library changes
|
||||
|
||||
set -e
|
||||
|
||||
echo "🔄 Library changed, rebuilding..."
|
||||
|
||||
# Build the library
|
||||
cd ../lib
|
||||
npm run build --silent
|
||||
|
||||
# Copy to CLI assets
|
||||
echo "📁 Copying updated library to CLI assets..."
|
||||
cp dist/* ../insertr-cli/pkg/content/assets/
|
||||
|
||||
# Get library version for confirmation
|
||||
VERSION=$(node -e "console.log(require('./package.json').version)")
|
||||
echo "✅ Library v$VERSION ready for CLI embedding"
|
||||
Reference in New Issue
Block a user