Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the text with new text #4

Closed
badsyntax opened this issue Oct 14, 2012 · 3 comments
Closed

Replace the text with new text #4

badsyntax opened this issue Oct 14, 2012 · 3 comments

Comments

@badsyntax
Copy link
Contributor

Hi James. Firstly, thanks a lot for this code!

All the examples I've seen have demonstrated how to wrap text with an element node.

I wanted to know if you had any ideas for adapting this code to provide an API method to actually replace the text in the DOM?

For example: I have the following DOM tree:

<div>
    badw<strong>o<em>rd</em></strong>d
</div>

I want to replace the word 'badwordd' with 'bad word' in the above DOM tree.

I've had a go at doing this myself by providing a handler function for the replacementNode argument, but the issue here is that the replacementNode function is called in the incorrect order.
It seems the recursive logic for traversing the tree does not match the order of the word you are searching for.

For example:

findAndReplaceDOMText(new RegExp(oldWord), this.element[0], function(fill){
    console.log(fill);
    return document.createTextNode(fill);
});

/* will output:
badw
d
o
rd 
*/

The order in which the replacementNode handler is called makes it a bit tricky for me to replace the 'fill' value with something else.

If you have any ideas on how to do this elegantly, it would be most appreciated.

Thanks,
Rich

@padolsey
Copy link
Owner

Thanks for reporting this issue. The order that the replacement-function is called in should now be correct (version 0.11).

It'll still be a bit tricky to do what you want though, since you'll inevitably have to deal with portions of words instead of entire words. There is a potentially useful second argument to your replacement-function though (if you need to replace many instances of entire words):

findAndReplaceDOMText(r, n, function(fill, i){
   i; // => index of the entire regex match
});

I'm not sure if that helps.

I'll keep thinking about the API though. There may be something it can provide. Like a way to replace the entire DOM fragment of a match at once.

Thanks for reporting this once again!

@badsyntax
Copy link
Contributor Author

Thanks a lot for the change. This helps a lot! I've briefly tested replacing words and I'm now able to do the following:

var word = 'badwordd';
var replacement;
var replaced;
var replaceFill;
var c;

findAndReplaceDOMText(new RegExp(word, 'g'), this.element[0], function(fill, i){

  // Reset the replacement for each match
  if (i !== c) {
    c = i;
    replacement = 'bad word';
    replaced = '';
  }

  replaceFill = replacement.substring(0, fill.length);
  replacement = replacement.substring(fill.length);
  replaced += fill;

  if (replaced === word) {
    // Add remaining text to last node
    if (replacement.length > 0) {
      replaceFill += replacement;
    }
  }

  return document.createTextNode(replaceFill || '');
});

Although not the most elegant, I believe that code should satisfy all edge conditions of replacing words (if the replacement word is longer or shorter than the word to replace).

@padolsey
Copy link
Owner

Looks good! Glad the change helped.

Hope it's okay if I close this ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants