Different markup generated on server and client from the same JSX code - reactjs

This is my JSX:
<h4>{post.title} <small> (by {post.author})</small> </h4>
This is what is generated on the server (using React.renderComponentToString()) and sent to the client.
<h4 data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0">
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.0">Why JavaScript is eating the world.</span>
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.1"> </span>
<small data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.2">
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.2.0"> (by </span>
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.2.1">spike</span>
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.2.2">)</span>
</small>
<span data-reactid=".2ggx1vlvrwg.1.0.0.$posts-about.$2.0.3"></span>
</h4>
And this is what is generated on the client side (in browser):
<h4 data-reactid=".0.1.0.0.$posts-about.$2.0">
<span data-reactid=".0.1.0.0.$posts-about.$2.0.0">Why JavaScript is eating the world.</span>
<small data-reactid=".0.1.0.0.$posts-about.$2.0.1">
<span data-reactid=".0.1.0.0.$posts-about.$2.0.1.0"> (by </span>
<span data-reactid=".0.1.0.0.$posts-about.$2.0.1.1">spike</span>
<span data-reactid=".0.1.0.0.$posts-about.$2.0.1.2">)</span>
</small>
</h4>
Apparently two spans are missing and that's causing React attempted to use reuse markup in a container but the checksum was invalid. error.
I suppose that the problem is in the JSX compiler. The generated JavaScript that is bundled and sent to the client is different from what the server is using.
Funny thing is that if I "fix" the indentation in JSX, it works. Both server and client generate the same HTML markup without those extra spans.
<h4>{post.title}
<small> (by {post.author})</small>
</h4>
However I haven't read anything in the documentation about being careful width JSX indentation and this makes me a little bit nervous because this kind of problem is hard (or at least annoying) to debug.

The problem was caused by an out-dated version of reactify. As a consequence two different versions of JSX compiler were used. As #FakeRainBrigand pointed out, the rules for treating whitespaces in JSX have changed recently and that caused the difference in compiled JavaScript.

JSX handling of whitespace makes a lot of sense when you understand the rules.
If it's on the same line it will work exactly like html whitespace
Spaces directly before or after a new line character are removed
The last rule is different from HTML for a very good reason. If you have a list of things, and you don't want a space between them in HTML, you have to pick one of these:
<ul><li>Apples</li><li>Oranges</li></ul>
<ul><!--
--><li>Apples</li><!--
--><li>Oranges</li><!--
--></ul>
As wonderful as those are, in JSX it can either look like the first one, or
<ul>
<li>Apples</li>
<li>Oranges</li>
</ul>
And if you do want the space you can either insert it inside one of the elements
<ul>
<li>Apples </li>
<li>Oranges </li>
</ul>
or put a very explicit literal space where you want it
<ul>
<li>Apples</li>
{' '}
<li>Oranges</li>
</ul>
It has the side bonus of being my new favorite emoticon {' '}

Related

ng-repeat fails on a p>div structure, but works for a div>div structure?

I'm maintaining a legacy product, and found a quirk that I haven't seen before in AngularJS.
As demonstrated in this Plunker, the following HTML fails to render:
<p ng-repeat="item in items">
<div>{{item.type}}</div>
</p>
while this renders just fine:
<div ng-repeat="item in items">
<div>{{item.type}}</div>
</div>
Is there any explanation as to why this might be the case?
I was rather caught off-guard with this, as I don't recall seeing anything about this in the development resources.
It most likely is due to the fact that the HTML spec specifies that for a <p> immediately followed by a <div>, the close tag is optional.
I would assume this means that somehow the browser silently ignores the presence of any explicit source-specified </p> tag. I'd guess that when ng-repeat is parsing the source, it then cannot find the end of the repeated section, and therefore cannot render as expected.

Tampermonkey Remove specific Content

I would like to remove things from the main page but the information I need is stored on the next site. How do I approach this?
This is stored on the first page where I can see all articles and all links in href have different numbers, sometimes numbers and letters.
<div class="NewsArticle">
<div class="featured-content-image">
<a href="/27312/72410214/" rel="bookmark">
<img class="imageclass" referrerpolicy="no-referrer" data-original"https/domainname.com/2021/0/Article01.jpg" src="https/domainname.com/2021/0/Article01.jpg" alt="Article01" style="display: inline;">
<div class="link-overlay"></div>
</a>
<span class"article-views">170392 Views</span>
</div>
This is on the second site where, for example, "military" is stored for whatever reason. Is it possible to remove the articles that contain "military"?
<a title="military" href="/category/military" rel="tag" style="margin-right:3px;margin-bottom:3px;" class="btn btn-info btn-md">military</a>
using jquery you can do something like
$("div").remove()
this selects all the divs and removes them
or you can do
$( "div:contains('military')" ).remove()
this looks at all divs if the divs have military in it it is then removed
IMPORTANT:
Make sure to have
// #require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
And declare the variable
/* globals jQuery, $, waitForKeyElements */

