Is it possible truncate excerpt with DOM atributtes? HTML/JS - javascript

I have tried to shorten excerpt from Wordpress REST API, I've tried maxLength HTML attribute, but it does not work.
<p
dangerouslySetInnerHTML={{ __html: excerpt.rendered }}
maxLength={10}
/>
Is there any way I can handle it within JS/React?
Thanks in advance

Your question hardly has anything to do with React, it's more about html.
HTML's maxlength attribute is applicable only to input and textarea tags, this way it will do nothing when applied to p tag.
HTML doesn't have anything similar for p natively, so, a custom implementation is needed. You obviously could do:
'Long text of the article that is going to be shortened'.slice(0, 9).concat('…')
which would produce Long text….
However, since you use dangerouslySetInnerHTML, I guess that excerpt.rendered contains HTML tags, so, you can't just slice it.
In this case, the easiest option would be to have 2 strings:
One containing ready-to-use markup.
One containing just text content.
If it's not an option, you may try to parse HTML & extract only text content (be cautious, it might produce unexpected results):
const parsedExcerpt = new DOMParser().parseFromString(excerpt.rendered, 'text/html');
const excerptText = parsedExcerpt.body.innerText.trim();
Now you could use excerptText.slice(0, 9).concat('…') (more or less) safely.

Related

How to render HTML tags from text in React

I'm working on a text highlighting and I was able to detect selection etc. Now I have something like
Te<span>x</span>t
in a string and
["Te", "<span>", "x", "</span>", "t"]
In an array. How can I render this using react in a safe way? DangerouslysetinnerHTML doesn't work here by the way (maybe needs a hook or something, but it's unsafe so, better to use something else).
*The amount of these spans can change so there may be a lot of tags.
Edit: My algorithm makes a mask (an array full of zeros) for a text and whenever user selects something it adds 1 to certain fields in array (like an interval). Then it parses the text and the mask, and when for example 01 occurs then it pastes the opening tag in between (and when 10 => closing tag). What's maybe other way of achieving Medium-like highlighting feature?
Thanks in advance
The dangerouslySetInnerHTML is dangerous when you try to render user content with it. What I mean, it's not more dangerous to render string with <spans> injected than the original string. If you want to sanitize the string, you could do it before highlighting.
<div dangerouslySetInnerHTML={{ __html: "Te<span>x</span>t" }} />

How do I apply css to text separated by commas inside of a textarea tag? (React.js Project)

