HTMLReader icon indicating copy to clipboard operation
HTMLReader copied to clipboard

Is it possible to replace a tag with its own innerHTML? Insert HTMLNode.children into parent.mutableChildren?

Open Apocryphon opened this issue 6 years ago • 3 comments

I'm looking to replace a tag with all of its own text and HTML content, similar to unwrap in jQuery. Presumably I could do something like:

NSRange currentNodeRange = NSMakeRange([parentNode indexOfChild:currentNode], currentNode.numberOfChildren);
NSIndexSet *newNodesIndexSet = [NSIndexSet indexSetWithIndexesInRange:currentNodeRange];

[parentNode.mutableChildren insertObjects:currentNode.children atIndexes:newNodesIndexSet];

However, insertObjects:atIndexes: only accepts NSArray<HTMLNode *> *, which forces me to use currentNode.childElementNodes. Because that array cannot contain HTMLTextNode objects, it wipes out any text that might have existed in currentNode. Well, I am able to do the above, but I get an incompatible pointer type warning.

What's the best way to accomplish this? Or since I'm able to do the above, could the warning be fixed?

Edit: looks like I can side step the warning with [currentNode.children array], which extracts an NSArray from the NSOrderedSet. However, it's still strange that by default children/mutableChildren do not contain HTMLTextNode objects but only HTMLNode.

Apocryphon avatar Apr 10 '18 00:04 Apocryphon

Hello! I’m not sure I understand 100% so forgive me if I'm off base here.

I think you reached for childElementNodes because you needed an NSArray but had an NSOrderedSet. What you ended up doing is exactly right: ask the ordered set for its contents as an array. (Happily this is cheap; if I recall correctly, the array you get back just proxies the ordered set, there’s no copying going on.)

childElementNodes does filter out out non-element nodes such as text nodes, and is tended as a convenience property for that (presumably) common need. Do you find that children does not include text nodes? Because it absolutely should. HTMLTextNode is a subclass of HTMLNode so the declared types don’t indicate any kind of filtering here.

I’m always happy to fix any documentation that’s not doing its job. Once we sort this out I’ll do another pass and see if I can clear things up!

nolanw avatar Apr 15 '18 14:04 nolanw

My main issue with childElementNodes is that it doesn't have a variant that returns text nodes, but I suppose children is a valid substitute for what I'm trying to achieve. I guess I was just expecting there would be something like a childNodes property that would be like childElementNodes except with all nodes, but then it would be a bit redundant when children exists.

Apocryphon avatar Apr 16 '18 18:04 Apocryphon

I think childNodes is a good idea. NSOrderedSet isn't a very common collection so the weirdness with the array property isn't obvious, and I doubt you're the first person to hesitate when looking for an array of child nodes.

I'll keep this issue open while pondering and then probably adding childNodes.

nolanw avatar Apr 16 '18 22:04 nolanw