This code behaves funny on Chrome (fiddle here):
try {
open('6:-=');
} catch(e) {}
First, despite the code being wrapped in a try-catch, an error is thrown:
Unable to open a window with invalid URL '%36:%04-='.
Second, extraneous characters are inserted in the URL, namely %3 and %04.
Why doesn't the try-catch intercept the error, and why does the URL have those extra characters?
The try/catch doesn't have any effect because it's not an exception. It's merely an error message printed to the console. You can proof that:
open('6:-=');
console.log(1); // logged as usual
Basically, it's just like console.error() doesn't throw an exception either, yet it prints an exception-like message to the console.
Your fiddle contains a non-printable character with ASCII code 4 in the 6:-= string after the colon, which is URL-encoded as %04 in the displayed error. In addition, the 6: part of the provided URL is interpreted as an URL scheme, which cannot start with a digit, so apparently Chrome URL-quotes the 6 as %36 as well, although such behavior is not prescribed by the RFC.
First: As pimvdb said, it's because it isn't actually an exception.
Second: %04 is an invisible character inserted by JSFiddle. %36 is the number 6 which Chrome converts to %36 when encoding it for URL scheme. Updated fiddle without %04
Related
Recently I wrote a simple javascript code, but got a very weird behavior in Firefox and Chrome, code lists bellow:
console.log(
"sap.ui.widget.Progressbar"
.replace(/\./g, '/')
.replace("", "./resources/css/")
);
In Chrome (version 69.0.3497.100) I got expected result: "./resources/css/sap/ui/widget/Progressbar", but in Firefox (version 63.0) I get a totally different result: "sap/ui/widget/Progressbar".
Can some explain this? Is it a bug for Firefox? Thanks.
Yes, this is a bug in Spidermonkey. It has been reported and will be fixed in FF 65 if all goes well. (The bug does not occur on any other Javascript engine)
The problem is that intermediate strings (such as those resulting from calling String.prototype.replace on a string literal) more than 24 characters long are represented in Spidermonkey as ropes, while those 23 or fewer characters long are not ropes. Spidermonkey did not properly replace ropes when called with replace(''. (see function BuildFlatRopeReplacement in js/src/builtin/String.cpp)
You can reproduce the problem by calling .replace and replacing at least one character in a 24+ character string, and then calling .replace again with the empty string:
// Run on FF 64 or lower to reproduce:
// Second replacement at the beginning of the string fails:
console.log(
"a".repeat(24).replace('a', 'b').replace("", "foo")
);
// Works as expected:
console.log(
"a".repeat(23).replace('a', 'b').replace("", "foo")
);
I've run into an issue of regex match not evaluating in Internet Explorer and in Firefox. It works fine in Chrome and Opera. I know Chrome is generally much more tolerant of mistakes so I suspect I've dropped the ball somewhere along the way - yet none of the online evaluation tools seem to find any errors in my expression. I'm sorry that it's such a convoluted expression but hopefully something will be easily obvious as the culprit. The expression is as follows:
keyData = data.match(/\w+\u0009\w+\u0009[\u0009]?\w+\u0009([-]?\w+|%%)[#]?\u0009([-]?\w+|%%)[#]?\u0009([-]?\w+|%%)[#]?(\u0009([-]?\w+|%%)[#]?)?(\u0009([-]?\w+|%%)[#]?)?(\u0009([-]?\w+|%%)[#]?)?\u0009\u0009\/\//g);
'data' is a text file which I am parsing with no errors. I wont post the whole file here but what I am hoping to match is something such as the following:
10 Q 1 0439 0419 -1 // CYRILLIC SMALL LETTER SHORT I, CYRILLIC CAPITAL LETTER SHORT I, <none>
I believe that when I post the string here it removes the 'u0009' characters so if you'd like to see one of the full files, I've linked one here. If there is anything more I can clarify, please let me know!
Edit:
My goal in this post is understanding not only why this is failing, but also if this expression well-formatted. After further review, it seems that it's an issue with how Internet Explorer and Firefox parse the text file. They seem to strip out the tabs and replace them with spaces. I tried to update the expression and it matches with no problems in an online validator but it still fails in IE/FF.
Edit 2
I have since updated my expression to a clearer form taking into account feedback. The issue still is persisting in IE and Firefox. It seems to be an issue with the string itself. IE won't let me match more than a single character, no matter what my expression is. For example, if the character string of the file is KEYBOARD and I try to match with /\w+/, it will just return K.
/[0-9](\w)?(\t+|\s+)\w+(\t+|\s+)[0-9](\t+|\s+)(-1|\w+#?|%%)(\t+|\s+)(-1|\w+#?|%%)(\t+|\s+)(-1|\w+#?|%%)((\t+|\s+)(-1|\w+#?|%%))?((\t+|\s+)(-1|\w+#?|%%))?((\t+|\s+)(-1|\w+#?|%%))?(\t+|\s+)\/\//g
After poking around with my regex for a while, I suspected something was wrong with the way IE was actually reading the text file as compared to Chrome. Specifically, if I had the string KEYBOARDwithin the text file and I tried to match it using /\w+/, it would simply return K in IE but in Chrome it would match the whole string KEYBOARD. I suspected IE was inserting some dead space between characters so I stepped through the first few characters of the file and printed their unicode equivalent.
for (i = 0; i < 30; i++) {
console.log(data.charCodeAt(i) + ' ' + data[i]);
}
This confirmed my suspicion and I saw u0000 pop up between each character. I'm not sure why there are NULL characters between each character but to resolve my issue I simply performed:
data = data.replace(/\u0000+/g, '');
This completely resolved my issue and I was able to parse my string like normal using the expression:
keyData = data.match(/[0-9](\w)?(\t+|\s+)\w+(\t+|\s+)[0-9](\t+|\s+)(-1|\w+#?|%%)(\t+|\s+)(-1|\w+#?|%%)(\t+|\s+)(-1|\w+#?|%%)((\t+|\s+)(-1|\w+#?|%%))?((\t+|\s+)(-1|\w+#?|%%))?((\t+|\s+)(-1|\w+#?|%%))?(\t+|\s+)\/\//g);
I wanted to understand what carriage return is by writint a simple code to console.As carriage return '\r' means
" return to the beginning of the current line without advancing
downward"
But in my code the following string is appended at the end of the line .Why it is behaving like this.I have a string "this is my string" ,then i have carriage return ,and it is followed by another string "that".I thought "that" will be placed at the beginning of the string
console.log("this is my string"+String.fromCharCode(13)+"that");
it prints "this is my stringthat"
Using \r in a string in JavaScript is probably going to give you different results depending on a combination of how the program is being run (in a browser or a standalone engine) and the target of the text (console, alert, a text node in an HTML element etc). It's not clear from your question whether you're running JavaScript in a browser, but (assuming you are) you're going to get different results for different browsers. Internet Explorer's console treats \r as a newline character (\n) while most other browsers will ignore it. I doubt any browser implementation of console is going to give you the behavior you've described.
Note that \r is not a string processing instruction, it's a character. Doing this:
var aString="one\r2";
is never going to result in
aString == "2ne"
or
aString == "2one"
or
aString == "one2"
or anything similar evaluating to true. aString's value will remain "one\r2" until you change it. It's up to the console or alert that is displaying the string to choose how to render \r.
There are string processing methods in JavaScript for splitting and recombining strings (see the w3schools Javascript String Reference or Mozilla's String reference) that would better suit your purposes. If you start using characters like \r or \b in other languages and/or environments you're going to encounter different behaviors based on a whole host of factors.
Note that I ONLY get this error when onclick is called on an item that contains string with multiple lines, so I narrowed it down to this probably having something to do with new line characters. I am stuck as to how to fix this problem.
All information is loaded from my database. Here is an example of text that is loaded from database that is giving me this error because it has multiple lines (refer to longDescription field):
Here is how my source looks like near the error (note that the longDescription text starts right above line 264):
Here is the error message in console:
Here is the function:
Here is where it is being called:
Once again note that is works when there is no apparent new lines in the strings. Please help.
I used the following statement to properly deal with the new line characters. Don't be fooled by php's function nl2br() because it only inserts <br/> in front of new line characters, it does NOT replace new line characters.
$longDescription = preg_replace("/\r\n|\r|\n/",'<br/>',$longDescription);
so this is an xPath expression which runs fine in a Firefox userscript but fails in a (native) chrome userscript:
var nodesSnapshot = document.evaluate("//a[#class='inline-object' and .[contains(#href,'test.com')] ]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
//just the string:
"//a[#class='inline-object' and .[contains(#href,'test.com')] ]"
The error message:
Uncaught SyntaxError: An invalid or illegal string was specified.
I've tried several things (e.g. extra brackets), googling and searching on stackoverflow without success. I also tried:
"//a[#class='inline-object action-card' and .[#href = 'test.com']]"
which also did not work. Is there someone who can explain this and correct the code?
Thanks in advance
Edit: More important information: The problem seems to be the 'current node' (the dot) in the 'and statement'.
2nd Edit: Here's a test-node:
text of the testnode
XPath expressions like .[true()] are actually illegal (at least in XPath 1.0). Predicates are only allowed
in location steps after a NodeTest but not after an AbbreviatedStep like .
after a FilterExpr or PrimaryExpr but not after any other expression
You should simply follow #Ross Patterson's suggestion and write //a[#class='inline-object' and contains(#href,'test.com')]. Or, alternatively but more convoluted:
self::node()[contains(#href,'test.com')] or
self::*[contains(#href,'test.com')] or
(.)[contains(#href,'test.com')]