Remove dollar sign from dom text - not from js code - javascript

I'm trying to replace all occurences of '$' (dollar sign) in a web page with another string.
The problem is that there may be some <script> tags that may contain the '$' (jQuery code) that I don't want to change.
For example:
document.body.innerHTML = document.body.innerHTML.replace(/\$/g, 'xxx'); seems to work, but also replaces '$' from any <script>$('...')...</script> parts.
Is this achievable?
Thank you in advance.
EDIT: I cannot modify the way the page is generated or change all other js parts - neither use some server-side logic. I can only add some custom js code

You can filter out the script tags
[].slice.call(document.body.children).forEach(function(element) {
if ( element.tagName.toLowerCase() != 'script' ) {
element.innerHTML = element.innerHTML.replace(/\$/g, 'xxx');
}
});
FIDDLE
This is not recursive, which means it only works for script tags directly under the body tag, not script tags that are nested deeper

function textNodes(main) {
var arr = [];
var loop = function(main) {
do {
if(main.hasChildNodes() && (["STYLE","SCRIPT"].indexOf(main.nodeName)==-1)){
loop(main.firstChild);
} else if(main.nodeType === 3) {
arr.push(main)
}
}
while (main = main.nextSibling);
}
loop(main);
return arr;
}
textNodes(document.body).forEach(function(a){a.textContent=a.textContent.replace(/\$/g,'€')});
Based on this DOM walking example

Related

Convert URL in paragraphs to links using jQuery or Javascript

I am new to javascript but understand jQuery. I am trying to use this code to convert www. and http in p tags to working links.
Here is the code I am using, the problem is that I do not fully understand how the code works, could anybody please explain?
<script>
var re = /(http:\/\/[^ ]+)/g;
function createLinks(els) {
$(els).contents().each(function () {
if (this.nodeType === 1 && this.nodeName !== 'script') {
createLinks(this);
} else if (this.nodeType === 3 && this.data.match(re)) {
var markup = this.data.replace(re, '$1');
$(this).replaceWith(markup);
}
});
}
createLinks(document.body);
</script>
First, you set regular expression template for matching text which starts from "http://"
Second, you create recursive function which traverse whole html document.
nodeType == 1 means that current element is html tag (i.e. a, p, div etc)
nodeType == 2 means that element is Attribute
nodeType == 3 means that element is text node
So when you found html tag, you're searching inside it,
when you found text node, you are checking via regular expression, if this text starts from "http://", if so you change and replce this text to yourmatchedurl
in the end you call your function to start from body as a root
ok, here goes...
//create a regular expression to format the link
var re = /(http:\/\/[^ ]+)/g;
//this is the create links function which gets called below, "els" is the elements passed to the function (document.body)
function createLinks(els) {
//for each of the elements in the body
$(els).contents().each(function () {
//check if its an element type but not a script
if (this.nodeType === 1 && this.nodeName !== 'script') {
//call the create links function and send in this object
createLinks(this);
//if its not an element but is a text node and the format matches the regular expression
} else if (this.nodeType === 3 && this.data.match(re)) {
//create the markup
var markup = this.data.replace(re, '$1');
//finally, replace this link with the marked up link
$(this).replaceWith(markup);
}
});
}
//call the create links function
createLinks(document.body);
I hope the commented code helps you understand.

How to replace < and > with < and > with jQuery or JS