Avalon Edit Highlighting within Highlighting

With Avalon Edit, I'm looking for a way to provide a highlighting format while inside something that is already formatted.
That is, I'd like to highlight thing inside quotes, but within those quotes I have another syntax that can be added that starts with ${ and ends with }.
By default, it seems that the syntax highlighting stops once it enters a 'begin' and doesn't look for any others until the end is reached.
<Span color="ParamName">
<Begin>"</Begin>
<End>(?=:)</End>
</Span>
<Span color="Variable" multiline="false">
<Begin>\${</Begin>
<End>}</End>
</Span>
So here the ${ syntax is only colorized if it is not within a ParamName ("). is there a way to allow my Variable highlighting to work even if it is in a ParamName (yes ParamName is from JSON formatting, I'd like my highlighting to work no matter where it shows in the JSON syntax)?
Full Highlighter code:
<Keywords color="Digits" >
<Word>true</Word>
<Word>false</Word>
</Keywords>
<Span color="Value" multiline="true">
<Begin>
(?<=:)\040?"[^"]*
</Begin>
<End>"</End>
</Span>
<Span color="ParamName">
<Begin>"</Begin>
<End>(?=:)</End>
</Span>
<Span color="Variable" multiline="false">
<Begin>\${</Begin>
<End>}</End>
</Span>
<Rule color="Digits">\b0[xX][0-9a-fA-F]+|(\b\d+(\.[0-9]+)?|\.[0-9]+)([eE][+-]?[0-9]+)?</Rule>
A <Span> switches to another <RuleSet> that is active within the span. By default, that's an empty rule set, so nothing else is active.
If you want a rule to apply within a span, move it to the nested ruleset:
<Span color="ParamName">
<Begin>"</Begin>
<End>(?=:)</End>
<RuleSet>
<Span color="Variable" multiline="false">
<Begin>\${</Begin>
<End>}</End>
</Span>
</RuleSet>
</Span>

Only certain bootstrap glyphicons are displaying correctly, consistent results in all browsers

I know that this question has been asked a lot but I tried re-downloading Bootstrap (I've got the latest version - 3.3.6), my #font-face{ } has the correct paths to my font files, I don't know what else to try. I get the same results in both Chrome and Firefox. One thought I had is that I'm trying to put my icons w/in <em> tags, but when I tried moving them to outside the tags, they still looked like squiggley lines, so that didn't fix it.
I want to use glyphicon-chevron-up and glyphicon-chevron-down (which show up as ≅ and [ ) but when I do something like <span class="caret"></span> then it looks perfectly normal.
Here is how I am using them:
<em class="pull-right">
<em class="pull-left">
<span class="glyphicon-chevron-up" ng-click="plusOne($index)"></span><br>
<span class="glyphicon-chevron-down" ng-click="minusOne($index)"></span>
</em>
{{ post.upvotes - post.downvotes }}
</em>
I can still click the icons and increase/decrease the vote count so I don't think it is a problem with Angular, but just for reference I am using angular1.4.9 and django1.9. Again, I know several variations of this question have been asked but none of the solutions I found worked for me so any additional ideas would be appreciated!
Maybe its for this:
<span class="glyphicon glyphicon-chevron-up" ng-click="plusOne($index)"></span><br>
In my page works great.
Just add glyphicon before the glyphicon-icon name.

angularjs: how to prevent from processing additional directives after ng-hide

I have some code that is running twice even thou angularJs is rendering only one branch of it.
<div ng-Show="SomeCondition">
...
</div>
<div ng-Hide="SomeCondition">
...
</div>
AngularJs is correctly only rendering one of the divs, however it's processing both. This is leading to some performance degredation as each section is quite big. Is there a way to remove processing from one of the branch of execution?
What you're looking for is ng-switch, which will 'Conditionally change the DOM structure.' This means that the other cases will not be run, unlike using ng-hide/ng-show, which just adjust CSS.
http://docs.angularjs.org/api/ng.directive:ngSwitch
<div ng-switch on="SomeCondition">
<div ng-switch-when="true">Example</div>
<span ng-switch-when="false">Example Two</span>
<span ng-switch-when="somethingElse">Example Three</span>
<span ng-switch-default>default</span>
</div>

Resources