Replacing all urls in a div - javascript

I am trying to write javascript code to find all the urls inside a div. Now this would be pretty easy if all the urls within the div were separated by spaces in which case I can just do a regex on what's inside the div to find them. However, the urls within this outer div may be in sub divs (or any other html tag) and I want to consider the subdivs as separators as well (and I don't want to get rid of these subdivs). To give an example, in the following I want to find www.foo.com and www.bar.com within the div with id "outer":
<div id="outer"><div>www.foo.com</div>www.bar.com</div>
What would be a good way of doing this?

You can apply a recursive call to all non-text child nodes.
function replaceWwwInNodes(node) {
//text node
if (node.nodeType === 3) {
node.textContent = node.textContent.replace(/* ??? */)
}
else {
Array.prototype.forEach.call(node.childNodes, function (elem) {
replaceWwwInNodes(elem);
});
}
}
replaceWwwInNodes(document.getElementById('outer'));
http://jsfiddle.net/UDX5V/

Try to use this sample http://jsfiddle.net/iklementiev/TaCx9/1/
var data = document.getElementById("outer").innerText;
var myRe = /www\.[0-9a-z-]+\.[a-z]{2,4}/igm;
var matches= data.match(myRe)
for (var i = 0; i < matches.length; i++) {
alert('match: ' + matches[i]);
}
this help to find all urls.

