How to create 1-click Copy links? - javascript

For this linkify plus script, I'm trying to make the href links 1-click copy to the clipboard, using GM_Setclipboard.
The script works fine if the webpage in question only finds and "linkifies" one string of text. If it linkifies two strings, the 1-click copy function works on both links but will only copy the last string to be "linkified".
I'm not even sure what I am trying to do is possible. Found some similar questions/workarounds that use flash+jQuery+zeroClipboard. But not sure if I can implement this into a Greasemonkey script.
// ==UserScript==
// #name 1Click_COPY
// #include http*://www.w3schools.com/*
// $Revision: #2 $
// ==/UserScript==
// Originally written by Anthony Lieuallen of http://www.arantius.com/
// Licensed for unlimited modification and redistribution as long as this notice is kept intact.
//
// If possible, please contact me regarding new features, bugfixes
// or changes that I could integrate into the existing code instead of
// creating a different script. Thank you
(function (){
function linkify () {
try {
var notInTags=['a', 'head', 'noscript', 'option', 'script', 'style', 'title', 'textarea'];
var res = document.evaluate("//text()[not(ancestor::"+notInTags.join(') and not(ancestor::')+")]",
document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i, el, l, m, p, span, txt, urlRE, linky;
//The string you want to find using reg ex. This finds http to create links.
urlRE=/\b(https?:\/\/[^\s+\"\<\>]+)/ig.
for (i=0; el=res.snapshotItem(i); i++) {
//grab the text of this element and be sure it has a URL in it
txt=el.textContent;
span=null;
p=0;
while (m=urlRE.exec(txt)) {
if (null==span) {
//create a span to hold the new text with links in it
span=document.createElement('span');
}
//get the link without trailing dots
l=m[0].replace(/\.*$/, '');
//put in text up to the link
span.appendChild(document.createTextNode(txt.substring(p, m.index)));
//create a link and put it in the span
a=document.createElement('a');
a.className='linkifyplus';
a.appendChild(document.createTextNode(l));
a.setAttribute('href', l);
//a.setAttribute('onclick', "return false");
//linky=a.getAttritube('href');
//a.setAttritube("onclick", function() { GM_setClipboard(l, 'text')
} );
//copy text to clipboard
a.onclick = function() { GM_setClipboard(l, 'text'); return false};
span.appendChild(a);
p=m.index+m[0].length;
}
// This removes the non linked text
if (span) {
//take the text after the last link
span.appendChild(document.createTextNode(txt.substring(p, txt.length)));
//replace the original text with the new span
el.parentNode.replaceChild(span, el);
}
}
}
catch(e) {dump('Linkify Plus Error ('+e.lineNumber+'): '+e+'\n');}
}
window.addEventListener("load", linkify, false);
} ) ();

Use Anthony Lieuallen latest v2.0.2 of the script. GM_setClipboard works like a charm now. See below:
// ==UserScript==
// #name Linkify Plus
// #version 2.0.2
// #namespace http://arantius.com/misc/greasemonkey/
// #description Turn plain text URLs into links. Supports http, https, ftp, email addresses.
// #grant GM_setClipboard
// ==/UserScript==
/*******************************************************************************
Loosely based on the Linkify script located at:
http://downloads.mozdev.org/greasemonkey/linkify.user.js
Originally written by Anthony Lieuallen of http://arantius.com/
Licensed for unlimited modification and redistribution as long as
this notice is kept intact.
If possible, please contact me regarding new features, bugfixes
or changes that I could integrate into the existing code instead of
creating a different script. Thank you.
Version history:
Version 2.0.3:
- Fix infinite recursion on X(HT)ML pages.
Version 2.0.2:
- Limit #include, for greater site/plugin compatibility.
Version 2.0.1:
- Fix aberrant 'mailto:' where it does not belong.
Version 2.0:
- Apply incrementally, so the browser does not hang on large pages.
- Continually apply to new content added to the page (i.e. AJAX).
Version 1.1.4:
- Basic "don't screw up xml pretty printing" exception case
Version 1.1.3:
- Include "+" in the username of email addresses.
Version 1.1.2:
- Include "." in the username of email addresses.
Version 1.1:
- Fixed a big that caused the first link in a piece of text to
be skipped (i.e. not linkified).
*******************************************************************************/
var notInTags=[
'a', 'head', 'noscript', 'option', 'script', 'style', 'title', 'textarea'
];
var textNodeXpath=
".//text()[not(ancestor::ns:"+notInTags.join(') and not(ancestor::ns:')+")]";
//Insert Your personal Regex below. (My example: ip + port in "xxx.xxx.xxx.xxx PORT" format)
var urlRE=/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\s\d{1,5}\b/gi;
var queue=[];
/******************************************************************************/
linkifyContainer(document.body);
document.body.addEventListener('DOMNodeInserted', function(event) {
linkifyContainer(event.target);
}, false);
/******************************************************************************/
function linkifyContainer(container) {
var xpathResult=document.evaluate(
textNodeXpath,
container,
{ lookupNamespaceURI: function(prefix) { return container.namespaceURI; } },
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null
);
var i=0;
function continuation() {
var node, counter=0;
while (node=xpathResult.snapshotItem(i++)) {
linkifyTextNode(node);
if (++counter>50) {
return setTimeout(continuation, 0);
}
}
}
setTimeout(continuation, 0);
}
function linkifyTextNode(node) {
var i, l, m;
var txt=node.textContent;
var span=null;
var p=0;
while (m=urlRE.exec(txt)) {
if (null==span) {
//create a span to hold the new text with links in it
span=document.createElement('span');
}
//get the link without trailing dots
l=m[0].replace(/\.*$/, '');
//put in text up to the link
span.appendChild(document.createTextNode(txt.substring(p, m.index)));
//create a link and put it in the span
a=document.createElement('a');
a.appendChild(document.createTextNode(l));
//if (l.match(/^www/i)) {
// l='http://'+l;
//} else if (-1==l.indexOf('://')) {
// l='mailto:'+l;
//}
a.setAttribute('href', l);
a.onclick = function() { GM_setClipboard(l, 'text'); return false};
span.appendChild(a);
//track insertion point
p=m.index+m[0].length;
}
if (span) {
//take the text after the last link
span.appendChild(document.createTextNode(txt.substring(p, txt.length)));
//replace the original text with the new span
try {
node.parentNode.replaceChild(span, node);
} catch (e) {
console.error(e);
console.log(node);
}
}
}

http://www.htmlgoodies.com/beyond/javascript/article.php/3458851
See if this helps.
I am right now on phone so can't explore much. Will try once I get on a system.

Related

Do an action based on presence of ALT attribute with Javascript

I have some javascript which looks at the body and finds words and if one is present, it outputs a div. This is useful for many things, however...
What I need to do is also look at the body and all the ALT tags for the page as well.
I found this: Use javascript to hide element based on ALT TAG only?
Which seems to change the ALT attribute, however I want to perform an action.
Here's my JS so far.
var bodytext = $('body').text();
if(bodytext.toLowerCase().indexOf('one' || 'two')==-1)
return;
var elem = $("<div>Text Here</div>");
Thank you.
P.S. I am a N00B/ relatively new at JS, I am doing this for a small project, so I am not sure where to start for this in terms of JS functions.
Updated Answer
Try this out, I commented the code to explain it a bit.
// build array of triggers
var triggers = ['trigger1','trigger2','trigger3'];
// wait for page to load
$(function() {
// show loading overlay
$('body').append('<div id="mypluginname-overlay" style="height:100%;width:100%;background-color:#FFF;"></div>');
// check page title
var $title = $('head title');
for(trigger of triggers) {
if($($title).innerHTML.toLowerCase().indexOf(trigger) >= 0) {
$($title).innerHTML = '*censored*';
}
}
// check all meta
$('meta').each(function() {
var $meta = $(this);
for(trigger of triggers) {
if($($meta).attr('name').toLowerCase().indexOf(trigger) >= 0) {
censorPage();
return; //stop script if entire page must be censored
} else if($($meta).attr('content').toLowerCase().indexOf(trigger) >= 0) {
censorPage();
return; //stop script if entire page must be censored
}
}
});
// check all img
$('img').each(function() {
var $img = $(this);
for(trigger of triggers) {
if($($img).attr('alt').toLowerCase().indexOf(trigger) >= 0) {
censor($img);
}
}
});
// check all video
$('video').each(function() {
var $video = $(this);
for(trigger of triggers) {
if($($video).attr('alt').toLowerCase().indexOf(trigger) >= 0) {
censor($video);
}
}
});
// if you want to be extra careful and check things like background image name,
// you'll have to run this code here - very inefficent
// but necessary if you want to check every single element's background image name:
for($element of $('body').children()) {
for(trigger of triggers) {
if($($element).css('background-image').toLowerCase().indexOf(trigger) >= 0) {
$($element).css('background-image','');
}
}
}
, function() { // Not sure if this is totally correct syntax, but use a callback function to determine when
// when the rest of the script has finished running
// hide overlay
$('#mypluginname-overlay').fadeOut(500);
}});
function censor($element) {
// just a basic example, you'll probably want to make this more complex to overlay it properly
$element.innerHTML = 'new content';
}
function censorPage() {
// just a basic example, you'll probably want to make this more complex to overlay it properly
$('body').innerHTML = 'new content';
}
---Original Answer---
I'm not sure exactly what you would like to do here, you should add more detail. However if you choose to use jQuery, it provides tons of useful methods including the method .attr(), which lets you get the value of any attribute of any element.
Example:
var alt = $('#my-selector').attr('alt');
if (alt == 'whatYouWant') {
alert('yay');
} else {
alert('nay');
}
You're using jQuery lib, you could select elements by attribute like:
$('[alt="one"]').each(function(el){
// do something
var x = $(el).arrt('alt');
});
If you use selector $('[alt]') you can get elements that have this attribute set, and then check the value of the element if you have a more complicated selection.
Than you have to change your return, as you could not put a div inside an ALT tag, it didn't work.
Here is about what is your expected output.
UPDATE
As you want to change all images and video in a page, the way to do this with jquery is through $.replaceWith():
$('img,video').replaceWith($('<div>Text Here</div>'));
If you need to filter the elements:
$('img,video').each(function(el){
if($(el).prop('tagName') == 'IMG' &&
$(el).attr('alt') == 'the text...') {
$(el).replaceWith($('<div>Text Here</div>'));
}
})
But I'm not an expert on Chrome Extensions, I just put this code here in jQuery, as you was using jQuery.
Of course it could be done, with much code with plain javascript and the DOM API.

Difficulty constructing Absolute URL

www.baxter.com source page, shows most of the href links starting with the word baxter, like this -
href="/baxter/corporate.page?">About Baxter<
So the way I can construct an absolute url from the above is by combining the base url, www.baxter.com and the relative url /baxter/corporate.page?giving me www.baxter.com/baxter/corporate.page? which results in 404, cause the actual url is www.baxter.com/corporate.page?
I know how to generally parse relative URLs in PHP but is there a way to sense and remove words from relative urls like these?
Also mouseover on About Baxter on www.baxter.com web page displays the correct url, www.baxter.com/corporate.page? at bottom left of the page - where is this coming from? can it be accessed?
Will deeply appreciate any help/pointers...
EDIT on Nov 7:
In main.js, they are removing /baxter:
var fixer = function() {
var init = function() {
var digitasFinder = /(proto)|(cms-)|(teamsite-)/
, baxterFinder = /(\/baxter\/)/
, $allAnchors = $("a")
, $allForms = $("form");
digitasFinder.test(location.host) || ($allAnchors.each(function() {
var $this = $(this)
, actualHref = $this.attr("href");
if (baxterFinder.test(actualHref)) {
var newHref = actualHref.replace(baxterFinder, "/");
$this.attr("href", newHref)
}
}
),
$allForms.each(function() {
var $this = $(this)
, actualAction = $this.attr("action");
if (baxterFinder.test(actualAction)) {
var newAction = actualAction.replace(baxterFinder, "/");
$this.attr("action", newAction)
}
}
))
}
;
return {
init: init
}
}
Looks like some JavaScript executed on page load is modifying the hrefs of the links.
You could try duplicating the effects of the JS code (ie. remove '/baxter' from the links), or for a more generic solution, you could use a headless browser to execute the JS code and then evaluate the resulting DOM. Look into the Mink project for a PHP-based solution.

Targeting tabs on page with direct URL link breaks URL on tab click

I'm trying to create a tabbed area within my page. The tabs navigate hidden areas with out leaving the page. I also want to be able to link to an area with in the page. It's working except when you click the menu as well as revealing the hidden area it's rewriting the URL with only the tab extension and therefor breaking the link of the URL. So someone trying to share the link would not know the format..
I'm using this code https://css-tricks.com/examples/OrganicTabsReplaceState which I see no problem with.
You can see a live demo with my issue here: http://bit.ly/1IP1ST4
Clicking the tab is removing:
/products/eurorack-modules/waveform-modifiers/reactive-shaper/
And replacing it with ?tab=mytabname
It should be simply adding it. I'm struggling to work out why..?
If you inspect the source of the first link you provided, you will see that the tabs contain links like this:
Featured
That's an in-page link. You should use #'s for in page links. The reason the whole url is being replaced is because it's interpreting the href as a new url to go to. #'s look inside the current page.
This version of organictabs.jquery.js got it working in the end seemed to be an issue with the way it treated the URL.. Maybe this will help someone else.
// IIFE
(function($) {
// Define Plugin
$.organicTabs = function(el, options) {
// JavaScript native version of this
var base = this;
// jQuery version of this
base.$el = $(el);
// Navigation for current selector passed to plugin
base.$nav = base.$el.find(".nav");
// Returns the fragment identifier of the given URL
function getFragmentIdentifier(url) {
if(url && url.match && url.match(/#(.*)/)) {
return RegExp.$1;
}
}
// Remove the query string from the url
function noQueryString(url) {
if(url && url.match && url.match(/^([^\?]*)\??/)) {
return RegExp.$1;
}
}
// Runs once when plugin called
base.init = function() {
// Pull in arguments
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix (hmmm, re-look at this, screen readers still run JS)
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
// When navigation tab is clicked...
base.$nav.delegate("a", "click", function(e) {
// no hash links
e.preventDefault();
// Figure out current list via CSS class
var curList = getFragmentIdentifier(base.$el.find("a.current").attr("href")),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = getFragmentIdentifier($newList.attr("href")),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
}, base.options.speed);
// Remove highlighting - Add to just-clicked tab
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
// Change window location to add URL params
if (window.history && history.pushState) {
// NOTE: doesn't take into account existing params
history.replaceState("", "", noQueryString(window.location.href) + "?" + base.options.param + "=" + listID);
}
});
}
});
var queryString = {};
window.location.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
if (queryString[base.options.param]) {
var tab = $("a[href='#" + queryString[base.options.param] + "']");
tab
.closest(".nav")
.find("a")
.removeClass("current")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#" + queryString[base.options.param]).show();
};
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300,
"param": "tab"
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);

