Size
5.7 KB
Version
0.1.2
Created
Nov 25, 2025
Updated
about 2 months ago
1/**
2 *
3 * This is a Greasemonkey script and must be run using a Greasemonkey-compatible browser.
4 *
5 * @author maymay <bitetheappleback@gmail.com>
6 */
7// ==UserScript==
8// @name FetLife Video Sharer
9// @version 0.1.2
10// @namespace com.maybemaimed.fetlife
11// @updateURL https://github.com/meitar/fetlife-video-sharer/raw/master/fetlife-video-sharer.user.js
12// @description Lets you share videos on FetLife with anyone for free.
13// @match https://fetlife.com/*
14// @grant GM_addStyle
15// @grant GM_log
16// ==/UserScript==
17
18FL_VIDSHARE = {};
19FL_VIDSHARE.CONFIG = {
20 'debug': false, // switch to true to debug.
21};
22
23// Utility debugging function.
24FL_VIDSHARE.log = function (msg) {
25 if (!FL_VIDSHARE.CONFIG.debug) { return; }
26 GM_log('FETLIFE VIDEO SHARER: ' + msg);
27};
28
29// Initializations.
30var uw = (unsafeWindow) ? unsafeWindow : window ; // Help with Chrome compatibility?
31GM_addStyle('\
32');
33FL_VIDSHARE.init = function () {
34 FL_VIDSHARE.main();
35};
36window.addEventListener('DOMContentLoaded', FL_VIDSHARE.init);
37
38// This is the main() function, executed on page load.
39FL_VIDSHARE.main = function () {
40 // Scan page for any FetLife video links.
41 var vid_links = [];
42 for (var i = 0; i < document.links.length; i++) {
43 if (document.links[i].getAttribute('href').match(/videocdn\.fetlife\.com\/videos\/\S+\/encoded\.mp4$/)) {
44 vid_links.push(document.links[i]);
45 }
46 }
47 // For any found, add a "share this video" link.
48 for (var i = 0; i < vid_links.length; i++) {
49 var id = 'fetlife-video-sharer-link-' + i;
50 FL_VIDSHARE.injectDialog(id, vid_links[i].getAttribute('href'));
51 var trigger_el = document.createElement('a');
52 trigger_el.setAttribute('class', 'opens-modal');
53 trigger_el.setAttribute('data-opens-modal', id);
54 trigger_el.setAttribute('data-opens-modal', id);
55 trigger_el.innerHTML = '(share this video)';
56 var before = vid_links[i];
57 before.parentNode.insertBefore(trigger_el, before.nextSibling);
58 }
59 var sv = document.getElementById('video');
60 if (sv) {
61 // Grab the direct video link.
62 var m = sv.innerHTML.match(/videocdn\.fetlife\.com\/videos\/\S+\/encoded\.mp4/);
63 if (m) {
64 FL_VIDSHARE.log('Found match in #video element.');
65 FL_VIDSHARE.injectDialog('fetlife-video-sharer-share-this-video', 'https://' + m[0]);
66 var trigger_el = document.createElement('a');
67 trigger_el.setAttribute('class', 'opens-modal');
68 trigger_el.setAttribute('data-opens-modal', 'fetlife-video-sharer-share-this-video');
69 trigger_el.setAttribute('data-opens-modal', 'fetlife-video-sharer-share-this-video');
70 trigger_el.setAttribute('href', '#');
71 trigger_el.innerHTML = '<strong><big>Share this video!</big></strong>';
72 var li = document.createElement('li');
73 li.appendChild(trigger_el);
74 document.querySelector('li.duration').parentNode.appendChild(li);
75 }
76 }
77};
78
79FL_VIDSHARE.injectDialog = function (id, vid_url) {
80 var id = id || 'fetlife-video-sharer-link-0';
81 // Inject dialog box HTML. FetLife currently uses Rails 3, so mimic that.
82 // See, for instance, Rails Behaviors: http://josh.github.com/rails-behaviors/
83 var dialog = document.createElement('div');
84 dialog.setAttribute('style', 'display: none; position: absolute; overflow: hidden; z-index: 1000; outline: 0px none;');
85 dialog.setAttribute('class', 'ui-dialog ui-widget ui-widget-content ui-corner-all');
86 dialog.setAttribute('tabindex', '-1');
87 dialog.setAttribute('role', 'dialog');
88 dialog.setAttribute('aria-labelledby', 'ui-dialog-title-' + id);
89 var html_string = '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" unselectable="on" style="-moz-user-select: none;">';
90 html_string += '<span class="ui-dialog-title" id="ui-dialog-title-' + id + '" unselectable="on" style="-moz-user-select: none;">Share this video!</span>';
91 html_string += '<a href="#" class="ui-dialog-titlebar-close ui-corner-all" role="button" unselectable="on" style="-moz-user-select: none;">';
92 html_string += '<span class="ui-icon ui-icon-closethick" unselectable="on" style="-moz-user-select: none;">close</span>';
93 html_string += '</a>';
94 html_string += '</div>';
95 html_string += '<div data-modal-title="Share this video!" data-modal-height="280" data-modal-auto-open="false" class="modal ui-dialog-content ui-widget-content" id="' + id + '">';
96 html_string += '<p>The <em style="font-size:larger;">free, direct link</em> to this video is:</p>';
97 html_string += '<p><a href="' + vid_url + '">' + vid_url + '</a></p>';
98 html_string += '<p>How would you like to help others get their perv on?</p>';
99 html_string += '<p id="' + id + '-actions" class="ac">';
100 html_string += '<a rel="nofollow" href="https://twitter.com/intent/tweet/?text=' + encodeURIComponent(vid_url) + '" target="_blank">Tweet link to video</a>';
101 html_string += '<span class="i s q"> -or- </span>';
102 html_string += '<a rel="nofollow" href="mailto:?subject=' + encodeURIComponent('Check out this hot video!') + '&body=' + encodeURIComponent(vid_url) + '" target="_blank">Send link to video in email</a>';
103// html_string += '<span class="i s q"> -or- </span>';
104// html_string += '<a rel="nofollow" href="https://fetlife.com/conversations/new?with=" target="_blank">Send link to video in FetLife Conversation</a>';
105 html_string += '<span class="i s q"> -or- </span>';
106 html_string += '<a data-closes-modal="' + id + '" class="close tdn q" href="#">Cancel</a>';
107 html_string += '</p>';
108 html_string += '</div>';
109 dialog.innerHTML = html_string;
110 document.body.appendChild(dialog);
111};
112