try this
var expression = /[-a-zA-Z0-9#:%_\+.~#?&//=]{2,256}\.[a-z]{2,4}\b(\/[-a-zA-Z0-9#:%_\+.~#?&//=]*)?/gi;
var regex = new RegExp(expression);
var regContent = $("#outer").html();
var newContent = regContent;
if(regContent.match(regex))
{
var textContent = regContent.match(regex);
for(var i=0;i<regContent.match(regex).length;i++)
{
newContent = newContent.replace(new RegExp(regContent.match(regex)[i], "g"), "test");
}
$("#outer").html(newContent);
}
this will get all url content and replace it as "test".

Related

InDesign Target XML Structure element by partial name

In my Structure pane there are some elements that their partial name is identical, eg. image01, image03, image03 etc.
I want to know if there is a way to access them via scripting using the itemByName() method, but by providing a partial name, like in CSS i can use
h1[rel*="external"]
Is there a similar way to do this in:
var items2 = items.xmlElements.itemByName("image");
You could try something like the code below. You can test against the markupTag.name properties with a regular expression. The regex is equivalent to something like /^image/ in your example (find image at the beginning of a string).
function itemsWithPartialName(item, partialName) {
var elems = item.xmlElements;
var result = [];
for (var i=0; i<elems.length; i++) {
var elem = elems[i];
var elemName = elem.markupTag.name;
var regex = new RegExp("^" + partialName);
if (regex.test(elemName)) {
result.push(elem);
}
}
return result;
}
itemsWithPartialName(/* some xml item */, 'image');
You can use an XPath:
var rootXE = app.activeDocument.xmlElements.item(0);
var tagXEs = rootXE.evaluateXPathExpression("//*[starts-with(local-name(),'image')]");

JS Regex for a word which is not contained in <a>?

I'm using the following js to highlight the content of searched string in html, but the problem is that this also affects the url string.
var a = new RegExp(keywords, "igm");
container.innerHTML = container.innerHTML.replace(a, "<span style='background:#FF0;'>" + keywords + "</span>");
If the keyword is in the url, then the url will be relaced with xxxx.com/<span style='background:#FF0;'>product</span> which is wrong.
So is there any way to filter out the words that not contained in url? Not sure if there is a RegExp could do this. Thanks in advance.
Here is a block of code that does what you ask:
// prepare the replacement as a function
function do_replacement(node) {
var a = new RegExp(keywords, "igm");
node.innerHTML = node.innerHTML.replace(a,
"<span style='background:#FF0;'>" + keywords + "</span>");
}
// back up the links
var link_backups = new Array();
var link_refs = new Array();
var container_links = container.getElementsByTagName("a");
for (var i = 0; i < container_links.length; i++) {
var copy = container_links[i].cloneNode(true);
// the link target (href) is not contained in the link's innerHTML
// remove this line if you don't want to replace the link's TEXT
do_replacement(copy);
link_backups.push(copy);
link_refs[i] = container_links[i];
}
do_replacement(container);
// restore the backed up links
// (this uses link_refs[] because container_links[] could have changed)
for (var i = 0; i < link_refs.length; i++) {
container.replaceChild(link_backups[i], link_refs[i]);
}
This will (probably) fail if your keywords matches the tag name (<a>) of the links, e.g. when keywords = "a".
However, I'm sure you'll merely run into another instance of HTML code that you don't actually want to replace. JS doesn't really have the best of ways to manipulate just the DOM's text. For example, changing Node.textContent will kill all of the node's HTML content.

find div in html with javascript and regex

I try to select html element with javascript without! jQuery...
for example my html is:
<div id="my1231">
</div>
and i want to select any first div with id started with my, and i try so:
var regex = /my(.*)/;
var templateCode = document.match(regex)
alert(templateCode);
but nothing happend, what i do wrong?
how to select div with regex, where first part of id is static, and second random?
How about document.querySelectorAll?
document.querySelectorAll("[id^='my']")
Just be aware of the >= IE8 support
http://caniuse.com/#search=querySelectorAll
If you really want to use regex to match against ids, you must first get a node list and then loop through it and check each id individually. You can then append each matching element to a new array:
var divs = document.getElementsByTagName('div');
var regex = /my(.*)/, matches = [];
for(i=0; i< divs.length; i++){
if(regex.test(divs[i].id)){
matches.push(divs[i]);
}
}
JSFiddle
Of course you can always mix both answers and use feature detection to determine which method to use:
var divs;
var matches = [];
var re = /^my\w+/;
if (document.querySelectorAll) {
matches = document.querySelectorAll("[id^='my']");
} else if (document.getElementsByTagName) {
divs = document.getElementsByTagName('div');
for(i=0, iLen=divs.length; i<iLen; i++){
if (re.test(divs[i].id)) {
matches.push(divs[i]);
}
}
}
HTH.

Make a text Highlight using javascript

I want to make a word bold in given paragraph. Here is a javascript code.
var hlWord = "idm";
var nregex = new RegExp(hlWord,"gi");
var div = document.getElementById("SR").innerHTML;
var rword = div.replace(nregex,"<b>"+hlWord+"</b>");
document.getElementById("SR").innerHTML = rword;
Here is a HTML code.
<div id="SR">
Download here free idm.
click here to download
</div>
This is work well and make all idm bold but here is a problem that it also change
url to like this
click here to download
This is not a valid url.This is the problem that this code make the url damaged.
Please tell me how can I avoid this.
Thanks...
You can iterate through all the text nodes with the methods in this thread, change them and replace them with new bold ones.
var hlWord = "idm";
var nregex = new RegExp(hlWord,"gi");
var sr = document.getElementById('SR');
function escape_html(html) {
return html.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
}
(function findTextNodes(current) {
// make a shadow copy of the child nodes.
var current_children = Array.prototype.slice.call(current.childNodes);
for(var i = 0; i < current_children.length; i++) {
var child = current.childNodes[i];
// text node
if(child.nodeType == 3) {
var value = escape_html(child.nodeValue);
var html = value.replace(nregex, '<b>' + hlWord + '</b>');
if (html != value) {
var node = document.createElement('div');
node.innerHTML = html;
// make a shadow copy of the child nodes.
var childNodes = Array.prototype.slice.call(node.childNodes);
// replace the plain text node with the bold segments
for (var j = 0; j < childNodes.length; j++) {
var c = childNodes[j];
current.insertBefore(c, child);
}
current.removeChild(child);
}
}
else {
findTextNodes(child);
}
}
})(sr);
Check the code example at jsFiddle.
UPDATE:
Passerby pointed out that innerHTML should be used carefully. Escape text nodeValue before processing.
After some try-and-fail, I made a working demo that may be more complicated than you might have think:
http://jsfiddle.net/4VKNk/
var cache=[];
var reg=/idm/gi;
var id=function(ID){return document.getElementById(ID);}
function walkElement(ele){
if(ele.childNodes.length>0){
for(var i=0;i<ele.childNodes.length;i++){
walkElement(ele.childNodes[i]);
}
}else if(ele.nodeType==3){//text node
if(reg.test(ele.nodeValue)){
cache.push(ele);
}
}
}
id("test").onclick=function(){
cache=[];
walkElement(id("SR"));
while(cache.length>0){
var ele=cache.shift();
var val=ele.nodeValue;
var pnt=ele.parentNode;
var nextSibling=ele.nextSibling;
var i=0;
var r,tmp;
pnt.removeChild(ele);
while(r=reg.exec(val)){
tmp=document.createTextNode(val.substring(i,r.index));
if(nextSibling){
pnt.insertBefore(tmp,nextSibling);
tmp=document.createElement("strong");
tmp.appendChild(document.createTextNode("idm"));
pnt.insertBefore(tmp,nextSibling);
}else{
pnt.appendChild(tmp);
tmp=document.createElement("strong");
tmp.appendChild(document.createTextNode("idm"));
pnt.appendChild(tmp);
}
i=reg.lastIndex;
}
if(i<val.length-1){
tmp=document.createTextNode(val.substring(i,val.length));
if(nextSibling){
pnt.insertBefore(tmp,nextSibling);
}else{
pnt.appendChild(tmp);
}
}
}
};
I took the approach of DOM manipulation.
Explanation:
Walk through the whole DOM tree under target element, and cache all TEXT_NODE (nodeType==3);
Use RegExp.exec() method to get the index of each match;
While you find a match, add back the text that come before it, and then add a highlight element (<strong>) that contains the match; continue this step;
If we still have text left, add it back.
The reason I need to cache the TEXT_NODEs first, is that if we directly modify it in walkElement, it will change childNodes.length of its parent, and break the process.

JavaScript: Add elements in textNode

I want to add an element to a textNode. For example: I have a function that search for a string within element's textNode. When I find it, I want to replace with a HTML element. Is there some standard for that?
Thank you.
You can't just replace the string, you'll have to replace the entire TextNode element, since TextNode elements can't contain child elements in the DOM.
So, when you find your text node, generate your replacement element, then replace the text node with a function similar to:
function ReplaceNode(textNode, eNode) {
var pNode = textNode.parentNode;
pNode.replaceChild(textNode, eNode);
}
For what it appears you want to do, you will have to break apart the current Text Node into two new Text Nodes and a new HTML element. Here's some sample code to point you hopefully in the right direction:
function DecorateText(str) {
var e = document.createElement("span");
e.style.color = "#ff0000";
e.appendChild(document.createTextNode(str));
return e;
}
function SearchAndReplaceElement(elem) {
for(var i = elem.childNodes.length; i--;) {
var childNode = elem.childNodes[i];
if(childNode.nodeType == 3) { // 3 => a Text Node
var strSrc = childNode.nodeValue; // for Text Nodes, the nodeValue property contains the text
var strSearch = "Special String";
var pos = strSrc.indexOf(strSearch);
if(pos >= 0) {
var fragment = document.createDocumentFragment();
if(pos > 0)
fragment.appendChild(document.createTextNode(strSrc.substr(0, pos)));
fragment.appendChild(DecorateText(strSearch));
if((pos + strSearch.length + 1) < strSrc.length)
fragment.appendChild(document.createTextNode(strSrc.substr(pos + strSearch.length + 1)));
elem.replaceChild(fragment, childNode);
}
}
}
}
Maybe jQuery would have made this easier, but it's good to understand why all of this stuff works the way it does.

Categories

Resources