Skip to content

Instantly share code, notes, and snippets.

@josecanciani
Last active February 1, 2023 17:20
Show Gist options
  • Save josecanciani/faca999e992f343c3c97269be664466f to your computer and use it in GitHub Desktop.
Save josecanciani/faca999e992f343c3c97269be664466f to your computer and use it in GitHub Desktop.
[DEPRECATED] DNA Markdown support
// ==UserScript==
// @name [DEPRECATED] DNA Markdown support
// @namespace https://github.com/josecanciani
// @match https://*.avature.net/DNA/*
// @match https://*.avature.net/_DNA/*
// @version 17
// @deprecated Since DNA now supports Markdown, this script is useless
// @updateURL https://gist.githubusercontent.com/josecanciani/faca999e992f343c3c97269be664466f/raw/dna-markdown.user.js
// @downloadURL https://gist.githubusercontent.com/josecanciani/faca999e992f343c3c97269be664466f/raw/dna-markdown.user.js
// @author Jose Luis Canciani
// @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
// @description This script will search multiline texts (in DNA posts) and transform them assuming it's Markdown code.
// @grant GM_addStyle
// @grant GM_getResourceText
// @require https://cdnjs.cloudflare.com/ajax/libs/markdown-it/11.0.0/markdown-it.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/bash.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/dart.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/dockerfile.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/go.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/java.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/javascript.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/json.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/markdown.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/nginx.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/php.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/plaintext.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/puppet.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/shell.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/sql.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/twig.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/typescript.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/xml.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/languages/yaml.min.js
// @resource highlightCSS https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/styles/vs2015.min.css
// @resource markdownCSS https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css
// ==/UserScript==
(function() {
var MyMutationObserver =
this.MutationObserver ||
this.WebKitMutationObserver ||
(
window ? window.MutationObserver || window.WebKitMutationObserver :
null);
if (!MyMutationObserver) {
console.log('MutationObserver not found, disabling Avature Markdown plugin');
return;
}
var listeners = [];
var observer;
// add default styles for markdown and code highlighting
GM_addStyle('.social_message_text_Plain .social_mobile_message_Text_TextPreWrap.markdown-body { white-space: normal; }');
GM_addStyle('.social_message_text_Plain .social_mobile_message_Text_TextPreWrap.markdown-body { white-space: normal; }');
GM_addStyle(
GM_getResourceText('markdownCSS')
.replace(/font\-size\:16px/g, 'font-size:14px')
.replace(/line\-height\:1.5/g, 'line-height:1.4')
.replace(
'font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;',
''
)
.replace(/color\:#[a-zA-Z0-9]+\}/g, '}')
.replace(/color\:#[a-zA-Z0-9]+;/g, '')
//.replace(/margin\-bottom\:16px/g, 'margin-bottom:10px')
//.replace(/margin\-bottom\:10px/g, 'margin-bottom:8px')
//.replace(/margin\-top\:24px/g, 'margin-top:12px')
//.replace(/padding\-left\:2em;/g, 'padding-left:1em;')
.replace(/;/g, ' !important;')
.replace(/}/g, ' !important;}')
);
GM_addStyle(GM_getResourceText('highlightCSS').replace(/;/g, ' !important;').replace(/}/g, ' !important;}'));
// init markdown converter
var md = new markdownit({
breaks: true,
linkify: true,
typographer: true,
highlight: function(str, lang) {
if (lang && hljs.getLanguage(lang)) {
try {
return '<pre class="hljs"><code>' + hljs.highlight(lang, str).value + '</code></pre>';
} catch (__) {
console.log('hljs.highlightAuto Error for lang ' + lang + ': ' + __);
}
}
try {
return '<pre class="hljs"><code>' + hljs.highlightAuto(str).value + '</code></pre>';
} catch (__) {
console.log('hljs.highlightAuto Error: ' + __);
}
return '<pre class="hljs"><code>' + md.utils.escapeHtml(str) + '</code></pre>';
}
});
// functions to obsert dom changes
function observeSelector(selector, fn) {
// Store the selector and callback to be monitored
listeners.push({
selector: selector,
fn: fn
});
if (!observer) {
// Watch for changes in the document
observer = new MyMutationObserver(check);
observer.observe(window.document.documentElement, {
childList: true,
subtree: true
});
}
// Check if the element is currently in the DOM
check();
}
function check() {
// Check the DOM for elements matching a stored selector
for (var i = 0, len = listeners.length, listener, elements; i < len; i++) {
listener = listeners[i];
// Query for elements matching the specified selector
elements = window.document.querySelectorAll(listener.selector);
for (var j = 0, jLen = elements.length, element; j < jLen; j++) {
element = elements[j];
// Make sure the callback isn't invoked with the
// same element more than once
if (!element.observeSelector) {
element.observeSelector = true;
// Invoke the callback with the element
listener.fn.call(element, element);
}
}
}
}
// click "more..." button to display the full text
function toogleButton(element, searchForLessOnly) {
var button =
element.getElementsByTagName('BUTTON') ? element.getElementsByTagName('BUTTON')[0] :
null;
if (!button) {
return;
}
if (!searchForLessOnly && button.innerText.endsWith('...')) {
button.click();
button.style.display = 'none';
toogleButton(element, true);
return;
}
if (button.innerText.startsWith('...')) {
button.style.display = 'none';
}
}
// detect markdown code insde a comment
function isMarkDown(text) {
const italics = /\*(.*)\*/gim;
const bold = /\*\*(.*)\*\*/gim;
const bq = /^\> (.*$)/gim;
const h1 = /^# (.*$)/gim;
const h2 = /^## (.*$)/gim;
const h3 = /^### (.*$)/gim;
const h4 = /^#### (.*$)/gim;
const h5 = /^##### (.*$)/gim;
const image = /!\[(.*?)\]\((.*?)\)/gim;
const link = /\[(.*?)\]\((.*?)\)/gim;
const lineBreak = /\n$/gim;
if (text.match(link) || text.match(image)) {
return true;
}
let found = 0;
[italics, bold, bq, h1, h2, h3, h4, h5, lineBreak].forEach(function(regexp) { text.match(regexp) && found++; });
// avoid some false positives, require at least a couple of modifiers
return found > 1;
}
// obsert callback where magic happens
function convertMarkdown(element, useInnerText) {
// toogleButton(element);
// check if this text contains markdown code
if (!isMarkDown(useInnerText ? element.innerText : element.textContent)) {
return;
}
if (!element.observer) {
element.classList.add('markdown-body');
try {
element.innerHTML = md.render(useInnerText ? element.innerText : element.textContent);
} catch (err) {
console.log('markdownit: Error converting text to html', err);
return;
}
// Watch for changes in the document
element.observer = new MyMutationObserver(function() {
element.observer.disconnect();
element.observer = null;
convertMarkdown(element, useInnerText);
});
element.observer.observe(element, {
childList: true,
subtree: true
});
}
}
function observeForTextContent(element) {
convertMarkdown(element, false);
}
function observeForInnerText(element) {
convertMarkdown(element, true);
}
// Main script: start listening DOM insertions
// OLD TEG code: observeSelector('.schema_MultiLineTextViewerBase', observeForInnerText);
observeSelector('.social_message_text_Plain .social_mobile_message_Text_TextPreWrap', observeForTextContent);
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment