Results 1 to 2 of 2

Thread: CSS Camelizer

  1. #1
    Join Date
    Jun 2008
    Posts
    589
    Thanks
    13
    Thanked 54 Times in 54 Posts
    Blog Entries
    1

    Default CSS Camelizer

    This script takes normal css (e.g. "background-color") and converts it into "camel style" which can be parsed by JavaScript. Of course, it applies these styles to any element. Here:

    Code:
    function css(elem, options) {
      var ss = (options.replace(/ /g, "")).split(";");
      var privates = {};
      for (var i = 0; i < ss.length; ++i) {
        var s = ss[i].split(":");
        while (1) {
          if (s[0].indexOf("-") != -1) {
            s[0] = s[0].replace(new RegExp(s[0].substr(s[0].indexOf("-"), 2), "g"), (s[0].substr(s[0].indexOf("-"), 2))[1].toUpperCase());
          } else {
            break;
          }
        }
        document.getElementById(elem).style[s[0]] = s[1];
      }
    }
    Syntax: css("myElement1", "background-color: blue; color: red; width: 200; height: 100;");

    There's one flaw where if you try "border: 1px solid black;", its result will be "border:1pxsolidblack", thus "1pxsolidblack" is applied to border. This isn't an actual style, however, there is a messy way to avoid this, though I may not use it. Does anyone have an idea how I would avoid this problem cleanly?

  2. #2
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,878
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Like this:

    Code:
    function css(elem, options) {
      if (typeof elem === "string")
        elem = document.getElementById("elem");
    
      elem.style.cssText += "; " + options;
    }
    Never make the user pass in an ID if they've got a reference to the element lying around. It's horribly inefficient, and very messy — and, of course, requires giving all their elements IDs.

    However, this is passing around strings of code, and is a perfect example as to why doing so is a bad idea. Say, for example, since we don't want our viewers to suffer epileptic fits whilst reading our page, we want to first apply a filter function that will strip out all text-decoration: blink instructions. The only decent way to do this is to parse the string and break it down into a native data-type, remove the offending property, and then compile it back into a string! Horrible. Additionally, long strings get very difficult to read. Rather, it would be preferable to pass an object in the first place:

    Code:
    function css(elem, options) {
      if (typeof elem === "string")
        elem = document.getElementById(elem);
    
      for (var x in options)
        elem.style[x] = options[x];
    
      return elem;
    }
    ... and use it like:

    Code:
    css("myElement1", {
      backgroundColor: "blue",
      color: "red",
      width: "200px",
      height: "100px"
    });
    This is much more readable, allows us to apply proper formatting, and is much easier to work with, too: we can simply write our filter function thus:

    Code:
    Object.copy = function(o) {
      var r = {};
    
      for (var x in o)
        if (o.hasOwnProperty(x))
          r[x] = o[x];
    
      return r;
    };
    
    function removeBlink(cssObj) {
      var r = Object.copy(cssObj);
    
      if (r.textDecoration === "blink")
        delete r.textDecoration;
    
      return r;
    }
    To half-answer your previous question, the proper way to parse such a string into an object would be:

    Code:
    Array.map = function(f, a) {
      for (var i = a.length - 1, r = []; i >= 0; --i)
        r[i] = f(a[i], i);
    
      return r;
    };
    
    String.upperFirst = function(s) {
      return s.charAt(0).toUpperCase() + s.substr(1);
    };
    
    String.trim = function(s) {
      return s.replace(/^\s+/, "").replace(/\s+$/, "");
    };
    
    Object.fromArray = function(a) {
      var r = {};
    
      Array.map(function(pair) { r[pair[0]] = pair[1]; }, a);
    
      return r;
    };
    
    var Css = (function() {
      var jsEquivs = {
        'float' : "css-float"
        // &c.
      };
    
      function cssToObject(s) {
        return Object.fromArray(Array.map(textToPair, s.split(";")));
      }
    
      function textToPair(s) {
        var r = Array.map(String.trim, s.split(":"));
    
        r[0] = propertyToCss(r[0]);
    
        return r;
      }
    
      function propertyToJs(s) {
        return Array.map(String.upperFirst, (jsEquivs[s] || s).split("-")).join("");
      }
    
      return {
        propertyToJs: propertyToJs,
        cssToObject: cssToObject
      };
    })();
    Also note that "100" is not a proper value for a CSS property: it requires a unit.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

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
  •