findandreplacedomtext
Advanced tools
Comparing version 0.4.4 to 0.4.5
{ | ||
"name": "findandreplacedomtext", | ||
"version": "0.4.4", | ||
"version": "0.4.5", | ||
"main": "./src/findAndReplaceDOMText.js", | ||
@@ -5,0 +5,0 @@ "description": "findAndReplaceDOMText: DOM find/replace utility", |
@@ -83,2 +83,3 @@ # findAndReplaceDOMText | ||
* **wrap** *optional* (`String | Node`): A string representing the node-name of an element that will be wrapped around matches (e.g. `span` or `em`). Or a Node (i.e. a stencil node) that we will clone for each match portion. | ||
* **wrapClass** *optional* (`String`): A string representing the class name to be assigned to the wrapping element (e.g. `<span class="myClass">found text</span>`). If the `wrap` option is not specified, then this option is ignored. | ||
* **portionMode** *optional* (`String`, one of `"retain"` or `"first"`): Indicates whether to re-use existing node boundaries when replacing a match with text (i.e. the default, `"retain"`), or whether to instead place the entire replacement in the first-found match portion's node. *Most of the time you'll want the default*. | ||
@@ -111,2 +112,11 @@ * **filterElements** *optional* (`Function`): A function to be called on every element encountered by `findAndReplaceDOMText`. If the function returns false the element will be altogether ignored. | ||
A portion object has the following properties: | ||
* `node`: The DOM node pertaining to the portion. Note that this node might not fully encapsulate part of a match, e.g. the node might contain additional text. | ||
* `index`: The index of the portion (`0` is the first portion of the match, etc.) | ||
* `text`: The text of the portion relevant to the match | ||
* `indexInMatch`: The index of the portion within the match | ||
* `indexInNode`: The index of the portion text within the node | ||
#### The `replace` Function | ||
@@ -145,2 +155,46 @@ | ||
#### The `wrap` Option | ||
If you pass a string to the `wrap` option, every matching text segment will be wrapped in that element. If you also specify the `wrapClass` option, the wrapping element will be assigned that class after it is created. This is useful for attaching various styles from your css. | ||
E.g. | ||
*Input HTML* | ||
```html | ||
<div id="container"> | ||
Explaining how to wrap text in elements with and without classes assigned. | ||
</div> | ||
``` | ||
*JS* | ||
```js | ||
findAndReplaceDOMText(document.getElementById('container'), { | ||
find: 'without', | ||
wrap: 'em' | ||
}); | ||
findAndReplaceDOMText(document.getElementById('container'), { | ||
find: 'with ', | ||
wrap: 'em', | ||
wrapClass: 'shiny' | ||
}); | ||
``` | ||
*CSS* | ||
```css | ||
.shiny { | ||
background-color: yellow; | ||
} | ||
``` | ||
*Output HTML* | ||
```html | ||
<div id="container"> | ||
Explaining how to wrap text in elements <em class="shiny">with </em>and <em>without</em> classes assigned. | ||
</div> | ||
``` | ||
#### The instance | ||
@@ -147,0 +201,0 @@ |
/** | ||
* findAndReplaceDOMText v 0.4.3 | ||
* findAndReplaceDOMText v 0.4.5 | ||
* @author James Padolsey http://james.padolsey.com | ||
@@ -27,9 +27,4 @@ * @license http://unlicense.org/UNLICENSE | ||
var doc = document; | ||
var toString = {}.toString; | ||
var hasOwn = {}.hasOwnProperty; | ||
function isArray(a) { | ||
return toString.call(a) == '[object Array]'; | ||
} | ||
function escapeRegExp(s) { | ||
@@ -77,3 +72,3 @@ return String(s).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | ||
} | ||
m.endIndex = m.index + m[0].length; | ||
@@ -95,5 +90,5 @@ m.startIndex = m.index; | ||
/** | ||
/** | ||
* findAndReplaceDOMText | ||
* | ||
* | ||
* Locates matches and replaces with replacementNode | ||
@@ -104,2 +99,3 @@ * | ||
* @param {String|Element} [options.wrap] A NodeName, or a Node to clone | ||
* @param {String} [options.wrapClass] A classname to append to the wrapping element | ||
* @param {String|Function} [options.replace='$&'] What to replace each match with | ||
@@ -137,3 +133,3 @@ * @param {Function} [options.filterElements] A Function to be called to check whether to | ||
// Input elements | ||
input:1, textarea:1, select:1, option:1, optgroup: 1, button:1, | ||
input:1, textarea:1, select:1, option:1, optgroup:1, button:1, | ||
// Table related elements: | ||
@@ -180,3 +176,3 @@ table:1, tbody:1, thead:1, th:1, tr:1, td:1, caption:1, col:1, tfoot:1, colgroup:1 | ||
// ENable match-preparation method to be passed as option: | ||
// Enable match-preparation method to be passed as option: | ||
this.prepMatch = options.prepMatch || this.prepMatch; | ||
@@ -250,3 +246,3 @@ | ||
} | ||
match.endIndex = characterOffset + match.index + match[0].length; | ||
@@ -273,5 +269,5 @@ match.startIndex = characterOffset + match.index; | ||
*/ | ||
function getText(node, txt) { | ||
function getText(node) { | ||
if (node.nodeType === 3) { | ||
if (node.nodeType === Node.TEXT_NODE) { | ||
return [node.data]; | ||
@@ -289,3 +285,3 @@ } | ||
if (node.nodeType === 3) { | ||
if (node.nodeType === Node.TEXT_NODE) { | ||
txt[i] += node.data; | ||
@@ -299,3 +295,3 @@ continue; | ||
forceContext && | ||
node.nodeType === 1 && | ||
node.nodeType === Node.ELEMENT_NODE && | ||
(forceContext === true || forceContext(node)) | ||
@@ -322,6 +318,6 @@ ) { | ||
} | ||
}, | ||
/** | ||
/** | ||
* Steps through the target node, looking for matches, and | ||
@@ -349,3 +345,3 @@ * calling replaceFn when a match is found. | ||
if (curNode.nodeType === 3) { | ||
if (curNode.nodeType === Node.TEXT_NODE) { | ||
@@ -392,3 +388,3 @@ if (!endPortion && curNode.length + atIndex >= match.endIndex) { | ||
doAvoidNode = curNode.nodeType === 1 && elementFilter && !elementFilter(curNode); | ||
doAvoidNode = curNode.nodeType === Node.ELEMENT_NODE && elementFilter && !elementFilter(curNode); | ||
@@ -400,3 +396,3 @@ if (startPortion && endPortion) { | ||
// processMatches has to return the node that replaced the endNode | ||
// and then we step back so we can continue from the end of the | ||
// and then we step back so we can continue from the end of the | ||
// match: | ||
@@ -459,3 +455,3 @@ | ||
prepareReplacementString: function(string, portion, match, matchIndex) { | ||
prepareReplacementString: function(string, portion, match) { | ||
var portionMode = this.options.portionMode; | ||
@@ -497,6 +493,7 @@ if ( | ||
getPortionReplacementNode: function(portion, match, matchIndex) { | ||
getPortionReplacementNode: function(portion, match) { | ||
var replacement = this.options.replace || '$&'; | ||
var wrapper = this.options.wrap; | ||
var wrapperClass = this.options.wrapClass; | ||
@@ -511,3 +508,3 @@ if (wrapper && wrapper.nodeType) { | ||
if (typeof replacement == 'function') { | ||
replacement = replacement(portion, match, matchIndex); | ||
replacement = replacement(portion, match); | ||
if (replacement && replacement.nodeType) { | ||
@@ -521,5 +518,9 @@ return replacement; | ||
if (el && wrapperClass) { | ||
el.className = wrapperClass; | ||
} | ||
replacement = doc.createTextNode( | ||
this.prepareReplacementString( | ||
replacement, portion, match, matchIndex | ||
replacement, portion, match | ||
) | ||
@@ -546,3 +547,3 @@ ); | ||
var preceedingTextNode; | ||
var precedingTextNode; | ||
var followingTextNode; | ||
@@ -556,4 +557,4 @@ | ||
// Add `before` text node (before the match) | ||
preceedingTextNode = doc.createTextNode(node.data.substring(0, startPortion.indexInNode)); | ||
node.parentNode.insertBefore(preceedingTextNode, node); | ||
precedingTextNode = doc.createTextNode(node.data.substring(0, startPortion.indexInNode)); | ||
node.parentNode.insertBefore(precedingTextNode, node); | ||
} | ||
@@ -578,4 +579,4 @@ | ||
this.reverts.push(function() { | ||
if (preceedingTextNode === newNode.previousSibling) { | ||
preceedingTextNode.parentNode.removeChild(preceedingTextNode); | ||
if (precedingTextNode === newNode.previousSibling) { | ||
precedingTextNode.parentNode.removeChild(precedingTextNode); | ||
} | ||
@@ -594,3 +595,3 @@ if (followingTextNode === newNode.nextSibling) { | ||
preceedingTextNode = doc.createTextNode( | ||
precedingTextNode = doc.createTextNode( | ||
matchStartNode.data.substring(0, startPortion.indexInNode) | ||
@@ -630,3 +631,3 @@ ); | ||
matchStartNode.parentNode.insertBefore(preceedingTextNode, matchStartNode); | ||
matchStartNode.parentNode.insertBefore(precedingTextNode, matchStartNode); | ||
matchStartNode.parentNode.insertBefore(firstNode, matchStartNode); | ||
@@ -640,3 +641,3 @@ matchStartNode.parentNode.removeChild(matchStartNode); | ||
this.reverts.push(function() { | ||
preceedingTextNode.parentNode.removeChild(preceedingTextNode); | ||
precedingTextNode.parentNode.removeChild(precedingTextNode); | ||
firstNode.parentNode.replaceChild(matchStartNode, firstNode); | ||
@@ -643,0 +644,0 @@ followingTextNode.parentNode.removeChild(followingTextNode); |
Sorry, the diff of this file is not supported yet
107896
2929
303