diff --git a/package.json b/package.json
index 0e6f3fd..f57edb5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "findandreplacedomtext",
- "version": "0.4.5",
+ "version": "0.4.6",
"main": "./src/findAndReplaceDOMText.js",
"description": "findAndReplaceDOMText: DOM find/replace utility",
"repository": {
diff --git a/readme.md b/readme.md
index 445fbf5..1c82391 100644
--- a/readme.md
+++ b/readme.md
@@ -262,6 +262,7 @@ exposed.PRESETS = {
### Changelog
+ * 0.4.6 (5 Dec 2017): Fix indexInMatch ([See #60](https://github.com/padolsey/findAndReplaceDOMText/issues/60)). Fix undefined being echoed in optional+empty capture groups ([See #70](https://github.com/padolsey/findAndReplaceDOMText/issues/70)).
* 0.4.4 (4 May 2015): Remove duplicate key from `NON_CONTIGUOUS_PROSE_ELEMENTS`. Expose library via UMD ([See #32](https://github.com/padolsey/findAndReplaceDOMText/issues/32)).
* 0.4.3 (28 Apr 2015): Add `preset:prose` and `forceContext` features. [See #29](https://github.com/padolsey/findAndReplaceDOMText/issues/29).
* 0.4.2 (30 Mar 2014): Fix IE to avoid incorrectly-closed-tags issue ([see #20](https://github.com/padolsey/findAndReplaceDOMText/issues/20)). Thanks to [shauryamal](https://github.com/shauryamal)!
diff --git a/src/findAndReplaceDOMText.js b/src/findAndReplaceDOMText.js
index 556cc9a..f4c4cb9 100644
--- a/src/findAndReplaceDOMText.js
+++ b/src/findAndReplaceDOMText.js
@@ -1,5 +1,5 @@
/**
- * findAndReplaceDOMText v 0.4.5
+ * findAndReplaceDOMText v 0.4.6
* @author James Padolsey http://james.padolsey.com
* @license http://unlicense.org/UNLICENSE
*
@@ -334,14 +334,18 @@
if (curNode.nodeType === Node.TEXT_NODE) {
if (!endPortion && curNode.length + atIndex >= match.endIndex) {
-
// We've found the ending
+ // (Note that, in the case of a single portion, it'll be an
+ // endPortion, not a startPortion.)
endPortion = {
node: curNode,
index: portionIndex++,
text: curNode.data.substring(match.startIndex - atIndex, match.endIndex - atIndex),
- indexInMatch: atIndex - match.startIndex,
- indexInNode: match.startIndex - atIndex, // always zero for end-portions
+
+ // If it's the first match (atIndex==0) we should just return 0
+ indexInMatch: atIndex === 0 ? 0 : atIndex - match.startIndex,
+
+ indexInNode: match.startIndex - atIndex,
endIndexInNode: match.endIndex - atIndex,
isEnd: true
};
@@ -459,7 +463,7 @@
replacement = match.input.substring(match.endIndex);
break;
default:
- replacement = match[+t];
+ replacement = match[+t] || '';
}
return replacement;
});
diff --git a/test/test.js b/test/test.js
index cf91132..0562d2f 100644
--- a/test/test.js
+++ b/test/test.js
@@ -328,6 +328,17 @@ test('Right (\')', function() {
htmlEqual(d.innerHTML, 'this is [ test] test');
});
+test('Empty captured groups', function() {
+ var d = document.createElement('div');
+ d.innerHTML = '111333';
+ findAndReplaceDOMText(d, {
+ find: /(1+)(\s+)?(3+)/g,
+ replace: '$3$2$1'
+ });
+ // $2 is empty, so should be replaced by nothing (empty string):
+ htmlEqual(d.innerHTML, '333111');
+});
+
module('Filtering');
test('Element filtering', function() {
@@ -480,3 +491,44 @@ test('prose', function() {
');
});
+
+module('indexInMatch');
+
+test('Single portion', function() {
+ var d = document.createElement('div');
+ d.innerHTML = '___AAAAA';
+ // ^ 0
+ findAndReplaceDOMText(d, {
+ find: /A+/g,
+ replace: function(portion) {
+ return portion.indexInMatch;
+ }
+ });
+ htmlEqual(d.innerHTML, '___0');
+});
+
+test('Two portions', function() {
+ var d = document.createElement('div');
+ d.innerHTML = '___AAAAA';
+ // ^ 0 ^ 3
+ findAndReplaceDOMText(d, {
+ find: /A+/g,
+ replace: function(portion) {
+ return portion.indexInMatch;
+ }
+ });
+ htmlEqual(d.innerHTML, '___03');
+});
+
+test('>Two portions', function() {
+ var d = document.createElement('div');
+ d.innerHTML = '___AAAAA';
+ // ^ 0 ^ 2 ^ 3 ^ 4
+ findAndReplaceDOMText(d, {
+ find: /A+/g,
+ replace: function(portion) {
+ return portion.indexInMatch;
+ }
+ });
+ htmlEqual(d.innerHTML, '___0234');
+});