SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Durban
    Posts
    34
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Using JS to detect colour codes in a css file

    Hi

    I am trying to find a way to pull out all the colours used in a template css file so that I can make a list of the colours automatically.

    Due to the various ways in which the colours are typed in the template css file, the only way I can think of is to actually search for the 6-digit hex codes that make up the colour. Yes, I know about named colours, RGB coding and hex sorthand, but I am going to ignore those for now.

    So, I need a JS routine that:

    1. steps through the css file
    2. stops at every # sign
    3. reads the following text to see if it is 6 digits long
    4. if it is, sees whether it is a valid code (as opposed to a CSS id that happens to be six letters long!)
    5. outputs a comma separated list of colours
    6. removes the duplicates

    Thanks
    Brendon

  2. #2
    CSS & JS/DOM Adept bronze trophy
    Join Date
    Mar 2005
    Location
    USA
    Posts
    5,482
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Use a regular expression. This would match some possible IDs though.

    Code:
    var matches = str.match(/#[\da-f]{6}/ig).unique().join(',');
    
    if(![].push){ // for old browsers that don't natively support Array.push()
      Array.prototype.push=function(){
        for(var i=0;i<arguments.length;i++) this[this.length]=arguments[i];
        return this.length;
      }
    }
    if(![].unique){ // removes duplicate values
      Array.prototype.unique = function(){
        var a=[],i=0,l=this.length;
        for(;i<l;i++) if(a.indexOf(this[i])<0) a.push(this[i]);
        return a;
      }
    }
    if(![].indexOf){
      Array.prototype.indexOf = function(elt /*, from*/){
        var len=this.length;
        var from=Number(arguments[1])||0;
        from=(from<0)?Math.ceil(from):Math.floor(from);
        if(from<0) from+=len;
        for(;from<len;from++){
          if((from in this) && (this[from] === elt)) return from;
        }
        return -1;
      }
    }
    Off Topic:

    This looks like a homework question, but since you've been a member here for over 3 years, I'm assuming it isn't.
    We miss you, Dan Schulz.
    Learn CSS. | X/HTML Validator | CSS validator
    Dynamic Site Solutions
    Code for Firefox, Chrome, Safari, & Opera, then add fixes for IE, not vice versa.

  3. #3
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How about a routine that returns an array of every color in use in an open document, whether set by a link stylesheet or script?

    The browser doesn't care if they are set as rgbs or hexcodes or names-
    why should you?

    Code:
    var Colors={
    	dasher: function (str,boo){
    		if (/^[A-Z]+$/.test(str) || /\-/.test(str)) str = str.toLowerCase();
    		if (boo=== true ){
    			if(/[a-z][A-Z]/.test(str)){
    				str= str.replace(/[A-Z]/g, function (w){
    					return "-" + w.toLowerCase();
    				});
    			}
    		}
    		else if(/\-/.test(str)){
    			str= str.replace(/\-[a-z]/g, function (w){
    				return w.charAt(1).toUpperCase() + w.substring(2);
    			});
    		}
    		return str;
    	},
    	deepCss:function(who, cssprop){
    		var  val= '', str= '';
    		str= Colors.dasher(cssprop);
    		
    		val= who.style[str];
    		if(!val){
    			if(who.currentStyle) val= who.currentStyle[str];
    			else{
    				var dv= document.defaultView;
    				if(dv && dv.getComputedStyle){
    					str= Colors.dasher(str,true);
    					val= dv.getComputedStyle(who,'').getPropertyValue(str);
    				}
    			}
    		}
    		return (val)? val: '';
    	},
    	fromPage: function(){
    		var D= document.getElementsByTagName('*');
    		var A= [], cnt= 0, who, val, V=['color','background-color','border-color'];
    		while(D[cnt++]){
    			who=D[cnt];
    			if(!who || !who.style) continue;
    			for(var i=0; i< 3;i++){
    				val= Colors.deepCss(who,V[i]);
    				if(!val || /^(transparent|inherit)/i.test(val)) continue;
    				val=val.toLowerCase();
    				if(Colors.indexAt(A,val)== -1)A.push(val);
    			}
    		}
    		return A;
    	},
    	indexAt: function(A,wot){
    		var L= A.length;
    		var i= 0;
    		while(i< L){
    			if(A[i]=== wot)return i;
    			++i;
    		}
    		return -1;
    	}
    }
    //test case:
    Colors.fromPage()
    Last edited by mrhoo; Jun 20, 2007 at 20:46.

  4. #4
    CSS & JS/DOM Adept bronze trophy
    Join Date
    Mar 2005
    Location
    USA
    Posts
    5,482
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Good idea, mrhoo. That way you let the browser do more of the work for you.

    One thing though, what is aliasCss()?
    We miss you, Dan Schulz.
    Learn CSS. | X/HTML Validator | CSS validator
    Dynamic Site Solutions
    Code for Firefox, Chrome, Safari, & Opera, then add fixes for IE, not vice versa.

  5. #5
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You caught me, Kravvitz-
    I missed that reference to aliasCss when I was pulling the code together.

    Since the fromPage routine feeds the deepCss function only property names longer than 4 characters, it won't throw an error.

    It translates style shorthand, I use it for quick style experiments-
    'pos:relative;bC:white;color:black;pT:2px;m:1em 1ex;vis:v;z:10';
    I allowed the original deepCss to use the shortcuts as well.
    Code:
    aliasCss: function(){
    	var wot= this.toLowerCase();
    	if(/^[pm][trbl]?$/.test(wot)){
    		var s= (/^p/.test(wot))? 'padding': 'margin';
    		if(wot.length==1) return s;
    		switch(wot.substring(1)){
    			case 't': return s+ 'Top';
    			case 'r': return s+ 'Right';
    			case 'b': return s+ 'Bottom';
    			case 'l': return s+ 'Left';
    			default: return s;
    		}
    	}
    	switch(wot){
    		case 'bg': return 'background';
    		case 'bc': return 'backgroundColor';
    		case 'bi': return 'backgroundImage';
    		case 'bp': return 'backgroundPosition';
    		case 'br': return 'backgroundRepeat';
    		case 'd': case 'dis': return 'display';
    		case 'ff': return 'fontFamily';
    		case 'fs': return 'fontSize';
    		case 'fst': return 'fontStyle';
    		case 'fw': return 'fontWeight';
    		case 'lh': return 'lineHeight';
    		case 'pos': return 'position';
    		case 'ta': return 'textAlign';
    		case 'ti': return 'textIndent';
    		case 'td': return 'textDecoration';
    		case 'tt': return 'textTransform';
    		case 'v': case 'vis': return 'visibility';
    		case 'z': return 'zIndex';
    		default: return this;
    	}
    }

  6. #6
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Durban
    Posts
    34
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi

    Thanks or the responses. Nope, it isn't homework! I am wanting the list of colours in a template css file so that I can populate a drop down list of colours in a wysiwg editor for the Joomla CMS.

    So, I would prefer to get the colours from the css file rather than the browser for 2 reasons - firstly the user may have already assigned extra colours to text (precisely what I want to avoid) and secondly, the editor is used on the backend of the cms, so the page with its colours isn't even loaded.

    Ideally I need to pull in the full content of the css file and then pull out the colours.

    I'll pass your code and ideas onto the developer to see if they can use them.

    Regards
    Brendon

  7. #7
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    sorry-double post.

  8. #8
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    get_colorsfromCss=function(str){
    	var A=[],tem,M;
    	var Rx=/\-?color *\: *([#\w][^\s;\}]+)/ig
    	while(str && (M= Rx.exec(str)) !=null){
    		tem=M[1].toLowerCase();
    		if(A.hasAny(tem))continue;
    		A.push(tem);
    	}
    	return A;
    }
    
    Array.prototype.hasAny= function(wot){
    	var L= this.length;
    	for(var i= 0; i< L; i++){				
    		if(this[i]=== wot) return true;		
    	}
    	return false;
    }
    //testcase:
    var str='body{margin:1ex 1em;color: black ;background-color : white ; font-size: 1em}';
    str+='p{color: black; background-color:white;font-size: 1em}';
    str+='h1{line-height:1;color:black;background-color:#ff0000;font-size:1em}';
    str+='span{font-size:1em;color:#000000;background-color:rgb(0,0,255);}';

    get_colorsfromCss(str)
    /*
    returns:
    [black,white,#ff0000,#000000,rgb(0,0,255)]

    You can convert any legal color value to hex or rgb, to prevent black and rgb(0,0,0) and #000000 appearing together in your template

    */
    Last edited by mrhoo; Jun 21, 2007 at 07:56.

  9. #9
    SitePoint Enthusiast
    Join Date
    Feb 2004
    Location
    Third Stone From The Sun
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could try and look at the style property of each rule.

    Code:
    for(var i =0; i < rules.length; i++) {
    var style=rules[ i ].style;
    }
    My outdated site is down for a while now.

  10. #10
    SitePoint Enthusiast
    Join Date
    Feb 2004
    Location
    Third Stone From The Sun
    Posts
    82
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have an example that I was working on.

    I never finished it and it is pretty old, but you'll be able to see the way I read a stylesheet and access the rules.

    http://dhtmlkitchen.com/editor/demo/
    My outdated site is down for a while now.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •