Skip to content

Instantly share code, notes, and snippets.

@unarist
Last active February 6, 2021 19:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unarist/31d8eae2e2c633a51897858b83b0e7f3 to your computer and use it in GitHub Desktop.
Save unarist/31d8eae2e2c633a51897858b83b0e7f3 to your computer and use it in GitHub Desktop.
Mastodon - Make fullscreen on clicking media modal
// ==UserScript==
// @name Mastodon - Make fullscreen on clicking media modal
// @namespace https://github.com/unarist/
// @version 0.4.1
// @author unarist
// @match https://*/web/*
// @grant none
// @downloadURL https://gist.github.com/unarist/31d8eae2e2c633a51897858b83b0e7f3/raw/mastodon-fullscreen-image.user.js
// ==/UserScript==
/*
0.4: CSP fix, bindTarget fix, etc. (tested on v3.3.0)
0.3: support new media modal fix (#6750) on v2.3.1
0.2: support new media modal (#5956) on v2.3.0
*/
(function() {
'use strict';
if (!document.querySelector('.app-holder[data-react-class="Mastodon"], #mastodon')) return;
const modalRoot = document.querySelector('.modal-root'),
tag = (e,p) => Object.assign(document.createElement(e), p || {}),
isEventHandled = (e) => e.composedPath().some(e => e.tagName === 'BUTTON' || e.tagName === 'A'),
getFullscreenElement = () => document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement,
requestFullscreen = Element.prototype.requestFullscreen || Element.prototype.webkitRequestFullscreen || Element.prototype.mozRequestFullScreen,
exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen;
const log = x => console.debug(`${GM.info.script.name}: ${x}`);
const setupStylesheet = css => {
if (!document.querySelector('meta[name="style-nonce"]')) {
const styleEl = document.head.appendChild(tag('style', { textContent: css }));
if (styleEl.sheet) {
return styleEl.sheet;
}
styleEl.remove(); // 多分CSPで弾かれてるので削除
}
// workaround for Blink
if (document.adoptedStyleSheets) {
log('<style> may be blocked by CSP, using adoptedStylesheets instead.');
const sheet = new CSSStyleSheet();
sheet.replaceSync(css);
document.adoptedStyleSheets = document.adoptedStyleSheets.concat(sheet);
return sheet;
}
// workaround2
const usableSheet = [...document.styleSheets].filter(x=>(x.href || "").startsWith(location.origin)).slice(-1)[0];
if (usableSheet) {
log(`<style> may be blocked by CSP, inserting into ${usableSheet.href} instead.`);
usableSheet.insertRule(`@supports (display:block) { ${css} }`);
return usableSheet;
}
throw Error(`Cannot setup custom styles (probably due to CSP).\nUA: ${navigator.userAgent}`);
};
setupStylesheet(`
.media-modal .image-loader img { cursor: zoom-in; }
.media-modal:-moz-full-screen .image-loader img { cursor: zoom-out; }
.media-modal:-webkit-full-screen .image-loader img { cursor: zoom-out; }
.media-modal:fullscreen .image-loader img { cursor: zoom-out; }
` );
const mark = `__userscript-don-fullscreen-image`;
new MutationObserver(() => {
const bindTarget = modalRoot.querySelector('.media-modal');
if (!bindTarget || bindTarget.classList.contains(mark)) return;
bindTarget.classList.add(mark);
bindTarget.addEventListener('click', (e) => {
if (isEventHandled(e) || e.target.tagName !== 'IMG') return;
if (!getFullscreenElement()) {
requestFullscreen.call(bindTarget);
} else {
exitFullscreen.call(document);
}
});
}).observe(modalRoot, { childList: 1, subtree: 1 });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment