* replace inline attribute defer with external js - show.html.erb * fix typo in filename * disable no-undef and bail if not defined * put js on subfolder utilities * refactor jsx instead of loading chunk with defer * fix typo in desc * better name for global gist helper * use InstantClick * working script on preview AND single view, not dynamic import, though * embed only if gists * combine all approaches to make dynamic import work * make gist embeds work on submit comment form * make gist embeds work on preview comment * refactor - preview comments and submit * add pack editComment + helper embedGistsInComments * comment gist helper * delete useless file utility * use new syntax for events * put code in method embedGistsInComments * delete older pack gist * handle edge case 'view full discussion' * resolve conflict with package ibm-openapi-validator * resolve conflict with package husky * empty commit to test random error travis * better name for class dismiss * handle future events submit * delete test code on click toggle form * delete unused file * rename pack as js file, not jsx * Added POC using MutationObserver. * missing case: notification page * use custom pack notification page * add e2e test for comment with embed gist * add e2e test for preview post with embed gist * add an extra step in tests to check gist is present Co-authored-by: Nick Taylor <nick@dev.to> Co-authored-by: Suzanne Aitchison <suzanne@forem.com>
74 lines
1.8 KiB
JavaScript
74 lines
1.8 KiB
JavaScript
let postscribeImport;
|
|
|
|
async function getPostScribe() {
|
|
if (postscribeImport) {
|
|
// Grab the cached import so we're not always fetching it from the network.
|
|
return postscribeImport;
|
|
}
|
|
|
|
const { default: postscribe } = await import('postscribe');
|
|
postscribeImport = postscribe;
|
|
|
|
return postscribeImport;
|
|
}
|
|
|
|
function getGistTags(nodes) {
|
|
const gistNodes = [];
|
|
|
|
for (const node of nodes) {
|
|
if (node.nodeType === 1) {
|
|
if (node.classList.contains('ltag_gist-liquid-tag')) {
|
|
gistNodes.push(node);
|
|
}
|
|
|
|
gistNodes.push(...node.querySelectorAll('.ltag_gist-liquid-tag'));
|
|
}
|
|
}
|
|
|
|
return gistNodes;
|
|
}
|
|
|
|
function loadEmbeddedGists(postscribe, gistTags) {
|
|
for (const gistTag of gistTags) {
|
|
postscribe(gistTag, gistTag.firstElementChild.outerHTML, {
|
|
beforeWrite(text) {
|
|
return gistTag.childElementCount > 3 ? '' : text;
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
function watchForGistTagInsertion(targetNode, postscribe) {
|
|
const config = { attributes: false, childList: true, subtree: true };
|
|
|
|
const callback = function (mutationsList) {
|
|
for (const { type, addedNodes } of mutationsList) {
|
|
if (type === 'childList' && addedNodes.length > 0) {
|
|
loadEmbeddedGists(postscribe, getGistTags(addedNodes));
|
|
}
|
|
}
|
|
};
|
|
|
|
const observer = new MutationObserver(callback);
|
|
observer.observe(targetNode, config);
|
|
|
|
InstantClick.on('change', () => {
|
|
observer.disconnect();
|
|
});
|
|
|
|
window.addEventListener('beforeunload', () => {
|
|
observer.disconnect();
|
|
});
|
|
}
|
|
|
|
export async function embedGists(targetNode) {
|
|
const postscribe = await getPostScribe();
|
|
|
|
// Load gist tags that were rendered server-side
|
|
loadEmbeddedGists(
|
|
postscribe,
|
|
document.querySelectorAll('.ltag_gist-liquid-tag'),
|
|
);
|
|
|
|
watchForGistTagInsertion(targetNode, postscribe);
|
|
}
|