Custom CSS Function

From PowerUI
Jump to: navigation, search

Defining a new CSS function can be wonderfully useful if you want to make something more readable. You can use them anywhere except for existing specification defined composite properties like font as they reject CSS values they don't recognise.

hello-world: say-hello("everybody");

A basic function

The most basic CSS function (A C# file) looks like this:

using Css;

// say-hello
public class SayHello : CssFunction{
    
    public override string[] GetNames(){
        return new string[]{"say-hello"};
    }

    public override Css.Value Clone(){
        // Create the new one:
        SayHello result = new SayHello();
        
        // Copy the params:
        result.Values = CopyInnerValues();
        
        // Ok!
        return result;
    }
    
}

This function would act the same as a '0' when used, except for if you did e.g. aCssValue is SayHello.

At the very least, you must:

  • Inherit from CssFunction.
  • Give it one or more (sometimes prefixed) names.
  • Give it a class name, which is typically just the name of the function.
  • Declare the Clone method which creates an exact copy.
  • Optionally put it in the Css.Functions namespace.

Place it somewhere outside the PowerUI folders. This is just incase you update PowerUI, as you won't want to loose your changes. It can go anywhere you find appropriate.

Accessing parameters

A function is simply a value set, meaning you just do this[index] to access a particular parameter:

// This could be e.g. double(5) which responds with '10'.
public override float GetDecimal(RenderableData context, CssProperty property){
    
    if(Count == 0){
        // No parameters!
        return 0;
    }
    
    // Double the first parameter:
    return this[0].GetDecimal(context, property) * 2f;
    
}

It's not required, but typically the built in functions cache parameter values by reading them immediately after the value was parsed via the OnValueReady method:

// Typically something a little more intensive 
// which isn't context sensitive at all.
private float MyInputValue;

public override void OnValueReady(CssLexer lexer){
    
    if(Count == 0){
        // No parameters!
        return;
    }
    
    // Must not be context sensitive
    MyInputValue=this[0].GetRawDecimal();
    
}

Note that you don't have to override GetDecimal - you could override GetText instead or define some entirely custom response type. Using partial classes you can extend, for example, CssProperty or Css.Value to add entirely custom CSS value types without needing to modify PowerUI's source.

Finding built-in functions

CSS functions tend to be more spread out in PowerUI, but you can find many of them here:

  • Path/To/PowerUI/Spark/Functions