- // ==UserScript==
- // @name One Click Copy URIs
- // @namespace http://github.com/kba
- // @version 0.2
- // @description Adds buttons to text links and videos to copy the linked URI to clipboard in one click.
- // @author kba
- // @match */*
-
- // @grant GM_setValue
- // @grant GM_getValue
- // @grant GM_registerMenuCommand
- // @grant GM_log
-
- // @require https://greasyfork.org/libraries/GM_config/20131122/GM_config.js
- // @require https://code.jquery.com/jquery-2.2.0.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.5.8/clipboard.min.js
-
- // ==/UserScript==
- /* jshint -W097, esnext:true */
- /* globals GM_log, GM_setValue, GM_getValue, GM_registerMenuCommand, GM_config, Clipboard, $ */
- 'use strict';
-
- // Setup configuration
- GM_config.init({
- 'id': 'one-click-copy',
- 'title': 'Configure OneClickCopy',
- 'fields': {
-
- 'auto_video': {
- 'label': 'Add Copy Button to all videos?',
- 'type': 'checkbox',
- 'default': false,
- },
-
- 'timeout': {
- 'label': 'Delay in ms before adding button to video',
- 'type': 'number',
- 'default': 1500,
- },
-
- 'auto_text': {
- 'label': 'Add Copy Button to all Text links?',
- 'type': 'checkbox',
- 'default': false,
- },
-
- "include_links": {
- 'label': 'Selectors to find text links. First matching selector is used.',
- 'type': 'textarea',
- 'rows': 5,
- 'width': 30,
- 'default': [
- '#content a[href]',
- 'a[href]'
- ].join("\n"),
- },
-
-
- "skip_parents": {
- 'label': 'Skip text links that are children of parents matching these selectors',
- 'type': 'textarea',
- 'rows': 10,
- 'width': 30,
- 'default': [
- 'header',
- '#header',
- 'footer',
- '#footer',
- '#tags',
- '*[id*=tags]',
- '*[class*=tags]',
- '#categories',
- '*[id*=categories]',
- '*[class*=categories]',
- '#navigation',
- '.nav',
- '*[role="navigation"]',
- ].join("\n"),
- },
-
- },
-
- });
-
- // Helper to add inline CSS rules
- function addCSSRules(rules) {
- var style = document.createElement("style");
- style.innerHTML = rules.replace(/;/g, '!important ;');
- document.head.appendChild(style);
- }
-
- // Add CSS
- $('head').append($('<style>').append(`
-
- .gm-link-tools {
- position: relative;
- display: inline-block;
- line-height: 1;
- padding: 0 2px;
- cursor: copy;
- font-size: 150%;
- opacity: 1;
- vertical-align: middle;
- background: gray;
- color: white;
- height: initial;
- width: initial;
- z-index: 1001;
- }
-
- .gm-link-tools > span {
- display: block;
- overflow:hidden;
- max-height:100%;
- }
-
- .gm-link-tools.copied {
- color: #6f5;
- }
-
- `));
-
- // The rules that determine which links are skipped
- var skip_parents = GM_config.get('skip_parents').split(/\n/g);
- var excludeMatchers = {
- 'numeric': function($link) { return /^\d+$/.test($link.html()); },
- 'image': function($link) { return $("img", $link).length; },
- 'parent': function($link) {
- for (var i = 0 ; i < skip_parents.length ; i++) {
- if ($link.parents(skip_parents[i]).length > 0) {
- return skip_parents[i];
- }
- }
- },
- };
-
- // Create the button
- function createCopyLink(href) {
- return $(`
- <a data-clipboard-text="${href}" title="Copy to Clipboard" class="gm-link-tools">
- <span>∀</span>
- </a>
- `);
- }
-
- // Add clipboard functionality to copy button and add after element
- function appendClipboardLink($el, $copyLink) {
- var clipboard = new Clipboard($copyLink[0]);
- clipboard.on('success', function(e) {
- $copyLink.addClass("copied");
- $copyLink.html('<span>✔</span>');
- return false;
- });
- clipboard.on('error', function(e) {
- $copyLink.addClass("failed");
- $copyLink.html('<span>X</span>');
- });
- $("<span>")
- .on('click tap mousedown touchstart', function(evt) {
- evt.stopPropagation();
- return false;
- })
- .append($copyLink)
- .insertAfter($el);
- }
-
- //
- // Text Links
- //
-
- function clippifyLink(){
- /* jshint validthis:true */
- var $link = $(this);
- for (var rule in excludeMatchers) {
- var result = excludeMatchers[rule]($link);
- if (result) {
- GM_log(`SKIP ${rule}/${result}: '${$link.text()}'`);
- return;
- }
- }
- var href = $link[0].href;
- var $copyLink = createCopyLink(href);
- appendClipboardLink($link, $copyLink);
- }
-
- function clippifyLinks(){
- var links;
- var includeLinks = GM_config.get('include_links').split(/\n/g);
- for (var i = 0 ; i < includeLinks.length ; i++) {
- links = $(includeLinks[i]);
- if (links.length > 0) {
- break;
- }
- }
- $(links).each(clippifyLink);
- }
-
- //
- // Videos
- //
-
- function clippifyVideo() {
- /* jshint validthis:true */
- var $video = $(this);
- var src = $video[0].currentSrc;
- if (! src) return;
- var $copyLink = createCopyLink(src);
- appendClipboardLink($video, $copyLink);
- }
-
- function clippifyVideos() {
- $("video").each(clippifyVideo);
- }
-
- //
- // Setup menu commands
- //
- GM_registerMenuCommand('Configure One-Click-Copy', GM_config.open.bind(GM_config), 'c');
- GM_registerMenuCommand("Text Links: Add Copy Button", clippifyLinks, "l");
- GM_registerMenuCommand("Videos: Add Copy Button", clippifyVideos, "v");
-
- //
- // Automate adding buttons
- //
- if (GM_config.get('auto_video')) {
- setTimeout(function() {
- $("video").one('progress', clippifyVideo);
- }, GM_config.get('timeout'));
- }
- if (GM_config.get('auto_text')) {
- setTimeout(function() {
- clippifyLinks();
- }, GM_config.get('timeout'));
- }
-
-
-
-
-
-
- // vim: set noet ts=4 sw=4 :