How to change the opacity of a text in search box?

http://i.stack.imgur.com/P3ZTz.jpg
You guys have any idea,if so can you please give me an example? (I'am a novice)
Thank you
Credit goes to Krowe.
// ==UserScript==
// #name Tamper with Google Results
// #namespace http://superuser.com/users/145045/krowe
// #version 0.1
// #description This just modifies google results to exclude certain things.
// #match http://*.google.com
// #match https://*.google.com
// #copyright 2014+, KRowe
// ==/UserScript==
function GM_main () {
window.onload = function () {
var targ = window.location;
if(targ && targ.href && targ.href.match('https?:\/\/www.google.com/.+#q=.+') && targ.href.search("/+-torrent/+-watch/+-download")==-1) {
targ.href = targ.href +"+-torrent+-watch+-download";
}
};
}
//-- This is a standard-ish utility function:
function addJS_Node(text, s_URL, funcToRun, runOnLoad) {
var D=document, scriptNode = D.createElement('script');
if(runOnLoad) scriptNode.addEventListener("load", runOnLoad, false);
scriptNode.type = "text/javascript";
if(text) scriptNode.textContent = text;
if(s_URL) scriptNode.src = s_URL;
if(funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName('head')[0] || D.body || D.documentElement;
targ.appendChild(scriptNode);
}
addJS_Node (null, null, GM_main);
Using (-) sign I can exclude unwanted results,but dont want the other users become aware of it.If someone searches Google or any other search engine this phrase(-torrent-download-watch) should be automatically and invisibly added
edit- how can I use css to add a blank white layer on top of the unwanted text and sync them in the textarea?
For example : http://i.stack.imgur.com/uAz0i.jpg
No, you can't change opacity for partial content.
However you can hide the input box and place a overlay div, which can mimic as a textbox, that can be then further styled with different text colors.
Take a hint from following post:
How do I make a div element editable (like a textarea when I click it)?
You can use color to change to color of the text.
color:rgb(255,0,0); //red
color:rgba(255,0,0,0.5); //half opaque red.
The first three numbers are color, the fourth is opacity.

Why isn't this chrome / Greasemonkey script executing?

I have the following simple Greasemonkey script:
// ==UserScript==
// #name MetaCPAN Everywhere
// #description Add to every link to CPAN a link to MetaCPAN on a Google results page.
// #namespace http://ajct.info
// #match http://*/*
// #version 0.1
// ==/UserScript==
(function() {
var page_links = document.links;
for (var i=0; i<page_links.length; i++){
if (page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i)) {
var match = page_links[i].href.match(/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i);
var span = document.createElement("span");
span.innerHTML = " MetaCPAN";
page_links[i].parentNode.insertBefore(span, page_links[i].nextSibling);
}
}
})();
If I run the JavaScript snippet through firebug it does the right thing but if I install it and visit the search results page it doesn't seem to execute the script.
It's presumably something trivial but can anyone point out what I missed?
The main thing is that Google ajaxes-in just about all of its results, so you need a way to wait for the first batch and to check for later batches.
There are numerous techniques. A simple one is to use a timer:
//--- This handles both page-load delays, and AJAX changes.
var chkInterval = setInterval (checkForResultsLinks, 500);
function checkForResultsLinks () {
var links = document.querySelectorAll ('#search a');
if (links) {
for (var J = links.length - 1; J >= 0; --J) {
var link = links[J];
if (link.weHaveProcessed)
continue;
if (link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i) ) {
var match = link.href.match (/http:\/\/search\.cpan\.org\/perldoc\?(.*?)$/i);
var span = document.createElement("span");
span.innerHTML = " MetaCPAN";
link.parentNode.insertBefore (span, link.nextSibling);
link.weHaveProcessed = true;
}
}
}
}
Notes:
Google search results appear inside a div with the id, "search".
Best add the // #run-at document-end directive to this kind of script.
The current script's#match directive is overly broad, the script will fire on every web page!
You probably want to restrict it to:
// #match http://www.google.com/*
// #match http://google.com/*
There is no need or point to wrapping the code in an anonymous function, like: (function() { ... })(); .
I found that some scripts although really simple wouldn't run in chrome, however I did find a chrome extension that fully supports greasemonkey scripts, it's called Tampermonkey

Categories