Implementing hook_civicrm_alterAngular breaks href attributes that include some angular expressions
See also https://chat.civicrm.org/civicrm/pl/xqbryepb4fra5f6smn8uazbeoc
searchkit has a line like this in the code: <a href="#/create/{{:: row.data.api_entity + '?params=' + $ctrl.encode(row.data.api_params) }}">
If you implement alterAngular, even if you don't change anything, it breaks that code because the +
's become spaces. e.g.
function myextension_civicrm_alterAngular(\Civi\Angular\Manager $angular) {
$changeSet = \Civi\Angular\ChangeSet::create('dosomething')
->alterHtml('~/crmSearchAdmin/searchListing/buttons.html',
function (phpQueryObject $doc) {
// it breaks even if you don't do anything here
});
$angular->add($changeSet);
The problem seems to be in DOMDocument itself (or maybe libxml). It treats href specially, but is picky about which characters it encodes. It will encode {
, [
, &
, $
, etc but not +
, .
, =
, etc, and amazingly not even %
. So then when you urldecode it turns the +
into a space, and if you had something like %12
in your original string, it would end up decoding that into a single char. It serves you right a bit for using those chars in a filename/url, but it's legal.
This seems inconsistent/error-prone.
And note it only does this for href attributes, e.g.
<?php
$d = new DOMDocument();
$d->loadHTML('<a href="abc/!@#$%12*-.+(){}[]=" data-foo="abc/!@#$%12*-.+(){}[]=">');
echo $d->saveHTML();
gives
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><a href="abc/!@#%24%12*-.+()%7B%7D%5B%5D=" data-foo="abc/!@#$%12*-.+(){}[]="></a></body></html>
So while Civi\Angular\Coder could maybe be updated somehow, there isn't really a way for it to know if you meant something like %2C
to be a literal percent followed by 2C, or if you meant ,
, and ditto for all the other characters it skips. So using ng-href instead seems like a good way of avoiding the problem, just as noted in the chat it's hard to enforce this. But core could do it at least.