diff --git a/src/dyna-rules.html b/src/dyna-rules.html
index de125bf39..704b3976e 100644
--- a/src/dyna-rules.html
+++ b/src/dyna-rules.html
@@ -51,6 +51,7 @@
+
diff --git a/src/js/dyna-rules.js b/src/js/dyna-rules.js
index 581d48fc6..2c3655cb5 100644
--- a/src/js/dyna-rules.js
+++ b/src/js/dyna-rules.js
@@ -29,6 +29,9 @@
/******************************************************************************/
+const psl = self.publicSuffixList;
+const hostnameToDomainMap = new Map();
+
const mergeView = new CodeMirror.MergeView(
document.querySelector('.codeMirrorMergeContainer'),
{
@@ -387,8 +390,22 @@ const onPresentationChanged = (( ) => {
const reRule = /^([^ ]+) ([^/ ]+) ([^ ]+ [^ ]+)/;
const reUrlRule = /^([^ ]+) ([^ ]+) ([^ ]+ [^ ]+)/;
- const reverseHn = function(hn) {
- return hn.split('.').reverse().join('.');
+ const sortNormalizeHn = function(hn) {
+ let domain = hostnameToDomainMap.get(hn);
+ if ( domain === undefined ) {
+ domain = psl.getDomain(hn);
+ hostnameToDomainMap.set(hn, domain);
+ }
+ let normalized = domain || hn;
+ if ( hn.length !== domain.length ) {
+ const subdomains = hn.slice(0, hn.length - domain.length - 1);
+ normalized += '.' + (
+ subdomains.includes('.')
+ ? subdomains.split('.').reverse().join('.')
+ : subdomains
+ );
+ }
+ return normalized;
};
const slotFromRule = rule => {
@@ -396,18 +413,18 @@ const onPresentationChanged = (( ) => {
let match = reSwRule.exec(rule);
if ( match !== null ) {
type = ' ' + match[1];
- srcHn = reverseHn(match[2]);
+ srcHn = sortNormalizeHn(match[2]);
desHn = srcHn;
extra = match[3];
} else if ( (match = reRule.exec(rule)) !== null ) {
type = '\x10FFFE';
- srcHn = reverseHn(match[1]);
- desHn = reverseHn(match[2]);
+ srcHn = sortNormalizeHn(match[1]);
+ desHn = sortNormalizeHn(match[2]);
extra = match[3];
} else if ( (match = reUrlRule.exec(rule)) !== null ) {
type = '\x10FFFF';
- srcHn = reverseHn(match[1]);
- desHn = reverseHn(vAPI.hostnameFromURI(match[2]));
+ srcHn = sortNormalizeHn(match[1]);
+ desHn = sortNormalizeHn(vAPI.hostnameFromURI(match[2]));
extra = match[3];
}
if ( sortType === 0 ) {
@@ -614,6 +631,7 @@ vAPI.messaging.send('dashboard', {
}).then(details => {
thePanes.orig.original = details.permanentRules;
thePanes.edit.original = details.sessionRules;
+ psl.fromSelfie(details.pslSelfie);
onPresentationChanged(true);
});
diff --git a/src/js/messaging.js b/src/js/messaging.js
index 06cad9fdb..561c66561 100644
--- a/src/js/messaging.js
+++ b/src/js/messaging.js
@@ -1053,7 +1053,8 @@ const getRules = function() {
µb.sessionFirewall.toArray().concat(
µb.sessionSwitches.toArray(),
µb.sessionURLFiltering.toArray()
- )
+ ),
+ pslSelfie: self.publicSuffixList.toSelfie(),
};
};