1

What i have done:

 function makeBold(strings) {

            var myHTML = document.getElementsByTagName('body')[0].innerHTML;


             myHTML = myHTML.replace(strings, '<b>' + strings + '</b>');


             document.getElementsByTagName('body')[0].innerHTML = myHTML
        }

this code works only for the paces where the texts are free from ant tags

Eg: <p class="ClassName">Some free text without any inner html elements</p>

But for sentences below this the above javascript function is not giving any result

Eg sentence which are not working:

<p class="Aclass"><span class="char-style-override-1">Starting from here, </span><span class="char-style-override-2">text resumes after the span tag</span><span class="char-style-override-1">. again text resumes.</span></p>

What I need

i need a functionality to make the above text bold when i pass that text into my js function. and by text i mean only

Starting from here,text resumes after the span tag. again text resumes.

when i call the above mentioned jas function like this

makeBold('Starting from here,text resumes after the span tag. again text resumes.');

nothing happens, the entire sentence does not gets bold nothing happens, because the js function only looks for the occurrence of that string and makes it bold, in my second example the text is mixed with html tags

so that the above mentioned text will get bold when i call my makebold function.

Please note that i dont have the id for the <p> , what i have is a couple of random strings stored in my db and load a couple of webpages, while doing so i want to bold the sentence/text from the webpage if is matches with my passed string from db

While doing my research i got a code to highlight text given to a js. this js function will select the exact text in the html page which is passed to the js function.

the second eg also works for this code. i.e i can select the exact string from the example by passing it to the function.

function selectText(text) {
if (window.find && window.getSelection) {
    document.designMode = "on";
    var sel = window.getSelection();
    sel.collapse(document.body, 0);

    while (window.find(text)) {
        document.getElementById("button").blur();
        document.execCommand("HiliteColor", false, "yellow");
        sel.collapseToEnd();
    }
    document.designMode = "off";
} else if (document.body.createTextRange) {
    var textRange = document.body.createTextRange();
    while (textRange.findText(text)) {
        textRange.execCommand("BackColor", false, "yellow");
        textRange.collapse(false);
    }
}

}

I tried to customize it so that instead of selecting the passed text, i tried to make it bold. but coudnt succed.

Please help me in getting this done. I am new to js.

Mukund
  • 1,107
  • 2
  • 18
  • 40
  • Your script is just working fine as of your wish :) – Mohana Naga Venkat Sayempu Aug 31 '18 at 12:04
  • i want to bold the entire text, not just a part of it – Mukund Aug 31 '18 at 12:08
  • Are you passing the entire sentence that you want to render bold? – Robidu Aug 31 '18 at 12:11
  • yes, i have updated my question – Mukund Aug 31 '18 at 12:12
  • 1
    then pass the entire text as a parameter to the makeBold() function. you can get entire text using document.body.textContent – Mohana Naga Venkat Sayempu Aug 31 '18 at 12:12
  • That would destroy any markup that would be transported via the innerHTML. I doubt that that is what the OP intends to do. – Robidu Aug 31 '18 at 12:12
  • i dont want to pass the entire content, i just want to customize the second function from selecting the passed string from html page to make the passed sentence/text/string to bold. or similar ways – Mukund Aug 31 '18 at 12:15
  • As I thought. I'm currently deriving a test case for this. – Robidu Aug 31 '18 at 12:16
  • 1
    just as a note - you should be using `` in place of `` nowadays :) https://stackoverflow.com/questions/271743/whats-the-difference-between-b-and-strong-i-and-em#271776 – treyBake Aug 31 '18 at 12:18
  • @Mukund: This is a good question, indeed. Please be patient, because deriving a solution is quite tricky if things are to be made foolproof (i. e. no tag soup is to be generated by the modification). – Robidu Aug 31 '18 at 12:34
  • One thing that just struck me while working on the problem: The string that you pass to `makeBold()` doesn't match the plain text (i. e. your text with all tags stripped) in the paragraph to be modified (you missed a blank after the first comma). This way you wouldn't produce a result, anyway. – Robidu Aug 31 '18 at 13:05
  • Done with it. It should work according to your specifications and also keep you safe from generating tag soup in the process of turning the text to boldface. – Robidu Aug 31 '18 at 17:04

1 Answers1

0

I finally got a solution to your problem that works as you want it to (i. e. the function takes an arbitrary substring and marks anything that fits the substring bold while leaving the rest of the string untouched). If the string passed doesn't match any part of the string that you want to modify, the latter remains untouched.

Here goes (Beware: That JS section got really BIG!):

<!DOCTYPE html>
<html lang="en">
<head>
<title>Test case for making arbitrary text bold</title>
<meta charset="UTF-8">
<script type="application/javascript">
// Takes two strings and attempts to intersect them (i. e. the end of p_str1
// must match the beginning of p_str2). The index into p_str1 is returned.
// If no intersection can be found, -1 is returned.
function intersectStrings(p_str1, p_str2)
  {
var l_pos = -1;

  do
    {
    l_pos = p_str1.indexOf(p_str2[0], l_pos + 1);
    if(p_str1.substr(l_pos) == p_str2.substr(0, p_str1.length - l_pos))
// If the two substrings match, we found something. Return with the position.
      break;
    }
  while(l_pos != -1);

  return l_pos;
  }

