I would test typeof(el.innerHTML) != 'string'.
Makes sense. If someone ever tries to subvert my function with
something like the following, it will fail silently.
{ innerHTML : "foo" }
I think I can live w/that.
Why not do an initial feature test that sets outerHTML for an element
and then tests innerHTML for the \n character?
I think you meant to say: Do an initial feature test by setting the
element's innerHTML and then checking the outerHTML for "\n" ?
If that's what you meant, that seems like the right way to do it.
The idea you're proposing sounds to be the most correct one:
if set innerHTML with \n results in the browser not displaying \n as a
line break, use the outerHTML regexp hack. Is that Right?
Would require a good bit of testing. Safari 2 has some whitespace
issues on textContent (Problem: to preseve whitespace, use a PRE tag
that is visible). I haven't found any problems with innerHTML yet. So
far, it's just IE.
better test than checking clipboardData, then assuming IE, then
assuming all versions of IE have this problem (and all others don't.)
You're absolutely right. I'm not going down the clipboardData road
anymore.
Furthermore, don't bother doing this if there are no \n characters in
the passed string.
Good point, so:
if( isIE && /\n/.test(s) )
Considering what this clause does, you want it to
be invoked as little as possible.
Why should this be invoked as little as possible?
alert(window.clipboardData && (typeof(window.clipboardData.getData) ==
'object' || typeof(window.clipboardData.getData) == 'unknown'));
The "unknown" test is included in case IE changes clipboardData in the
future to behave like other COM objects (or if they behaved like them
in the past.)
javascript:alert(typeof(window.clipboardData.getData))
"object" in ie7.
For now, I'm just using a conditional comment browser check. I may
revisit this with a more correct approach.
String.nl = /*@cc_on!@*/false ? "\r\n" : "\n";
I put a similar check in the setOuterHTML function, too.
It's in closed scope, so no need to worry about the isIE variable;
it's hidden:
======================================================================
/** This method will work with PRE but not TD elements
*/
var isIE = /*@cc_on!@*/false;
function setInnerHTML( el, s ) {
if(typeof el["innerHTML"] != "string" ) {
throw new TypeError("setInnerHTML: first argument does not
support innerHTML. Is it an element?");
}
var outerHTML = el.outerHTML;
if( isIE && /\n/.test(s) ) {
var innerHTML = new RegExp(">([^<]*)<");
var oldContent = outerHTML.match(innerHTML)[1];
el.outerHTML = outerHTML.replace( oldContent, s );
}
else {
el.innerHTML = s;
}
}
======================================================================
Thanks,
Garrett