Replace the text with new text #4

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

Comments

Projects
None yet
2 participants
Contributor

badsyntax commented Oct 14, 2012

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

Owner

padolsey commented Oct 14, 2012

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!

Contributor

badsyntax commented Oct 14, 2012

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).

Owner

padolsey commented Oct 14, 2012

Looks good! Glad the change helped.

Hope it's okay if I close this ticket.

padolsey closed this Oct 14, 2012

badsyntax referenced this issue in badsyntax/jquery-spellchecker Oct 25, 2012

Closed

Full unicode support #4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment