From 48ce46589394db7e164e7096b737e2c7b44c855b Mon Sep 17 00:00:00 2001 From: flashwave Date: Thu, 26 Jan 2023 22:51:33 +0000 Subject: [PATCH] Fixed various video embedding bugs. --- assets/css/misuzu/embed.css | 2 + assets/js/misuzu/_main.js | 104 ++++++++++++++++++++++----- assets/js/misuzu/uiharu.js | 2 +- lib/index | 2 +- src/Parsers/BBCode/Tags/AudioTag.php | 9 ++- src/Parsers/BBCode/Tags/ImageTag.php | 15 +++- src/Parsers/BBCode/Tags/VideoTag.php | 6 +- src/Parsers/MarkdownParser.php | 32 +++++++-- 8 files changed, 140 insertions(+), 32 deletions(-) diff --git a/assets/css/misuzu/embed.css b/assets/css/misuzu/embed.css index 889bb3b..acff610 100644 --- a/assets/css/misuzu/embed.css +++ b/assets/css/misuzu/embed.css @@ -89,10 +89,12 @@ font-weight: 400; line-height: 1.1em; margin-bottom: 5px; + word-break: break-word; } .embedph-info-desc { line-height: 1.4em; margin: .5em 0; + word-break: break-word; } .embedph-info-site { font-size: .9em; diff --git a/assets/js/misuzu/_main.js b/assets/js/misuzu/_main.js index d606288..8856081 100644 --- a/assets/js/misuzu/_main.js +++ b/assets/js/misuzu/_main.js @@ -129,31 +129,70 @@ Misuzu.handleEmbeds = function() { if(embeds.length > 0) { $as(embeds); - const uiharu = new Uiharu(UIHARU_API) - elems = new Map(embeds.map(function(elem) { return [elem.dataset.mszEmbedUrl, elem]; })); + const uiharu = new Uiharu(UIHARU_API), + elems = new Map; + + for(const elem of embeds) { + let cleanUrl = elem.dataset.mszEmbedUrl.replace(/ /, '%20'); + if(cleanUrl.indexOf('http://') !== 0 && cleanUrl.indexOf('https://') !== 0) { + elem.textContent = elem.dataset.mszEmbedUrl; + continue; + } + + elem.textContent = 'Loading...'; + + if(elems.has(cleanUrl)) + elems.get(cleanUrl).push(elem); + else + elems.set(cleanUrl, [elem]); + } uiharu.lookupMany(Array.from(elems.keys()), function(resp) { if(resp.results === undefined) return; // rip for(const result of resp.results) { + let elemList = elems.get(result.url); + + const replaceWithUrl = function() { + for(let i = 0; i < elemList.length; ++i) { + let body = $e({ + tag: 'a', + attrs: { + className: 'link', + href: result.url, + target: '_blank', + rel: 'noopener noreferrer', + }, + child: result.url + }); + $ib(elemList[i], body); + $r(elemList[i]); + elemList[i] = body; + } + }; + if(result.error) { + replaceWithUrl(); console.error(result.error); continue; } if(result.info.title === undefined) { + replaceWithUrl(); console.warn('Media is no longer available.'); continue; } - let elem = elems.get(result.url); - (function(elem, info) { - const replaceElement = function(body) { - $ib(elem, body); - $r(elem); - elem = body; + (function(elemList, info) { + const replaceElement = function(bodyInfo) { + for(let i = 0; i < elemList.length; ++i) { + let body = $e(bodyInfo); + $ib(elemList[i], body); + $r(elemList[i]); + elemList[i] = body; + } }; const createEmbedPH = function(type, info, onclick, width, height) { @@ -208,7 +247,7 @@ Misuzu.handleEmbeds = function() { bgElem = {}; } - return $e({ + return { attrs: { href: 'javascript:void(0);', className: ('embedph embedph-' + type), @@ -284,7 +323,7 @@ Misuzu.handleEmbeds = function() { ], }, ], - }); + }; }; if(info.type === 'youtube:video') { @@ -301,7 +340,7 @@ Misuzu.handleEmbeds = function() { } replaceElement(createEmbedPH('youtube', info, function() { - replaceElement($e({ + replaceElement({ attrs: { className: 'embed embed-youtube', }, @@ -314,7 +353,7 @@ Misuzu.handleEmbeds = function() { src: embedUrl, }, }, - })); + }); })); } else if(info.type === 'niconico:video') { let embedUrl = 'https://embed.nicovideo.jp/watch/' + info.nicovideo_video_id + '/script?w=100%25&h=100%25&autoplay=1'; @@ -323,7 +362,7 @@ Misuzu.handleEmbeds = function() { embedUrl += '&from=' + encodeURIComponent(info.nicovideo_start_time); replaceElement(createEmbedPH('nicovideo', info, function() { - replaceElement($e({ + replaceElement({ attrs: { className: 'embed embed-nicovideo', }, @@ -334,9 +373,11 @@ Misuzu.handleEmbeds = function() { src: embedUrl, }, }, - })); + }); })); } else if(info.type === 'media') { + // todo: proxying + // think uiharu will just serve as the camo system if(info.is_video) { let width = info.width, height = info.height; @@ -360,7 +401,7 @@ Misuzu.handleEmbeds = function() { } replaceElement(createEmbedPH('external', info, function() { - replaceElement($e({ + replaceElement({ attrs: { className: 'embed embed-external', }, @@ -376,13 +417,40 @@ Misuzu.handleEmbeds = function() { }, }, }, - })); + }); }, width, height)); } else if(info.is_audio) { - // coming someday + // need dedicated audio placeholder and a player frame that includes the cover art + replaceElement(createEmbedPH('external', info, function() { + replaceElement({ + attrs: { + className: 'embed embed-external', + }, + child: { + tag: 'audio', + attrs: { + autoplay: 'autoplay', + controls: 'controls', + src: info.url, + }, + }, + }); + }, '300px', '300px')); + } else if(info.is_image) { + replaceElement({ + tag: 'img', + attrs: { + src: info.url, + alt: info.url, + style: { + maxWidth: '100%', + maxHeight: '900px', + }, + }, + }); } } - })(elem, result.info); + })(elemList, result.info); } }); } diff --git a/assets/js/misuzu/uiharu.js b/assets/js/misuzu/uiharu.js index 27a817a..6ff501d 100644 --- a/assets/js/misuzu/uiharu.js +++ b/assets/js/misuzu/uiharu.js @@ -1,5 +1,5 @@ const Uiharu = function(apiUrl) { - const maxBatchSize = 5; + const maxBatchSize = 4; const lookupOneUrl = apiUrl + '/metadata', lookupManyUrl = apiUrl + '/metadata/batch'; diff --git a/lib/index b/lib/index index fbe4fe1..1a8344c 160000 --- a/lib/index +++ b/lib/index @@ -1 +1 @@ -Subproject commit fbe4fe18decd502a0ca15ffe8a7c3b2d847349d5 +Subproject commit 1a8344c1c31cb62726305d079384045582315f64 diff --git a/src/Parsers/BBCode/Tags/AudioTag.php b/src/Parsers/BBCode/Tags/AudioTag.php index c4735a8..e96f598 100644 --- a/src/Parsers/BBCode/Tags/AudioTag.php +++ b/src/Parsers/BBCode/Tags/AudioTag.php @@ -13,10 +13,13 @@ final class AudioTag extends BBCodeTag { if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true)) return $matches[0]; - //return sprintf('%1$s', $matches[1]); + // return sprintf( + // '' + // . '', + // $matches[1] + // ); - $mediaUrl = $matches[1]; - return ""; + return ""; }, $text ); diff --git a/src/Parsers/BBCode/Tags/ImageTag.php b/src/Parsers/BBCode/Tags/ImageTag.php index 69d5d19..f779ee4 100644 --- a/src/Parsers/BBCode/Tags/ImageTag.php +++ b/src/Parsers/BBCode/Tags/ImageTag.php @@ -6,9 +6,18 @@ use Misuzu\Parsers\BBCode\BBCodeTag; final class ImageTag extends BBCodeTag { public function parseText(string $text): string { return preg_replace_callback("/\[img\]((?:https?:\/\/).+?)\[\/img\]/", function ($matches) { - //$mediaUrl = url_proxy_media($matches[1]); - $mediaUrl = $matches[1]; - return sprintf('%s', $mediaUrl, $matches[1]); + $url = parse_url($matches[1]); + + if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true)) + return $matches[0]; + + // return sprintf( + // '' + // . '', + // $matches[1] + // ); + + return sprintf('%1$s', $matches[1]); }, $text); } } diff --git a/src/Parsers/BBCode/Tags/VideoTag.php b/src/Parsers/BBCode/Tags/VideoTag.php index 1bc2d27..f2f3b0e 100644 --- a/src/Parsers/BBCode/Tags/VideoTag.php +++ b/src/Parsers/BBCode/Tags/VideoTag.php @@ -13,7 +13,11 @@ final class VideoTag extends BBCodeTag { if(empty($url['scheme']) || !in_array(mb_strtolower($url['scheme']), ['http', 'https'], true)) return $matches[0]; - return sprintf('%1$s', $matches[1]); + return sprintf( + '' + . '', + $matches[1] + ); }, $text ); diff --git a/src/Parsers/MarkdownParser.php b/src/Parsers/MarkdownParser.php index 9180644..7928a8e 100644 --- a/src/Parsers/MarkdownParser.php +++ b/src/Parsers/MarkdownParser.php @@ -13,12 +13,34 @@ class MarkdownParser extends Parsedown implements ParserInterface { } protected function inlineImage($excerpt) { - $object = parent::inlineImage($excerpt); + // remove this line when media detection works entirely as expected + return parent::inlineImage($excerpt); - //if(!empty($object['element']['attributes']['src']) && !is_local_url($object['element']['attributes']['src'])) { - // $object['element']['attributes']['src'] = url_proxy_media($object['element']['attributes']['src']); - //} + if(!isset($excerpt['text'][1]) || $excerpt['text'][1] !== '[') + return; - return $object; + $excerpt['text'] = substr($excerpt['text'], 1); + + $link = $this->inlineLink($excerpt); + if($link === null) + return; + + $inline = [ + 'extent' => $link['extent'] + 1, + 'element' => [ + 'name' => 'span', + 'attributes' => [ + 'class' => 'js-msz-embed-media', + 'data-msz-embed-url' => $link['element']['attributes']['href'], + 'data-msz-embed-alt' => $link['element']['text'], + ], + ], + ]; + + $inline['element']['attributes'] += $link['element']['attributes']; + + unset($inline['element']['attributes']['href']); + + return $inline; } }