Styles System
The Styles System is made by a powerful set of classes which provide versatile and easy to customize ways to apply formatting styles to selected ranges in a DOM tree.
As styles are designed to be applied to selections, the Style System is strictly dependent on the Selection System.
Overview
In poor words, styles are merely HTML tags and attributes to be added or modified in the DOM tree. Some styles can be applied by creating new tags, while others are available only for already existing ones. Because of this, we can group those tags with the following criteria:
- Formatting Tags: tags used to apply formatting or semantic value to text selections (which may also include objects). Those kids of tags may be created on the fly if not available in the selection. Some examples of tags in this group are <b>, <em>, <span> and <abbr>.
- Object Tags: tags that may be selected as a whole with a single click. These tags can't be created on the fly. Some example of tags in this group are <img> and <table>.
- Block Tags: tags that embrace blocks of text, object or even other block tags. Applying block tags will always replace existing ones. Examples of tags in this group are <p>, <h1> and <address>.
When defining a tag, you may also set the attributes to be applied with the tag. For example, you can defined a tag that outputs <span class="MyClass">. Other than attributes, you can also define "style" properties to be applied to the tag, having outputs like <span style="color: #FF0000; border: solid 1px #0000FF">, where each style property (color and border) has been defined separately.
The "style" attribute may also be defined. We must first apply the attributes, and them apply the styles.
Variable Attributes and Styles
On tag definitions, you may create "variable attributes or styles", which require their values inputted by the end user, or by code execution. An example of variable attribute is the "title" of a <abbr title="xxx">, or even the color for <span style="color:xxx"> tag. Those variable entries may have a "label" which is shown to the end user, and a "type", which defined the types of values accepted:
- text: any text.
- percent: a percent value (possibly using a percent slider).
- color: a color value (possibly using a color selector).
- select: a list of predefined options.
- unit: a "CSS compatible" unit (Length or Percentage).
- fontSize: a Font Size unit.
Variable attributes or styles are defined by setting its value to a string in the following format:
#('<identifier>', '<type>', '<default value>', '<options>')
- Only <identifier> is required. It is the name used to set the variable value.
- The <type> value defaults to "text".
- The <options> parameter is valid only for the "select", "fontSize" and "unit" types, with values separated by a pipe (|).
- For fontSize or unit types, the <options> parameter can be used to limit the accepted units.
Some examples are:
- #('Title')
- #("AltText", "string", "FCKeditor")
- #('Color', 'select', '', 'red|green|blue')
Overrides
In some situations, it is important to define rules to indicate how some styles will behave in the presence of others.
A classic example is the <font> element. If a style with output <span style="font-size:x"> is defined, we want it to "override" any <font size="y"> elements, possibly removing them.
To solve this situation, a list of "overrides" can be defined, with element definitions to be overridden. Each element in the list is much similar to a normal element definition, with the exception that attributes and styles can be set to "null" to catch all values, or a regular expression.
Special Elements
When defining a style, the special "#" element name can be used to point the editor to apply the style to the block element(s) enclosed by the selection. This is useful only when attributes and styles are also defined.
Classes
Internally, styles definitions are represented by the "FCKStyle" based class. Those classes are then used and applied through the "FCKStylesHandler" class.
FCKStyle
Properties
- Element: The element to which the style will be applied.
- Label: (optional) The text to represent the style when displaying it to the end user, when needed.
- Attributes: (optional) A key-value list of attribute names and values.
- Styles: (optional) A key-value list of styles names and values.
FCKStylesHandler
Methods
- ApplyStyle( styleObj ): Applies the provided style to the current selection.
- RemoveStyle( styleObj ): Removes the provided style from the selection.
- RemoveStyles(): Removes all kinds of "inline" styles from the selection.
Built-in Commands
Some specific formatting commands are today handled by the browser itself, usually by calling the "execCommand" function. The problem here is that each browser has its own implementation of it. For example, for the "Bold" command, you may have <b>, <strong> and <span style="font-weight:bold"> being produced depending on the browser. Other that the evident difference, there is no control on how to apply those styles.
With our Styles System, we are able to replace the browser's built-in commands with well configured styles, providing the exact same behavior with all browsers.
The following is the list of commands that we can replace:
- Bold
- Italic
- Underline
- Strikethrough
- Subscript
- Superscript
- Paragraph Align (left, right, center and justify)
- Style Combo
- Format Combo
- Font Combo
- Font Size Combo
- Foreground Color
- Background Color
Also, the "Remove Styles" command will also be handled by this system (using FCKStylesHandler.RemoveStyles()).
Predefined Styles List
FCKeditor will present a toolbar combo with all styles available to the end user. Those styles will be defined by the developer and can be inputted in the editor using any of the following methods:
- XML File
- CSS File
- Configuration Option
If more than one of the above methods are used, the styles get combined (no override).
XML File
The following sample is a "self described" representation of the XML file that can be used to feed FCKeditor with its styles definitions:
<Styles>
<Style label="Custom Bold" element="span">
<!-- The "style" attribute can be set also
using the <Attribute> node. -->
<Attribute name="style" value="font-weight: bold;" />
</Style>
<Style label="Image on Left" element="img">
<Attribute name="border" value="2" />
<Attribute name="align" value="left" />
<Style name="padding" value="5px" />
<Style name="margin-right" value="5px" />
</Style>
<Style label="Variables Sample" element="span">
<Attribute name="title" value="#('string')" />
<Style name="backgroundColor" value="#('color', '#ff0000')" />
<Style name="color" value="#('select', 'red', 'red|green|blue')" />
<Style name="width" value="#('unit', '', 'px|%')" />
</Style>
</Styles>
CSS File
By pointing FCKeditor to a CSS file, some of the CSS rules can be parsed and added to the Styles combo. Actually, all "named" rules will be considered, while element exclusive rules will be ignored.
For example, the following styles will be considered:
.MyStyles { ... }
h1.This_is_a_Style { ... }
b.customBold { ... }
For element-less rules (like the first one above), the <span> tag will be used. For other rules, the element will be considered.
Also, the style labels will be composed by the rules names. The name will be spaced before UPPERCASED characters or underscores. The first character will be converted to uppercase, so the above rules will result in the following styles:
- My Styles: using <span>
- This is a Style: using <h1>
- Custom Bold: using <b>
There are some rules to be considered:
- Successive rules using the same name in the CSS file will be ignored. So, if you have ".MyStyle" and "h1.MyStyle", only the first entry will be considered.
- Nested rules (like "td span.red") will be ignored.
- Element ID specific rules (like "#myId") will be ignored.
FCKeditor will not append the CSS file to the editing area, which must be done by using the EditingAreaCSS setting.
Configuration Option
Another way to set the styles in the Styles combo is by passing a string, in "JavaScript object definition format" which defines the styles. The following is an example of it:
FCKConfig.Styles = "'My Style' : { Element : 'h1', Attributes : { title : 'Title 1' }, Styles : { color : '#ff0000', 'font-family' : 'Courier' } }, 'Another Style' : { Element : 'span', Attributes : { class : 'MyClass' } }" ;
Which is the single line representation of:
'My Style' : {
Element : 'h1',
Attributes : {
title : 'Title 1' },
Styles : {
color : '#ff0000',
'font-family' : 'Courier' }
},
'Another Style' : {
Element : 'span',
Attributes : {
class : 'MyClass' }
}