140 lines
4.1 KiB
JavaScript
140 lines
4.1 KiB
JavaScript
(function () {
|
|
if (window.GIAComposePanelCore) {
|
|
return;
|
|
}
|
|
|
|
const PANEL_SELECTOR = ".compose-shell[data-compose-panel='1']";
|
|
window.giaComposePanels = window.giaComposePanels || {};
|
|
|
|
const collectPanels = function (root) {
|
|
const panels = [];
|
|
if (!root) {
|
|
return panels;
|
|
}
|
|
if (root.matches && root.matches(PANEL_SELECTOR)) {
|
|
panels.push(root);
|
|
}
|
|
if (root.querySelectorAll) {
|
|
root.querySelectorAll(PANEL_SELECTOR).forEach(function (panel) {
|
|
panels.push(panel);
|
|
});
|
|
}
|
|
return panels;
|
|
};
|
|
|
|
const toInt = function (value) {
|
|
const parsed = parseInt(value || "0", 10);
|
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
};
|
|
|
|
const parseJsonSafe = function (value, fallback) {
|
|
try {
|
|
return JSON.parse(String(value || ""));
|
|
} catch (_err) {
|
|
return fallback;
|
|
}
|
|
};
|
|
|
|
const createNode = function (tagName, className, text) {
|
|
const node = document.createElement(tagName);
|
|
if (className) {
|
|
node.className = className;
|
|
}
|
|
if (text !== undefined && text !== null) {
|
|
node.textContent = String(text);
|
|
}
|
|
return node;
|
|
};
|
|
|
|
const normalizeSnippet = function (value) {
|
|
const compact = String(value || "").replace(/\s+/g, " ").trim();
|
|
if (!compact) {
|
|
return "(no text)";
|
|
}
|
|
if (compact.length <= 120) {
|
|
return compact;
|
|
}
|
|
return compact.slice(0, 117).trimEnd() + "...";
|
|
};
|
|
|
|
const titleCase = function (value) {
|
|
const raw = String(value || "").trim().toLowerCase();
|
|
if (!raw) {
|
|
return "";
|
|
}
|
|
if (raw === "whatsapp") {
|
|
return "WhatsApp";
|
|
}
|
|
if (raw === "xmpp") {
|
|
return "XMPP";
|
|
}
|
|
return raw.charAt(0).toUpperCase() + raw.slice(1);
|
|
};
|
|
|
|
const normalizeIdentifierForService = function (service, identifier) {
|
|
const serviceKey = String(service || "").trim().toLowerCase();
|
|
const raw = String(identifier || "").trim();
|
|
if (serviceKey === "whatsapp" && raw.includes("@")) {
|
|
return raw.split("@", 1)[0].trim();
|
|
}
|
|
return raw;
|
|
};
|
|
|
|
const buildComposeUrl = function (renderMode, service, identifier, personId) {
|
|
const serviceKey = String(service || "").trim().toLowerCase();
|
|
const identifierValue = normalizeIdentifierForService(serviceKey, identifier);
|
|
if (!serviceKey || !identifierValue) {
|
|
return "";
|
|
}
|
|
const params = new URLSearchParams();
|
|
params.set("service", serviceKey);
|
|
params.set("identifier", identifierValue);
|
|
if (personId) {
|
|
params.set("person", String(personId || "").trim());
|
|
}
|
|
return (renderMode === "page" ? "/compose/page/" : "/compose/widget/")
|
|
+ "?"
|
|
+ params.toString();
|
|
};
|
|
|
|
const parseServiceMap = function (optionNode) {
|
|
const fallbackService = String(
|
|
(optionNode && optionNode.dataset && optionNode.dataset.service) || ""
|
|
).trim().toLowerCase();
|
|
const fallbackIdentifier = String((optionNode && optionNode.value) || "").trim();
|
|
const fallback = {};
|
|
if (fallbackService && fallbackIdentifier) {
|
|
fallback[fallbackService] = fallbackIdentifier;
|
|
}
|
|
if (!optionNode || !optionNode.dataset) {
|
|
return fallback;
|
|
}
|
|
const parsed = parseJsonSafe(optionNode.dataset.serviceMap || "{}", fallback);
|
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
return fallback;
|
|
}
|
|
const normalized = {};
|
|
Object.keys(parsed).forEach(function (key) {
|
|
const serviceKey = String(key || "").trim().toLowerCase();
|
|
const identifierValue = String(parsed[key] || "").trim();
|
|
if (serviceKey && identifierValue) {
|
|
normalized[serviceKey] = identifierValue;
|
|
}
|
|
});
|
|
return Object.keys(normalized).length ? normalized : fallback;
|
|
};
|
|
|
|
window.GIAComposePanelCore = {
|
|
PANEL_SELECTOR: PANEL_SELECTOR,
|
|
buildComposeUrl: buildComposeUrl,
|
|
collectPanels: collectPanels,
|
|
createNode: createNode,
|
|
normalizeIdentifierForService: normalizeIdentifierForService,
|
|
normalizeSnippet: normalizeSnippet,
|
|
parseJsonSafe: parseJsonSafe,
|
|
parseServiceMap: parseServiceMap,
|
|
titleCase: titleCase,
|
|
toInt: toInt,
|
|
};
|
|
})();
|