findAndReplaceDOMText icon indicating copy to clipboard operation
findAndReplaceDOMText copied to clipboard

Proposal: wrap combine mode

Open hftf opened this issue 8 years ago • 9 comments

Introduction

The main idea of this library is to split a match into portions when it crosses element boundaries.

Note: I will refer to only the input and output as a shorthand for calling the following function:

function wrap(input) {
	var el = document.createElement('div');
	el.innerHTML = input;
	findAndReplaceDOMText(el, {
		find:  /\w+/g,
		wrap:  'w'
	});
	var output = el.innerHTML;
	return output;
}

As expected, the following code splits the matched word b1b2 among two <w> elements:

input:  a b1<i>b2 c</i> <i>d e</i>
output: <w>a</w> <w>b1</w><i><w>b2</w> <w>c</w></i> <i><w>d</w> <w>e</w></i>

However, if the entire match corresponds to properly-nested HTML, then it is possible to just use a single element to wrap the match. So instead of the following:

input:  a b1<i>b2</i> <i>c d</i>
output: <w>a</w> <w>b1</w><i><w>b2</w></i> <i><w>c</w> <w>d</w></i>

the two portions b1 and b2 could be combined as such:

output: <w>a</w> <w>b1<i>b2</i></w> <i><w>c</w> <w>d</w></i>

Proposal

I think it could be useful to add this behavior in a new option called wrapCombineMode.

wrapCombineMode behavior
separate Original behavior. Each leaf (portion) of a match gets wrapped.
combine If the entire match encompasses balanced HTML, it is wrapped.
Otherwise, fall back to separate.
split Force the entire match to be wrapped as a unit.
(If the entire match encompasses balanced HTML, it is wrapped.
Otherwise, split up elements that cross the edges of the match.)

Here are some test cases (spaced out for legibility):

Basic balanced

input:    <i>aa</i>a               a<i>aa</i>               a<i>a</i>a
separate: <i><w>aa</w></i><w>a</w> <w>a</w><i><w>aa</w></i> <w>a</w><i><w>a</w></i><w>a</w>
combine:  <w><i>aa</i>a</w>        <w>a<i>aa</i></w>        <w>a<i>a</i>a</w>
split:    <w><i>aa</i>a</w>        <w>a<i>aa</i></w>        <w>a<i>a</i>a</w>

Complex balanced

input:    a<i><i>a</i></i>a                      <i>a<i>a</i></i>a                      <i>a</i>a<i>a</i>
separate: <w>a</w><i><i><w>a</w></i></i><w>a</w> <i><w>a</w><i><w>a</w></i></i><w>a</w> <i><w>a</w></i><w>a</w><i><w>a</w></i>
combine:  <w>a<i><i>a</i></i>a</w>               <w><i>a<i>a</i></i>a</w>               <w><i>a</i>a<i>a</i></w>
split:    <w>a<i><i>a</i></i>a</w>               <w><i>a<i>a</i></i>a</w>               <w><i>a</i>a<i>a</i></w>

Unbalanced

input:    aa<i>a               a</i>a<i>a                      a</i>aa
separate: <w>aa</w><i><w>a</w> <w>a</w></i><w>a</w><i><w>a</w> <w>a</w></i><w>aa</w>
combine:  <w>aa</w><i><w>a</w> <w>a</w></i><w>a</w><i><w>a</w> <w>a</w></i><w>aa</w>
split:    <w>aa<i>a</i></w>    <w><i>a</i>a<i>a</i></w>        <w><i>a</i>aa</w>

hftf avatar Dec 05 '17 13:12 hftf

Thanks for writing this up. 👍 Seems like a good idea! I'm pondering a slight re-write of the lib (the code is getting a bit difficult to maintain), and this definitely seems like a feature worth putting in (especially the 'combine' mode). Not sure of timeline, but shall update this ticket when the time comes.

padolsey avatar Dec 06 '17 08:12 padolsey

FWIW, I had ported my code to Fibrio so I could use it easily on the server. The author of that project also refactored the code, so it might be helpful to look at.

hftf avatar Dec 06 '17 10:12 hftf

@hftf @padolsey Any progress on this feature. It would be an amazing feature.

pjebs avatar Dec 29 '18 20:12 pjebs

I noticed back in 2012 that @padolsey mentioned it as 1 of 2 solutions to solve the problem in https://j11y.io/javascript/replacing-text-in-the-dom-solved/

pjebs avatar Dec 29 '18 20:12 pjebs

@hftf Are you aware of any forks that implement this feature?

pjebs avatar Dec 29 '18 21:12 pjebs

@pjebs I am not aware of any, no. In my opinion, this is the main feature I would expect to bring the project up to a 1.0 milestone.

hftf avatar Dec 29 '18 22:12 hftf

I have created a $30 USD bounty for anyone who can solve this:

https://thehonestscoop.com/docs/gutter/bounty/

pjebs avatar Feb 13 '19 03:02 pjebs

Do you think this may be relevant: https://github.com/bfred-it/zip-text-nodes (in some way)?

pjebs avatar May 24 '19 00:05 pjebs

Would love this too!

tobyzerner avatar Sep 17 '19 02:09 tobyzerner