I've been searching for a day or so how to do something with JS or jQuery and found a couple of solutions but nothing solid yet.
I want to use this:
<code class="codeIt">
<h2> This is an H2 </h2>
</code>
And I want the output to be:
<h2> This is an H2 </h2>
I know I can achieve this by doing:
<code class="codeIt">
<h2> This is an H2 </h2>
</code>
...But I would like to not do a manual search and replace on my code in those blocks and rather have it done on the fly in the browser. Is this possible?
I'm pretty noob with jQuery so I've tried .replaceWith or JavaScript's .replace but so far I've not gotten where I need to be with it. I'm either replacing the whole tag or doing something else wrong.
My question is: How would I write a simple jQuery (or regular JS) to help me replace my < and my > with HTML entities like < and > inside my <code> tags.
I appreciate any help, Thanks.
UPDATE:
I managed to get it working nice how #Prisoner explained, it's very nifty, however this in my particular case needed a little extending because I have more than one block of code with the .codeIt class, so I had to make it check each element and output... otherwise it would keep making the same output (like the first block)
Here is the fiddle
Thanks to everyone for their answers.
Assuming you just want to escape all HTML:
$(".codeIt").text($(".codeIt").html());
Plain JS for single code element
var myCode = document.getElementById('mycode');
myCode.innerHTML = myCode.innerHTML.replace(/</g,'<').replace(/>/g,'>')
Plain JS for multiple code elements
var codeEls = document.getElementsByTagName('code');
for(var i in codeEls)
{
if(parseInt(i)==i)
{
var codeEl = codeEls[i];
if(codeEl.className.match(/\bcodeIt\b/)!==null) codeEl.innerHTML = codeEl.innerHTML.replace(/</g,'<').replace(/>/g,'>')
}
}
or jQuery
$(".codeIt").each(function() {
$(this).html(
$(this).html().replace(/</g,'<').replace(/>/g,'>')
);
});
You could use the text function of jquery:
var myText = $('.codeIt').html();
var escapedText = $('.codeIt').text(myText).html();
var t = $('.codeIt').html();
$('.codeIt').text(t).html();
Look at this fiddle http://jsfiddle.net/kU8bV/1/
$('code').html($('code').html().replace(/</g, '<').replace(/>/g, '>'));
Assuming you want to code all the html in codeIt class :
<script type="text/javascript">
function htmlEncode(value){
if (value) {
return jQuery('<div />').text(value).html();
} else {
return '';
}
}
function htmlDecode(value) {
if (value) {
return $('<div />').html(value).text();
} else {
return '';
}
}
$('.codeIt').each(function() {
myEncodedString = htmlEncode($(this).html());
$(this).html(myEncodedString);
});
</script>

jQuery javascript way of checking if some html exist on page

Before appending more code, I want to make sure:
<a href='index.php?option=com_content&view=article&id=36'>Hello</a>
isn't already on the html page inside the div where id='faqs'
<div id='faqs'>
<a href='index.php?option=com_content&view=article&id=36'>Hello</a>
</div>
What is the best way of doing this with jquery or javascript?
Thanks
The easiest way would be to use jQuery to select the element, and check the length property of the resulting object:
var anchor = $('#faqs a[href="index.php?option=com_content&view=article&id=36"]')
if(anchor.length == 0) {
// element isn't on the page
}
You could search using indexOf
var inBlock = $('#faqs').html();
if (inBlock.indexOf("<a href='index.php?option=com_content&view=article&id=36'>Hello</a>") == -1) {
$('#faqs').append ("<a href='index.php?option=com_content&view=article&id=36'>Hello</a>");
}
if (!$('a[href$="view=article&id=36"]', '#faqs').length) {
//does'nt exist
}
If the goal is to end up with the a tag as a child in the div tag, and thats it, then don't bother checking, just re add it, like this:
$('#faqs').html('');
$('<a />')
.attr('href', 'index.php?option=com_content&view=article&id=36')
.html('hello')
.appendTo($('#faqs'))​;​
However, if you genuinely need to check if it exists, then you can do something like this:
var exists = $('#faqs a[href="index.php?option=com_content&view=article&id=36"]').length > 0;
UPDATE
Finding the string in the html can be done as follows, but this is not a recommended solution. You may run into issues with different browsers encoding html in different ways etc (tested in chrome):
var stringToFind = 'Hello';
// need to replace the & ...
stringToFind = stringToFind.replace(/&/g, '&');
var exists = $('#faqs').html().indexOf(stringToFind) > -1;
if (exists) {
// do something
} else {
// do something else
}
Here's a working example -> http://jsfiddle.net/Uzef8/2/

Apply ligature with jquery to link text only, not link href

I am using ligatures.js to replace text within my site with the ligature of some character combinations. For instance, the 'fi' in 'five'.
Here is my example: http://jsfiddle.net/vinmassaro/GquVy/
When you run it, you can select the output text and see that the 'fi' in 'five' has become one character as intended. If you copy the link address and paste it, you will see that the href portion has been replaced as well:
/news/here-is-a-url-with-%EF%AC%81ve-ligature
This is unintended and breaks the link. How can I make the replacement on JUST the text of the link but not the href portion? I've tried using .text() and .not() with no luck. Thanks in advance.
I think you can solve it using the appropiate jQuery selectors
$('h3 a, h3:not(:has(a))')
.ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
See http://jsfiddle.net/GquVy/7/
You are applying the function to the whole heading's innerHTML, which includes the anchor's href attribute. This should work for your fiddle example:
$('h1 a, h2 a, h3 a, h4 a').ligature( //...
However, it will only work on links inside the headings, and I'm not sure that's what you're looking for. If you want something that works for any contents inside a certain element (with any level of tag nesting), then you'll need a recursive approach. Here is an idea, which is basically plain JavaScript since jQuery does not provide a way to target DOM text nodes:
$.fn.ligature = function(str, lig) {
return this.each(function() {
recursiveLigatures(this, lig);
});
function recursiveLigatures(el, lig) {
if(el.childNodes.length) {
for(var i=0, len=el.childNodes.length; i<len; i++) {
if(el.childNodes[i].childNodes.length > 0) {
recursiveLigatures(el.childNodes[i], lig);
} else {
el.childNodes[i].nodeValue = htmlDecode(el.childNodes[i].nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
} else {
el.nodeValue = htmlDecode(el.nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
// http://stackoverflow.com/a/1912522/825789
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
};
// call this from the document.ready handler
$(function(){
$('h3').ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
});
That should work on contents like this:
<h3>
mixed ffi content
<span>this is another tag ffi <span>(and this is nested ffi</span></span>
Here is a ffi ligature
</h3>
http://jsfiddle.net/JjLZR/

Find Characters and wrap with HTML

I am trying to find // (slashes) in the document and wrap it with a span.
I've tried
var slashes = "//";
/slashes+/
So output should be:
Hello There! I Am <span class="slashes">//</span> An Alien
With jQuery .replace() and :contains but nothing happens, and I am new to reguler expressions to do this correctly. How would I do this?
Edit: What have I tried:
Solution for this question didn't work:
function slashes($el) {
$el.contents().each(function () {
dlbSlash = "//";
if (this.nodeType == 3) { // Text only
$(this).replaceWith($(this).text()
.replace(/(dlbSlash)/gi, '<span class="slashes">$1</span>'));
} else { // Child element
slashes($(this));
}
});
}
slashes($("body"));
You need to escape the slashes in your regex. Try
var mystring = "adjfadfafdas//dsagdsg//dsafda"
mystring.replace(/\/\//g,'<span class="slashes">\/\/</span>');
Should output
"adjfadfafdas<span class="slashes">//</span>dsagdsg<span class="slashes">//</span>dsafda"
If you want to replace the slashes in h2 and p tags, you can loop through them like so:
$('h2, p').each(function(i, elem) {
$(elem).text(
$(elem).text().replace(/\/\//g,'<span class="slashes">\/\/</span>'));
});
This will blow away any additional html tags you may have had in your p and h2 tags, though.
This is one more way of doing this
//Find html inside element with id content
var html = $('#content').html();
//Replace // with <span style='color:red'>//</span>
html = html.replace(/\/{2}/g,"<span style='color:red'>$&</span>");
//Return updated html back to DOM
$('#content').html(html);​
and here is the demo
I think you were looking in the right place. The only thing to fix is your regular expression:
.replace(/\/\//g, '<span class="slashes">$1</span>'));
Focusing on text nodes (type 3) is important, instead of doing a global replace of the body innerHTML that might break your page.
If you want to apply such replacement for single // only, go with
mystring = mystring.replace(/(\/{2})/g, "<span class=\"slashes\">$1</span>");
However if you want to apply that for 2 or more slashes, then use
mystring = mystring.replace(/(\/{2,})/g, "<span class=\"slashes\">$1</span>");
But if you want to apply it for any even quantity of slashes (e.g. //, ////, etc.) then you need to use
mystring = mystring.replace(/((?:\/{2})+)/g, "<span class=\"slashes\">$1</span>");
Test the code here.

Categories

Resources