Skip to content

Proposal: wrap combine mode #71

@hftf

Description

@hftf

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>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions