isColor()?

D

David Birnbaum

Dear comp.lang.javascript,

I need to allow users to enter a color as free text (not by choosing
from a list) and I'd like to allow any color that will be recognized
by the user's browser. This means that users may (inadvertently or
perversely) enter invalid colors (e.g., "green" is okay but
"greenpeace" isn't). Javascript engines seem to know whether a color
is invalid; they can generate some sort of error, instead of just
applying the color and having it fail silently. Firefox (at least)
knows when it's been fed a non-color because it generates an error in
the error console:

Warning: Expected color but found 'koala'. Error in parsing value
for 'color'. Declaration dropped.).

Can I get access to information about whether a color is legit in my
javascript program? I tried:

if (element.style.color = 'koala') { alert('Nope');}

but running the test generates the error, instead of trapping it.

Is there a standard way to verify that the user has entered a color
name (or other notation) that will be recognized as a color by the
javascript engine in the browser? Something like an isColor() test
that would let me check whether the user input will be recognized as a
color before otherwise using it? I can write a function that will do
this, but I can't think of how to do that without hard-wiring a list
of recognized color names, and the recognized names might 1) vary
across browsers and 2) change over time, which means that I might have
to be more pessimistic than an individual user's individual browser
might require. Advice welcome!

Thanks,

David
(e-mail address removed)
 
D

David Birnbaum

Dear comp.lang.javascript,

I forgot to mention: try ... catch doesn't work either. It will catch
an error when I try to set the color of a nonexistent object, but it
won't catch the error when I try to assign a nonexistent color to a
legitimate object.

Thanks,

David
(e-mail address removed)
 
R

rf

David Birnbaum said:
Dear comp.lang.javascript,

I need to allow users to enter a color as free text (not by choosing
from a list) and I'd like to allow any color that will be recognized
by the user's browser.

Then why not keep a list of the colours recognized by the users browser and
validate against this?

The specification lists 16 of them:
http://www.w3.org/TR/html401/types.html#h-6.5

W3Schools (if you can believe them) lists a few more:
http://www.w3schools.com/html/html_colornames.asp
 
D

David Birnbaum

Then why not keep a list of the colours recognized by the users browser and
validate against this?

I mentioned this as a possible solution in my original posting, but I
find it unappealing for two reasons:

1) different browsers may differ in the values they accept, and

2) browsers that recognize only certain values today might recognize
additional ones tomorrow.

Validating against a precompiled list of colors means picking a spot
along the continuum between limiting myself to a safe subset
(restricting choice more than may be necessary) or risking an
untrapped error. I'll fall back on validation against a precompiled
list if necessary, but if the javascript engine knows when it's been
fed an invalid value, I'd prefer to find a way to make it tell me
that.

I've experimented with window.onerror, which has inconsistent results
across browsers (testing limited to Windows 7 for the moment). IE 8
reports an error that I could probably trap and handle, but Firefox
doesn't (the JavaScript console reports a warning, and window.onerror
doesn't trap warnings). Chrome, Opera, and Safari all don't seem to
report anything at all.

Best,

David
(e-mail address removed)
 
R

RobG

Dear comp.lang.javascript,

I need to allow users to enter a color as free text (not by choosing
from a list) and I'd like to allow any color that will be recognized
by the user's browser.

Letting users make up their own colour names and guessing whether it's
one that their browser may or may not recognise sounds like a very
frustrating interface.

Surely it's better to provide some kind of colour picker to give them
some help?

I'm sure most would like to see examples when trying to choose between
corn silk, blanched almond and bisque. Picking contrasts and blends
will be simpler too.

This means that users may (inadvertently or
perversely) enter invalid colors (e.g., "green" is okay but
"greenpeace" isn't). Javascript engines seem to know whether a color
is invalid; they can generate some sort of error, instead of just
applying the color and having it fail silently. Firefox (at least)
knows when it's been fed a non-color because it generates an error in
the error console:

Warning: Expected color but found 'koala'. Error in parsing value
for 'color'. Declaration dropped.).

Can I get access to information about whether a color is legit in my
javascript program? I tried:

if (element.style.color = 'koala') { alert('Nope');}

but running the test generates the error, instead of trapping it.

Is there a standard way to verify that the user has entered a color
name (or other notation) that will be recognized as a color by the
javascript engine in the browser?

That seems like an awful lot of bother and means that users are
limited by their browsers (if it can be made to work at all).

As an alternative, create a table of allowable colours and map them to
hex values. When a user types a colour name, look it up and give the
browser the equivalent hex number.

e.g. if the user enters "turquoise", you map it to #40E0D0.

Here's a list of names and values to get start (the camel case names
should be made two words, so LawnGreen becomes lawn green, and the
match should be case insensitive):

<URL: http://en.wikipedia.org/wiki/Web_colors >
 
L

Lasse Reichstein Nielsen

David Birnbaum said:
I mentioned this as a possible solution in my original posting, but I
find it unappealing for two reasons:

1) different browsers may differ in the values they accept, and

There is a base set that they must support (I'd go for the CSS 2.1
set, now with orange). I would have no problem restricting input
to that set. It makes the user's expectations consistent.
2) browsers that recognize only certain values today might recognize
additional ones tomorrow.
Validating against a precompiled list of colors means picking a spot
along the continuum between limiting myself to a safe subset
(restricting choice more than may be necessary) or risking an
untrapped error. I'll fall back on validation against a precompiled
list if necessary, but if the javascript engine knows when it's been
fed an invalid value, I'd prefer to find a way to make it tell me
that.

Then you need to check that the color is recognized.

You can use something like this:

function isValidColor(userInput) {
var current =
document.defaultView && document.defaultView.getComputedStyle ?
function(f) { return document.defaultView.getComputedStyle(f,""); } :
function(f) { return f.currentStyle; };
try {
if (userInput == "transparent") return true;
var elem = document.getElementById("someId");
elem.style.backgroundColor = "transparent";
var before = current(elem,"").backgroundColor;
elem.style.backgroundColor = userInput;
var after = current(elem,"").backgroundColor;
return before != after;
} catch (e) {
// IE ends here, which is great since IE < 9 doesn't support
// defaultView.getComputedStyle.
return false;
}
}

(tested, quickly, in IE 9, IE 8, Firefox, Opera and Chrome).

Best of luck.
/L
 
R

rf

David Birnbaum said:
I mentioned this as a possible solution in my original posting, but I
find it unappealing for two reasons:

I didn't read that far.

Two questions:

1) Why do you need to do this?

2) Is your user going to pick any of the strange colour names mentioned at
W3Schools even though their browser might accept them? I mean, why would a
user pick "AntiqueWhite" or "GhostWhite" or "NavajoWhite? or
"BlanchedAlmond". "DogerBlue"? "PaleGoldenRod"? "LightGoldenRodYellow"?
"Peru", that's a country, isn't it?

No, I think your user might pick something like "Red" or "Blue". But then
again they could pick "GhostGrey". What's wrong with that, it's just a tad
darker then "GhostWhite". Or "NavajoRed". Those blokes *are* red aren't
they? :)

Are you solving the wrong problem? Perhaps you should present them with a
colour picker.
 
R

Ry Nohryb

(...)
Is there a standard way to verify that the user has entered a color
name (or other notation) that will be recognized as a color by the
javascript engine in the browser? Something like an isColor() test
that would let me check whether the user input will be recognized as a
color before otherwise using it? I can write a function that will do
this, but I can't think of how to do that without hard-wiring a list
of recognized color names, and the recognized names might 1) vary
across browsers and 2) change over time, which means that I might have
to be more pessimistic than an individual user's individual browser
might require. Advice welcome!

I think that you can just set the color of an element and see if it
sticks. If it does it was a valid color. Like this:

function isColor (color) {
var dumyElement=
document.body.appendChild(document.createElement("span"));
dumyElement.style.color= color;
var isColor= dumyElement.style.color;
dumyElement.parentNode.removeChild(dumyElement);
return isColor;
}

Test page here: http://jorgechamorro.com/cljs/103/
 
R

Ry Nohryb

function isColor (color) {
  var dumyElement=
document.body.appendChild(document.createElement("span"));
  dumyElement.style.color= color;
  var isColor= dumyElement.style.color;
  dumyElement.parentNode.removeChild(dumyElement);
  return isColor;

}

s/dumy/dummy/g
 
D

David Birnbaum

Dear comp.lang.javasscript,

Thanks very much to Jorge and others who provided simple, effective
working solutions.

Best,

David
(e-mail address removed)
 
G

Garrett Smith

news:5b726d47-6059-40bc-a176-c9308c349fa4@l20g2000yqm.googlegroups.com... [...]
2) Is your user going to pick any of the strange colour names mentioned at
W3Schools even though their browser might accept them? I mean, why would a
user pick "AntiqueWhite" or "GhostWhite" or "NavajoWhite? or
"BlanchedAlmond". "DogerBlue"? "PaleGoldenRod"? "LightGoldenRodYellow"?
"Peru", that's a country, isn't it?
Depends on the user. Me, I always liked lawngreen and papayawhip.
 
G

Garrett Smith

news:5b726d47-6059-40bc-a176-c9308c349fa4@l20g2000yqm.googlegroups.com... [...]
2) Is your user going to pick any of the strange colour names
mentioned at
W3Schools even though their browser might accept them? I mean, why
would a
user pick "AntiqueWhite" or "GhostWhite" or "NavajoWhite? or
"BlanchedAlmond". "DogerBlue"? "PaleGoldenRod"? "LightGoldenRodYellow"?
"Peru", that's a country, isn't it?
Depends on the user. Me, I always liked lawngreen and papayawhip.
Forgot to mention cornflowerblue.
 
G

Garrett Smith

That is a boolean-looking method name that is required to throw an error
if the color name is not a valid value and that error is only correctly
thrown in IE.

The result of calling that method in other browsers has been observed to
be a string value.

That same effect could have probably been achieved sans appending (which
would be a lot less inefficient).

var s = document.createElement("div").style;
s.color = v;

Setting `color` to an invalid value can be expected to result in
DOM_EXCEPTION being raised and that happens in IE.

http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties-color

| color of type DOMString
| See the /_color property definition_/ in CSS2.
| Exceptions on setting
|
| DOMException
|
| SYNTAX_ERR: Raised if the new value has a syntax error and is
| unparsable.
|
| NO_MODIFICATION_ALLOWED_ERR: Raised if this property is readonly.

"color property definition" links to:
http://www.w3.org/TR/1998/REC-CSS2-19980512/colors.html#propdef-color

Which describes:
http://www.w3.org/TR/1998/REC-CSS2-19980512/syndata.html#value-def-color

Which states:
| A <color> is either a keyword or a numerical RGB specification.

Which describes the 16 color names:
http://www.w3.org/TR/html4/types.html#h-6.5

Browsers are known to support X11 colors and so you could try the list
here for that:
<http://www.w3.org/TR/css3-color/#svg-color>.
 
G

Garrett Smith

Dear comp.lang.javasscript,

Thanks very much to Jorge and others who provided simple, effective
working solutions.
Jorge's code is broken. Please see my reply.
 
R

Ry Nohryb

On 2010-08-16 07:03 AM, David Birnbaum wrote:> Dear comp.lang.javasscript,


Jorge's code is broken.

In Microsoft's Internet Explorers... what's not broken in that piece
of crap ?
Please see my reply.

Talk is cheap. Show me the code.
 
G

Garrett Smith

In Microsoft's Internet Explorers... what's not broken in that piece
of crap ?
MSIE was actually the only browser to correctly execute your test code.

Your test page* states: "Tested in Safari, Opera, Chrome and FireFox,
not tested in any IEs"

However, you now say that it is broken in MSIEs. It seems you have found
your code threw an error in IE.

When looking at the code, I knew that it would throw an error in IE,
just like you said it would. I've investigated this matter before and
explained this error before. I've covered MSIE "invalid value" two times
recently. My most recent recollection is in the Sencha Touch thread.

When I read the "not tested in IEs" on your test page, I suspected that
you had perhaps created an error condition for IE out of your contempt
for that browser and that you had not read the specs and had not read
the other comment I had posted on the "Sencha Touch" thread, which, to
my recollection, you had replied to.

* said:
Talk is cheap. Show me the code.
Please do see my previous reply to you. That reply explains why the
result in MSIE is correct and how the browsers you tested violate the
standard by not throwing or "raising" a DOM_EXCEPTION.

Always, before declaring a bug, read the pertinent specification.

Thank you.
 
L

Lasse Reichstein Nielsen

Garrett Smith said:
That is a boolean-looking method name that is required to throw an
error if the color name is not a valid value and that error is only
correctly thrown in IE.

You are guessing.
Since it's not tested in IE, I guess it's supposed to do what it
actually does in the browsers it's tested in.

In this case, it's returning a non-falsy value (the color string
itself) if the color is valid, and a falsy value (the empty string) if
the color is not valid.

It is broken in IE because IE behaves differently (throws an exception
if the value isn't valid, as you also write).

That could be fixed by wrapping the code in
try {
...
} catch (e) { return ""; }
The result of calling that method in other browsers has been observed
to be a string value.

That same effect could have probably been achieved sans appending
(which would be a lot less inefficient).

True. Adding the element to the document tree doesn't appear to make
any difference in any of the browsers I have.

/L
 
G

Garrett Smith

You are guessing.

No, I carefully and correctly explained what can be expected of the code.
Since it's not tested in IE, I guess it's supposed to do what it
actually does in the browsers it's tested in.

What it is *required* to do, by the DOM 2 Style standard that I
referenced, is to throw an error.

What the author was expecting was probably that it would not throw an error.
In this case, it's returning a non-falsy value (the color string
itself) if the color is valid, and a falsy value (the empty string) if
the color is not valid.

You're following right into Jorge's faulty thinking.
It is broken in IE because IE behaves differently (throws an exception
if the value isn't valid, as you also write).

No, it is not "broken in IE because IE behaves differently." The
function is broken by design. I see you've fallen into the trap of the
misthinking that since IE is different, it must be wrong.

I carefully referenced DOM 2 Style specification and a couple of other
specs. You snipped that. Please do read that

I suggest reading reading my explanation carefully. After doing this,
please follow up on this thread to acknowledge that the answer I have
provided is correct. Otherwise, others may believe that you are correct
here (you're not).

Thank you.
That could be fixed by wrapping the code in
try {
...
} catch (e) { return ""; }
Doing that would hide any exception and, as stated in the specification,
an exception required to be thrown.

An error is required to be thrown if the value has a syntax error and is
unparsable.

I very carefully explained all of that in the message. You've not
acknowledged that and snipped what was written without comment.
True. Adding the element to the document tree doesn't appear to make
any difference in any of the browsers I have.

Right. Regardless, the approach itself is broken as stated for reasons
that I stated in my previous message and I fail to see what was wrong
with that explanation. Please do (re)read and acknowledge. TIA.
 
R

Ry Nohryb

(...)
It is broken in IE because IE behaves differently (throws an exception
if the value isn't valid, as you also write).

That could be fixed by wrapping the code in
 try {
  ...
 } catch (e) { return ""; }

[x] FIXED.
True. Adding the element to the document tree doesn't appear to make
any difference in any of the browsers I have.

[x] FIXED.

function isColor (color) {
var dummyElement= document.createElement("span");
try { //IEs throw for non valid colours... LOL
dummyElement.style.color= color;
} catch (e) { }
return dummyElement.style.color;
}

http://jorgechamorro.com/cljs/103/

KTHX !
 
G

Garrett Smith

On Aug 17, 8:00 am, Lasse Reichstein Nielsen<[email protected]>
wrote: [...]
function isColor (color) {
var dummyElement= document.createElement("span");
try { //IEs throw for non valid colours... LOL

And yet again, as I carefully explained (please read it), for any
"unparsable" color, an error should be expected, as per DOM 2 Style.

I'm getting the broken record feeling again. Is the specification that
unpleasant to read? How, if at all, was the explanation I provided, not
clear? Or what??

dummyElement.style.color= color;
} catch (e) { }
return dummyElement.style.color;
}
Now it returns either a string value or undefined.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top