feat: reorganize builder
This commit is contained in:
parent
ff7bb041ef
commit
362b7aa15e
18 changed files with 1094 additions and 310 deletions
88
lib/utils/LinkProcessor.js
Normal file
88
lib/utils/LinkProcessor.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* LinkProcessor provides utilities for processing link elements.
|
||||
*/
|
||||
class LinkProcessor {
|
||||
/**
|
||||
* Creates a new link processor instance.
|
||||
* @param {Object} [options] - Options object
|
||||
* @param {boolean} [options.debug=false] - Enable debug logging
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
this.options = {
|
||||
debug: false,
|
||||
...options,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a link node and extracts the href attribute.
|
||||
* Converts to an internal link if it doesn't start with http:// or https://.
|
||||
*
|
||||
* @param {Object} node - The link node to process
|
||||
* @returns {Object} - An object containing link properties
|
||||
*/
|
||||
processLink(node) {
|
||||
if (this.options.debug) {
|
||||
console.log("\n[LinkProcessor] Processing link node");
|
||||
}
|
||||
|
||||
const hrefProp = node.props.find((p) => p.startsWith("href:"));
|
||||
let href = "#";
|
||||
|
||||
if (hrefProp) {
|
||||
let hrefTarget = hrefProp
|
||||
.substring(hrefProp.indexOf(":") + 1)
|
||||
.trim()
|
||||
.replace(/^"|"$/g, "");
|
||||
|
||||
if (!hrefTarget.startsWith("http://") && !hrefTarget.startsWith("https://")) {
|
||||
hrefTarget = "/" + hrefTarget;
|
||||
if (this.options.debug) {
|
||||
console.log(`[LinkProcessor] Converted to internal link: "${hrefTarget}"`);
|
||||
}
|
||||
} else {
|
||||
if (this.options.debug) {
|
||||
console.log(`[LinkProcessor] External link detected: "${hrefTarget}"`);
|
||||
}
|
||||
}
|
||||
href = hrefTarget;
|
||||
} else {
|
||||
if (this.options.debug) {
|
||||
console.log("[LinkProcessor] No href property found, using default: '#'");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
href,
|
||||
isExternal: href.startsWith("http://") || href.startsWith("https://")
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets appropriate HTML attributes for a link based on its type
|
||||
* @param {Object} linkInfo - Link information object
|
||||
* @returns {string} - HTML attributes for the link
|
||||
*/
|
||||
getLinkAttributes(linkInfo) {
|
||||
if (linkInfo.isExternal) {
|
||||
return ` href="${linkInfo.href}" target="_blank" rel="noopener noreferrer"`;
|
||||
} else {
|
||||
return ` href="${linkInfo.href}"`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the click handler for a button inside a link
|
||||
* @param {Object} linkInfo - Link information object
|
||||
* @returns {string} - onclick attribute value
|
||||
*/
|
||||
getButtonClickHandler(linkInfo) {
|
||||
if (linkInfo.isExternal) {
|
||||
return ` onclick="window.open('${linkInfo.href}', '_blank', 'noopener,noreferrer')"`;
|
||||
} else {
|
||||
return ` onclick="window.location.href='${linkInfo.href}'"`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LinkProcessor;
|
59
lib/utils/StringUtils.js
Normal file
59
lib/utils/StringUtils.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Utilities for string operations used throughout the Blueprint compiler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Escapes special HTML characters in a string to prevent XSS attacks.
|
||||
* @param {string} text - The text to escape
|
||||
* @returns {string} - The escaped text
|
||||
*/
|
||||
const escapeHTML = (text) => {
|
||||
return text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a camelCase string to kebab-case (lowercase with hyphens).
|
||||
* @param {string} str - The string to convert
|
||||
* @returns {string} - The converted string
|
||||
*/
|
||||
const toKebabCase = (str) => {
|
||||
return str.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
||||
};
|
||||
|
||||
/**
|
||||
* Stringify an object while handling circular references.
|
||||
* @param {Object} obj - The object to stringify
|
||||
* @returns {string} - JSON string representation
|
||||
*/
|
||||
const safeStringify = (obj) => {
|
||||
const getCircularReplacer = () => {
|
||||
const seen = new WeakSet();
|
||||
return (key, value) => {
|
||||
if (key === "parent") return "[Circular:Parent]";
|
||||
if (typeof value === "object" && value !== null) {
|
||||
if (seen.has(value)) {
|
||||
return "[Circular]";
|
||||
}
|
||||
seen.add(value);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
return JSON.stringify(obj, getCircularReplacer(), 2);
|
||||
} catch (err) {
|
||||
return `[Unable to stringify: ${err.message}]`;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
escapeHTML,
|
||||
toKebabCase,
|
||||
safeStringify
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue