Proper encoding of href for window.open() in JavaScript - javascript

What is the proper cross-browser encoding for the href when using window.open() in JavaScript? First I was using
var href = "http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1&copy=1";
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
IE8 opens: http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1©=1
FireFox opens: http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1&copy=1
var href = "http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1&copy=1";
var win = window.open(href, name, 'height=500,width=800,resizable=yes,scrollbars=yes');
IE8 opens: http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1&copy=1
FireFox opens: http://127.0.0.1:8000/etf/admin/escola/t34atividade/?pop=1&copy=1

Use the Javascript "encodeURIComponent" function for each piece of the URI that's not part of the URI syntax (that is, separator slashes, the question mark for the query string, parameter separator ampersands, etc).
URI encoding is not the same as HTML escaping. For example, you don't escape an ampersand in a URL as &.

IE8 appears to be trying to coerce the query string argument &copy=1 to the entity ©, which is the copyright symbol (©). That is actually funny. Just like Microsoft to encumber the user with "help".
Pointy is correct about encoding. Be careful also that you don't have a code minifier that removes everything on a line after a pair of double slashes (//); I've seen those wreck pages before.

The simplest solution I found was to stop using copy as a GET parameter. The problem is that &copy is actually an HTML entity for the copyright symbol. IE applies an entity replacement converting it to the symbol even though it's in JavaScript code. Apparently Firefox does not perform the entity replacement. According to a comment in this blog what IE is doing might be correct, but to avoid all the mess I just renamed my parameter to clone.
http://nedbatchelder.com/blog/200812/accidental_html_entities_in_urls.html

Related

what kind of encoding is this?

I've got some data from dbpedia using jena and since jena's output is based on xml so there are some circumstances that xml characters need to be treated differently like following :
Guns n ' Roses
I just want to know what kind of econding is this?
I want decode/encode my input based on above encode(r) with the help of javascript and send it back to a servlet.
(edited post if you remove the space between & and amp you will get the correct character since in stackoverflow I couldn't find a way to do that I decided to put like that!)
Seems to be XML entity encoding, and a numeric character reference (decimal).
A numeric character reference refers to a character by its Universal
Character Set/Unicode code point, and uses the format
You can get some info here: List of XML and HTML character entity references on Wikipedia.
Your character is number 39, being the apostrophe: ', which can also be referenced with a character entity reference: '.
To decode this using Javascript, you could use for example php.js, which has an html_entity_decode() function (note that it depends on get_html_translation_table()).
UPDATE: in reply to your edit: Basically that is the same, the only difference is that it was encoded twice (possibly by mistake). & is the ampersand: &.
This is an SGML/HTML/XML numeric character entity reference.
In this case for an apostrophe '.

Why doesn't the javascript replace global flag work in Chrome or IE, and how to I work around it?

According to the String.prototype.replace() page on MDN, I should be able to easily replace multiple patterns just by using
str.replace('what to replace', 'replace with', 'flags')
and setting the flags to 'g'.
It works perfect in Firefox 3.6. But in Chrome and IE8, it only replaces the first 'what to replace'.
I can use the
str.replace(/what to replace/gi, 'replace with')
syntax. But I'm pulling the 'what to replace' out of an array, which makes it hard to add the flags in that syntax.
Here's the code I'm trying to use. How to I modify it to work in Chrome as well as Firefox?
function generateQuestion()
{
//alert('variable length: '+variableList.length);
for(i=0;i<variableList.length;i++)
{
variable = variableList[i];
rep = replacementList[i];
flags = "gi";
questionText = questionText.replace(variable, rep, flags);
}
}
And why do I have to bother modifying it at all? Shouldn't Chrome evaluate the JavaScript as described in the link?
The very page you linked to mentions:
The use of the flags parameter in the String.replace method is non-standard. For cross-browser compatibility, use a RegExp object with corresponding flags.
Basically, it should only work on Firefox. As per the documentation, you can generate regexes dynamically using new RegExp:
var regex = new RegExp(variable, 'gi');
questionText = questionText.replace(regex, rep);
This will need variable to be escaped, however.
It appears that webkit's implementation of string.replace perhaps doesn't have the 3rd parameter, as 'foo'.replace('o','i','g') results in fio for me.
The following appears to work however:
'foo'.replace(/o/gi,'i')
Another option is:
'foo'.replace(new RegExp('o', 'gi'),'i')
From Mozilla Developer Network - JavaScript - String - replace
Non-standard
The use of the flags parameter in the String.replace method is non-standard. For cross-browser compatibility, use a RegExp object with corresponding flags.
Working in Chrome and Firefox
To get your code to work in Chrome and Firefox, you'll have to create a RegExp object (since your strings aren't hardcoded) with the appropriate flags. See Mozilla Developer Network - RegExp

IE8 window.open name - doesn't like JavaScript encoding?

I'm calling window.open() like this:
window.open('blank.html', 'New_Window\x3a_Jamie', 'width=800,height=800');
What I've done in the code is taken the window's name and JavaScript encoded it using the Microsoft Web Protection library. I'm also replacing spaces with underscores because I read that IE doesn't like spaces in window names. FYI the original string was "New Window: Jamie" and it looks like the ":" gets encoded as "\x3a". The window opens in FireFox just fine, but the window does not open in IE8. Does IE8 just not like this encoding, or the character or what? Are there rules around what characters can appear in the window name for IE8?
Are there rules around what characters can appear in the window name for IE8?
Yes. Although it doesn't seem to be documented, IE has always required that a window name be composed of alphanumerics and underscore. A colon won't be accepted, whether read from an encoded string literal or not.
If you really needed to map an arbitrary string to a unique name-safe version you'd have to do something like encoding every non-alphanumeric character into an escape sequence, eg:
function encodeToName(s) {
return s.replace(/[^A-Za-z0-9]/g, function(match) {
var c= match[0].charCodeAt(0).toString(16);
return '_'+(new Array(5-c.length).join('0'))+c;
});
}
alert(encodeToName('New Window: Jamie'));
// 'New_0020Window_003A_0020Jamie'
I agree with casablanca though, it seems very unlikely you should actually need to do this. The user is never going to get to see the window name, so w1 is just as good. It's rare enough that you need window names at all.
I think it wants the window name to be something that'd work as an identifier. Thus, "New_Window_Jamie" would probably be OK.
Do you really need a window name? From the docs:
Such string can be used to be the target of links and forms when the target attribute of an <a> element or of a <form> is specified. This string parameter should not contain any blank space.
That's about the only use of specifying a name, and though I don't see any restrictions apart from "no spaces", it would be safe to just stick to letters, digits and underscores.

How to end a regular expression with a forward slash in Javascript

Problem
I am trying to match the hash part of a URL using Javascript. The hash will have the format
/#\/(.*)\//
This is easy to achieve using "new RegExp()" method of creating a JS regular expression, but I can't figure out how to do it using the standard format, because the two forward slashes at the end begin a comment. Is there another way to write this that won't start a comment?
Example
// works
myRegexp = new RegExp ('#\/(.*)\/');
// fails
myRegexp = /#\/(.*)\//
I am trying to match the hash part of a URL using Javascript.
Yeah, don't do that. There's a perfectly good URL parser built into every browser. Set an href on a location object (window.location or a link) and you can read/write URL parts from properties hostname, pathname, search, hash etc.
var a= document.createElement('a');
a.href= 'http://www.example.com/foo#bar#bar';
alert(a.hash); // #bar#bar
If you're putting a path-like /-separated list in the hash, I'd suggest hash.split('/') to follow.
As for the regex, both versions work identically for me. The trailing // does not cause a comment. If you just want to appease some dodgy syntax highlighting, you could potentially escape the / to \x2F.
It is not starting a comment, just like two slashes in a string. Look here: http://jsfiddle.net/Gr2qb/2/

Building a Hashtag in Javascript without matching Anchor Names, BBCode or Escaped Characters

I would like to convert any instances of a hashtag in a String into a linked URL:
#hashtag -> should have "#hashtag" linked.
This is a #hashtag -> should have "#hashtag" linked.
This is a [url=http://www.mysite.com/#name]named anchor[/url] -> should not be linked.
This isn't a pretty way to use quotes -> should not be linked.
Here is my current code:
String.prototype.parseHashtag = function() {
return this.replace(/[^&][#]+[A-Za-z0-9-_]+(?!])/, function(t) {
var tag = t.replace("#","")
return t.link("http://www.mysite.com/tag/"+tag);
});
};
Currently, this appears to fix escaped characters (by excluding matches with the amperstand), handles named anchors, but it doesn't link the #hashtag if it's the first thing in the message, and it seems to grab include the 1-2 characters prior to the "#" in the link.
Halp!
How about the following:
/(^|[^&])#([A-Za-z0-9_-]+)(?![A-Za-z0-9_\]-])/g
matches the hashtags in your example. Since JavaScript doesn't support lookbehind, it tries to either match the start of the string or any character except & before the hashtag. It captures the latter so it can later be replaced. It also captures the name of the hashtag.
So, for example:
subject.replace(/(^|[^&])#([A-Za-z0-9_-]+)(?![A-Za-z0-9_\]-])/g, "$1http://www.mysite.com/tag/$2");
will transform
#hashtag
This is a #hashtag and this one #too.
This is a [url=http://www.mysite.com/#name]named anchor[/url]
This isn't a pretty way to use quotes
into
http://www.mysite.com/tag/hashtag
This is a http://www.mysite.com/tag/hashtag and this one http://www.mysite.com/tag/too.
This is a [url=http://www.mysite.com/#name]named anchor[/url]
This isn't a pretty way to use quotes
This probably isn't what t.link() (which I don't know) would have returned, but I hope it's a good starting point.
There is an open-source Ruby gem to do this sort of thing (hashtags and #usernames) called twitter-text. You might get some ideas and regexes from that, or try out this JavaScript port.
Using the JavaScript port, you'll want to just do:
var linked = TwitterText.auto_link_hashtags(text, {hashtag_url_base: "http://www.mysite.come/tag/"});
Tim, your solution was almost perfect. Here's what I ended up using:
subject.replace(/(^| )#([A-Za-z0-9_-]+)(?![A-Za-z0-9_\]-])/g, "$1#$2");
The only change is the first conditional, changed it to match the beginning of the string or a space character. (I tried \s, but that didn't work at all.)

Categories

Resources