您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Smarter image handling on the Something Awful forums.
- // ==UserScript==
- // @name Something Awful Image Fixes
- // @namespace SA
- // @description Smarter image handling on the Something Awful forums.
- // @include http://forums.somethingawful.com/*
- // @version 1.2.0
- // @grant GM_openInTab
- // @run-at document-end
- // @icon http://forums.somethingawful.com/favicon.ico
- // ==/UserScript==
- var Util = {
- assetsLoaded: false,
- assetsLoading: 0,
- /**
- * Initialise the page, strip out any assets that we will load.
- */
- initialise: function(target) {
- // Remove content images:
- var images = document.querySelectorAll('td.postbody img');
- for (var index in images) {
- var image = images[index];
- if (typeof image !== 'object') continue;
- var src = image.getAttribute('src');
- // Exclude smilies:
- if (!/somethingawful[.]com[/](images[/]smilies|forumsystem[/]emoticons)[/]/.test(src)) {
- var placeholder = document.createElement('span');
- placeholder.setAttribute('data-saif-pending', 'yes');
- placeholder.saifCreate = src;
- image.parentNode.replaceChild(placeholder, image);
- }
- }
- // Remove other images:
- var images = document.querySelectorAll('img');
- for (var index in images) {
- var image = images[index];
- if (!image.parentNode) continue;
- var placeholder = document.createElement('span');
- placeholder.setAttribute('data-saif-pending', 'yes');
- placeholder.saifClone = image;
- image.parentNode.replaceChild(placeholder, image);
- }
- // Remove embedded videos:
- var iframes = document.querySelectorAll('td.postbody iframe');
- for (var index in iframes) {
- var iframe = iframes[index];
- if (!iframe.parentNode) continue;
- var placeholder = document.createElement('span');
- placeholder.setAttribute('data-saif-pending', 'yes');
- placeholder.saifClone = iframe;
- iframe.parentNode.replaceChild(placeholder, iframe);
- }
- // Fix post table styles:
- var posts = document.querySelectorAll('table.post');
- for (var index in posts) {
- var post = posts[index];
- if (typeof post !== 'object') continue;
- post.style.tableLayout = 'fixed';
- }
- Util.beginLoading(target);
- },
- /**
- * Begin loading assets from the start of the document
- * until and including the windows viewport.
- */
- beginLoading: function(target) {
- var offset = window.scrollY + window.innerHeight;
- if (!!target) {
- offset = Util.getElementOffset(target) + window.innerHeight
- }
- // Initialise all elements up until the offset:
- var placeholders = document.querySelectorAll('[data-saif-pending]'),
- queue = [];
- for (var index in placeholders) {
- var placeholder = placeholders[index];
- if (typeof placeholder !== 'object') continue;
- if (Util.getElementOffset(placeholder) < offset) {
- queue.push(placeholder);
- }
- }
- for (var index in queue) {
- Util.createElement(queue[index]);
- }
- // Wait until everything initialised thus far is loaded:
- if (!!target) {
- Util.waitForReady(function() {
- // Scroll to the target element:
- window.scrollTo(0, Util.getElementOffset(target));
- // Resume loading of images and videos:
- Util.resumeLoading();
- });
- }
- // No reason to wait:
- else {
- Util.resumeLoading();
- }
- },
- /**
- * Resume loading assets not handled by `Util.beginLoading`
- * as they become visible in the windows viewport.
- */
- resumeLoading: function() {
- var placeholders = document.querySelectorAll('[data-saif-pending]');
- for (var index in placeholders) {
- var placeholder = placeholders[index];
- Util.waitForVisibility(placeholder, function(placeholder) {
- Util.createElement(placeholder);
- });
- }
- },
- /**
- * Create an asset element from a placeholder.
- */
- createElement: function(placeholder) {
- if (!placeholder.parentNode) return;
- // No processing needs to be done:
- if (!!placeholder.saifClone) {
- var element = placeholder.saifClone.cloneNode(true);
- // Track the loading of this image:
- if (element instanceof HTMLImageElement) {
- Util.trackLoadState(element, ['load']);
- }
- placeholder.parentNode.replaceChild(element, placeholder);
- }
- // Process the source of this image:
- else if (!!placeholder.saifCreate) {
- var src = placeholder.saifCreate;
- if (/i\.imgur\.com/.test(src)) {
- Util.createImgur(placeholder, src);
- }
- else if (/staticflickr\.com\//.test(src)) {
- Util.createFlickr(placeholder, src);
- }
- else {
- Util.createImage(placeholder, src);
- }
- }
- },
- /**
- * Create an empty element indicating of failure.
- */
- createEmpty: function(placeholder) {
- var span = document.createElement('span');
- span.setAttribute('data-saif-empty', 'yes');
- placeholder.parentNode.replaceChild(span, placeholder);
- },
- /**
- * Create a simple image element from a given source URL.
- */
- createImage: function(placeholder, src, href) {
- var wrapper = document.createElement('span');
- wrapper.setAttribute('class', 'saif-wrapper');
- // Create image element:
- var image = document.createElement('img');
- // Track the loading of this image:
- Util.trackLoadState(image, ['load']);
- // Append the image to the page when it is loaded:
- image.addEventListener('load', function() {
- if (!!href) {
- var link = document.createElement('a');
- link.setAttribute('href', href);
- link.appendChild(image);
- wrapper.appendChild(link);
- }
- else {
- wrapper.appendChild(image);
- }
- if (!!placeholder.parentNode) {
- placeholder.parentNode.replaceChild(wrapper, placeholder);
- }
- });
- // Set image source:
- image.setAttribute('src', src);
- },
- /**
- * Create a video element from a list of source URLs with media types.
- */
- createVideo: function(placeholder, src, href, sources) {
- var wrapper = document.createElement('span');
- wrapper.setAttribute('class', 'saif-wrapper');
- // Create video element:
- var video = document.createElement('video');
- // Set attributes to ensure gif style playback:
- video.setAttribute('preload', 'auto');
- video.setAttribute('autoplay', 'autoplay');
- video.setAttribute('muted', 'muted');
- video.setAttribute('loop', 'loop');
- video.setAttribute('webkit-playsinline', 'webkit-playsinline');
- var action = document.createElement('a');
- action.setAttribute('class', 'saif-link');
- action.setAttribute('target', '_blank');
- action.textContent = 'See original';
- action.addEventListener('click', function(event) {
- event.stopPropagation();
- event.preventDefault();
- wrapper.setAttribute('class', 'saif-wrapper hide');
- wrapper.removeChild(action);
- video.pause();
- Util.createImage(wrapper, src, href);
- });
- wrapper.appendChild(action);
- // Video has loaded, insert it or a fallback:
- video.addEventListener('loadeddata', function() {
- if (
- (video.videoWidth < 75 && video.videoHeight < 100)
- || (video.videoHeight < 75 && video.videoWidth < 100)
- ) {
- video.pause();
- Util.createImage(placeholder, src, href);
- }
- else {
- var link = document.createElement('a');
- link.setAttribute('href', href);
- link.appendChild(video);
- wrapper.appendChild(link);
- if (!!placeholder.parentNode) {
- placeholder.parentNode.replaceChild(wrapper, placeholder);
- }
- }
- });
- // Track the loading of this video:
- Util.trackLoadState(video, ['loadeddata', 'error']);
- // Add media sources:
- for (var index in sources) {
- var source = document.createElement('source');
- source.setAttribute('src', sources[index][0]);
- source.setAttribute('type', sources[index][1]);
- video.appendChild(source);
- }
- },
- createStyle: function(css) {
- var head = document.querySelectorAll('head')[0],
- style = document.createElement('style');
- style.textContent = css;
- head.appendChild(style);
- },
- /**
- * Create an imgur image or video from a given source URL.
- */
- createImgur: function(placeholder, src) {
- var bits = /\/(.{5}|.{7})[hls]?\.(jpg|png|gif)/i.exec(src);
- // Could not parse the image:
- if (bits) {
- var identity = bits[1],
- extension = bits[2].toLowerCase();
- // Is a video:
- if ('gif' === extension) {
- Util.createVideo(
- placeholder,
- '//i.imgur.com/' + identity + '.' + extension,
- '//i.imgur.com/' + identity + '.' + extension,
- [
- ['//i.imgur.com/' + identity + '.webm', 'video/webm'],
- ['//i.imgur.com/' + identity + '.mp4', 'video/mp4']
- ]
- );
- }
- // Is an image:
- else {
- Util.createImage(
- placeholder,
- '//i.imgur.com/' + identity + 'h.' + extension,
- '//i.imgur.com/' + identity + '.' + extension
- );
- }
- }
- // The source was invalid:
- else {
- Util.createEmpty(placeholder);
- }
- },
- /**
- * Create a flickr image from a given source URL.
- */
- createFlickr: function(placeholder, src) {
- var bits = /^(.+?\.com\/.+?\/.+?_.+?)(_[omstzb])?\.(.+?)$/.exec(src),
- location,
- extension;
- // Create an image:
- if (bits) {
- var location = bits[1],
- extension = bits[3].toLowerCase();
- Util.createImage(
- placeholder,
- location + '_b.' + extension,
- location + '_b.' + extension
- );
- }
- // The source was invalid:
- else {
- Util.createEmpty(placeholder);
- }
- },
- /**
- * Calculate the offset from the top of the page to the
- * top of the given element.
- */
- getElementOffset: function(element) {
- var offset = 0;
- while (element.offsetParent) {
- offset += element.offsetTop;
- element = element.offsetParent;
- }
- return offset;
- },
- /**
- * Style an element so that it cannot break out of the post table.
- */
- setElementStyles: function(element) {
- element.style.display = 'inline-block';
- element.style.marginBottom = '5px';
- element.style.marginTop = '5px';
- element.style.maxWidth = '100%';
- },
- /**
- * Attach events to count the number of currently loading assets.
- */
- trackLoadState: function(element, eventNames) {
- if (Util.assetsLoaded) return;
- Util.assetsLoading++;
- for (var index in eventNames) {
- element.addEventListener(eventNames[index], Util.trackReadyState);
- }
- },
- /**
- * The attached event handler for `Util.trackLoadState`.
- */
- trackReadyState: function(event) {
- if (Util.assetsLoaded) return;
- Util.assetsLoading--;
- if (0 === Util.assetsLoading) {
- Util.assetsLoaded = true;
- }
- },
- /**
- * Wait for all of the assets loaded in `Util.beginLoading`
- * to complete.
- */
- waitForReady: function(callback) {
- var wait = setInterval(function() {
- if (Util.assetsLoaded) {
- clearInterval(wait);
- callback();
- }
- }, 1);
- },
- /**
- * Wait for the user to scroll within two pages of an element
- * and then call the callback.
- */
- waitForVisibility: function(element, callback) {
- var chromeSucks = false;
- var scroll = function() {
- if (chromeSucks) return;
- var offset = Util.getElementOffset(element),
- max = window.scrollY + (window.innerHeight * 2);
- if (max > offset) {
- chromeSucks = true;
- window.removeEventListener('scroll', scroll);
- callback(element);
- }
- };
- scroll();
- window.addEventListener('scroll', scroll);
- }
- };
- try {
- var offset = window.outerHeight;
- Util.createStyle("\
- @-webkit-keyframes saifProgressSlider {\
- 0% { background: #3b3b3b; }\
- 100% { background: #3b3b3b; }\
- }\
- @keyframes saifProgressSlider {\
- 0% { background-position: 0px 0px; }\
- 100% { background-position: 16px 0px; }\
- }\
- span.saif-wrapper {\
- display: inline-block;\
- position: relative;\
- margin: 5px 0;\
- max-width: 100%;\
- }\
- span.saif-wrapper img,\
- span.saif-wrapper video {\
- max-width: 100%;\
- opacity: 1;\
- vertical-align: bottom;\
- }\
- span.saif-wrapper.hide {\
- background: repeating-linear-gradient(45deg, #444444 0px, #444444 8px, #3b3b3b 8px, #3b3b3b 16px) scroll 0% 0% / 300% 300%;\
- -webkit-animation: saifProgressSlider 60s linear infinite;\
- animation: saifProgressSlider 1s linear infinite;\
- }\
- span.saif-wrapper.hide video {\
- transition: opacity 0.5s ease;\
- opacity: 0;\
- }\
- span.saif-wrapper a.saif-link {\
- background: hsla(0, 0%, 10%, 0.7);\
- color: #ffffff;\
- cursor: pointer;\
- display: none;\
- font-size: 0.75em;\
- left: 0;\
- line-height: 1;\
- padding: 5px;\
- position: absolute;\
- right: 0;\
- text-decoration: none;\
- top: 0;\
- z-index: 1;\
- }\
- span.saif-wrapper:hover a.saif-link {\
- display: block;\
- }\
- ");
- // Prevent images from loading:
- window.stop();
- // Redirect the page:
- if (document.querySelectorAll('meta[http-equiv=refresh]').length) {
- var rule = document.querySelectorAll('meta[http-equiv=refresh]')[0].getAttribute('content');
- if (/URL=(.+)$/.test(rule)) {
- window.location = /URL=(.+)$/.exec(rule)[1];
- }
- }
- // Jump to appropriate place on page:
- else if (!!window.location.hash && document.querySelectorAll(window.location.hash).length) {
- Util.initialise(document.querySelectorAll(window.location.hash)[0]);
- }
- // Load the page normally:
- else {
- Util.initialise();
- }
- }
- catch (e) {
- console.log("Exception: " + e.name + " Message: " + e.message);
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址