milov.nl

Interaction design • webdevelopment • web art • photography

January 2003

New bookmarklet: !usedcolors (drag to Links-bar)
This opens a new window with a listing of all hex colour values specified in the current webpage's source and in its stylesheets. Internet Explorer-only at the moment.

Remaining bugs:
- doesn't read stylesheets linked with "@import";
- mistakes entities like { for colour values;
- doesn't detect colour values specified in words or in rgb() syntax;
- thinks #ffffff and #FFFFFF are two different colours.

Here's the hacked-together source code:
javascript:void(S=document.body.innerHTML.replace(/href="[^"]*"/g,'').replace(/&#[0-9]{3,6};/g,''),sS=document.styleSheets,w='<tt>',L=new Array());for(i=0;i<sS.length;i++){void(S+=sS[i].cssText);}if(K=S.match(/#[0-9a-f]{3,6}/gi)){for(k=0;k<K.length;k++){if(!L[K[k]]){w+=L[K[k]]='<body bgcolor=#c0c0c0><div style="border-left:20px solid '+K[k]+';color:'+K[k]+'">&nbsp;'+K[k]+'</div>'}}void(window.open().document.write(w));}else{void(alert('No colours found.'))}

Basic procedure:
  1. collect innerHTML of body and cssText of each stylesheet in one big string var;
  2. extract all hex values from that string;
  3. add each hex value to generated html page as a div using that colour (but only if not already added);
  4. open new window and fill it with generated html page.
I think I can make it work for Mozilla by looping through each document.styleSheets[i].cssRules[j].cssText instead of document.styleSheets[i].cssText, which returns 'undefined'.

Update:
I made a separate Mozilla-compatible version that also catches rgb() values. This one doesn't work in IE6 for some reason even though it should, perhaps it exceeds a bookmarklet/url-length limit. It does work in IE5.5 however:

!usedcolors_moz (drag to Links-bar)

Also, Mozilla seems to turn hex values into rgb() values.


poi wrote on 2003/01/08:
that's an interresting bookmarklet you did. If all the bugs you mentionned could be fixed, it could be really helpful. It could be great to put the number of occurence of each color code

You might need to use some REGEX

Do you know of any size limit for a bookmarlet ? Whatever if there's small limitation, an IFRAME or a WINDOW.OPEN might do the trick to load some additionnal code ( as you did for your LINEDRAW bookmarklet )


mados wrote on 2003/01/08:
Please replace the /href=".*"/ regex with /href="[^"]*"/ - that's a common error. Look for greedy/ungreedy in some manual. :-)


Bob wrote on 2003/01/09:
Wow, very nice!


kristoff wrote on 2003/01/09:
Not only nice, useful too!
Great work, Milo (yet again!)


Nate wrote on 2003/01/09:
Hey, it even works in Safari!... at least for a second.. then it tries to load a page called "undefined", as if it were a page at the same site you used the bookmarklet on. If I knew anything about javascript or regex maybe I could have provided better feedback.


Nate wrote on 2003/01/09:
There is probably a more direct workaround for Safari, but this one seems to work just fine:
Change:
window.open().document.write(w))
To:
window.open('','colors','height=200,width=200,left=80,top=80').document.write(w))


Ben wrote on 2003/01/10:
This chunk of code:
(this.style.behavior = 'url(#default#homepage)
makes the bookmarklet think #DEFA is a color variable.


Owentje wrote on 2003/01/13:
nice work..2 comments:

- it doesn't work on frames, maybe try searching one level deep into frames?
- it is case-sensitive, which means #ffffff and #FFFFFF are two different colours where they are not.

:)


GTonini wrote on 2003/05/26:
I reworked the bookmarl - at least for IE/Mac. It nevigates thru each color element of the document, so it is very, very slow but accurate. Also built-in a name-to-hex color conversion (e.g. aqua=#00FFFF,...). It list also the position of the first occourrence of each color. All that withi 1kB code.

Here's the result on this page:
#000000 all[17] backgroundColor
#CCCCCC all[17] color
transparent all[18] backgroundColor
#888888 all[26] color
#AAAAAA all[27] color
#999999 all[42] color
#333333 all[532] backgroundColor
#FF6600 all[553] backgroundColor
#FFC8A4 all[553] borderBottomColor
#FFFFFF all[553] color
#666666 all[566] color

The code:javascript:
w='',j=0,C=new Array(),C['AQUA']='0FF',C['BLACK']='000',C['BLUE']='00F',C['FUCHSIA']='F0F',C['GRAY']='808080',C['GREEN']='008000',C['LIME']='0F0',C['MAROON']='800000',C['NAVY']='000080',C['OLIVE']='808000',C['PURPLE']='800080',C['RED']='F00',C['SILVER']='C0C0C0',C['TEAL']='008080',C['WHITE']='FFF',C['YELLOW']='FF0';
function g(n,m){
for(var i in n){
if(i.toLowerCase().indexOf('color')>=0&&n[i]!=''&&typeof(n[i])!='undefined'&&n[i].indexOf(' ')<0){
var V=n[i].toUpperCase(),W=(V.charAt(0)!='#'?('#'+C[V]):V),X=W.charAt(1),Y=W.charAt(2),Z=W.charAt(3);
W=(W=='#undefined'?n[i]:(W.length==4?'#'+X+X+Y+Y+Z+Z:W));
if(!C[W]&&W!='invert'){
w+=C[W]='<div style="border-left:20px solid '+W+'">&nbsp;'+W+' all['+m.sourceIndex+'] '+i+'</div>';
j++
}
}
}
}
function gC(m){
g(m,m);
g(m.currentStyle,m)
}
gC(document.body);
with(document.body){
for(i=0;i<all.length;i++){
if(all[i].nodeType!=3){
gC(all[i]);
}
}
}
if(j>0){
with(open('','iM','').document){
write('<body><h3>URL: '+this.location+'<br>Colors: '+j+'</h3><tt>'+w+'</tt></body>');
close()
}
}


Bob wrote on 2005/07/12:
It finds unexisting colours, for example it finds #FF6600 just because someone mentioned it in the previous comment. Search the tags not the text...


GTonini wrote on 2006/12/19:
Oh yes. I see the !usedcolors bookmarklet extracts colors from text! Bad idea. My bookmarklet above doesn't do that. The results posted upon running it in this page are no longer valid, since the CSS was changed after the test.