diff --git a/index.html b/index.html
index 781b0ba3..5b684594 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,6 @@
Akkoma
-
diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js
index a0778b6d..58b14967 100644
--- a/src/components/emoji_input/suggestor.js
+++ b/src/components/emoji_input/suggestor.js
@@ -1,4 +1,4 @@
-const MFM_TAGS = ['blur', 'bounce', 'flip', 'font', 'jelly', 'jump', 'rainbow', 'rotate', 'shake', 'sparkle', 'spin', 'tada', 'twitch', 'x2', 'x3', 'x4']
+const MFM_TAGS = ['bg', 'blur', 'bounce', 'center', 'fg', 'flip', 'font', 'jelly', 'jump', 'position', 'rainbow', 'rotate', 'scale', 'shake', 'sparkle', 'spin', 'tada', 'twitch', 'x2', 'x3', 'x4']
.map(tag => ({ displayText: tag, detailText: '$[' + tag + ' ]', replacement: '$[' + tag + ' ]', mfm: true }))
/**
diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
index 0da7f3de..eeb5475e 100644
--- a/src/components/rich_content/rich_content.jsx
+++ b/src/components/rich_content/rich_content.jsx
@@ -121,6 +121,19 @@ export default {
}
}
+ const mfmStyleFromDataAttributes = (attributes) => {
+ // CSS selectors can check if a data-* attribute is true, but can't use other values, so we want to add them to the style attribute
+ // Here we turn e.g. `{'data-mfm-some': '1deg', 'data-mfm-thing': '5s'}` to "--mfm-some: 1deg;--mfm-thing: 5s;"
+ // Note that we only add the value to `style` when they contain only letters, numbers, dot, or minus signs
+ // At the moment of writing, this should be enough for legitimate purposes and reduces the chance of injection by using special characters
+ // There is a special case for the `color` value, who is provided without `#`, but requires this in the `style` attribute
+ return Object.keys(attributes).filter(
+ (key) => key.startsWith('data-mfm-') && attributes[key] !== true && /^[a-zA-Z0-9.\-]*$/.test(attributes[key])
+ ).map(
+ (key) => '--mfm-' + key.substr(9) + (key === 'data-mfm-color' ? ': #' : ': ') + attributes[key] + ';'
+ ).reduce((a,v) => a+v, '')
+ }
+
// Processor to use with html_tree_converter
const processItem = (item, index, array, what) => {
// Handle text nodes - just add emoji
@@ -191,6 +204,15 @@ export default {
if (this.handleLinks && attrs?.['class']?.includes?.('h-card')) {
return ['', children.map(processItem), '']
}
+
+ let mfm_style = mfmStyleFromDataAttributes(attrs)
+ if (mfm_style !== '') {
+ return [
+ opener.slice(0,-1) + ' style="' + mfm_style + '">',
+ children.map(processItem),
+ closer
+ ]
+ }
}
if (children !== undefined) {
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
index 434cb482..3d70ca47 100644
--- a/src/components/status_body/status_body.scss
+++ b/src/components/status_body/status_body.scss
@@ -3,6 +3,7 @@
.StatusBody {
display: flex;
flex-direction: column;
+ overflow: hidden;
.translation {
border: 1px solid var(--accent, $fallback--link);
@@ -23,24 +24,6 @@
transition: 0.05s;
}
- ._mfm_x2_ {
- .emoji {
- height: 100px;
- }
- }
-
- ._mfm_x3_ {
- .emoji {
- height: 150px;
- }
- }
-
- ._mfm_x4_ {
- .emoji {
- height: 200px;
- }
- }
-
.attachments {
margin-top: 0.5em;
}
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index ba9a3ded..068c6c1b 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -1,7 +1,7 @@