function makeBold(p_string)
  {
var l_elem = document.getElementById('modify');
var l_html = l_elem.innerHTML;
var l_text = l_elem.innerText;
var l_aux = l_html.match(/<.+?>/g);

var l_here = l_text.indexOf(p_string);
var l_before;
var l_middle;
var l_behind;

  if(typeof(p_string) != 'string')
    throw "invalid argument";

// First of all, see whether or not we have a match at all. If no, we don't
// need to continue with this.
  if(l_here == -1)
    {
    console.error('makeBold: Could not find desired substring ' + p_string + '! Stop...');
    return;
    }

// Take the plain text and split it into three distinct parts (l_middle is of
// interest for us here).      
  l_before = l_html.slice(0, l_here);
  l_behind = l_html.slice(l_here + l_html.length);
  l_middle = l_html.slice(l_here, l_here + l_html.length);

  if(l_aux)
    {
// If we have a set of markup tags, we need to do some additional checks to
// avoid generating tag soup.
let l_target = new Array();
let l_tag;
let l_nexttag;
let l_this;
let l_endpos = 0;
let l_in_str = false;
let l_start;

    while(l_aux.length - 1)
      {
      l_tag = l_aux.shift();
      l_target.push(l_tag);
      l_nexttag = l_aux[0];
      l_endpos = l_html.indexOf(l_nexttag, 1);
      l_this = l_html.slice(l_tag.length, l_endpos);
      l_html = l_html.slice(l_endpos);
// Skip the entire rigmarole if there are two adjacent tags!
      if(l_tag.length == l_endpos)
        continue;
      if(!l_in_str)
        {
        if((l_start = l_this.indexOf(p_string)) != -1)
          {
// If we find the entire passed string in a fragment of plain text, we can
// modify that, reassemble everything and exit the loop.
          l_before = l_this.slice(0, l_start);
          l_behind = l_this.slice(l_start + p_string.length);
          l_middle = l_this.slice(l_start, l_start + p_string.length);
          l_this = l_before + '<strong>' + l_middle + '</strong>' + l_behind;
          l_target.push(l_this);
          l_target.push(l_html);
          l_html = l_target.join('');

          console.info('makeBold: The passed string fit between two tags: Done!');

          break;
          }

// Take the possibility of having to scan across fragments into account. If
// that is the case, we need to piece things together.
        if((l_start = intersectStrings(l_this, p_string)) != -1)
          {
// Once we wind up here we have a partial match. Now the piecework starts...
          l_before = l_this.slice(0, l_start);
          l_middle = l_this.slice(l_start);
          l_this = l_before + '<strong>' + l_middle + '</strong>';
          l_target.push(l_this);

          console.info('makeBold: Found starting point of bold string!');

          l_in_str = true;
          }
        else
          {
// Nothing to do: Push the unmodified string.
          l_target.push(l_this);
          }
        }
      else
        if((l_endpos = intersectStrings(p_string, l_this)) == -1)
          {
// We haven't arrived at the end position yet: Push the entire segment with
// bold markers onto the stack.
          l_this = '<strong>' + l_this + '</strong>';
          l_target.push(l_this);
          }
        else
          {
// We have an end position: Treat this fragment accordingly, wrap everything up
// and exit the loop.
          l_behind = l_this.slice(l_endpos + 1);
          l_middle = l_this.slice(0, l_endpos + 1);
          l_this = '<strong>' + l_middle + '</strong>' + l_behind;
          l_target.push(l_this);
          l_target.push(l_html);
          l_html = l_target.join('');

          console.info('makeBold: Found the end part: Done!');

          break;
          }
      }
    }
  else
    l_html = l_before + '<strong>' + l_middle + '</strong>' + l_behind;

  l_elem.innerHTML = l_html;
  }
</script>
</head>
<body>
<header><h1>Test case for making arbitrary text bold by using JavaScript</h1></header>
<main>
<p id="modify"><span class="char-style-override-1">Starting from here, </span><span class="char-style-override-2">text resumes after the span tag</span><span class="char-style-override-1">. again text resumes.</span></p>
</main>
<script type="application/javascript">
// makeBold('Starting from here, text resumes after the span tag. again text resumes.');
// makeBold('from here, text resumes');
// makeBold('resumes after the span');
makeBold('text resumes after the span tag');
</script>
</body>
</html>

Unfortunately this job couldn't be done with a short section, because you need to take various cases into account that need to be handled individually. The control logic that I have come up with addresses all these concerns.
See the annotations in the JS that I have made for details.

Robidu
  • 576
  • 3
  • 17
  • I have tested your case, and its works fine, but in my test case, i randomly load a couple of webpages and i have some texts pre-stored in my db, from there, i am calling them one by one so that only the called strings/texts/sentences will get bold. In this scenario, i cannot create a js like you have developed which catch the

    with its id, for me the id of

    is unknown, i only have the text user sees in the browser. Still i appreciate your effort in deriving a solution. thanks pal, I am still in search for the same

    – Mukund Sep 03 '18 at 06:44
  • You always have the option to retool the statement that finds the element containing your text. I have used an ID here to simplify things a bit. Oh, by the way: Feel free to experiment with the code... – Robidu Sep 03 '18 at 10:45