
extCSSStyle
===========

This extension provides support for reading style sheets from CSS files. CSS is parsed using a
tokenizer generated using flex, and built upon the
[W3C grammar](http://www.w3.org/TR/css3-syntax/#lexical) for CSS3. By adding this extension to
any project, you can begin to customize your app with CSS by simply adding 3 lines of code.


Dependencies
------------

* Core
* Network
* Style


Using it in your App
--------------------

Add the `extThree20CSSStyle.xcodeproj` file to your project. Add `extThree20CSSStyle.a` to your
"Link Binary With Libraries" phase, and add `extThree20CSSStyle` as a dependency.

Import the following into your precompiled header.

    #import <extThree20CSSStyle/extThree20CSSStyle.h>


### If you want to use the CSS-powered default style sheet

Drag extThree20CSSStyle.bundle from the `src/extThree20CSSStyle/Resources` directory into your
project and ensure that "Create Folder References" is selected.

Set the global stylesheet when your app launches.

    [TTStyleSheet setGlobalStyleSheet:[[[TTDefaultCSSStyleSheet alloc] init] autorelease]];


Breakdown
---------

The CSSStyle extension includes a CSS grammar, a tokenizer built from this grammar, and a
couple stylesheet objects that provide the interface for grabbing properties from the
stylesheet.

### The Grammar

You can find the grammar in `three20/src/extThree20CSSStyle/Grammars/`. The file is named
`css.grammar`.

To build the grammar, you will need to install flex.

http://flex.sourceforge.net/

The version used to build the grammar included in this lib was 2.5.35 from February 26, 2008.

Building the grammar generates a tokenizer in the file `CssTokenizer.m`. Please read the
flex documentation for more details on tokenizer generation.

### The Parser

TTCSSParser uses the tokenizer generated by flex to process any given CSS file. The result is
a dictionary of rule sets, each containing a set of properties, each with an array of values.
The parser is designed to only read in one file at a time, but within the file all css properties
are cascading as expected.

However, strict adherence to the W3C has not been met. For example, strict checks for validity
do not exist yet, making it possible for the resulting dictionary to include rule sets and
properties that might otherwise be ignored by industry standard CSS systems.

### The Style Sheets

There are two style sheet objects included in this extension. The first, TTCSSStyleSheet is
a new object that reads the results from a TTCSSParser and provides a set of accessors for
interacting with a css stylesheet. This object also provides a method for compositing style
sheets together, where each style sheet overwrites the properties of those before it.

The second style sheet object is TTDefaultCSSStyleSheet. This guy provides a CSS layer upon
the standard TTDefaultStyleSheet. By using TTDefaultCSSStyleSheet, you can theme your app
with a .css file provided in your app. This extension provides a bundle that contains a
style sheet with all of the default TTDefaultStyleSheet values. You can then composite another
style sheet upon this one using addStyleSheetFromDisk:. For an example of this in action,
see TTFacebook in the `three20/samples` directory.


Known Limitations
-----------------

### Font Sizes

Font-size is always interpreted in points, regardless of what you specify. This is due to
the tricky nature of varying DPI on the various iPhone OS devices.

### Text Shadows

The "blur" property is always interpreted as "0". This is due to the technical limitations
of specifying blur for text shadows for UILabels.


Supported CSS Properties and Values
-----------------------------------

### Definitions used below

    Value           Example
    ------------|  |-------------------
    <color>         #FFF or #FF00FF or rgb(255, 0, 255)
                    or rgba(0, 255, 255, 0.5) or <color-name>
    
    <color-name>    Any of the standard names found in the W3C for css3.
                    http://www.w3.org/TR/css3-color/
                    Also, iPhone OS standard colors:
                    lightTextColor
                    darkTextColor
                    groupTableViewBackgroundColor
                    viewFlipsideBackgroundColor
    
    <number>        [0-9.]+


### Colors

    color:            <color>
                      colorWithCssSelector
    background-color: <color>
                      backgroundColorWithCssSelector

`color` is used for text color.

### Fonts

    font-size:        <number>pt
    font-weight:      (bold|normal)
                      fontWithCssSelector

Fonts are defined with a set of properties that collectively create the final UIFont* object.
`fontWithCssSelector` reads each of these properties when building the font object.

### Text Shadow

    text-shadow:      <number>px <number>px <ignored> <color>
                      textShadowColorWithCssSelector
                      textShadowOffsetWithCssSelector

The `text-shadow` property is defined in one chunk, but read using two distinct methods.

The third parameter is ignored. See "Text Shadows" in the `Known Limitations` section for
the technical reasons.


Examples
--------

See `three20/samples/TTFacebook` for a working example.

### How to use TTDefaultCSSStyleSheet

Add `extThree20CSSStyle.bundle` to your project. Make sure that "Create Folder References" is
selected.

Create a file, let's call it "stylesheet.css", and add it to your project. Ensure that it's
being copied in the "Copy Bundle Resources" phase.

Add the following code in your app delegate's `applicationDidFinishLaunching`.

    // TTDefaultCSSStyleSheet automatically reads default.css from extThree20CSSStyle.bundle
    TTDefaultCSSStyleSheet* styleSheet = [[TTDefaultCSSStyleSheet alloc] init];
    
    [styleSheet addStyleSheetFromDisk:TTPathForBundleResource(@"stylesheet.css")];
    
    [TTStyleSheet setGlobalStyleSheet:styleSheet];
    
    TT_RELEASE_SAFELY(styleSheet);

Now you can freely customize the styles of your app using `stylesheet.css`. You can freely
add new styles to the CSS, but with the current design you will also need to add an accessor
to a custom object that inherits from `TTDefaultCSSStyleSheet`. See the source for
`TTDefaultCSSStyleSheet` for examples of how to interact with the style sheet object.
