Comments (15)
function stripHTML ( htmlString ) {
const tmp = document.createElement('div');
tmp.innerHTML = htmlString;
return tmp.textContent;
}
from react-contenteditable.
It's your responsability to sanitize the output of this component to your needs. Even if this component returns plain text, it does not prevent a hacker to send HTML and script tags in api payloads to your server, by using curl.
from react-contenteditable.
@SilvioMessi, because you are changing the content the caret position is being reset. To combat this you need to measure, and then save the current caret position and then restore it after the content has been replaced.
here is some sample code to help
// no operation
const noop = () => null
/**
* @function
* @description
* @param {DOMElement} container The container in which the cursor position must be saved
* @return {Function} A function used to restore caret position
*/
function selectionSaveCaretPosition(container) {
const selection = window.getSelection();
if (!selection || selection.rangeCount === 0) {
return noop;
}
const range = selection.getRangeAt(0);
const clone = range.cloneRange();
// find the range start index
clone.selectNodeContents(container);
clone.setStart(container, 0);
clone.setEnd(range.startContainer, range.startOffset);
const startIndex = clone.toString().length;
// find the range end index
clone.selectNodeContents(container);
clone.setStart(container, 0);
clone.setEnd(range.endContainer, range.endOffset);
const endIndex = clone.toString().length;
return function restoreCaretPosition() {
const start = getTextNodeAtPosition(container, startIndex);
const end = getTextNodeAtPosition(container, endIndex);
const newRange = new Range();
newRange.setStart(start.node, start.position);
newRange.setEnd(end.node, end.position);
selection.removeAllRanges();
selection.addRange(newRange);
container.focus();
};
};
/**
* @function
* @description This function is used to determine the text node and it's index within
* a "root" DOM element.
*
* @param {DOMElement} rootEl The root
* @param {Integer} index The index within the root element of which you want to find the text node
* @return {Object} An object that contains the text node, and the index within that text node
*/
function getTextNodeAtPosition(rootEl, index) {
const treeWalker = document.createTreeWalker(rootEl, NodeFilter.SHOW_TEXT, function next(elem) {
if(index > elem.textContent.length) {
index -= elem.textContent.length;
return NodeFilter.FILTER_REJECT;
}
return NodeFilter.FILTER_ACCEPT;
});
const node = treeWalker.nextNode();
return {
node: node ? node : rootEl,
position: node ? index : 0,
};
};
from react-contenteditable.
@thomfoolery good idea,so nice
from react-contenteditable.
@thomfoolery
line breaks are lost with this method
stripHTML('line1<br>line2')
=> 'line1line2'
from react-contenteditable.
Hi!
I've a problem using the solution proposed by @thomfoolery.
Inside my component I have an editable div, and its value is bind to a state variable.
<ContentEditable
html={this.state.entries[entryIndex].rawText}
disabled={this.state.entries[entryIndex].disabled}
onChange={this.entryChange.bind(this, entryIndex)}
/>
entryChange(entryIndex, event) {
const entries = this.state.entries.slice();
entries[entryIndex].rawText = this.stripHTML(event.target.value);
this.setState({
entries : entries
});
}
stripHTML ( htmlString ) {
const tmp = document.createElement('div');
tmp.innerHTML = htmlString;
return tmp.textContent;
}
When I write inside the div all works fine until I type the space bar, because the caret goes at the start of the div.
.
How can I solve this problem?
Thank you.
from react-contenteditable.
@sharpensteel, this is in congruence with the method name, stripHTML.
It strips out any markup, including line breaks defined with markup.
from react-contenteditable.
i ended up with variation of this solution:
https://stackoverflow.com/questions/22677931/react-js-onchange-event-for-contenteditable#answer-27255103
it's just simple wrapper component around pure <div>
. it monitors changes in div
and emmits text version of html content (converter: html-to-text)
from react-contenteditable.
What would be the interest of using a contenteditable element if you only want plain text ? A simple <input>
or <textarea>
would be simpler, wouldn't it ?
from react-contenteditable.
See here for an example of how to sanitize the html input : https://codesandbox.io/s/n067mmwjym
from react-contenteditable.
Hi I have a problem with ave and load safe text
I am sending the text to a redux store to send it an API and response with other text
when I save it in redux it looks like the following
__
this is how it looks & nbsp;
& n bsp ; lik& n bsp;"
from react-contenteditable.
@ramisalem And what do you expect ? If you do not want html, then you could use a simple textarea. I you want to sanitize the html or reformat it, then you can use a js library for that.
from react-contenteditable.
What would be the interest of using a contenteditable element if you only want plain text ? A simple
<input>
or<textarea>
would be simpler, wouldn't it ?
And what do you expect ? If you do not want html, then you could use a simple textarea. I you want to sanitize the html or reformat it, then you can use a js library for that.
Elements marked withe contenteditable
that aren't input / text naturally expand to the size of their content. With input
/ textarea
you would have to use JavaScript to do that. I.e: https://css-tricks.com/auto-growing-inputs-textareas/
Regardless, supplying this use case would help wary developers from otherwise creating something that has a security risk attached. I see no reason that you can't support this by providing alternative props or some sort of a toggle. This is a valid use case and I don't think it should go ignored.
Also if the text going into the component has HTML (or something that looks like it) then it might get processed as such even though it's just plain text. So as a user of this component I would have to make sure everything is encoded. In addition to that, say I wanted to remove HTML completely and used something like DOMParser or created an element and called textContent: then I would run in to small bugs such as when I start typing <a
but through those methods the text would come back as blank because it thought it was HTML. Another hiccup manifests when all text is removed from the element. You would expect that it would become an empty string but it returns <br />
instead.
Without hassle on the user's side, if all innerHTML
in this library could be toggled to innerText
then this issue would be resolved. Here is my makeshift component using that StackOverflow answer as a base:
class ContentEditable extends React.Component {
getDOMNode() {
return ReactDOM.findDOMNode(this);
}
shouldComponentUpdate(nextProps) {
return nextProps.value !== this.getDOMNode().innerText;
}
componentDidUpdate() {
if (this.props.value !== this.getDOMNode().innerText) {
this.getDOMNode().innerText = this.props.value;
}
}
emitChange() {
const value = this.getDOMNode().innerText;
if (this.props.onChange && value !== this.lastText) {
this.props.onChange({
target: {
value: value
}
});
}
this.lastText = value;
}
render() {
return <div {...this.props} onInput={() => this.emitChange()} onBlur={() => this.emitChange()} contentEditable>
{this.props.value || ""}
</div>;
}
}
from react-contenteditable.
@k3zi : This does not work. This prevents the user from typing text anywhere but at the very end of the contentEditable div. Trying to write something in the middle would cause a cursor jump.
from react-contenteditable.
@lovasoa I'm not seeing that issue. Could you share your setup? I have it working here: https://codesandbox.io/s/simple-rich-text-editor-in-react-forked-xzbm9
Note: I did change the name of the incoming prop to value
.
from react-contenteditable.
Related Issues (20)
- Switch to edit mode only on double click HOT 1
- When using Firefox and pressing enter, a <br> tag is added to the saved html HOT 1
- Custom components in html? HOT 1
- Retain caret position while dynamically changing the rendered html HOT 2
- cursor outside of block HOT 3
- expose props API to enable selection range get & set HOT 1
- auto height support
- vertical align center support as a props option HOT 3
- accept image
- Contenteditable should accept aria, for to accommodate label HOT 1
- ContentEditable' cannot be used as a JSX component HOT 4
- ability to set inputmode
- if ContentEditable in contenteditable="true", no trigger onChange HOT 1
- Is this component usable in Typescript?
- vim cursor popping up to top of view when hit escape
- how to set custom style in html HOT 1
- Getting caret line number.
- Enable passing custom value for active state
- Paste wont work some times.
- Content color is changing to red
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-contenteditable.