0

How can I uppercase small a's inside a Meteor template after rendering?

What I tried:

Meteor's LiveRange object has a visit() method. With it I can access all rendered DOM nodes of a template. For each DOM text node I modify its data in the visitor.

However! How to get the LiveRange object for a template??

In the callback rendered() for the template this is the template instance. It has a LiveRange object in a member called _spark_kEezuQToKtbuQw3Xw or such. This looks like Meteor is disliking someone to access this member.

How can I get the LiveRange object of a template in a way which pleases the Meteor gods?

And before you ask why I would do such a stupid thing as uppercasing all "a"'s: It's complicated. Actually I would like to execute a search-and-replace on all DOM text nodes in a template, because I am trying to apply a cross-cutting concern to several templates in a Meteor application.

Ben
  • 51,770
  • 36
  • 127
  • 149
nalply
  • 26,770
  • 15
  • 78
  • 101

1 Answers1

1

Do you have any constraints on where the a's are within the template?

For example, this is how you'd uppercase all a's within all SPANs in the template:

Template.complicated.rendered = function() {

    this.findAll('span').each(function(idx, element) {
        $(element).html( $(element).html().replace(/a/g, 'A');
    });

};

 


 

If you want to traverse all top-level nodes, you can do it like that:

Template.complicated.rendered = function() {
  var node = this.firstNode;

  while(true) {

    // manipulate with node
    //
    // for example, get all text nodes within in
    // and replace a's with A's

    if(node === template.lastNode) return;
    node = node.nextSibling;
  }
}

However, you need to be careful with this method and only replace contents of leaf nodes. If you change every a there is, you may change link urls you don't want to change. Also, changing all the DOM, not just text node contents, may anger Meteor gods.

 


 

EDIT: Combined with How do I select text nodes with jQuery? , this code will upcase all a's in all text nodes within the template:

Template.complicated.rendered = function() {
  var node = this.firstNode;

  while(true) {

    _.each(getTextNodesIn(node, false), function(textNode) {
      textNode.nodeValue = textNode.nodeValue.replace(/a/g, 'A');
    });

    if(node === template.lastNode) return;
    node = node.nextSibling;
  }
}
Community
  • 1
  • 1
Hubert OG
  • 19,314
  • 7
  • 45
  • 73
  • Good question about the occurences of a's. They occur in all DOM text nodes and in some attribute nodes as well. – nalply Jul 10 '13 at 20:22
  • Ok, answer updated. A trick similar to the referenced should help with those attribute nodes. – Hubert OG Jul 10 '13 at 20:51