├── CNAME ├── start.cmd ├── .vscode ├── settings.json └── launch.json ├── images ├── favicon.png ├── fullscreen.png ├── 1437338478_screen-full.svg └── play.svg ├── _redirects ├── nodejs ├── .eslintrc.js ├── app.js └── test-embedit.js ├── vercel.json ├── js ├── fix-tagsyo-link.js ├── jquery.touchwipe.js ├── js.cookie.js ├── ie_hacks.js ├── EmbedIt.js └── script.js ├── redditp-redirect └── docker-compose.yml ├── docker-compose.yml ├── .htaccess ├── package.json ├── server.js ├── .gitignore ├── LICENSE ├── dmca.html ├── README.md ├── 404.html ├── css └── style.css ├── .eslintrc.js ├── index.html └── httpd.conf /CNAME: -------------------------------------------------------------------------------- 1 | redditp.com -------------------------------------------------------------------------------- /start.cmd: -------------------------------------------------------------------------------- 1 | http-server -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.enable": true 3 | } -------------------------------------------------------------------------------- /images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubershmekel/redditp/HEAD/images/favicon.png -------------------------------------------------------------------------------- /images/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ubershmekel/redditp/HEAD/images/fullscreen.png -------------------------------------------------------------------------------- /_redirects: -------------------------------------------------------------------------------- 1 | # DOES THIS FILE EVEN WORK AT ALL? 2 | # vercel.json seems to be the only one that counts. 3 | # source dest httpcode 4 | /r/* / 200 5 | /u/* / 200 6 | /user/* / 200 7 | /domain/* / 200 8 | /search/* / 200 9 | /search / 200 10 | 11 | -------------------------------------------------------------------------------- /images/1437338478_screen-full.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /nodejs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "ecmaFeatures": { 3 | "modules": true, 4 | "spread" : true, 5 | "restParams" : true 6 | }, 7 | "env" : { 8 | "browser" : true, 9 | "node" : true, 10 | "es6" : true 11 | }, 12 | "rules" : { 13 | "no-unused-vars" : 2, 14 | "no-undef" : 2 15 | }, 16 | "parserOptions": { 17 | "sourceType": "module" 18 | } 19 | } -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewrites": [ 3 | { "source": "/u/stellaraeee/submitted", "destination": "/dmca.html" }, 4 | { "source": "/r/(.*)", "destination": "/index.html" }, 5 | { "source": "/u/(.*)", "destination": "/index.html" }, 6 | { "source": "/user/(.*)", "destination": "/index.html" }, 7 | { "source": "/domain/(.*)", "destination": "/index.html" }, 8 | { "source": "/search/(.*)", "destination": "/index.html" }, 9 | { "source": "/search", "destination": "/index.html" } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /js/fix-tagsyo-link.js: -------------------------------------------------------------------------------- 1 | function fixTagsyoLink() { 2 | var subMatch = /\/r\/([a-zA-Z_0-9\-]+)/.exec(window.location.href); 3 | if (!subMatch) { 4 | return; 5 | } 6 | var subName = subMatch[1]; 7 | var query = "SELECT * FROM url WHERE LOWER(channel) = '" + subName.toLowerCase() + "' ORDER BY timestamp DESC !slideshow"; 8 | var tagsyoLink = "http://www.tagsyo.com/q/?q=" + encodeURIComponent(query); 9 | document.getElementById('tagsyo-link').href = tagsyoLink; 10 | console.log("fixed tagsyo link"); 11 | } 12 | 13 | fixTagsyoLink(); 14 | -------------------------------------------------------------------------------- /redditp-redirect/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | nginxredirect: 4 | image: schmunk42/nginx-redirect 5 | environment: 6 | - SERVER_REDIRECT=redditp.com 7 | labels: 8 | - "traefik.port=80" 9 | - "traefik.enable=true" 10 | - "traefik.frontend.rule=Host:www.redditp.com" 11 | - "traefik.docker.network=reverseproxy_default" 12 | networks: 13 | - "reverseproxy_default" 14 | restart: always 15 | logging: 16 | options: 17 | max-size: "50m" 18 | 19 | networks: 20 | reverseproxy_default: 21 | external: 22 | name: reverseproxy_default 23 | 24 | -------------------------------------------------------------------------------- /nodejs/app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | 5 | app.use('/css', express.static(__dirname + '/css')); 6 | app.use('/images', express.static(__dirname + '/images')); 7 | app.use('/js', express.static(__dirname + '/js')); 8 | 9 | 10 | // Always respond with the html, except for the above exceptions. 11 | // Because it's a single page app. 12 | app.get('/*', function(req, res) { 13 | res.sendFile(__dirname + '/index.html'); 14 | }); 15 | 16 | var port = process.env.PORT || 8080; 17 | //app.set('port', port); 18 | 19 | 20 | app.listen(port, function () { 21 | console.log('Listening on port: ' + port); 22 | }); 23 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | redditp: 4 | image: httpd:2.2.32 5 | labels: 6 | - "traefik.enable=true" 7 | - "traefik.docker.network=reverseproxy_default" 8 | - "traefik.backend=redditp" 9 | - "traefik.frontend.rule=Host:redditp.com" 10 | networks: 11 | - "reverseproxy_default" 12 | restart: always 13 | volumes: 14 | - .:/usr/local/apache2/htdocs/:ro 15 | - ./httpd.conf:/usr/local/apache2/conf/httpd.conf:ro 16 | logging: 17 | options: 18 | max-size: "50m" 19 | 20 | networks: 21 | reverseproxy_default: 22 | external: 23 | name: reverseproxy_default 24 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | #Action php54-cgi /php54.cgi 2 | #AddHandler php54-cgi .php 3 | 4 | # Updates here should coincide with rp.getRestOfUrl() 5 | RewriteEngine On 6 | 7 | RewriteBase / 8 | RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC] 9 | RewriteRule ^(.*)$ http://%1/$1 [R=301,L] 10 | 11 | RewriteRule ^r/(.*) /index.html 12 | RewriteRule ^u(ser)?/(.*) /index.html 13 | RewriteRule ^domain/(.*) /index.html 14 | RewriteRule ^search(.*) /index.html 15 | 16 | # to hide .git, allow redditp.com/.compact, and letsencrypt looks at `.well-known` 17 | RewriteRule ^\.([^w].*) /index.html 18 | 19 | # new multireddits with /me/ 20 | RewriteRule ^me/(.*) /index.html 21 | 22 | ErrorDocument 404 /404.html 23 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch via NPM", 11 | "runtimeExecutable": "npm", 12 | "windows": { 13 | "runtimeExecutable": "npm.cmd" 14 | }, 15 | "runtimeArgs": [ 16 | "run", 17 | "debug" 18 | ], 19 | "port": 9229 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /js/jquery.touchwipe.js: -------------------------------------------------------------------------------- 1 | !function(e){e.fn.touchwipe=function(t){var n={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:!0};return t&&e.extend(n,t),this.each(function(){function e(){this.removeEventListener("touchmove",t),o=null,c=!1}function t(t){if(n.preventDefaultEvents&&t.preventDefault(),t.touches.length>=2)return void e();if(c){var i=t.touches[0].pageX,h=t.touches[0].pageY,s=o-i,a=u-h;Math.abs(s)>=n.min_move_x?(e(),s>0?n.wipeLeft():n.wipeRight()):Math.abs(a)>=n.min_move_y&&(e(),a>0?n.wipeDown():n.wipeUp())}}function i(e){1==e.touches.length&&(o=e.touches[0].pageX,u=e.touches[0].pageY,c=!0,this.addEventListener("touchmove",t,!1))}var o,u,c=!1;"ontouchstart"in document.documentElement&&this.addEventListener("touchstart",i,!1)}),this}}(jQuery); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redditp", 3 | "version": "1.0.0", 4 | "description": "Convert reddit urls into slideshows", 5 | "main": "index.html", 6 | "devDependencies": { 7 | "express": "^4.18.2" 8 | }, 9 | "scripts": { 10 | "start": "node server.js", 11 | "debug": "node --inspect server.js", 12 | "test": "node ./nodejs/test-embedit.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ubershmekel/redditp.git" 17 | }, 18 | "keywords": [ 19 | "reddit", 20 | "redditp", 21 | "slideshow", 22 | "images" 23 | ], 24 | "author": "Yuval Greenfield", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/ubershmekel/redditp/issues" 28 | }, 29 | "homepage": "https://github.com/ubershmekel/redditp#readme" 30 | } 31 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // This node server is not required, you can use index.html directly off 2 | // the file system or a static host but you just have to use a question mark e.g.: 3 | // http://localhost:8080/index.html?/r/gifs 4 | 5 | var http = require('http'); 6 | var path = require('path'); 7 | 8 | var express = require('express'); 9 | 10 | var app = express(); 11 | 12 | app.set('port', process.env.PORT || 8080); 13 | 14 | const publicFolder = [ 15 | '.well-known', 16 | 'css', 17 | 'images', 18 | 'js' 19 | ]; 20 | 21 | for (let name of publicFolder) { 22 | app.use('/' + name, express.static(path.join(__dirname, name))); 23 | } 24 | 25 | var server = http.createServer(app); 26 | 27 | app.get('/*', function (req, res) { 28 | res.sendFile(path.join(__dirname, 'index.html')); 29 | }); 30 | 31 | server.listen(app.get('port'), function () { 32 | console.log("Web server listening at: http://localhost:" + app.get('port')); 33 | }); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Windows ### 4 | # Windows image file caches 5 | Thumbs.db 6 | ehthumbs.db 7 | 8 | # Folder config file 9 | Desktop.ini 10 | 11 | # Recycle Bin used on file shares 12 | $RECYCLE.BIN/ 13 | 14 | # Windows Installer files 15 | *.cab 16 | *.msi 17 | *.msm 18 | *.msp 19 | 20 | 21 | ### Node ### 22 | # Logs 23 | logs 24 | *.log 25 | 26 | # Runtime data 27 | pids 28 | *.pid 29 | *.seed 30 | 31 | # Directory for instrumented libs generated by jscoverage/JSCover 32 | lib-cov 33 | 34 | # Coverage directory used by tools like istanbul 35 | coverage 36 | 37 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 38 | .grunt 39 | 40 | # Compiled binary addons (http://nodejs.org/api/addons.html) 41 | build/Release 42 | 43 | # Dependency directory 44 | # Deployed apps should consider commenting this line out: 45 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git 46 | node_modules 47 | /.DS_Store 48 | /.idea 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /js/js.cookie.js: -------------------------------------------------------------------------------- 1 | !function(e){if("function"==typeof define&&define.amd)define(e);else if("object"==typeof exports)module.exports=e();else{var n=window.Cookies,t=window.Cookies=e();t.noConflict=function(){return window.Cookies=n,t}}}(function(){function e(){for(var e=0,n={};e1){if(i=e({path:"/"},o.defaults,i),"number"==typeof i.expires){var s=new Date;s.setMilliseconds(s.getMilliseconds()+864e5*i.expires),i.expires=s}try{c=JSON.stringify(r),/^[\{\[]/.test(c)&&(r=c)}catch(a){}return r=encodeURIComponent(String(r)),r=r.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),n=encodeURIComponent(String(n)),n=n.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),n=n.replace(/[\(\)]/g,escape),document.cookie=[n,"=",r,i.expires&&"; expires="+i.expires.toUTCString(),i.path&&"; path="+i.path,i.domain&&"; domain="+i.domain,i.secure?"; secure":""].join("")}n||(c={});for(var p=document.cookie?document.cookie.split("; "):[],u=/(%[0-9A-Z]{2})+/g,d=0;d 0) { 21 | length -= 1; 22 | method = methods[length]; 23 | 24 | // Only stub undefined methods. 25 | if (!console[method]) { 26 | console[method] = noop; 27 | } 28 | } 29 | }()); 30 | 31 | 32 | // IE doesn't have indexOf... 33 | if (!Array.indexOf) { 34 | // eslint-disable-next-line no-extend-native 35 | Array.prototype.indexOf = function (obj) { 36 | for (var i = 0; i < this.length; i++) { 37 | if (this[i] == obj) { 38 | return i; 39 | } 40 | } 41 | return -1; 42 | }; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /nodejs/test-embedit.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const embedit = require('../js/EmbedIt'); 3 | 4 | const imageTests = [ 5 | { 6 | src: 'https://gfycat.com/gifs/detail/EntireForkedArachnid', 7 | dst: 'EntireForkedArachnid', 8 | }, 9 | { 10 | src: 'https://gfycat.com/EntireForkedArachnid', 11 | dst: 'EntireForkedArachnid', 12 | }, 13 | ]; 14 | 15 | const redGifTests = [ 16 | { 17 | src: 'https://www.redgifs.com/watch/gaseousoblongant', 18 | dst: 'gaseousoblongant', 19 | }, 20 | { 21 | src: 'https://www.redgifs.com/watch/palatableflashybantamrooster-nature', 22 | dst: 'palatableflashybantamrooster-nature', 23 | }, 24 | ]; 25 | 26 | function getIdTests() { 27 | for (let tst of imageTests) { 28 | var result = embedit.gfyUrlToId(tst.src); 29 | if(result !== tst.dst) { 30 | console.warn('Mismatch expected', tst.dst, result); 31 | } else { 32 | console.log('.'); 33 | } 34 | } 35 | 36 | for (let tst of redGifTests) { 37 | var result = embedit.redGifUrlToId(tst.src); 38 | if(result !== tst.dst) { 39 | console.warn('Mismatch expected', tst.dst, result); 40 | } else { 41 | console.log('.'); 42 | } 43 | } 44 | } 45 | 46 | async function redditJsonTests() { 47 | // const redditJson = require('../test-data/reddit.com.json'); 48 | const redditJson = require('../test-data/reddit-image-v2.json'); 49 | const childrenAndAfter = embedit.processRedditJson(redditJson); 50 | const children = childrenAndAfter.children.map(embedit.redditItemToPic); 51 | await fs.promises.writeFile(__dirname + '/../build/result.json', JSON.stringify(childrenAndAfter, null, 4)); 52 | await fs.promises.writeFile(__dirname + '/../build/children.json', JSON.stringify(children, null, 4)); 53 | } 54 | 55 | getIdTests(); 56 | redditJsonTests(); 57 | -------------------------------------------------------------------------------- /dmca.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RedditP DMCA 6 | 10 | 11 | 12 | 29 | 30 | 31 |

Sorry, couldn't find that page probably because of a DMCA takedown.

32 |

33 | Here's a link to the reddit page if that 34 | works. 35 |

36 |

Try these presentations instead:

37 | 63 | 64 |

65 | You could also 66 | find the bug or email 67 | the author. 68 |

69 | 70 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redditp 2 | 3 | A full screen reddit presentation or slide show. 4 | 5 | http://redditp.com 6 | 7 | ## Hotkeys 8 | 9 | - a - toggles auto-next (play/pause) 10 | - t - collapse/uncollapse title 11 | - c - collapse/uncollapse controls 12 | - i - open image in a new tab 13 | - r - open comments in a new tab 14 | - u - open user slideshow in new tab 15 | - f - toggle full screen mode 16 | - m - toggle sound 17 | - g - skip gallery 18 | - Arrow keys, pgup/pgdown, spacebar change slides 19 | - Swipe gestures on phones 20 | 21 | ## Features 22 | 23 | - All /r/ subreddits, including different ?sort stuff. 24 | - /user/ , /domain/ , /me/ url's work. 25 | - Url's ending with ['.jpg', '.jpeg', '.gif', '.bmp', '.png'] 26 | - You can save the html file locally and use it, just make sure you add a 27 | separator e.g. the question mark in file:///c/myredditp.html?/r/gifs so the 28 | browser knows to pick up the right file and go to the right subreddit. 29 | - Support for /r/random and /r/randnsfw virtual subreddits. These'll be tricky 30 | unless I cheat as they contain redirects. 31 | 32 | Possible future features, depending on feedback: 33 | 34 | - Zoom/Pan for comics 35 | - Imgur albums support 36 | - Offline access support, though I don't know if this is even possible actually 37 | (caching external image resources). 38 | - Login and upvoting support 39 | 40 | ## Host your own redditp 41 | 42 | Redditp relies on the `/r/subreddit` in the URL to fetch the JSON from the 43 | corresponding reddit endpoint. There are a few ways you can set up support for 44 | these URLs yourself: 45 | 46 | - You can use an Apache server with the `.htaccess` file. 47 | - Netlify removed redditp without warning. So now we're moving the hosting to 48 | Vercel, Cloudflare, or GitHub pages. Not sure. See vc.redditp.com for Vercel 49 | - Use NodeJS (see `package.json`). 50 | - Use a simple HTTP server and put the subreddit URL in the get parameters like 51 | `http://localhost?/r/subreddit`. 52 | - Use GitHub pages by copying `index.html` into `404.html` which will make all 53 | unknown URLs reach the same `index.html`. This currently only works with a 54 | custom domain because of where the `.js` and `.css` files are located. 55 | 56 | ## Credits 57 | 58 | - Ubershmekel http://yuvalg.com/ 59 | - [js-cookie](https://github.com/js-cookie/js-cookie) for managing cookies 60 | - Favicon by Double-J designs 61 | http://www.iconfinder.com/icondetails/68600/64/_icon 62 | - Slideshow based on http://demo.marcofolio.net/fullscreen_image_slider/ 63 | - Author of slideshow base: Marco Kuiper (http://www.marcofolio.net/) 64 | - And many more that have contributed to this project through feedback and pull 65 | requests https://github.com/ubershmekel/redditp/graphs/contributors 66 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | RedditP 404 6 | 10 | 11 | 12 | 29 | 30 | 31 |

Sorry, couldn't find that page (404)...

32 |

Maybe try these presentations instead:

33 | 59 | 60 |

61 | You could also 62 | find the bug or email 63 | the author. 64 |

65 | 66 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | /* BASIC RESET */ 2 | ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,body,html,p,blockquote,fieldset,input{margin:0; padding:0;} 3 | 4 | /* HTML ELEMENTS */ 5 | body { overflow:hidden; background-color: #000; color:#fff;} 6 | 7 | /* PICTURES */ 8 | #pictureSlider { 9 | position: absolute; 10 | left: 0; 11 | top: 0; 12 | width: 100%; 13 | height: 100%; 14 | z-index:-999; 15 | } 16 | 17 | #pictureSlider div { height:100%; width:100%; position:absolute; z-index:-999; } 18 | 19 | /* NAVIGATION BOX */ 20 | #navigationBoxes {float: left;} 21 | a { text-decoration:none; color:#eee; font-weight: bold; } 22 | a:hover { 23 | opacity: 1.0; 24 | border-bottom:1px dotted; 25 | } 26 | .navbox { width:450px; max-height: 40%; overflow: auto; position:relative; left: 0px; opacity: 0.9; background-color: rgba(0,0,0,0.7);z-index:2;} 27 | /* 108px so the next row is half-visible */ 28 | .numberButtonList { overflow: auto; max-height: 108px; } 29 | .navbox ul { list-style-type:none; display:block; margin:0px; right:10px; top:10px; text-align: left;} 30 | .navbox ul li { display: inline-block; list-style-type: none; } 31 | .numberButton { 32 | float: left; 33 | 34 | min-width: 15px; 35 | margin-left: 5px; 36 | text-decoration: none; 37 | color: #eee; 38 | 39 | font: bold 12px Helvetica, Arial, Sans-serif; 40 | text-align: center; 41 | line-height: 18px; 42 | padding: 3px 5px; 43 | } 44 | .over18 { 45 | color: #f99; 46 | } 47 | .galleryCount { 48 | color: rgb(158, 217, 8); 49 | } 50 | .navbox ul li a { 51 | cursor:pointer; 52 | 53 | } 54 | .numberButtonList ul li a:hover { background:#888; border: 0; } 55 | .numberButtonList ul li a.active { 56 | color: #00AAAA; 57 | -moz-box-shadow: 2px 2px 3px #eee; 58 | /* For IE 8 */ 59 | -ms-filter: "progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color='#EEEEEE')"; 60 | /* For IE 5.5 - 7 */ 61 | filter: progid:DXImageTransform.Microsoft.Shadow(Strength=3, Direction=135, Color='#EEEEEE'); 62 | } 63 | 64 | #controlsDiv {position: absolute; bottom: 64px; left: 0;right: 0;} 65 | #titleDiv {position: absolute; top: 0;left: 0;right: 0;} 66 | .navbox h2 { padding: 10px 20px 10px 10px; font: bold 20px Helvetica, Arial, Sans-serif; } 67 | .navbox h3 { padding: 0px 20px 10px 10px; font: bold 12px Helvetica, Arial, Sans-serif; } 68 | .navbox p { padding:20px 20px 20px 20px; font-family: "Segoe UI","HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Arial,Tahoma,Verdana,sans-serif; font-size:13px; color:#111; } 69 | .navbox p.bottom { position:absolute; bottom:5px; right:5px; } 70 | 71 | .nbmenu { 72 | margin: 0 0 0 5px; 73 | width: 100%; 74 | font-family: "Segoe UI","HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Arial,Tahoma,Verdana,sans-serif; 75 | font-size:14px; 76 | 77 | } 78 | 79 | .nbmenu li { 80 | text-align: left; 81 | padding: 6px; 82 | max-width: 300px; 83 | overflow: hidden; 84 | } 85 | 86 | #navboxContents { 87 | padding: 10px 25px 10px 0; 88 | margin:0; 89 | } 90 | 91 | label.checkbox { font-weight: bold; } 92 | 93 | .cam { background-image:url("../images/bg_cam_txt.png"); } 94 | .clouds { } 95 | .key { background-image:url("../images/bg_key_txt.png"); } 96 | .flowers { background-image:url("../images/bg_flowers_txt.png"); } 97 | 98 | .collapser { border: solid 1px #555; font-size: 20px; color: #bbb; padding: 0 10px; float:right; cursor: hand; cursor: pointer;} 99 | .checkbox { cursor: hand; cursor: pointer; } 100 | 101 | .prevArrow { 102 | position: absolute; 103 | top: 50%; 104 | left: 10px; 105 | width: 0; 106 | height: 0; 107 | 108 | border-top: 25px solid transparent; 109 | border-bottom: 25px solid transparent; 110 | border-right: 50px solid white; 111 | z-index:2; 112 | opacity: 0.8; 113 | 114 | cursor: hand; cursor: pointer; 115 | } 116 | 117 | .nextArrow { 118 | position: absolute; 119 | top: 50%; 120 | right: 10px; 121 | width: 0; 122 | height: 0; 123 | 124 | border-top: 25px solid transparent; 125 | border-bottom: 25px solid transparent; 126 | border-left: 50px solid white; 127 | z-index:2; 128 | opacity: 0.8; 129 | cursor: hand; cursor: pointer; 130 | } 131 | 132 | #fullScreenButton { 133 | width: 20px; 134 | padding-left: 10px; 135 | cursor:pointer; 136 | } 137 | 138 | #playButton { 139 | position: absolute; 140 | left: 0; 141 | top: 0; 142 | width: 100%; 143 | height: 100%; 144 | cursor: pointer; 145 | z-index: 2 146 | } 147 | -------------------------------------------------------------------------------- /images/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 23 | 27 | 31 | 32 | 43 | 54 | 55 | 77 | 79 | 80 | 82 | image/svg+xml 83 | 85 | 86 | 87 | 88 | 89 | 94 | 97 | 102 | Mobile browserswon't autoplaywithout a tap 124 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "browser": true 4 | }, 5 | "globals": { 6 | "$": false, 7 | "toastr": false, 8 | "Cookies": false, 9 | "embedit": false, 10 | }, 11 | "extends": "eslint:recommended", 12 | "rules": { 13 | "accessor-pairs": "error", 14 | "array-bracket-newline": "error", 15 | "array-bracket-spacing": [ 16 | "error", 17 | "never" 18 | ], 19 | "array-callback-return": "error", 20 | "array-element-newline": "off", 21 | "arrow-body-style": "error", 22 | "arrow-parens": "error", 23 | "arrow-spacing": "error", 24 | "block-scoped-var": "off", 25 | "block-spacing": [ 26 | "error", 27 | "never" 28 | ], 29 | "brace-style": "off", 30 | "callback-return": "error", 31 | "camelcase": "off", 32 | "capitalized-comments": "off", 33 | "class-methods-use-this": "error", 34 | "comma-dangle": "off", 35 | "comma-spacing": "off", 36 | "comma-style": [ 37 | "error", 38 | "last" 39 | ], 40 | "complexity": "error", 41 | "computed-property-spacing": [ 42 | "error", 43 | "never" 44 | ], 45 | "consistent-return": "off", 46 | "consistent-this": "error", 47 | "curly": "off", 48 | "default-case": "off", 49 | "dot-location": [ 50 | "error", 51 | "property" 52 | ], 53 | "dot-notation": "off", 54 | "eol-last": "error", 55 | "eqeqeq": "off", 56 | "for-direction": "error", 57 | "func-call-spacing": "error", 58 | "func-name-matching": "error", 59 | "func-names": [ 60 | "error", 61 | "never" 62 | ], 63 | "func-style": "off", 64 | "function-paren-newline": "off", 65 | "generator-star-spacing": "error", 66 | "getter-return": "error", 67 | "global-require": "error", 68 | "guard-for-in": "error", 69 | "handle-callback-err": "error", 70 | "id-blacklist": "error", 71 | "id-length": "off", 72 | "id-match": "error", 73 | "implicit-arrow-linebreak": "error", 74 | "indent": "off", 75 | "indent-legacy": "off", 76 | "init-declarations": "off", 77 | "jsx-quotes": "error", 78 | "key-spacing": "off", 79 | "keyword-spacing": "off", 80 | "line-comment-position": "off", 81 | "linebreak-style": [ 82 | "error", 83 | "unix" 84 | ], 85 | "lines-around-comment": "off", 86 | "lines-around-directive": "error", 87 | "lines-between-class-members": "error", 88 | "max-depth": "error", 89 | "max-len": "off", 90 | "max-lines": "off", 91 | "max-nested-callbacks": "error", 92 | "max-params": "error", 93 | "max-statements": "off", 94 | "max-statements-per-line": "error", 95 | "multiline-comment-style": "off", 96 | "new-cap": "error", 97 | "new-parens": "error", 98 | "newline-after-var": "off", 99 | "newline-before-return": "off", 100 | "newline-per-chained-call": "off", 101 | "no-alert": "error", 102 | "no-array-constructor": "error", 103 | "no-await-in-loop": "error", 104 | "no-bitwise": "error", 105 | "no-buffer-constructor": "error", 106 | "no-caller": "error", 107 | "no-catch-shadow": "error", 108 | "no-confusing-arrow": "error", 109 | "no-console": "off", 110 | "no-continue": "off", 111 | "no-div-regex": "error", 112 | "no-duplicate-imports": "error", 113 | "no-else-return": "off", 114 | "no-empty-function": "error", 115 | "no-eq-null": "off", 116 | "no-eval": "error", 117 | "no-extend-native": "error", 118 | "no-extra-bind": "error", 119 | "no-extra-label": "error", 120 | "no-extra-parens": "off", 121 | "no-floating-decimal": "error", 122 | "no-implicit-globals": "off", 123 | "no-implied-eval": "error", 124 | "no-inline-comments": "off", 125 | "no-inner-declarations": [ 126 | "error", 127 | "functions" 128 | ], 129 | "no-invalid-this": "error", 130 | "no-iterator": "error", 131 | "no-label-var": "error", 132 | "no-labels": "error", 133 | "no-lone-blocks": "error", 134 | "no-lonely-if": "off", 135 | "no-loop-func": "error", 136 | "no-magic-numbers": "off", 137 | "no-mixed-operators": [ 138 | "error", 139 | { 140 | "allowSamePrecedence": true 141 | } 142 | ], 143 | "no-mixed-requires": "error", 144 | "no-multi-assign": "error", 145 | "no-multi-spaces": "off", 146 | "no-multi-str": "error", 147 | "no-multiple-empty-lines": "off", 148 | "no-native-reassign": "error", 149 | "no-negated-condition": "off", 150 | "no-negated-in-lhs": "error", 151 | "no-nested-ternary": "error", 152 | "no-new": "error", 153 | "no-new-func": "error", 154 | "no-new-object": "error", 155 | "no-new-require": "error", 156 | "no-new-wrappers": "error", 157 | "no-octal-escape": "error", 158 | "no-param-reassign": "off", 159 | "no-path-concat": "error", 160 | "no-plusplus": [ 161 | "error", 162 | { 163 | "allowForLoopAfterthoughts": true 164 | } 165 | ], 166 | "no-process-env": "error", 167 | "no-process-exit": "error", 168 | "no-proto": "error", 169 | "no-prototype-builtins": "error", 170 | "no-restricted-globals": "error", 171 | "no-restricted-imports": "error", 172 | "no-restricted-modules": "error", 173 | "no-restricted-properties": "error", 174 | "no-restricted-syntax": "error", 175 | "no-return-assign": "error", 176 | "no-return-await": "error", 177 | "no-script-url": "error", 178 | "no-self-compare": "error", 179 | "no-sequences": "error", 180 | "no-shadow": "error", 181 | "no-shadow-restricted-names": "error", 182 | "no-spaced-func": "error", 183 | "no-sync": "error", 184 | "no-tabs": "error", 185 | "no-template-curly-in-string": "error", 186 | "no-ternary": "off", 187 | "no-throw-literal": "error", 188 | "no-trailing-spaces": "off", 189 | "no-undef-init": "error", 190 | "no-undefined": "off", 191 | "no-underscore-dangle": "error", 192 | "no-unmodified-loop-condition": "error", 193 | "no-unneeded-ternary": "error", 194 | "no-unused-expressions": "error", 195 | "no-use-before-define": "off", 196 | "no-useless-call": "error", 197 | "no-useless-computed-key": "error", 198 | "no-useless-concat": "off", 199 | "no-useless-constructor": "error", 200 | "no-useless-rename": "error", 201 | "no-useless-return": "error", 202 | "no-var": "off", 203 | "no-void": "error", 204 | "no-warning-comments": "off", 205 | "no-whitespace-before-property": "error", 206 | "no-with": "error", 207 | "object-curly-newline": "off", 208 | "object-curly-spacing": "off", 209 | "object-property-newline": "error", 210 | "object-shorthand": "off", 211 | "one-var": "off", 212 | "one-var-declaration-per-line": "error", 213 | "operator-assignment": [ 214 | "error", 215 | "always" 216 | ], 217 | "operator-linebreak": "error", 218 | "padded-blocks": "off", 219 | "padding-line-between-statements": "error", 220 | "prefer-arrow-callback": "off", 221 | "prefer-const": "error", 222 | "prefer-destructuring": "off", 223 | "prefer-numeric-literals": "error", 224 | "prefer-promise-reject-errors": "error", 225 | "prefer-reflect": "off", 226 | "prefer-rest-params": "off", 227 | "prefer-spread": "error", 228 | "prefer-template": "off", 229 | "quote-props": "off", 230 | "quotes": "off", 231 | "radix": "error", 232 | "require-await": "error", 233 | "require-jsdoc": "off", 234 | "rest-spread-spacing": "error", 235 | "semi": "off", 236 | "semi-spacing": [ 237 | "error", 238 | { 239 | "after": true, 240 | "before": false 241 | } 242 | ], 243 | "semi-style": [ 244 | "error", 245 | "last" 246 | ], 247 | "sort-imports": "error", 248 | "sort-keys": "off", 249 | "sort-vars": "error", 250 | "space-before-blocks": "off", 251 | "space-before-function-paren": "off", 252 | "space-in-parens": "off", 253 | "space-infix-ops": "error", 254 | "space-unary-ops": "error", 255 | "spaced-comment": "off", 256 | "strict": [ 257 | "error", 258 | "never" 259 | ], 260 | "switch-colon-spacing": "error", 261 | "symbol-description": "error", 262 | "template-curly-spacing": "error", 263 | "template-tag-spacing": "error", 264 | "unicode-bom": [ 265 | "error", 266 | "never" 267 | ], 268 | "valid-jsdoc": "error", 269 | "vars-on-top": "off", 270 | "wrap-iife": "error", 271 | "wrap-regex": "error", 272 | "yield-star-spacing": "error" 273 | } 274 | }; -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | redditP 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 31 | 32 | 33 | 36 | 69 | 70 | 73 | 76 | 92 | 113 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
125 |
126 | 127 | 197 | 209 | 210 | 245 | 246 | 247 |
248 | 249 |
250 | 251 |
252 |
253 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /js/EmbedIt.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-global-assign,no-native-reassign 2 | embedit = {}; 3 | 4 | embedit.imageTypes = { 5 | image: "image", 6 | gfycat: "gfycat", 7 | gifv: "gifv", 8 | redgif: "redgif", 9 | }; 10 | 11 | embedit.redditBaseUrl = "http://old.reddit.com"; 12 | 13 | if (typeof window === "undefined") { 14 | // eslint-disable-next-line no-redeclare 15 | var window = {}; 16 | } 17 | 18 | if (window.location && window.location.protocol === "https:") { 19 | // page is secure 20 | embedit.redditBaseUrl = "https://old.reddit.com"; 21 | } 22 | 23 | embedit.video = function (webmUrl, mp4Url) { 24 | // imgur is annoying and when you use the tags 25 | // it tries to redirect you to the gifv page instead of serving 26 | // video. We can only circumvent that by putting the src 27 | // on the