Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions markup.css
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,42 @@ L + ratio { }
height: auto;
}

.Markup .M-emote {
display: inline-block;
object-fit: contain;
width: calc(var(--size)*var(--emote-size, 1.125em));
height: calc(var(--size)*var(--emote-size, 1.125em));
vertical-align: middle;
max-height: unset;
border: none;
}

.M-filter-h {
transform: scaleX(-1);
}
.M-filter-v {
transform: scaleY(-1);
}
.M-filter-h.M-image-filter-v {
transform: scaleX(-1) scaleY(-1);
}
.M-filter-r {
transform: rotate(90deg);
}
.M-filter-h.M-filter-r {
transform: scaleX(-1) rotate(90deg);
}
.M-filter-v.M-filter-r {
transform: scaleY(-1) rotate(90deg);
}
.M-filter-h.M-filter-v.M-filter-r {
transform: rotate(270deg);
}
.M-filter-p {
image-rendering: pixelated;
image-rendering: crisp-edges;
}

/* ruby text doesn't work if set to white-space: pre */
.Markup rt {
white-space: pre-line;
Expand Down
6 changes: 5 additions & 1 deletion parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ class Markup_12y2 { constructor() {
read_args()
if (token==='\\link') {
read_body(false)
} else {
} else if (token!=='\\e') { // Emote should not have body
read_body(true)
if (NO_ARGS===rargs && false===body) {
NEVERMIND()
Expand Down Expand Up @@ -504,6 +504,10 @@ class Markup_12y2 { constructor() {
let [lang=""] = rargs
OPEN('language', {lang})
word_maybe()
} break; case '\\e': {
let [id="",name="",role="emote",source=""] = rargs.reverse()
OPEN('emote', {source, name, id, role})
CLOSE()
}}
} break; case 'STYLE': {
let c = check_style(token, text.charAt(match.index-1)||"\n", text.charAt(REGEX.lastIndex)||"\n")
Expand Down
72 changes: 72 additions & 0 deletions render.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ class Markup_Render_Dom { constructor() {
ERROR: (href, thing)=> "about:blank#"+href,
}

let EMOTE_SOURCES = {
__proto__: null,
"": (id, options) => options.pixel ? `sbs:image/${id}` : `sbs:image/${id}?size=128`,
"url": (id, options) => id,
"discordemote": (id, options) => `https://cdn.discordapp.com/emojis/${id}`,
"discordsticker": (id, options) => `https://media.discordapp.net/stickers/${id}`,
UNKNOWN: (id, options) => null
}

function filter_url(url, thing) {
try {
let u = new URL(url, "no-scheme:/")
Expand Down Expand Up @@ -112,6 +121,68 @@ class Markup_Render_Dom { constructor() {
})
return e
},

emote: function({source, name, id, role, filter}, filter2) {
if (id == "") id = name
if (role == "") role = "emote"
let options
[id, options=""] = id.split("#")
options+=(filter || "") + (filter2 || "")
let opt = {}
// Duplicate filters cancel out
options.split('').forEach(c=>opt[c] = !opt[c])
let url, unknown = false
if (id)
url = (EMOTE_SOURCES[source] || EMOTE_SOURCES.UNKNOWN)(id, {pixel: opt["p"]})
let src = filter_url(url || "data:image/gif;base64,R0lGODlhAQABAIAAANDL5NDL5CH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==", 'image')
let e = document.createElement('img')
e.classList.add('M-emote')
e.dataset.emotesource = source
if (url == null) e.dataset.emoteunknown = true
if (name!=null)
e.alt = e.title = name
e.tabIndex = 0
const set_size = (state, width=e.naturalWidth, height=e.naturalHeight)=>{
if (state=="size") {
e.width = width
e.height = height
}
e.style.setProperty('--width', width)
e.style.setProperty('--height', height)
e.dataset.state = state
}
let size = 2
switch (role) {
case "icon":
size = 1
break
case "emote":
size = 2
break
case "medium":
size = 4
break
case "sticker":
size = 8
break
}
e.style.setProperty('--size', size)
set_size('size', size * 16, size * 16)
e.src = src
Object.keys(opt).forEach(x => x ? e.classList.add(`M-filter-${x}`) : undefined)
// check whether the image is "available" (i.e. size is known) by looking at naturalHeight
// https://html.spec.whatwg.org/multipage/images.html#img-available
// this will happen here if the image is VERY cached, i guess
if (e.naturalHeight)
set_size('loaded-emote')
else // otherwise wait for load
e.decode().then(ok=>{
set_size('loaded-emote')
}, no=>{
e.dataset.state = 'error'
})
return e
},

error: 𐀶`<div class='error'><code>🕯error🕯</code>🕯message🕯<pre>🕯stack🕯`,

Expand Down Expand Up @@ -416,6 +487,7 @@ we should create our own fake bullet elements instead.*/
@member {Object<string,function>}
**/
this.url_scheme = URL_SCHEME
this.emote_sources = EMOTE_SOURCES
this.filter_url = filter_url
}}

Expand Down