mojolicious / dom.js

:crystal_ball: A fast and very small HTML/XML DOM parser with CSS selectors
https://www.npmjs.com/package/@mojojs/dom
MIT License
20 stars 3 forks source link

el.replace escapes &#x27; but not < or >, which is different than Mojo::DOM #27

Open akarelas opened 8 months ago

akarelas commented 8 months ago
import DOM from '@mojojs/dom';

let dom = new DOM('<div><p>Alex</p></div>');
dom.at('div').replace('<b>1</b>');
console.log(dom.toString()); // prints: <b>1</b>

dom = new DOM('<div><p>Alex</p></div>');
dom.at('div').replace('&#x27;hi');
console.log(dom.toString()); // prints: &amp;#x27;hi

First replace invocation doesn't escape < or >, whereas second snippet escapes &. This behavior is inconsistent with Mojo::DOM, as can be shown by the following piece of code:

use Mojo::DOM;

my $dom = Mojo::DOM->new('<div><p>Alex</p></div>');
$dom->at('div')->replace('<b>1</b>');
say $dom->to_string; # prints <b>1</b>

$dom = Mojo::DOM->new('<div><p>Alex</p></div>');
$dom->at('div')->replace('&#x27;hi');
say $dom->to_string; # prints &#39;hi which is equivalent to &#x27;hi
kraih commented 8 months ago

Isn't there an existing Mojo::DOM test that covers the case already?

akarelas commented 8 months ago

I don't know, but in the JS lib, the bug only appears with entities matching &#x (the x is necessary).

Whereas Mojo::DOM's tests don't contain &#x anywhere.

akarelas commented 8 months ago

The same issue (i.e. &#x27; being escaped in JS) also appears with the replaceContent (vs Mojo::DOM's content method, which doesn't escape it):

import DOM from '@mojojs/dom';

let dom = new DOM('<div><p>Alex</p></div>');
dom.at('div').replaceContent('&#x27;hi');
console.log(dom.toString()); // prints: <div>&amp;#x27;hi</div>