From 1f1f4c6be8e7a3a8c2dc5425cb9d71ac76aaf04f Mon Sep 17 00:00:00 2001 From: KillyMXI Date: Fri, 2 Jun 2017 21:29:45 +0300 Subject: juick-www: embed fixes --- juick-www/src/main/js/killy/index.js | 136 ++++++++++++++--------------------- juick-www/src/main/static/scripts.js | 11 +-- juick-www/src/main/static/style.css | 62 ++++++++++++---- 3 files changed, 101 insertions(+), 108 deletions(-) (limited to 'juick-www') diff --git a/juick-www/src/main/js/killy/index.js b/juick-www/src/main/js/killy/index.js index bb8e21f9..1a59805d 100644 --- a/juick-www/src/main/js/killy/index.js +++ b/juick-www/src/main/js/killy/index.js @@ -15,36 +15,10 @@ function removeAllFrom(fromNode) { for (let c; c = fromNode.lastChild; ) { fromNode.removeChild(c); } } -function turnIntoCts(node, makeNodeCallback) { - node.onclick = function(e){ - e.preventDefault(); - let newNode = makeNodeCallback(); - if (newNode !== node) { - removeAllFrom(node); - moveAll(newNode, node); - node.className = newNode.className; - } else { - node.onclick = ''; - node.classList.remove('cts'); - } - }; -} - -function makeCts(makeNodeCallback, title) { - let ctsNode = document.createElement('div'); - let placeholder = document.createElement('div'); - placeholder.className = 'placeholder'; - placeholder.innerHTML = title; - ctsNode.className = 'cts'; - ctsNode.appendChild(placeholder); - turnIntoCts(ctsNode, makeNodeCallback); - return ctsNode; -} - function makeIframe(src, w, h, scrolling='no') { let iframe = document.createElement('iframe'); - iframe.width = w; - iframe.height = h; + iframe.style.width = w; + iframe.style.height = h; iframe.frameBorder = 0; iframe.scrolling = scrolling; iframe.setAttribute('allowFullScreen', ''); @@ -52,15 +26,6 @@ function makeIframe(src, w, h, scrolling='no') { return iframe; } -function naiveEllipsis(str, len, ellStr='...') { - let ellLen = ellStr.length; - if (str.length <= len) { return str; } - let half = Math.floor((len - ellLen) / 2); - let left = str.substring(0, half); - let right = str.substring(str.length - (len - half - ellLen)); - return '' + left + ellStr + right; -} - function wrapIntoTag(node, tagName, className) { let tag = document.createElement(tagName); if (className !== undefined) { tag.className = className; } @@ -68,7 +33,19 @@ function wrapIntoTag(node, tagName, className) { return tag; } -function getEmbedableLinkTypes() { +function makeResizableToRatio(element, ratio) { + element.dataset['ratio'] = ratio; + makeResizable(element, w => w * element.dataset['ratio']); +} + +// calcHeight :: Number -> Number -- calculate element height for a given width +function makeResizable(element, calcHeight) { + const resizeToRatio = el => { el.style.height = (calcHeight(el.offsetWidth)).toFixed(2) + 'px'; }; + window.addEventListener('resize', () => resizeToRatio(element)); + resizeToRatio(element); +} + +function getEmbeddableLinkTypes() { return [ { name: 'Jpeg and png images', @@ -81,7 +58,7 @@ function getEmbedableLinkTypes() { imgNode.src = aNode.href; aNode2.href = aNode.href; aNode2.appendChild(imgNode); - return wrapIntoTag(aNode2, 'div'); + return wrapIntoTag(aNode2, 'div', 'picture compact'); } }, { @@ -95,29 +72,31 @@ function getEmbedableLinkTypes() { imgNode.src = aNode.href; aNode2.href = aNode.href; aNode2.appendChild(imgNode); - return wrapIntoTag(aNode2, 'div'); + return wrapIntoTag(aNode2, 'div', 'picture compact'); } }, { - name: 'Webm and mp4 video', + name: 'Video (webm, mp4, ogv)', id: 'embed_webm_and_mp4_videos', ctsDefault: false, - re: /\.(webm|mp4)(?:\?[\w&;\?=]*)?$/i, + re: /\.(webm|mp4|m4v|ogv)(?:\?[\w&;\?=]*)?$/i, makeNode: function(aNode) { let video = document.createElement('video'); video.src = aNode.href; + video.title = aNode.href; video.setAttribute('controls', ''); - return wrapIntoTag(video, 'div', 'video'); + return wrapIntoTag(video, 'div', 'video compact'); } }, { - name: 'Mp3 and ogg audio', + name: 'Audio (mp3, ogg, weba, opus, m4a, oga, wav)', id: 'embed_sound_files', ctsDefault: false, - re: /\.(mp3|ogg)(?:\?[\w&;\?=]*)?$/i, + re: /\.(mp3|ogg|weba|opus|m4a|oga|wav)(?:\?[\w&;\?=]*)?$/i, makeNode: function(aNode) { let audio = document.createElement('audio'); audio.src = aNode.href; + audio.title = aNode.href; audio.setAttribute('controls', ''); return wrapIntoTag(audio, 'div', 'audio'); } @@ -125,11 +104,12 @@ function getEmbedableLinkTypes() { { name: 'YouTube videos (and playlists)', id: 'embed_youtube_videos', + onByDefault: false, ctsDefault: false, re: /^(?:https?:)?\/\/(?:www\.|m\.)?(?:youtu(?:(?:\.be\/|be\.com\/(?:v|embed)\/)([-\w]+)|be\.com\/watch)((?:(?:\?|&(?:amp;)?)(?:\w+=[-\.\w]*[-\w]))*)|youtube\.com\/playlist\?list=([-\w]*)(&(amp;)?[-\w\?=]*)?)/i, makeNode: function(aNode, reResult) { let [url, v, args, plist] = reResult; - let iframeUrl = url; + let iframeUrl; if (plist !== undefined) { iframeUrl = '//www.youtube-nocookie.com/embed/videoseries?list=' + plist; } else { @@ -148,17 +128,22 @@ function getEmbedableLinkTypes() { v = v || pp.v; iframeUrl = '//www.youtube-nocookie.com/embed/' + v + '?' + Object.keys(embedArgs).map(k => `${k}=${embedArgs[k]}`).join('&'); } - return wrapIntoTag(makeIframe(iframeUrl, 640, 360), 'div', 'youtube'); + let iframe = makeIframe(iframeUrl, '100%', '360px'); + setTimeout(() => makeResizableToRatio(iframe, 9.0/16.0), 10); + return wrapIntoTag(iframe, 'div', 'youtube resizableV'); } }, { name: 'Vimeo videos', id: 'embed_vimeo_videos', + onByDefault: false, ctsDefault: false, //re: /^(?:https?:)?\/\/(?:www\.)?(?:player\.)?vimeo\.com\/(?:(?:video\/|album\/[\d]+\/video\/)?([\d]+)|([\w-]+)\/(?!videos)([\w-]+))/i, re: /^(?:https?:)?\/\/(?:www\.)?(?:player\.)?vimeo\.com\/(?:video\/|album\/[\d]+\/video\/)?([\d]+)/i, makeNode: function(aNode, reResult) { - return wrapIntoTag(makeIframe('//player.vimeo.com/video/' + reResult[1], 640, 360), 'div', 'vimeo'); + let iframe = makeIframe('//player.vimeo.com/video/' + reResult[1], '100%', '360px'); + setTimeout(() => makeResizableToRatio(iframe, 9.0/16.0), 10); + return wrapIntoTag(iframe, 'div', 'vimeo resizableV'); } } ]; @@ -167,38 +152,23 @@ function getEmbedableLinkTypes() { function embedLink(aNode, linkTypes, container, alwaysCts, afterNode) { let anyEmbed = false; let linkId = (aNode.href.replace(/^https?:/i, '').replace(/\'/i,'')); - let sameEmbed = container.querySelector('*[data-linkid=\'' + linkId + '\']'); // do not embed the same thing twice + let sameEmbed = container.querySelector(`*[data-linkid='${linkId}']`); // do not embed the same thing twice if (sameEmbed === null) { anyEmbed = [].some.call(linkTypes, function(linkType) { - /* if (GM_getValue(linkType.id, true)) { TODO user embed particular link type setting */ let reResult = linkType.re.exec(aNode.href); if (reResult !== null) { if ((linkType.match !== undefined) && (linkType.match(aNode, reResult) === false)) { return false; } - let newNode; - let isCts = alwaysCts; /* || TODO user click-to-show setting */ - if (isCts) { - let linkTitle = (linkType.makeTitle !== undefined) ? linkType.makeTitle(aNode, reResult) : naiveEllipsis(aNode.href, 55); - newNode = makeCts(() => linkType.makeNode(aNode, reResult, newNode), 'Click to show: ' + linkTitle); - } else { - newNode = linkType.makeNode(aNode, reResult); - } + let newNode = linkType.makeNode(aNode, reResult); if (!newNode) { return false; } - aNode.classList.add('embedLink'); - /* - if (GM_getValue('enable_link_text_update', true) && (linkType.linkTextUpdate !== undefined)) { - linkType.linkTextUpdate(aNode, reResult); - } - */ newNode.setAttribute('data-linkid', linkId); if (afterNode !== undefined) { insertAfter(newNode, afterNode); } else { container.appendChild(newNode); } - //setHighlightOnHover(aNode, newNode); + aNode.classList.add('embedLink'); return true; } - /* } */ }); } return anyEmbed; @@ -206,36 +176,36 @@ function embedLink(aNode, linkTypes, container, alwaysCts, afterNode) { function embedLinks(aNodes, container, alwaysCts, afterNode) { let anyEmbed = false; - let embedableLinkTypes = getEmbedableLinkTypes(); + let embeddableLinkTypes = getEmbeddableLinkTypes(); Array.from(aNodes).forEach(aNode => { - let isEmbedded = embedLink(aNode, embedableLinkTypes, container, alwaysCts, afterNode); + let isEmbedded = embedLink(aNode, embeddableLinkTypes, container, alwaysCts, afterNode); anyEmbed = anyEmbed || isEmbedded; }); return anyEmbed; } function articleInfo(article) { - let userId = article.querySelector('div.msg-avatar > a > img').alt; let tagNodes = article.querySelectorAll('.msg-tags > *'); let tags = Array.from(tagNodes).map(d => d.textContent.toLowerCase()); - return { userId: userId, tags: tags }; -} - -function isFilteredX(x, filteredUsers, filteredTags) { - let {userId, tags} = articleInfo(x); - return (filteredUsers !== undefined && filteredUsers.indexOf(userId.toLowerCase()) !== -1) - || (intersect(tags, filteredTags).length > 0); + return { tags: tags }; } function embedLinksToX(x, beforeNodeSelector, allLinksSelector, ctsUsers, ctsTags) { - let isCtsPost = isFilteredX(x, ctsUsers, ctsTags); + let isCtsPost = false; let allLinks = x.querySelectorAll(allLinksSelector); - let embedContainer = document.createElement('div'); - embedContainer.className = 'embedContainer'; - let anyEmbed = embedLinks(allLinks, embedContainer, isCtsPost); - if (anyEmbed) { - let beforeNode = x.querySelector(beforeNodeSelector); - x.insertBefore(embedContainer, beforeNode); + + let existingContainer = x.querySelector('div.embedContainer'); + if (existingContainer !== null) { + embedLinks(allLinks, existingContainer, isCtsPost); + } else { + let embedContainer = document.createElement('div'); + embedContainer.className = 'embedContainer'; + + let anyEmbed = embedLinks(allLinks, embedContainer, isCtsPost); + if (anyEmbed) { + let beforeNode = x.querySelector(beforeNodeSelector); + x.insertBefore(embedContainer, beforeNode); + } } } diff --git a/juick-www/src/main/static/scripts.js b/juick-www/src/main/static/scripts.js index 7de14b34..e3d2445a 100644 --- a/juick-www/src/main/static/scripts.js +++ b/juick-www/src/main/static/scripts.js @@ -736,16 +736,7 @@ ready(function () { return a.textContent === 'NSFW'; } )) { - var img = article.querySelector('.ir img'); - if (img) { - img.style.opacity = 0.05; - img.addEventListener('mouseover', function (e) { - e.target.style.opacity = 1; - }); - img.addEventListener('mouseout', function (e) { - e.target.style.opacity = 0.05; - }); - } + article.classList.add('nsfw'); } }); diff --git a/juick-www/src/main/static/style.css b/juick-www/src/main/static/style.css index d34da0e0..fd81070b 100644 --- a/juick-www/src/main/static/style.css +++ b/juick-www/src/main/static/style.css @@ -730,26 +730,58 @@ fieldset { border: 1px dotted #ccc; margin-top: 25px; } +/* embeds */ .embedContainer { - height: 0; - overflow: hidden; - padding-bottom: 56.25%; - padding-top: 30px; - position: relative; - text-align: center; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + padding: 0; + margin: 30px -3px 15px -3px; } -.embedContainer iframe, -.embedContainer object, -.embedContainer embed { - height: 100%; - left: 0; - position: absolute; - top: 0; - width: 100%; +.embedContainer > * { + box-sizing: border-box; + flex-grow: 1; + margin: 3px; + min-width: 49%; } -.embedContainer img { +.embedContainer > .compact { + flex-grow: 0; +} +.embedContainer .picture img { + display: block; +} +.embedContainer img, +.embedContainer video { max-width: 100%; + max-height: 80vh; +} +.embedContainer > .audio, +.embedContainer > .youtube { + min-width: 90%; +} +.embedContainer audio { + width: 100%; +} +.embedContainer iframe { + overflow:hidden; + resize: vertical; + display: block; +} +/* end of embeds*/ +/* nsfw */ +article.nsfw .embedContainer img, +article.nsfw .embedContainer iframe, +article.nsfw .ir img { + opacity: 0.1; + transition: opacity 0.05s; +} +article.nsfw .embedContainer img:hover, +article.nsfw .embedContainer iframe:hover, +article.nsfw .ir img:hover { + opacity: 1.0; } +/* end of nsfw */ @media screen and (max-width: 850px) { body { -moz-text-size-adjust: 100%; -- cgit v1.2.3