I need alittle help with getting a script that will take param from the orginal link and re-write them into a new link. I guess it should be pretty easy but I'm a noob still when it comes to this.
Here is the orginal HTML code for 1 link. (should be replaced globaly on the page. image1.jpg, image2.jpg etc.)
<div align="center"><img src="/preview/image1.jpg" width="128" height="128" border="0" style="border: 0px black solid;" /></div>
This should be done global on all the links that contain the imagepath "/preview/"
Thanks to Brock Adams I kinda understand how to get the param values with this code but I still don't really get it how to re-write all the links in a page.
var searchableStr = document.URL + '&';
var value1 = searchableStr.match (/[\?\&]id=([^\&\#]+)[\&\#]/i) [1];
var value2 = searchableStr.match (/[\?\&]connect=([^\&\#]+)[\&\#]/i) [1];
and then rewrite the links with "newlink"
var domain = searchableStr.match (/\/\/([w\.]*[^\/]+)/i) [1];
var newlink = '//' + domain + '/' + value1 + '/data/' + value2 + '.ext';
If someone could be so nice to help me setup an example greasemonkey script I would be very greatful for it.
OK, This is a fairly common task and I don't see any previous, Stack Overflow questions like it -- at least in a 2 minute search.
So, here's a script that should do what you want, based on the information provided...
// ==UserScript==
// #name Site_X, image relinker.
// #namespace StackOverflow
// #description Rewrites the preview links to ???
// #include http://Site_X.com/*
// #include http://www.Site_X.com/*
// #include https://Site_X.com/*
// #include https://www.Site_X.com/*
// ==/UserScript==
function LocalMain () {
/*--- Get all the images that have /preview/ in their path.
*/
var aPreviewImages = document.evaluate (
"//img[contains (#src, '/preview/')]",
document,
null,
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
null
);
var iNumImages = aPreviewImages.snapshotLength;
GM_log (iNumImages + ' preview images found.');
/*--- Rewrite the parent links to our new specifications.
Note, all the target links are of the form:
<a href="/index.php?Submit=ok&seson=b1e4&connect=127.0.0.1&id=13033&name=on">
<img src="/preview/image1.jpg" width="128" height="128" border="0" style="border: 0px black solid;" />
</a>
The desired rewrite changes the link to this form:
<a href="{current page's domain}/{id-value}/data/{connect-value}.ext">
*/
for (var iLinkIdx=0; iLinkIdx < iNumImages; iLinkIdx++) {
var zThisImage = aPreviewImages.snapshotItem (iLinkIdx);
var zParentLink = zThisImage.parentNode;
//--- Get the key href parameters.
var sIdValue = sGetUrlParamValue (zParentLink, 'id');
if (!sIdValue) continue; //-- Oopsie, this link was a malformed.
var sConnectValue = sGetUrlParamValue (zParentLink, 'connect');
if (!sConnectValue) continue;
//--- Get the current page's domain. (Or just use a relative link.)
var sPageDomain = document.URL.match (/\/\/([w\.]*[^\/]+)/i) [1];
//--- Generate the desired link value.
var sDesiredLink = 'http://' + sPageDomain + '/' + sIdValue + '/data/' + sConnectValue + '.ext';
//--- Rewrite the target link.
zParentLink.href = sDesiredLink;
}
}
function sGetUrlParamValue (zTargLink, sParamName) {
var zRegEx = eval ('/[\?\&]' + sParamName + '=([^\&\#]+)[\&\#]/i');
var aMatch = (zTargLink.href + '&').match (zRegEx);
if (aMatch)
return decodeURI (aMatch[1]);
else
return null;
}
window.addEventListener ("load", LocalMain, false);
Related
I'd like to use fontawesome icons in SVG scope. I cannot achieve it in common way, but I can add <text> element containing corresponding UTF-8 char and with font set to fontawesome, like that:
<text style="font-family: FontAwesome;">\uf0ac</text>
To make it clear I wrote a switch for getting useful icons:
getFontAwesomeIcon(name) {
switch (name) {
case 'fa-globe':
return '\uf0ac'
case 'fa-lock':
return '\uf023'
case 'fa-users':
return '\uf0c0'
case 'fa-ellipsis-h':
return '\uf141'
default:
throw '# Wrong fontawesome icon name.'
}
}
But of course that's ugly, because I must write it myself im my code. How can I get these values just from fontawesome library?
You can avoid producing such a list and extract the information from the font-awesome stylesheet on the fly. Include the stylesheet and set the classes like usual, i. e.
<tspan class="fa fa-globe"></tspan>
and you can do the following:
var icons = document.querySelectorAll(".fa");
var stylesheet = Array.from(document.styleSheets).find(function (s) {
return s.href.endsWith("font-awesome.css");
});
var rules = Array.from(stylesheet.cssRules);
icons.forEach(function (icon) {
// extract the class name for the icon
var name = Array.from(icon.classList).find(function (c) {
return c.startsWith('fa-');
});
// get the ::before styles for that class
var style = rules.find(function (r) {
return r.selectorText && r.selectorText.endsWith(name + "::before");
}).style;
// insert the content into the element
// style.content returns '"\uf0ac"'
icon.textContent = style.content.substr(1,1);
});
My two answers for two approaches to the problem (both developed thanks to ccprog):
1. Setting char by class definition:
In that approach we can define element that way:
<text class="fa fa-globe"></text>
And next run that code:
var icons = document.querySelectorAll("text.fa");
// I want to modify only icons in SVG text elements
var stylesheets = Array.from(document.styleSheets);
// In my project FontAwesome styles are compiled with other file,
// so I search for rules in all CSS files
// Getting rules from stylesheets is slightly more complicated:
var rules = stylesheets.map(function(ss) {
return ss && ss.cssRules ? Array.from(ss.cssRules) : [];
})
rules = [].concat.apply([], rules);
// Rest the same:
icons.forEach(function (icon) {
var name = Array.from(icon.classList).find(function (c) {
return c.startsWith('fa-');
});
var style = rules.find(function (r) {
return r.selectorText && r.selectorText.endsWith(name + "::before");
}).style;
icon.textContent = style.content.substr(1,1);
});
But I had some problems with that approach, so I developed the second one.
2. Getting char with function:
const getFontAwesomeIconChar = (name) => {
var stylesheets = Array.from(document.styleSheets);
var rules = stylesheets.map(function(ss) {
return ss && ss.cssRules ? Array.from(ss.cssRules) : [];
})
rules = [].concat.apply([], rules);
var style = rules.find(function (r) {
return r.selectorText && r.selectorText.endsWith(name + "::before");
}).style;
return style.content.substr(1,1);
}
Having that funcion defined we can do something like this (example with React syntax):
<text>{getFontAwesomeIconChar('fa-globe')}</text>
I am trying to Maximize/Minimize a Document list Web Part.
I used the following code from http://blog.pathtosharepoint.com/2008/10/25/expandcollapse-buttons-for-your-web-parts/
and it works for my first two Web Parts but not my other two. All I did was include their titles within my coding as a change. Therefore, there shouldn't be any issue with the display.
Any suggestions on what can cause this?
The only changes I made after the first 2 were working was I added 2 more title1 to include the other 2 Web Parts.
As you can see, the bottom 2 don't fully minimize on page load
fYI: inside the coding.. the titles are changed to "... Orders" but the ... is in place of the actual name
<script type="text/javascript">
// Expand/Collapse Buttons
function WPToggle(thisId, ImageId)
{
if (document.getElementById(thisId).style.display=="none")
{
document.getElementById(thisId).style.display="";
document.getElementById(ImageId).src = "/_layouts/images/minus.gif";
}
else
{
document.getElementById(thisId).style.display="none";
document.getElementById(ImageId).src = "/_layouts/images/plus.gif";
}
}
function ExpandCollapseBody()
{
var i = 1;
var WPid = "WebPartWPQ1" ;
var WPtitleid = "WebPartTitleWPQ1" ;
var Toggleid = "ToggleImage1" ;
do
{
try
{
title1 = document.getElementById(WPtitleid).getAttribute("title");
if (title1 == "... Orders" || title1 == "... Orders" || title1 =="... Orders" || title1 == "... Orders")
{
document.getElementById(WPtitleid).innerHTML = '<IMG id="' + Toggleid + '" onClick="WPToggle(\'' + WPid + '\',\'' + Toggleid +
'\')" alt="Expand/Collapse" style="margin:6px 5px 0px 2px; float:left; cursor:pointer;" src="/_layouts/images/minus.gif" />' +
document.getElementById(WPtitleid).innerHTML ;
document.getElementById(Toggleid).src = "/_layouts/images/plus.gif";
}
}
catch(err) {}
i = i + 1;
WPid = "WebPartWPQ" + i ;
WPtitleid = "WebPartTitleWPQ" + i;
Toggleid = "ToggleImage" + i;
} while (document.getElementById(WPid))
}
_spBodyOnLoadFunctionNames.push("ExpandCollapseBody()");
</script>
I guess I see that by default, the more I add more webparts they start at expanded rather than collapse....
I see. I need the following condition of Chrome: minimize for the Web Part
How to print SVG elements that are built by jsPlumb.
Known that getting all SVG Elements drawen by jsPlumb is retrieved by this code :
var uiJsPlumbConnectors=jsPlumb.getAllConnections().map(function(conn){return conn.canvas;})
All connectors are SVG elements :
Using html2canvas to print all connectors (SVG), it does not work :
html2canvas(uiJsPlumbConnectors).then(function(c){
window.open(c.toDataURL('image/png'))
});
An image has been generated , however, it is an emply image .
FIDDLE
It seems that html2canvas does not support yet multi-elements drawing ?
Last time I checked html2canvas was not able to convert SVGs, you will need another script to handle that.
The steps:
transfer html elements to canvas
transfer svg elements to canvas
export canvas
I used https://code.google.com/p/canvg/ to export to the same canvas after using html2canvas. Hope that helps you.
I just implemented this
<%--stuff for printing--%>
<script type="text/javascript" src="../../../../Scripts/Print/html2canvas.js"></script>
<script src="<%=AdminPath%>Scripts/canvg/rgbcolor.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/StackBlur.js" type="text/javascript"></script>
<script src="<%=AdminPath%>Scripts/canvg/canvg.js" type="text/javascript"></script>
jsplumb div
<div class="demo statemachine-demo" id="statemachine-demo" style="margin: 0px;">
</div>
hidden div for printing
<div id="canvasDiv" style='visibility:hidden;' >
</div>
function renderImage()
{
var statemachinediv = document.getElementById('statemachine-demo');
html2canvas([statemachinediv], {
onrendered: function (canvas) {
document.getElementById('canvasDiv').appendChild(canvas);
var svgList = $(statemachinediv).find( "svg" );
svgList.each(function(index, value) {
try
{
var svgExample = this;
var serializer = new XMLSerializer();
var svgMarkup = serializer.serializeToString(svgExample);
if(svgMarkup.indexOf("_jsPlumb_connector") > -1)
{
var leftIndex = svgMarkup.indexOf("left: ");
var endOfLeft = svgMarkup.indexOf("px", leftIndex);
var leftPosition = svgMarkup.substring(leftIndex+6, endOfLeft );
var left = parseInt(leftPosition);
var topIndex = svgMarkup.indexOf("top: ");
var endOfTop = svgMarkup.indexOf("px", topIndex);
var topPosition = svgMarkup.substring(topIndex+5, endOfTop );
var top = parseInt(topPosition);
svgMarkup = svgMarkup.replace('xmlns="http://www.w3.org/2000/svg"','');
var connectorCanvas = document.createElement('canvas');
canvg(connectorCanvas, svgMarkup); //add connector to canvas
var context = canvas.getContext('2d');
context.drawImage(connectorCanvas, left, top);
}
}
catch(err)
{
showBalloon('error in print');
}
});
var stateMachineName = $("#stateMachineDropDown option:selected").text();
var data = canvas.toDataURL('image/png');
var mywindow = window.open('', 'my div', 'height=400,width=600');
mywindow.document.write('<html><head><title>' + stateMachineName + '</title>');
mywindow.document.write('</head><body ><table><tr><td>');
mywindow.document.write('</td></tr></table><img src="' + data + '" />');
mywindow.document.write('</body></html>');
mywindow.print();
}
});
return false;
}
Its a old question, but, this helped me. Mode details.
$clone.find('.jtk-connector').each(function () {
// for every SVG element created by JsPlumb for connections...
var left = parseInt(this.style.left, 10) + 'px';
var top = parseInt(this.style.top, 10) + 'px';
this.removeAttribute('style');
this.removeAttribute('position');
this.setAttribute('width', parseInt(this.getAttribute('width'), 10) + 'px');
this.setAttribute('height', parseInt(this.getAttribute('height'), 10) + 'px');
this.setAttribute('preserveAspectRatio', 'xMidYMid meet');
this.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// this.children[0] is the path for connection line
// this.children[1] is the path for connection arrow shape
this.children[0].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
this.children[1].setAttribute('xmlns', 'http://www.w3.org/2000/svg');
this.setAttribute('viewbox', '0 0 ' + parseInt(this.getAttribute('width'), 10) + ' ' + parseInt(this.getAttribute('height'), 10));
this.children[0].setAttribute('stroke-width', '2px');
this.children[0].setAttribute('stroke', '#c9c9c9');
this.children[1].setAttribute('fill', '#c9c9c9');
this.children[1].setAttribute('stroke', '#c9c9c9');
$clone.find(this).wrap('<span style="position: absolute; left: ' + left + '; top: ' + top + ';"></span>');
});
On first sign I have the following code:
Accounts.onCreateUser(function(options,user){
if (typeof(user.services.facebook) != "undefined") {
user.services.facebook.picture = "http://graph.facebook.com/" + user.services.facebook.id + "/picture/?type=large";
}
return user;
});
Which results in the following URL string
http://graph.facebook.com/[myfacebookid]/picture/?type=large
Yet when it renders that url and returns
<img scr="http://graph.facebook.com/[myfacebookid]/picture/?type=large" alt="My Name">
All I see is a broken image. How can I pull this in so that it renders the facebook profile picture?
I use a helper function based off of the Facebook ID of the user to grab the image on the server. I notice my url has /picture? and your has /picture/? Hope this helps.
userPicHelper: function() {
if (this.profile) {
var id = this.profile.facebookId;
var img = 'http://graph.facebook.com/' + id + '/picture?type=square&height=160&width=160';
return img;
}
},
I don't know how I missed this before, but is this the src attribute on the image tag is actually written as scr:
<img scr=
Should be...
<img src=
You have http instead of https.
So:
"https://graph.facebook.com/" + id + "/picture/?type=large";
This was my problem.
I have read various entries about searching by description and subcategories in opencart by default but I have a unique problem. I have two header files because my site has 2 headers... one for the home page and one for every other page.
Home Page:
https://garrysun.com/
Other Page:
https://garrysun.com/ayurveda-products/categories
When I search on the home page I get the correct results (search the word "heart") but when I search any other page it doesn't return the search for descriptions or subcategories.
Home Page Search Results:https://garrysun.com/index.php?route=product/search&filter_description=true&filter_sub_category=true&filter_name=heart
Other Page Search Results:https://garrysun.com/index.php?route=product/search&filter_name=heart
As you can see, when I search the other page the extra code is not being added to search in descriptions and subcategories.
So why is this new code that I added working for the home page an not any other page?
To make this search function work I have changed the common.js file to look like this (adding the two lines below each "url= $(base..." section:
/* Search */
$('.button-search').bind('click', function() {
url = $('base').attr('href') + 'index.php?route=product/search';
url += '&filter_description=true'; // ADDED this to search descriptions
url += '&filter_sub_category=true'; // ADDED this to search sub-categories
var filter_name = $('input[name=\'filter_name\']').attr('value');
if (filter_name) {
url += '&filter_name=' + encodeURIComponent(filter_name) ;
}
location = url;
});
$('#header input[name=\'filter_name\']').bind('keydown', function(e) {
if (e.keyCode == 13) {
url = $('base').attr('href') + 'index.php?route=product/search';
url += '&filter_description=true'; // ADDED this to search descriptions
url += '&filter_sub_category=true'; // ADDED this to search sub-categories
var filter_name = $('input[name=\'filter_name\']').attr('value');
if (filter_name) {
url += '&filter_name=' + encodeURIComponent(filter_name) ;
}
location = url;
}
});
Both header files use the same code to call the search function:
<div id="search">
<div class="button-search"></div>
<?php if ($filter_name) { ?>
<input type="text" name="filter_name" value="<?php echo $filter_name; ?>" />
<?php } else { ?>
<input type="text" name="filter_name" value="<?php echo $text_search; ?>" onclick="this.value = '';" onkeydown="this.style.color = '#000000';" />
<?php } ?>
</div>
</div>
After trying to figure out what's wrong in your code for few minutes (unsuccessfully), I ran a network debugging and found out that nothing is wrong with your code, you are just calling 2 different Javascript files(!):
On your home page, you are using common.js that is located at https://garrysun.com/catalog/view/javascript/common.js.
On your category pages, you are using common.js that is located at https://garrysun.com/catalog/view/javascript/add2cart-go2cart/common.js.
The 2nd one does not include your modifications, and looks like this:
$('.button-search').bind('click', function() {
url = $('base').attr('href') + 'index.php?route=product/search';
var filter_name = $('input[name=\'filter_name\']').attr('value');
if (filter_name) {
url += '&filter_name=' + encodeURIComponent(filter_name);
}
location = url;
});
$('#header input[name=\'filter_name\']').bind('keydown', function(e) {
if (e.keyCode == 13) {
url = $('base').attr('href') + 'index.php?route=product/search';
var filter_name = $('input[name=\'filter_name\']').attr('value');
if (filter_name) {
url += '&filter_name=' + encodeURIComponent(filter_name);
}
location = url;
}
});
Vuala.
Hope this helps!