Last active
September 26, 2024 18:12
-
-
Save annibal/0a852b03d6733d21a2b217c944ef4380 to your computer and use it in GitHub Desktop.
FixColmeiaChat
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function FixColmeiaChatFactory() { | |
// Will execute the fix, at the end of this script, | |
// Will assign an object with the props and the methods: window.FixColmeiaChat, | |
// Will return the object as well. | |
var props = { | |
// config max attempts of trying to find the <colmeia-chat> element | |
retryTimeout: 600, | |
retryAttempts: 6, | |
// only for debugging, if necessary | |
isFixApplied: false, | |
fixedAt: [], | |
// configures the behavior of the event handler | |
// { [EVENT_NAME]: settings } | |
// will add and remove classes from "<div class="chat-box">", and from "<button class="main-button">". | |
// also optional flag for preventDefault | |
stateEventsData: { | |
ready: { | |
rootClsAdd: "open", | |
rootClsRemove: "", | |
btnClsAdd: "", | |
btnClsRemove: "", | |
preventsDefault: false, | |
}, | |
error: { | |
rootClsAdd: "", | |
rootClsRemove: "", | |
btnClsAdd: "", | |
btnClsRemove: "", | |
preventsDefault: false, | |
}, | |
open: { | |
rootClsAdd: "open", | |
rootClsRemove: "is-open", | |
btnClsAdd: "", | |
btnClsRemove: "", | |
preventsDefault: false, | |
}, | |
close: { | |
rootClsAdd: "", | |
rootClsRemove: "open", | |
btnClsAdd: "", | |
btnClsRemove: "is-open", | |
preventsDefault: false, | |
}, | |
restore: { | |
rootClsAdd: "open", | |
rootClsRemove: "is-open", | |
btnClsAdd: "", | |
btnClsRemove: "", | |
preventsDefault: false, | |
}, | |
minify: { | |
rootClsAdd: "", | |
rootClsRemove: "open", | |
btnClsAdd: "", | |
btnClsRemove: "is-open", | |
preventsDefault: false, | |
}, | |
}, | |
}; | |
function debugLog(logIdx, data) { | |
var logs = [ | |
// 0 | |
function (_data) { | |
return [ | |
"<colmeia-chat> not found. ", | |
"Can retry " + _data[0] + " times, ", | |
_data[1] ? "will retry in " + _data[2] + "ms" : "aborting", | |
".", | |
].join(""); | |
}, | |
// 1 | |
function (_data) { | |
return [ | |
"Found <colmeia-chat> element in the ", | |
_data[0], | |
"th attempt. ", | |
"Will apply Colmeia Chat fix.", | |
].join(""); | |
}, | |
// 2 | |
function (_data) { | |
return [ | |
"Binding listener #", | |
_data[0], | |
" to the colmeia-chat's '", | |
_data[1], | |
"' event.", | |
// "' event, which will ", | |
// _data[2] ? "Open" : "Close", | |
// " the webchat chat box.", | |
].join(""); | |
}, | |
// 3 | |
function (_data) { | |
return [ | |
"chatBox's current classList: '", | |
_data[0], | |
"', will run .add('", | |
_data[1], | |
"') then .remove('", | |
_data[2], | |
"').", | |
].join(""); | |
}, | |
// 4 | |
function (_data) { | |
return [ | |
"<colmeia-chat> already has ", | |
_data[1], | |
" listeners for '", | |
_data[0], | |
"' event, will remove all of them.", | |
].join(""); | |
}, | |
// 5 | |
function (_data) { | |
return [ | |
"Handling event '", | |
_data[0], | |
_data[1] | |
? ", Ignoring given no stateEventData exists for this event type" | |
: "", | |
".", | |
].join(""); | |
}, | |
// 6 | |
function (_data) { | |
return ["Will prevent default for event '", _data[0], "'."]; | |
}, | |
]; | |
try { | |
var logStr = logs[logIdx](data); | |
console.debug(">>: FixColmeiaChat: " + logStr); | |
} catch (e) { | |
try { | |
console.error(e); | |
} catch (e2) {} | |
} | |
} | |
function getElm_ChatRoot() { | |
return document.querySelector("colmeia-chat"); | |
} | |
function getElm_ChatBox() { | |
return getElm_ChatRoot().shadowRoot.querySelector(".chat-box"); | |
} | |
function getElm_ChatButton() { | |
return getElm_ChatRoot().shadowRoot.querySelector(".main-button"); | |
} | |
function setElementClass(elm, clsAdd, clsRemove) { | |
debugLog(3, [elm.classList, clsAdd, clsRemove]); | |
if (clsAdd) { | |
elm.classList.add(clsAdd); | |
} | |
if (clsRemove) { | |
elm.classList.remove(clsRemove); | |
} | |
} | |
// the actual fix | |
function handleColmeiaChatEvent(event) { | |
var stateEventData = props.stateEventsData[event.eventType]; | |
debugLog(5, [event.eventType, !stateEventData]); | |
if (stateEventData) { | |
setElementClass( | |
getElm_ChatBox(), | |
stateEventData.rootClsAdd, | |
stateEventData.rootClsRemove | |
); | |
setElementClass( | |
getElm_ChatButton(), | |
stateEventData.btnClsAdd, | |
stateEventData.btnClsRemove | |
); | |
if (stateEventData.preventsDefault) { | |
debugLog(6, [event.eventType]); | |
event.preventDefault(); | |
return false; | |
} | |
} | |
} | |
function applyStateEvents(eventTypes) { | |
for (var i = 0; i < eventTypes.length; i += 1) { | |
var eventType = eventTypes[i]; | |
debugLog(2, [i, eventType]); | |
var allListeners = getElm_ChatRoot().eventListeners(eventType); | |
if (allListeners.length > 0) { | |
debugLog(4, [eventType, allListeners.length]); | |
for (var j = 0; j < allListeners.length; j += 1) { | |
getElm_ChatRoot().removeEventListener(eventType, allListeners[j]); | |
} | |
} | |
getElm_ChatRoot().addEventListener(eventType, handleColmeiaChatEvent); | |
} | |
} | |
function tryToApplyFix(mRetryCount, eventTypesToFix) { | |
props.fixedAt.push({ type: "attempt", time: Date.now() }); | |
var elmChatRoot = getElm_ChatRoot(); | |
if (!elmChatRoot) { | |
var canRetry = mRetryCount > 0; | |
debugLog(0, [mRetryCount, canRetry, props.retryTimeout]); | |
if (canRetry) { | |
setTimeout(function () { | |
tryToApplyFix(mRetryCount - 1); | |
}, props.retryTimeout); | |
return; | |
} else { | |
props.fixedAt.push({ type: "fail", time: Date.now() }); | |
throw new ReferenceError( | |
"Failed to fix Colmeia Chat after " + | |
props.retryAttempts + | |
" attempts: 'colmeia-chat' element not found." | |
); | |
} | |
} | |
debugLog(1, [props.retryAttempts - mRetryCount]); | |
applyStateEvents(eventTypesToFix); | |
props.isFixApplied = true; | |
props.fixedAt.push({ type: "success", time: Date.now() }); | |
} | |
function fixTheChat(eventTypesToFix) { | |
setTimeout(function () { | |
tryToApplyFix(props.retryAttempts, eventTypesToFix); | |
}, props.retryTimeout); | |
} | |
window.FixColmeiaChat = { | |
data: props, | |
setElementClass: setElementClass, | |
handleColmeiaChatEvent: handleColmeiaChatEvent, | |
applyStateEvents: applyStateEvents, | |
tryToApplyFix: tryToApplyFix, | |
}; | |
fixTheChat(["ready", "error", "open", "close", "restore", "minify"]); | |
return window.FixColmeiaChat; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment