mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
4.20.26
* Fixed: Remove console debugging. * API Added: Link embeds and tooltips now support markdown. * API Fixed: Bug when setting raw HTML while using `createElement`.
This commit is contained in:
parent
e73534dd75
commit
e87c99f206
4 changed files with 81 additions and 28 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "frankerfacez",
|
||||
"author": "Dan Salvato LLC",
|
||||
"version": "4.20.25",
|
||||
"version": "4.20.26",
|
||||
"description": "FrankerFaceZ is a Twitch enhancement suite.",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
|
|
@ -63,8 +63,6 @@ export default class RichContent extends Module {
|
|||
data = await data;
|
||||
}
|
||||
|
||||
console.log('data', data);
|
||||
|
||||
if ( ! data )
|
||||
data = {
|
||||
error: {type: 'i18n', key: 'card.empty', phrase: 'No data was returned.'}
|
||||
|
|
|
@ -83,7 +83,9 @@ export function findReactFragment(frag, criteria, depth = 25, current = 0, visit
|
|||
export function createElement(tag, props, ...children) {
|
||||
const el = document.createElement(tag);
|
||||
|
||||
if ( children.length === 1)
|
||||
if ( children.length === 0)
|
||||
children = null;
|
||||
else if ( children.length === 1)
|
||||
children = children[0];
|
||||
|
||||
if ( typeof props === 'string' )
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// ============================================================================
|
||||
|
||||
import {has} from 'utilities/object';
|
||||
import Markdown from 'markdown-it';
|
||||
import MILA from 'markdown-it-link-attributes';
|
||||
|
||||
export const TOKEN_TYPES = {};
|
||||
|
||||
|
@ -22,6 +24,26 @@ const VALID_WEIGHTS = ['regular', 'bold', 'semibold'],
|
|||
huge: 'huge'
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Markdown
|
||||
// ============================================================================
|
||||
|
||||
const md = new Markdown({
|
||||
html: false,
|
||||
linkify: true
|
||||
}).disable('image');
|
||||
|
||||
md.use(MILA, {
|
||||
attrs: {
|
||||
class: 'ffz-tooltip',
|
||||
target: '_blank',
|
||||
rel: 'noopener',
|
||||
'data-tooltip-type': 'link'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Render Tokens
|
||||
// ============================================================================
|
||||
|
@ -127,10 +149,13 @@ export function getRoundClass(value) {
|
|||
}*/
|
||||
|
||||
|
||||
export function renderWithCapture(tokens, createElement, ctx) {
|
||||
const old_capture = ctx.text_capture;
|
||||
export function renderWithCapture(tokens, createElement, ctx, markdown) {
|
||||
const old_capture = ctx.text_capture, old_markdown = ctx.markdown;
|
||||
ctx.text_capture = [];
|
||||
|
||||
if ( markdown )
|
||||
ctx.markdown = true;
|
||||
|
||||
const content = renderTokens(tokens, createElement, ctx);
|
||||
|
||||
let title = ctx.text_capture.join('').trim();
|
||||
|
@ -138,17 +163,22 @@ export function renderWithCapture(tokens, createElement, ctx) {
|
|||
title = null;
|
||||
|
||||
ctx.text_capture = old_capture;
|
||||
ctx.markdown = old_markdown;
|
||||
|
||||
return {
|
||||
content,
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function renderTokens(tokens, createElement, ctx) {
|
||||
export function renderTokens(tokens, createElement, ctx, markdown) {
|
||||
if ( tokens == null )
|
||||
return null;
|
||||
|
||||
const old_markdown = ctx.markdown;
|
||||
if ( markdown )
|
||||
ctx.markdown = true;
|
||||
|
||||
let out = [];
|
||||
if ( ! Array.isArray(tokens) )
|
||||
tokens = [tokens];
|
||||
|
@ -164,6 +194,25 @@ export function renderTokens(tokens, createElement, ctx) {
|
|||
const val = String(token);
|
||||
if ( ctx.text_capture )
|
||||
ctx.text_capture.push(val);
|
||||
|
||||
if ( ctx.markdown ) {
|
||||
const content = md.render(val);
|
||||
if ( content === val )
|
||||
out.push(val);
|
||||
else if ( ctx.vue )
|
||||
out.push(createElement('span', {
|
||||
domProps: {
|
||||
innerHTML: content
|
||||
}
|
||||
}));
|
||||
else
|
||||
out.push(createElement('span', {
|
||||
dangerouslySetInnerHTML: {
|
||||
__html: content
|
||||
}
|
||||
}));
|
||||
|
||||
} else
|
||||
out.push(val);
|
||||
}
|
||||
|
||||
|
@ -184,6 +233,7 @@ export function renderTokens(tokens, createElement, ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
ctx.markdown = old_markdown;
|
||||
if ( ! out.length )
|
||||
return null;
|
||||
|
||||
|
@ -214,14 +264,15 @@ TOKEN_TYPES.box = function(token, createElement, ctx) {
|
|||
applySpacing('pd', token, classes, style);
|
||||
applySpacing('mg', token, classes, style);
|
||||
|
||||
const capture = token.ellipsis || token.lines;
|
||||
const capture = token.ellipsis || token.lines,
|
||||
markdown = token.markdown;
|
||||
let content, title = null;
|
||||
|
||||
if ( capture ) {
|
||||
const out = renderWithCapture(token.content, createElement, ctx);
|
||||
const out = renderWithCapture(token.content, createElement, ctx, markdown);
|
||||
content = out.content; title = out.title;
|
||||
} else
|
||||
content = renderTokens(token.content, createElement, ctx);
|
||||
content = renderTokens(token.content, createElement, ctx, markdown);
|
||||
|
||||
if ( ctx.vue )
|
||||
return createElement('div', {class: classes, style, attrs: {title}}, content);
|
||||
|
@ -264,8 +315,9 @@ TOKEN_TYPES.fieldset = function(token, createElement, ctx) {
|
|||
if ( ! field )
|
||||
continue;
|
||||
|
||||
const name = renderTokens(field.name, createElement, ctx),
|
||||
value = renderTokens(field.value, createElement, ctx);
|
||||
|
||||
const name = renderTokens(field.name, createElement, ctx, token.markdown),
|
||||
value = renderTokens(field.value, createElement, ctx, token.markdown);
|
||||
|
||||
if ( name == null || value == null )
|
||||
continue;
|
||||
|
@ -352,7 +404,7 @@ TOKEN_TYPES.flex = function(token, createElement, ctx) {
|
|||
applySpacing('pd', token, classes, style);
|
||||
applySpacing('mg', token, classes, style);
|
||||
|
||||
const content = renderTokens(token.content, createElement, ctx);
|
||||
const content = renderTokens(token.content, createElement, ctx, token.markdown);
|
||||
if ( ctx.vue )
|
||||
return createElement('div', {class: classes, style}, content);
|
||||
|
||||
|
@ -460,7 +512,7 @@ function header_vue(token, h, ctx) {
|
|||
let content = [];
|
||||
|
||||
if ( token.title ) {
|
||||
const out = renderWithCapture(token.title, h, ctx);
|
||||
const out = renderWithCapture(token.title, h, ctx, token.markdown);
|
||||
content.push(h('div', {
|
||||
class: 'tw-ellipsis tw-semibold tw-mg-x-05',
|
||||
attrs: {
|
||||
|
@ -470,7 +522,7 @@ function header_vue(token, h, ctx) {
|
|||
}
|
||||
|
||||
if ( token.subtitle ) {
|
||||
const out = renderWithCapture(token.subtitle, h, ctx);
|
||||
const out = renderWithCapture(token.subtitle, h, ctx, token.markdown);
|
||||
content.push(h('div', {
|
||||
class: 'tw-ellipsis tw-c-text-alt-2 tw-mg-x-05',
|
||||
attrs: {
|
||||
|
@ -480,7 +532,7 @@ function header_vue(token, h, ctx) {
|
|||
}
|
||||
|
||||
if ( token.extra ) {
|
||||
const out = renderWithCapture(token.extra, h, ctx);
|
||||
const out = renderWithCapture(token.extra, h, ctx, token.markdown);
|
||||
content.push(h('div', {
|
||||
class: 'tw-ellipsis tw-c-text-alt-2 tw-mg-x-05',
|
||||
attrs: {
|
||||
|
@ -555,7 +607,7 @@ function header_normal(token, createElement, ctx) {
|
|||
let content = [];
|
||||
|
||||
if ( token.title ) {
|
||||
const out = renderWithCapture(token.title, createElement, ctx);
|
||||
const out = renderWithCapture(token.title, createElement, ctx, token.markdown);
|
||||
content.push(createElement('div', {
|
||||
className: `tw-ellipsis tw-semibold ${token.compact ? 'tw-mg-r-1' : ''}`,
|
||||
title: out.title
|
||||
|
@ -563,7 +615,7 @@ function header_normal(token, createElement, ctx) {
|
|||
}
|
||||
|
||||
if ( token.subtitle ) {
|
||||
const out = renderWithCapture(token.subtitle, createElement, ctx);
|
||||
const out = renderWithCapture(token.subtitle, createElement, ctx, token.markdown);
|
||||
content.push(createElement('div', {
|
||||
className: `tw-ellipsis tw-c-text-alt-2`,
|
||||
title: out.title
|
||||
|
@ -571,7 +623,7 @@ function header_normal(token, createElement, ctx) {
|
|||
}
|
||||
|
||||
if ( token.extra ) {
|
||||
const out = renderWithCapture(token.extra, createElement, ctx);
|
||||
const out = renderWithCapture(token.extra, createElement, ctx, token.markdown);
|
||||
content.push(createElement('div', {
|
||||
className: 'tw-ellipsis tw-c-text-alt-2',
|
||||
title: out.title
|
||||
|
@ -749,7 +801,8 @@ TOKEN_TYPES.i18n = function(token, createElement, ctx) {
|
|||
return renderTokens(
|
||||
ctx.i18n.tList(token.key, token.phrase, token.content),
|
||||
createElement,
|
||||
ctx
|
||||
ctx,
|
||||
token.markdown
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -759,7 +812,7 @@ TOKEN_TYPES.i18n = function(token, createElement, ctx) {
|
|||
// ============================================================================
|
||||
|
||||
TOKEN_TYPES.link = function(token, createElement, ctx) {
|
||||
const content = renderTokens(token.content, createElement, ctx);
|
||||
const content = renderTokens(token.content, createElement, ctx, token.markdown);
|
||||
|
||||
const klass = [];
|
||||
if ( token.interactive )
|
||||
|
@ -800,13 +853,13 @@ TOKEN_TYPES.link = function(token, createElement, ctx) {
|
|||
// ============================================================================
|
||||
|
||||
TOKEN_TYPES.overlay = function(token, createElement, ctx) {
|
||||
const content = renderTokens(token.content, createElement, ctx);
|
||||
const content = renderTokens(token.content, createElement, ctx, token.markdown);
|
||||
if ( ! content )
|
||||
return null;
|
||||
|
||||
const corners = [];
|
||||
for(const corner of ['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right']) {
|
||||
const stuff = renderTokens(token[corner], createElement, ctx);
|
||||
const stuff = renderTokens(token[corner], createElement, ctx, token.markdown);
|
||||
if ( stuff )
|
||||
corners.push(ctx.vue ?
|
||||
createElement('div', {class: `ffz--overlay__bit`, attrs:{'data-side':corner}}, stuff) :
|
||||
|
@ -883,10 +936,10 @@ TOKEN_TYPES.style = function(token, createElement, ctx) {
|
|||
let content, title = null;
|
||||
|
||||
if ( capture ) {
|
||||
const out = renderWithCapture(token.content, createElement, ctx);
|
||||
const out = renderWithCapture(token.content, createElement, ctx, token.markdown);
|
||||
content = out.content; title = out.title;
|
||||
} else
|
||||
content = renderTokens(token.content, createElement, ctx);
|
||||
content = renderTokens(token.content, createElement, ctx, token.markdown);
|
||||
|
||||
if ( ctx.vue )
|
||||
return createElement('span', {class: classes, style, attrs: {title}}, content);
|
||||
|
@ -957,7 +1010,7 @@ TOKEN_TYPES.tag = function(token, createElement, ctx) {
|
|||
if ( tag === 'video' || tag === 'audio' )
|
||||
attrs.loadedmetadata = ctx.onload;
|
||||
|
||||
const content = renderTokens(token.content, createElement, ctx);
|
||||
const content = renderTokens(token.content, createElement, ctx, token.markdown);
|
||||
|
||||
if ( ctx.vue )
|
||||
return createElement(tag, {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue