Skip to content
This repository has been archived by the owner on Aug 16, 2023. It is now read-only.

Commit

Permalink
fix gorhill/uBlock#2084 for uMatrix
Browse files Browse the repository at this point in the history
  • Loading branch information
gorhill committed Dec 4, 2016
1 parent 019d2ce commit b2a10e3
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -360,15 +360,15 @@
"description": "Second part of 'Clear browser cache every [n] minutes'"
},
"privacyClearCacheHelp" : {
"message": "<p>Some web sites are really bent on tracking you, so much that they will use not-so-nice tricks to work around whatever measures you take in order to not be tracked.</p><p>A few of these tricks rely<sup style='font-size:smaller'>[1, 2]</sup> on the <a href='https://en.wikipedia.org/wiki/Web_cache'>browser cache</a>, which content is often long lasting since rarely will users take the time to regularly clear their browser cache.</p><p>There is little inconvenience to clear the browser cache regularly (likelihood is that you won't notice when it happens), and the benefit is to prevent these obnoxious trackers from invading your privacy.</p><p>Check this option to have <i>uMatrix</i> do it for you, at the interval you wish.</p><p style='font-size:smaller'>[1] <a href='https://grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache'>&ldquo;Preventing Web Tracking via the Browser Cache&rdquo;</a><br>[2] <a href='http://lucb1e.com/rp/cookielesscookies/'>&ldquo;Cookieless cookies&rdquo;</a></p>",
"message": "<p>Some web sites are really bent on tracking you, so much that they will use not-so-nice tricks to work around whatever measures you take in order to not be tracked.</p><p>A few of these tricks rely<sup>[1, 2]</sup> on the <a href='https://en.wikipedia.org/wiki/Web_cache'>browser cache</a>, which content is often long lasting since rarely will users take the time to regularly clear their browser cache.</p><p>There is little inconvenience to clear the browser cache regularly (likelihood is that you won't notice when it happens), and the benefit is to prevent these obnoxious trackers from invading your privacy.</p><p>Check this option to have <i>uMatrix</i> do it for you, at the interval you wish.</p><p>[1] <a href='https://grepular.com/Preventing_Web_Tracking_via_the_Browser_Cache'>&ldquo;Preventing Web Tracking via the Browser Cache&rdquo;</a>\n[2] <a href='http://lucb1e.com/rp/cookielesscookies/'>&ldquo;Cookieless cookies&rdquo;</a></p>",
"description": ""
},
"privacyProcessRefererPrompt" : {
"message": "Spoof <a href='https://en.wikipedia.org/wiki/HTTP_referer'>HTTP referrer</a> string of third-party requests.",
"description": ""
},
"privacyProcessRefererHelp" : {
"message": "<p>From Wikipedia:</p><blockquote>HTTP referer is an HTTP header field that identifies the address of the webpage that linked to the resource being requested. ... <b>Because referer information can violate privacy, some web browsers allow the user to disable the sending of referer information.</b></blockquote><p>If this setting is checked, <i>uMatrix</i> will spoof the HTTP referrer information if the domain name of the HTTP referrer is third-party to the domain name of net request.",
"message": "From Wikipedia:<blockquote>HTTP referer is an HTTP header field that identifies the address of the webpage that linked to the resource being requested. ... <b>Because referer information can violate privacy, some web browsers allow the user to disable the sending of referer information.</b></blockquote>If this setting is checked, <i>uMatrix</i> will spoof the HTTP referrer information if the domain name of the HTTP referrer is third-party to the domain name of net request.",
"description": ""
},
"privacyNoMixedContentPrompt" : {
Expand Down
9 changes: 5 additions & 4 deletions src/css/dashboard-common.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ button {
opacity: 1.0;
}
.whatisthis-expandable {
background-color: #F8F8F8;
border: 1px dotted #aaa;
display: none;
font-size: smaller;
margin: 0.5em 0 1em 1.25em;
padding: 0.5em;
font-size: smaller;
display: none;
border: 1px dotted #aaa;
background-color: #F8F8F8;
white-space: pre-line;
}
.whatisthis-expandable > p {
margin-top: 1em;
Expand Down
120 changes: 117 additions & 3 deletions src/js/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,125 @@

/******************************************************************************/

// https://github.com/gorhill/uBlock/issues/2084
// Anything else than <a>, <b>, <code>, <em>, <i>, <input>, and <span> will
// be rendered as plain text.
// For <input>, only the type attribute is allowed.
// For <a>, only href attribute must be present, and it MUST starts with
// `https://`, and includes no single- or double-quotes.
// No HTML entities are allowed, there is code to handle existing HTML
// entities already present in translation files until they are all gone.

var reSafeTags = /^([\s\S]*?)<(b|blockquote|code|em|i|span|sup)>(.+?)<\/\2>([\s\S]*)$/,
reSafeInput = /^([\s\S]*?)<(input type="[^"]+")>(.*?)([\s\S]*)$/,
reInput = /^input type=(['"])([a-z]+)\1$/,
reSafeLink = /^([\s\S]*?)<(a href=['"]https?:\/\/[^'" <>]+['"])>(.+?)<\/a>([\s\S]*)$/,
reLink = /^a href=(['"])(https?:\/\/[^'"]+)\1$/;

var safeTextToTagNode = function(text) {
var matches, node;
if ( text.lastIndexOf('a ', 0) === 0 ) {
matches = reLink.exec(text);
if ( matches === null ) { return null; }
node = document.createElement('a');
node.setAttribute('href', matches[2]);
return node;
}
if ( text.lastIndexOf('input ', 0) === 0 ) {
matches = reInput.exec(text);
if ( matches === null ) { return null; }
node = document.createElement('input');
node.setAttribute('type', matches[2]);
return node;
}
// Firefox extension validator warns if using a variable as argument for
// document.createElement().
switch ( text ) {
case 'b':
return document.createElement('b');
case 'blockquote':
return document.createElement('blockquote');
case 'code':
return document.createElement('code');
case 'em':
return document.createElement('em');
case 'i':
return document.createElement('i');
case 'span':
return document.createElement('span');
case 'sup':
return document.createElement('sup');
default:
break;
}
};

var safeTextToTextNode = function(text) {
// TODO: remove once no more HTML entities in translation files.
if ( text.indexOf('&') !== -1 ) {
text = text.replace(/&ldquo;/g, '“')
.replace(/&rdquo;/g, '”')
.replace(/&lsquo;/g, '‘')
.replace(/&rsquo;/g, '’');
}
return document.createTextNode(text);
};

var safeTextToDOM = function(text, parent) {
if ( text === '' ) { return; }
// Fast path (most common).
if ( text.indexOf('<') === -1 ) {
return parent.appendChild(safeTextToTextNode(text));
}
// Slow path.
// `<p>` no longer allowed. Code below can be remove once all <p>'s are
// gone from translation files.
text = text.replace(/^<p>|<\/p>/g, '')
.replace(/<p>/g, '\n\n');
// Parse allowed HTML tags.
var matches,
matches1 = reSafeTags.exec(text),
matches2 = reSafeLink.exec(text);
if ( matches1 !== null && matches2 !== null ) {
matches = matches1.index < matches2.index ? matches1 : matches2;
} else if ( matches1 !== null ) {
matches = matches1;
} else if ( matches2 !== null ) {
matches = matches2;
} else {
matches = reSafeInput.exec(text);
}
if ( matches === null ) {
parent.appendChild(safeTextToTextNode(text));
return;
}
safeTextToDOM(matches[1], parent);
var node = safeTextToTagNode(matches[2]) || parent;
safeTextToDOM(matches[3], node);
parent.appendChild(node);
safeTextToDOM(matches[4], parent);
};

/******************************************************************************/

// Helper to deal with the i18n'ing of HTML files.
vAPI.i18n.render = function(context) {
uDom('[data-i18n]', context).forEach(function(elem) {
elem.html(vAPI.i18n(elem.attr('data-i18n')));
});
var docu = document,
root = context || docu,
elems, n, i, elem, text;

elems = root.querySelectorAll('[data-i18n]');
n = elems.length;
for ( i = 0; i < n; i++ ) {
elem = elems[i];
text = vAPI.i18n(elem.getAttribute('data-i18n'));
if ( !text ) { continue; }
// TODO: remove once it's all replaced with <input type="...">
if ( text.indexOf('{') !== -1 ) {
text = text.replace(/\{\{input:([^}]+)\}\}/g, '<input type="$1">');
}
safeTextToDOM(text, elem);
}

uDom('[title]', context).forEach(function(elem) {
var title = vAPI.i18n(elem.attr('title'));
Expand Down

0 comments on commit b2a10e3

Please sign in to comment.