| Index: include.postload.js |
| =================================================================== |
| --- a/include.postload.js |
| +++ b/include.postload.js |
| @@ -24,9 +24,28 @@ |
| var clickHideFiltersDialog = null; |
| var lastRightClickEvent = null; |
| +function escapeChar(chr, pos, s) { |
| + var code = chr.charCodeAt(0); |
| + |
| + // non-ascii, needs no escaping |
| + if (code >= 128) |
|
Sebastian Noack
2014/11/05 18:09:04
I just realized that I can easily check in the reg
|
| + return chr; |
| + |
| + // control characters and numbers, must be escaped based on their code point |
| + if ((code >= 0 && code <= 31) || (code >= 48 && code <= 57) || code == 127) |
|
Wladimir Palant
2014/11/05 15:14:41
How about:
if (code <= 0x1F || /\d/.test(chr) |
Sebastian Noack
2014/11/05 18:09:04
I already considered using that regex to check for
|
| + return "\\" + code.toString(16) + (pos + 1 < s.length ? " " : ""); |
|
Wladimir Palant
2014/11/05 15:14:41
Why create a special case for end of string? That
Sebastian Noack
2014/11/05 18:09:04
I find the extra space in the end confusing. It ca
|
| + |
| + // others, can be escaped by prepending a backslash |
| + return "\\" + chr; |
| +} |
| + |
| function quote(value) |
| { |
| - return '"' + value.replace(/(["\\])/g, "\\$1") + '"'; |
| + return '"' + value.replace(/["\\\r\n\f\0]/g, escapeChar) + '"'; |
|
Wladimir Palant
2014/11/05 15:14:41
How about generally escaping all non-printable cha
Sebastian Noack
2014/11/05 18:09:04
Yeah, un-escaped control characters make quoted st
|
| +} |
| + |
| +function escapeToken(s) { |
| + return s.replace(/^\d|^-(?![^\d-])|[^\w-]/g, escapeChar); |
|
Wladimir Palant
2014/11/05 15:14:41
How about always escaping leading dashes? These ar
Sebastian Noack
2014/11/05 18:09:04
I'd prefer to keep the logic for escaping dashes.
Wladimir Palant
2014/11/05 19:56:52
I'll leave the decision on whether that branch in
|
| } |
| function supportsShadowRoot(element) |
| @@ -376,10 +395,6 @@ |
| else if (elt.src) |
| url = elt.src; |
| - // Construct filters. The popup will retrieve these. |
| - // Only one ID |
| - var elementId = elt.id ? elt.id.split(' ').join('') : null; |
| - |
| clickHideFilters = new Array(); |
| selectorList = new Array(); |
| @@ -389,15 +404,15 @@ |
| selectorList.push(selector); |
| }; |
| - if (elementId) |
| - addSelector("#" + elementId); |
| + if (elt.id) |
| + addSelector("#" + escapeToken(elt.id)); |
| if (elt.classList.length > 0) |
| { |
| var selector = ""; |
| for (var i = 0; i < elt.classList.length; i++) |
| - selector += "." + elt.classList[i].replace(/([^\w-])/g, "\\$1"); |
| + selector += "." + escapeToken(elt.classList[i]); |
| addSelector(selector); |
| } |
| @@ -405,7 +420,7 @@ |
| if (url) |
| { |
| var src = elt.getAttribute("src"); |
| - var selector = src && elt.localName + '[src=' + quote(src) + ']'; |
| + var selector = src && escapeToken(elt.localName) + '[src=' + quote(src) + ']'; |
| if (/^https?:/i.test(url)) |
| { |
| @@ -427,7 +442,7 @@ |
| { |
| var style = elt.getAttribute("style"); |
| if (style) |
| - addSelector(elt.localName + '[style=' + quote(style) + ']'); |
| + addSelector(escapeToken(elt.localName) + '[style=' + quote(style) + ']'); |
| } |
| // Show popup |