Desired result:
I'm trying to highlight text separated by commas inside of a textarea tag (in a React project).
I really can't figure out how to accomplish this, yet every solution I've come across online uses jQuery (I really don't want to inject jQuery halfway through my project).
This is the function I currently have to trim the input values and split them:
handleTags = async (event) => {
let tags = event.target.value.toLowerCase().trim().replace(/[^\w,-]/g, '')
tags = tags.split(",")
await this.setState({post: {...this.state.post, tags: tags}})
}
And this is the JSX for the textarea within my render() {...} function:
<Card.Footer className="quickpost-tags-container">
<textarea
onChange={event => this.handleTags(event)}
className="postbox-tags-textarea"
placeholder="science, non-fiction, etc..."
contentEditable
suppressContentEditableWarning>
</textarea>
</Card.Footer>
I'd appreciate any help.
So I understand that this question was a bit meh, didn't make much sense and made me sound like a massive noob (it was like 4 in the morning). I was trying to get the tags that the user would put in to render the same as [refer to the image in the question]
I was able to conditionally render a span element above the textarea which would render each tag within a span element, dynamically. This achieved the desired result.
Hopefully, this will be helpful to someone looking to solve a similar problem.

How to retrieve the text in html CDATA section?

I have the following script element section in HTML:
<script type="text/x-markdown"><![CDATA[
# hello, This is Markdown Script Demo]]></script>
When i'm trying to retrieve the inner content via scripttag.innerHTML, it returns the text with ![CDATA[...]]>parts
Is there more efficient way to retrieve the inner part of CDATA section at once instead of applying regexp to remove it from received innerHTML data?
I don't think you will be able to retreive only whats inside the CDATA as its not a tag but plain text, when you get the innerHTML of the tag you will get everything as a string, so regexp is the only way I see you could get whats inside.
CDATA is an XML concept. It is a way of specifying a section of text inside which things that look like mark-up or special XML characters are treated as plain text. It is essentially equivalent to escaping < to < etc. everywhere within the CDATA section.
If the document has an HTML doctype, then the CDATA receives no special processing and is just more characters. If the document had an XHTML doctype, then you would be able to retrieve the CDATA section as is, with no further ado.
This question is quite old, but this might help somebody.
You can probably use textContent.
Example from parsing a rss feed node which looks like this:
<title><![CDATA[This contains the title]]></title>
Javascript:
const desc = el.querySelector('title').textContent;

Javascript: get plain text inside a span which has other nested tags present

Just for you guys to note, of course I have read this first:
Javascript get text inside a <span> element
However, my case is not that easy, let alone because I need to do it natively, without jQuery.
Supposing we have this on an arbitrary web page:
<span id="entry1" class="entries">
<img src="http://whereyourpicis.at/pic.jpg" border="0">
++ This is the plain text we want to get from the SPAN block. ++
<span id="nested2"><a onclick="doSomething()">Action!</a></span>
</span>
I've tried anything imaginable, but I can't say any of the "solutions" I tried was a good one, since it feels like a total kludge taking the whole innerHTML and then doing some sed-style regex magic on it.
There must be a more elegant way to accomplish this, which is why I'm asking here.
BTW I've also found out that even nextSibling() cannot work here.
I am not sure this is what you need, because you didn't specify what you need to be an exact output in your example code.
If you need to literally Strip HTML from Text JavaScript
you could use function like this:
function strip(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
please check this: http://jsfiddle.net/shershen08/7fFWn/3/
If you want to get only the text nodes within an element, I think you'll need to iterate over the element's childNodes and fetch the text nodes. Here's a quick-and-dirty example of a function that will fetch only the text nodes from a given element (it also skips any text nodes that are just whitespace, since those are often added as a result of HTML formatting but don't really mean anything to a human).

Regex replace string but not inside html tag

I want to replace a string in HTML page using JavaScript but ignore it, if it is in an HTML tag, for example:
visit google search engine
you can search on google tatatata...
I want to replace google by <b>google</b>, but not here:
visit google search engine
you can search on <b>google</b> tatatata...
I tried with this one:
regex = new RegExp(">([^<]*)?(google)([^>]*)?<", 'i');
el.innerHTML = el.innerHTML.replace(regex,'>$1<b>$2</b>$3<');
but the problem: I got <b>google</b> inside the <a> tag:
visit <b>google</b> search engine
you can search on <b>google</b> tatatata...
How can fix this?
You'd be better using an html parser for this, rather than regex. I'm not sure it can be done 100% reliably.
You may or may not be able to do with with a regexp. It depends on how precisely you can define the conditions. Saying you want the string replaced except if it's in an HTML tag is not narrow enough, since everything on the page is presumably within some HTML tag (BODY if nothing else).
It would probably work better to traverse the DOM tree for this instead of trying to use a regexp on the HTML.
Parsing HTML with a regular expression is not going to be easy for anything other than trivial cases, since HTML isn't regular.
For more details see this Stackoverflow question (and answers).
I think you're all missing the question here...
When he says inside the tag, he means inside the opening tag, as in the <a href="google.com"> tag...This is something quite different than text, say, inside a <p> </p> tag pair or <body> </body>. While I don't have the answer yet, I'm struggling with this same problem and I know it has to be solvable using regex. Once I figure it out, i'll come back and post.
WORKAROUND
If You can't use a html parser or are quite confident about Your html structure try this:
do the "bad" changing
repeat replace (<[^>]*)(<[^>]+>) to $1 a few times (as much as You need)
It's a simple workaround, but works for me.
Cons?
Well... You have to do the replace twice for the case ... ...> as it removes only first unwanted tag from every tag on the page
[edit:]
SOLUTION
Why not use jQuery, put the html code into the page and do something like this:
$(containerOrSth).find('a').each(function(){
if($(this).children().length==0){
$(this).text($(this).text().replace('google','evil'));
}else{
//here You have to care about children tags, but You have to know where to expect them - before or after text. comment for more help
}
});
I'm using
regex = new RegExp("(?=[^>]*<)google", 'i');
you can't really do that, your "google" is always in some tag, either replace all or none
Well, since everything is part of a tag, your request makes no real sense. If it's just the <a /> tag, you might just check for that part. Mainly by making sure you don't have a tailing </a> tag before a fresh <a>
You can do that using REGEX, but filtering blocks like STYLE, SCRIPT and CDATA will need more work, and not implemented in the following solution.
Most of the answers state that 'your data is always in some tags' but they are missing the point, the data is always 'between' some tags, and you want to filter where it is 'in' a tag.
Note that tag characters in inline scripts will likely break this, so if they exist, they should be processed seperately with this method. Take a look at here :
complex html string.replace function
I can give you a hacky solution…
Pick a non printable character that’s not in your string…. Dup your buffer… now overwrite the tags in your dup buffer using the non printable character… perform regex to find position and length of match on dup buffer … Now you know where to perform replace in original buffer

Categories

Resources